From 4cd30de3e38e4ae1ce57844c0d9967fead711826 Mon Sep 17 00:00:00 2001 From: tristan Date: Mon, 13 Apr 2026 09:41:36 +0200 Subject: [PATCH] feat : ajout d'un onglet formation --- CLAUDE.md | 11 + config/services.yaml | 1 + doc/formations.md | 58 ++++ frontend/components/CalendarGrid.vue | 13 +- .../components/employees/FormationTab.vue | 251 ++++++++++++++++++ frontend/components/hours/HoursDayView.vue | 29 +- frontend/composables/useEmployeeDetailPage.ts | 9 +- frontend/composables/useEmployeeFormation.ts | 73 +++++ frontend/composables/useHoursPage.ts | 10 + frontend/data/documentation-content.ts | 11 + frontend/i18n/locales/fr.json | 10 + frontend/pages/calendar.vue | 64 ++++- frontend/pages/employees/[id].vue | 30 +++ frontend/pages/hours.vue | 4 + frontend/services/dto/formation.ts | 12 + frontend/services/dto/work-hour.ts | 2 + frontend/services/formations.ts | 82 ++++++ migrations/Version20260413120000.php | 29 ++ src/Dto/WorkHours/DayContextRow.php | 15 +- src/Entity/Formation.php | 192 ++++++++++++++ .../FormationReadRepositoryInterface.php | 26 ++ src/Repository/FormationRepository.php | 74 ++++++ src/State/AbsencePrintProvider.php | 59 +++- src/State/FormationDeleteProcessor.php | 42 +++ .../FormationJustificatifDownloadProvider.php | 53 ++++ .../FormationJustificatifUploadProcessor.php | 75 ++++++ src/State/WorkHourDayContextProvider.php | 17 +- templates/absence/print.html.twig | 13 +- .../State/WorkHourDayContextProviderTest.php | 15 +- 29 files changed, 1244 insertions(+), 36 deletions(-) create mode 100644 doc/formations.md create mode 100644 frontend/components/employees/FormationTab.vue create mode 100644 frontend/composables/useEmployeeFormation.ts create mode 100644 frontend/services/dto/formation.ts create mode 100644 frontend/services/formations.ts create mode 100644 migrations/Version20260413120000.php create mode 100644 src/Entity/Formation.php create mode 100644 src/Repository/Contract/FormationReadRepositoryInterface.php create mode 100644 src/Repository/FormationRepository.php create mode 100644 src/State/FormationDeleteProcessor.php create mode 100644 src/State/FormationJustificatifDownloadProvider.php create mode 100644 src/State/FormationJustificatifUploadProcessor.php diff --git a/CLAUDE.md b/CLAUDE.md index 79edb61..90a8cef 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -54,6 +54,17 @@ - Validation: mois obligatoire + au moins `kilometers > 0` ou `amount > 0` - Les deux champs km et montant sont optionnels individuellement mais au moins un requis +## Formations +- Onglet "Formation" sur la fiche employé (admin uniquement) +- Champs : date début, date fin, justificatif PDF optionnel, commentaire +- Validation: dates obligatoires, `endDate >= startDate`, fichier PDF uniquement +- Justificatif stocké dans `var/uploads/formations/{année}/{mois}/{uuid}.pdf` (année/mois = startDate) +- Suppression et remplacement du justificatif nettoient l'ancien fichier disque +- Tri tableau par `startDate DESC` +- Affichage écran Heures (jour) : pill "Formation" (indigo) dans la colonne Absence. Quand une formation existe, le bouton "Modifier" de la colonne Absence est masqué (lockdown complet du jour pour la gestion d'absence) +- Affichage Calendrier : cellule "F" (indigo) si formation seule, ou icône école en coin si formation + absence. Cellules avec formation non cliquables. Légende dédiée. PDF export : code "F" indigo ou astérisque à côté du code d'absence +- Le CRUD formation est exclusivement géré depuis la fiche employé > onglet Formation + ## Frontend Patterns ### Table styling (standard across all pages) diff --git a/config/services.yaml b/config/services.yaml index ad87606..511f83d 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -37,6 +37,7 @@ services: App\Repository\Contract\AbsenceReadRepositoryInterface: '@App\Repository\AbsenceRepository' App\Repository\Contract\EmployeeContractPeriodReadRepositoryInterface: '@App\Repository\EmployeeContractPeriodRepository' App\Repository\Contract\EmployeeScopedRepositoryInterface: '@App\Repository\EmployeeRepository' + App\Repository\Contract\FormationReadRepositoryInterface: '@App\Repository\FormationRepository' App\Repository\Contract\WorkHourReadRepositoryInterface: '@App\Repository\WorkHourRepository' App\Service\Contracts\EmployeeContractPeriodManagerInterface: '@App\Service\Contracts\EmployeeContractPeriodManager' diff --git a/doc/formations.md b/doc/formations.md new file mode 100644 index 0000000..7cb8579 --- /dev/null +++ b/doc/formations.md @@ -0,0 +1,58 @@ +# Formations + +Onglet **Formation** accessible depuis la fiche employé. Permet de tracer les formations suivies par un salarié. + +## Accès + +- Réservé aux administrateurs (`ROLE_ADMIN`) +- Invisible pour les autres rôles + +## Champs + +| Champ | Type | Obligatoire | +| --- | --- | --- | +| Date de début | date | oui | +| Date de fin | date | oui | +| Justificatif | fichier PDF | non | +| Commentaire | texte libre | non | + +## Règles de validation + +- La date de fin doit être supérieure ou égale à la date de début +- Seuls les fichiers PDF sont acceptés pour le justificatif +- Un employé peut avoir plusieurs formations (aucune unicité imposée) + +## Stockage + +Les justificatifs PDF sont stockés dans `var/uploads/formations/{année}/{mois}/{uuid}.pdf`, où l'année et le mois sont ceux de la date de début de la formation. Le nom d'origine du fichier est conservé en base pour l'affichage et le téléchargement. + +Lors de la suppression d'une formation, le fichier associé est automatiquement supprimé du disque. Lors du remplacement d'un justificatif, l'ancien fichier est également supprimé. + +## Tri + +Les formations sont affichées dans le tableau par **date de début décroissante**. + +## Affichage sur les autres écrans + +### Écran des heures (vue jour) + +Dans la colonne "Absence", lorsqu'un salarié est en formation sur la date sélectionnée, une pastille indigo **Formation** est affichée sous la pastille d'absence éventuelle. Cette pastille est uniquement informative : + +- Le bouton **Modifier** de la colonne Absence est masqué : aucune création/modification/suppression d'absence n'est possible sur un jour en formation +- La gestion CRUD d'une formation se fait exclusivement depuis la fiche employé, onglet **Formation** + +### Calendrier + +Dans le calendrier mensuel, les formations sont affichées de deux façons : + +- **Jour avec formation uniquement** : la cellule est teintée en indigo avec le code `F` +- **Jour avec absence + formation** : la cellule garde la couleur de l'absence et une icône école est ajoutée en coin supérieur droit + +Une entrée "Formation" est visible dans la légende du calendrier. Les cellules contenant une formation sont **non cliquables** (aucune création/édition d'absence possible). La gestion d'une formation se fait exclusivement depuis la fiche employé, onglet **Formation**. + +### Export PDF du calendrier + +L'impression du calendrier d'absences reprend le même principe : + +- **Jour avec formation uniquement** : cellule indigo avec le code `F` +- **Jour avec absence + formation** : le code de l'absence est suivi d'un astérisque (`*`) diff --git a/frontend/components/CalendarGrid.vue b/frontend/components/CalendarGrid.vue index fbd734f..5402ffd 100644 --- a/frontend/components/CalendarGrid.vue +++ b/frontend/components/CalendarGrid.vue @@ -45,9 +45,9 @@