fix : le cron de bascule recalcule la vraie clôture au lieu du placeholder
LeaveRolloverCommand::resolveCarry se fiait au closing_days stocké quand une ligne existait pour l'exercice précédent. Or closing_days n'est jamais recalculé après création (toujours = opening, ou 0 sur un bootstrap), donc le report propageait l'ouverture sans créditer l'acquisition de l'année. Cas Aurore : bascule 2026->2027 aurait reporté 0 au lieu de 31. resolveCarry calcule désormais toujours la clôture réelle via computeDynamicClosingForYear (bootstrap-aware, intègre acquisition + samedis + fractionnés − pris), puis fige ce résultat dans closing_days de l'exercice qui se termine. Vérifié sur données réelles : report 2027 d'Aurore = 31,00 j / 5,00 samedis (au lieu de 0). Corrections manuelles préservées : le cron reste idempotent (ne réécrit pas une ligne existante) et le bon levier de correction devient opening_days (propagé par le recalcul), pas closing_days. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+12
-5
@@ -69,7 +69,7 @@ Etat implementation:
|
||||
- le calcul de synthese conges lit en priorite `opening_days/opening_saturdays` de cette table quand une ligne existe pour `(employee, rule_code, year)`
|
||||
- si aucune ligne n'existe, le calcul reste base sur le report dynamique N-1
|
||||
- **le report dynamique (`LeaveBalanceComputationService::computeDynamicClosingForYear`, qui alimente le solde d'ouverture de l'exercice suivant) ancre lui aussi sur cette table** : pour chaque exercice de sa boucle, si une ligne bootstrap existe il part de `opening_days/opening_saturdays` (et ajoute l'offset `taken_days/taken_saturdays`) au lieu de recalculer depuis l'embauche. Sans cet ancrage, la clôture d'un exercice consulté en avance (ex. exercice suivant) cumulerait une année pleine d'acquisition par exercice antérieur à la mise en service — aucune absence historique n'étant saisie (cas Aurore : 88 jours au lieu de 31).
|
||||
- la commande `app:leave:rollover` calcule aussi le report dynamique N-1 si la ligne N-1 n'est pas encore persistée (pas de reset a 0 par defaut)
|
||||
- la commande `app:leave:rollover` recalcule **toujours** le report via `computeDynamicClosingForYear(N-1)` (et ne se fie plus au `closing_days` stocké, qui n'est qu'un placeholder = `opening`), puis fige ce résultat dans le `closing_days` de l'exercice qui se termine ; voir § 6
|
||||
|
||||
### Definition des colonnes
|
||||
|
||||
@@ -121,12 +121,19 @@ Date d'effet:
|
||||
- non forfait: au `1er juin`
|
||||
|
||||
Traitement par employe:
|
||||
1. lire l'exercice precedent
|
||||
2. determiner le report:
|
||||
1. determiner le report de l'exercice precedent:
|
||||
- si cloture `paidLeaveSettled=true` sur la periode precedente => report `0`
|
||||
- sinon report = `closing` exercice precedent
|
||||
- sinon report = **cloture reelle recalculee** via `computeDynamicClosingForYear(exercicePrecedent)` (acquisition + samedis + fractionnes − pris, ancree sur l'`opening_days` bootstrap de chaque exercice). On **ne se fie PAS** au `closing_days` stocke : il n'est jamais recalcule apres creation (toujours egal a l'`opening`), donc s'y fier propagerait l'ouverture sans jamais crediter l'acquisition de l'annee (cas Aurore : report 0 au lieu de 31).
|
||||
2. **figer** ce report dans `closing_days/closing_saturdays` de la ligne de l'exercice qui se termine (la colonne contient enfin un vrai solde de cloture, auditable).
|
||||
3. creer la ligne du nouvel exercice avec ce report en `opening_*`
|
||||
4. initialiser `accrued/taken/closing` pour le nouvel exercice
|
||||
4. initialiser `accrued/taken/closing` pour le nouvel exercice (= `opening` a la creation)
|
||||
|
||||
### Correction manuelle d'un solde (RH / comptable)
|
||||
|
||||
Le verrouillage (`is_locked`) n'est pas utilise ; les corrections se font directement en BDD. Deux garde-fous rendent cela sur :
|
||||
|
||||
- **Idempotence** : le cron ne cree la ligne d'un exercice que si elle n'existe pas (les lignes existantes sont ignorees). Une ligne corrigee a la main n'est donc **jamais** ecrasee par un passage ulterieur du cron (meme avec `--force`).
|
||||
- **Le bon levier est `opening_days`, pas `closing_days`** : `computeDynamicClosingForYear` part de l'`opening_days` de chaque exercice comme ancre. Corriger l'`opening_days` d'un exercice (ou la donnee de fond : absence, fractionne, paye) se propage automatiquement aux reports des exercices suivants. Editer un `closing_days` d'un exercice **pas encore bascule** est inutile (il sera recalcule a la bascule) ; une fois la ligne suivante creee, plus rien n'y touche.
|
||||
|
||||
## 7) Donnees a fournir au go-live
|
||||
|
||||
|
||||
Reference in New Issue
Block a user