forked from ScoDoc/ScoDoc
Assiduités : fix view_module_abs #688
This commit is contained in:
parent
4387727d2f
commit
6c77f7faca
@ -350,11 +350,15 @@ def compute_assiduites_justified(
|
||||
if justificatifs is None:
|
||||
justificatifs: Justificatif = Justificatif.query.filter_by(etudid=etudid).all()
|
||||
|
||||
justificatifs = [j for j in justificatifs if j.etat == EtatJustificatif.VALIDE]
|
||||
|
||||
assiduites: Assiduite = Assiduite.query.filter_by(etudid=etudid)
|
||||
|
||||
assiduites_justifiees: list[int] = []
|
||||
|
||||
for assi in assiduites:
|
||||
if assi.etat == EtatAssiduite.PRESENT:
|
||||
continue
|
||||
if any(
|
||||
assi.date_debut >= j.date_debut and assi.date_fin <= j.date_fin
|
||||
for j in justificatifs
|
||||
|
@ -212,7 +212,7 @@ def get_assiduites_stats(
|
||||
output: dict = {}
|
||||
calculator: CountCalculator = CountCalculator()
|
||||
|
||||
if "split" not in filtered:
|
||||
if filtered is None or "split" not in filtered:
|
||||
calculator.compute_assiduites(assiduites)
|
||||
count: dict = calculator.to_dict()
|
||||
|
||||
@ -382,7 +382,10 @@ def justifies(justi: Justificatif, obj: bool = False) -> list[int] or Query:
|
||||
|
||||
|
||||
def get_all_justified(
|
||||
etudid: int, date_deb: datetime = None, date_fin: datetime = None
|
||||
etudid: int,
|
||||
date_deb: datetime = None,
|
||||
date_fin: datetime = None,
|
||||
moduleimpl_id: int = None,
|
||||
) -> Query:
|
||||
"""Retourne toutes les assiduités justifiées sur une période"""
|
||||
|
||||
@ -393,7 +396,9 @@ def get_all_justified(
|
||||
|
||||
date_deb = scu.localize_datetime(date_deb)
|
||||
date_fin = scu.localize_datetime(date_fin)
|
||||
justified = Assiduite.query.filter_by(est_just=True, etudid=etudid)
|
||||
justified: Query = Assiduite.query.filter_by(est_just=True, etudid=etudid)
|
||||
if moduleimpl_id is not None:
|
||||
justified = justified.filter_by(moduleimpl_id=moduleimpl_id)
|
||||
after = filter_by_date(
|
||||
justified,
|
||||
Assiduite,
|
||||
@ -419,7 +424,7 @@ def get_assiduites_count(etudid: int, sem: dict) -> tuple[int, int]:
|
||||
|
||||
|
||||
def formsemestre_get_assiduites_count(
|
||||
etudid: int, formsemestre: FormSemestre
|
||||
etudid: int, formsemestre: FormSemestre, moduleimpl_id: int = None
|
||||
) -> tuple[int, int]:
|
||||
"""Les comptes d'absences de cet étudiant dans ce semestre:
|
||||
tuple (nb abs non justifiées, nb abs justifiées)
|
||||
@ -428,9 +433,14 @@ def formsemestre_get_assiduites_count(
|
||||
metrique = sco_preferences.get_preference("assi_metrique", formsemestre.id)
|
||||
return get_assiduites_count_in_interval(
|
||||
etudid,
|
||||
date_debut=formsemestre.date_debut,
|
||||
date_fin=formsemestre.date_fin,
|
||||
date_debut=scu.localize_datetime(
|
||||
datetime.combine(formsemestre.date_debut, time(8, 0))
|
||||
),
|
||||
date_fin=scu.localize_datetime(
|
||||
datetime.combine(formsemestre.date_fin, time(18, 0))
|
||||
),
|
||||
metrique=scu.translate_assiduites_metric(metrique),
|
||||
moduleimpl_id=moduleimpl_id,
|
||||
)
|
||||
|
||||
|
||||
@ -441,6 +451,7 @@ def get_assiduites_count_in_interval(
|
||||
metrique="demi",
|
||||
date_debut: datetime = None,
|
||||
date_fin: datetime = None,
|
||||
moduleimpl_id: int = None,
|
||||
):
|
||||
"""Les comptes d'absences de cet étudiant entre ces deux dates, incluses:
|
||||
tuple (nb abs, nb abs justifiées)
|
||||
@ -452,30 +463,41 @@ def get_assiduites_count_in_interval(
|
||||
key = f"{etudid}_{date_debut_iso}_{date_fin_iso}{metrique}_assiduites"
|
||||
|
||||
r = sco_cache.AbsSemEtudCache.get(key)
|
||||
if not r:
|
||||
if not r or moduleimpl_id is not None:
|
||||
date_debut: datetime = date_debut or datetime.fromisoformat(date_debut_iso)
|
||||
date_fin: datetime = date_fin or datetime.fromisoformat(date_fin_iso)
|
||||
|
||||
assiduites: Assiduite = Assiduite.query.filter_by(etudid=etudid)
|
||||
log(f"deb : {date_debut.isoformat()} fin: {date_fin.isoformat()}")
|
||||
|
||||
assiduites: Query = Assiduite.query.filter_by(etudid=etudid)
|
||||
assiduites = assiduites.filter(Assiduite.etat == scu.EtatAssiduite.ABSENT)
|
||||
justificatifs: Justificatif = Justificatif.query.filter_by(etudid=etudid)
|
||||
|
||||
assiduites = filter_by_date(assiduites, Assiduite, date_debut, date_fin)
|
||||
|
||||
if moduleimpl_id is not None:
|
||||
assiduites = assiduites.filter_by(moduleimpl_id=moduleimpl_id)
|
||||
|
||||
justificatifs = filter_by_date(
|
||||
justificatifs, Justificatif, date_debut, date_fin
|
||||
)
|
||||
|
||||
log(f"---assi---\n{[a.assiduite_id for a in assiduites]}")
|
||||
calculator: CountCalculator = CountCalculator()
|
||||
calculator.compute_assiduites(assiduites)
|
||||
nb_abs: dict = calculator.to_dict()[metrique]
|
||||
|
||||
abs_just: list[Assiduite] = get_all_justified(etudid, date_debut, date_fin)
|
||||
abs_just: list[Assiduite] = get_all_justified(
|
||||
etudid, date_debut, date_fin, moduleimpl_id
|
||||
)
|
||||
|
||||
log(f"---justi---\n{[a.assiduite_id for a in abs_just]}")
|
||||
|
||||
calculator.reset()
|
||||
calculator.compute_assiduites(abs_just)
|
||||
nb_abs_just: dict = calculator.to_dict()[metrique]
|
||||
|
||||
r = (nb_abs, nb_abs_just)
|
||||
if moduleimpl_id is None:
|
||||
ans = sco_cache.AbsSemEtudCache.set(key, r)
|
||||
if not ans:
|
||||
log("warning: get_assiduites_count failed to cache")
|
||||
|
@ -237,7 +237,7 @@ def localize_datetime(date: datetime.datetime or str) -> datetime.datetime:
|
||||
new_date: datetime.datetime = date
|
||||
if new_date.tzinfo is None:
|
||||
try:
|
||||
new_date = timezone("Europe/Paris").localize(date)
|
||||
new_date = TIME_ZONE.localize(date)
|
||||
except OverflowError:
|
||||
new_date = timezone("UTC").localize(date)
|
||||
return new_date
|
||||
|
@ -1174,22 +1174,9 @@ def view_module_abs(moduleimpl_id, fmt="html"):
|
||||
|
||||
rows = []
|
||||
for etud in inscrits:
|
||||
# TODO-ASSIDUITE ne va pas car ne filtre pas sur le moduleimpl
|
||||
# nb_abs, nb_abs_just = sco_assiduites.formsemestre_get_assiduites_count(etud.id, modimpl.formsemestre)
|
||||
nb_abs, nb_abs_just = 0, 0 # XXX TODO-ASSIDUITE
|
||||
# nb_abs = sco_abs.count_abs(
|
||||
# etudid=etud.id,
|
||||
# debut=debut_sem,
|
||||
# fin=fin_sem,
|
||||
# moduleimpl_id=moduleimpl_id,
|
||||
# )
|
||||
# if nb_abs:
|
||||
# nb_abs_just = sco_abs.count_abs_just(
|
||||
# etudid=etud.id,
|
||||
# debut=debut_sem,
|
||||
# fin=fin_sem,
|
||||
# moduleimpl_id=moduleimpl_id,
|
||||
# )
|
||||
nb_abs, nb_abs_just = sco_assiduites.formsemestre_get_assiduites_count(
|
||||
etud.id, modimpl.formsemestre, moduleimpl_id=modimpl.id
|
||||
)
|
||||
rows.append(
|
||||
{
|
||||
"nomprenom": etud.nomprenom,
|
||||
|
@ -13,8 +13,7 @@ import app.scodoc.sco_assiduites as scass
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app import db
|
||||
from app.models import Assiduite, FormSemestre, Identite, Justificatif, ModuleImpl
|
||||
|
||||
# from app.scodoc import sco_abs_views, sco_formsemestre TODO-ASSIDUITE
|
||||
from app.models.assiduites import compute_assiduites_justified
|
||||
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from tests.unit import sco_fake_gen
|
||||
@ -39,7 +38,7 @@ def test_bi_directional_enum(test_client):
|
||||
assert BiInt.inverse()[1] == BiInt.A and BiInt.inverse()[2] == BiInt.B
|
||||
|
||||
|
||||
@pytest.mark.skip # XXX TODO-ASSIDUITE (issue #690)
|
||||
# @pytest.mark.skip # XXX TODO-ASSIDUITE (issue #690)
|
||||
def test_general(test_client):
|
||||
"""tests général du modèle assiduite"""
|
||||
|
||||
@ -80,11 +79,11 @@ def test_general(test_client):
|
||||
date_fin="31/07/2024",
|
||||
)
|
||||
|
||||
formsemestre_1 = sco_formsemestre.get_formsemestre(
|
||||
formsemestre_1 = FormSemestre.get_formsemestre(
|
||||
formsemestre_id_1
|
||||
) # Utiliser plutot FormSemestre de nos jours TODO-ASSIDUITE
|
||||
formsemestre_2 = sco_formsemestre.get_formsemestre(formsemestre_id_2)
|
||||
formsemestre_3 = sco_formsemestre.get_formsemestre(formsemestre_id_3)
|
||||
formsemestre_2 = FormSemestre.get_formsemestre(formsemestre_id_2)
|
||||
formsemestre_3 = FormSemestre.get_formsemestre(formsemestre_id_3)
|
||||
|
||||
# Création des modulesimpls (4, 2 par semestre)
|
||||
|
||||
@ -145,11 +144,14 @@ def test_general(test_client):
|
||||
etuds, moduleimpls, (formsemestre_1, formsemestre_2, formsemestre_3)
|
||||
)
|
||||
verifier_filtrage_justificatifs(etuds[0], justificatifs)
|
||||
|
||||
essais_cache(etuds[0].etudid, (formsemestre_1, formsemestre_2), moduleimpls)
|
||||
|
||||
editer_supprimer_assiduites(etuds, moduleimpls)
|
||||
editer_supprimer_justificatif(etuds[0])
|
||||
|
||||
|
||||
@pytest.mark.skip # XXX TODO-ASSIDUITE (issue #696)
|
||||
# XXX TODO-ASSIDUITE (issue #696)
|
||||
def verif_migration_abs_assiduites():
|
||||
"""Vérification que le script de migration fonctionne correctement"""
|
||||
downgrade_module(assiduites=True, justificatifs=True)
|
||||
@ -476,11 +478,11 @@ def _get_justi(
|
||||
).first()
|
||||
|
||||
|
||||
def essais_cache(etudid):
|
||||
def essais_cache(etudid, sems: tuple[FormSemestre], moduleimpls: list[ModuleImpl]):
|
||||
"""Vérification des fonctionnalités du cache"""
|
||||
|
||||
date_deb: str = "2023-01-01T07:00"
|
||||
date_fin: str = "2023-03-31T19:00"
|
||||
date_deb: str = "2022-09-01T07:00"
|
||||
date_fin: str = "2023-01-31T19:00"
|
||||
|
||||
assiduites_count_no_cache = scass.get_assiduites_count_in_interval(
|
||||
etudid, date_deb, date_fin
|
||||
@ -490,8 +492,36 @@ def essais_cache(etudid):
|
||||
)
|
||||
|
||||
assert (
|
||||
assiduites_count_cache == assiduites_count_no_cache == (34, 15)
|
||||
), "Erreur cache"
|
||||
assiduites_count_cache == assiduites_count_no_cache == (2, 1)
|
||||
), "Erreur cache classique"
|
||||
|
||||
assert scass.formsemestre_get_assiduites_count(etudid, sems[0]) == (
|
||||
2,
|
||||
1,
|
||||
), "Erreur formsemestre_get_assiduites_count (sans module) A"
|
||||
assert scass.formsemestre_get_assiduites_count(etudid, sems[1]) == (
|
||||
0,
|
||||
0,
|
||||
), "Erreur formsemestre_get_assiduites_count (sans module) B"
|
||||
|
||||
assert scass.formsemestre_get_assiduites_count(
|
||||
etudid, sems[0], moduleimpl_id=moduleimpls[0].id
|
||||
) == (
|
||||
1,
|
||||
1,
|
||||
), "Erreur formsemestre_get_assiduites_count (avec module) A"
|
||||
assert scass.formsemestre_get_assiduites_count(
|
||||
etudid, sems[0], moduleimpl_id=moduleimpls[1].id
|
||||
) == (
|
||||
1,
|
||||
0,
|
||||
), "Erreur formsemestre_get_assiduites_count (avec module) A"
|
||||
assert scass.formsemestre_get_assiduites_count(
|
||||
etudid, sems[0], moduleimpl_id=moduleimpls[2].id
|
||||
) == (
|
||||
0,
|
||||
0,
|
||||
), "Erreur formsemestre_get_assiduites_count (avec module) A"
|
||||
|
||||
|
||||
def ajouter_justificatifs(etud):
|
||||
@ -543,6 +573,8 @@ def ajouter_justificatifs(etud):
|
||||
db.session.commit()
|
||||
justificatifs.append(just_obj)
|
||||
|
||||
compute_assiduites_justified(etud.etudid, justificatifs)
|
||||
|
||||
# Vérification de la création des justificatifs
|
||||
assert [
|
||||
justi for justi in justificatifs if not isinstance(justi, Justificatif)
|
||||
@ -858,7 +890,7 @@ def ajouter_assiduites(
|
||||
|
||||
|
||||
def verifier_comptage_et_filtrage_assiduites(
|
||||
etuds: list[Identite], moduleimpls: list[int], formsemestres: tuple[int]
|
||||
etuds: list[Identite], moduleimpls: list[int], formsemestres: tuple[FormSemestre]
|
||||
):
|
||||
"""
|
||||
Deuxième partie:
|
||||
@ -931,9 +963,6 @@ def verifier_comptage_et_filtrage_assiduites(
|
||||
), "Filtrage par 'Moduleimpl' mauvais"
|
||||
|
||||
# Formsemestre
|
||||
formsemestres = [
|
||||
FormSemestre.query.filter_by(id=fms["id"]).first() for fms in formsemestres
|
||||
]
|
||||
assert (
|
||||
scass.filter_by_formsemestre(
|
||||
etu1.assiduites, Assiduite, formsemestres[0]
|
||||
|
Loading…
Reference in New Issue
Block a user