Fix API assiduité: departement étudiant et time-zone

This commit is contained in:
Emmanuel Viennet 2023-10-11 14:45:06 +02:00
parent 9fbfa3861d
commit 164cc3c8b4
8 changed files with 26 additions and 13 deletions

View File

@ -454,7 +454,7 @@ def count_assiduites_formsemestre(
@permission_required(Permission.AbsChange) @permission_required(Permission.AbsChange)
def assiduite_create(etudid: int = None, nip=None, ine=None): def assiduite_create(etudid: int = None, nip=None, ine=None):
""" """
Création d'une assiduité pour l'étudiant (etudid) Enregistrement d'assiduités pour un étudiant (etudid)
La requête doit avoir un content type "application/json": La requête doit avoir un content type "application/json":
[ [
{ {
@ -479,7 +479,7 @@ def assiduite_create(etudid: int = None, nip=None, ine=None):
404, 404,
message="étudiant inconnu", message="étudiant inconnu",
) )
if not hasattr(g, "scodoc_dept_id") and etud.dept_id is not None: if g.scodoc_dept is None and etud.dept_id is not None:
# route sans département # route sans département
set_sco_dept(etud.departement.acronym) set_sco_dept(etud.departement.acronym)
create_list: list[object] = request.get_json(force=True) create_list: list[object] = request.get_json(force=True)
@ -490,7 +490,7 @@ def assiduite_create(etudid: int = None, nip=None, ine=None):
errors: list = [] errors: list = []
success: list = [] success: list = []
for i, data in enumerate(create_list): for i, data in enumerate(create_list):
code, obj = _create_singular(data, etud) code, obj = _create_one(data, etud)
if code == 404: if code == 404:
errors.append({"indice": i, "message": obj}) errors.append({"indice": i, "message": obj})
else: else:
@ -544,11 +544,11 @@ def assiduites_create():
if etud is None: if etud is None:
errors.append({"indice": i, "message": "Cet étudiant n'existe pas."}) errors.append({"indice": i, "message": "Cet étudiant n'existe pas."})
continue continue
if not hasattr(g, "scodoc_dept_id") and etud.dept_id is not None: if g.scodoc_dept is None and etud.dept_id is not None:
# route sans département # route sans département
set_sco_dept(etud.departement.acronym) set_sco_dept(etud.departement.acronym)
code, obj = _create_singular(data, etud) code, obj = _create_one(data, etud)
if code == 404: if code == 404:
errors.append({"indice": i, "message": obj}) errors.append({"indice": i, "message": obj})
else: else:
@ -558,7 +558,7 @@ def assiduites_create():
return {"errors": errors, "success": success} return {"errors": errors, "success": success}
def _create_singular( def _create_one(
data: dict, data: dict,
etud: Identite, etud: Identite,
) -> tuple[int, object]: ) -> tuple[int, object]:
@ -582,6 +582,8 @@ def _create_singular(
deb = scu.is_iso_formated(date_debut, convert=True) deb = scu.is_iso_formated(date_debut, convert=True)
if deb is None: if deb is None:
errors.append("param 'date_debut': format invalide") errors.append("param 'date_debut': format invalide")
elif deb.tzinfo is None:
deb = scu.localize_datetime(deb)
# cas 3 : date_fin # cas 3 : date_fin
date_fin = data.get("date_fin", None) date_fin = data.get("date_fin", None)
@ -590,9 +592,10 @@ def _create_singular(
fin = scu.is_iso_formated(date_fin, convert=True) fin = scu.is_iso_formated(date_fin, convert=True)
if fin is None: if fin is None:
errors.append("param 'date_fin': format invalide") errors.append("param 'date_fin': format invalide")
elif fin.tzinfo is None:
fin = scu.localize_datetime(fin)
# cas 5 : desc # cas 5 : desc
desc: str = data.get("desc", None) desc: str = data.get("desc", None)
external_data = data.get("external_data", None) external_data = data.get("external_data", None)

View File

@ -279,7 +279,7 @@ def justif_create(etudid: int = None, nip=None, ine=None):
success: list = [] success: list = []
justifs: list = [] justifs: list = []
for i, data in enumerate(create_list): for i, data in enumerate(create_list):
code, obj, justi = _create_singular(data, etud) code, obj, justi = _create_one(data, etud)
if code == 404: if code == 404:
errors.append({"indice": i, "message": obj}) errors.append({"indice": i, "message": obj})
else: else:
@ -291,7 +291,7 @@ def justif_create(etudid: int = None, nip=None, ine=None):
return {"errors": errors, "success": success} return {"errors": errors, "success": success}
def _create_singular( def _create_one(
data: dict, data: dict,
etud: Identite, etud: Identite,
) -> tuple[int, object]: ) -> tuple[int, object]:

View File

@ -44,6 +44,7 @@ def scodoc(func):
Set `g.scodoc_dept` and `g.scodoc_dept_id` if `scodoc_dept` is present Set `g.scodoc_dept` and `g.scodoc_dept_id` if `scodoc_dept` is present
in the argument (for routes like in the argument (for routes like
`/<scodoc_dept>/Scolarite/sco_exemple`). `/<scodoc_dept>/Scolarite/sco_exemple`).
Else set scodoc_dept=None, scodoc_dept_id=-1.
""" """
@wraps(func) @wraps(func)

View File

@ -134,6 +134,12 @@ class Assiduite(db.Model):
notify_mail=False, notify_mail=False,
) -> "Assiduite": ) -> "Assiduite":
"""Créer une nouvelle assiduité pour l'étudiant""" """Créer une nouvelle assiduité pour l'étudiant"""
if date_debut.tzinfo is None:
log(
f"Warning: create_assiduite: date_debut without timezone ({date_debut})"
)
if date_fin.tzinfo is None:
log(f"Warning: create_assiduite: date_fin without timezone ({date_fin})")
# Vérification de non duplication des périodes # Vérification de non duplication des périodes
assiduites: Query = etud.assiduites assiduites: Query = etud.assiduites
if is_period_conflicting(date_debut, date_fin, assiduites, Assiduite): if is_period_conflicting(date_debut, date_fin, assiduites, Assiduite):

View File

@ -60,8 +60,8 @@ def abs_notify(etudid: int, date: str | datetime.datetime):
""" """
from app.scodoc import sco_assiduites from app.scodoc import sco_assiduites
if current_app and current_app.config["DEBUG"]: # if current_app and current_app.config["DEBUG"]:
return # return
formsemestre = retreive_current_formsemestre(etudid, date) formsemestre = retreive_current_formsemestre(etudid, date)
if not formsemestre: if not formsemestre:

View File

@ -285,6 +285,7 @@ class BasePreferences:
def __init__(self, dept_id: int): def __init__(self, dept_id: int):
dept = db.session.get(Departement, dept_id) dept = db.session.get(Departement, dept_id)
if not dept: if not dept:
log(f"BasePreferences: Invalid departement: {dept_id}")
raise ScoValueError(f"BasePreferences: Invalid departement: {dept_id}") raise ScoValueError(f"BasePreferences: Invalid departement: {dept_id}")
self.dept_id = dept.id self.dept_id = dept.id
self.init() self.init()

View File

@ -76,6 +76,7 @@ STATIC_DIR = (
os.environ.get("SCRIPT_NAME", "") + "/ScoDoc/static/links/" + sco_version.SCOVERSION os.environ.get("SCRIPT_NAME", "") + "/ScoDoc/static/links/" + sco_version.SCOVERSION
) )
# La time zone du serveur: # La time zone du serveur:
# Attention: suppose que la timezone utilisée par postgresql soit la même !
TIME_ZONE = timezone("/".join(os.path.realpath("/etc/localtime").split("/")[-2:])) TIME_ZONE = timezone("/".join(os.path.realpath("/etc/localtime").split("/")[-2:]))
# ----- CALCUL ET PRESENTATION DES NOTES # ----- CALCUL ET PRESENTATION DES NOTES
@ -251,7 +252,8 @@ def is_period_overlapping(
""" """
Vérifie si la période et l'interval s'intersectent Vérifie si la période et l'interval s'intersectent
si strict == True : les extrémitées ne comptes pas si strict == True : les extrémitées ne comptes pas
Retourne Vrai si c'est le cas, faux sinon Retourne Vrai si c'est le cas, faux sinon.
Attention: offset-aware datetimes
""" """
p_deb, p_fin = periode p_deb, p_fin = periode
i_deb, i_fin = interval i_deb, i_fin = interval

View File

@ -1,7 +1,7 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
SCOVERSION = "9.6.43" SCOVERSION = "9.6.44"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"