*/ public function provide(Operation $operation, array $uriVariables = [], array $context = []): array { $user = $this->security->getUser(); if (!$user instanceof User) { throw new AccessDeniedHttpException('Authentication required.'); } if (!$user->hasLeaveRecapAccess()) { throw new AccessDeniedHttpException('Leave recap access not granted.'); } $cutoff = LeaveRecapCutoff::resolveCutoff(new DateTimeImmutable('today')); $cutoffYmd = $cutoff->format('Y-m-d'); $employees = $this->resolveScopedEmployees($user); $rows = []; foreach ($employees as $employee) { if (!$employee->getHasActiveContract()) { continue; } $row = $this->rowBuilder->build($employee, $cutoff); $resource = new EmployeeLeaveRecap(); $resource->employeeId = (int) $employee->getId(); $resource->lastName = $row['lastName'] ?? ''; $resource->firstName = $row['firstName'] ?? ''; $site = $employee->getSite(); $resource->siteId = $site?->getId(); $resource->siteName = $site?->getName(); $resource->siteColor = $site?->getColor(); $resource->contractName = $row['contractName'] ?? null; $resource->contractSortKey = $this->resolveContractSortKey($employee->getContract()); $resource->cpN1Remaining = is_numeric($row['cpN1Remaining']) ? (float) $row['cpN1Remaining'] : 0.0; $resource->cpN = (string) $row['cpN']; $resource->acquiredSaturdays = (string) $row['acquiredSaturdays']; $resource->rtt = (string) $row['rtt']; $resource->cutoffDate = $cutoffYmd; $rows[] = $resource; $this->entityManager->clear(); } usort($rows, static function (EmployeeLeaveRecap $a, EmployeeLeaveRecap $b): int { $siteCmp = strcmp((string) ($a->siteName ?? 'zzz'), (string) ($b->siteName ?? 'zzz')); if (0 !== $siteCmp) { return $siteCmp; } $contractCmp = $a->contractSortKey <=> $b->contractSortKey; if (0 !== $contractCmp) { return $contractCmp; } $lastCmp = strcmp($a->lastName, $b->lastName); if (0 !== $lastCmp) { return $lastCmp; } return strcmp($a->firstName, $b->firstName); }); return $rows; } /** * Sort order: FORFAIT → 39h → 35h → 25h → 4h → autres. */ private function resolveContractSortKey(?Contract $contract): int { if (null === $contract) { return 99; } if (ContractType::FORFAIT === $contract->getType()) { return 0; } $weeklyHours = $contract->getWeeklyHours(); return match ($weeklyHours) { 39 => 1, 35 => 2, 25 => 3, 4 => 4, default => 99, }; } /** * @return list */ private function resolveScopedEmployees(User $user): array { if (in_array('ROLE_ADMIN', $user->getRoles(), true)) { return $this->employeeRepository->findForPrintBySiteIds([]); } if (in_array('ROLE_SELF', $user->getRoles(), true)) { $employee = $user->getEmployee(); return $employee instanceof Employee ? [$employee] : []; } $siteIds = $this->employeeScopeService->getAllowedSiteIds($user); if ([] === $siteIds) { return []; } return $this->employeeRepository->findForPrintBySiteIds($siteIds); } }