diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 8eaa2eb..148322c 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -22,7 +22,8 @@
"Bash(which python3:*)",
"Bash(sudo apt-get:*)",
"Bash(npx xlsx-cli:*)",
- "Bash(cat /home/m-tristan/.claude/projects/-home-m-tristan-workspace-SIRH/4b53d9d7-d8ae-451f-a5cc-5d4fd55f2eef/tool-results/toolu_019hng9Cu2m9wiNACuC2Wm3F.json | python3 -c \"import json,sys; data=json.load\\(sys.stdin\\); print\\(data[0]['text']\\)\" 2>/dev/null | head -2000)"
+ "Bash(cat /home/m-tristan/.claude/projects/-home-m-tristan-workspace-SIRH/4b53d9d7-d8ae-451f-a5cc-5d4fd55f2eef/tool-results/toolu_019hng9Cu2m9wiNACuC2Wm3F.json | python3 -c \"import json,sys; data=json.load\\(sys.stdin\\); print\\(data[0]['text']\\)\" 2>/dev/null | head -2000)",
+ "Bash(pip3 install:*)"
]
}
}
diff --git a/doc/functional-rules.md b/doc/functional-rules.md
index b41f978..aded520 100644
--- a/doc/functional-rules.md
+++ b/doc/functional-rules.md
@@ -270,7 +270,34 @@ Tous les filtres checkbox sont cochés par défaut à l'ouverture du drawer.
- affichage:
- le compteur global RTT est affiché en **heures** (format `Xh00`)
-## 10) Notifications
+## 10) Récapitulatif Salaire (PDF mensuel)
+
+- Accessible depuis la page Employés via le bouton "Récap. Salaire" (réservé `ROLE_ADMIN`)
+- Sélecteur de mois (défaut = mois courant), génère un PDF A3 paysage
+- Endpoint: `GET /api/salary-recap/print?month=YYYY-MM`
+- Données groupées par site, un en-tête par site
+
+### Colonnes du tableau
+
+| Colonne | Source | Logique |
+|---------|--------|---------|
+| Nom | Employee | firstName + lastName |
+| Base | Contract.name | Via EmployeeContractResolver pour le mois |
+| Jour de présence Cadre | WorkHour | Uniquement FORFAIT (PRESENCE). Somme isPresentMorning (0.5) + isPresentAfternoon (0.5) |
+| Heures de nuit | WorkHour | Non-chauffeurs: calcul intervalles nuit (00:00-06:00, 21:00-24:00). Chauffeurs: somme nightHoursMinutes |
+| Panier de nuit | WorkHour | Nombre de jours où nightMinutes > dayMinutes |
+| Heures payés | EmployeeRttPayment | Somme base25Minutes + base50Minutes du mois, convertie en heures |
+| Congés - Nombre | Absence code 'C' | Jours (demi-journées = 0.5) |
+| Congés - Date | Absence code 'C' | Dates formatées dd/mm |
+| Maladie - Nombre | Absence code 'M' ou 'AT' | Jours (demi-journées = 0.5) |
+| Maladie - Date | Absence code 'M' ou 'AT' | Dates formatées dd/mm |
+| CHAUFFEUR - PDJ | WorkHour.hasBreakfast | Comptage mois (chauffeurs uniquement) |
+| CHAUFFEUR - REPAS | WorkHour.hasLunch + hasDinner | Comptage mois (chauffeurs uniquement) |
+| CHAUFFEUR - NUITEE | WorkHour.hasOvernight | Comptage mois (chauffeurs uniquement) |
+| CHAUFFEUR - samedi | WorkHour (samedi) | Samedis travaillés (chauffeurs uniquement) |
+| Observations | — | Colonne vide pour saisie manuelle |
+
+## 11) Notifications
- Icône cloche en topbar:
- badge = nombre de notifications non lues
diff --git a/frontend/components/SalaryRecapDrawer.vue b/frontend/components/SalaryRecapDrawer.vue
new file mode 100644
index 0000000..0f01b68
--- /dev/null
+++ b/frontend/components/SalaryRecapDrawer.vue
@@ -0,0 +1,87 @@
+
+
| Nom | +Base | +Jour de présence Cadre |
+ Frais Kms |
+ Heures de nuit |
+ Panier de nuit |
+ Heures payés |
+ Heures dim. |
+ Prime | +Congés | +Maladie | +CHAUFFEUR | +Observations | +|||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Nbre | +Date | +Nbre | +Date | +PDJ | +REPAS | +NUITEE | +samedi | +||||||||||
| + {{ group.name }} + | +|||||||||||||||||
| {{ row.lastName }} {{ row.firstName }} |
+ {{ row.contractName ?? '' }} | +{{ row.presenceDays > 0 ? row.presenceDays : '' }} | +{{ row.mileageKm > 0 ? row.mileageKm : '' }} | +{{ row.nightHours > 0 ? row.nightHours : '' }} | +{{ row.nightBasketCount > 0 ? row.nightBasketCount : '' }} | +{{ row.paidHours > 0 ? row.paidHours : '' }} | +{{ row.sundayHours > 0 ? row.sundayHours : '' }} | +{{ row.bonusAmount > 0 ? row.bonusAmount : '' }} | +{{ row.congesCount > 0 ? row.congesCount : '' }} | +{{ row.congesDates }} | +{{ row.maladieCount > 0 ? row.maladieCount : '' }} | +{{ row.maladieDates }} | +{{ row.isDriver and row.driverBreakfast > 0 ? row.driverBreakfast : '' }} | +{{ row.isDriver and row.driverMeals > 0 ? row.driverMeals : '' }} | +{{ row.isDriver and row.driverOvernight > 0 ? row.driverOvernight : '' }} | +{{ row.isDriver and row.driverSaturdays > 0 ? row.driverSaturdays : '' }} | ++ |
| Aucun employé. | +|||||||||||||||||