Jury BUT: affiche la liste des modules avec note en ATTente

This commit is contained in:
Emmanuel Viennet 2024-03-23 13:23:26 +01:00
parent 12256dc3d4
commit fa0417f0b1
4 changed files with 56 additions and 18 deletions

View File

@ -77,7 +77,7 @@ from app.models.but_refcomp import (
ApcNiveau, ApcNiveau,
ApcParcours, ApcParcours,
) )
from app.models import Evaluation, Scolog, ScolarAutorisationInscription from app.models import Evaluation, ModuleImpl, Scolog, ScolarAutorisationInscription
from app.models.but_validations import ( from app.models.but_validations import (
ApcValidationAnnee, ApcValidationAnnee,
ApcValidationRCUE, ApcValidationRCUE,
@ -796,16 +796,33 @@ class DecisionsProposeesAnnee(DecisionsProposees):
if self.formsemestre_pair is not None: if self.formsemestre_pair is not None:
sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre_pair.id) sco_cache.invalidate_formsemestre(formsemestre_id=self.formsemestre_pair.id)
def has_notes_en_attente(self) -> bool: def _get_current_res(self) -> ResultatsSemestreBUT:
"Vrai si l'étudiant a au moins une note en attente dans le semestre origine de ce deca" "Les res. du semestre d'origine du deca"
res = ( return (
self.res_pair self.res_pair
if self.formsemestre_pair if self.formsemestre_pair
and (self.formsemestre.id == self.formsemestre_pair.id) and (self.formsemestre.id == self.formsemestre_pair.id)
else self.res_impair 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() 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: def record_all(self, only_validantes: bool = False) -> bool:
"""Enregistre les codes qui n'ont pas été spécifiés par le formulaire, """Enregistre les codes qui n'ont pas été spécifiés par le formulaire,
et sont donc en mode "automatique". et sont donc en mode "automatique".

View File

@ -19,6 +19,13 @@
font-weight: bold; font-weight: bold;
} }
ul.modimpls_att {
margin-top: 8px;
margin-left: 32px;
padding-top: 0;
color: black;
}
.jury_but h3 { .jury_but h3 {
margin-top: 0px; margin-top: 0px;
} }

View File

@ -16,6 +16,10 @@ table.listesems tr td.titresem {
font-weight: bold; font-weight: bold;
font-size: 110%; font-size: 110%;
} }
div.semlist {
padding-right: 8px;
}
table.semlist tr td.datesem { table.semlist tr td.datesem {
text-align: center; text-align: center;
white-space: nowrap; 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) url_for('scolar.export_table_dept_formsemestres', scodoc_dept=g.scodoc_dept)
}}">{{scu.ICON_XLS|safe}}</a> }}">{{scu.ICON_XLS|safe}}</a>
</summary> </summary>
{{ html_table_formsemestres|safe }} <div class="semlist">
{{ html_table_formsemestres|safe }}
</div>
</details> </details>
{% else %} {% else %}
<p><a class="stdlink" href="{{ <p><a class="stdlink" href="{{

View File

@ -2393,17 +2393,16 @@ def formsemestre_validation_but(
<div class="bull_head"> <div class="bull_head">
<div> <div>
<div class="titre_parcours">Jury BUT</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>
<div class="bull_photo"><a href="{ <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> }">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a>
</div> </div>
</div> </div>
<div class="warning">Impossible de statuer sur cet étudiant: <div class="warning">Impossible de statuer sur cet étudiant:
il est démissionnaire ou défaillant (voir <a class="stdlink" href="{ il est démissionnaire ou défaillant (voir <a class="stdlink" href="{
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid) etud.url_fiche()}">sa fiche</a>)
}">sa fiche</a>)
</div> </div>
</div> </div>
{navigation_div} {navigation_div}
@ -2461,17 +2460,27 @@ def formsemestre_validation_but(
inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id) inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id)
if (not inscription) or inscription.etat != scu.INSCRIT: if (not inscription) or inscription.etat != scu.INSCRIT:
etat_ins = scu.ETATS_INSCRIPTION.get(inscription.etat, "inconnu?") 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: if deca.formsemestre_pair:
inscription = deca.formsemestre_pair.etuds_inscriptions.get(etud.id) inscription = deca.formsemestre_pair.etuds_inscriptions.get(etud.id)
if (not inscription) or inscription.etat != scu.INSCRIT: if (not inscription) or inscription.etat != scu.INSCRIT:
etat_ins = scu.ETATS_INSCRIPTION.get(inscription.etat, "inconnu?") 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: if has_notes_en_attente:
warning += f"""<div class="warning-bloquant">{etud.nomprenom} a des notes en ATTente. warning += f"""<div class="warning-bloquant">{etud.html_link_fiche()
Vous devez régler cela avant de statuer en jury !</div>""" } 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: if evaluations_a_debloquer:
links_evals = [ links_evals = [
f"""<a class="stdlink" href="{url_for( f"""<a class="stdlink" href="{url_for(
@ -2484,6 +2493,8 @@ def formsemestre_validation_but(
voir {", ".join(links_evals)} voir {", ".join(links_evals)}
""" """
if warning:
warning = f"""<div class="jury_but_warning jury_but_box">{warning}</div>"""
H.append( H.append(
f""" f"""
<div> <div>
@ -2492,16 +2503,13 @@ def formsemestre_validation_but(
<div class="titre_parcours">Jury BUT{deca.annee_but} <div class="titre_parcours">Jury BUT{deca.annee_but}
- Parcours {(deca.parcour.libelle if deca.parcour else False) or "non spécifié"} - Parcours {(deca.parcour.libelle if deca.parcour else False) or "non spécifié"}
- {deca.annee_scolaire_str()}</div> - {deca.annee_scolaire_str()}</div>
<div class="nom_etud">{etud.nomprenom}</div> <div class="nom_etud">{etud.html_link_fiche()}</div>
</div> </div>
<div class="bull_photo"><a href="{ <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>
}">{etud.photo_html(title="fiche de " + etud.nomprenom)}</a>
</div> </div>
</div> </div>
<div class="jury_but_warning jury_but_box">
{warning} {warning}
</div>
</div> </div>
<form method="post" class="jury_but_box" id="jury_but"> <form method="post" class="jury_but_box" id="jury_but">