74 lines
2.8 KiB
Markdown
74 lines
2.8 KiB
Markdown
# Écran Récap. congés
|
||
|
||
## Objet
|
||
|
||
Vue tableau des soldes de congés par employé, figée à un cutoff temporel (fin de semaine S-2).
|
||
Complémentaire à l'export PDF admin : mêmes colonnes, accès étendu aux employés et chefs de site.
|
||
|
||
## Cutoff
|
||
|
||
La formule est : `cutoffDate = dimanche de (lundi de la semaine courante − 14 jours)`.
|
||
|
||
Exemple : mardi 14/04/2026 (S16) → **dimanche 05/04/2026 23:59:59** (fin S14).
|
||
|
||
Le cutoff est purement temporel : l'état `isValid` des heures n'entre pas en compte. Les heures
|
||
et absences postérieures au cutoff sont ignorées dans le calcul des soldes.
|
||
|
||
Implémentation : `App\Util\LeaveRecapCutoff::resolveCutoff()` côté backend, helper `parseYmd` +
|
||
`getIsoWeekNumber` côté frontend pour l'affichage du badge.
|
||
|
||
## Colonnes
|
||
|
||
Identiques au PDF :
|
||
|
||
- Nom
|
||
- Prénom
|
||
- Contrat
|
||
- CP N-1 restant
|
||
- CP N
|
||
- Samedis acquis
|
||
- RTT
|
||
|
||
Pour les admins et chefs de site, une colonne **Site** est ajoutée à gauche.
|
||
|
||
## Scoping
|
||
|
||
| Profil | Données visibles |
|
||
|---------------|-----------------------------------------|
|
||
| `ROLE_ADMIN` | Tous les employés actifs, tous sites |
|
||
| `ROLE_USER` (chef de site) | Employés actifs des sites autorisés via `UserSiteRole` |
|
||
| `ROLE_SELF` | Uniquement l'employé lié à son compte |
|
||
|
||
## Flag d'accès
|
||
|
||
Le champ `User.hasLeaveRecapAccess` (boolean, défaut `false`) conditionne :
|
||
|
||
- L'affichage de l'entrée "Récap. congés" dans la sidebar
|
||
- L'accès à la route `/leave-recap` (middleware `leave-recap-access.ts`)
|
||
- L'endpoint API `GET /api/leave-recap` (le provider renvoie `403` si le flag est faux)
|
||
|
||
Le flag s'applique même aux admins : un admin sans le flag ne voit pas l'écran. Il se configure
|
||
dans le drawer de création/édition d'un utilisateur.
|
||
|
||
## Service partagé
|
||
|
||
`App\Service\Leave\LeaveRecapRowBuilder::build(Employee $employee, DateTimeImmutable $asOfDate)`
|
||
construit une ligne de récap. Il est utilisé par :
|
||
|
||
- `LeaveRecapPrintProvider` (PDF admin) avec `$asOfDate = today`
|
||
- `EmployeeLeaveRecapProvider` (écran) avec `$asOfDate = cutoff`
|
||
|
||
## Propagation du cutoff dans les calculs
|
||
|
||
`EmployeeLeaveSummaryProvider::computeYearSummary()` accepte un `?DateTimeImmutable $asOfDate`.
|
||
Lorsqu'il est fourni et appliqué à l'année cible, il remplace "today" dans :
|
||
|
||
- `resolveAccrualCalculationEndDate()` — la borne d'accrual devient le dernier jour du mois
|
||
précédant `asOfDate` (au lieu du mois précédent today).
|
||
- `resolveTakenCalculationEndDate()` — les absences postérieures à `asOfDate` sont ignorées.
|
||
|
||
Pour les années antérieures (carry forward), le comportement reste inchangé (pas de cap).
|
||
|
||
Le RTT est capé via `RttRecoveryComputationService::computeTotalRecoveryForExercise(..., $limitDate)`
|
||
qui existait déjà, en passant `cutoff` comme date de référence.
|