1
0
forked from ScoDoc/ScoDoc
ScoDoc-Front/app/scodoc/sco_assiduites.py

129 lines
4.0 KiB
Python
Raw Normal View History

from app.models.etudiants import Identite
from app.models.formsemestre import FormSemestre
from app.models.assiduites import Assiduite
import app.scodoc.sco_utils as scu
from datetime import datetime, date, time, timedelta
# TOTALK: Réfléchir sur le fractionnement d'une assiduite prolongée
def get_assiduites_stats(
assiduites: Assiduite, metric: str = "all", filter: dict[str, object] = {}
) -> Assiduite:
if filter != {}:
for key in filter:
if key == "etat":
assiduites = filter_by_etat(assiduites, filter[key])
elif key == "date_fin":
assiduites = filter_by_date(assiduites, filter[key], sup=False)
elif key == "date_debut":
assiduites = filter_by_date(assiduites, filter[key], sup=True)
elif key == "moduleimpl_id":
assiduites = filter_by_module_impl(assiduites, filter[key])
elif key == "formsemestre":
assiduites = filter_by_formsemstre(assiduites, filter[key])
count: dict = get_count(assiduites)
metrics: list[str] = metric.split(",")
output: dict = {}
for key in count:
if key in metrics:
output[key] = count[key]
return output if output != {} else count
def get_count(assiduites: Assiduite) -> dict[str, int or float]:
output: dict[str, int or float] = {}
output["compte"] = assiduites.count()
output["heure"] = 0.0
output["journee"] = 0
output["demi"] = 0
all_assiduites: list[Assiduite] = assiduites.order_by(Assiduite.date_debut).all()
current_day: date = None
current_time: str = None
MIDNIGHT: time = time(hour=0)
NOON: time = time(hour=12)
time_check = lambda d: (MIDNIGHT <= d.time() <= NOON)
for ass in all_assiduites:
delta: timedelta = ass.date_fin - ass.date_debut
output["heure"] += delta.total_seconds() / 3600
ass_time: str = time_check(ass.date_debut)
if current_day != ass.date_debut.date():
current_day = ass.date_debut.date()
current_time = ass_time
output["demi"] += 1
output["journee"] += 1
if current_time != ass_time:
current_time = ass_time
output["demi"] += 1
output["heure"] = round(output["heure"], 2)
return output
def filter_by_etat(assiduites: Assiduite, etat: str) -> Assiduite:
"""
Filtrage d'une collection d'assiduites en fonction de leur état
"""
etats: list[str] = list(etat.split(","))
2022-12-19 21:32:45 +01:00
etats = [scu.ETATS_ASSIDUITE.get(e, -1) for e in etats]
return assiduites.filter(Assiduite.etat.in_(etats))
def filter_by_date(
assiduites: Assiduite, date: datetime, sup: bool = True
) -> Assiduite:
"""
Filtrage d'une collection d'assiduites en fonction d'une date
Sup == True -> les assiduites doivent débuter après 'date'\n
Sup == False -> les assiduites doivent finir avant 'date'
"""
if date.tzinfo is None:
first_assiduite: Assiduite = assiduites.first()
if first_assiduite is not None:
date: datetime = date.replace(tzinfo=first_assiduite.date_debut.tzinfo)
if sup:
return assiduites.filter(Assiduite.date_debut >= date)
else:
return assiduites.filter(Assiduite.date_fin <= date)
def filter_by_module_impl(
assiduites: Assiduite, module_impl_id: int or None
) -> Assiduite:
"""
Filtrage d'une collection d'assiduites en fonction de l'ID du module_impl
"""
return assiduites.filter(Assiduite.moduleimpl_id == module_impl_id)
def filter_by_formsemstre(assiduites: Assiduite, formsemestre: FormSemestre):
"""
Filtrage d'une collection d'assiduites en fonction d'un formsemestre
"""
if formsemestre is None:
return assiduites.filter(False)
assiduites = assiduites.filter(
Identite.query.filter_by(id=Assiduite.etudid).first()
in formsemestre.etuds.all()
)
assiduites = assiduites.filter(Assiduite.date_debut >= formsemestre.date_debut)
return assiduites.filter(Assiduite.date_fin <= formsemestre.date_fin)