## Résumé
Nouvel export PDF **Contingent heures de nuit** dans le drawer Export de la liste employés.
- PDF **A4 paysage** : lignes = employés (groupés par site, triés displayOrder/nom/prénom), colonnes = 12 mois civils, chaque mois avec 2 sous-colonnes **H.nuit** et **N.jours**.
- Heures de nuit = minutes dans la fenêtre **21h→6h** via un service partagé `NightHoursCalculator` (mutualisé avec `WorkHourWeeklySummaryProvider` et `YearlyHoursExportBuilder` — duplication supprimée, sans changement de comportement).
- **Conducteurs inclus** via `WorkHour.nightHoursMinutes`. Statut conducteur résolu par date.
- **N.jours** = nb de jours où les minutes de nuit ≥ 240 (4h). Aucun crédit absence/férié.
- Périmètre via `EmployeeRepository::findScoped` (admin → tous, chef de site → ses sites), endpoint `GET /night-hours-contingent/print?year=YYYY` (`ROLE_USER`).
- Sélecteur d'année (année civile). Colonne Nom calibrée, séparateurs de mois épais.
## Composants
- Service `NightHoursCalculator`, builder `NightContingentExportBuilder`, DTO `NightContingentRow`
- Provider `NightHoursContingentPrintProvider` + opération API `NightHoursContingentPrint`
- Gabarit `templates/night-hours-contingent/print.html.twig`
- Option frontend dans `frontend/pages/employees/index.vue`
- Docs : `doc/functional-rules.md`, `CLAUDE.md`, `frontend/data/documentation-content.ts`
## Tests
- Nouveaux tests unitaires : `NightHoursCalculatorTest` (fenêtre 21h→6h, passage minuit, bornes), `NightContingentExportBuilderTest` (agrégation mensuelle, règle ≥4h=1j, conducteur, cas sans heures)
- Suite complète : **208 tests OK**
- Rendu PDF validé visuellement (Twig→Dompdf)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed-on: #28
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
Affinements de l'export PDF des heures (vue Jour) :
- **Colonne Statut** : affiche le **code** du type d'absence (ex. `AT`) au lieu du libellé, sur sa couleur de fond. Férié sans absence inchangé (nom du férié sur fond bleu clair).
- **Colonne Total** en gras.
- **Légende** sous le tableau : carré coloré contenant le code + libellé à droite, 6 éléments par ligne, triée et dédupliquée (hors férié).
- **Bouton Exporter masqué en vue Semaine** (visible uniquement en vue Jour).
Docs mises à jour : `doc/hours-day-export.md`, `frontend/data/documentation-content.ts`, `CLAUDE.md`. Tests backend verts (173/361).
Reviewed-on: #25
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
## Résumé
Ajoute un bouton **Exporter** (admin uniquement) à droite du titre « Heures » qui génère un **PDF d'une journée**, regroupé par site, reprenant les colonnes de la vue Jour **sans la colonne « Valider »**.
- Drawer : champ date (préremplit la date affichée) + cases à cocher des sites (préselectionnées sur le filtre courant).
- Portée identique à l'écran : non-conducteurs, sous contrat à la date, sites cochés (lignes vides incluses).
- Jour/Nuit/Total incluent le crédit d'absence et le crédit virtuel férié.
## Implémentation
- Back : `WorkHourDayExport` (ApiResource) + `WorkHourDayExportProvider`, endpoint `GET /work-hours/day-export?workDate=&siteIds=` (ROLE_ADMIN).
- Calcul des cellules mutualisé via `YearlyHoursExportBuilder::buildDayRowsForEmployees` (source unique de vérité).
- Gabarit `templates/work-hour-day-export/print.html.twig` (A4 portrait compact).
- Front : `HoursDayExportDrawer.vue` + câblage dans `pages/hours.vue`.
- Docs : `doc/hours-day-export.md`, `documentation-content.ts`, `CLAUDE.md`.
## Tests
- Test unitaire `YearlyHoursDayRowsTest` ajouté.
- Suite complète verte : 173 tests, 359 assertions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed-on: #24
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>