docs(overtime-contingent) : doc fonctionnelle, CLAUDE.md et doc in-app
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -108,6 +108,24 @@
|
||||
- **Verrou** : si le report de l'exercice courant est `is_locked`, le paiement rétroactif est **refusé** (`assertReportNotLocked`) — la RH doit déverrouiller d'abord.
|
||||
- Portée limitée à N-1 (chaîne de recalcul = 1 étape). Si la ligne courante n'existe pas encore, le fallback provider couvre l'affichage (cf. ci-dessus).
|
||||
|
||||
## Contingent heures supplémentaires payées
|
||||
- Suivi par **année civile** (Janv–Déc) des heures supp payées vs plafond légal (350 h
|
||||
chauffeur / 220 h autres), non-forfait uniquement.
|
||||
- **Heures payées** = `base25 + base50` (hors bonus). **Mapping** : paiements RTT stockés par
|
||||
exercice → `annéeCivile = mois ≥ 6 ? exercice − 1 : exercice` ; année civile Y = exercice Y
|
||||
(mois 1–5) + exercice Y+1 (mois 6–12). Cœur partagé pur `OvertimePaidContingentCalculator`.
|
||||
- **Plafond** résolu sur `isDriver` du **contrat courant**.
|
||||
- **Fiche employé** : encart header `Contingent {année} : X h / plafond h` (année civile
|
||||
courante, rouge si dépassement), via `GET /employees/{id}/overtime-contingent`. Encart
|
||||
volontairement indépendant de la phase sélectionnée (toujours l'année civile courante).
|
||||
- **Export PDF** (`GET /overtime-contingent/print?year=&siteIds=`, `ROLE_USER`,
|
||||
`findScoped`) : groupé par site (`displayOrder`), tri `displayOrder → nom → prénom`,
|
||||
colonnes Janv–Déc + `Total payé / payable`. Drawer liste employés : sélecteur année +
|
||||
sites (vide = périmètre complet). Exclut les FORFAIT (contrat courant).
|
||||
- ⚠️ Bug latent consigné : `SalaryRecapPrintProvider` rattache mal les paiements RTT des mois
|
||||
Juin–Déc (requête par année civile sur un stockage par exercice). Hors périmètre.
|
||||
- Doc : `doc/overtime-contingent.md`.
|
||||
|
||||
## Vue contrat (sélecteur de phase)
|
||||
- Picker `Vue contrat` en haut de la fiche employé (`pages/employees/[id].vue`). Caché si l'employé n'a qu'une phase.
|
||||
- Phase = groupe d'`EmployeeContractPeriod` consécutifs partageant la signature `(contract.type, weeklyHours, isDriver)`. Résolu par `App\Service\Contracts\EmployeeContractPhaseResolver`.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# Contingent d'heures supplémentaires payées
|
||||
|
||||
## Objectif
|
||||
Suivre, par année civile (Janv–Déc), les heures supplémentaires payées de chaque employé
|
||||
non-forfait (chauffeurs inclus) face au plafond légal annuel.
|
||||
|
||||
## Règles
|
||||
- **Heures payées** = `base25 + base50` (en minutes), hors majoration (bonus).
|
||||
- **Plafond** : 350 h pour les chauffeurs (contrat courant `isDriver`), 220 h sinon.
|
||||
- **Périmètre** : non-forfait uniquement (FORFAIT exclus, ni RTT ni heures supp payées).
|
||||
|
||||
## Mapping exercice → année civile
|
||||
Les paiements RTT (`EmployeeRttPayment`) sont stockés par **exercice** (`year` = Juin N-1 →
|
||||
Mai N) + `month` (1–12). L'année civile d'un paiement :
|
||||
|
||||
annéeCivile = month >= 6 ? exerciseYear - 1 : exerciseYear
|
||||
|
||||
Donc l'année civile **Y** agrège : exercice `Y` (mois 1–5) + exercice `Y+1` (mois 6–12).
|
||||
|
||||
## Implémentation
|
||||
- Cœur partagé : `App\Service\WorkHours\OvertimePaidContingentCalculator` (pur).
|
||||
- Repo : `EmployeeRttPaymentRepository::findByEmployeesAndYears`.
|
||||
- Fiche employé : `GET /employees/{id}/overtime-contingent?year=YYYY` → encart header
|
||||
(`Contingent {année} : X h / plafond h`, rouge si dépassement, année civile courante).
|
||||
- Export PDF : `GET /overtime-contingent/print?year=&siteIds=` (`ROLE_USER`, périmètre
|
||||
`findScoped`), groupé par site (`displayOrder`), tri `displayOrder → nom → prénom`,
|
||||
colonnes Janv–Déc + colonne `Total payé / payable`. Builder
|
||||
`OvertimeContingentExportBuilder`, template `overtime-contingent/print.html.twig`.
|
||||
|
||||
## Hors périmètre / connu
|
||||
- Bug latent récap salaire : `SalaryRecapPrintProvider` requête `findByYearAndMonth` avec
|
||||
l'année civile alors que le stockage est par exercice (mauvais rattachement des paiements
|
||||
des mois Juin–Déc sur le récap mensuel). À corriger séparément.
|
||||
@@ -643,6 +643,18 @@ export const documentationSections: DocSection[] = [
|
||||
{ type: 'note', content: 'Export « Contingent H.nuit » : depuis la liste des employés, bouton Export → « Contingent H.nuit » + année. Génère un PDF A4 paysage avec une ligne par employé (groupés par site) et une colonne par mois, chacune avec le total d\'heures de nuit (travail entre 21h et 6h) et le nombre de nuits (jours où au moins 4h ont été travaillées de nuit). Les conducteurs utilisent leurs heures de nuit saisies.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'contingent-heures-supp',
|
||||
title: 'Export Contingent H.supp.',
|
||||
requiredLevel: 'admin',
|
||||
blocks: [
|
||||
{ type: 'paragraph', content: 'L\'encart « Contingent {année} : X h / plafond h », affiché dans l\'en-tête de la fiche d\'un employé non-forfait, indique le total d\'heures supplémentaires payées sur l\'année civile en cours face au plafond légal. Il passe en rouge si ce plafond est dépassé.' },
|
||||
{ type: 'list', content: 'Plafond chauffeur (contrat courant « conducteur ») : 350 h\nPlafond autres salariés non-forfait : 220 h\nSeuls les employés non-forfait disposent de cet encart (FORFAIT exclus)' },
|
||||
{ type: 'paragraph', content: 'L\'export PDF « Contingent H.supp. » est accessible depuis la liste des employés, via le bouton Export → option « Contingent H.supp. ». Choisissez l\'année civile (par défaut l\'année courante) et éventuellement des sites ; sans sélection de site, tous les sites de votre périmètre sont inclus.' },
|
||||
{ type: 'list', content: 'PDF A4 paysage, une ligne par employé non-forfait, groupé par site\nTri : ordre d\'affichage du site, puis nom, puis prénom\nColonnes : Janv à Déc (heures payées par mois) + colonne « Total payé / payable »\nLes employés FORFAIT n\'apparaissent pas dans cet export' },
|
||||
{ type: 'note', content: 'Les heures prises en compte sont les bases payées (25 % et 50 % confondus), hors majorations. Le contingent est calculé sur l\'année civile (janvier–décembre), indépendamment de l\'exercice RTT (juin–mai) : un paiement RTT saisi pour le mois de juin est rattaché à l\'année civile précédente.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'impression-absences',
|
||||
title: 'Impression absences',
|
||||
|
||||
Reference in New Issue
Block a user