From 161f8476ca32ab424cdf73e6b326894402c26ec1 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sun, 24 Mar 2024 09:17:01 +0100 Subject: [PATCH] =?UTF-8?q?Conversion=20dates=20=C3=A9dition=20=C3=A9valua?= =?UTF-8?q?tions=20et=20formsemestres.=20Fix=20#593.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scodoc/notesdb.py | 5 +++-- app/scodoc/sco_evaluation_edit.py | 8 +------- app/scodoc/sco_formsemestre_edit.py | 12 +++++++---- app/scodoc/sco_utils.py | 32 +++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/app/scodoc/notesdb.py b/app/scodoc/notesdb.py index e0f24606..5aa5c91b 100644 --- a/app/scodoc/notesdb.py +++ b/app/scodoc/notesdb.py @@ -460,7 +460,8 @@ def dictfilter(d, fields, filter_nulls=True): # --- Misc Tools -def DateDMYtoISO(dmy: str, null_is_empty=False) -> str | None: # XXX deprecated +# XXX deprecated, voir convert_fr_date +def DateDMYtoISO(dmy: str, null_is_empty=False) -> str | None: """Convert date string from french format (or ISO) to ISO. If null_is_empty (default false), returns "" if no input. """ @@ -479,7 +480,7 @@ def DateDMYtoISO(dmy: str, null_is_empty=False) -> str | None: # XXX deprecated try: dt = datetime.datetime.fromisoformat(dmy) except ValueError as exc: - raise ScoValueError(f'Date (j/m/a or iso) invalide: "{dmy}"') from exc + raise ValueError(f'Date (j/m/a or iso) invalide: "{dmy}"') from exc return dt.date().isoformat() diff --git a/app/scodoc/sco_evaluation_edit.py b/app/scodoc/sco_evaluation_edit.py index 3824ca60..2b47e131 100644 --- a/app/scodoc/sco_evaluation_edit.py +++ b/app/scodoc/sco_evaluation_edit.py @@ -374,13 +374,7 @@ def evaluation_create_form( args = tf[2] # modifie le codage des dates # (nb: ce formulaire ne permet de créer que des évaluation sur la même journée) - if args.get("jour"): - try: - date_debut = datetime.datetime.strptime(args["jour"], "%d/%m/%Y") - except ValueError as exc: - raise ScoValueError("Date (j/m/a) invalide") from exc - else: - date_debut = None + date_debut = scu.convert_fr_date(args["jour"]) if args.get("jour") else None args["date_debut"] = date_debut args["date_fin"] = date_debut # même jour args.pop("jour", None) diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py index c8de7b9f..6ee35513 100644 --- a/app/scodoc/sco_formsemestre_edit.py +++ b/app/scodoc/sco_formsemestre_edit.py @@ -812,14 +812,18 @@ def do_formsemestre_createwithmodules(edit=False, formsemestre: FormSemestre = N ) msg = "" if tf[0] == 1: - # check dates - if ndb.DateDMYtoISO(tf[2]["date_debut"]) > ndb.DateDMYtoISO(tf[2]["date_fin"]): - msg = '' + # convert and check dates + tf[2]["date_debut"] = scu.convert_fr_date(tf[2]["date_debut"]) + tf[2]["date_fin"] = scu.convert_fr_date(tf[2]["date_fin"]) + if tf[2]["date_debut"] > tf[2]["date_fin"]: + msg = """""" if ( sco_preferences.get_preference("always_require_apo_sem_codes") and not any( - [tf[2]["etape_apo" + str(n)] for n in range(0, scu.EDIT_NB_ETAPES + 1)] + tf[2]["etape_apo" + str(n)] for n in range(0, scu.EDIT_NB_ETAPES + 1) ) # n'impose pas d'Apo pour les sem. extérieurs and ((formsemestre is None) or formsemestre.modalite != "EXT") diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py index 51d8a5d4..fa2ae54a 100644 --- a/app/scodoc/sco_utils.py +++ b/app/scodoc/sco_utils.py @@ -109,6 +109,38 @@ ETATS_INSCRIPTION = { } +def convert_fr_date(date_str: str, allow_iso=True) -> datetime.datetime: + """Converti une date saisie par un humain français avant 2070 + en un objet datetime. + 12/2/1972 => 1972-02-12, 12/2/72 => 1972-02-12, mais 12/2/24 => 2024-02-12 + Le pivot est 70. + ScoValueError si date invalide. + """ + try: + return datetime.datetime.strptime(date_str, "%d/%m/%Y") + except ValueError: + # Try to add century ? + m = re.match(r"^(\d{1,2})/(\d{1,2})/(\d\d)$", date_str) + if m: + year = int(m.group(3)) + if year < 70: + year += 2000 + else: + year += 1900 + try: + return datetime.datetime.strptime( + f"{m.group(1)}/{m.group(2)}/{year}", "%d/%m/%Y" + ) + except ValueError: + pass + if allow_iso: + try: + return datetime.datetime.fromisoformat(date_str) + except ValueError as exc: + raise ScoValueError("Date (j/m/a or ISO) invalide") from exc + raise ScoValueError("Date (j/m/a) invalide") + + def print_progress_bar( iteration, total,