From 4d90f2cb42f62ee5bab78080e05873d15ed605aa Mon Sep 17 00:00:00 2001 From: tristan Date: Thu, 26 Feb 2026 17:15:13 +0100 Subject: [PATCH] =?UTF-8?q?feat=20:=20ajout=20du=20nouveau=20syst=C3=A8me?= =?UTF-8?q?=20de=20contrat=20et=20ajout=20de=20filtre=20d'impression?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 134 +++++++----- frontend/components/AbsencePrintDrawer.vue | 81 ++++++- frontend/components/hours/HoursDayView.vue | 14 +- frontend/composables/useHoursPage.ts | 7 + frontend/pages/calendar.vue | 30 ++- frontend/pages/employees.vue | 197 +++++++++++++++--- frontend/pages/hours.vue | 2 + frontend/services/dto/employee.ts | 3 + frontend/services/dto/work-hour.ts | 1 + frontend/services/employees.ts | 14 +- migrations/Version20260226203000.php | 33 +++ migrations/Version20260226210000.php | 82 ++++++++ src/ApiResource/AbsencePrint.php | 2 + src/ApiResource/WorkHourDayContext.php | 1 + src/Dto/WorkHours/DayContextRow.php | 12 ++ src/Entity/Employee.php | 98 ++++++++- src/Entity/EmployeeContractPeriod.php | 24 ++- src/Enum/ContractNature.php | 17 ++ src/Repository/EmployeeRepository.php | 2 + .../Contracts/EmployeeContractResolver.php | 55 +++++ src/State/AbsencePrintProvider.php | 41 +++- src/State/EmployeeWriteProcessor.php | 99 +++++++-- src/State/WorkHourDayContextProvider.php | 1 + src/State/WorkHourWeeklySummaryProvider.php | 17 +- 24 files changed, 853 insertions(+), 114 deletions(-) create mode 100644 migrations/Version20260226203000.php create mode 100644 migrations/Version20260226210000.php create mode 100644 src/Enum/ContractNature.php diff --git a/AGENTS.md b/AGENTS.md index b277fe9..02f1a16 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # AGENTS.md -État des lieux opérationnel du projet SIRH (backend + frontend), à utiliser comme base sur les prochaines interventions. +État des lieux opérationnel du projet SIRH (backend + frontend), mis à jour après les évolutions sur heures/absences/validations. ## 1) Stack et structure @@ -25,81 +25,107 @@ Arborescence clé: ### Contrats - Entité: `Contract` -- Champs principaux: `name`, `trackingMode`, `weeklyHours`, `isActive` +- Champs principaux: `name`, `trackingMode`, `weeklyHours`, `isActive`, `type` - `trackingMode`: - - `TIME`: suivi par heures - - `PRESENCE`: suivi présence demi-journées/journées + - `TIME`: suivi en heures + - `PRESENCE`: suivi en demi-journées/journées - Enums backend: - `App\Enum\TrackingMode` - - `App\Enum\ContractType` (`FORFAIT`, `35H`, `39H`, `INTERIM`, `CUSTOM`) -- `Contract::getType()` est exposé en API (`contract:read`, `employee:read`) + - `App\Enum\ContractType` (`FORFAIT`, `THIRTY_FIVE_HOURS`, `THIRTY_NINE_HOURS`, `INTERIM`, `CUSTOM`) +- Historique de contrat par employé: + - table `employee_contract_periods` + - résolu par `App\Service\Contracts\EmployeeContractResolver` ### Heures / absences -- Les absences sont découpées en enregistrements journaliers (pas de période unique stockée). -- Une ligne d’heures validée est verrouillée côté métier. -- Règles de crédit absence (`countAsWorkedHours=true`) gérées dans `WorkedHoursCreditPolicy`: - - contrats présence: crédit en unités de présence - - contrats temps: crédit en minutes selon règles contrat (35h, 39h, 4h, fallback) +- Les absences sont stockées en **lignes journalières** (découpage automatique dans `AbsenceWriteProcessor`). +- Les absences `countAsWorkedHours=true` créditent: + - minutes (contrats TIME) + - unités de présence (contrats PRESENCE) +- Les absences AM/PM effacent les plages horaires concernées. -## 4) Écrans principaux +## 4) Validations (important) -### Page Heures (`frontend/pages/hours.vue`) -- Vue Jour + Vue Semaine (semaine réservée admin) -- Toolbar dédiée: `frontend/components/hours/HoursToolbar.vue` -- Vue jour: `frontend/components/hours/HoursDayView.vue` -- Vue semaine: `frontend/components/hours/HoursWeekView.vue` -- Logique page: `frontend/composables/useHoursPage.ts` +### Validation RH (admin) +- Champ: `work_hours.is_valid` +- Endpoint API Platform standard: `PATCH /api/work_hours/{id}` +- Gérée côté front par `updateWorkHourValidation`. -### Points UX déjà en place -- Toolbar semaine: raccourcis semaine précédente / actuelle / suivante -- Légende absences affichée dans la toolbar (admin + vue semaine) -- Cellules semaine avec absence: couleur du type d’absence (plus rouge fixe) -- Pour user non-admin: restrictions d’édition selon validations/absences +### Validation site (chef de site) +- Champ: `work_hours.is_site_valid` +- Endpoint dédié: `PATCH /api/work_hours/{id}/site-validation` +- Processor: `src/State/WorkHourSiteValidationProcessor.php` +- Autorisé uniquement aux utilisateurs "Sites" (ni `ROLE_ADMIN`, ni `ROLE_SELF`) dans leur scope site. -## 5) API / calculs hebdo +### Règles de verrouillage +- `is_valid=true`: ligne verrouillée pour tout le monde (admin inclus pour saisie heures/absence; peut toujours décocher validation RH). +- `is_site_valid=true`: + - non-admin: ligne verrouillée (heures + absences) + - admin: ligne éditable +- Toute modification de ligne (heures/présence/absence) remet: + - `is_site_valid=false` + - `is_valid=false` + +## 5) Page Heures (front) + +- Page: `frontend/pages/hours.vue` +- Composable principal: `frontend/composables/useHoursPage.ts` +- Composants: + - `frontend/components/hours/HoursToolbar.vue` + - `frontend/components/hours/HoursDayView.vue` + - `frontend/components/hours/HoursWeekView.vue` + +### Comportement par profil (vue jour) +- Admin: + - colonne RH avec checkbox + - badge `Site validé` affiché près du site +- Chef de site: + - colonne `Validation site` avec checkbox + - colonne RH en lecture (`Validé`/`-`) +- Employé: + - colonne `Validation site` en lecture + - colonne RH en lecture + +## 6) Résumé hebdo / calculs - Provider: `src/State/WorkHourWeeklySummaryProvider.php` - DTOs: - `src/Dto/WorkHours/WeeklySummaryRow.php` - `src/Dto/WorkHours/WeeklyDaySummary.php` -- Le résumé hebdo renvoie notamment: - - `trackingMode` - - `contractName` - - `contractType` - - détails journaliers (jour/nuit/total, présence, absence label/couleur) +- Inclut: contrat résolu par jour, absences, crédits, jour/nuit/total, majorations, récup. -### Heures supp -- Règles métier: - - contrats <= 35h: tranche 25% de 35h à 43h, puis 50% au-delà - - contrats >= 39h: tranche 25% de 39h à 43h, puis 50% au-delà - - contrats `INTERIM`: pas de bonus 25/50 ni récup +Règles majorations: +- Contrats <= 35h: +25% de 35h à 43h, +50% au-delà +- Contrats >= 39h: +25% de 39h à 43h, +50% au-delà +- `INTERIM`: pas de 25% / 50% / récup -## 6) Conventions techniques +## 7) Migrations sensibles -- Favoriser DTO explicites plutôt que tableaux associatifs bruts. -- Utiliser les interfaces repository dans providers/processors testés. -- Centraliser les règles métier dans services/providers backend plutôt que dupliquer côté front. -- Front: éviter les calculs métier lourds; consommer les champs API déjà calculés. +- `migrations/Version20260226183000.php` + - ajoute `work_hours.is_site_valid BOOLEAN NOT NULL DEFAULT FALSE` + - non destructive (pas de perte de données) -## 7) Tests et qualité +## 8) Points de vigilance prod -- Les TU backend passent actuellement via `make test`. -- Le build frontend passe via `npm run build`. -- À chaque évolution métier: - - mettre à jour les tests provider/processor/service impactés - - maintenir la cohérence des DTO TypeScript (`frontend/services/dto/*`) +- Toujours exécuter migration avant déploiement code backend/front lié. +- Après déploiement backend, si route manquante côté runtime: + - `php bin/console cache:clear && php bin/console cache:warmup` +- Vérifier présence route: + - `/api/work_hours/{id}/site-validation` (PATCH) -## 8) Fichiers sensibles (à lire avant modif) +## 9) Conventions techniques +- Favoriser DTO explicites plutôt que tableaux associatifs. +- Garder règles métier dans backend (providers/processors/services), front orienté affichage/interaction. +- Maintenir alignement backend DTO PHP / frontend DTO TS (`frontend/services/dto/*`). +- Mettre à jour TU si signature constructor/service change. + +## 10) Fichiers à lire avant modification + +- `src/State/WorkHourBulkUpsertProcessor.php` +- `src/State/AbsenceWriteProcessor.php` +- `src/State/WorkHourSiteValidationProcessor.php` - `src/State/WorkHourWeeklySummaryProvider.php` - `src/Service/WorkHours/WorkedHoursCreditPolicy.php` -- `src/State/AbsenceWriteProcessor.php` -- `src/State/WorkHourBulkUpsertProcessor.php` - `frontend/composables/useHoursPage.ts` +- `frontend/components/hours/HoursDayView.vue` - `frontend/components/hours/HoursWeekView.vue` - -## 9) Décisions de conception actuelles - -- Les absences sont stockées par jour (facilite verrouillage/édition fine). -- Les règles de calcul (crédits, majorations, récup) sont portées côté backend. -- Le front reste centré sur l’affichage/interaction et réutilise les données enrichies de l’API. diff --git a/frontend/components/AbsencePrintDrawer.vue b/frontend/components/AbsencePrintDrawer.vue index c4729dd..0685439 100644 --- a/frontend/components/AbsencePrintDrawer.vue +++ b/frontend/components/AbsencePrintDrawer.vue @@ -54,6 +54,48 @@

+
+

+ Type de contrat * +

+
+
+ + +
+
+

+ Sélectionne au moins un type de contrat. +

+
+ +
+

+ Temps de travail * +

+
+
+ + +
+
+

+ Sélectionne au moins un temps de travail. +

+
+
-
-

+

+ :style="getRowAbsenceStyle(employee.id)" + > {{ getRowAbsenceLabel(employee.id) || '—' }} -

+

@@ -32,10 +32,11 @@
-
+
Prénom Nom Site + Nature Contrat Actions
@@ -46,7 +47,7 @@
{{ employee.firstName }} {{ employee.lastName }} @@ -57,6 +58,7 @@ > {{ employee.site?.name ?? '-' }} + {{ contractNatureLabel(employee.currentContractNature) }} {{ employee.contract?.name ?? '-' }}
-
- - -

- Le contrat est obligatoire. -

-
+