Jury BUT auto: avertissement si semestres pairs non bloqués

This commit is contained in:
Emmanuel Viennet 2024-03-22 21:56:52 +01:00
parent 46c86d2928
commit 2367984848
3 changed files with 55 additions and 8 deletions

View File

@ -16,8 +16,8 @@ from app.scodoc.sco_exceptions import ScoValueError
def formsemestre_validation_auto_but( def formsemestre_validation_auto_but(
formsemestre: FormSemestre, only_adm: bool = True formsemestre: FormSemestre, only_adm: bool = True, dry_run=False
) -> int: ) -> tuple[int, list[jury_but.DecisionsProposeesAnnee]]:
"""Calcul automatique des décisions de jury sur une "année" BUT. """Calcul automatique des décisions de jury sur une "année" BUT.
- N'enregistre jamais de décisions de l'année scolaire précédente, même - N'enregistre jamais de décisions de l'année scolaire précédente, même
@ -27,16 +27,22 @@ def formsemestre_validation_auto_but(
En revanche, si only_adm est faux, on enregistre la première décision proposée par ScoDoc En revanche, si only_adm est faux, on enregistre la première décision proposée par ScoDoc
(mode à n'utiliser que pour les tests unitaires vérifiant la saisie des jurys) (mode à n'utiliser que pour les tests unitaires vérifiant la saisie des jurys)
Returns: nombre d'étudiants pour lesquels on a enregistré au moins un code. Returns:
- En mode normal, (nombre d'étudiants pour lesquels on a enregistré au moins un code, []])
- En mode dry_run, (0, list[DecisionsProposeesAnnee])
""" """
if not formsemestre.formation.is_apc(): if not formsemestre.formation.is_apc():
raise ScoValueError("fonction réservée aux formations BUT") raise ScoValueError("fonction réservée aux formations BUT")
nb_etud_modif = 0 nb_etud_modif = 0
decas = []
with sco_cache.DeferredSemCacheManager(): with sco_cache.DeferredSemCacheManager():
for etudid in formsemestre.etuds_inscriptions: for etudid in formsemestre.etuds_inscriptions:
etud = Identite.get_etud(etudid) etud = Identite.get_etud(etudid)
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre) deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
nb_etud_modif += deca.record_all(only_validantes=only_adm) if not dry_run:
nb_etud_modif += deca.record_all(only_validantes=only_adm)
else:
decas.append(deca)
db.session.commit() db.session.commit()
ScolarNews.add( ScolarNews.add(
@ -49,4 +55,4 @@ def formsemestre_validation_auto_but(
formsemestre_id=formsemestre.id, formsemestre_id=formsemestre.id,
), ),
) )
return nb_etud_modif return nb_etud_modif, decas

View File

@ -12,7 +12,7 @@
<h2>Calcul automatique des décisions de jury du BUT</h2> <h2>Calcul automatique des décisions de jury du BUT</h2>
<ul> <ul>
<li>N'enregistre jamais de décisions de l'année scolaire précédente, même <li>N'enregistre jamais de décisions de l'année scolaire précédente, même
si on a des RCUE "à cheval" sur deux années. si on a des RCUEs "à cheval" sur deux années.
</li> </li>
<li><b>Attention: peut modifier des décisions déjà enregistrées</b>, si la <li><b>Attention: peut modifier des décisions déjà enregistrées</b>, si la
@ -47,6 +47,20 @@
</div> </div>
{% if formsemestres_suspects %}
<div class="scobox">
<div class="scobox-title">Attention</div>
<div class="warning">Les semestres pairs suivants vont être pris en compte, mais ils sont postérieurs et n'ont pas leurs moyennes bloquées
(voir la documentation sur les jurys BUT).
</div>
<ul>
{% for formsemestre in formsemestres_suspects.values() %}
<li>{{ formsemestre.html_link_status() | safe }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="row"> <div class="row">
<div class="col-md-10"> <div class="col-md-10">
{{ wtf.quick_form(form) }} {{ wtf.quick_form(form) }}

View File

@ -30,6 +30,7 @@ Module notes: issu de ScoDoc7 / ZNotes.py
Emmanuel Viennet, 2021 Emmanuel Viennet, 2021
""" """
import datetime
import html import html
from operator import itemgetter from operator import itemgetter
import time import time
@ -2449,6 +2450,12 @@ def formsemestre_validation_but(
warning += ( warning += (
"""<div class="warning">L'étudiant n'est pas inscrit à un parcours.</div>""" """<div class="warning">L'étudiant n'est pas inscrit à un parcours.</div>"""
) )
if formsemestre.date_fin - datetime.date.today() > datetime.timedelta(days=12):
# encore loin de la fin du semestre de départ de ce jury ?
warning += f"""<div class="warning">Le semestre S{formsemestre.semestre_id}
terminera le {formsemestre.date_fin.strftime("%d/%m/%Y")}&nbsp;:
êtes-vous certain de vouloir enregistrer une décision de jury&nbsp;?
</div>"""
if deca.formsemestre_impair: if deca.formsemestre_impair:
inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id) inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id)
@ -2614,13 +2621,17 @@ def formsemestre_validation_auto_but(formsemestre_id: int = None):
formsemestre_id=formsemestre_id, formsemestre_id=formsemestre_id,
) )
) )
if not formsemestre.formation.is_apc():
raise ScoValueError(
"formsemestre_validation_auto_but est réservé aux formations APC"
)
formsemestre = FormSemestre.get_formsemestre(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
form = jury_but_forms.FormSemestreValidationAutoBUTForm() form = jury_but_forms.FormSemestreValidationAutoBUTForm()
if request.method == "POST": if request.method == "POST":
if not form.cancel.data: if not form.cancel.data:
nb_etud_modif = jury_but_validation_auto.formsemestre_validation_auto_but( nb_etud_modif, _ = (
formsemestre jury_but_validation_auto.formsemestre_validation_auto_but(formsemestre)
) )
flash(f"Décisions enregistrées ({nb_etud_modif} étudiants modifiés)") flash(f"Décisions enregistrées ({nb_etud_modif} étudiants modifiés)")
return redirect( return redirect(
@ -2631,9 +2642,25 @@ def formsemestre_validation_auto_but(formsemestre_id: int = None):
mode_jury=1, mode_jury=1,
) )
) )
# Avertissement si formsemestre impair
formsemestres_suspects = {}
if formsemestre.semestre_id % 2:
_, decas = jury_but_validation_auto.formsemestre_validation_auto_but(
formsemestre, dry_run=True
)
# regarde si il y a des semestres pairs postérieurs qui ne soient pas bloqués
formsemestres_suspects = {
deca.formsemestre_pair.id: deca.formsemestre_pair
for deca in decas
if deca.formsemestre_pair
and deca.formsemestre_pair.date_debut > formsemestre.date_debut
and not deca.formsemestre_pair.block_moyennes
}
return render_template( return render_template(
"but/formsemestre_validation_auto_but.j2", "but/formsemestre_validation_auto_but.j2",
form=form, form=form,
formsemestres_suspects=formsemestres_suspects,
sco=ScoData(formsemestre=formsemestre), sco=ScoData(formsemestre=formsemestre),
title="Calcul automatique jury BUT", title="Calcul automatique jury BUT",
) )