327c10fda4
Auto Tag Develop / tag (push) Successful in 7s
## Résumé
Suivi par **année civile** (Janv–Déc) des heures supplémentaires payées des employés non-forfait (chauffeurs inclus) face au plafond légal (**350 h** chauffeurs / **220 h** autres).
- **Fiche employé** : encart header `Total H.payés {année} : X h / plafond h` (année civile courante, rouge si dépassement), via `GET /employees/{id}/overtime-contingent`.
- **Export PDF** `GET /overtime-contingent/print?year=&siteIds=` (ROLE_USER, périmètre `findScoped`) : groupé par site, colonnes Janv–Déc + colonne `Total payé / payable`. Drawer liste employés (année + sites).
- Heures payées = `base25 + base50` (hors majoration). Mapping exercice→civil : `mois ≥ 6 ? exercice−1 : exercice`.
- Cœur partagé pur `OvertimePaidContingentCalculator`.
- Ajout « Année civile » dans le titre des deux exports PDF (contingent H.supp. et heures de nuit).
## Tests
- 214 tests PHPUnit verts (calculateur : mapping civil, base-only, plafond ; builder : ventilation mensuelle, ligne à zéro).
## Hors périmètre (consigné)
- Bug latent `SalaryRecapPrintProvider` : rattachement des paiements RTT des mois Juin–Déc par année civile sur un stockage par exercice. À traiter séparément.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed-on: #29
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
1.8 KiB
1.8 KiB
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 (Total H.payés {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ètrefindScoped), groupé par site (displayOrder), tridisplayOrder → nom → prénom, colonnes Janv–Déc + colonneTotal payé / payable. BuilderOvertimeContingentExportBuilder, templateovertime-contingent/print.html.twig.
Hors périmètre / connu
- Bug latent récap salaire :
SalaryRecapPrintProviderrequêtefindByYearAndMonthavec 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.