Corrige le décompte des demi-journées restantes et le rendu des champs horaires

Une demi-journée passée non renseignée était exclue à tort du calcul de
rattrapage (l'appli permet de saisir ses heures après coup, un jour passé
vide n'est pas une perte définitive) : une semaine entièrement vide affichait
"reste à faire ... sur 2 demi-journées" au lieu de 10. Corrige aussi le
chevauchement de l'icône d'horloge sur les champs <input type="time"> de la
page Réglages (largeur trop juste pour le texte + l'icône native).
This commit is contained in:
Antoine
2026-07-17 23:21:55 +02:00
parent d87bf6a212
commit 436f923148
3 changed files with 33 additions and 8 deletions

View File

@ -123,12 +123,12 @@ def compute_week(pointages: list[dict], conges: list[dict], heures_jour_min: int
jour["cible_matin"] = None jour["cible_matin"] = None
jour["cible_aprem"] = None jour["cible_aprem"] = None
today = datetime.today().strftime("%Y-%m-%d")
restant = total_du - total_travaille restant = total_du - total_travaille
slots = [] # (jour, "matin"|"aprem", nominal_min) slots = [] # (jour, "matin"|"aprem", nominal_min)
for jour in jours: for jour in jours:
if jour["date"] < today: # Un jour passé non renseigné n'est pas exclu : cette appli permet de saisir
continue # jour passé : impossible d'y rattraper quoi que ce soit # ses heures après coup, donc une demi-journée vide reste "à faire" quelle
# que soit sa date.
cg = jour["conge"] cg = jour["conge"]
du = jour["du_min"] du = jour["du_min"]
if du == 0: if du == 0:

View File

@ -25,18 +25,18 @@
<form method="post" action="/settings/plages" class="settings-form"> <form method="post" action="/settings/plages" class="settings-form">
<label class="login-label" for="matin_debut">Présence matin</label> <label class="login-label" for="matin_debut">Présence matin</label>
<div class="settings-range"> <div class="settings-range">
<input id="matin_debut" class="login-input settings-range-input" type="time" name="matin_debut" value="{{ plages.matin_debut }}"> <input id="matin_debut" class="login-input time-range-input" type="time" name="matin_debut" value="{{ plages.matin_debut }}">
<span class="settings-range-sep"></span> <span class="settings-range-sep"></span>
<input id="matin_fin" class="login-input settings-range-input" type="time" name="matin_fin" value="{{ plages.matin_fin }}"> <input id="matin_fin" class="login-input time-range-input" type="time" name="matin_fin" value="{{ plages.matin_fin }}">
</div> </div>
<label class="login-label" for="aprem_debut">Présence après-midi</label> <label class="login-label" for="aprem_debut">Présence après-midi</label>
<div class="settings-range"> <div class="settings-range">
<input id="aprem_debut" class="login-input settings-range-input" type="time" name="aprem_debut" value="{{ plages.aprem_debut }}"> <input id="aprem_debut" class="login-input time-range-input" type="time" name="aprem_debut" value="{{ plages.aprem_debut }}">
<span class="settings-range-sep"></span> <span class="settings-range-sep"></span>
<input id="aprem_fin" class="login-input settings-range-input" type="time" name="aprem_fin" value="{{ plages.aprem_fin }}"> <input id="aprem_fin" class="login-input time-range-input" type="time" name="aprem_fin" value="{{ plages.aprem_fin }}">
</div> </div>
<label class="login-label" for="pause_dejeuner_fin">Reprise par défaut de l'après-midi</label> <label class="login-label" for="pause_dejeuner_fin">Reprise par défaut de l'après-midi</label>
<input id="pause_dejeuner_fin" class="login-input settings-range-input" type="time" name="pause_dejeuner_fin" value="{{ plages.pause_dejeuner_fin }}"> <input id="pause_dejeuner_fin" class="login-input time-range-input" type="time" name="pause_dejeuner_fin" value="{{ plages.pause_dejeuner_fin }}">
<button class="login-btn" type="submit">Enregistrer</button> <button class="login-btn" type="submit">Enregistrer</button>
</form> </form>
</div> </div>
@ -167,5 +167,13 @@
.settings-range { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; } .settings-range { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.settings-range-input { width: 70px; text-align: center; } .settings-range-input { width: 70px; text-align: center; }
.settings-range-sep { font-size: 12px; color: var(--muted); font-family: var(--mono); } .settings-range-sep { font-size: 12px; color: var(--muted); font-family: var(--mono); }
.time-range-input {
width: 128px;
text-align: left;
padding-right: .4rem;
}
.time-range-input::-webkit-calendar-picker-indicator {
margin-left: .5rem;
}
</style> </style>
{% endblock %} {% endblock %}

View File

@ -115,6 +115,23 @@ def test_compute_week_cible_repartie_sur_seule_demi_journee_restante(freeze_toda
assert vendredi["cible_aprem"] == "18:18" assert vendredi["cible_aprem"] == "18:18"
def test_compute_week_semaine_totalement_vide_compte_les_10_demi_journees(freeze_today):
"""Régression : une semaine entièrement vide (rien saisi, y compris les jours déjà
passés) doit compter 10 demi-journées restantes, pas seulement celles à partir
d'aujourd'hui. Cette appli permet de saisir ses heures après coup — un jour passé
non renseigné reste "à faire", il n'est pas un manque définitivement perdu."""
dates = ["2026-07-13", "2026-07-14", "2026-07-15", "2026-07-16", "2026-07-17"]
pointages = [_pointage(d) for d in dates]
result = compute_week(pointages, [], HEURES_JOUR_MIN)
assert result["slots_restants"] == 10
assert result["reste_min"] == HEURES_JOUR_MIN * 5
# Rien n'est encore en retard puisque rien n'a encore été renseigné : le rythme
# normal (à répartir librement sur les 10 demi-journées) suffit, pas de cible imposée.
assert result["extra_min"] == 0
assert all(j["cible_matin"] is None and j["cible_aprem"] is None for j in result["jours"])
def test_compute_week_jour_futur_non_entame_recoit_une_cible_repartie(freeze_today): def test_compute_week_jour_futur_non_entame_recoit_une_cible_repartie(freeze_today):
"""Un jour futur non entamé fait maintenant partie de la répartition (spread sur la semaine).""" """Un jour futur non entamé fait maintenant partie de la répartition (spread sur la semaine)."""
dates_completes = ["2026-07-13", "2026-07-14", "2026-07-15", "2026-07-16"] dates_completes = ["2026-07-13", "2026-07-14", "2026-07-15", "2026-07-16"]