From d5565ae8c3917f90f47433cb928d52fc644cb6f9 Mon Sep 17 00:00:00 2001 From: tristan Date: Thu, 21 May 2026 08:14:14 +0200 Subject: [PATCH] docs(leave) : document non-forfait header presence + contract-start bound Co-Authored-By: Claude Opus 4.7 (1M context) --- CLAUDE.md | 3 ++- frontend/data/documentation-content.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 27e4367..b07649e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -69,6 +69,7 @@ - Driver contracts: RTT uses `dayHoursMinutes + nightHoursMinutes + workshopHoursMinutes` instead of morning/afternoon/evening time ranges - FORFAIT weekend/holiday bonus: each weekend or public holiday day worked gives bonus leave (full day if morning+afternoon, 0.5 if only one). Added to acquired days, no cap. PRESENCE mode only. - **FORFAIT — jours de présence et N-1** : les congés posés et imputés sur le stock N-1 ne décrémentent **pas** les jours de présence affichés (`presenceDaysByMonth` et `presenceDaysToToday`). Implémenté dans `EmployeeLeaveSummaryProvider::computePresenceDaysByMonth` via un budget N-1 (= `previousYearTakenDays`) consommé chronologiquement avant comptage des absences. Pour les non-forfait, ce budget vaut toujours 0 → comportement inchangé. +- **Jours de présence — borne début de contrat** : `presenceDaysByMonth`/`presenceDaysToToday` sont calculés à partir de `resolveEarliestContractStartWithinRange` (début de contrat dans l'exercice), pas du début d'exercice brut. Évite de compter comme « présents » les jours ouvrés antérieurs à l'embauche pour une entrée en cours d'exercice (ex. CDD : Dylan passait de 43,5 à 246 sans la borne). Sans effet pour un employé présent depuis avant l'exercice ni pour le forfait (déjà capé au début de phase). ## Onglet Congés (fiche employé) - Calendrier annuel des congés (`frontend/components/employees/LeaveTab.vue`) — période = Janvier→Décembre pour FORFAIT, Juin(N-1)→Mai(N) pour les autres contrats. Règle pilotée par le **contrat courant** (cf. `EmployeeLeaveSummaryProvider::resolveYear`), même quand on consulte une année passée. @@ -92,7 +93,7 @@ - Sélectionner une phase passée : - Onglet **Congés** : période et règles de la phase (Juin→Mai non-forfait, Jan→Déc FORFAIT). Exercice de transition capé sur `phase.endDate`. **Cap `from` au `phase.startDate` uniquement pour FORFAIT** (sémantique année civile). Pour le non-forfait, l'exercice CP reste annuel et continu à travers les changements d'heures (35h→39h, etc.) — seul `resolveEffectivePeriodStart` clampe sur la date d'entrée en contrat des nouveaux embauchés. - **Entrée FORFAIT en cours d'année** (année d'entrée only) : l'exercice d'entrée crédite `repos_proratisés + CP_reportés` au lieu de `max(0, businessDays−218)`=0. Repos année = `jours_ouvrés_année − 218 − 25`, proratisés par jours ouvrés. CP reportés = solde de la phase non-forfait précédente (jours ouvrés nets + samedis bruts ; un samedi posé ne réduit PAS le report ; fractionnés exclus). Nouvel embauché = repos seuls. Années pleines suivantes + forfait démarrant le 01/01 = calcul 218 inchangé (→34). Services : `EmployeeLeaveSummaryProvider::{resolveLeavePolicy (branche FORFAIT), isForfaitEntryYear, computeProratedForfaitRepoDays, resolveCarriedCpFromPriorPhase}`. Témoin Grégory : ≈13. - - **Header fiche employé (jours à travailler / présence / restant)** : `EmployeeLeaveSummary.forfaitWorkTargetDays` = `jours_ouvrés_période − acquiredDays` (218 année pleine = 252−34 ; entrée = 168−13 ≈ **155**). Le header (`useEmployeeDetailPage.employeeContractWorkLabel` + `forfaitRemainingDaysLabel`) affiche `Forfait - {target} jours ({presenceDaysToToday} présence · {target−présence} restants)`. Avant : `218` codé en dur → faux pour une entrée en cours d'année. Témoin Grégory : `155 jours (11 présence · 144 restants)`. + - **Header fiche employé (jours à travailler / présence / restant)** : `EmployeeLeaveSummary.forfaitWorkTargetDays` = `jours_ouvrés_période − acquiredDays` (218 année pleine = 252−34 ; entrée = 168−13 ≈ **155**). Le header (`useEmployeeDetailPage.employeeContractWorkLabel` + `forfaitRemainingDaysLabel`) affiche `Forfait - {target} jours ({presenceDaysToToday} présence · {target−présence} restants)`. Avant : `218` codé en dur → faux pour une entrée en cours d'année. Témoin Grégory : `155 jours (11 présence · 144 restants)`. **Non-forfait** : le header affiche les jours de présence seuls via `nonForfaitPresenceLabel` (`{weeklyHours} heures ({presenceDaysToToday} présence)`, ex. `39 heures (43,5 présence)`). Le récap congés est désormais chargé en eager pour tout employé avec onglet Congés (pas seulement le forfait) afin d'alimenter ce libellé. - Onglet **RTT** : visible ssi `phase.contractType !== FORFAIT`. Tableau hebdo affiché sur l'exercice complet (Juin→Mai) ; `periodFrom` non capé sur `phase.startDate` (les semaines avant embauche ou hors phase apparaissent à 0). `periodTo`/`limitDate` capés sur `phase.endDate` pour les phases clôturées. `+ Payer les RTT` actif uniquement sur l'exercice contenant `phase.endDate`. - Bandeau jaune affiché en mode phase passée. Édition d'absences et des stocks de report (jours fractionnés, Année N-1 payés) désactivée. - Sélection non persistée — chaque ouverture de fiche démarre sur la phase courante. diff --git a/frontend/data/documentation-content.ts b/frontend/data/documentation-content.ts index d74d924..8101b59 100644 --- a/frontend/data/documentation-content.ts +++ b/frontend/data/documentation-content.ts @@ -430,6 +430,7 @@ export const documentationSections: DocSection[] = [ blocks: [ { type: 'paragraph', content: 'Pour les contrats CDI et CDD (hors forfait), l\'exercice de congés va du 1er juin (N-1) au 31 mai (N).' }, { type: 'list', content: 'Acquisition annuelle : 25 jours + 5 samedis\nAcquisition mensuelle : 2,08 jours + 0,42 samedi par mois\nProratisation en cas de début/fin ou suspension en cours de mois\nContrat 4h : 10 jours annuels, 0 samedi, 0,83 jour/mois' }, + { type: 'paragraph', content: 'En haut de la fiche, l\'en-tête affiche le nombre de jours de présence du salarié sur l\'exercice. La présence est comptée à partir de la date de début de contrat : les jours antérieurs à l\'embauche ne sont pas comptés (utile pour un salarié arrivé en cours d\'année).' }, ], }, {