Assiduité : edit_assiduite_etud : modification dates/heures assiduités (formulaires)

This commit is contained in:
Iziram 2024-06-04 16:01:05 +02:00
parent 9801cf7936
commit 93bb9d598e
4 changed files with 111 additions and 37 deletions

View File

@ -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})

View File

@ -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

View File

@ -119,6 +119,21 @@
{{ form.assi_etat.label }}
{{ form.assi_etat() }}
</div>
<div class="dates-heures">
{{ form.date_debut.label }}&nbsp;: {{ form.date_debut }}
à {{ form.heure_debut }}
{{ render_field_errors(form, 'date_debut') }}
{{ render_field_errors(form, 'heure_debut') }}
<br>
{{ form.date_fin.label }}&nbsp;: {{ form.date_fin }}
à {{ form.heure_fin }}
{{ render_field_errors(form, 'date_fin') }}
{{ render_field_errors(form, 'heure_fin') }}
<br>
{{ form.entry_date.label }}&nbsp;: {{ form.entry_date }} à {{ form.entry_time }}
</div>
<br>
{# Menu module #}
<div class="select-module">
{{ form.modimpl.label }}&nbsp;:

View File

@ -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}",
)