diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py index db0a64c28..3f863ebe4 100644 --- a/app/scodoc/sco_apogee_csv.py +++ b/app/scodoc/sco_apogee_csv.py @@ -586,7 +586,16 @@ class ApoEtud(dict): (sem["semestre_id"] == apo_data.cur_semestre_id) and (apo_data.etape in sem["etapes"]) and ( - sco_formsemestre.sem_in_annee_scolaire(sem, apo_data.annee_scolaire) + # sco_formsemestre.sem_in_annee_scolaire(sem, apo_data.annee_scolaire) # TODO à remplacer par ? + sco_formsemestre.sem_in_semestre_scolaire( + sem, + apo_data.annee_scolaire, + 0, + # jour_pivot_annee, + # mois_pivot_annee, + # jour_pivot_periode, + # mois_pivot_periode + ) ) ) ] diff --git a/app/scodoc/sco_formsemestre.py b/app/scodoc/sco_formsemestre.py index 42e6bd46e..38b0e9cb9 100644 --- a/app/scodoc/sco_formsemestre.py +++ b/app/scodoc/sco_formsemestre.py @@ -422,67 +422,97 @@ def sem_set_responsable_name(sem): ) -def debut_in_semestre_scolaire( - date_debut: datetime.date, year: int = False, saison: int = 0 -) -> bool: - """Vrai si date_debut est dans l'année scolaire ou le semestre - indiquée par year et periode - (par défaut, l'année scolaire en cours). - periode: - 1 = sept, - 0 = janvier - None = année complète +def get_periode( + debut: datetime, + jour_pivot_annee=1, + mois_pivot_annee=8, + jour_pivot_periode=1, + mois_pivot_periode=12, +): + """Calcule la session associée à un formsemestre sous la forme (année, période) + année: première année de l'année scolaire + période = 1 (première période de l'année scolaire anciennement automne) + ou 2 (deuxième période de l'année scolaire - anciennement printemps) + les quatre derniers paramètres forment les dates pivots pour l'année (1er août par défaut) + et pour la période (1er décembre par défaut). + Tous les calculs se font à partir de la date de début du formsemestre. + Exemples dans tests/unit/test_periode """ - if not year: - year = scu.AnneeScolaire() - # XXX WIP à voir selon ce que fait réellement sem_in_semestre_scolaire - - -def sem_in_semestre_scolaire(sem, year=False, saison=0): - """n'utilise que la date de debut, pivot au 1er aout - si annee non specifiée, année scolaire courante - Patch Jmp: ajout du parametre optionnel saison - 1 = sept, 0 = janvier, None = année complète - si saison non spécifiée: année complète - pivot de saison au 1er décembre - XXX TODO: la période (ici appelée "saison" devrait être éditable - manuellement dans le formsemestre_edit afin de couvrir les cas particulier - comme un semestre S2 qui commencerait en décembre... voire novembre. - ) + """Implementation + Cas à considérer pour le calcul de la période + + pa < pp -----------------|-------------------|----------------> + (A-1, P:2) pa (A, P:1) pp (A, P:2) + pp < pa -----------------|-------------------|----------------> + (A-1, P:1) pp (A-1, P:2) pa (A, P:1) """ - if not year: - year = scu.AnneeScolaire() - # est-on dans la même année universitaire ? - if sem["mois_debut_ord"] > 7: # XXX - if sem["annee_debut"] != str(year): - return False + pa = 100 * mois_pivot_annee + jour_pivot_annee + pp = 100 * mois_pivot_periode + jour_pivot_periode + ps = 100 * debut.month + debut.day + if ps < pa: + annee = debut.year - 1 else: - if sem["annee_debut"] != str(year + 1): - return False - # raffinement éventuel sur le semestre - # saison is None => pas de rafinement => True - if saison == 0: - return True - elif saison == 1: # calcul en fonction de la saison - return sem["mois_debut_ord"] > 7 and sem["mois_debut_ord"] < 12 - else: # saison == 0 - return sem["mois_debut_ord"] <= 7 or sem["mois_debut_ord"] == 12 + annee = debut.year + if pa < pp: + if ps < pa or ps > pp: + periode = 2 + else: + periode = 1 + else: + if ps < pp or ps > pa: + periode = 1 + else: + periode = 2 + return annee, periode -def sem_in_annee_scolaire(sem, year=False): - """Test si sem appartient à l'année scolaire year (int). - N'utilise que la date de début, pivot au 1er août. - Si année non specifiée, année scolaire courante +def sem_in_semestre_scolaire( + sem, + year=False, + periode=None, + jour_pivot_annee=1, + mois_pivot_annee=8, + jour_pivot_periode=1, + mois_pivot_periode=12, +): + """n'utilise que la date de debut, + si annee non specifiée, année scolaire courante + la période garde les même convention que semset["sem_id"]; + * 1 : premère période + * 2 : deuxième période + * 0 ou periode non précisée: annualisé (donc inclut toutes les périodes) + ) """ if not year: year = scu.AnneeScolaire() - return ( - (sem["annee_debut"] == str(year)) - and (sem["mois_debut_ord"] > scu.MONTH_FIN_ANNEE_SCOLAIRE) - ) or ( - (sem["annee_debut"] == str(year + 1)) - and (sem["mois_debut_ord"] <= scu.MONTH_FIN_ANNEE_SCOLAIRE) + # calcule l'année universitaire et la periode + sem_annee, sem_periode = get_periode( + datetime.datetime.fromisoformat(sem["date_debut_iso"]), + jour_pivot_annee, + mois_pivot_annee, + jour_pivot_periode, + mois_pivot_periode, ) + if periode is None or periode == 0: + return sem_annee == year + else: + return sem_annee == year and sem_periode == periode + + +# def sem_in_annee_scolaire(sem, year=False): +# """Test si sem appartient à l'année scolaire year (int). +# N'utilise que la date de début, pivot au 1er août. +# Si année non specifiée, année scolaire courante +# """ +# if not year: +# year = scu.AnneeScolaire() +# return ( +# (sem["annee_debut"] == str(year)) +# and (sem["mois_debut_ord"] > scu.MONTH_FIN_ANNEE_SCOLAIRE) +# ) or ( +# (sem["annee_debut"] == str(year + 1)) +# and (sem["mois_debut_ord"] <= scu.MONTH_FIN_ANNEE_SCOLAIRE) +# ) def sem_est_courant(sem): # -> FormSemestre.est_courant diff --git a/app/scodoc/sco_semset.py b/app/scodoc/sco_semset.py index 4eeff7cff..92e23203f 100644 --- a/app/scodoc/sco_semset.py +++ b/app/scodoc/sco_semset.py @@ -233,7 +233,8 @@ class SemSet(dict): if sco_formsemestre.sem_in_semestre_scolaire( sem, year=self["annee_scolaire"], - saison=self["sem_id"], + # Indiquer ici les valeur des dates pivots année et période + periode=self["sem_id"], ) ] return sems diff --git a/tests/unit/test_periode.py b/tests/unit/test_periode.py new file mode 100644 index 000000000..4c818c01f --- /dev/null +++ b/tests/unit/test_periode.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- + +"""Test Periodes + +Utiliser comme: + pytest tests/unit/test_periode.py +""" +import datetime + +from app.scodoc.sco_formsemestre import get_periode, sem_in_semestre_scolaire + +""" Calcule la session associée à un formsemestre sous la forme (année, période) +année: première année de l'année scolaire +période = 1 (première période de l'année scolaire) ou 2 (deuxième période de l'année scolaire) +les quatre derniers paramètres forment les dates pivots pour l'année (1er août par défaut) +et pour la période (1er décembre par défaut). +Tous les calculs se font à partir de la date de début du formsemestre. +Exemples: +Début FormSemestre pivot_année pivot_periode Résultat +01/01/2022 ( 1, 8) ( 1,12) (2021,2) # A: printemps nord +01/09/2022 ( 1, 8) ( 1,12) (2022,1) # B: automne nord +15/12/2022 ( 1, 8) ( 1,12) (2022,2) +30/07/2023 ( 1, 8) ( 1,12) (2022,2) +01/01/2022 ( 1, 1) ( 1, 8) (2022,1) # antipodes +30/07/2022 ( 1, 1) ( 1, 8) (2022,1) # antipodes +02/08/2022 ( 1, 1) ( 1, 8) (2022,2) # antipodes +30/12/2022 ( 1, 1) ( 1, 8) (2022,2) # antipodes +01/01/2022 ( 3, 1) ( 1, 8) (2021,2) # antipodes l'année scolaire démarre le 3 janvier +10/01/2024 ( 1, 8) ( 1, 2) (2023,2) # pivot période < pivot année +01/06/2024 ( 1, 8) ( 1, 2) (2023,2) # pivot période < pivot année +20/09/2024 ( 1, 8) ( 1, 2) (2024,1) # pivot période < pivot année +""" + + +def test_default(): + # with default + assert (2021, 2) == get_periode(datetime.datetime(2022, 1, 1)) + assert (2021, 2) == get_periode(datetime.datetime(2022, 1, 1), 1, 8, 1, 12) + + +def test_automne_nord(): + assert (2022, 1) == get_periode(datetime.datetime(2022, 9, 1)) + + +def test_noel_nord(): + assert (2022, 2) == get_periode(datetime.datetime(2022, 12, 15)) + + +def test_étét_nord(): + assert (2021, 2) == get_periode(datetime.datetime(2022, 7, 30)) + + +def test_printemps_sud(): + assert (2022, 1) == get_periode(datetime.datetime(2022, 1, 1), 1, 1, 1, 8) + + +def test_automne_sud(): + assert (2022, 2) == get_periode(datetime.datetime(2022, 8, 2), 1, 1, 1, 8) + + +def test_noel_sud(): + assert (2022, 2) == get_periode(datetime.datetime(2022, 12, 30), 1, 1, 1, 8) + + +def test_été_sud(): + assert (2022, 1) == get_periode(datetime.datetime(2022, 7, 30), 1, 1, 1, 8) + + +def test_nouvel_an_sud(): + assert (2021, 2) == get_periode(datetime.datetime(2022, 1, 1), 3, 1, 1, 8) + + +def test_nouvel_an_special_pp_before_pa(): + assert (2023, 1) == get_periode(datetime.datetime(2024, 1, 10), 1, 8, 1, 2) + + +def test_nouvel_été_pp_before_pa(): + assert (2023, 2) == get_periode(datetime.datetime(2024, 6, 1), 1, 8, 1, 2) + + +def test_automne_special_pp_before_pa(): + assert (2024, 1) == get_periode(datetime.datetime(2024, 9, 20), 1, 8, 1, 2) + + +sem_automne = {"date_debut_iso": "2022-09-24"} +sem_nouvel_an = {"date_debut_iso": "2023-01-01"} +sem_printemps = {"date_debut_iso": "2023-03-14"} +sem_été = {"date_debut_iso": "2023-07-11"} +sem_next_year = {"date_debut_iso": "2023-08-16"} +sem_prev_year = {"date_debut_iso": "2022-07-31"} + + +def test_sem_in_periode1_default(): + assert True == sem_in_semestre_scolaire(sem_automne, 2022, 1) + assert False == sem_in_semestre_scolaire(sem_nouvel_an, 2022, 1) + assert False == sem_in_semestre_scolaire(sem_printemps, 2022, 1) + assert False == sem_in_semestre_scolaire(sem_été, 2022, 1) + assert False == sem_in_semestre_scolaire(sem_next_year, 2022, 1) + assert False == sem_in_semestre_scolaire(sem_prev_year, 2022, 1) + + +def test_sem_in_periode2_default(): + assert False == sem_in_semestre_scolaire(sem_automne, 2022, 2) + assert True == sem_in_semestre_scolaire(sem_nouvel_an, 2022, 2) + assert True == sem_in_semestre_scolaire(sem_printemps, 2022, 2) + assert True == sem_in_semestre_scolaire(sem_été, 2022, 2) + assert False == sem_in_semestre_scolaire(sem_next_year, 2022, 1) + assert False == sem_in_semestre_scolaire(sem_prev_year, 2022, 1) + + +def test_sem_in_annee_default(): + assert True == sem_in_semestre_scolaire(sem_automne, 2022, 0) + assert True == sem_in_semestre_scolaire(sem_nouvel_an, 2022) + assert True == sem_in_semestre_scolaire(sem_printemps, 2022, 0) + assert True == sem_in_semestre_scolaire(sem_été, 2022, 0) + assert False == sem_in_semestre_scolaire(sem_next_year, 2022) + assert False == sem_in_semestre_scolaire(sem_prev_year, 2022, 0)