forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -47,7 +47,19 @@ class AjoutAssiOrJustForm(FlaskForm):
|
||||
assiduité et justificatif
|
||||
"""
|
||||
|
||||
error_message = "" # used to report our errors
|
||||
def __init__(self, *args, **kwargs):
|
||||
"Init form, adding a filed for our error messages"
|
||||
super().__init__(*args, **kwargs)
|
||||
self.ok = True
|
||||
self.error_messages: list[str] = [] # used to report our errors
|
||||
|
||||
def set_error(self, err_msg, field=None):
|
||||
"Set error message both in form and field"
|
||||
self.ok = False
|
||||
self.error_messages.append(err_msg)
|
||||
if field:
|
||||
field.errors.append(err_msg)
|
||||
|
||||
date_debut = StringField(
|
||||
"Date de début",
|
||||
validators=[validators.Length(max=10)],
|
||||
|
@ -148,6 +148,9 @@ class Assiduite(db.Model):
|
||||
# Vérification de non duplication des périodes
|
||||
assiduites: Query = etud.assiduites
|
||||
if is_period_conflicting(date_debut, date_fin, assiduites, Assiduite):
|
||||
log(
|
||||
f"create_assiduite: period_conflicting etudid={etud.id} date_debut={date_debut} date_fin={date_fin}"
|
||||
)
|
||||
raise ScoValueError(
|
||||
"Duplication: la période rentre en conflit avec une plage enregistrée"
|
||||
)
|
||||
@ -215,10 +218,10 @@ class Assiduite(db.Model):
|
||||
# ci-dessous un fix temporaire en attendant explication de @iziram
|
||||
try:
|
||||
moduleimpl_id_int = int(moduleimpl_id)
|
||||
except ValueError:
|
||||
raise ScoValueError("invalid moduleimpl_id")
|
||||
except ValueError as exc:
|
||||
raise ScoValueError("invalid moduleimpl_id") from exc
|
||||
# /fix
|
||||
moduleimpl: ModuleImpl = ModuleImpl.query.get(moduleimpl_id)
|
||||
moduleimpl: ModuleImpl = ModuleImpl.query.get(moduleimpl_id_int)
|
||||
if moduleimpl is not None:
|
||||
# Vérification de l'inscription de l'étudiant
|
||||
if moduleimpl.est_inscrit(self.etudiant):
|
||||
|
@ -194,9 +194,9 @@ class ModuleImpl(db.Model):
|
||||
|
||||
def est_inscrit(self, etud: Identite) -> bool:
|
||||
"""
|
||||
Vérifie si l'étudiant est bien inscrit au moduleimpl
|
||||
|
||||
Retourne Vrai si c'est le cas, faux sinon
|
||||
Vérifie si l'étudiant est bien inscrit au moduleimpl (même si DEM ou DEF au semestre).
|
||||
(lent, pas de cache: pour un accès rapide, utiliser nt.modimpl_inscr_df).
|
||||
Retourne Vrai si inscrit au module, faux sinon.
|
||||
"""
|
||||
|
||||
is_module: int = (
|
||||
|
@ -53,11 +53,11 @@ div.submit > input {
|
||||
<div class="tab-content">
|
||||
<h2>Signaler une absence, retard ou présence pour {{etud.html_link_fiche()|safe}}</h2>
|
||||
|
||||
{% if form.error_message %}
|
||||
{% for err_msg in form.error_messages %}
|
||||
<div class="wtf-error-messages">
|
||||
{{ form.error_message }}
|
||||
{{ err_msg }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<form id="ajout-assiduite-etud" method="post">
|
||||
{{ form.hidden_tag() }}
|
||||
|
@ -28,6 +28,12 @@ div.submit > input {
|
||||
|
||||
<section class="justi-form page">
|
||||
|
||||
{% for err_msg in form.error_messages %}
|
||||
<div class="wtf-error-messages">
|
||||
{{ err_msg }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<form id="ajout-justificatif-etud" method="post">
|
||||
<fieldset>
|
||||
{{ form.hidden_tag() }}
|
||||
|
@ -257,7 +257,7 @@ def bilan_dept():
|
||||
@bp.route("/ajout_assiduite_etud", methods=["GET", "POST"])
|
||||
@scodoc
|
||||
@permission_required(Permission.AbsChange)
|
||||
def ajout_assiduite_etud() -> str:
|
||||
def ajout_assiduite_etud() -> str | Response:
|
||||
"""
|
||||
ajout_assiduite_etud Saisie d'une assiduité d'un étudiant
|
||||
|
||||
@ -270,13 +270,13 @@ def ajout_assiduite_etud() -> str:
|
||||
Returns:
|
||||
str: l'html généré
|
||||
"""
|
||||
etudid = request.args.get("etudid", -1)
|
||||
etudid: int = request.args.get("etudid", -1)
|
||||
etud = Identite.get_etud(etudid)
|
||||
|
||||
# Gestion évaluations (appel à la page depuis les évaluations)
|
||||
evaluation_id: int = request.args.get("evaluation_id")
|
||||
evaluation_id: int | None = request.args.get("evaluation_id")
|
||||
saisie_eval = evaluation_id is not None
|
||||
moduleimpl_id: int = request.args.get("moduleimpl_id", "")
|
||||
moduleimpl_id: int | None = request.args.get("moduleimpl_id", "")
|
||||
|
||||
redirect_url: str = (
|
||||
"#"
|
||||
@ -340,13 +340,14 @@ def ajout_assiduite_etud() -> str:
|
||||
|
||||
def _get_dates_from_assi_form(
|
||||
form: AjoutAssiOrJustForm,
|
||||
) -> tuple[bool, datetime.datetime, datetime.datetime, datetime.datetime]:
|
||||
) -> tuple[
|
||||
bool, datetime.datetime | None, datetime.datetime | None, datetime.datetime | None
|
||||
]:
|
||||
"""Prend les dates et heures du form, les vérifie
|
||||
puis converti en deux datetime, en timezone du serveur.
|
||||
Ramène ok=True si ok.
|
||||
Met des messages d'erreur dans le form.
|
||||
"""
|
||||
ok = True
|
||||
debut_jour = "00:00"
|
||||
fin_jour = "23:59:59"
|
||||
date_fin = None
|
||||
@ -355,8 +356,7 @@ def _get_dates_from_assi_form(
|
||||
date_debut = datetime.datetime.strptime(form.date_debut.data, "%d/%m/%Y")
|
||||
except ValueError:
|
||||
date_debut = None
|
||||
form.date_debut.errors.append("date début invalide")
|
||||
ok = False
|
||||
form.set_error("date début invalide", form.date_debut)
|
||||
try:
|
||||
date_fin = (
|
||||
datetime.datetime.strptime(form.date_fin.data, "%d/%m/%Y")
|
||||
@ -365,8 +365,7 @@ def _get_dates_from_assi_form(
|
||||
)
|
||||
except ValueError:
|
||||
date_fin = None
|
||||
form.date_fin.errors.append("date fin invalide")
|
||||
ok = False
|
||||
form.set_error("date fin invalide", form.date_fin)
|
||||
|
||||
if date_fin:
|
||||
# ignore les heures si plusieurs jours
|
||||
@ -378,38 +377,42 @@ def _get_dates_from_assi_form(
|
||||
form.heure_debut.data or debut_jour
|
||||
)
|
||||
except ValueError:
|
||||
form.heure_debut.errors.append("heure début invalide")
|
||||
ok = False
|
||||
form.set_error("heure début invalide", form.heure_debut)
|
||||
if bool(form.heure_debut.data) != bool(form.heure_fin.data):
|
||||
form.set_error(
|
||||
"Les deux heures début et fin doivent être spécifiées, ou aucune"
|
||||
)
|
||||
try:
|
||||
heure_fin = datetime.time.fromisoformat(form.heure_fin.data or fin_jour)
|
||||
except ValueError:
|
||||
form.heure_fin.errors.append("heure fin invalide")
|
||||
ok = False
|
||||
form.set_error("heure fin invalide", form.heure_fin)
|
||||
|
||||
if not form.ok:
|
||||
return False, None, None, None
|
||||
|
||||
# Vérifie cohérence des dates/heures
|
||||
dt_debut = (
|
||||
datetime.datetime.combine(date_debut, heure_debut) if date_debut else None
|
||||
)
|
||||
dt_fin = (
|
||||
datetime.datetime.combine(date_fin or date_debut, heure_fin)
|
||||
if (date_fin or date_debut)
|
||||
else None
|
||||
)
|
||||
if ok and dt_fin <= dt_debut:
|
||||
form.errors["general_errors"] = ["Erreur: dates début/fin incohérentes"]
|
||||
ok = False
|
||||
dt_debut = datetime.datetime.combine(date_debut, heure_debut)
|
||||
dt_fin = datetime.datetime.combine(date_fin or date_debut, heure_fin)
|
||||
if dt_fin <= dt_debut:
|
||||
form.set_error("dates début/fin incohérentes")
|
||||
# La date de dépot (si vide, la date actuelle)
|
||||
dt_entry_date = (
|
||||
datetime.datetime.strptime(form.entry_date.data, "%d/%m/%Y")
|
||||
if form.entry_date.data
|
||||
else None
|
||||
)
|
||||
try:
|
||||
dt_entry_date = (
|
||||
datetime.datetime.strptime(form.entry_date.data, "%d/%m/%Y")
|
||||
if form.entry_date.data
|
||||
else None
|
||||
)
|
||||
except ValueError:
|
||||
dt_entry_date = None
|
||||
form.set_error("format de date de dépôt invalide", form.entry_date)
|
||||
|
||||
# Ajoute time zone serveur
|
||||
dt_debut_tz_server = scu.TIME_ZONE.localize(dt_debut) if dt_debut else None
|
||||
dt_fin_tz_server = scu.TIME_ZONE.localize(dt_fin) if dt_fin else None
|
||||
dt_debut_tz_server = scu.TIME_ZONE.localize(dt_debut)
|
||||
dt_fin_tz_server = scu.TIME_ZONE.localize(dt_fin)
|
||||
dt_entry_date_tz_server = (
|
||||
scu.TIME_ZONE.localize(dt_entry_date) if dt_entry_date else None
|
||||
)
|
||||
return ok, dt_debut_tz_server, dt_fin_tz_server, dt_entry_date_tz_server
|
||||
return form.ok, dt_debut_tz_server, dt_fin_tz_server, dt_entry_date_tz_server
|
||||
|
||||
|
||||
def _record_assiduite_etud(
|
||||
@ -472,7 +475,7 @@ def _record_assiduite_etud(
|
||||
db.session.commit()
|
||||
return True
|
||||
except ScoValueError as exc:
|
||||
form.error_message = f"Erreur: {exc.args[0]}"
|
||||
form.set_error(f"Erreur: {exc.args[0]}")
|
||||
return False
|
||||
|
||||
|
||||
@ -693,7 +696,7 @@ def _record_justificatif_etud(
|
||||
return True
|
||||
except ScoValueError as exc:
|
||||
db.session.rollback()
|
||||
form.error_message = f"Erreur: {exc.args[0]}"
|
||||
form.set_error(f"Erreur: {exc.args[0]}")
|
||||
return False
|
||||
|
||||
|
||||
@ -725,7 +728,7 @@ def _upload_justificatif_files(
|
||||
log(
|
||||
f"_upload_justificatif_files: error on {file.filename} for etud {just.etudid}"
|
||||
)
|
||||
form.error_message = f"Erreur sur fichier justificatif: {exc.args[0]}"
|
||||
form.set_error(f"Erreur sur fichier justificatif: {exc.args[0]}")
|
||||
return False
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.6.69"
|
||||
SCOVERSION = "9.6.70"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user