Ajoute colonnes Δ sem. / Fin cible, supprime solde global, indicateurs minima
- Nouvelles colonnes : Δ sem. (solde cumulé semaine) et Fin cible (heure de sortie aprem optimale pour 0h suppl. en fin de semaine) - Δ sem. n'est affiché que quand la journée est complète et la chaîne de jours ininterrompue (pas de saut de jour non saisi) - Fin cible disparaît quand la journée est validée (passée/complète) - Delta = "—" pour les jours non travaillés (futur ou congé jour) - Indicateur warn (fond rouge) sur matin/aprem si horaires < minimum (matin 09:00→12:00, aprem 14:00→17:00) ; mise à jour live via JS - Suppression du solde global (3 cartes au lieu de 4) - Tableau sans largeurs fixes + container 1100 px pour éviter scroll horizontal sur écrans normaux ; touch-scroll conservé sur mobile - Base reste 39h/semaine (7h48/jour) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -71,6 +71,51 @@ def compute_week(pointages: list[dict], conges: list[dict], heures_jour_min: int
|
||||
"conge": {c["type"] for c in conges if c["date"] == p["date"]},
|
||||
})
|
||||
|
||||
# Mark each day as complete (all non-congé slots filled, or day is a congé/weekend)
|
||||
for jour in jours:
|
||||
cg = jour["conge"]
|
||||
matin_done = bool(jour.get("matin_entree") and jour.get("matin_sortie")) or "matin" in cg or "jour" in cg
|
||||
aprem_done = bool(jour.get("aprem_entree") and jour.get("aprem_sortie")) or "aprem" in cg or "jour" in cg
|
||||
jour["is_complete"] = (jour["du_min"] == 0) or (matin_done and aprem_done)
|
||||
|
||||
# Cumulative weekly delta — accumulated for all days, but visible only when chain is unbroken
|
||||
cumul = 0
|
||||
cumul_chain_ok = True
|
||||
for jour in jours:
|
||||
cumul += jour["delta_min"]
|
||||
jour["delta_cumul_min"] = cumul
|
||||
jour["delta_cumul"] = minutes_to_hhmm(abs(cumul))
|
||||
# Chain breaks on the first incomplete workday — subsequent days don't show cumul
|
||||
if not jour["is_complete"] and jour["du_min"] > 0:
|
||||
cumul_chain_ok = False
|
||||
jour["cumul_visible"] = jour["is_complete"] and cumul_chain_ok
|
||||
|
||||
# Sortie cible: optimal aprem exit so the week totals exactly the target hours
|
||||
worked_before = 0
|
||||
for i, jour in enumerate(jours):
|
||||
cg = jour["conge"]
|
||||
if jour["du_min"] == 0 or "aprem" in cg or "jour" in cg:
|
||||
jour["sortie_cible"] = None
|
||||
worked_before += jour["travaille_min"]
|
||||
continue
|
||||
|
||||
du_remaining = sum(j["du_min"] for j in jours[i + 1:])
|
||||
needed_today = max(0, total_du - worked_before - du_remaining)
|
||||
|
||||
worked_morning = 0
|
||||
if jour.get("matin_entree") and jour.get("matin_sortie"):
|
||||
worked_morning = max(0, hhmm_to_minutes(jour["matin_sortie"]) - hhmm_to_minutes(jour["matin_entree"]))
|
||||
|
||||
needed_aprem = max(0, needed_today - worked_morning)
|
||||
aprem_start = hhmm_to_minutes(jour["aprem_entree"]) if jour.get("aprem_entree") else 14 * 60
|
||||
sortie_min = max(aprem_start + needed_aprem, 17 * 60)
|
||||
|
||||
if sortie_min > 23 * 60 + 59:
|
||||
jour["sortie_cible"] = None # deficit too large to recover in one afternoon
|
||||
else:
|
||||
jour["sortie_cible"] = f"{sortie_min // 60:02d}:{sortie_min % 60:02d}"
|
||||
worked_before += jour["travaille_min"]
|
||||
|
||||
return {
|
||||
"jours": jours,
|
||||
"total_travaille": minutes_to_hhmm(total_travaille),
|
||||
|
||||
Reference in New Issue
Block a user