docs : add contract-phase-view documentation

This commit is contained in:
2026-05-19 12:21:06 +02:00
parent a5c75a9129
commit 835e758ed1

View File

@@ -0,0 +1,59 @@
# Vue contrat — sélecteur de phase
## Objectif
Permettre à la RH de consulter les onglets Congés et RTT d'un employé selon une phase de contrat passée (ex. un 39h CDI avant un switch FORFAIT, ou un CDD clôturé avec solde de tout compte) sans changer le comportement par défaut sur la phase courante.
## Concept de "phase"
Une **phase** = groupe d'`EmployeeContractPeriod` consécutifs (triés par `startDate`) partageant la signature `(contract.type, weeklyHours, isDriver)`. Le service `EmployeeContractPhaseResolver` (`src/Service/Contracts/EmployeeContractPhaseResolver.php`) calcule ces phases à la volée depuis `Employee::getContractPeriods()`.
Une transition de signature (35h → 39h, 39h → FORFAIT, driver false→true, weeklyHours 28→30, etc.) ouvre une nouvelle phase. Un type différent entre deux périodes de même signature empêche leur fusion (39h → INTERIM → 39h = 3 phases).
## Picker UI
- Position : en haut de la fiche employé, sous le nom et au-dessus des onglets.
- Libellé : `Vue contrat`.
- Caché si l'employé n'a qu'une seule phase.
- Sélection non persistée — chaque ouverture de fiche démarre sur la phase courante.
## Bandeau d'information
Affiché quand le picker est sur une phase passée. Indique que le mode lecture est partiel — les paiements de solde restent possibles, l'édition d'absences et des stocks de report est désactivée.
## Effet sur les onglets
| Onglet | Effet |
|---|---|
| Congés | Recharge avec les règles de la phase. Période Juin→Mai pour non-forfait, Jan→Déc pour FORFAIT. Exercices bornés à la phase. |
| RTT | Visible ssi `phase.contractType !== FORFAIT`. Exercices bornés à la phase. |
| Heures, Frais, Formation, Contrat, Calendrier | Non impactés. |
## Paiements de solde sur phase passée
- **RTT** : `+ Payer les RTT` activé sur le **dernier exercice de la phase** uniquement (l'exercice contenant `phase.endDate`). Les exercices antérieurs restent en lecture seule.
- **CP** : utiliser le mécanisme existant `EmployeeContractPeriod.paidLeaveSettledClosureDate` pour solder. Pas de nouveau channel.
## Transition d'exercice
Quand un exercice chevauche deux phases (ex. switch 39h→FORFAIT au 01/05/2026 fait que l'exercice Juin 2025 → Mai 2026 est à cheval) :
- Vu depuis la phase 39h, l'exercice est borné à `phase.endDate` (30/04/2026).
- Vu depuis la phase FORFAIT, la période civile 2026 est bornée à `phase.startDate` (01/05/2026).
## API
Les endpoints suivants acceptent `?phaseId=N` :
- `GET /employees/{id}/leave-summary`
- `GET /employees/{id}/rtt-summary`
Quand absent, ils utilisent la phase courante (comportement inchangé).
`Employee.contractPhases` (lecture, groupe `employee:read`) liste les phases au format `{id, contractType, weeklyHours, isDriver, contractNature, startDate, endDate, periodIds, isCurrent}`.
## Tests
- `tests/Service/Contracts/EmployeeContractPhaseResolverTest.php` (unit)
- `tests/State/EmployeeLeaveSummaryProviderTest.php` (functional, phaseId)
- `tests/State/EmployeeRttSummaryProviderTest.php` (functional, phaseId)
- `tests/State/EmployeeRttPaymentProcessorTest.php` (functional, dernier exo phase clôturée)
- `tests/Service/Exercise/ExerciseYearResolverTest.php` (helper extrait pendant Task 5)