forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -1208,6 +1208,7 @@ class DecisionsProposeesRCUE(DecisionsProposees):
|
|||||||
ue1_id=ue1.id,
|
ue1_id=ue1.id,
|
||||||
ue2_id=ue2.id,
|
ue2_id=ue2.id,
|
||||||
code=sco_codes.ADSUP,
|
code=sco_codes.ADSUP,
|
||||||
|
formsemestre_id=self.deca.formsemestre.id, # origine
|
||||||
)
|
)
|
||||||
db.session.add(validation_rcue)
|
db.session.add(validation_rcue)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -36,7 +36,7 @@ class ApcValidationRCUE(db.Model):
|
|||||||
formsemestre_id = db.Column(
|
formsemestre_id = db.Column(
|
||||||
db.Integer, db.ForeignKey("notes_formsemestre.id"), index=True, nullable=True
|
db.Integer, db.ForeignKey("notes_formsemestre.id"), index=True, nullable=True
|
||||||
)
|
)
|
||||||
"formsemestre pair du RCUE"
|
"formsemestre origine du RCUE (celui d'où a été émis la validation)"
|
||||||
# Les deux UE associées à ce niveau:
|
# Les deux UE associées à ce niveau:
|
||||||
ue1_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
|
ue1_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
|
||||||
ue2_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
|
ue2_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
|
||||||
|
@ -56,6 +56,7 @@ class ScolarFormSemestreValidation(db.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
ue = db.relationship("UniteEns", lazy="select", uselist=False)
|
ue = db.relationship("UniteEns", lazy="select", uselist=False)
|
||||||
|
etud = db.relationship("Identite", backref="validations")
|
||||||
formsemestre = db.relationship(
|
formsemestre = db.relationship(
|
||||||
"FormSemestre", lazy="select", uselist=False, foreign_keys=[formsemestre_id]
|
"FormSemestre", lazy="select", uselist=False, foreign_keys=[formsemestre_id]
|
||||||
)
|
)
|
||||||
|
@ -88,7 +88,7 @@ class DEFAULT_TABLE_PREFERENCES(object):
|
|||||||
return self.values[k]
|
return self.values[k]
|
||||||
|
|
||||||
|
|
||||||
class GenTable(object):
|
class GenTable:
|
||||||
"""Simple 2D tables with export to HTML, PDF, Excel, CSV.
|
"""Simple 2D tables with export to HTML, PDF, Excel, CSV.
|
||||||
Can be sub-classed to generate fancy formats.
|
Can be sub-classed to generate fancy formats.
|
||||||
"""
|
"""
|
||||||
@ -197,6 +197,9 @@ class GenTable(object):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<gen_table( nrows={self.get_nb_rows()}, ncols={self.get_nb_cols()} )>"
|
return f"<gen_table( nrows={self.get_nb_rows()}, ncols={self.get_nb_cols()} )>"
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.rows)
|
||||||
|
|
||||||
def get_nb_cols(self):
|
def get_nb_cols(self):
|
||||||
return len(self.columns_ids)
|
return len(self.columns_ids)
|
||||||
|
|
||||||
|
@ -51,7 +51,14 @@ from app import log
|
|||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.comp.res_but import ResultatsSemestreBUT
|
from app.comp.res_but import ResultatsSemestreBUT
|
||||||
from app.models import FormSemestre, Identite, ApcValidationAnnee
|
from app.models import (
|
||||||
|
ApcValidationAnnee,
|
||||||
|
ApcValidationRCUE,
|
||||||
|
FormSemestre,
|
||||||
|
Identite,
|
||||||
|
ScolarFormSemestreValidation,
|
||||||
|
)
|
||||||
|
|
||||||
from app.models.config import ScoDocSiteConfig
|
from app.models.config import ScoDocSiteConfig
|
||||||
from app.scodoc.sco_apogee_reader import (
|
from app.scodoc.sco_apogee_reader import (
|
||||||
APO_DECIMAL_SEP,
|
APO_DECIMAL_SEP,
|
||||||
@ -64,6 +71,7 @@ from app.scodoc.gen_tables import GenTable
|
|||||||
from app.scodoc.sco_vdi import ApoEtapeVDI
|
from app.scodoc.sco_vdi import ApoEtapeVDI
|
||||||
from app.scodoc.codes_cursus import code_semestre_validant
|
from app.scodoc.codes_cursus import code_semestre_validant
|
||||||
from app.scodoc.codes_cursus import (
|
from app.scodoc.codes_cursus import (
|
||||||
|
ADSUP,
|
||||||
DEF,
|
DEF,
|
||||||
DEM,
|
DEM,
|
||||||
NAR,
|
NAR,
|
||||||
@ -903,6 +911,54 @@ class ApoData:
|
|||||||
)
|
)
|
||||||
return T
|
return T
|
||||||
|
|
||||||
|
def build_adsup_table(self):
|
||||||
|
"""Construit une table listant les ADSUP émis depuis les formsemestres
|
||||||
|
NIP nom prenom nom_formsemestre etape UE
|
||||||
|
"""
|
||||||
|
validations_ues, validations_rcue = self.list_adsup()
|
||||||
|
rows = [
|
||||||
|
{
|
||||||
|
"code_nip": v.etud.code_nip,
|
||||||
|
"nom": v.etud.nom,
|
||||||
|
"prenom": v.etud.prenom,
|
||||||
|
"formsemestre": v.formsemestre.titre_formation(with_sem_idx=1),
|
||||||
|
"etape": v.formsemestre.etapes_apo_str(),
|
||||||
|
"ue": v.ue.acronyme,
|
||||||
|
}
|
||||||
|
for v in validations_ues
|
||||||
|
]
|
||||||
|
return GenTable(
|
||||||
|
columns_ids=("code_nip", "nom", "prenom", "formsemestre", "etape", "ue"),
|
||||||
|
titles={
|
||||||
|
"code_nip": "NIP",
|
||||||
|
"nom": "Nom",
|
||||||
|
"prenom": "Prénom",
|
||||||
|
"formsemestre": "Semestre",
|
||||||
|
"etape": "Etape",
|
||||||
|
"ue": "UE",
|
||||||
|
},
|
||||||
|
row=rows,
|
||||||
|
xls_sheet_name="ADSUPs",
|
||||||
|
)
|
||||||
|
|
||||||
|
def list_adsup(
|
||||||
|
self,
|
||||||
|
) -> tuple[list[ScolarFormSemestreValidation], list[ApcValidationRCUE]]:
|
||||||
|
"""Liste les validations ADSUP émises par des formsemestres de cet ensemble"""
|
||||||
|
validations_ues = (
|
||||||
|
ScolarFormSemestreValidation.query.filter_by(code=ADSUP)
|
||||||
|
.filter(ScolarFormSemestreValidation.ue_id != None)
|
||||||
|
.filter(
|
||||||
|
ScolarFormSemestreValidation.formsemestre_id.in_(
|
||||||
|
self.etape_formsemestre_ids
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
validations_rcue = ApcValidationRCUE.query.filter_by(code=ADSUP).filter(
|
||||||
|
ApcValidationRCUE.formsemestre_id.in_(self.etape_formsemestre_ids)
|
||||||
|
)
|
||||||
|
return validations_ues, validations_rcue
|
||||||
|
|
||||||
|
|
||||||
def comp_apo_sems(etape_apogee, annee_scolaire: int) -> list[dict]:
|
def comp_apo_sems(etape_apogee, annee_scolaire: int) -> list[dict]:
|
||||||
"""
|
"""
|
||||||
@ -1029,6 +1085,10 @@ def export_csv_to_apogee(
|
|||||||
cr_table = apo_data.build_cr_table()
|
cr_table = apo_data.build_cr_table()
|
||||||
cr_xls = cr_table.excel()
|
cr_xls = cr_table.excel()
|
||||||
|
|
||||||
|
# ADSUPs
|
||||||
|
adsup_table = apo_data.build_adsup_table()
|
||||||
|
adsup_xls = adsup_table.excel() if len(adsup_table) else None
|
||||||
|
|
||||||
# Create ZIP
|
# Create ZIP
|
||||||
if not dest_zip:
|
if not dest_zip:
|
||||||
data = io.BytesIO()
|
data = io.BytesIO()
|
||||||
@ -1054,6 +1114,7 @@ def export_csv_to_apogee(
|
|||||||
log_filename = "scodoc-" + basename + ".log.txt"
|
log_filename = "scodoc-" + basename + ".log.txt"
|
||||||
nar_filename = basename + "-nar" + scu.XLSX_SUFFIX
|
nar_filename = basename + "-nar" + scu.XLSX_SUFFIX
|
||||||
cr_filename = basename + "-decisions" + scu.XLSX_SUFFIX
|
cr_filename = basename + "-decisions" + scu.XLSX_SUFFIX
|
||||||
|
adsup_filename = f"{basename}-adsups{scu.XLSX_SUFFIX}"
|
||||||
|
|
||||||
logf = io.StringIO()
|
logf = io.StringIO()
|
||||||
logf.write(f"export_to_apogee du {time.ctime()}\n\n")
|
logf.write(f"export_to_apogee du {time.ctime()}\n\n")
|
||||||
@ -1090,6 +1151,8 @@ def export_csv_to_apogee(
|
|||||||
"\n\nElements Apogee inconnus dans ces semestres ScoDoc:\n"
|
"\n\nElements Apogee inconnus dans ces semestres ScoDoc:\n"
|
||||||
+ "\n".join(apo_data.list_unknown_elements())
|
+ "\n".join(apo_data.list_unknown_elements())
|
||||||
)
|
)
|
||||||
|
if adsup_xls:
|
||||||
|
logf.write(f"\n\nADSUP générés: {len(adsup_table)}\n")
|
||||||
log(logf.getvalue()) # sortie aussi sur le log ScoDoc
|
log(logf.getvalue()) # sortie aussi sur le log ScoDoc
|
||||||
|
|
||||||
# Write data to ZIP
|
# Write data to ZIP
|
||||||
@ -1098,6 +1161,8 @@ def export_csv_to_apogee(
|
|||||||
if nar_xls:
|
if nar_xls:
|
||||||
dest_zip.writestr(nar_filename, nar_xls)
|
dest_zip.writestr(nar_filename, nar_xls)
|
||||||
dest_zip.writestr(cr_filename, cr_xls)
|
dest_zip.writestr(cr_filename, cr_xls)
|
||||||
|
if adsup_xls:
|
||||||
|
dest_zip.writestr(adsup_filename, adsup_xls)
|
||||||
|
|
||||||
if my_zip:
|
if my_zip:
|
||||||
dest_zip.close()
|
dest_zip.close()
|
||||||
|
@ -42,6 +42,7 @@ sem_set_list()
|
|||||||
import flask
|
import flask
|
||||||
from flask import g, url_for
|
from flask import g, url_for
|
||||||
|
|
||||||
|
from app import log
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.models import FormSemestre
|
from app.models import FormSemestre
|
||||||
@ -52,7 +53,6 @@ from app.scodoc import sco_formsemestre_status
|
|||||||
from app.scodoc import sco_portal_apogee
|
from app.scodoc import sco_portal_apogee
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app import log
|
|
||||||
from app.scodoc.sco_etape_bilan import EtapeBilan
|
from app.scodoc.sco_etape_bilan import EtapeBilan
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc.sco_vdi import ApoEtapeVDI
|
from app.scodoc.sco_vdi import ApoEtapeVDI
|
||||||
|
Loading…
Reference in New Issue
Block a user