From 164cc3c8b4f6f7edd755dda532e34f4801fcf2d5 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Wed, 11 Oct 2023 14:45:06 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20API=20assiduit=C3=A9:=20departement=20?= =?UTF-8?q?=C3=A9tudiant=20et=20time-zone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/assiduites.py | 17 ++++++++++------- app/api/justificatifs.py | 4 ++-- app/decorators.py | 1 + app/models/assiduites.py | 6 ++++++ app/scodoc/sco_abs_notification.py | 4 ++-- app/scodoc/sco_preferences.py | 1 + app/scodoc/sco_utils.py | 4 +++- sco_version.py | 2 +- 8 files changed, 26 insertions(+), 13 deletions(-) diff --git a/app/api/assiduites.py b/app/api/assiduites.py index 23c9e2fd2..b3ed9a580 100644 --- a/app/api/assiduites.py +++ b/app/api/assiduites.py @@ -454,7 +454,7 @@ def count_assiduites_formsemestre( @permission_required(Permission.AbsChange) 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": [ { @@ -479,7 +479,7 @@ def assiduite_create(etudid: int = None, nip=None, ine=None): 404, 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 set_sco_dept(etud.departement.acronym) 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 = [] success: list = [] for i, data in enumerate(create_list): - code, obj = _create_singular(data, etud) + code, obj = _create_one(data, etud) if code == 404: errors.append({"indice": i, "message": obj}) else: @@ -544,11 +544,11 @@ def assiduites_create(): if etud is None: errors.append({"indice": i, "message": "Cet étudiant n'existe pas."}) 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 set_sco_dept(etud.departement.acronym) - code, obj = _create_singular(data, etud) + code, obj = _create_one(data, etud) if code == 404: errors.append({"indice": i, "message": obj}) else: @@ -558,7 +558,7 @@ def assiduites_create(): return {"errors": errors, "success": success} -def _create_singular( +def _create_one( data: dict, etud: Identite, ) -> tuple[int, object]: @@ -582,6 +582,8 @@ def _create_singular( deb = scu.is_iso_formated(date_debut, convert=True) if deb is None: errors.append("param 'date_debut': format invalide") + elif deb.tzinfo is None: + deb = scu.localize_datetime(deb) # cas 3 : date_fin date_fin = data.get("date_fin", None) @@ -590,9 +592,10 @@ def _create_singular( fin = scu.is_iso_formated(date_fin, convert=True) if fin is None: errors.append("param 'date_fin': format invalide") + elif fin.tzinfo is None: + fin = scu.localize_datetime(fin) # cas 5 : desc - desc: str = data.get("desc", None) external_data = data.get("external_data", None) diff --git a/app/api/justificatifs.py b/app/api/justificatifs.py index bac373bff..f5b804bb5 100644 --- a/app/api/justificatifs.py +++ b/app/api/justificatifs.py @@ -279,7 +279,7 @@ def justif_create(etudid: int = None, nip=None, ine=None): success: list = [] justifs: 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: errors.append({"indice": i, "message": obj}) else: @@ -291,7 +291,7 @@ def justif_create(etudid: int = None, nip=None, ine=None): return {"errors": errors, "success": success} -def _create_singular( +def _create_one( data: dict, etud: Identite, ) -> tuple[int, object]: diff --git a/app/decorators.py b/app/decorators.py index d8816d618..85b17a33a 100644 --- a/app/decorators.py +++ b/app/decorators.py @@ -44,6 +44,7 @@ def scodoc(func): Set `g.scodoc_dept` and `g.scodoc_dept_id` if `scodoc_dept` is present in the argument (for routes like `//Scolarite/sco_exemple`). + Else set scodoc_dept=None, scodoc_dept_id=-1. """ @wraps(func) diff --git a/app/models/assiduites.py b/app/models/assiduites.py index 766196c35..a78e709df 100644 --- a/app/models/assiduites.py +++ b/app/models/assiduites.py @@ -134,6 +134,12 @@ class Assiduite(db.Model): notify_mail=False, ) -> "Assiduite": """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 assiduites: Query = etud.assiduites if is_period_conflicting(date_debut, date_fin, assiduites, Assiduite): diff --git a/app/scodoc/sco_abs_notification.py b/app/scodoc/sco_abs_notification.py index 057d71913..6d2923236 100644 --- a/app/scodoc/sco_abs_notification.py +++ b/app/scodoc/sco_abs_notification.py @@ -60,8 +60,8 @@ def abs_notify(etudid: int, date: str | datetime.datetime): """ from app.scodoc import sco_assiduites - if current_app and current_app.config["DEBUG"]: - return + # if current_app and current_app.config["DEBUG"]: + # return formsemestre = retreive_current_formsemestre(etudid, date) if not formsemestre: diff --git a/app/scodoc/sco_preferences.py b/app/scodoc/sco_preferences.py index 88970b6b9..ea95821f7 100644 --- a/app/scodoc/sco_preferences.py +++ b/app/scodoc/sco_preferences.py @@ -285,6 +285,7 @@ class BasePreferences: def __init__(self, dept_id: int): dept = db.session.get(Departement, dept_id) if not dept: + log(f"BasePreferences: Invalid departement: {dept_id}") raise ScoValueError(f"BasePreferences: Invalid departement: {dept_id}") self.dept_id = dept.id self.init() diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py index 5baba6344..7a93198e7 100644 --- a/app/scodoc/sco_utils.py +++ b/app/scodoc/sco_utils.py @@ -76,6 +76,7 @@ STATIC_DIR = ( os.environ.get("SCRIPT_NAME", "") + "/ScoDoc/static/links/" + sco_version.SCOVERSION ) # 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:])) # ----- CALCUL ET PRESENTATION DES NOTES @@ -251,7 +252,8 @@ def is_period_overlapping( """ Vérifie si la période et l'interval s'intersectent 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 i_deb, i_fin = interval diff --git a/sco_version.py b/sco_version.py index 2fb32fb90..c9cbef32f 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.6.43" +SCOVERSION = "9.6.44" SCONAME = "ScoDoc"