diff --git a/app/forms/assiduite/edit_assiduite_etud.py b/app/forms/assiduite/edit_assiduite_etud.py
index ca284c014..cdcff62e0 100644
--- a/app/forms/assiduite/edit_assiduite_etud.py
+++ b/app/forms/assiduite/edit_assiduite_etud.py
@@ -1,7 +1,14 @@
""" """
from flask_wtf import FlaskForm
-from wtforms import SelectField, RadioField, TextAreaField, validators, SubmitField
+from wtforms import (
+ StringField,
+ SelectField,
+ RadioField,
+ TextAreaField,
+ validators,
+ SubmitField,
+)
from app.scodoc.sco_utils import EtatAssiduite
@@ -53,6 +60,63 @@ class EditAssiForm(FlaskForm):
"maxlength": 500,
},
)
+ date_debut = StringField(
+ "Date de début",
+ validators=[validators.Length(max=10)],
+ render_kw={
+ "class": "datepicker",
+ "size": 10,
+ "id": "assi_date_debut",
+ },
+ )
+ heure_debut = StringField(
+ "Heure début",
+ default="",
+ validators=[validators.Length(max=5)],
+ render_kw={
+ "class": "timepicker",
+ "size": 5,
+ "id": "assi_heure_debut",
+ },
+ )
+ heure_fin = StringField(
+ "Heure fin",
+ default="",
+ validators=[validators.Length(max=5)],
+ render_kw={
+ "class": "timepicker",
+ "size": 5,
+ "id": "assi_heure_fin",
+ },
+ )
+ date_fin = StringField(
+ "Date de fin",
+ validators=[validators.Length(max=10)],
+ render_kw={
+ "class": "datepicker",
+ "size": 10,
+ "id": "assi_date_fin",
+ },
+ )
+ entry_date = StringField(
+ "Date de dépôt ou saisie",
+ validators=[validators.Length(max=10)],
+ render_kw={
+ "class": "datepicker",
+ "size": 10,
+ "id": "entry_date",
+ },
+ )
+ entry_time = StringField(
+ "Heure dépôt",
+ default="",
+ validators=[validators.Length(max=5)],
+ render_kw={
+ "class": "timepicker",
+ "size": 5,
+ "id": "assi_heure_fin",
+ },
+ )
submit = SubmitField("Enregistrer")
cancel = SubmitField("Annuler", render_kw={"formnovalidate": True})
diff --git a/app/models/assiduites.py b/app/models/assiduites.py
index b741005e4..7c5c1ce26 100644
--- a/app/models/assiduites.py
+++ b/app/models/assiduites.py
@@ -703,10 +703,14 @@ def is_period_conflicting(
date_fin: datetime,
collection: Query,
collection_cls: Assiduite | Justificatif,
+ obj_id: int = -1,
) -> bool:
"""
Vérifie si une date n'entre pas en collision
avec les justificatifs ou assiduites déjà présentes
+
+ On peut donner un objet_id pour exclure un objet de la vérification
+ (utile pour les modifications)
"""
# On s'assure que les dates soient avec TimeZone
@@ -714,7 +718,9 @@ def is_period_conflicting(
date_fin = localize_datetime(date_fin)
count: int = collection.filter(
- collection_cls.date_debut < date_fin, collection_cls.date_fin > date_debut
+ collection_cls.date_debut < date_fin,
+ collection_cls.date_fin > date_debut,
+ collection_cls.id != obj_id,
).count()
return count > 0
diff --git a/app/templates/assiduites/pages/edit_assiduite_etud.j2 b/app/templates/assiduites/pages/edit_assiduite_etud.j2
index 8b0930e87..d80d58af1 100644
--- a/app/templates/assiduites/pages/edit_assiduite_etud.j2
+++ b/app/templates/assiduites/pages/edit_assiduite_etud.j2
@@ -119,6 +119,21 @@
{{ form.assi_etat.label }}
{{ form.assi_etat() }}
+
+ {{ form.date_debut.label }} : {{ form.date_debut }}
+ à {{ form.heure_debut }}
+ {{ render_field_errors(form, 'date_debut') }}
+ {{ render_field_errors(form, 'heure_debut') }}
+
+ {{ form.date_fin.label }} : {{ form.date_fin }}
+ à {{ form.heure_fin }}
+ {{ render_field_errors(form, 'date_fin') }}
+ {{ render_field_errors(form, 'heure_fin') }}
+
+ {{ form.entry_date.label }} : {{ form.entry_date }} à {{ form.entry_time }}
+
+
+
{# Menu module #}
{{ form.modimpl.label }} :
diff --git a/app/views/assiduites.py b/app/views/assiduites.py
index b98d61ecd..96445b81c 100644
--- a/app/views/assiduites.py
+++ b/app/views/assiduites.py
@@ -66,7 +66,7 @@ from app.models import (
from app.scodoc.codes_cursus import UE_STANDARD
from app.auth.models import User
-from app.models.assiduites import get_assiduites_justif
+from app.models.assiduites import get_assiduites_justif, is_period_conflicting
from app.tables.list_etuds import RowEtud, TableEtud
import app.tables.liste_assiduites as liste_assi
@@ -741,32 +741,6 @@ def ajout_justificatif_etud():
)
-def _verif_date_form_justif(
- form: AjoutJustificatifEtudForm, deb: datetime.datetime, fin: datetime.datetime
-) -> tuple[datetime.datetime, datetime.datetime]:
- """Gère les cas suivants :
- - si on indique seulement une date de debut : journée 0h-23h59
- - si on indique date de debut et heures : journée +heure deb/fin
- (déjà géré par _get_dates_from_assi_form)
- - Si on indique une date de début et de fin sans heures : Journées 0h-23h59
- - Si on indique une date de début et de fin avec heures : On fait un objet avec
- datedeb/heuredeb + datefin/heurefin (déjà géré par _get_dates_from_assi_form)
- """
-
- cas: list[bool] = [
- # cas 1
- not form.date_fin.data and not form.heure_debut.data,
- # cas 3
- form.date_fin.data != "" and not form.heure_debut.data,
- ]
-
- if any(cas):
- deb = deb.replace(hour=0, minute=0)
- fin = fin.replace(hour=23, minute=59)
-
- return deb, fin
-
-
def _record_justificatif_etud(
etud: Identite, form: AjoutJustificatifEtudForm, justif: Justificatif | None = None
) -> bool:
@@ -2222,13 +2196,17 @@ def edit_assiduite_etud(assiduite_id: int):
description = form.description.data or ""
description = description.strip()
- moduleimpl_id = form.modimpl.data or -1
- if isinstance(moduleimpl_id, int):
- try:
- ModuleImpl.get_moduleimpl(moduleimpl_id)
- except ValueError:
- form.error_messages.append("Module invalide")
- moduleimpl_id = -1
+ moduleimpl_id = form.modimpl.data if form.modimpl.data is not None else -1
+ # Vérifications des dates / horaires
+
+ ok, dt_deb, dt_fin, dt_entry = _get_dates_from_assi_form(
+ form, etud, from_justif=True, formsemestre=formsemestre
+ )
+ if ok:
+ if is_period_conflicting(
+ dt_deb, dt_fin, etud.assiduites, Assiduite, assi.id
+ ):
+ form.set_error("La période est en conflit avec une autre assiduité")
form.ok = False
if form.ok:
@@ -2237,6 +2215,10 @@ def edit_assiduite_etud(assiduite_id: int):
if moduleimpl_id != -1:
assi.set_moduleimpl(moduleimpl_id)
+ assi.date_debut = dt_deb
+ assi.date_fin = dt_fin
+ assi.entry_date = dt_entry
+
db.session.add(assi)
db.session.commit()
@@ -2251,12 +2233,19 @@ def edit_assiduite_etud(assiduite_id: int):
moduleimpl_id: int | str | None = assi.get_moduleimpl_id() or ""
form.modimpl.data = str(moduleimpl_id)
+ form.date_debut.data = assi.date_debut.strftime(scu.DATE_FMT)
+ form.heure_debut.data = assi.date_debut.strftime(scu.TIME_FMT)
+ form.date_fin.data = assi.date_fin.strftime(scu.DATE_FMT)
+ form.heure_fin.data = assi.date_fin.strftime(scu.TIME_FMT)
+ form.entry_date.data = assi.entry_date.strftime(scu.DATE_FMT)
+ form.entry_time.data = assi.entry_date.strftime(scu.TIME_FMT)
+
return render_template(
"assiduites/pages/edit_assiduite_etud.j2",
etud=etud,
sco=ScoData(etud, formsemestre=formsemestre),
form=form,
- readonly=readonly,
+ readonly=True,
objet=_preparer_objet("assiduite", assi),
title=f"Assiduité {etud.nom_short}",
)