diff --git a/app/but/jury_but.py b/app/but/jury_but.py
index 87bbe4721..5bd71c7ec 100644
--- a/app/but/jury_but.py
+++ b/app/but/jury_but.py
@@ -413,12 +413,12 @@ class DecisionsProposeesAnnee(DecisionsProposees):
# Si validée par niveau supérieur:
if self.code_valide == sco_codes.ADSUP:
self.codes.insert(0, sco_codes.ADSUP)
- self.explanation = f"
{explanation}
"
+ self.explanation = f'{explanation}
'
messages = self.descr_pb_coherence()
if messages:
self.explanation += (
- ''
- + '
'.join(messages)
+ '
'
+ + '
'.join(messages)
+ "
"
)
self.codes = [self.codes[0]] + sorted((c or "") for c in self.codes[1:])
@@ -1014,19 +1014,23 @@ class DecisionsProposeesAnnee(DecisionsProposees):
if dec_ue.code_valide not in CODES_UE_VALIDES:
if (
dec_ue.ue_status
- and dec_ue.ue_status["was_capitalized"]
+ and dec_ue.ue_status["is_capitalized"]
):
messages.append(
f"Information: l'UE {ue.acronyme} capitalisée est utilisée pour un RCUE cette année"
)
else:
messages.append(
- f"L'UE {ue.acronyme} n'est pas validée mais son RCUE l'est !"
+ f"L'UE {ue.acronyme} n'est pas validée mais son RCUE l'est (probablement une validation antérieure)"
)
else:
messages.append(
f"L'UE {ue.acronyme} n'a pas décision (???)"
)
+ # Voyons si on est dispensé de cette ue ?
+ res = self.res_impair if ue.semestre_idx % 2 else self.res_pair
+ if res and (self.etud.id, ue.id) in res.dispense_ues:
+ messages.append(f"Pas (ré)inscrit à l'UE {ue.acronyme}")
return messages
def valide_diplome(self) -> bool:
@@ -1531,7 +1535,7 @@ class DecisionsProposeesUE(DecisionsProposees):
def __repr__(self) -> str:
return f"""<{self.__class__.__name__} ue={self.ue.acronyme} valid={self.code_valide
- } codes={self.codes} explanation={self.explanation}>"""
+ } codes={self.codes} explanation="{self.explanation}">"""
def compute_codes(self):
"""Calcul des .codes attribuables et de l'explanation associée"""
diff --git a/app/but/jury_but_view.py b/app/but/jury_but_view.py
index 915d75393..169abdf27 100644
--- a/app/but/jury_but_view.py
+++ b/app/but/jury_but_view.py
@@ -109,23 +109,29 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
"""
)
ue_impair, ue_pair = rcue.ue_1, rcue.ue_2
- # Les UEs à afficher,
- # qui
- ues_ro = [
+ # Les UEs à afficher : on regarde si read only et si dispense (non ré-inscription à l'UE)
+ ues_ro_dispense = [
(
ue_impair,
rcue.ue_cur_impair is None,
+ deca.res_impair
+ and (deca.etud.id, ue_impair.id) in deca.res_impair.dispense_ues,
),
(
ue_pair,
rcue.ue_cur_pair is None,
+ deca.res_pair
+ and (deca.etud.id, ue_pair.id) in deca.res_pair.dispense_ues,
),
]
# Ordonne selon les dates des 2 semestres considérés:
if reverse_semestre:
- ues_ro[0], ues_ro[1] = ues_ro[1], ues_ro[0]
+ ues_ro_dispense[0], ues_ro_dispense[1] = (
+ ues_ro_dispense[1],
+ ues_ro_dispense[0],
+ )
# Colonnes d'UE:
- for ue, ue_read_only in ues_ro:
+ for ue, ue_read_only, ue_dispense in ues_ro_dispense:
if ue:
H.append(
_gen_but_niveau_ue(
@@ -134,6 +140,7 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
disabled=read_only or ue_read_only,
annee_prec=ue_read_only,
niveau_id=ue.niveau_competence.id,
+ ue_dispense=ue_dispense,
)
)
else:
@@ -188,21 +195,30 @@ def _gen_but_niveau_ue(
disabled: bool = False,
annee_prec: bool = False,
niveau_id: int = None,
+ ue_dispense: bool = False,
) -> str:
if dec_ue.ue_status and dec_ue.ue_status["is_capitalized"]:
moy_ue_str = f"""{
scu.fmt_note(dec_ue.moy_ue_with_cap)}"""
+
+ if ue_dispense:
+ etat_en_cours = """Non (ré)inscrit à cette UE"""
+ else:
+ etat_en_cours = f"""UE en cours
+ { "sans notes" if np.isnan(dec_ue.moy_ue)
+ else
+ ("avec moyenne " + scu.fmt_note(dec_ue.moy_ue) + "")
+ }
+ """
+
scoplement = f"""
UE {ue.acronyme} capitalisée
le {dec_ue.ue_status["event_date"].strftime("%d/%m/%Y")}
-
UE en cours
- { "sans notes" if np.isnan(dec_ue.moy_ue)
- else
- ("avec moyenne
" + scu.fmt_note(dec_ue.moy_ue) + "")
- }
+
+ { etat_en_cours }
"""
@@ -244,7 +260,13 @@ def _gen_but_niveau_ue(
"""
else:
- scoplement = ""
+ if dec_ue.ue_status and dec_ue.ue_status["was_capitalized"]:
+ scoplement = """
+ UE déjà capitalisée avec résultat moins favorable.
+
+ """
+ else:
+ scoplement = ""
ue_class = "" # 'recorded' if dec_ue.code_valide is not None else ''
if dec_ue.code_valide is not None and dec_ue.codes:
diff --git a/app/but/rcue.py b/app/but/rcue.py
index 2fce54ffc..9a6ee73ce 100644
--- a/app/but/rcue.py
+++ b/app/but/rcue.py
@@ -75,7 +75,7 @@ class RegroupementCoherentUE:
else None
)
- # Autres validations pour l'UE paire
+ # Autres validations pour les UEs paire/impaire
self.validation_ue_best_pair = best_autre_ue_validation(
etud.id,
niveau.id,
@@ -101,14 +101,24 @@ class RegroupementCoherentUE:
"résultats formsemestre de l'UE si elle est courante, None sinon"
self.ue_status_impair = None
if self.ue_cur_impair:
+ # UE courante
ue_status = res_impair.get_etud_ue_status(etud.id, self.ue_cur_impair.id)
self.moy_ue_1 = ue_status["moy"] if ue_status else None # avec capitalisée
self.ue_1 = self.ue_cur_impair
self.res_impair = res_impair
self.ue_status_impair = ue_status
elif self.validation_ue_best_impair:
+ # UE capitalisée
self.moy_ue_1 = self.validation_ue_best_impair.moy_ue
self.ue_1 = self.validation_ue_best_impair.ue
+ if (
+ res_impair
+ and self.validation_ue_best_impair
+ and self.validation_ue_best_impair.ue
+ ):
+ self.ue_status_impair = res_impair.get_etud_ue_status(
+ etud.id, self.validation_ue_best_impair.ue.id
+ )
else:
self.moy_ue_1, self.ue_1 = None, None
self.moy_ue_1_val = self.moy_ue_1 if self.moy_ue_1 is not None else 0.0
diff --git a/app/comp/res_common.py b/app/comp/res_common.py
index 6e06487fc..9915c6162 100644
--- a/app/comp/res_common.py
+++ b/app/comp/res_common.py
@@ -438,7 +438,7 @@ class ResultatsSemestre(ResultatsCache):
def get_etud_ue_status(self, etudid: int, ue_id: int) -> dict | None:
"""L'état de l'UE pour cet étudiant.
- Result: dict, ou None si l'UE n'est pas dans ce semestre.
+ Result: dict, ou None si l'UE n'existe pas ou n'est pas dans ce semestre.
{
"is_capitalized": # vrai si la version capitalisée est celle prise en compte (meilleure)
"was_capitalized":# si elle a été capitalisée (meilleure ou pas)
@@ -456,6 +456,8 @@ class ResultatsSemestre(ResultatsCache):
}
"""
ue: UniteEns = db.session.get(UniteEns, ue_id)
+ if not ue:
+ return None
ue_dict = ue.to_dict()
if ue.type == UE_SPORT:
diff --git a/app/static/css/jury_but.css b/app/static/css/jury_but.css
index 525c532f0..295e9496a 100644
--- a/app/static/css/jury_but.css
+++ b/app/static/css/jury_but.css
@@ -279,4 +279,10 @@ div.but_doc table tr td.amue {
.but_autorisations_passage.but_explanation {
font-weight: normal;
color: var(--color-explanation);
+}
+
+.deca-expl {
+ font-size: 110%;
+ margin-bottom: 8px;
+ margin-left: 16px;
}
\ No newline at end of file
diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css
index 31ceab22c..6bd88ebc5 100644
--- a/app/static/css/scodoc.css
+++ b/app/static/css/scodoc.css
@@ -3434,6 +3434,14 @@ div.formsemestre-warning-box {
vertical-align: -40%;
}
+.warning.warning-info::before {
+ height:24px;
+ width: 24px;
+ background-size: 24px 24px;
+ background-image: url(/ScoDoc/static/icons/warning-info.svg);
+}
+
+
.warning-light {
font-style: italic;
color: rgb(166, 50, 159);