From cfbea730d7f6c2badad5f4e4482b61a43ebae322 Mon Sep 17 00:00:00 2001 From: tristan Date: Tue, 26 May 2026 10:06:16 +0200 Subject: [PATCH] =?UTF-8?q?docs=20:=20spec=20exercice=20suivant=20sur=20s?= =?UTF-8?q?=C3=A9lecteurs=20Cong=C3=A9s=20et=20RTT=20(SIRH-32)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 (1M context) --- ...5-26-exercice-suivant-conges-rtt-design.md | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-26-exercice-suivant-conges-rtt-design.md diff --git a/docs/superpowers/specs/2026-05-26-exercice-suivant-conges-rtt-design.md b/docs/superpowers/specs/2026-05-26-exercice-suivant-conges-rtt-design.md new file mode 100644 index 0000000..4246250 --- /dev/null +++ b/docs/superpowers/specs/2026-05-26-exercice-suivant-conges-rtt-design.md @@ -0,0 +1,118 @@ +# Proposer toujours l'exercice suivant dans les sélecteurs Congés et RTT + +**Date** : 2026-05-26 +**Ticket** : SIRH-32 +**Statut** : design validé + +## Contexte + +Les onglets **Congés** et **RTT** de la fiche employé proposent un sélecteur +d'exercice (`availableLeaveYears` / `availableRttYears`) dont la borne haute est +plafonnée à l'**exercice courant**. La RH a commencé à poser des congés sur +l'**exercice suivant**, mais ne peut pas le consulter dans la fiche employé : +l'exercice suivant n'apparaît pas dans le menu déroulant. + +On veut que le sélecteur propose **toujours** l'exercice suivant pour une phase +de contrat ouverte, afin que ce besoin ne ressurgisse jamais. + +## Faisabilité — déjà supportée côté backend + +Aucun changement backend n'est nécessaire : + +- `EmployeeLeaveSummaryProvider::clampYearToPhase` et son équivalent RTT ne + plafonnent **pas** vers le haut quand la phase est ouverte (`phase.endDate` + nul → `lastYear = null`). Une requête `?year=&phaseId=` + est donc déjà calculée correctement. +- La validation `year` (2000–2100) couvre largement l'exercice suivant. + +Le seul blocage est le **frontend**, qui calcule `maxYear = exercice courant`. + +## Le changement + +Frontend uniquement. Dans `frontend/composables/useEmployeeLeave.ts` +(`availableLeaveYears`) et `frontend/composables/useEmployeeRtt.ts` +(`availableRttYears`), la borne haute devient : + +- **Phase ouverte** (pas de `phase.endDate`) : + `maxYear = exercice courant + 1`. +- **Phase clôturée** (`phase.endDate` présent) : **inchangé** → + `maxYear = exercice de fin de phase` (on ne propose pas au-delà d'une phase + terminée). + +Le `+1` porte sur le **numéro d'exercice**, donc il est correct pour le forfait +(année civile) comme pour le non-forfait (Juin N-1 → Mai N), via +`computeLeaveYearForDate` / `computeRttYearForDate`. + +### Pseudo-code de la borne + +``` +maxYear = phase.endDate + ? computeYearForDate(phase.endDate) // phase clôturée : cap à la fin de phase + : currentYear + 1 // phase ouverte : on propose l'exercice suivant +``` + +La borne basse (`minYear = max(phaseStartYear, dataFloor)`) est **inchangée**. + +## Comportements conservés + +- **Sélection par défaut** : inchangée. L'onglet s'ouvre toujours sur l'exercice + **courant** ; l'exercice suivant est seulement disponible dans le menu (pas de + saut automatique sur le futur). `initSelected*Year` continue d'initialiser sur + `current*Year`, qui reste dans la plage `[minYear ; maxYear]`. +- **Verrouillage des éditions** : `isHistoricalYear` (`selectedYear !== currentYear`) + reste tel quel. Sur l'exercice suivant, les boutons **Jours fractionnés**, + **Année N-1 payés** (onglet Congés) et **+ Payer les RTT** (onglet RTT) sont + **désactivés** — souhaitable : pas d'édition de stocks ni de paiement sur un + exercice pas encore démarré. +- **Aucune mention « passé » trompeuse** : le bandeau « Vous consultez + l'historique » est piloté par la phase (`isViewingPastPhase`), pas par l'année + sélectionnée ; sélectionner un exercice futur ne l'affiche pas. + +## Affichage des congés posés sur l'exercice suivant (réponse Q1) + +Le header congés (grille de compteurs de l'onglet + libellé présence du header +de fiche) reflète **le récap de l'exercice sélectionné**. Chaque récap est +calculé sur sa fenêtre `[from, to]` ; les absences/jours pris ne sont comptés que +dans cette fenêtre. + +- **Sur l'exercice courant** (vue par défaut) : les congés posés sur l'exercice + suivant **n'apparaissent pas** dans les compteurs — comportement correct. +- **Sur l'exercice suivant** (sélectionné) : ils s'affichent (calendrier + + compteur « Pris »). + +### Caveat fonctionnel + +Sur l'exercice suivant, les compteurs **report / Année N-1 / reste** sont +**provisoires** jusqu'à la clôture de l'exercice courant (ils en dépendent). En +revanche, le **« Pris » et le calendrier** des congés posés sont exacts. À +communiquer à la RH. + +## Périmètre + +- Onglet **Congés** et onglet **RTT** (les deux sélecteurs partagent la même + mécanique). +- Forfait (année civile) et non-forfait (Juin→Mai). + +## Hors périmètre + +- Aucune modification de la mécanique de saisie d'absences (la RH pose déjà des + congés sur l'exercice suivant via les écrans Calendrier / Heures, indépendamment + de ce sélecteur). +- Pas de proposition de plusieurs exercices futurs (un seul : N+1). +- Pas d'activation des éditions de stocks/paiement sur l'exercice futur. + +## Documentation à mettre à jour (règle obligatoire CLAUDE.md) + +- `doc/leave-tab.md` — plage du sélecteur. +- `doc/rtt-tab.md` — plage du sélecteur. +- `CLAUDE.md` — sections « Onglet Congés » et « Onglet RTT » (description de la + plage `max(...)` → borne haute `exercice courant + 1` sur phase ouverte). +- `frontend/data/documentation-content.ts` — documentation in-app. + +## Tests + +Pas de harnais de test frontend dans le projet (backend PHPUnit uniquement). La +modification est de la logique de calcul de plage dans deux `computed` : +vérification manuelle (dev Nuxt) que l'exercice suivant apparaît dans les deux +sélecteurs pour une phase ouverte, et n'apparaît pas pour une phase clôturée. Les +tests backend existants doivent rester verts (aucun changement backend).