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);