Modif gestion dates annees scolaire pour mieux gérer l'hémisphère sud.
This commit is contained in:
parent
b6344c27a8
commit
bb99cd8aa6
@ -526,7 +526,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
|||||||
return formsemestre.annee_scolaire()
|
return formsemestre.annee_scolaire()
|
||||||
|
|
||||||
def annee_scolaire_str(self) -> str:
|
def annee_scolaire_str(self) -> str:
|
||||||
"L'année scolaire, eg '2021 - 2022'"
|
"L'année scolaire, eg '2021 - 2022' ou '2021' en hémisphère sud"
|
||||||
formsemestre = self.formsemestre_impair or self.formsemestre_pair
|
formsemestre = self.formsemestre_impair or self.formsemestre_pair
|
||||||
return formsemestre.annee_scolaire_str().replace(" ", "")
|
return formsemestre.annee_scolaire_str().replace(" ", "")
|
||||||
|
|
||||||
|
@ -355,7 +355,9 @@ class ScoDocSiteConfig(models.ScoDocModel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_month_debut_periode2(cls) -> int:
|
def get_month_debut_periode2(cls) -> int:
|
||||||
"""Mois de début de l'année scolaire."""
|
"""Mois de début de la seconde période (semestre) de l'année.
|
||||||
|
Par défaut, 12 (décembre). Sera souvent juillet en hémisphère sud.
|
||||||
|
"""
|
||||||
return cls._get_int_field("month_debut_periode2", scu.MONTH_DEBUT_PERIODE2)
|
return cls._get_int_field("month_debut_periode2", scu.MONTH_DEBUT_PERIODE2)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -699,18 +699,27 @@ class FormSemestre(models.ScoDocModel):
|
|||||||
"""
|
"""
|
||||||
if self.semestre_id <= 0:
|
if self.semestre_id <= 0:
|
||||||
return False # formations sans semestres
|
return False # formations sans semestres
|
||||||
|
# août (8) en métropole, janvier (1) en hémisphère sud:
|
||||||
|
month_debut = ScoDocSiteConfig.get_month_debut_annee_scolaire()
|
||||||
|
if month_debut < 4:
|
||||||
|
# Hémisphère sud: utilise date début deuxième période
|
||||||
|
# typiquement juillet
|
||||||
|
pivot = ScoDocSiteConfig.get_month_debut_periode2()
|
||||||
|
return (
|
||||||
|
# impair commençaant en fin d'année civile
|
||||||
|
(self.semestre_id % 2 and self.date_debut.month >= pivot)
|
||||||
|
or
|
||||||
|
# pair commençant en début d'année civile
|
||||||
|
((not self.semestre_id % 2) and self.date_debut.month < pivot)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Hémisphère nord
|
||||||
return (
|
return (
|
||||||
# impair
|
# impair
|
||||||
(
|
(self.semestre_id % 2 and self.date_debut.month < month_debut)
|
||||||
self.semestre_id % 2
|
|
||||||
and self.date_debut.month < scu.MONTH_DEBUT_ANNEE_SCOLAIRE
|
|
||||||
)
|
|
||||||
or
|
or
|
||||||
# pair
|
# pair
|
||||||
(
|
((not self.semestre_id % 2) and self.date_debut.month >= month_debut)
|
||||||
(not self.semestre_id % 2)
|
|
||||||
and self.date_debut.month >= scu.MONTH_DEBUT_ANNEE_SCOLAIRE
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -719,8 +728,8 @@ class FormSemestre(models.ScoDocModel):
|
|||||||
date_debut: datetime.date,
|
date_debut: datetime.date,
|
||||||
year=False,
|
year=False,
|
||||||
periode=None,
|
periode=None,
|
||||||
mois_pivot_annee=scu.MONTH_DEBUT_ANNEE_SCOLAIRE,
|
mois_pivot_annee: int | None = None,
|
||||||
mois_pivot_periode=scu.MONTH_DEBUT_PERIODE2,
|
mois_pivot_periode: int | None = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Vrai si la date_debut est dans la période indiquée (1,2,0)
|
"""Vrai si la date_debut est dans la période indiquée (1,2,0)
|
||||||
du semestre `periode` de l'année scolaire indiquée
|
du semestre `periode` de l'année scolaire indiquée
|
||||||
@ -734,6 +743,10 @@ class FormSemestre(models.ScoDocModel):
|
|||||||
"""
|
"""
|
||||||
if not year:
|
if not year:
|
||||||
year = scu.annee_scolaire()
|
year = scu.annee_scolaire()
|
||||||
|
if mois_pivot_annee is None:
|
||||||
|
mois_pivot_annee = ScoDocSiteConfig.get_month_debut_annee_scolaire()
|
||||||
|
if mois_pivot_periode is None:
|
||||||
|
mois_pivot_periode = ScoDocSiteConfig.get_month_debut_periode2()
|
||||||
# n'utilise pas le jour pivot
|
# n'utilise pas le jour pivot
|
||||||
jour_pivot_annee = jour_pivot_periode = 1
|
jour_pivot_annee = jour_pivot_periode = 1
|
||||||
# calcule l'année universitaire et la période
|
# calcule l'année universitaire et la période
|
||||||
@ -758,10 +771,10 @@ class FormSemestre(models.ScoDocModel):
|
|||||||
def comp_periode(
|
def comp_periode(
|
||||||
cls,
|
cls,
|
||||||
date_debut: datetime,
|
date_debut: datetime,
|
||||||
mois_pivot_annee=scu.MONTH_DEBUT_ANNEE_SCOLAIRE,
|
mois_pivot_annee: int | None = None,
|
||||||
mois_pivot_periode=scu.MONTH_DEBUT_PERIODE2,
|
mois_pivot_periode: int | None = None,
|
||||||
jour_pivot_annee=1,
|
jour_pivot_annee: int = 1,
|
||||||
jour_pivot_periode=1,
|
jour_pivot_periode: int = 1,
|
||||||
) -> tuple[int, int]:
|
) -> tuple[int, int]:
|
||||||
"""Calcule la session associée à un formsemestre commençant en date_debut
|
"""Calcule la session associée à un formsemestre commençant en date_debut
|
||||||
sous la forme (année, période)
|
sous la forme (année, période)
|
||||||
@ -782,6 +795,10 @@ class FormSemestre(models.ScoDocModel):
|
|||||||
pp < pa -----------------|-------------------|---------------->
|
pp < pa -----------------|-------------------|---------------->
|
||||||
(A-1, P:1) pp (A-1, P:2) pa (A, P:1)
|
(A-1, P:1) pp (A-1, P:2) pa (A, P:1)
|
||||||
"""
|
"""
|
||||||
|
if mois_pivot_annee is None:
|
||||||
|
mois_pivot_annee = ScoDocSiteConfig.get_month_debut_annee_scolaire()
|
||||||
|
if mois_pivot_periode is None:
|
||||||
|
mois_pivot_periode = ScoDocSiteConfig.get_month_debut_periode2()
|
||||||
pivot_annee = 100 * mois_pivot_annee + jour_pivot_annee
|
pivot_annee = 100 * mois_pivot_annee + jour_pivot_annee
|
||||||
pivot_periode = 100 * mois_pivot_periode + jour_pivot_periode
|
pivot_periode = 100 * mois_pivot_periode + jour_pivot_periode
|
||||||
pivot_sem = 100 * date_debut.month + date_debut.day
|
pivot_sem = 100 * date_debut.month + date_debut.day
|
||||||
@ -930,7 +947,7 @@ class FormSemestre(models.ScoDocModel):
|
|||||||
return scu.annee_scolaire_debut(self.date_debut.year, self.date_debut.month)
|
return scu.annee_scolaire_debut(self.date_debut.year, self.date_debut.month)
|
||||||
|
|
||||||
def annee_scolaire_str(self):
|
def annee_scolaire_str(self):
|
||||||
"2021 - 2022"
|
"""2021 - 2022 (ou "2021" si hémisphère sud)"""
|
||||||
return scu.annee_scolaire_repr(self.date_debut.year, self.date_debut.month)
|
return scu.annee_scolaire_repr(self.date_debut.year, self.date_debut.month)
|
||||||
|
|
||||||
def mois_debut(self) -> str:
|
def mois_debut(self) -> str:
|
||||||
|
@ -778,7 +778,7 @@ class CursusMasterLMD(TypeCursus):
|
|||||||
TYPE_CURSUS = CodesCursus.MasterLMD
|
TYPE_CURSUS = CodesCursus.MasterLMD
|
||||||
NAME = "Master LMD"
|
NAME = "Master LMD"
|
||||||
NB_SEM = 4
|
NB_SEM = 4
|
||||||
COMPENSATION_UE = True # variabale inutilisée
|
COMPENSATION_UE = True # variable inutilisée
|
||||||
UNUSED_CODES = set((ADC, ATT, ATB))
|
UNUSED_CODES = set((ADC, ATT, ATB))
|
||||||
|
|
||||||
|
|
||||||
|
@ -1429,13 +1429,23 @@ def timedate_human_repr():
|
|||||||
|
|
||||||
|
|
||||||
def annee_scolaire_repr(year, month):
|
def annee_scolaire_repr(year, month):
|
||||||
"""representation de l'annee scolaire : '2009 - 2010'
|
"""Représentation de l'annee scolaire : '2009 - 2010'
|
||||||
à partir d'une date.
|
à partir d'une date.
|
||||||
|
Dans l'hémisphère sud, l'année scolaire coincide avec l'année civile.
|
||||||
|
On considère que si le mois de début de l'année scolaire est au
|
||||||
|
premier trimestre (jan-fev-mar), alors l'affichage n'indique que l'année
|
||||||
|
en cours (eg "2024").
|
||||||
"""
|
"""
|
||||||
if month >= MONTH_DEBUT_ANNEE_SCOLAIRE: # apres le 1er aout
|
from app.models.config import ScoDocSiteConfig
|
||||||
|
|
||||||
|
month_debut = ScoDocSiteConfig.get_month_debut_annee_scolaire()
|
||||||
|
if month_debut < 4:
|
||||||
|
# Hémisphère sud:
|
||||||
|
return str(year) if month >= month_debut else str(year - 1)
|
||||||
|
# Hémisphère nord
|
||||||
|
if month >= month_debut: # par ex. apres le 1er aout
|
||||||
return f"{year} - {year + 1}"
|
return f"{year} - {year + 1}"
|
||||||
else:
|
return f"{year - 1} - {year}"
|
||||||
return f"{year - 1} - {year}"
|
|
||||||
|
|
||||||
|
|
||||||
def annee_scolaire() -> int:
|
def annee_scolaire() -> int:
|
||||||
@ -1450,10 +1460,12 @@ def annee_scolaire_debut(year, month) -> int:
|
|||||||
Par défaut (hémisphère nord), l'année du mois de août
|
Par défaut (hémisphère nord), l'année du mois de août
|
||||||
précédent la date indiquée.
|
précédent la date indiquée.
|
||||||
"""
|
"""
|
||||||
if int(month) >= MONTH_DEBUT_ANNEE_SCOLAIRE:
|
from app.models.config import ScoDocSiteConfig
|
||||||
|
|
||||||
|
month_debut = ScoDocSiteConfig.get_month_debut_annee_scolaire()
|
||||||
|
if int(month) >= month_debut:
|
||||||
return int(year)
|
return int(year)
|
||||||
else:
|
return int(year) - 1
|
||||||
return int(year) - 1
|
|
||||||
|
|
||||||
|
|
||||||
def date_debut_annee_scolaire(annee_sco: int | None = None) -> datetime.datetime:
|
def date_debut_annee_scolaire(annee_sco: int | None = None) -> datetime.datetime:
|
||||||
@ -1461,11 +1473,15 @@ def date_debut_annee_scolaire(annee_sco: int | None = None) -> datetime.datetime
|
|||||||
Si annee_sco n'est pas spécifié, année courante
|
Si annee_sco n'est pas spécifié, année courante
|
||||||
(par défaut, l'année scolaire en métropole commence le 1er aout)
|
(par défaut, l'année scolaire en métropole commence le 1er aout)
|
||||||
"""
|
"""
|
||||||
|
from app.models.config import ScoDocSiteConfig
|
||||||
|
|
||||||
if annee_sco is None:
|
if annee_sco is None:
|
||||||
annee_sco = annee_scolaire()
|
annee_sco = annee_scolaire()
|
||||||
try:
|
try:
|
||||||
return datetime.datetime(
|
return datetime.datetime(
|
||||||
year=annee_sco, month=MONTH_DEBUT_ANNEE_SCOLAIRE, day=1
|
year=annee_sco,
|
||||||
|
month=ScoDocSiteConfig.get_month_debut_annee_scolaire(),
|
||||||
|
day=1,
|
||||||
)
|
)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise ScoValueError("année scolaire invalide") from exc
|
raise ScoValueError("année scolaire invalide") from exc
|
||||||
@ -1478,11 +1494,15 @@ def date_fin_annee_scolaire(annee_sco: int | None = None) -> datetime.datetime:
|
|||||||
# on prend la date de début de l'année scolaire suivante,
|
# on prend la date de début de l'année scolaire suivante,
|
||||||
# et on lui retire 1 jour.
|
# et on lui retire 1 jour.
|
||||||
# On s'affranchit ainsi des problèmes de durées de mois.
|
# On s'affranchit ainsi des problèmes de durées de mois.
|
||||||
|
from app.models.config import ScoDocSiteConfig
|
||||||
|
|
||||||
if annee_sco is None:
|
if annee_sco is None:
|
||||||
annee_sco = annee_scolaire()
|
annee_sco = annee_scolaire()
|
||||||
try:
|
try:
|
||||||
return datetime.datetime(
|
return datetime.datetime(
|
||||||
year=annee_sco + 1, month=MONTH_DEBUT_ANNEE_SCOLAIRE, day=1
|
year=annee_sco + 1,
|
||||||
|
month=ScoDocSiteConfig.get_month_debut_annee_scolaire(),
|
||||||
|
day=1,
|
||||||
) - datetime.timedelta(days=1)
|
) - datetime.timedelta(days=1)
|
||||||
except (TypeError, ValueError) as exc:
|
except (TypeError, ValueError) as exc:
|
||||||
raise ScoValueError("année scolaire invalide") from exc
|
raise ScoValueError("année scolaire invalide") from exc
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"""Test Periodes
|
"""Test Periodes
|
||||||
|
|
||||||
Utiliser comme:
|
Utiliser comme:
|
||||||
pytest tests/unit/test_periode.py
|
pytest tests/unit/_test_periode.py
|
||||||
|
|
||||||
Calcule la session associée à un formsemestre sous la forme (année, période)
|
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
|
année: première année de l'année scolaire
|
||||||
@ -32,8 +32,30 @@ import datetime
|
|||||||
from app.models import FormSemestre
|
from app.models import FormSemestre
|
||||||
from app.scodoc.sco_formsemestre import sem_in_semestre_scolaire
|
from app.scodoc.sco_formsemestre import sem_in_semestre_scolaire
|
||||||
|
|
||||||
|
# Nota: pour accélerer (éviter de recrer l'app),
|
||||||
|
# on regroupe ces petits tests dans une seule fonction
|
||||||
|
|
||||||
def test_default():
|
|
||||||
|
def test_periode(test_client):
|
||||||
|
"Joue tous les tests de ce module"
|
||||||
|
_test_default()
|
||||||
|
_test_automne_nord()
|
||||||
|
_test_noel_nord()
|
||||||
|
_test_ete_nord()
|
||||||
|
_test_printemps_sud()
|
||||||
|
_test_automne_sud()
|
||||||
|
_test_noel_sud()
|
||||||
|
_test_ete_sud()
|
||||||
|
_test_nouvel_an_sud()
|
||||||
|
_test_nouvel_an_special_pp_before_pa()
|
||||||
|
_test_nouvel_ete_pp_before_pa()
|
||||||
|
_test_automne_special_pp_before_pa()
|
||||||
|
_test_sem_in_periode1_default()
|
||||||
|
_test_sem_in_periode2_default()
|
||||||
|
_test_sem_in_annee_default()
|
||||||
|
|
||||||
|
|
||||||
|
def _test_default():
|
||||||
# with default
|
# with default
|
||||||
assert (2021, 2) == FormSemestre.comp_periode(datetime.datetime(2022, 1, 1))
|
assert (2021, 2) == FormSemestre.comp_periode(datetime.datetime(2022, 1, 1))
|
||||||
assert (2021, 2) == FormSemestre.comp_periode(
|
assert (2021, 2) == FormSemestre.comp_periode(
|
||||||
@ -41,59 +63,59 @@ def test_default():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_automne_nord():
|
def _test_automne_nord():
|
||||||
assert (2022, 1) == FormSemestre.comp_periode(datetime.datetime(2022, 9, 1))
|
assert (2022, 1) == FormSemestre.comp_periode(datetime.datetime(2022, 9, 1))
|
||||||
|
|
||||||
|
|
||||||
def test_noel_nord():
|
def _test_noel_nord():
|
||||||
assert (2022, 2) == FormSemestre.comp_periode(datetime.datetime(2022, 12, 15))
|
assert (2022, 2) == FormSemestre.comp_periode(datetime.datetime(2022, 12, 15))
|
||||||
|
|
||||||
|
|
||||||
def test_ete_nord():
|
def _test_ete_nord():
|
||||||
assert (2021, 2) == FormSemestre.comp_periode(datetime.datetime(2022, 7, 30))
|
assert (2021, 2) == FormSemestre.comp_periode(datetime.datetime(2022, 7, 30))
|
||||||
|
|
||||||
|
|
||||||
def test_printemps_sud():
|
def _test_printemps_sud():
|
||||||
assert (2022, 1) == FormSemestre.comp_periode(
|
assert (2022, 1) == FormSemestre.comp_periode(
|
||||||
datetime.datetime(2022, 1, 1), 1, 1, 1, 8
|
datetime.datetime(2022, 1, 1), 1, 1, 1, 8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_automne_sud():
|
def _test_automne_sud():
|
||||||
assert (2022, 2) == FormSemestre.comp_periode(
|
assert (2022, 2) == FormSemestre.comp_periode(
|
||||||
datetime.datetime(2022, 8, 2), 1, 8, 1, 1
|
datetime.datetime(2022, 8, 2), 1, 8, 1, 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_noel_sud():
|
def _test_noel_sud():
|
||||||
assert (2022, 2) == FormSemestre.comp_periode(
|
assert (2022, 2) == FormSemestre.comp_periode(
|
||||||
datetime.datetime(2022, 12, 30), 1, 8, 1, 1
|
datetime.datetime(2022, 12, 30), 1, 8, 1, 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_ete_sud():
|
def _test_ete_sud():
|
||||||
assert (2022, 1) == FormSemestre.comp_periode(
|
assert (2022, 1) == FormSemestre.comp_periode(
|
||||||
datetime.datetime(2022, 7, 30), 1, 8, 1, 1
|
datetime.datetime(2022, 7, 30), 1, 8, 1, 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_nouvel_an_sud():
|
def _test_nouvel_an_sud():
|
||||||
assert (2021, 2) == FormSemestre.comp_periode(
|
assert (2021, 2) == FormSemestre.comp_periode(
|
||||||
datetime.datetime(2022, 1, 1), 3, 8, 1, 1
|
datetime.datetime(2022, 1, 1), 3, 8, 1, 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_nouvel_an_special_pp_before_pa():
|
def _test_nouvel_an_special_pp_before_pa():
|
||||||
assert (2023, 1) == FormSemestre.comp_periode(
|
assert (2023, 1) == FormSemestre.comp_periode(
|
||||||
datetime.datetime(2024, 1, 10), 8, 2, 1, 1
|
datetime.datetime(2024, 1, 10), 8, 2, 1, 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_nouvel_ete_pp_before_pa():
|
def _test_nouvel_ete_pp_before_pa():
|
||||||
assert (2023, 2) == FormSemestre.comp_periode(datetime.datetime(2024, 6, 1), 8, 2)
|
assert (2023, 2) == FormSemestre.comp_periode(datetime.datetime(2024, 6, 1), 8, 2)
|
||||||
|
|
||||||
|
|
||||||
def test_automne_special_pp_before_pa():
|
def _test_automne_special_pp_before_pa():
|
||||||
assert (2024, 1) == FormSemestre.comp_periode(datetime.datetime(2024, 9, 20), 8, 2)
|
assert (2024, 1) == FormSemestre.comp_periode(datetime.datetime(2024, 9, 20), 8, 2)
|
||||||
|
|
||||||
|
|
||||||
@ -105,7 +127,7 @@ sem_next_year = {"date_debut_iso": "2023-08-16"}
|
|||||||
sem_prev_year = {"date_debut_iso": "2022-07-31"}
|
sem_prev_year = {"date_debut_iso": "2022-07-31"}
|
||||||
|
|
||||||
|
|
||||||
def test_sem_in_periode1_default():
|
def _test_sem_in_periode1_default():
|
||||||
assert True is sem_in_semestre_scolaire(sem_automne, 2022, 1)
|
assert True is sem_in_semestre_scolaire(sem_automne, 2022, 1)
|
||||||
assert False is sem_in_semestre_scolaire(sem_nouvel_an, 2022, 1)
|
assert False is sem_in_semestre_scolaire(sem_nouvel_an, 2022, 1)
|
||||||
assert False is sem_in_semestre_scolaire(sem_printemps, 2022, 1)
|
assert False is sem_in_semestre_scolaire(sem_printemps, 2022, 1)
|
||||||
@ -114,7 +136,7 @@ def test_sem_in_periode1_default():
|
|||||||
assert False is sem_in_semestre_scolaire(sem_prev_year, 2022, 1)
|
assert False is sem_in_semestre_scolaire(sem_prev_year, 2022, 1)
|
||||||
|
|
||||||
|
|
||||||
def test_sem_in_periode2_default():
|
def _test_sem_in_periode2_default():
|
||||||
assert False is sem_in_semestre_scolaire(sem_automne, 2022, 2)
|
assert False is sem_in_semestre_scolaire(sem_automne, 2022, 2)
|
||||||
assert True is sem_in_semestre_scolaire(sem_nouvel_an, 2022, 2)
|
assert True is sem_in_semestre_scolaire(sem_nouvel_an, 2022, 2)
|
||||||
assert True is sem_in_semestre_scolaire(sem_printemps, 2022, 2)
|
assert True is sem_in_semestre_scolaire(sem_printemps, 2022, 2)
|
||||||
@ -123,7 +145,7 @@ def test_sem_in_periode2_default():
|
|||||||
assert False is sem_in_semestre_scolaire(sem_prev_year, 2022, 1)
|
assert False is sem_in_semestre_scolaire(sem_prev_year, 2022, 1)
|
||||||
|
|
||||||
|
|
||||||
def test_sem_in_annee_default():
|
def _test_sem_in_annee_default():
|
||||||
assert True is sem_in_semestre_scolaire(sem_automne, 2022, 0)
|
assert True is sem_in_semestre_scolaire(sem_automne, 2022, 0)
|
||||||
assert True is sem_in_semestre_scolaire(sem_nouvel_an, 2022)
|
assert True is sem_in_semestre_scolaire(sem_nouvel_an, 2022)
|
||||||
assert True is sem_in_semestre_scolaire(sem_printemps, 2022, 0)
|
assert True is sem_in_semestre_scolaire(sem_printemps, 2022, 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user