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(
~
valeur manquante
=
UE dispensée
nan
valeur non disponible
+
📍
code jury non enregistré
""" diff --git a/app/tables/jury_recap.py b/app/tables/jury_recap.py index 5d9e5b8858..8d02065cf7 100644 --- a/app/tables/jury_recap.py +++ b/app/tables/jury_recap.py @@ -81,11 +81,14 @@ class TableJury(TableRecap): def add_jury(self): """Ajoute la colonne code jury et le lien. - Le code jury est celui du semestre: cette colonne n'est montrée + - Le code jury est celui du semestre: cette colonne n'est montrée que pour les formations classiques, ce code n'est pas utilisé en BUT. + - En BUT, on donne la décision de jury annuelle. """ res = self.res autorisations = res.get_autorisations_inscription() + if res.is_apc: + validations_annee = res.get_validations_annee() for row in self.rows: etud = row.etud if not res.is_apc: @@ -115,6 +118,15 @@ class TableJury(TableRecap): group="jury_code_sem", classes=["recorded_code"], ) + if res.is_apc: # BUT + validation_annee = validations_annee.get(etud.id, None) + row.add_cell( + "decision_annuelle", + "Année", + validation_annee.code if validation_annee else "", + group="jury_code_sem", + classes=["recorded_code"], + ) # Lien saisie ou visu jury a_saisir = (not res.validations) or (not res.validations.has_decision(etud)) row.add_cell(