diff --git a/app/comp/res_but.py b/app/comp/res_but.py index a91b1dbbcb..2c60f24a02 100644 --- a/app/comp/res_but.py +++ b/app/comp/res_but.py @@ -10,17 +10,17 @@ import time import numpy as np import pandas as pd -from app import log +from app import db, log from app.comp import moy_ue, moy_sem, inscr_mod from app.comp.res_compat import NotesTableCompat from app.comp.bonus_spo import BonusSport -from app.models import ScoDocSiteConfig +from app.models import Formation, FormSemestreInscription, ScoDocSiteConfig from app.models.moduleimpls import ModuleImpl from app.models.but_refcomp import ApcParcours, ApcNiveau from app.models.ues import DispenseUE, UniteEns from app.models.but_validations import ApcValidationAnnee, ApcValidationRCUE from app.scodoc import sco_preferences -from app.scodoc.codes_cursus import UE_SPORT +from app.scodoc.codes_cursus import BUT_CODES_ORDERED, UE_SPORT from app.scodoc.sco_utils import ModuleType @@ -44,7 +44,8 @@ class ResultatsSemestreBUT(NotesTableCompat): """Parcours de chaque étudiant { etudid : parcour_id }""" self.ues_ids_by_parcour: dict[set[int]] = {} """{ parcour_id : set }, ue_id de chaque parcours""" - + self.validations_annee: dict[int, ApcValidationAnnee] = {} + """chargé par get_validations_annee: jury annuel BUT""" if not self.load_cached(): t0 = time.time() self.compute() @@ -321,3 +322,42 @@ class ResultatsSemestreBUT(NotesTableCompat): formsemestre_id=self.formsemestre.id, etudid=etudid ).count() ) + + def get_validations_annee(self) -> dict[int, ApcValidationAnnee]: + """Les validations des étudiants de ce semestre + pour l'année BUT d'une formation compatible avec celle de ce semestre. + Attention: + 1) la validation ne provient pas nécessairement de ce semestre + (redoublants, pair/impair, extérieurs). + 2) l'étudiant a pu démissionner ou défaillir. + 3) S'il y a plusieurs validations pour le même étudiant, prend la "meilleure". + + Mémorise le résultat (dans l'instance, pas en cache: TODO voir au profiler) + """ + if self.validations_annee: + return self.validations_annee + annee_but = (self.formsemestre.semestre_id + 1) // 2 + validations = ( + ApcValidationAnnee.query.filter_by(ordre=annee_but) + .join(Formation) + .filter_by(formation_code=self.formsemestre.formation.formation_code) + .join( + FormSemestreInscription, + db.and_( + FormSemestreInscription.etudid == ApcValidationAnnee.etudid, + FormSemestreInscription.formsemestre_id == self.formsemestre.id, + ), + ) + ) + validation_by_etud = {} + for validation in validations: + if validation.etudid in validation_by_etud: + # keep the "best" + if BUT_CODES_ORDERED.get(validation.code, 0) > BUT_CODES_ORDERED.get( + validation_by_etud[validation.etudid].code, 0 + ): + validation_by_etud[validation.etudid] = validation + else: + validation_by_etud[validation.etudid] = validation + self.validations_annee = validation_by_etud + return self.validations_annee diff --git a/app/scodoc/sco_recapcomplet.py b/app/scodoc/sco_recapcomplet.py index 63a0d4e252..9ebe4e87d2 100644 --- a/app/scodoc/sco_recapcomplet.py +++ b/app/scodoc/sco_recapcomplet.py @@ -251,6 +251,7 @@ def formsemestre_recapcomplet(