feat(absences) : fondation backend du module de gestion des absences
Module type Payfit (étapes 1+2 de la spec V1) : demande d'absence, validation admin, soldes à jour. - Enums : AbsenceType, AbsenceStatus, HalfDay, ContractType, FamilySituation - Entités : AbsencePolicy, AbsenceBalance, AbsenceRequest + champs RH sur User - Services : PublicHolidayProvider (fériés FR métropole en PHP pur, Computus), AbsenceDayCalculator (décompte jours ouvrés/ouvrables + demi-journées, TDD), AbsenceBalanceService (périodes + pending/taken/recrédit) - API Platform : providers/processors (création, approve/reject/cancel) + RBAC me/admin, contrôleurs preview (dry-run), upload/download justificatif, calendrier - Migrations : une par table + colonnes RH user (DEFAULT puis DROP DEFAULT) - Fixtures : 5 policies par défaut, salariés démo, soldes et demandes - Tests unitaires : PublicHolidayProvider, AbsenceDayCalculator (12 tests) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\DataFixtures;
|
||||
|
||||
use App\Entity\AbsenceBalance;
|
||||
use App\Entity\AbsencePolicy;
|
||||
use App\Entity\AbsenceRequest;
|
||||
use App\Entity\Client;
|
||||
use App\Entity\ClientTicket;
|
||||
use App\Entity\MailConfiguration;
|
||||
@@ -19,6 +22,10 @@ use App\Entity\TimeEntry;
|
||||
use App\Entity\User;
|
||||
use App\Entity\Workflow;
|
||||
use App\Entity\ZimbraConfiguration;
|
||||
use App\Enum\AbsenceStatus;
|
||||
use App\Enum\AbsenceType;
|
||||
use App\Enum\ContractType;
|
||||
use App\Enum\FamilySituation;
|
||||
use App\Enum\RecurrenceType;
|
||||
use App\Enum\StatusCategory;
|
||||
use DateTimeImmutable;
|
||||
@@ -722,6 +729,106 @@ class AppFixtures extends Fixture
|
||||
$mailConfig->setEnabled(false);
|
||||
$manager->persist($mailConfig);
|
||||
|
||||
// =============================================
|
||||
// Absence management — policies, employees, balances, requests
|
||||
// =============================================
|
||||
|
||||
// Default policies for the 5 absence types (legal defaults, editable by admin)
|
||||
$policyData = [
|
||||
// [type, daysPerYear, daysPerEvent, justifRequired, noticeDays, workingDaysOnly]
|
||||
[AbsenceType::PaidLeave, 25.0, null, false, 30, true],
|
||||
[AbsenceType::MarriagePacs, null, 4.0, true, 0, true],
|
||||
[AbsenceType::ParentalLeave, null, null, true, 30, true],
|
||||
[AbsenceType::Bereavement, null, 3.0, true, 0, true],
|
||||
[AbsenceType::SickLeave, null, null, true, 0, true],
|
||||
];
|
||||
|
||||
foreach ($policyData as [$type, $daysPerYear, $daysPerEvent, $justif, $notice, $workingDaysOnly]) {
|
||||
$policy = new AbsencePolicy();
|
||||
$policy->setType($type);
|
||||
$policy->setDaysPerYear($daysPerYear);
|
||||
$policy->setDaysPerEvent($daysPerEvent);
|
||||
$policy->setJustificationRequired($justif);
|
||||
$policy->setNoticeDays($notice);
|
||||
$policy->setCountWorkingDaysOnly($workingDaysOnly);
|
||||
$policy->setActive(true);
|
||||
$manager->persist($policy);
|
||||
}
|
||||
|
||||
// Mark internal users as employees
|
||||
$admin->setIsEmployee(true);
|
||||
$admin->setHireDate(new DateTimeImmutable('2020-01-15'));
|
||||
$admin->setContractType(ContractType::Cdi);
|
||||
$admin->setFamilySituation(FamilySituation::Married);
|
||||
$admin->setNbChildren(2);
|
||||
|
||||
$userAlice->setIsEmployee(true);
|
||||
$userAlice->setHireDate(new DateTimeImmutable('2022-09-01'));
|
||||
$userAlice->setContractType(ContractType::Cdi);
|
||||
$userAlice->setFamilySituation(FamilySituation::Single);
|
||||
|
||||
$userBob->setIsEmployee(true);
|
||||
$userBob->setHireDate(new DateTimeImmutable('2023-03-10'));
|
||||
$userBob->setContractType(ContractType::Cdd);
|
||||
$userBob->setWorkTimeRatio(0.8);
|
||||
$userBob->setFamilySituation(FamilySituation::Pacsed);
|
||||
$userBob->setNbChildren(1);
|
||||
|
||||
// Paid-leave balances for the current reference period (June 1st → May 31st)
|
||||
$cpPeriod = '2025-2026';
|
||||
$balanceData = [
|
||||
// [user, acquired, taken, pending]
|
||||
[$admin, 22.5, 5.0, 0.0],
|
||||
[$userAlice, 18.0, 2.0, 5.0],
|
||||
[$userBob, 14.0, 0.0, 0.0],
|
||||
];
|
||||
|
||||
foreach ($balanceData as [$bUser, $acquired, $taken, $pending]) {
|
||||
$balance = new AbsenceBalance();
|
||||
$balance->setUser($bUser);
|
||||
$balance->setType(AbsenceType::PaidLeave);
|
||||
$balance->setPeriod($cpPeriod);
|
||||
$balance->setAcquired($acquired);
|
||||
$balance->setTaken($taken);
|
||||
$balance->setPending($pending);
|
||||
$manager->persist($balance);
|
||||
}
|
||||
|
||||
// Demo requests
|
||||
$approvedCp = new AbsenceRequest();
|
||||
$approvedCp->setUser($admin);
|
||||
$approvedCp->setType(AbsenceType::PaidLeave);
|
||||
$approvedCp->setStartDate(new DateTimeImmutable('2026-04-13'));
|
||||
$approvedCp->setEndDate(new DateTimeImmutable('2026-04-17'));
|
||||
$approvedCp->setCountedDays(5.0);
|
||||
$approvedCp->setReason('Vacances de printemps');
|
||||
$approvedCp->setStatus(AbsenceStatus::Approved);
|
||||
$approvedCp->setCreatedAt(new DateTimeImmutable('2026-03-10'));
|
||||
$approvedCp->setReviewedAt(new DateTimeImmutable('2026-03-11'));
|
||||
$approvedCp->setReviewedBy($admin);
|
||||
$manager->persist($approvedCp);
|
||||
|
||||
$pendingCp = new AbsenceRequest();
|
||||
$pendingCp->setUser($userAlice);
|
||||
$pendingCp->setType(AbsenceType::PaidLeave);
|
||||
$pendingCp->setStartDate(new DateTimeImmutable('2026-06-15'));
|
||||
$pendingCp->setEndDate(new DateTimeImmutable('2026-06-19'));
|
||||
$pendingCp->setCountedDays(5.0);
|
||||
$pendingCp->setStatus(AbsenceStatus::Pending);
|
||||
$pendingCp->setCreatedAt(new DateTimeImmutable('-2 days'));
|
||||
$manager->persist($pendingCp);
|
||||
|
||||
$pendingMarriage = new AbsenceRequest();
|
||||
$pendingMarriage->setUser($userBob);
|
||||
$pendingMarriage->setType(AbsenceType::MarriagePacs);
|
||||
$pendingMarriage->setStartDate(new DateTimeImmutable('2026-07-06'));
|
||||
$pendingMarriage->setEndDate(new DateTimeImmutable('2026-07-09'));
|
||||
$pendingMarriage->setCountedDays(4.0);
|
||||
$pendingMarriage->setReason('Mariage');
|
||||
$pendingMarriage->setStatus(AbsenceStatus::Pending);
|
||||
$pendingMarriage->setCreatedAt(new DateTimeImmutable('-1 day'));
|
||||
$manager->persist($pendingMarriage);
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user