From cc868a1e82d56fe4320776dccf28900005772c43 Mon Sep 17 00:00:00 2001 From: tristan Date: Mon, 27 Apr 2026 12:08:24 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20ajout=20malio=20UI=20+=20d=C3=A9compte?= =?UTF-8?q?=20des=20jours=20de=20pr=C3=A9sence=20forfait=20(#17)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit | Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [ ] Pas de régression - [ ] TU/TI/TF rédigée - [ ] TU/TI/TF OK - [ ] CHANGELOG modifié Reviewed-on: https://gitea.malio.fr/MALIO-DEV/SIRH/pulls/17 Co-authored-by: tristan Co-committed-by: tristan --- CLAUDE.md | 4 + doc/functional-rules.md | 9 +- frontend/.npmrc | 1 + frontend/components/AbsenceFormDrawer.vue | 130 ++++----- frontend/components/AppDrawer.vue | 2 +- .../components/EmployeeNameFilterInput.vue | 26 -- frontend/components/SiteFilterSelector.vue | 69 ----- .../driver-hours/DriverHoursDayView.vue | 3 +- frontend/components/hours/HoursDayView.vue | 5 +- frontend/components/hours/HoursToolbar.vue | 40 ++- frontend/composables/useDriverHoursPage.ts | 5 + frontend/composables/useEmployeeDetailPage.ts | 14 +- frontend/composables/useHoursPage.ts | 5 + frontend/data/documentation-content.ts | 2 + frontend/layouts/default.vue | 2 +- frontend/nuxt.config.ts | 1 + frontend/package-lock.json | 260 +++++++----------- frontend/package.json | 1 + frontend/pages/absence-types.vue | 143 ++++------ frontend/pages/calendar.vue | 58 ++-- frontend/pages/driver-hours.vue | 2 + frontend/pages/employees/[id].vue | 3 +- frontend/pages/employees/index.vue | 219 ++++++++++----- frontend/pages/hours.vue | 2 + frontend/pages/login.vue | 35 +-- frontend/pages/sites.vue | 84 ++---- frontend/pages/users.vue | 164 ++++------- .../services/dto/employee-leave-summary.ts | 1 + frontend/services/dto/work-hour.ts | 1 + src/ApiResource/EmployeeLeaveSummary.php | 3 + src/Dto/WorkHours/DayContextRow.php | 5 +- src/Service/Leave/LeaveRecapRowBuilder.php | 2 +- src/State/EmployeeLeaveSummaryProvider.php | 56 +++- src/State/WorkHourDayContextProvider.php | 8 +- .../State/WorkHourDayContextProviderTest.php | 5 + 35 files changed, 652 insertions(+), 718 deletions(-) create mode 100644 frontend/.npmrc delete mode 100644 frontend/components/EmployeeNameFilterInput.vue delete mode 100644 frontend/components/SiteFilterSelector.vue diff --git a/CLAUDE.md b/CLAUDE.md index a9aa367..cd33261 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,6 +15,7 @@ ## Stack - Backend: Symfony + API Platform + Doctrine ORM - Frontend: Nuxt 4 + Vue 3 + TypeScript + Tailwind CSS +- UI library: `@malio/layer-ui` (Nuxt layer, `extends: ['@malio/layer-ui']` dans `nuxt.config.ts`). Composants auto-importés avec préfixe `Malio*` (ex. `MalioSelectCheckbox`, `MalioInputText`…). Doc d'usage dans `node_modules/@malio/layer-ui/COMPONENTS.md`. Tokens Tailwind `m-*` (primary/muted/danger/success/…) et variables CSS `--m-*` fournies par la couche. ## Project Structure - `src/` — Symfony domain, API resources, state providers/processors, services @@ -32,6 +33,8 @@ - Contract nature (per period): CDI, CDD, INTERIM - **Agence d'intérim** (`InterimAgency` entity, table `interim_agencies`): optionnelle sur `EmployeeContractPeriod` quand nature = INTERIM. Pas de CRUD UI — gérée en BDD. API lecture seule `GET /interim_agencies`. Affichée "Intérim (NomAgence)" sur la liste employés et l'historique contrat. - Employee contract history: `employee_contract_periods`, resolved by `EmployeeContractResolver` +- **Écrans Heures / Heures Conducteurs (vue jour)** : le libellé nature (CDI/CDD/Intérim) sous le nom de l'employé est résolu **à la date filtrée** via `WorkHourDayContext.contractNature` (alimenté par `EmployeeContractResolver::resolveNatureForEmployeeAndDate`), pas via `Employee.currentContractNature` (qui est résolu à aujourd'hui). +- **Écran Calendrier** : un employé est affiché uniquement si au moins une de ses périodes de contrat (`employee.contractHistory`) intersecte le mois affiché (`[1er ; dernier jour]`). Filtre côté frontend dans `visibleEmployees` (`pages/calendar.vue`). - **Planning jours travaillés** (`EmployeeContractPeriod.workDaysHours` : JSON `{iso_day: minutes}`) : obligatoire pour tout contrat TIME **hors 35h/39h/INTERIM** (ex. 4h, 25h, 28h). Somme = `weeklyHours × 60`. Utilisé par `HolidayVirtualHoursResolver` (crédit férié) et `WorkedHoursCreditPolicy` (crédit absence) pour ne créditer que les jours effectivement travaillés. Validation : `EmployeeContractPeriodValidator::assertWorkDaysHours`. - Absences: stored per day (auto-split), AM/PM/full day, clear corresponding hour slots - Absences with `countAsWorkedHours=true`: credit minutes (TIME) or nothing (PRESENCE) @@ -58,6 +61,7 @@ - INTERIM: no overtime bonuses, no recovery time - Driver contracts: RTT uses `dayHoursMinutes + nightHoursMinutes + workshopHoursMinutes` instead of morning/afternoon/evening time ranges - FORFAIT weekend/holiday bonus: each weekend or public holiday day worked gives bonus leave (full day if morning+afternoon, 0.5 if only one). Added to acquired days, no cap. PRESENCE mode only. +- **FORFAIT — jours de présence et N-1** : les congés posés et imputés sur le stock N-1 ne décrémentent **pas** les jours de présence affichés (`presenceDaysByMonth` et `presenceDaysToToday`). Implémenté dans `EmployeeLeaveSummaryProvider::computePresenceDaysByMonth` via un budget N-1 (= `previousYearTakenDays`) consommé chronologiquement avant comptage des absences. Pour les non-forfait, ce budget vaut toujours 0 → comportement inchangé. ## Récap. congés (écran) - Accès via sidebar `Récap. congés`, conditionné au flag `User.hasLeaveRecapAccess` (défaut `false`) — activé au create/edit user. Le flag s'applique à tous les profils, y compris admin. diff --git a/doc/functional-rules.md b/doc/functional-rules.md index e732e9f..3be0d1d 100644 --- a/doc/functional-rules.md +++ b/doc/functional-rules.md @@ -58,6 +58,9 @@ Documents complementaires: - mise à jour uniquement quand un employé (`ROLE_SELF`) modifie ses propres heures - non mise à jour lors de modifications admin ou chef de site - affichée sous le nom de l'employé (visible admin uniquement) +- Libellé nature de contrat (CDI/CDD/Intérim) affiché sous le nom: + - résolu à la date filtrée (période de contrat couvrant ce jour), pas à aujourd'hui + - masqué si aucun contrat à cette date (cas rarissime en vue jour puisque l'employé est alors déjà filtré) ## 4) Absences @@ -71,6 +74,10 @@ Documents complementaires: - Calendrier congés: fond coloré selon la couleur du type d'absence (`AbsenceType.color`) - demi-journée: dégradé diagonal - journée complète: fond plein +- Visibilité des employés dans le Calendrier: + - un employé est affiché si au moins une de ses périodes de contrat intersecte le mois affiché + - un employé dont toutes les périodes se terminent avant le 1er du mois (ou commencent après la fin du mois) est masqué + - même logique que l'écran Heures : « pas de contrat sur la période → masqué » ### Effet absence sur les heures @@ -328,7 +335,7 @@ Tous les filtres checkbox sont cochés par défaut à l'ouverture du drawer. | Contrat | Contract.name | | CP N-1 restant | CDI/CDD: acquis N-1 − pris sur N-1. Forfait: report N-1 restant | | Samedi restant | CDI/CDD: samedis acquis N-1 − pris. Forfait: `-` | -| CP N | Forfait: jours acquis année civile. Non-forfait: en cours d'acquisition | +| CP N | Forfait: restant sur quota année civile (acquis − pris depuis N, sans toucher au stock N-1). Non-forfait: en cours d'acquisition | | RTT | Minutes disponibles (report N-1 + acquis N - payés). Format `X h Y m`. Forfait et INTERIM: `-` | ## 10bis) Écran Récap. congés (tableau) diff --git a/frontend/.npmrc b/frontend/.npmrc new file mode 100644 index 0000000..303a6d3 --- /dev/null +++ b/frontend/.npmrc @@ -0,0 +1 @@ +@malio:registry=https://gitea.malio.fr/api/packages/MALIO-DEV/npm/ diff --git a/frontend/components/AbsenceFormDrawer.vue b/frontend/components/AbsenceFormDrawer.vue index ec25735..d663372 100644 --- a/frontend/components/AbsenceFormDrawer.vue +++ b/frontend/components/AbsenceFormDrawer.vue @@ -1,44 +1,26 @@