2.8 KiB
É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(middlewareleave-recap-access.ts) - L'endpoint API
GET /api/leave-recap(le provider renvoie403si 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 = todayEmployeeLeaveRecapProvider(é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édantasOfDate(au lieu du mois précédent today).resolveTakenCalculationEndDate()— les absences postérieures àasOfDatesont 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.