Deux lots regroupés sur la branche feat/absence-management. Suppression complète du portail client : - retire ROLE_CLIENT (security.yaml) ; User::getRoles() ajoute toujours ROLE_USER - supprime l'entité ClientTicket (+ repo, states, relations), User.client et User.allowedProjects, NotificationService, ProjectAllowedExtension, le bloc ROLE_CLIENT de MailAccessChecker - front : pages /portal, layout portal, composants client-ticket/, AdminClientTicketTab, services/dto/i18n/docs associés - fixtures : retire les users client-liot / client-acme - migration Version20260522110000 (drop client_ticket, user_allowed_projects, colonnes liées ; task_document.task_id -> NOT NULL) - tests : retire les cas obsolètes testant le blocage des clients sur le mail Module gestion des absences (WIP) : - entités / migrations (Version20260521160000, Version20260522090000) - pages absences.vue / team-absences.vue, composants frontend/components/absence/ - services front, AccrueLeaveCommand, PublicHolidayController Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
97 lines
5.7 KiB
Markdown
97 lines
5.7 KiB
Markdown
# Réorganisation de la gestion des employés (module Absences)
|
|
|
|
Date : 2026-05-22
|
|
Branche : `feat/absence-management`
|
|
Statut : design approuvé, prêt pour plan d'implémentation
|
|
|
|
## Contexte
|
|
|
|
Aujourd'hui, le `UserDrawer` (admin → utilisateurs) porte deux responsabilités mélangées :
|
|
|
|
1. l'administration du compte (nom, mot de passe, rôles, client, projets) ;
|
|
2. **tout le détail RH/employé** : case « Employé » + un bloc de champs (date d'embauche, date de sortie, type de contrat, situation familiale, temps de travail, CP annuels, début de période de référence, solde CP initial, nombre d'enfants).
|
|
|
|
Ces champs existent déjà sur l'entité `User` (backend) et dans le DTO `UserData`/`UserWrite` (frontend). La persistance se fait via l'API user (`PATCH /api/users/{id}`).
|
|
|
|
On veut séparer ces deux préoccupations : le `UserDrawer` ne décide plus que **si un utilisateur est un employé** ; l'édition des informations RH se fait dans un espace dédié, dans le module Absences.
|
|
|
|
## Objectifs
|
|
|
|
- `UserDrawer` : ne conserver que la case à cocher « Employé ».
|
|
- `team-absences` : ajouter un onglet « Employés » (la page est déjà `middleware: ["admin"]`, donc admin-only).
|
|
- L'onglet liste les utilisateurs marqués `isEmployee` avec leurs soldes de congés.
|
|
- Un drawer dédié permet d'éditer les informations RH d'un employé.
|
|
|
|
Hors périmètre : création d'utilisateur (reste dans l'admin), modification du flag `isEmployee` ailleurs que dans le `UserDrawer`, backend (déjà en place).
|
|
|
|
## Composants
|
|
|
|
### 1. `frontend/components/user/UserDrawer.vue`
|
|
|
|
- Supprimer le bloc détaillé employé (`hireDate`, `endDate`, `contractType`, `familySituation`, `workTimeRatio`, `annualLeaveDays`, `referencePeriodStart`, `initialLeaveBalance`, `nbChildren`).
|
|
- Conserver **uniquement** la case `isEmployee` (« Employé (soumis à la gestion des absences) »).
|
|
- Le payload de sauvegarde du user **n'envoie plus** les champs détaillés, pour ne pas les écraser. Il continue d'envoyer `isEmployee` et les champs de compte existants.
|
|
- Nettoyer l'état du formulaire et les imports devenus inutiles (options contrat / situation familiale si elles ne servent plus que là).
|
|
|
|
### 2. `frontend/pages/team-absences.vue` — onglet « Employés »
|
|
|
|
- Ajouter un 4ᵉ onglet dans `tabs` : `{ key: 'employees', label: t('absences.admin.tabs.employees'), icon: 'mdi:account-group' }`.
|
|
- Slot `#employees` : `MalioDataTable` avec les colonnes **Nom · Contrat · CP pris · CP restants**.
|
|
- Clic sur une ligne → ouvre `EmployeeDrawer` avec l'utilisateur sélectionné (cohérent avec l'onglet Demandes qui ouvre le détail au clic ligne).
|
|
- Chargement des données :
|
|
- `usersService.getAll()` filtré sur `isEmployee === true` ;
|
|
- `absenceService.getBalances({ type: 'cp' })` → map par `user.id` pour récupérer `taken` (CP pris) et `available` (CP restants) ;
|
|
- fusion en lignes de tableau (`taken`/`available` à `—` si pas de solde CP pour l'employé).
|
|
- Recharger la liste après `saved` du drawer.
|
|
|
|
### 3. `frontend/components/absence/EmployeeDrawer.vue` (nouveau)
|
|
|
|
- Props : `modelValue: boolean`, `user: UserData | null`.
|
|
- Events : `update:modelValue`, `saved`.
|
|
- Formulaire en **composants Malio** :
|
|
- `MalioDate` : `hireDate`, `endDate` (valeurs ISO `YYYY-MM-DD`) ;
|
|
- `MalioSelect` : `contractType` (CDI/CDD/Stage/Alternance/Autre), `familySituation` (Célibataire/Marié/Pacsé/Divorcé/Veuf) ;
|
|
- `MalioInputText` : `workTimeRatio`, `annualLeaveDays`, `referencePeriodStart` (MM-DD), `initialLeaveBalance`, `nbChildren`.
|
|
- À l'ouverture, initialiser le formulaire depuis `props.user` ; remettre à jour si `user` change.
|
|
- Sauvegarde : `usersService.update(user.id, { …champs employé })` ; à la réussite, émettre `saved` et fermer.
|
|
- En-tête : nom de l'employé.
|
|
|
|
### 4. i18n (`frontend/i18n/locales/fr.json`)
|
|
|
|
Nouvelles clés regroupées sous `absences.admin.employees.*` (et l'onglet sous `absences.admin.tabs.employees`) :
|
|
- onglet : `absences.admin.tabs.employees` = « Employés » ;
|
|
- colonnes liste : `absences.admin.employees.columns.{name,contract,cpTaken,cpRemaining}` ;
|
|
- drawer : `absences.admin.employees.drawer.title` + libellés de champs sous `absences.admin.employees.fields.*`.
|
|
|
|
Les libellés de contrat et de situation familiale (CDI/CDD/…, Célibataire/Marié/…) actuellement codés en dur dans `UserDrawer` sont déplacés avec leur drawer ; on les passe en clés i18n à cette occasion.
|
|
|
|
## Flux de données
|
|
|
|
```
|
|
UserDrawer --PATCH isEmployee--> User (backend)
|
|
|
|
|
team-absences (onglet Employés) |
|
|
getAll() ∩ isEmployee <-----------+
|
|
getBalances({type:'cp'}) --> map user.id -> {taken, available}
|
|
=> lignes tableau (nom, contrat, CP pris, CP restants)
|
|
|
|
|
clic ligne
|
|
v
|
|
EmployeeDrawer(user) --usersService.update--> User (backend)
|
|
|
|
|
@saved --> recharge liste
|
|
```
|
|
|
|
## Découpage / responsabilités
|
|
|
|
- `UserDrawer` : compte + flag employé. Ne connaît plus le détail RH.
|
|
- Onglet Employés : vue dérivée en lecture (jointure users ⋈ soldes), aiguille vers le drawer.
|
|
- `EmployeeDrawer` : seule unité qui édite les champs RH ; interface claire (`user` en entrée, `saved` en sortie), testable isolément.
|
|
|
|
## Vérification
|
|
|
|
- `UserDrawer` : ouvrir un user, vérifier qu'il ne reste que la case « Employé », cocher/décocher et sauvegarder sans perte des autres champs RH (qui ne sont plus envoyés).
|
|
- Onglet Employés : la liste affiche les users `isEmployee` avec CP pris/restants cohérents avec l'onglet Soldes.
|
|
- `EmployeeDrawer` : éditer un employé (dates en JJ/MM/AAAA, selects FR), sauvegarder, vérifier la persistance (recharge) et l'absence d'erreurs console.
|
|
- Vérification navigateur via Chrome DevTools sur les trois écrans.
|