feat : ajout de la gestion RTT
This commit is contained in:
@@ -2,8 +2,9 @@
|
||||
|
||||
Ce document centralise les règles métier actuellement implémentées dans l'application.
|
||||
|
||||
Document complementaire (rollover conges et checklist de lancement):
|
||||
- `doc/leave-rollover.md`
|
||||
Documents complementaires:
|
||||
- `doc/leave-rollover.md` (rollover conges et checklist de lancement)
|
||||
- `doc/rtt-rollover.md` (rollover RTT et checklist de lancement)
|
||||
|
||||
## 1) Utilisateurs et accès
|
||||
|
||||
@@ -196,6 +197,31 @@ Tous les filtres checkbox sont cochés par défaut à l'ouverture du drawer.
|
||||
- les compteurs sont calculés jusqu'au dernier jour du mois précédent (le mois en cours est exclu)
|
||||
- exemple: au `04/03/2026`, l'arret de calcul est le `28/02/2026` (ou `29/02` en année bissextile)
|
||||
- hors périmètre phase 1: `INTERIM` (retour non supporté)
|
||||
- onglet `RTT`:
|
||||
- endpoint de synthèse: `GET /api/employees/{id}/rtt-summary?year=YYYY`
|
||||
- exercice RTT: du `1er juin (YYYY-1)` au `31 mai (YYYY)` (paramètre `year` = année de fin d'exercice)
|
||||
- affichage:
|
||||
- détail hebdomadaire (semaine ISO) regroupé par mois
|
||||
- total mensuel des minutes de récupération
|
||||
- compteur global exercice = `report N-1 + acquis N`
|
||||
- attribution mensuelle des semaines:
|
||||
- une semaine ISO est affichée une seule fois, dans le mois qui contient le **samedi** de cette semaine
|
||||
- si le weekend tombe en début de mois suivant, c'est le mois suivant qui porte la semaine
|
||||
- logique de calcul:
|
||||
- base identique aux calculs d'heures supplémentaires de la vue semaine Heures
|
||||
- minutes de récupération hebdomadaires = `HS totales + bonus 25% + bonus 50%`
|
||||
- contrats `INTERIM` et suivi `PRESENCE`: récupération à `0`
|
||||
- compteur global:
|
||||
- affiché en **jours** (1 jour = 7h = 420 minutes)
|
||||
- report:
|
||||
- le report N-1 correspond à la somme des minutes de récupération calculées sur l'exercice précédent
|
||||
- si une ligne existe dans `employee_rtt_balances` pour `(employee, year)`, le champ `opening_minutes` est utilisé en priorité
|
||||
- sinon, le calcul dynamique sur l'exercice N-1 est effectué
|
||||
- rollover automatique:
|
||||
- commande: `php bin/console app:rtt:rollover`
|
||||
- s'exécute le `1er juin` (même cron que le rollover congés)
|
||||
- calcule le total récup N-1 et le persiste en `opening_minutes` du nouvel exercice
|
||||
- idempotent (ne recrée pas si la ligne existe)
|
||||
|
||||
## 10) Notifications
|
||||
|
||||
|
||||
163
doc/rtt-rollover.md
Normal file
163
doc/rtt-rollover.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# 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 est affichee une seule fois, dans le mois qui contient le **samedi** de cette semaine
|
||||
- si le weekend tombe en debut du mois suivant, c'est ce mois qui porte la semaine
|
||||
- pas de prorata: la totalite des minutes de recuperation de la semaine est comptee dans un seul mois
|
||||
|
||||
## 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 >> var/log/rtt-rollover.log 2>&1
|
||||
```
|
||||
Prod
|
||||
```cron
|
||||
15 2 * * * cd /var/www/sirh && php bin/console app:rtt:rollover --no-interaction >> var/log/rtt-rollover.log 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)
|
||||
Reference in New Issue
Block a user