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