# En-cours d'acquisition « net / brut » — Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Sur l'onglet Congés de la fiche employé, afficher l'en-cours d'acquisition au format `{net} / {brut généré à ce jour}` pour les non-forfait, afin que la RH voie le total acquis même quand des congés ont été pris en anticipé. **Architecture :** Exposition d'une valeur **déjà calculée** côté backend (`generatedDays + generatedSaturdays`) via un nouveau champ `accruingDaysTotal` sur `EmployeeLeaveSummary`, puis affichage en fraction côté Nuxt. Aucune nouvelle règle métier ; `accruingDays` (net) reste le numérateur inchangé. **Tech Stack :** Backend Symfony / API Platform (State Provider + ApiResource DTO). Frontend Nuxt 4 / Vue 3 / TypeScript. Tests : PHPUnit (backend) ; pas de harnais frontend → vérification manuelle. **Référence spec :** `docs/superpowers/specs/2026-05-26-en-cours-acquisition-net-brut-design.md` --- ## File Structure - `src/State/EmployeeLeaveSummaryProvider.php` — calcule `accruingDaysTotal` dans `computeYearSummary` et le recopie sur le DTO. - `src/ApiResource/EmployeeLeaveSummary.php` — nouvelle propriété exposée `accruingDaysTotal`. - `frontend/services/dto/employee-leave-summary.ts` — champ TS `accruingDaysTotal`. - `frontend/components/employees/LeaveTab.vue` — affichage `net / brut` (non-forfait). - `doc/leave-tab.md` + `frontend/data/documentation-content.ts` — documentation. Aucun fichier créé ; 6 fichiers modifiés. --- ### Task 1 : Backend — exposer `accruingDaysTotal` **Files:** - Modify: `src/State/EmployeeLeaveSummaryProvider.php` - Modify: `src/ApiResource/EmployeeLeaveSummary.php` - [ ] **Step 1 : Calculer `accruingDaysTotal` dans les deux branches de `computeYearSummary`** Dans `src/State/EmployeeLeaveSummaryProvider.php`, branche non-forfait, remplacer : ```php $acquiredDays = $carryDays; $accruingDays = $remainingGenerated + $remainingGeneratedSaturdays; ``` par : ```php $acquiredDays = $carryDays; $accruingDays = $remainingGenerated + $remainingGeneratedSaturdays; // Brut généré à ce jour, AVANT imputation des congés pris en anticipé // (dénominateur de l'affichage « net / brut » sur l'onglet Congés). $accruingDaysTotal = $generatedDays + $generatedSaturdays; ``` Puis, branche forfait, remplacer : ```php $acquiredDays = $leavePolicy['acquiredDays']; $accruingDays = 0.0; ``` par : ```php $acquiredDays = $leavePolicy['acquiredDays']; $accruingDays = 0.0; $accruingDaysTotal = 0.0; ``` - [ ] **Step 2 : Ajouter la clé au tableau `targetSummary`** Toujours dans `computeYearSummary`, remplacer : ```php 'accruingDays' => $accruingDays, ``` par : ```php 'accruingDays' => $accruingDays, 'accruingDaysTotal' => $accruingDaysTotal, ``` - [ ] **Step 3 : Déclarer la clé dans le PHPDoc de retour** Dans le bloc `@return null|array{ ... }` de `computeYearSummary`, remplacer : ```php * accruingDays: float, ``` par : ```php * accruingDays: float, * accruingDaysTotal: float, ``` - [ ] **Step 4 : Recopier la valeur sur le DTO dans `provide()`** Remplacer : ```php $summary->accruingDays = $yearSummary['accruingDays']; ``` par : ```php $summary->accruingDays = $yearSummary['accruingDays']; $summary->accruingDaysTotal = $yearSummary['accruingDaysTotal']; ``` - [ ] **Step 5 : Ajouter la propriété sur l'ApiResource** Dans `src/ApiResource/EmployeeLeaveSummary.php`, remplacer : ```php public float $accruingDays = 0.0; ``` par : ```php public float $accruingDays = 0.0; /** Brut généré sur l'exercice à ce jour (= accruingDays + congés pris en anticipé). Dénominateur de l'affichage « net / brut ». */ public float $accruingDaysTotal = 0.0; ``` - [ ] **Step 6 : Lancer la suite PHPUnit (non-régression)** Run: `docker exec -t -u www-data php-sirh-fpm php vendor/bin/phpunit` Expected: `OK (151 tests, ...)` — vert. (Le champ est une exposition pure ; aucun test existant ne doit casser. Le service n'est pas unit-testable en isolation à cause des dépôts `final`, cf. note spec.) - [ ] **Step 7 : Vérification sur données réelles (jetable, non commitée)** Créer `src/Command/TmpVerifyAccruingCommand.php` : ```php em->getRepository(Employee::class)->findAll() as $e) { $s = $m->invoke($this->provider, $e, 2026, 0.0, null, null); if (null === $s || 'CDI_CDD_NON_FORFAIT' !== $s['ruleCode']) { continue; } $output->writeln(sprintf( '#%d %s : en-cours net=%.2f / brut=%.2f', $e->getId(), $e->getLastName(), $s['accruingDays'], $s['accruingDaysTotal'], )); } return Command::SUCCESS; } } ``` Run: `docker exec -t php-sirh-fpm php /var/www/html/bin/console app:tmp-verify-accruing --env=dev` Expected: chaque ligne affiche `net=… / brut=…` avec `net ≤ brut`. Pour un salarié sans congé anticipé, `net == brut` ; pour un salarié ayant débordé, `net < brut`. Puis supprimer le fichier : ```bash rm src/Command/TmpVerifyAccruingCommand.php ``` - [ ] **Step 8 : Commit** ```bash git add src/State/EmployeeLeaveSummaryProvider.php src/ApiResource/EmployeeLeaveSummary.php git commit -m "feat : exposer accruingDaysTotal (brut généré) sur le récap congés Co-Authored-By: Claude Opus 4.7 (1M context) " ``` --- ### Task 2 : Frontend — afficher « net / brut » **Files:** - Modify: `frontend/services/dto/employee-leave-summary.ts` - Modify: `frontend/components/employees/LeaveTab.vue` - [ ] **Step 1 : Ajouter le champ au DTO TypeScript** Dans `frontend/services/dto/employee-leave-summary.ts`, remplacer : ```ts accruingDays: number ``` par : ```ts accruingDays: number accruingDaysTotal: number ``` - [ ] **Step 2 : Afficher la fraction dans la case « En cours d'acquisition »** Dans `frontend/components/employees/LeaveTab.vue`, remplacer : ```vue

En cours d'acquisition : {{ formatCount(summary?.accruingDays) }} Jours

``` par : ```vue

En cours d'acquisition :

``` - [ ] **Step 3 : Vérification manuelle (dev server)** Run: `make dev-nuxt` puis ouvrir la fiche d'un employé **non-forfait**. Attendu : - La case « En cours d'acquisition » affiche deux nombres séparés par `/` (ex. `14,50 / 17,50` ou `17,50 / 17,50` si aucun congé anticipé). - Sur un employé **forfait**, la case affiche un seul nombre (`0`), inchangé. (Ne pas lancer `npm run build`.) - [ ] **Step 4 : Commit** ```bash git add frontend/services/dto/employee-leave-summary.ts frontend/components/employees/LeaveTab.vue git commit -m "feat : afficher l'en-cours d'acquisition au format net / brut (onglet Congés) Co-Authored-By: Claude Opus 4.7 (1M context) " ``` --- ### Task 3 : Documentation **Files:** - Modify: `doc/leave-tab.md` - Modify: `frontend/data/documentation-content.ts` - [ ] **Step 1 : `doc/leave-tab.md`** Repérer la section décrivant les compteurs du header (recherche : `grep -n "acquisition\|En cours\|compteur" doc/leave-tab.md`). Ajouter (ou compléter la puce correspondante) avec ce texte : ```markdown - **En cours d'acquisition** (non-forfait) : affiché au format `net / brut`. - `net` (`accruingDays`) : généré de l'exercice restant, déduit des congés posés en anticipé (au-delà du report acquis). - `brut` (`accruingDaysTotal` = `generatedDays + generatedSaturdays`) : total généré sur l'exercice à ce jour, avant cette déduction. - La RH voit ainsi le total réellement acquis même si une partie a déjà été consommée en anticipé. Forfait : pas d'en-cours (affiche `0`, sans fraction). ``` - [ ] **Step 2 : `frontend/data/documentation-content.ts`** Repérer le paragraphe de l'article « Onglet Congés » décrivant les compteurs (recherche : `grep -n "en cours d.acquisition\|En cours\|acquis" frontend/data/documentation-content.ts`). Ajouter un bloc `note` dans le tableau `blocks` de cet article : ```ts { type: 'note', content: 'La case « En cours d\'acquisition » affiche deux valeurs : à gauche les jours encore à acquérir (déduction faite des congés déjà posés en anticipé), à droite le total brut acquis sur l\'exercice à ce jour. Exemple : « 14,50 / 17,50 » signifie 17,50 jours acquis dont 3 déjà pris en anticipé.' }, ``` > Insérer ce bloc juste après le paragraphe qui présente les compteurs de l'exercice de congés (celui mentionnant l'exercice Juin→Mai / les jours acquis). Respecter l'indentation existante (10 espaces) et l'échappement des apostrophes (`\'`). - [ ] **Step 3 : Vérifier la cohérence** Run: `grep -rn "accruingDaysTotal\|net / brut\|14,50 / 17,50" doc/leave-tab.md frontend/data/documentation-content.ts` Expected : la doc fonctionnelle mentionne le format `net / brut` et la doc in-app contient la note d'exemple. - [ ] **Step 4 : Commit** ```bash git add doc/leave-tab.md frontend/data/documentation-content.ts git commit -m "docs : en-cours d'acquisition affiché net / brut sur l'onglet Congés Co-Authored-By: Claude Opus 4.7 (1M context) " ``` --- ## Self-Review **1. Couverture de la spec :** - Nouveau champ `accruingDaysTotal` = `generatedDays + generatedSaturdays` (non-forfait), `0` (forfait) → Task 1 Steps 1-2. ✓ - Exposition DTO PHP + recopie provider → Task 1 Steps 3-5. ✓ - DTO TS → Task 2 Step 1. ✓ - Affichage `net / brut` non-forfait, inchangé forfait → Task 2 Step 2. ✓ - Docs `doc/leave-tab.md` + in-app → Task 3. ✓ - Invariant `accruingDays ≤ accruingDaysTotal` → vérifié en Task 1 Step 7. ✓ - Hors périmètre (RTT, récap, header) → aucun fichier de ces zones touché. ✓ **2. Placeholders :** aucun « TBD/TODO » ; tout le code est fourni. Les Steps 1-2 de Task 3 demandent un `grep` pour localiser l'ancre exacte (le texte à insérer est fourni intégralement) car la position dans `documentation-content.ts` dépend de l'article ; c'est une instruction d'insertion, pas un placeholder de contenu. **3. Cohérence des types/noms :** `accruingDaysTotal` (float PHP / number TS) utilisé identiquement dans le provider, le tableau `targetSummary`, le PHPDoc, l'ApiResource, le DTO TS et le template. `accruingDays` (numérateur) reste inchangé. La variable `$accruingDaysTotal` est définie dans les deux branches avant la construction de `targetSummary` (comme `$accruingDays`).