Affiche l'heure d'arrivée en plus du départ dans les préconisations

La colonne "Cible" (anciennement "Fin cible") montre désormais une plage
complète entrée → sortie pour chaque demi-journée à rattraper, au lieu
d'une heure de départ seule. Moins ambigu pour l'utilisateur qui sait
aussi quand arriver.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
This commit is contained in:
Jacquin Antoine
2026-07-19 23:25:16 +02:00
parent d3c991f8d6
commit 27bcd7a0b4
5 changed files with 17 additions and 7 deletions

View File

@ -131,6 +131,8 @@ def compute_week(pointages: list[dict], conges: list[dict], heures_jour_min: int
for jour in jours: for jour in jours:
jour["cible_matin"] = None jour["cible_matin"] = None
jour["cible_aprem"] = None jour["cible_aprem"] = None
jour["cible_matin_entree"] = None
jour["cible_aprem_entree"] = None
restant = total_du - total_travaille restant = total_du - total_travaille
@ -204,8 +206,14 @@ def compute_week(pointages: list[dict], conges: list[dict], heures_jour_min: int
continue # rythme normal suffit pour cette demi-journée, rien à signaler continue # rythme normal suffit pour cette demi-journée, rien à signaler
sortie_min = s["debut"] + s["nominal"] + adjs[i] sortie_min = s["debut"] + s["nominal"] + adjs[i]
sortie_min = max(sortie_min, matin_fin_min if s["half"] == "matin" else aprem_fin_min) sortie_min = max(sortie_min, matin_fin_min if s["half"] == "matin" else aprem_fin_min)
cible = f"{sortie_min // 60:02d}:{sortie_min % 60:02d}" entree = f"{s['debut'] // 60:02d}:{s['debut'] % 60:02d}"
s["jour"]["cible_matin" if s["half"] == "matin" else "cible_aprem"] = cible sortie = f"{sortie_min // 60:02d}:{sortie_min % 60:02d}"
if s["half"] == "matin":
s["jour"]["cible_matin_entree"] = entree
s["jour"]["cible_matin"] = sortie
else:
s["jour"]["cible_aprem_entree"] = entree
s["jour"]["cible_aprem"] = sortie
reste_min = max(0, restant) reste_min = max(0, restant)

View File

@ -166,9 +166,9 @@ def _oob_week_extras(result):
html += f'<span id="calc-{date}-cumul" hx-swap-oob="true">{cumul_inner}</span>' html += f'<span id="calc-{date}-cumul" hx-swap-oob="true">{cumul_inner}</span>'
parts = [] parts = []
if jour.get("cible_matin"): if jour.get("cible_matin"):
parts.append(f'<span class="cible-num">M {jour["cible_matin"]}</span>') parts.append(f'<span class="cible-num">M {jour["cible_matin_entree"]}{jour["cible_matin"]}</span>')
if jour.get("cible_aprem"): if jour.get("cible_aprem"):
parts.append(f'<span class="cible-num">A {jour["cible_aprem"]}</span>') parts.append(f'<span class="cible-num">A {jour["cible_aprem_entree"]}{jour["cible_aprem"]}</span>')
cible_inner = " ".join(parts) if parts else '<span class="delta-zero">—</span>' cible_inner = " ".join(parts) if parts else '<span class="delta-zero">—</span>'
html += f'<span id="calc-{date}-cible" hx-swap-oob="true">{cible_inner}</span>' html += f'<span id="calc-{date}-cible" hx-swap-oob="true">{cible_inner}</span>'
return html return html

View File

@ -70,9 +70,9 @@
<td class="col-cible"> <td class="col-cible">
<span id="calc-{{ j.date }}-cible"> <span id="calc-{{ j.date }}-cible">
{%- if j.cible_matin or j.cible_aprem -%} {%- if j.cible_matin or j.cible_aprem -%}
{%- if j.cible_matin -%}<span class="cible-num">M {{ j.cible_matin }}</span>{%- endif -%} {%- if j.cible_matin -%}<span class="cible-num">M {{ j.cible_matin_entree }} → {{ j.cible_matin }}</span>{%- endif -%}
{%- if j.cible_matin and j.cible_aprem %} {% endif -%} {%- if j.cible_matin and j.cible_aprem %} {% endif -%}
{%- if j.cible_aprem -%}<span class="cible-num">A {{ j.cible_aprem }}</span>{%- endif -%} {%- if j.cible_aprem -%}<span class="cible-num">A {{ j.cible_aprem_entree }} → {{ j.cible_aprem }}</span>{%- endif -%}
{%- else -%} {%- else -%}
<span class="delta-zero"></span> <span class="delta-zero"></span>
{%- endif %} {%- endif %}

View File

@ -53,7 +53,7 @@
<th class="g-calc" rowspan="2">Travaillé</th> <th class="g-calc" rowspan="2">Travaillé</th>
<th class="g-calc" rowspan="2">Δ jour</th> <th class="g-calc" rowspan="2">Δ jour</th>
<th class="g-cumul" rowspan="2">Δ sem.</th> <th class="g-cumul" rowspan="2">Δ sem.</th>
<th class="g-cible" rowspan="2">Fin cible</th> <th class="g-cible" rowspan="2">Cible</th>
<th class="g-save" rowspan="2"></th> <th class="g-save" rowspan="2"></th>
<th class="g-conge" rowspan="2">Congé</th> <th class="g-conge" rowspan="2">Congé</th>
</tr> </tr>

View File

@ -113,6 +113,8 @@ def test_compute_week_cible_repartie_sur_seule_demi_journee_restante(freeze_toda
assert vendredi["cible_matin"] is None # matin déjà pointé (entrée+sortie), plus rien à y faire assert vendredi["cible_matin"] is None # matin déjà pointé (entrée+sortie), plus rien à y faire
assert vendredi["cible_aprem"] == "18:18" assert vendredi["cible_aprem"] == "18:18"
# La préconisation aprem inclut aussi l'heure d'arrivée (reprise par défaut 13:30)
assert vendredi["cible_aprem_entree"] == "13:30"
def test_compute_week_semaine_totalement_vide_compte_les_10_demi_journees(freeze_today): def test_compute_week_semaine_totalement_vide_compte_les_10_demi_journees(freeze_today):