diff --git a/app/but/jury_but.py b/app/but/jury_but.py
index 543a29eef..b5dbdc586 100644
--- a/app/but/jury_but.py
+++ b/app/but/jury_but.py
@@ -63,6 +63,8 @@ from operator import attrgetter
import re
from typing import Union
+from flask import g, url_for
+
from app import db
from app import log
from app.comp.res_but import ResultatsSemestreBUT
@@ -93,6 +95,32 @@ from app.scodoc import sco_utils as scu
from app.scodoc.sco_exceptions import ScoException, ScoValueError
+class NoRCUEError(ScoValueError):
+ """Erreur en cas de RCUE manquant"""
+
+ def __init__(self, deca: "DecisionsProposeesAnnee", ue: UniteEns):
+ if all(u.niveau_competence for u in deca.ues_pair):
+ warning_pair = ""
+ else:
+ warning_pair = """
certaines UE du semestre pair ne sont pas associées à un niveau de compétence
"""
+ if all(u.niveau_competence for u in deca.ues_impair):
+ warning_impair = ""
+ else:
+ warning_impair = """certaines UE du semestre impair ne sont pas associées à un niveau de compétence
"""
+ msg = (
+ f"""Pas de RCUE pour l'UE {ue.acronyme}
+ {warning_impair}
+ {warning_pair}
+ UE {ue.acronyme}: niveau {html.escape(str(ue.niveau_competence))}
+ UEs impaires: {html.escape(', '.join(str(u.niveau_competence or "pas de niveau")
+ for u in deca.ues_impair))}
+
+ """
+ + deca.infos()
+ )
+ super().__init__(msg)
+
+
class DecisionsProposees:
"""Une décision de jury proposé, constituée d'une liste de codes et d'une explication.
Super-classe, spécialisée pour les UE, les RCUE, les années et le diplôme.
@@ -196,6 +224,8 @@ class DecisionsProposeesAnnee(DecisionsProposees):
)
"le rang de l'année dans le BUT: 1, 2, 3"
assert self.annee_but in (1, 2, 3)
+ self.rcues_annee = []
+ "RCUEs de l'année"
if self.formsemestre_impair is not None:
self.validation = ApcValidationAnnee.query.filter_by(
etudid=self.etud.id,
@@ -234,7 +264,6 @@ class DecisionsProposeesAnnee(DecisionsProposees):
}
)
self.rcues_annee = self.compute_rcues_annee()
- "RCUEs de l'année"
formation = (
self.formsemestre_impair.formation
@@ -295,15 +324,41 @@ class DecisionsProposeesAnnee(DecisionsProposees):
def infos(self) -> str:
"informations, for debugging purpose"
- return f"""DecisionsProposeesAnnee
- etud: {self.etud}
- formsemestre_impair: {self.formsemestre_impair}
- formsemestre_pair: {self.formsemestre_pair}
- RCUEs: {self.rcues_annee}
- nb_competences: {self.nb_competences}
- nb_nb_validables: {self.nb_validables}
- codes: {self.codes}
- explanation: {self.explanation}
+ return f"""DecisionsProposeesAnnee
+
"""
def annee_scolaire(self) -> int:
@@ -416,11 +471,11 @@ class DecisionsProposeesAnnee(DecisionsProposees):
ues_impair_sans_rcue.discard(ue_impair.id)
break
if rcue is None:
- raise ScoValueError(f"pas de RCUE pour l'UE {ue_pair.acronyme}")
+ raise NoRCUEError(deca=self, ue=ue_pair)
rcues_annee.append(rcue)
if len(ues_impair_sans_rcue) > 0:
ue = UniteEns.query.get(ues_impair_sans_rcue.pop())
- raise ScoValueError(f"pas de RCUE pour l'UE {ue.acronyme}")
+ raise NoRCUEError(deca=self, ue=ue)
return rcues_annee
def compute_decisions_niveaux(self) -> dict[int, "DecisionsProposeesRCUE"]:
diff --git a/app/models/formations.py b/app/models/formations.py
index 7db99a1fb..d2970fce9 100644
--- a/app/models/formations.py
+++ b/app/models/formations.py
@@ -57,6 +57,10 @@ class Formation(db.Model):
def __repr__(self):
return f"<{self.__class__.__name__}(id={self.id}, dept_id={self.dept_id}, acronyme='{self.acronyme!r}')>"
+ def to_html(self) -> str:
+ "titre complet pour affichage"
+ return f"""Formation {self.titre} ({self.acronyme}) [version {self.version}] code {self.formation_code}"""
+
def to_dict(self):
e = dict(self.__dict__)
e.pop("_sa_instance_state", None)
diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py
index e8d8ba02b..86bc2b9ab 100644
--- a/app/scodoc/sco_edit_ue.py
+++ b/app/scodoc/sco_edit_ue.py
@@ -676,9 +676,7 @@ def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
],
page_title=f"Programme {formation.acronyme}",
),
- f"""Formation {formation.titre} ({formation.acronyme})
- [version {formation.version}] code {formation.formation_code}
- {lockicon}
+ f"""{formation.to_html()} {lockicon}
""",
]