diff --git a/app/calcul.py b/app/calcul.py index d30ced0..3802ee2 100644 --- a/app/calcul.py +++ b/app/calcul.py @@ -441,6 +441,7 @@ def compute_week(pointages: list[dict], conges: list[dict], heures_jour_min: int as_jours = [] as_total_min = 0 as_total_pondere_min = 0 + as_forfait_min = 0 as_cats: dict[str, dict] = {} for p in pointages: @@ -488,8 +489,18 @@ def compute_week(pointages: list[dict], conges: list[dict], heures_jour_min: int "retour_min": retour_min, "retour": minutes_to_time(retour_min) if retour_min is not None else None, }) + # Jours repris dans le récapitulatif d'astreinte : ceux avec des heures + # décomptées, mais aussi les jours AS déclarés portant un forfait (sans + # intervention) — le forfait y est rappelé, sans entrer dans les compteurs. + if (dec and dec["total_min"] > 0) or forfait: + as_jours.append({ + "date": p["date"], + "events": dec["events"] if dec else [], + "forfait_min": forfait, + "forfait_h": minutes_to_hhmm(forfait) if forfait else "", + }) + as_forfait_min += forfait if dec and dec["total_min"] > 0: - as_jours.append({"date": p["date"], "events": dec["events"]}) as_total_min += dec["total_min"] as_total_pondere_min += dec["total_pondere_min"] for c in dec["categories"]: @@ -691,11 +702,13 @@ def compute_week(pointages: list[dict], conges: list[dict], heures_jour_min: int "moyenne_extra_min": (extra_total // slots_restants) if slots_restants else 0, "moyenne_extra": minutes_to_hhmm((extra_total // slots_restants) if slots_restants else 0), "astreinte": { - "actif": as_total_min > 0, + "actif": as_total_min > 0 or as_forfait_min > 0, "total_min": as_total_min, "total_h": minutes_to_hhmm(as_total_min), "total_pondere_min": as_total_pondere_min, "total_pondere_h": minutes_to_hhmm(as_total_pondere_min), + "total_forfait_min": as_forfait_min, + "total_forfait_h": minutes_to_hhmm(as_forfait_min), "categories": as_categories, "jours": as_jours, }, diff --git a/app/templates/_soldes.html b/app/templates/_soldes.html index 3234a65..596fa66 100644 --- a/app/templates/_soldes.html +++ b/app/templates/_soldes.html @@ -68,10 +68,12 @@ {% endif %} {% endfor %} + {% if j.forfait_min %}
forfait + {{ j.forfait_h }}
{% endif %} {% endfor %}
{% for c in result.astreinte.categories %}{{ c.nom }} : {{ c.min_h }} ×{{ c.facteur_txt }} = {{ c.pondere_h }}{% endfor %} + {% if result.astreinte.total_forfait_min %}forfaits + {{ result.astreinte.total_forfait_h }}{% endif %} total {{ result.astreinte.total_h }} → {{ result.astreinte.total_pondere_h }} pondérées
diff --git a/app/templates/base.html b/app/templates/base.html index 00e5853..146051b 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -590,6 +590,7 @@ border-bottom: 1px dotted var(--rule); } .as-ev-cat, .as-cat { color: var(--accent); font-family: var(--mono); font-size: 11px; } + .as-forfait { font-family: var(--mono); color: var(--muted); font-size: 11px; } .as-ev-pond { font-family: var(--mono); color: var(--accent-2); } .as-jour-date { font-family: var(--mono); font-weight: 500; margin-right: .4rem; } .as-totaux { diff --git a/app/tests/test_astreinte.py b/app/tests/test_astreinte.py index b234f42..097a6f6 100644 --- a/app/tests/test_astreinte.py +++ b/app/tests/test_astreinte.py @@ -571,6 +571,14 @@ def test_compute_week_forfait_ajoute_au_travaille_du_jour_declare(freeze_today): assert result["jours"][2]["forfait_min"] == 0 # lendemain : rien assert result["jours"][0]["forfait_min"] == 0 # jour sans astreinte assert result["total_travaille"] == "16h36" # 2 × 7h48 + 1h + # récapitulatif d'astreinte : le jour AS apparaît avec son forfait même sans + # intervention ; le forfait est rappelé mais hors compteurs pondérés + ast = result["astreinte"] + assert ast["actif"] is True + assert ast["total_min"] == 0 + assert ast["total_forfait_min"] == 60 + assert ast["total_forfait_h"] == "1h00" + assert [(j["date"], j["forfait_min"], j["events"]) for j in ast["jours"]] == [("2026-07-14", 60, [])] def test_compute_week_sans_forfait_comportement_inchange(freeze_today):