Assiduités : fix view_module_abs #688

This commit is contained in:
iziram 2023-09-05 14:25:38 +02:00
parent 4387727d2f
commit 6c77f7faca
5 changed files with 88 additions and 46 deletions

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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,

View File

@ -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]