Retour décalé après astreinte : la présence obligatoire couverte compte comme effectuée
Quand le repos de 11h décale le retour au bureau (ex. 11:00), les heures de
présence obligatoire couvertes (ex. 09:00→11:00) sont créditées à la colonne
Travaillé au lieu d'être retirées des heures dues, qui restent complètes.
Le solde est inchangé, mais le calcul est explicite : badge « +2h00 repos »
sous le total (plages couvertes au survol) et rappel dans le bloc astreinte.
Rien n'est crédité sans heures dues (week-end, férié, congé), et le crédit
ne dépasse pas le nominal du jour.
Corrige aussi la perte des interventions postées sans description (le zip
s'arrêtait sur la liste vide des descriptions).
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
This commit is contained in:
@ -311,7 +311,8 @@ def test_nominaux_sans_exclusion_reste_la_moitié():
|
||||
def test_compute_week_decompte_absent_des_heures_de_semaine(freeze_today):
|
||||
"""Lundi et jeudi complets, mardi astreinte avec event 23:00→01:00, mercredi
|
||||
vide : les heures d'astreinte n'entrent jamais dans total_travaille/total_du,
|
||||
seulement dans result["astreinte"]."""
|
||||
seulement dans result["astreinte"] ; seules les 3h de présence obligatoire du
|
||||
matin couvertes par le repos (retour 12:00) sont créditées comme effectuées."""
|
||||
pointages = [
|
||||
_pointage("2026-07-13", "09:00", "12:24", "13:30", "17:54"),
|
||||
_pointage("2026-07-14", astreinte_events=[{"debut": "23:00", "fin": "01:00"}]),
|
||||
@ -321,8 +322,9 @@ def test_compute_week_decompte_absent_des_heures_de_semaine(freeze_today):
|
||||
]
|
||||
result = compute_week(pointages, [], HEURES_JOUR_MIN, PLAGES, ["2026-07-14"])
|
||||
|
||||
# seul le pointé compte : 2 × 468 = 15h36, astreinte exclue
|
||||
assert result["total_travaille"] == "15h36"
|
||||
# pointé (2 × 7h48) + 3h de présence couvertes créditées ; astreinte exclue
|
||||
assert result["total_travaille"] == "18h36"
|
||||
assert result["jours"][2]["couvert_min"] == 180
|
||||
|
||||
ast = result["astreinte"]
|
||||
assert ast["actif"] is True
|
||||
@ -341,8 +343,8 @@ def test_compute_week_decompte_absent_des_heures_de_semaine(freeze_today):
|
||||
|
||||
def test_compute_week_fin_nocturne_decale_le_decompte_et_les_cibles(freeze_today):
|
||||
"""Mardi astreinte, event 01:00→02:00 saisi sur le mercredi (lendemain) :
|
||||
retour mercredi 13:00, présence du matin retirée de la semaine, aucune cible
|
||||
matin, après-midi 13:30→18:18 (nominal 288 = 234 + report)."""
|
||||
retour mercredi 13:00, présence du matin (3h) créditée comme effectuée,
|
||||
aucune cible matin, après-midi 13:30→18:18 (nominal 288 = 234 + report)."""
|
||||
pointages = [
|
||||
_pointage("2026-07-13", "09:00", "12:24", "13:30", "17:54"),
|
||||
_pointage("2026-07-14", "09:00", "12:24", "13:30", "17:54"),
|
||||
@ -353,11 +355,16 @@ def test_compute_week_fin_nocturne_decale_le_decompte_et_les_cibles(freeze_today
|
||||
result = compute_week(pointages, [], HEURES_JOUR_MIN, PLAGES, ["2026-07-14"])
|
||||
mercredi = result["jours"][2]
|
||||
|
||||
assert mercredi["du_min"] == 468 - 180 # matin 09:00→12:00 exclu par le retour 13:00
|
||||
# dues complètes, présence matin 09:00→12:00 couverte créditée au travaillé
|
||||
assert mercredi["du_min"] == 468
|
||||
assert mercredi["couvert_min"] == 180
|
||||
assert mercredi["travaille_min"] == 180
|
||||
assert mercredi["couvert_detail"] == "matin 09:00→12:00"
|
||||
assert mercredi["retour"] == "13:00" # 02:00 + 11h
|
||||
assert mercredi["cible_matin"] is None
|
||||
assert mercredi["cible_aprem"] == "18:18"
|
||||
assert result["total_du"] == "36h00" # 39h - 3h de présence retirées
|
||||
assert result["total_du"] == "39h00" # dues nominales complètes
|
||||
assert result["total_travaille"] == "18h36" # 2 × 7h48 + 3h de présence créditée
|
||||
|
||||
|
||||
def test_compute_week_nuit_finissant_au_matin(freeze_today):
|
||||
@ -375,8 +382,10 @@ def test_compute_week_nuit_finissant_au_matin(freeze_today):
|
||||
mercredi = result["jours"][2]
|
||||
|
||||
assert mercredi["retour"] == "17:00"
|
||||
# matin (180) + 14:00→17:00 (180) exclus → dû = 108
|
||||
assert mercredi["du_min"] == 468 - 360
|
||||
# matin (180) + 14:00→17:00 (180) couverts → crédités 360, dues complètes 468
|
||||
assert mercredi["du_min"] == 468
|
||||
assert mercredi["couvert_min"] == 360
|
||||
assert mercredi["couvert_h"] == "6h00"
|
||||
assert mercredi["cible_matin"] is None
|
||||
# aprem démarre à 17:00, nominal 108 (54 matin + 54 aprem) → 18:48
|
||||
assert mercredi["cible_aprem_entree"] == "17:00"
|
||||
@ -386,6 +395,32 @@ def test_compute_week_nuit_finissant_au_matin(freeze_today):
|
||||
assert result["astreinte"]["total_pondere_min"] == 630
|
||||
|
||||
|
||||
def test_compute_week_presence_couvertes_comptees_effectuees(freeze_today):
|
||||
"""Retour décalé à 11:00 (event mardi 22:39→23:49) : les 2h de présence
|
||||
obligatoire du matin (09:00→11:00) sont comptées comme effectuées —
|
||||
créditées au travaillé, dues complètes, Δ inchangé par rapport à
|
||||
l'ancienne soustraction des dues."""
|
||||
pointages = [
|
||||
_pointage("2026-07-13", "09:00", "12:24", "13:30", "17:54"),
|
||||
_pointage("2026-07-14", "09:00", "12:24", "13:30", "17:54",
|
||||
astreinte_events=[{"debut": "22:39", "fin": "23:49"}]),
|
||||
_pointage("2026-07-15", "11:00", "12:00", "14:00", "17:00"),
|
||||
_pointage("2026-07-16"),
|
||||
_pointage("2026-07-17"),
|
||||
]
|
||||
result = compute_week(pointages, [], HEURES_JOUR_MIN, PLAGES, ["2026-07-14"])
|
||||
mercredi = result["jours"][2]
|
||||
|
||||
assert mercredi["retour"] == "11:00"
|
||||
assert mercredi["couvert_min"] == 120 # présence 09:00→11:00
|
||||
assert mercredi["couvert_h"] == "2h00"
|
||||
assert mercredi["couvert_detail"] == "matin 09:00→11:00"
|
||||
assert mercredi["travaille_min"] == 240 + 120 # pointé (1h + 3h) + couvert
|
||||
assert mercredi["travaille"] == "6h00"
|
||||
assert mercredi["du_min"] == 468 # dues complètes
|
||||
assert mercredi["delta_min"] == 360 - 468
|
||||
|
||||
|
||||
def test_compute_week_event_ignore_hors_jour_qualifie(freeze_today):
|
||||
"""Un event saisi un jour non qualifié (pas d'astreinte) ne change rien au
|
||||
décompte ni au décompte d'astreinte."""
|
||||
@ -447,7 +482,8 @@ def test_compute_week_demi_journee_entierement_en_repos_compte_complete(freeze_t
|
||||
assert mercredi["matin_nominal_min"] == 0
|
||||
assert mercredi["is_complete"] is True
|
||||
assert mercredi["cumul_visible"] is True
|
||||
assert mercredi["du_min"] == 180 # 6h dues - 3h de présence matin retirées
|
||||
assert mercredi["du_min"] == 360 # dues complètes du jour (6h)
|
||||
assert mercredi["couvert_min"] == 180 # 3h de présence matin couvertes, créditées
|
||||
|
||||
|
||||
# ── Stockage des astreintes ───────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user