Astreintes : fenêtre 18h-18h, week-end affiché, forfait réglable

Un jour d'astreinte déclaré couvre désormais 18:00 → 18:00 le lendemain :
les interventions hors fenêtre ne comptent ni au décompte ni pour les
11h de repos, et deux astreintes consécutives se recollent sans trou.
La fin de la dernière intervention est arrondie au quart d'heure entamé
avant de poser le retour. Samedi et dimanche apparaissent dans la
semaine (heures dues nulles) pour pouvoir y déclarer des astreintes,
dans les exports aussi. Un réglage par utilisateur ajoute une durée
forfaitaire au temps travaillé de chaque jour d'astreinte déclaré.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
This commit is contained in:
Jacquin Antoine
2026-09-08 23:06:59 +02:00
parent dc0e786428
commit 23271d736d
8 changed files with 351 additions and 48 deletions

View File

@ -50,6 +50,52 @@
</form>
</div>
<div class="settings-card">
<span class="hist-label">Ratios des heures d'astreinte</span>
<p class="settings-p">
Pondération des heures d'astreinte selon le type de jour et la fenêtre horaire :
le décompte se fait par tranches de 15 min (toute tranche entamée compte en
totalité) et chaque tranche est multipliée par le ratio de la première règle qui
la couvre. Une tranche hors règle compte ×1 (« Autre »). Règles globales à tous
les comptes, ajustables dans <code>data/config.json</code> (clé
<code>astreinte_facteurs</code>).
</p>
<div class="as-ratios">
{% for f in facteurs %}
<div class="as-ratio-row">
<span class="as-ratio-nom">{{ f.nom }}</span>
<span class="as-ratio-jours">{% for j in f.jours %}{{ {'semaine': 'Lun–Ven', 'sam': 'Samedi', 'dim': 'Dimanche', 'ferie': 'Férié'}[j] }}{% if not loop.last %} · {% endif %}{% endfor %}</span>
<span class="as-ratio-fenetre">{{ f.debut }} → {{ f.fin }}</span>
<span class="as-ratio-facteur">×{{ '%g' % f.facteur }}</span>
</div>
{% endfor %}
</div>
</div>
<div class="settings-card">
<span class="hist-label">Forfait par jour d'astreinte</span>
<p class="settings-p">
Durée ajoutée automatiquement au temps travaillé de chaque jour d'astreinte
déclaré (bouton <b>AS</b>), en plus des interventions saisies. Elle compte dans
le bilan de la semaine ; le lendemain de l'astreinte n'est pas concerné.
Vide = pas de forfait.
</p>
{% if forfait_saved %}
<div class="settings-saved">Enregistré.</div>
{% endif %}
{% if forfait_error %}
<div class="settings-error">Durée invalide (format HH:MM, 12h00 maximum).</div>
{% endif %}
<form method="post" action="/settings/astreinte-forfait" class="settings-form">
<label class="login-label" for="astreinte_forfait">Durée ajoutée par jour d'astreinte</label>
<input id="astreinte_forfait" class="login-input time-range-input" type="time" step="900"
name="astreinte_forfait" value="{{ plages.astreinte_forfait }}">
<button class="login-btn" type="submit">Enregistrer</button>
</form>
</div>
<div class="settings-card">
<span class="hist-label">Notifications (ntfy) <a href="/aide" class="settings-help-link">Aide</a></span>
<p class="settings-p">
@ -173,6 +219,30 @@
}
.settings-p { font-size: 13px; color: var(--text); line-height: 1.6; }
.settings-p a { color: var(--accent); }
.settings-p code {
font-family: var(--mono);
font-size: 12px;
background: var(--ground);
border: 1px solid var(--rule-l);
padding: 0 .25rem;
}
.as-ratios { border: 1px solid var(--rule-l); display: flex; flex-direction: column; }
.as-ratio-row {
display: grid;
grid-template-columns: minmax(110px, auto) 1fr auto auto;
gap: .5rem 1rem;
align-items: baseline;
padding: .45rem .8rem;
}
.as-ratio-row + .as-ratio-row { border-top: 1px solid var(--rule-l); }
.as-ratio-nom { font-size: 13px; font-weight: 500; }
.as-ratio-jours { font-size: 12px; color: var(--muted); }
.as-ratio-fenetre { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.as-ratio-facteur { font-family: var(--mono); font-size: 13px; font-weight: 500; color: var(--accent-2); }
@media (max-width: 600px) {
.as-ratio-row { grid-template-columns: 1fr auto; row-gap: .1rem; }
.as-ratio-jours, .as-ratio-fenetre { grid-column: 1 / -1; }
}
.settings-form { display: flex; flex-direction: column; gap: .5rem; max-width: 420px; }
.settings-saved {
background: var(--pos-bg);