diff --git a/app/but/bulletin_but.py b/app/but/bulletin_but.py index 279cf86e..2e9ee0a8 100644 --- a/app/but/bulletin_but.py +++ b/app/but/bulletin_but.py @@ -14,6 +14,7 @@ from flask import url_for, g from app.comp.res_but import ResultatsSemestreBUT from app.models import FormSemestre, Identite +from app.models import but_validations from app.models.groups import GroupDescr from app.models.ues import UniteEns from app.scodoc import sco_bulletins, sco_utils as scu @@ -326,6 +327,7 @@ class BulletinBUT: semestre_infos.update( sco_bulletins_json.dict_decision_jury(etud.id, formsemestre.id) ) + semestre_infos.update(but_validations.dict_decision_jury(etud, formsemestre)) if etat_inscription == scu.INSCRIT: # moyenne des moyennes générales du semestre semestre_infos["notes"] = { diff --git a/app/but/jury_but.py b/app/but/jury_but.py index ee23b975..071352c0 100644 --- a/app/but/jury_but.py +++ b/app/but/jury_but.py @@ -933,7 +933,7 @@ class BUTCursusEtud: # WIP TODO """La liste des UE à valider si on valide ce niveau. Ne liste que les UE qui ne sont pas déjà acquises. - Selon la règle donéne par l'arrêté BUT: + Selon la règle donnée par l'arrêté BUT: * La validation des deux UE du niveau d’une compétence emporte la validation de l'ensemble des UE du niveau inférieur de cette même compétence. """ diff --git a/app/models/but_refcomp.py b/app/models/but_refcomp.py index b1aea93e..b9626f82 100644 --- a/app/models/but_refcomp.py +++ b/app/models/but_refcomp.py @@ -195,6 +195,7 @@ class ApcCompetence(db.Model, XMLModel): return f"" def to_dict(self): + "repr dict recursive sur situations, composantes, niveaux" return { "id_orebut": self.id_orebut, "titre": self.titre, @@ -208,6 +209,16 @@ class ApcCompetence(db.Model, XMLModel): "niveaux": {x.annee: x.to_dict() for x in self.niveaux}, } + def to_dict_bul(self) -> dict: + "dict court pour bulletins" + return { + "id_orebut": self.id_orebut, + "titre": self.titre, + "titre_long": self.titre_long, + "couleur": self.couleur, + "numero": self.numero, + } + class ApcSituationPro(db.Model, XMLModel): "Situation professionnelle" @@ -262,6 +273,7 @@ class ApcNiveau(db.Model, XMLModel): self.annee!r} {self.competence!r}>""" def to_dict(self): + "as a dict, recursif sur les AC" return { "libelle": self.libelle, "annee": self.annee, @@ -269,6 +281,15 @@ class ApcNiveau(db.Model, XMLModel): "app_critiques": {x.code: x.to_dict() for x in self.app_critiques}, } + def to_dict_bul(self): + "dict pour bulletins: indique la compétence, pas les ACs (pour l'instant ?)" + return { + "libelle": self.libelle, + "annee": self.annee, + "ordre": self.ordre, + "competence": self.competence.to_dict_bul(), + } + @classmethod def niveaux_annee_de_parcours( cls, diff --git a/app/models/but_validations.py b/app/models/but_validations.py index 651e6fc2..5ec0e09d 100644 --- a/app/models/but_validations.py +++ b/app/models/but_validations.py @@ -13,6 +13,7 @@ from app.models import CODE_STR_LEN from app.models.but_refcomp import ApcNiveau from app.models.etudiants import Identite from app.models.ues import UniteEns +from app.models.formations import Formation from app.models.formsemestre import FormSemestre from app.scodoc import sco_codes_parcours as sco_codes @@ -63,6 +64,10 @@ class ApcValidationRCUE(db.Model): # Par convention, il est donné par la seconde UE return self.ue2.niveau_competence + def to_dict_bul(self) -> dict: + "Export dict pour bulletins" + return {"code": self.code, "niveau": self.niveau().to_dict_bul()} + # Attention: ce n'est pas un modèle mais une classe ordinaire: class RegroupementCoherentUE: @@ -280,3 +285,45 @@ class ApcValidationAnnee(db.Model): def __repr__(self): return f"<{self.__class__.__name__} {self.id} {self.etud} BUT{self.ordre}/{self.annee_scolaire}:{self.code!r}>" + + def to_dict_bul(self) -> dict: + "dict pour bulletins" + return { + "annee_scolaire": self.annee_scolaire, + "date": self.date.isoformat(), + "code": self.code, + "ordre": self.ordre, + } + + +def dict_decision_jury(etud: Identite, formsemestre: FormSemestre) -> dict: + """ + Un dict avec les décisions de jury BUT enregistrées. + Ne reprend pas les décisions d'UE, non spécifiques au BUT. + """ + decisions = {} + # --- RCUEs: seulement sur semestres pairs XXX à améliorer + if formsemestre.semestre_id % 2 == 0: + # validations émises depuis ce formsemestre: + validations_rcues = ApcValidationRCUE.query.filter_by( + etudid=etud.id, formsemestre_id=formsemestre.id + ) + decisions["decision_rcue"] = [v.to_dict_bul() for v in validations_rcues] + else: + decisions["decision_rcue"] = [] + # --- Année: prend la validation pour l'année scolaire de ce semestre + validation = ( + ApcValidationAnnee.query.filter_by( + etudid=etud.id, + annee_scolaire=formsemestre.annee_scolaire(), + ) + .join(ApcValidationAnnee.formsemestre) + .join(FormSemestre.formation) + .filter(Formation.formation_code == formsemestre.formation.formation_code) + .first() + ) + if validation: + decisions["decision_annee"] = validation.to_dict_bul() + else: + decisions["decision_annee"] = None + return decisions diff --git a/app/views/notes.py b/app/views/notes.py index eba13959..dc2b18d5 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -2265,7 +2265,6 @@ def formsemestre_validation_but( + html_sco_header.sco_footer() ) - res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre) deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre) if len(deca.rcues_annee) == 0: raise ScoValueError("année incomplète: pas de jury BUT annuel possible")