Files
SIRH/doc/rtt-rollover.md
tristan 0257e59671
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
[#SIRH-21] Revoir l'affichage des RTT pour les semaines qui se chevauchent (#13)
| Numéro du ticket | Titre du ticket |
|------------------|-----------------|
|                  |                 |

## Description de la PR

## Modification du .env

## Check list

- [ ] Pas de régression
- [ ] TU/TI/TF rédigée
- [ ] TU/TI/TF OK
- [ ] CHANGELOG modifié

Reviewed-on: #13
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
2026-04-02 08:54:55 +00:00

164 lines
5.6 KiB
Markdown

# Rollover RTT - Regles et Mise en Production
Document de reference pour expliquer le fonctionnement metier du report RTT N-1 et preparer le lancement en production.
## 1) Objectif
Permettre le report des heures supplementaires (RTT) d'un exercice a l'autre et fiabiliser les soldes.
Principe:
- le solde d'ouverture est stocke par exercice
- au changement d'exercice, on ouvre la nouvelle periode avec un "solde d'ouverture" (report N-1)
- au go-live, les soldes d'ouverture sont importes manuellement (CSV ou insertion SQL)
## 2) Exercice metier
- exercice RTT: du `1er juin` au `31 mai`
- `year` = annee de fin d'exercice (ex: `2026` = 01/06/2025 -> 31/05/2026)
- employes eligibles: tous sauf `INTERIM` et suivi `PRESENCE`
## 3) Logique de compteurs
- `report N-1`:
- correspond au solde d'ouverture (`opening_minutes`)
- source prioritaire: table `employee_rtt_balances`
- fallback: calcul dynamique de la somme des minutes de recuperation de l'exercice precedent
- `acquis N`:
- somme des minutes de recuperation hebdomadaires de l'exercice en cours
- calcul: `HS totales + bonus 25% + bonus 50%` par semaine
- `disponible`:
- `report N-1 + acquis N`
- affichage du compteur global: en **jours** (1 jour = 7h = 420 minutes)
## 4) Attribution mensuelle des semaines
- une semaine ISO qui chevauche deux mois est affichee dans **les deux mois**, avec les valeurs reparties proportionnellement aux minutes travaillees de chaque portion
- le calcul des heures supplementaires reste hebdomadaire (seuils 35h/39h/43h appliques sur la semaine entiere), seul l'affichage est scinde
- exemple: S14 lundi-mardi en mars, mercredi-dimanche en avril → la S14 apparait en mars (part lun-mar) et en avril (part mer-dim)
## 5) Table cible
Table `employee_rtt_balances` (une ligne par employe et exercice):
- `employee_id`
- `year`
- `opening_minutes`
- `is_locked`
- `created_at`, `updated_at`
Contrainte unique:
- `(employee_id, year)`
Etat implementation:
- la table est creee
- le calcul de synthese RTT lit en priorite `opening_minutes` de cette table quand une ligne existe pour `(employee, year)`
- si aucune ligne n'existe, le calcul dynamique sur l'exercice N-1 est effectue
### Definition des colonnes
- `employee_id`:
- identifiant employe (FK vers `employees`)
- une ligne de solde par employe / exercice
- `year`:
- annee d'exercice (annee de fin)
- `2026` = 01/06/2025 -> 31/05/2026
- `opening_minutes`:
- report N-1 en minutes (solde d'ouverture)
- correspond a la somme des minutes de recuperation de l'exercice precedent
- `is_locked`:
- `false` sur exercice ouvert (recalcul possible)
- `true` apres validation RH (exercice fige)
- `created_at`, `updated_at`:
- trace technique creation / mise a jour
## 6) Rollover automatique
Commande quotidienne (cron) idempotente.
- commande Symfony: `php bin/console app:rtt:rollover`
- comportement date metier:
- le `01/06`: calcule et persiste le report pour chaque employe eligible
- les autres jours: sortie sans action
- option manuelle: `--force` pour executer hors date metier (reprise/correction)
Date d'effet:
- au `1er juin` (meme date que le rollover conges non forfait)
Traitement par employe:
1. verifier l'eligibilite (ni INTERIM, ni suivi PRESENCE)
2. verifier qu'aucune ligne n'existe deja pour `(employee, targetYear)` (idempotence)
3. calculer la somme des minutes de recuperation de l'exercice N-1
4. creer la ligne du nouvel exercice avec ce total en `opening_minutes`
## 7) Donnees a fournir au go-live
La RH doit fournir les soldes RTT a reporter.
Colonnes minimales:
- `employee_id` (id interne)
- `year`
- `opening_minutes` (total en minutes)
Format recommande:
- CSV UTF-8
- separateur `;`
Exemple:
```csv
employee_id;year;opening_minutes
42;2026;1260
17;2026;840
```
Equivalent en insertion SQL directe:
```sql
INSERT INTO employee_rtt_balances (employee_id, year, opening_minutes, is_locked, created_at, updated_at)
VALUES
(42, 2026, 1260, false, NOW(), NOW()),
(17, 2026, 840, false, NOW(), NOW());
```
Conversion rapide: `1260 minutes = 21h00 = 3.00 jours` (1 jour = 420 min = 7h)
## 8) Checklist mise en prod
1. Executer la migration (`employee_rtt_balances`)
2. Importer les soldes d'ouverture N-1 (CSV ou SQL)
3. Verifier 3 cas metier:
- CDI 39h avec heures supp sur l'exercice precedent
- CDI 35h sans heures supp (report = 0)
- INTERIM (doit etre ignore, pas de ligne creee)
4. Activer le cron de rollover
5. Geler (`is_locked`) les exercices historicises valides
Exemple cron (tous les jours a 02:15, juste apres le rollover conges):
Dev
```cron
15 2 * * * cd /var/www/html && php bin/console app:rtt:rollover --no-interaction 2>&1
```
Prod
```cron
10 2 * * * cd /var/www/sirh && php bin/console app:rtt:rollover --no-interaction 2>&1
```
Explication de la ligne cron:
- `15 2 * * *`: tous les jours a 02:15
- `php bin/console app:rtt:rollover --no-interaction`: execute le rollover sans confirmation
- hors `01/06`, la commande sort en no-op (normal)
- `>> var/log/rtt-rollover.log 2>&1`: log sortie standard et erreurs
Execution manuelle forcee:
```bash
php bin/console app:rtt:rollover --force --no-interaction
```
Exemple de verification rapide:
```bash
tail -n 50 /var/www/html/var/log/rtt-rollover.log
```
## 9) Points de vigilance
- Ne jamais modifier `opening_minutes` apres validation RH sans procedure explicite
- Garder une trace de toute correction manuelle (auteur, date, motif)
- Le calcul dynamique N-1 (fallback) parcourt toutes les heures de l'exercice precedent: preferer l'import explicite pour les exercices historiques
- La commande de rollover est idempotente: si une ligne existe deja, l'employe est ignore (pas d'ecrasement)