diff --git a/app/pe/pe_jury.py b/app/pe/pe_jury.py index 882590e5b..2ac919629 100644 --- a/app/pe/pe_jury.py +++ b/app/pe/pe_jury.py @@ -98,142 +98,162 @@ class JuryPE(object): self.nom_export_zip = f"Jury_PE_{self.diplome}" "Nom du zip où ranger les fichiers générés" + # Chargement des étudiants à prendre en compte dans le jury + pe_affichage.pe_print( + f"""*** Recherche et chargement des étudiants diplômés en { + self.diplome} pour la formation {self.formation_id}""" + ) + self.etudiants = EtudiantsJuryPE(self.diplome) # Les infos sur les étudiants + self.etudiants.find_etudiants(self.formation_id) + self.diplomes_ids = self.etudiants.diplomes_ids + self.zipdata = io.BytesIO() - with ZipFile(self.zipdata, "w") as zipfile: - # Chargement des étudiants à prendre en compte dans le jury - pe_affichage.pe_print( - f"""*** Recherche et chargement des étudiants diplômés en { - self.diplome} pour la formation {self.formation_id}""" - ) - self.etudiants = EtudiantsJuryPE( - self.diplome - ) # Les infos sur les étudiants - self.etudiants.find_etudiants(self.formation_id) - self.diplomes_ids = self.etudiants.diplomes_ids - - # Intègre le bilan des semestres taggués au zip final - output = io.BytesIO() - with pd.ExcelWriter(output, engine="openpyxl") as writer: - if self.diplomes_ids: - onglet = "diplômés" - df_diplome = self.etudiants.df_administratif(self.diplomes_ids) - df_diplome.to_excel(writer, onglet, index=True, header=True) - if self.etudiants.abandons_ids: - onglet = "redoublants-réorientés" - df_abandon = self.etudiants.df_administratif( - self.etudiants.abandons_ids - ) - df_abandon.to_excel(writer, onglet, index=True, header=True) - output.seek(0) - - self.add_file_to_zip( - zipfile, - f"etudiants_{self.diplome}.xlsx", - output.read(), - path="details", - ) - if not self.diplomes_ids: - pe_affichage.pe_tools("*** Aucun étudiant diplômé") + pe_affichage.pe_print("*** Aucun étudiant diplômé") else: - # Génère les semestres taggués (avec le calcul des moyennes) pour le jury PE - pe_affichage.pe_print("*** Génère les semestres taggués") - self.semestres_taggues = compute_semestres_tag(self.etudiants) - - # Intègre le bilan des semestres taggués au zip final - output = io.BytesIO() - with pd.ExcelWriter(output, engine="openpyxl") as writer: - for formsemestretag in self.semestres_taggues.values(): - onglet = formsemestretag.nom - df = formsemestretag.df_moyennes_et_classements() - # écriture dans l'onglet - df.to_excel(writer, onglet, index=True, header=True) - output.seek(0) - - self.add_file_to_zip( - zipfile, - f"semestres_taggues_{self.diplome}.xlsx", - output.read(), - path="details", - ) - - # Génère les trajectoires (combinaison de semestres suivis - # par un étudiant pour atteindre le semestre final d'un aggrégat) - pe_affichage.pe_print( - "*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants" - ) - self.trajectoires = TrajectoiresJuryPE(self.diplome) - self.trajectoires.cree_trajectoires(self.etudiants) - - # Génère les moyennes par tags des trajectoires - pe_affichage.pe_print( - "*** Calcule les moyennes par tag des trajectoires possibles" - ) - self.trajectoires_tagguees = compute_trajectoires_tag( - self.trajectoires, self.etudiants, self.semestres_taggues - ) - - # Intègre le bilan des trajectoires tagguées au zip final - output = io.BytesIO() - with pd.ExcelWriter(output, engine="openpyxl") as writer: - for trajectoire_tagguee in self.trajectoires_tagguees.values(): - onglet = trajectoire_tagguee.get_repr() - df = trajectoire_tagguee.df_moyennes_et_classements() - # écriture dans l'onglet - df.to_excel(writer, onglet, index=True, header=True) - output.seek(0) - - self.add_file_to_zip( - zipfile, - f"trajectoires_taggues_{self.diplome}.xlsx", - output.read(), - path="details", - ) - - # Génère les interclassements (par promo et) par (nom d') aggrégat - pe_affichage.pe_print("*** Génère les interclassements par aggrégat") - self.interclassements_taggues = compute_interclassements( - self.etudiants, self.trajectoires, self.trajectoires_tagguees - ) - - # Intègre le bilan des aggrégats (interclassé par promo) au zip final - output = io.BytesIO() - with pd.ExcelWriter(output, engine="openpyxl") as writer: - for interclass_tag in self.interclassements_taggues.values(): - if interclass_tag.significatif: # Avec des notes - onglet = interclass_tag.get_repr() - df = interclass_tag.df_moyennes_et_classements() - # écriture dans l'onglet - df.to_excel(writer, onglet, index=True, header=True) - output.seek(0) - - self.add_file_to_zip( - zipfile, - f"interclassements_taggues_{self.diplome}.xlsx", - output.read(), - path="details", - ) - - # Synthèse des éléments du jury PE - self.synthese = self.synthetise_juryPE() - - # Export des données => mode 1 seule feuille -> supprimé - pe_affichage.pe_print("*** Export du jury de synthese") - output = io.BytesIO() - - with pd.ExcelWriter(output, engine="openpyxl") as writer: - for onglet, df in self.synthese.items(): - # écriture dans l'onglet: - df.to_excel(writer, onglet, index=True, header=True) - output.seek(0) - - self.add_file_to_zip( - zipfile, f"synthese_jury_{self.diplome}.xlsx", output.read() - ) + self._gen_xls_diplomes(zipfile) + self._gen_xls_semestre_taggues(zipfile) + self._gen_xls_trajectoires(zipfile) + self._gen_xls_aggregats(zipfile) + self._gen_xls_synthese(zipfile) # Fin !!!! Tada :) + def _gen_xls_diplomes(self, zipfile: ZipFile): + "Intègre le bilan des semestres taggués au zip" + output = io.BytesIO() + with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated + output, engine="openpyxl" + ) as writer: + if self.diplomes_ids: + onglet = "diplômés" + df_diplome = self.etudiants.df_administratif(self.diplomes_ids) + df_diplome.to_excel(writer, onglet, index=True, header=True) + if self.etudiants.abandons_ids: + onglet = "redoublants-réorientés" + df_abandon = self.etudiants.df_administratif( + self.etudiants.abandons_ids + ) + df_abandon.to_excel(writer, onglet, index=True, header=True) + output.seek(0) + + self.add_file_to_zip( + zipfile, + f"etudiants_{self.diplome}.xlsx", + output.read(), + path="details", + ) + + def _gen_xls_semestre_taggues(self, zipfile: ZipFile): + "Génère les semestres taggués (avec le calcul des moyennes) pour le jury PE" + pe_affichage.pe_print("*** Génère les semestres taggués") + self.semestres_taggues = compute_semestres_tag(self.etudiants) + + # Intègre le bilan des semestres taggués au zip final + output = io.BytesIO() + with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated + output, engine="openpyxl" + ) as writer: + for formsemestretag in self.semestres_taggues.values(): + onglet = formsemestretag.nom + df = formsemestretag.df_moyennes_et_classements() + # écriture dans l'onglet + df.to_excel(writer, onglet, index=True, header=True) + output.seek(0) + + self.add_file_to_zip( + zipfile, + f"semestres_taggues_{self.diplome}.xlsx", + output.read(), + path="details", + ) + + def _gen_xls_trajectoires(self, zipfile: ZipFile): + """Génère les trajectoires (combinaison de semestres suivis + par un étudiant pour atteindre le semestre final d'un aggrégat) + """ + pe_affichage.pe_print( + "*** Génère les trajectoires (différentes combinaisons de semestres) des étudiants" + ) + self.trajectoires = TrajectoiresJuryPE(self.diplome) + self.trajectoires.cree_trajectoires(self.etudiants) + + # Génère les moyennes par tags des trajectoires + pe_affichage.pe_print( + "*** Calcule les moyennes par tag des trajectoires possibles" + ) + self.trajectoires_tagguees = compute_trajectoires_tag( + self.trajectoires, self.etudiants, self.semestres_taggues + ) + + # Intègre le bilan des trajectoires tagguées au zip final + output = io.BytesIO() + with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated + output, engine="openpyxl" + ) as writer: + for trajectoire_tagguee in self.trajectoires_tagguees.values(): + onglet = trajectoire_tagguee.get_repr() + df = trajectoire_tagguee.df_moyennes_et_classements() + # écriture dans l'onglet + df.to_excel(writer, onglet, index=True, header=True) + output.seek(0) + + self.add_file_to_zip( + zipfile, + f"trajectoires_taggues_{self.diplome}.xlsx", + output.read(), + path="details", + ) + + def _gen_xls_aggregats(self, zipfile: ZipFile): + """Intègre le bilan des aggrégats (interclassé par promo) au zip""" + # Génère les interclassements (par promo et) par (nom d') aggrégat + pe_affichage.pe_print("*** Génère les interclassements par aggrégat") + self.interclassements_taggues = compute_interclassements( + self.etudiants, self.trajectoires, self.trajectoires_tagguees + ) + + # Intègre le bilan des aggrégats (interclassé par promo) au zip final + output = io.BytesIO() + with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated + output, engine="openpyxl" + ) as writer: + for interclass_tag in self.interclassements_taggues.values(): + if interclass_tag.significatif: # Avec des notes + onglet = interclass_tag.get_repr() + df = interclass_tag.df_moyennes_et_classements() + # écriture dans l'onglet + df.to_excel(writer, onglet, index=True, header=True) + output.seek(0) + + self.add_file_to_zip( + zipfile, + f"interclassements_taggues_{self.diplome}.xlsx", + output.read(), + path="details", + ) + + def _gen_xls_synthese(self, zipfile: ZipFile): + """Synthèse des éléments du jury PE""" + # Synthèse des éléments du jury PE + self.synthese = self.synthetise_juryPE() + + # Export des données => mode 1 seule feuille -> supprimé + pe_affichage.pe_print("*** Export du jury de synthese") + output = io.BytesIO() + with pd.ExcelWriter( # pylint: disable=abstract-class-instantiated + output, engine="openpyxl" + ) as writer: + for onglet, df in self.synthese.items(): + # écriture dans l'onglet: + df.to_excel(writer, onglet, index=True, header=True) + output.seek(0) + + self.add_file_to_zip( + zipfile, f"synthese_jury_{self.diplome}.xlsx", output.read() + ) + def add_file_to_zip(self, zipfile: ZipFile, filename: str, data, path=""): """Add a file to given zip All files under NOM_EXPORT_ZIP/ diff --git a/app/pe/pe_view.py b/app/pe/pe_view.py index 0dd60ca73..47eab917b 100644 --- a/app/pe/pe_view.py +++ b/app/pe/pe_view.py @@ -35,14 +35,13 @@ """ -from flask import send_file, request +from flask import flash, g, redirect, request, send_file, url_for from app.models import FormSemestre from app.scodoc.sco_exceptions import ScoValueError import app.scodoc.sco_utils as scu from app.scodoc import html_sco_header -from app.scodoc import sco_preferences from app.pe import pe_comp from app.pe import pe_jury @@ -125,7 +124,6 @@ def pe_view_sem_recap( """Génération des avis de poursuite d'étude""" if request.method == "GET": return _pe_view_sem_recap_form(formsemestre_id) - prefs = sco_preferences.SemPreferences(formsemestre_id=formsemestre_id) sem_base = FormSemestre.get_formsemestre(formsemestre_id) if not sem_base.formation.is_apc(): @@ -142,6 +140,15 @@ def pe_view_sem_recap( diplome = pe_comp.get_annee_diplome_semestre(sem_base) jury = pe_jury.JuryPE(diplome, sem_base.formation.formation_id) + if not jury.diplomes_ids: + flash("aucun étudiant à considérer !") + return redirect( + url_for( + "notes.pe_view_sem_recap", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + ) + ) data = jury.get_zipped_data()