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:
@ -12,7 +12,7 @@
|
||||
(j.aprem_entree and j.aprem_entree > borne_aprem) or
|
||||
(j.aprem_sortie and j.aprem_sortie < plages.aprem_fin)
|
||||
) %}
|
||||
<tr id="row-{{ j.date }}">
|
||||
<tr id="row-{{ j.date }}"{% if nom in ['Samedi', 'Dimanche'] %} class="we"{% endif %}>
|
||||
|
||||
<td class="col-jour">
|
||||
<span class="jour-nom">{{ nom }}</span>
|
||||
@ -117,7 +117,7 @@
|
||||
|
||||
{% if j.astreinte_qualifiee %}
|
||||
{% set nb_as = (j.astreinte_events or []) | length %}
|
||||
<tr class="as-row">
|
||||
<tr class="as-row{% if nom in ['Samedi', 'Dimanche'] %} we{% endif %}">
|
||||
<td colspan="9">
|
||||
<div id="as-block-{{ j.date }}" class="as-block" data-date="{{ j.date }}" data-label="Astreinte">
|
||||
<div class="as-head">
|
||||
@ -125,7 +125,8 @@
|
||||
onclick="asToggle(this)">
|
||||
<span class="as-caret">▸</span> {{ nb_as }} intervention{{ 's' if nb_as != 1 else '' }}
|
||||
</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.retour_min is not none %}<span class="as-hint" title="11h de repos consécutif après la dernière activité, fin arrondie au quart d'heure entamé">retour ≥ {{ j.retour }}</span>{% endif %}
|
||||
{% if j.forfait_min %}<span class="as-hint" title="Forfait réglé dans Réglages, ajouté au temps travaillé">forfait + {{ j.forfait_h }}</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>
|
||||
<div class="as-body">
|
||||
@ -166,5 +167,5 @@
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr class="as-row"><td colspan="9"><div id="as-block-{{ j.date }}" class="as-block"></div></td></tr>
|
||||
<tr class="as-row{% if nom in ['Samedi', 'Dimanche'] %} we{% endif %}"><td colspan="9"><div id="as-block-{{ j.date }}" class="as-block"></div></td></tr>
|
||||
{% endif %}
|
||||
|
||||
@ -320,6 +320,12 @@
|
||||
tbody tr:hover .td-fill.cg { background: var(--conge-bg); }
|
||||
tbody tr:not(:last-child) td { border-bottom: 1px solid var(--rule-l); }
|
||||
|
||||
/* Week-end : affiché pour déclarer des astreintes, mais hors heures dues */
|
||||
tbody tr.we td { background: var(--ground); }
|
||||
tbody tr.we:hover td, tbody tr.we:hover .td-fill { background: var(--ground); }
|
||||
tbody tr.we .jour-nom { color: var(--muted); font-weight: 400; }
|
||||
tbody tr.we .calc-num, tbody tr.we .delta-zero { color: var(--rule); }
|
||||
|
||||
td {
|
||||
padding: .5rem .65rem;
|
||||
vertical-align: middle;
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user