From d97cb6f309f7b0aa9de9bd8af57799504756d1b1 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 28 Oct 2024 22:16:06 +0100 Subject: [PATCH] =?UTF-8?q?Fix:=20assiduit=C3=A9:=20heures=20des=20assidui?= =?UTF-8?q?t=C3=A9s=20cr=C3=A9es=20dans=20log=20et=20journal=20=C3=A9tudia?= =?UTF-8?q?nt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/assiduites.py | 4 +++- app/models/assiduites.py | 12 +++++++++--- app/scodoc/sco_utils.py | 1 - app/static/js/etud_info.js | 2 +- tests/api/test_api_assiduites.py | 32 +++++++++++++++++++++++++++++--- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/app/api/assiduites.py b/app/api/assiduites.py index 5471d0a83..36d31d9b7 100644 --- a/app/api/assiduites.py +++ b/app/api/assiduites.py @@ -650,7 +650,9 @@ def assiduites_formsemestre_count( @permission_required(Permission.AbsChange) def assiduite_create(etudid: int = None, nip=None, ine=None): """ - Enregistrement d'assiduités pour un étudiant (etudid) + Enregistrement d'assiduités pour un étudiant (etudid). + + Si les heures n'ont pas de timezone, elles sont exprimées dans celle du serveur. DATA ---- diff --git a/app/models/assiduites.py b/app/models/assiduites.py index 7104c86ad..5c36a1710 100644 --- a/app/models/assiduites.py +++ b/app/models/assiduites.py @@ -124,19 +124,25 @@ class Assiduite(ScoDocModel): return data def __str__(self) -> str: - "chaine pour journaux et debug (lisible par humain français)" + "chaine pour journaux et debug (lisible par humain français, en timezone serveur)" try: etat_str = EtatAssiduite(self.etat).name.lower().capitalize() except ValueError: etat_str = "Invalide" + # passe en timezone serveur + d_deb = self.date_debut.astimezone(scu.TIME_ZONE) + d_fin = self.date_fin.astimezone(scu.TIME_ZONE) return f"""{etat_str} { "just." if self.est_just else "non just." } de { - self.date_debut.strftime("%d/%m/%Y %Hh%M") + d_deb.strftime("%d/%m/%Y %Hh%M") } à { - self.date_fin.strftime("%d/%m/%Y %Hh%M") + d_fin.strftime("%d/%m/%Y %Hh%M") }""" + def __repr__(self) -> str: + return f"" + @classmethod def create_assiduite( cls, diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py index 20c351dae..50f767a49 100644 --- a/app/scodoc/sco_utils.py +++ b/app/scodoc/sco_utils.py @@ -432,7 +432,6 @@ def localize_datetime(date: datetime.datetime) -> datetime.datetime: Tente de mettre l'offset de la timezone du serveur (ex : UTC+1) Si erreur, mettra l'offset UTC """ - new_date: datetime.datetime = date if new_date.tzinfo is None: try: diff --git a/app/static/js/etud_info.js b/app/static/js/etud_info.js index 56e59858a..4fbcb42ba 100644 --- a/app/static/js/etud_info.js +++ b/app/static/js/etud_info.js @@ -5,7 +5,7 @@ function get_etudid_from_elem(e) { // renvoie l'etudid, obtenu a partir de l'id de l'element // qui est soit de la forme xxxx-etudid, soit tout simplement etudid - var etudid = e.id.split("-")[1]; + let etudid = e.id.split("-")[1]; if (etudid == undefined) { return e.id; } else { diff --git a/tests/api/test_api_assiduites.py b/tests/api/test_api_assiduites.py index a95f06cf3..c860e573d 100644 --- a/tests/api/test_api_assiduites.py +++ b/tests/api/test_api_assiduites.py @@ -5,9 +5,11 @@ Ecrit par HARTMANN Matthias """ +import datetime from random import randint from types import NoneType +from app.scodoc import sco_utils as scu from tests.api.setup_test_api import ( GET, POST, @@ -265,15 +267,39 @@ def test_route_create(api_admin_headers): ) check_fields(res, BATCH_FIELD) assert len(res["success"]) == 1 - TO_REMOVE.append(res["success"][0]["message"]["assiduite_id"]) - data = GET( + data_get = GET( path=f'/assiduite/{res["success"][0]["message"]["assiduite_id"]}', headers=api_admin_headers, dept=DEPT_ACRONYM, ) - check_fields(data, fields=ASSIDUITES_FIELDS) + check_fields(data_get, fields=ASSIDUITES_FIELDS) + # la date de début est sans fournie sans timezone, mais celle renvoyé avec. + # Compare en ajoutant la timezone serveur: + assert scu.localize_datetime( + datetime.datetime.fromisoformat(data["date_debut"]) + ) == datetime.datetime.fromisoformat(data_get["date_debut"]) + # Création avec timezone (comme le fait assiduite.js) + data["date_debut"] = "2024-10-28T10:00:00.000Z" + data["date_fin"] = "2024-10-28T12:00:00.000Z" + res = POST( + f"/assiduite/{ETUDID}/create", [data], api_admin_headers, dept=DEPT_ACRONYM + ) + check_fields(res, BATCH_FIELD) + assert len(res["success"]) == 1 + TO_REMOVE.append(res["success"][0]["message"]["assiduite_id"]) + data_get = GET( + path=f'/assiduite/{res["success"][0]["message"]["assiduite_id"]}', + headers=api_admin_headers, + dept=DEPT_ACRONYM, + ) + check_fields(data_get, fields=ASSIDUITES_FIELDS) + assert scu.localize_datetime( + datetime.datetime.fromisoformat(data["date_debut"]) + ) == datetime.datetime.fromisoformat(data_get["date_debut"]) + + # Absence avec module data2 = create_data("absent", "04", MODULE, "desc") res = POST( f"/assiduite/{ETUDID}/create", [data2], api_admin_headers, dept=DEPT_ACRONYM