Assiduité : limitation ajout_assiduites_etud sur semestre + visu_assi_group lien ajout closes #908

This commit is contained in:
Iziram 2024-05-31 11:10:04 +02:00
parent 07a8658672
commit 675eccd6b6
2 changed files with 52 additions and 19 deletions

View File

@ -8,6 +8,7 @@
import datetime import datetime
from flask import g, url_for from flask import g, url_for
from flask_login import current_user
from app import log from app import log
from app.models import FormSemestre, Identite, Justificatif from app.models import FormSemestre, Identite, Justificatif
from app.tables import table_builder as tb from app.tables import table_builder as tb
@ -15,6 +16,7 @@ from app.scodoc import sco_preferences
from app.scodoc import sco_utils as scu from app.scodoc import sco_utils as scu
import app.scodoc.sco_assiduites as scass import app.scodoc.sco_assiduites as scass
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc.sco_permissions import Permission
class TableAssi(tb.Table): class TableAssi(tb.Table):
@ -171,6 +173,20 @@ class RowAssi(tb.Row):
"justificatifs", "Justificatifs", fmt_num(compte_justificatifs.count()) "justificatifs", "Justificatifs", fmt_num(compte_justificatifs.count())
) )
if current_user.has_permission(Permission.AbsChange):
ajout_url: str = url_for(
"assiduites.ajout_assiduite_etud",
scodoc_dept=g.scodoc_dept,
etudid=etud.id,
formsemestre_id=self.table.formsemestre.id,
)
self.add_cell(
"lien_ajout",
"",
f"<a href='{ajout_url}' class='stdlink'>signaler assiduité</a>",
no_excel=True,
)
def _get_etud_stats(self, etud: Identite) -> dict[str, list[str, float, float]]: def _get_etud_stats(self, etud: Identite) -> dict[str, list[str, float, float]]:
""" """
Renvoie le comptage (dans la métrique du département) des différents états Renvoie le comptage (dans la métrique du département) des différents états

View File

@ -225,6 +225,18 @@ def ajout_assiduite_etud() -> str | Response:
etudid: int = request.args.get("etudid", -1) etudid: int = request.args.get("etudid", -1)
etud = Identite.get_etud(etudid) etud = Identite.get_etud(etudid)
formsemestre_id = request.args.get("formsemestre_id", None)
# Gestion du semestre
formsemestre: FormSemestre | None = None
sems_etud: list[FormSemestre] = etud.get_formsemestres()
if formsemestre_id:
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
formsemestre = formsemestre if formsemestre in sems_etud else None
else:
formsemestre = [sem for sem in sems_etud if sem.est_courant()]
formsemestre = formsemestre[0] if formsemestre else None
# Gestion évaluations (appel à la page depuis les évaluations) # Gestion évaluations (appel à la page depuis les évaluations)
evaluation_id: int | None = request.args.get("evaluation_id") evaluation_id: int | None = request.args.get("evaluation_id")
saisie_eval = evaluation_id is not None saisie_eval = evaluation_id is not None
@ -246,26 +258,22 @@ def ajout_assiduite_etud() -> str | Response:
modimpls_by_formsemestre = etud.get_modimpls_by_formsemestre(scu.annee_scolaire()) modimpls_by_formsemestre = etud.get_modimpls_by_formsemestre(scu.annee_scolaire())
choices: OrderedDict = OrderedDict() choices: OrderedDict = OrderedDict()
choices[""] = [("", "Non spécifié"), ("autre", "Autre module (pas dans la liste)")] choices[""] = [("", "Non spécifié"), ("autre", "Autre module (pas dans la liste)")]
for formsemestre_id in modimpls_by_formsemestre:
formsemestre: FormSemestre = FormSemestre.query.get(formsemestre_id)
# indique le nom du semestre dans le menu (optgroup) # indique le nom du semestre dans le menu (optgroup)
group_name: str = formsemestre.titre_annee() group_name: str = formsemestre.titre_annee()
choices[group_name] = [ choices[group_name] = [
(m.id, f"{m.module.code} {m.module.abbrev or m.module.titre or ''}") (m.id, f"{m.module.code} {m.module.abbrev or m.module.titre or ''}")
for m in modimpls_by_formsemestre[formsemestre_id] for m in modimpls_by_formsemestre[formsemestre.id]
if m.module.ue.type == UE_STANDARD if m.module.ue.type == UE_STANDARD
] ]
if formsemestre.est_courant():
choices.move_to_end(group_name, last=False)
choices.move_to_end("", last=False) choices.move_to_end("", last=False)
form.modimpl.choices = choices form.modimpl.choices = choices
force_options: dict = None force_options: dict = None
if form.validate_on_submit(): if form.validate_on_submit():
if form.cancel.data: # cancel button if form.cancel.data: # cancel button
return redirect(redirect_url) return redirect(redirect_url)
ok = _record_assiduite_etud(etud, form) ok = _record_assiduite_etud(etud, form, formsemestre=formsemestre)
if ok: if ok:
flash("enregistré") flash("enregistré")
return redirect(redirect_url) return redirect(redirect_url)
@ -293,7 +301,7 @@ def ajout_assiduite_etud() -> str | Response:
form=form, form=form,
moduleimpl_id=moduleimpl_id, moduleimpl_id=moduleimpl_id,
redirect_url=redirect_url, redirect_url=redirect_url,
sco=ScoData(etud), sco=ScoData(etud, formsemestre=formsemestre),
tableau=tableau, tableau=tableau,
scu=scu, scu=scu,
) )
@ -303,6 +311,7 @@ def _get_dates_from_assi_form(
form: AjoutAssiOrJustForm, form: AjoutAssiOrJustForm,
etud: Identite, etud: Identite,
from_justif: bool = False, from_justif: bool = False,
formsemestre: FormSemestre | None = None,
) -> tuple[ ) -> tuple[
bool, datetime.datetime | None, datetime.datetime | None, datetime.datetime | None bool, datetime.datetime | None, datetime.datetime | None, datetime.datetime | None
]: ]:
@ -395,9 +404,11 @@ def _get_dates_from_assi_form(
dt_fin_tz_server = dt_fin_tz_server.replace(hour=23, minute=59) dt_fin_tz_server = dt_fin_tz_server.replace(hour=23, minute=59)
# Vérification dates contenu dans un semestre de l'étudiant # Vérification dates contenu dans un semestre de l'étudiant
dates_semestres: list[tuple[datetime.date, datetime.date]] = [ dates_semestres: list[tuple[datetime.date, datetime.date]] = (
(sem.date_debut, sem.date_fin) for sem in etud.get_formsemestres() [(sem.date_debut, sem.date_fin) for sem in etud.get_formsemestres()]
] if formsemestre is None
else [(formsemestre.date_debut, formsemestre.date_fin)]
)
# Vérification date début # Vérification date début
if not any( if not any(
@ -407,7 +418,9 @@ def _get_dates_from_assi_form(
] ]
): ):
form.set_error( form.set_error(
"La date de début n'appartient à aucun semestre de l'étudiant", "La date de début n'appartient à aucun semestre de l'étudiant"
if formsemestre is None
else "La date de début n'appartient pas au semestre",
form.date_debut, form.date_debut,
) )
@ -419,7 +432,10 @@ def _get_dates_from_assi_form(
] ]
): ):
form.set_error( form.set_error(
"La date de fin n'appartient à aucun semestre de l'étudiant", form.date_fin "La date de fin n'appartient à aucun semestre de l'étudiant"
if not formsemestre
else "La date de fin n'appartient pas au semestre",
form.date_fin,
) )
dt_entry_date_tz_server = ( dt_entry_date_tz_server = (
@ -431,6 +447,7 @@ def _get_dates_from_assi_form(
def _record_assiduite_etud( def _record_assiduite_etud(
etud: Identite, etud: Identite,
form: AjoutAssiduiteEtudForm, form: AjoutAssiduiteEtudForm,
formsemestre: FormSemestre | None = None,
) -> bool: ) -> bool:
"""Enregistre les données du formulaire de saisie assiduité. """Enregistre les données du formulaire de saisie assiduité.
Returns ok if successfully recorded, else put error info in the form. Returns ok if successfully recorded, else put error info in the form.
@ -444,7 +461,7 @@ def _record_assiduite_etud(
dt_debut_tz_server, dt_debut_tz_server,
dt_fin_tz_server, dt_fin_tz_server,
dt_entry_date_tz_server, dt_entry_date_tz_server,
) = _get_dates_from_assi_form(form, etud) ) = _get_dates_from_assi_form(form, etud, formsemestre=formsemestre)
# Le module (avec "autre") # Le module (avec "autre")
mod_data = form.modimpl.data mod_data = form.modimpl.data
if mod_data: if mod_data: