Forfait d'astreinte : bonifié comme réalisé en journée du jour AS

Le forfait était suivi brut, sans bonification. Considéré réalisé en
journée du jour où il est attribué, il reçoit désormais le facteur
journée correspondant : ×1 en semaine, ×1,5 le samedi, ×2 le dimanche
ou un jour férié (suit les règles de ratios configurées). Toujours hors
heures travaillées ; affiché pondéré sur la ligne du jour, dans les
totaux du récapitulatif et expliqué dans Réglages.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
This commit is contained in:
Jacquin Antoine
2026-09-10 17:05:05 +02:00
parent f50d1ef7fc
commit d760842121
7 changed files with 125 additions and 16 deletions

View File

@ -35,7 +35,7 @@ from calcul import (
compute_week, minutes_to_hhmm, minutes_to_time, hhmm_to_minutes, heures_dues,
heures_travaillees, jour_astreinte_qualifie, exclusion_retour, couvert_detail,
nominaux_du_jour, retour_apres_repos, retour_repos, retour_txt, decompte_astreinte,
fenetre_astreinte_jour,
fenetre_astreinte_jour, regle_journee_astreinte,
)
from stats import compute_all_stats
from export import export_semaine_ods, export_annee_ods
@ -370,6 +370,11 @@ def _build_jour_ctx(date, conges, h_jour, user_id):
matin_ex, aprem_ex = exclusion_retour(conges_date, retour_min, plages, jour_ferie)
forfait = (hhmm_to_minutes(plages["astreinte_forfait"]) if plages.get("astreinte_forfait") else 0) \
if date in astreintes else 0
# Le forfait est considéré réalisé en journée du jour AS déclaré : il reçoit
# la bonification « journée » de ce jour (×1 semaine, ×1,5 samedi, ×2
# dimanche/férié par défaut) — pondéré, mais toujours hors heures travaillées.
regle_journee = regle_journee_astreinte(date, load_facteurs_astreinte(), feries) if forfait else None
forfait_pondere = int(forfait * (regle_journee or {"facteur": 1.0})["facteur"] + 0.5) if forfait else 0
# Les heures de présence obligatoire couvertes par le repos de 11h sont
# comptées comme effectuées : créditées au travaillé, dues complètes (le
# forfait d'astreinte, lui, reste hors heures travaillées). Sans heures
@ -395,6 +400,10 @@ def _build_jour_ctx(date, conges, h_jour, user_id):
"ferie": jour_ferie,
"forfait_min": forfait,
"forfait_h": minutes_to_hhmm(forfait) if forfait else "",
"forfait_pondere_min": forfait_pondere,
"forfait_pondere_h": minutes_to_hhmm(forfait_pondere) if forfait_pondere else "",
"forfait_regle": regle_journee["nom"] if regle_journee else "",
"forfait_facteur_txt": regle_journee["facteur_txt"] if regle_journee else "1",
"du_full_min": du_full,
"matin_excl_min": matin_ex, "aprem_excl_min": aprem_ex,
"couvert_min": couvert,
@ -573,8 +582,10 @@ def _as_block_html(date, jour):
hint += (f'<span class="as-hint" title="Présence obligatoire couverte par le repos ({_e(jour["couvert_detail"])}) : comptée comme effectuées dans la colonne Travaillé">'
f'+{_e(jour["couvert_h"])} de présence comptées</span>')
if jour.get("forfait_min"):
hint += (f'<span class="as-hint" title="Forfait du jour AS déclaré (réglé dans Réglages) : suivi dans le récapitulatif d&#39;astreinte, hors heures travaillées">'
f'forfait {_e(jour["forfait_h"])}</span>')
f_txt = jour.get("forfait_facteur_txt") or "1"
f_regle = f" ({_e(jour['forfait_regle'])})" if jour.get("forfait_regle") else ""
hint += (f'<span class="as-hint" title="Forfait du jour AS déclaré (réglé dans Réglages), considéré réalisé en journée du jour : pondéré ×{f_txt}{f_regle} — suivi dans le récapitulatif d&#39;astreinte, hors heures travaillées">'
f'forfait {_e(jour["forfait_h"])} → {_e(jour["forfait_pondere_h"])} pondérées</span>')
total = ""
if jour.get("astreinte_min"):
total = (f'<span class="as-total" title="Durée réelle des interventions arrondie au quart d\'heure supérieur (2, 5 ou 12 min → 15 ; 22 ou 28 → 30) — compteur séparé, hors heures de semaine">'