From fa0417f0b1cb136b12de281052b80bc11fe0bb66 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet <emmanuel.viennet@gmail.com> Date: Sat, 23 Mar 2024 13:23:26 +0100 Subject: [PATCH] Jury BUT: affiche la liste des modules avec note en ATTente --- app/but/jury_but.py | 25 +++++++++++++++++++++---- app/static/css/jury_but.css | 7 +++++++ app/templates/scolar/index.j2 | 8 +++++++- app/views/notes.py | 34 +++++++++++++++++++++------------- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/app/but/jury_but.py b/app/but/jury_but.py index fe670d70e..87bbe4721 100644 --- a/app/but/jury_but.py +++ b/app/but/jury_but.py @@ -77,7 +77,7 @@ from app.models.but_refcomp import ( ApcNiveau, ApcParcours, ) -from app.models import Evaluation, Scolog, ScolarAutorisationInscription +from app.models import Evaluation, ModuleImpl, Scolog, ScolarAutorisationInscription from app.models.but_validations import ( ApcValidationAnnee, ApcValidationRCUE, @@ -796,16 +796,33 @@ class DecisionsProposeesAnnee(DecisionsProposees): if self.formsemestre_pair is not None: sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre_pair.id) - def has_notes_en_attente(self) -> bool: - "Vrai si l'étudiant a au moins une note en attente dans le semestre origine de ce deca" - res = ( + def _get_current_res(self) -> ResultatsSemestreBUT: + "Les res. du semestre d'origine du deca" + return ( self.res_pair if self.formsemestre_pair and (self.formsemestre.id == self.formsemestre_pair.id) else self.res_impair ) + + def has_notes_en_attente(self) -> bool: + "Vrai si l'étudiant a au moins une note en attente dans le semestre origine de ce deca" + res = self._get_current_res() return res and self.etud.id in res.get_etudids_attente() + def get_modimpls_attente(self) -> list[ModuleImpl]: + "Liste des ModuleImpl dans lesquels l'étudiant à au moins une note en ATTente" + res = self._get_current_res() + modimpls_results = [ + modimpl_result + for modimpl_result in res.modimpls_results.values() + if self.etud.id in modimpl_result.etudids_attente + ] + modimpls = [ + db.session.get(ModuleImpl, mr.moduleimpl_id) for mr in modimpls_results + ] + return sorted(modimpls, key=lambda mi: (mi.module.numero, mi.module.code)) + def record_all(self, only_validantes: bool = False) -> bool: """Enregistre les codes qui n'ont pas été spécifiés par le formulaire, et sont donc en mode "automatique". diff --git a/app/static/css/jury_but.css b/app/static/css/jury_but.css index c75c1a50c..525c532f0 100644 --- a/app/static/css/jury_but.css +++ b/app/static/css/jury_but.css @@ -19,6 +19,13 @@ font-weight: bold; } +ul.modimpls_att { + margin-top: 8px; + margin-left: 32px; + padding-top: 0; + color: black; +} + .jury_but h3 { margin-top: 0px; } diff --git a/app/templates/scolar/index.j2 b/app/templates/scolar/index.j2 index c5c243f2b..8b93dee0a 100644 --- a/app/templates/scolar/index.j2 +++ b/app/templates/scolar/index.j2 @@ -16,6 +16,10 @@ table.listesems tr td.titresem { font-weight: bold; font-size: 110%; } +div.semlist { + padding-right: 8px; +} + table.semlist tr td.datesem { text-align: center; white-space: nowrap; @@ -113,7 +117,9 @@ table.semlist tbody tr td.modalite { url_for('scolar.export_table_dept_formsemestres', scodoc_dept=g.scodoc_dept) }}">{{scu.ICON_XLS|safe}}</a> </summary> - {{ html_table_formsemestres|safe }} + <div class="semlist"> + {{ html_table_formsemestres|safe }} + </div> </details> {% else %} <p><a class="stdlink" href="{{ diff --git a/app/views/notes.py b/app/views/notes.py index 317e71a9e..ea190b4f1 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -2393,17 +2393,16 @@ def formsemestre_validation_but( <div class="bull_head"> <div> <div class="titre_parcours">Jury BUT</div> - <div class="nom_etud">{etud.nomprenom}</div> + <div class="nom_etud">{etud.html_link_fiche()}</div> </div> <div class="bull_photo"><a href="{ - url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id) + etud.url_fiche() }">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a> </div> </div> <div class="warning">Impossible de statuer sur cet étudiant: il est démissionnaire ou défaillant (voir <a class="stdlink" href="{ - url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid) - }">sa fiche</a>) + etud.url_fiche()}">sa fiche</a>) </div> </div> {navigation_div} @@ -2461,17 +2460,27 @@ def formsemestre_validation_but( inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id) if (not inscription) or inscription.etat != scu.INSCRIT: etat_ins = scu.ETATS_INSCRIPTION.get(inscription.etat, "inconnu?") - warning += f"""<div class="warning">{etat_ins} en S{deca.formsemestre_impair.semestre_id}</div>""" + warning += f"""<div class="warning">{etat_ins} + en S{deca.formsemestre_impair.semestre_id}</div>""" if deca.formsemestre_pair: inscription = deca.formsemestre_pair.etuds_inscriptions.get(etud.id) if (not inscription) or inscription.etat != scu.INSCRIT: etat_ins = scu.ETATS_INSCRIPTION.get(inscription.etat, "inconnu?") - warning += f"""<div class="warning">{etat_ins} en S{deca.formsemestre_pair.semestre_id}</div>""" + warning += f"""<div class="warning">{etat_ins} + en S{deca.formsemestre_pair.semestre_id}</div>""" if has_notes_en_attente: - warning += f"""<div class="warning-bloquant">{etud.nomprenom} a des notes en ATTente. - Vous devez régler cela avant de statuer en jury !</div>""" + warning += f"""<div class="warning-bloquant">{etud.html_link_fiche() + } a des notes en ATTente dans les modules suivants. + Vous devez régler cela avant de statuer en jury ! + <ul class="modimpls_att"> + """ + for modimpl in deca.get_modimpls_attente(): + warning += f"""<li><a href="{ + url_for("notes.moduleimpl_status", scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id) + }" class="stdlink">{modimpl.module.code} {modimpl.module.titre_str()}</a></li>""" + warning += "</ul></div>" if evaluations_a_debloquer: links_evals = [ f"""<a class="stdlink" href="{url_for( @@ -2484,6 +2493,8 @@ def formsemestre_validation_but( voir {", ".join(links_evals)} """ + if warning: + warning = f"""<div class="jury_but_warning jury_but_box">{warning}</div>""" H.append( f""" <div> @@ -2492,16 +2503,13 @@ def formsemestre_validation_but( <div class="titre_parcours">Jury BUT{deca.annee_but} - Parcours {(deca.parcour.libelle if deca.parcour else False) or "non spécifié"} - {deca.annee_scolaire_str()}</div> - <div class="nom_etud">{etud.nomprenom}</div> + <div class="nom_etud">{etud.html_link_fiche()}</div> </div> <div class="bull_photo"><a href="{ - url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id) - }">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a> + etud.url_fiche()}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a> </div> </div> - <div class="jury_but_warning jury_but_box"> {warning} - </div> </div> <form method="post" class="jury_but_box" id="jury_but">