From 10de8c4cc26178b293cf8281ad63bbcc5cc99530 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sun, 2 Jul 2023 12:09:17 +0200 Subject: [PATCH] Export Apogee: ajout table ADSUPs --- app/but/jury_but.py | 1 + app/models/but_validations.py | 2 +- app/models/validations.py | 1 + app/scodoc/gen_tables.py | 5 ++- app/scodoc/sco_apogee_csv.py | 67 ++++++++++++++++++++++++++++++++++- app/scodoc/sco_semset.py | 2 +- 6 files changed, 74 insertions(+), 4 deletions(-) diff --git a/app/but/jury_but.py b/app/but/jury_but.py index 99ea436857..05978de2d8 100644 --- a/app/but/jury_but.py +++ b/app/but/jury_but.py @@ -1208,6 +1208,7 @@ class DecisionsProposeesRCUE(DecisionsProposees): ue1_id=ue1.id, ue2_id=ue2.id, code=sco_codes.ADSUP, + formsemestre_id=self.deca.formsemestre.id, # origine ) db.session.add(validation_rcue) db.session.commit() diff --git a/app/models/but_validations.py b/app/models/but_validations.py index fcab132bd0..185ab53987 100644 --- a/app/models/but_validations.py +++ b/app/models/but_validations.py @@ -36,7 +36,7 @@ class ApcValidationRCUE(db.Model): formsemestre_id = db.Column( 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: 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) diff --git a/app/models/validations.py b/app/models/validations.py index 91f17f605a..d4ca5bb074 100644 --- a/app/models/validations.py +++ b/app/models/validations.py @@ -56,6 +56,7 @@ class ScolarFormSemestreValidation(db.Model): ) ue = db.relationship("UniteEns", lazy="select", uselist=False) + etud = db.relationship("Identite", backref="validations") formsemestre = db.relationship( "FormSemestre", lazy="select", uselist=False, foreign_keys=[formsemestre_id] ) diff --git a/app/scodoc/gen_tables.py b/app/scodoc/gen_tables.py index 436ecde25d..2b5e867a92 100644 --- a/app/scodoc/gen_tables.py +++ b/app/scodoc/gen_tables.py @@ -88,7 +88,7 @@ class DEFAULT_TABLE_PREFERENCES(object): return self.values[k] -class GenTable(object): +class GenTable: """Simple 2D tables with export to HTML, PDF, Excel, CSV. Can be sub-classed to generate fancy formats. """ @@ -197,6 +197,9 @@ class GenTable(object): def __repr__(self): return f"" + def __len__(self): + return len(self.rows) + def get_nb_cols(self): return len(self.columns_ids) diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py index 2d3b6af440..e58e05002a 100644 --- a/app/scodoc/sco_apogee_csv.py +++ b/app/scodoc/sco_apogee_csv.py @@ -51,7 +51,14 @@ from app import log from app.comp import res_sem from app.comp.res_compat import NotesTableCompat 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.scodoc.sco_apogee_reader import ( APO_DECIMAL_SEP, @@ -64,6 +71,7 @@ from app.scodoc.gen_tables import GenTable from app.scodoc.sco_vdi import ApoEtapeVDI from app.scodoc.codes_cursus import code_semestre_validant from app.scodoc.codes_cursus import ( + ADSUP, DEF, DEM, NAR, @@ -903,6 +911,54 @@ class ApoData: ) 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]: """ @@ -1029,6 +1085,10 @@ def export_csv_to_apogee( cr_table = apo_data.build_cr_table() 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 if not dest_zip: data = io.BytesIO() @@ -1054,6 +1114,7 @@ def export_csv_to_apogee( log_filename = "scodoc-" + basename + ".log.txt" nar_filename = basename + "-nar" + scu.XLSX_SUFFIX cr_filename = basename + "-decisions" + scu.XLSX_SUFFIX + adsup_filename = f"{basename}-adsups{scu.XLSX_SUFFIX}" logf = io.StringIO() 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".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 # Write data to ZIP @@ -1098,6 +1161,8 @@ def export_csv_to_apogee( if nar_xls: dest_zip.writestr(nar_filename, nar_xls) dest_zip.writestr(cr_filename, cr_xls) + if adsup_xls: + dest_zip.writestr(adsup_filename, adsup_xls) if my_zip: dest_zip.close() diff --git a/app/scodoc/sco_semset.py b/app/scodoc/sco_semset.py index c028429356..f3d8c6d3a5 100644 --- a/app/scodoc/sco_semset.py +++ b/app/scodoc/sco_semset.py @@ -42,6 +42,7 @@ sem_set_list() import flask from flask import g, url_for +from app import log from app.comp import res_sem from app.comp.res_compat import NotesTableCompat 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_preferences from app.scodoc.gen_tables import GenTable -from app import log from app.scodoc.sco_etape_bilan import EtapeBilan from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_vdi import ApoEtapeVDI