forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -119,9 +119,13 @@ def check_ics_regexp(form, field):
|
||||
class ConfigAssiduitesForm(FlaskForm):
|
||||
"Formulaire paramétrage Module Assiduité"
|
||||
|
||||
morning_time = TimeField("Début de la journée")
|
||||
lunch_time = TimeField("Heure de midi (date pivot entre Matin et Après Midi)")
|
||||
afternoon_time = TimeField("Fin de la journée")
|
||||
morning_time = TimeField(
|
||||
"Début de la journée"
|
||||
) # TODO utiliser TextField + timepicker voir AjoutAssiOrJustForm
|
||||
lunch_time = TimeField(
|
||||
"Heure de midi (date pivot entre matin et après-midi)"
|
||||
) # TODO
|
||||
afternoon_time = TimeField("Fin de la journée") # TODO
|
||||
|
||||
tick_time = DecimalField(
|
||||
"Granularité de la timeline (temps en minutes)",
|
||||
|
@ -20,13 +20,15 @@ from app.scodoc import sco_etud
|
||||
class CountCalculator:
|
||||
"""Classe qui gére le comptage des assiduités"""
|
||||
|
||||
# TODO documenter
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
morning: time = time(8, 0),
|
||||
morning: time = time(8, 0), # TODO utiliser ScoDocSiteConfig
|
||||
noon: time = time(12, 0),
|
||||
after_noon: time = time(14, 00),
|
||||
evening: time = time(18, 0),
|
||||
skip_saturday: bool = True,
|
||||
skip_saturday: bool = True, # TODO préférence workdays
|
||||
) -> None:
|
||||
self.morning: time = morning
|
||||
self.noon: time = noon
|
||||
@ -50,14 +52,14 @@ class CountCalculator:
|
||||
self.count: int = 0
|
||||
|
||||
def reset(self):
|
||||
"""Remet à zero le compteur"""
|
||||
"""Remet à zero les compteurs"""
|
||||
self.days = []
|
||||
self.half_days = []
|
||||
self.hours = 0.0
|
||||
self.count = 0
|
||||
|
||||
def add_half_day(self, day: date, is_morning: bool = True):
|
||||
"""Ajoute une demi journée dans le comptage"""
|
||||
"""Ajoute une demi-journée dans le comptage"""
|
||||
key: tuple[date, bool] = (day, is_morning)
|
||||
if key not in self.half_days:
|
||||
self.half_days.append(key)
|
||||
@ -67,7 +69,7 @@ class CountCalculator:
|
||||
if day not in self.days:
|
||||
self.days.append(day)
|
||||
|
||||
def check_in_morning(self, period: tuple[datetime, datetime]) -> bool:
|
||||
def is_in_morning(self, period: tuple[datetime, datetime]) -> bool:
|
||||
"""Vérifiée si la période donnée fait partie du matin
|
||||
(Test sur la date de début)
|
||||
"""
|
||||
@ -82,7 +84,7 @@ class CountCalculator:
|
||||
)
|
||||
return in_morning
|
||||
|
||||
def check_in_evening(self, period: tuple[datetime, datetime]) -> bool:
|
||||
def is_in_evening(self, period: tuple[datetime, datetime]) -> bool:
|
||||
"""Vérifie si la période fait partie de l'aprèm
|
||||
(test sur la date de début)
|
||||
"""
|
||||
@ -123,9 +125,9 @@ class CountCalculator:
|
||||
)
|
||||
hours = 0.0
|
||||
for period in (start_period, finish_period):
|
||||
if self.check_in_evening(period):
|
||||
if self.is_in_evening(period):
|
||||
self.add_half_day(period[0].date(), False)
|
||||
if self.check_in_morning(period):
|
||||
if self.is_in_morning(period):
|
||||
self.add_half_day(period[0].date())
|
||||
|
||||
while pointer_date < assi.date_fin.date():
|
||||
@ -156,9 +158,9 @@ class CountCalculator:
|
||||
|
||||
period: tuple[datetime, datetime] = (assi.date_debut, assi.date_fin)
|
||||
deb_date: date = assi.date_debut.date()
|
||||
if self.check_in_morning(period):
|
||||
if self.is_in_morning(period):
|
||||
self.add_half_day(deb_date)
|
||||
if self.check_in_evening(period):
|
||||
if self.is_in_evening(period):
|
||||
self.add_half_day(deb_date, False)
|
||||
|
||||
self.add_day(deb_date)
|
||||
@ -241,7 +243,8 @@ def _count_assiduites_etat(
|
||||
calculator: CountCalculator,
|
||||
metrics: list[str],
|
||||
justifie: bool = False,
|
||||
):
|
||||
): # TODO type retour ?
|
||||
# TODO documenter
|
||||
calculator.reset()
|
||||
etat_num: int = scu.EtatAssiduite.get(etat, -1)
|
||||
assiduites_etat: Query = assiduites.filter(Assiduite.etat == etat_num)
|
||||
@ -298,7 +301,7 @@ def filter_by_date(
|
||||
if date_fin is None:
|
||||
date_fin = datetime.max
|
||||
|
||||
date_deb = scu.localize_datetime(date_deb)
|
||||
date_deb = scu.localize_datetime(date_deb) # TODO A modifier (timezone ?)
|
||||
date_fin = scu.localize_datetime(date_fin)
|
||||
if not strict:
|
||||
return collection.filter(
|
||||
@ -414,6 +417,7 @@ def create_absence(
|
||||
est_just: bool = False,
|
||||
) -> int:
|
||||
"""TODO: doc, dire quand l'utiliser"""
|
||||
# TODO
|
||||
etud: Identite = Identite.query.filter_by(etudid=etudid).first_or_404()
|
||||
assiduite_unique: Assiduite = Assiduite.create_assiduite(
|
||||
etud=etud,
|
||||
@ -495,6 +499,7 @@ def get_assiduites_count_in_interval(
|
||||
"""
|
||||
date_debut_iso = date_debut_iso or date_debut.isoformat()
|
||||
date_fin_iso = date_fin_iso or date_fin.isoformat()
|
||||
# TODO Question: pourquoi ne pas cacher toutes les métriques, si l'API les veut toutes ?
|
||||
key = f"{etudid}_{date_debut_iso}_{date_fin_iso}{metrique}_assiduites"
|
||||
|
||||
r = sco_cache.AbsSemEtudCache.get(key)
|
||||
|
@ -60,9 +60,15 @@ async function load_ics_sample() {
|
||||
|
||||
<h1>Configuration du suivi de l'assiduité</h1>
|
||||
|
||||
<div class="help"> Ces paramètres seront utilisés par tous les départements et
|
||||
<div class="help">
|
||||
<p>Ces paramètres seront utilisés par tous les départements et
|
||||
affectent notamment les comptages d'absences de tous les bulletins des
|
||||
étudiants : ne changer que lorsque c'est vraiment nécessaire.
|
||||
</p>
|
||||
<p>
|
||||
Les heures de ScoDoc sont exprimées en <em>heures locale du serveur</em>,
|
||||
c'est à dire à la montre des étudiants.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user