Décompte les heures d'astreinte par tranches de 15 min dans des compteurs pondérés séparés

La saisie astreinte devient une liste d'événements (début, fin, description,
nombre illimité, fin antérieure au début = intervention à cheval sur minuit).
Ces heures ne comptent jamais dans la semaine : elles sont décomptées à part
par pas de 15 minutes, toute tranche entamée comptant en totalité, et rangées
dans des compteurs selon le jour et l'heure (Nuit ×1,5, Journée semaine ×1,
Samedi ×1,5, Dimanche/férié ×2 ; jours fériés français calculés
automatiquement, règles ajustables dans config.json via astreinte_facteurs).
Le détail par événement et les totaux pondérés s'affichent sous le bandeau de
la semaine, et les exports .ods gagnent les colonnes Astreinte brute et
pondérée. Le retour au bureau (fin du dernier événement + 11h de repos) est
désormais dérivé des événements.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
This commit is contained in:
Jacquin Antoine
2026-09-08 22:26:47 +02:00
parent 065d73e15c
commit c208a17eec
11 changed files with 695 additions and 118 deletions

View File

@ -43,11 +43,37 @@
</div>
{% if j.astreinte_qualifiee %}
<div id="as-block-{{ j.date }}" class="as-block" data-label="Astreinte">
<span class="as-label">Fin activité</span>
<input class="time-input" type="time" name="astreinte_fin"
data-date="{{ j.date }}" value="{{ j.astreinte_fin or '' }}"
title="Heure de fin de la dernière activité (peut être le matin) — 11h de repos ensuite">
<div class="as-events" id="as-events-{{ j.date }}">
{% for ev in j.astreinte_events or [] %}
<div class="as-event">
<input class="time-input" type="time" name="astreinte_debut"
data-date="{{ j.date }}" value="{{ ev.debut or '' }}">
<span class="time-sep">→</span>
<input class="time-input" type="time" name="astreinte_fin"
data-date="{{ j.date }}" value="{{ ev.fin or '' }}">
<input type="text" class="as-desc" name="astreinte_desc"
data-date="{{ j.date }}" maxlength="200" placeholder="description"
value="{{ ev.desc or '' }}">
<button type="button" class="as-del" title="Supprimer"
onclick="this.closest('.as-event').remove()">×</button>
</div>
{% else %}
<div class="as-event">
<input class="time-input" type="time" name="astreinte_debut"
data-date="{{ j.date }}" value="">
<span class="time-sep">→</span>
<input class="time-input" type="time" name="astreinte_fin"
data-date="{{ j.date }}" value="">
<input type="text" class="as-desc" name="astreinte_desc"
data-date="{{ j.date }}" maxlength="200" placeholder="description" value="">
<button type="button" class="as-del" title="Supprimer"
onclick="this.closest('.as-event').remove()">×</button>
</div>
{% endfor %}
</div>
<button type="button" class="as-add" onclick="asAddEvent('{{ j.date }}')">+ intervention</button>
{% if j.retour_min is not none %}<span class="as-hint" title="11h de repos consécutif après la dernière activité">retour ≥ {{ j.retour }}</span>{% endif %}
{% if j.astreinte_min %}<span class="as-total" title="Compteur séparé, hors heures de semaine">astreinte : {{ j.astreinte_h }}</span>{% endif %}
</div>
{% else %}
<div id="as-block-{{ j.date }}"></div>