$payload */ $payload = json_decode($request->getContent(), true) ?? []; $type = AbsenceType::tryFrom((string) ($payload['type'] ?? '')); if (null === $type) { throw new UnprocessableEntityHttpException('Unknown absence type.'); } $startRaw = (string) ($payload['startDate'] ?? ''); $endRaw = (string) ($payload['endDate'] ?? ''); if ('' === $startRaw || '' === $endRaw) { throw new UnprocessableEntityHttpException('Start date and end date are required.'); } $start = new DateTimeImmutable($startRaw); $end = new DateTimeImmutable($endRaw); if ($end < $start) { throw new UnprocessableEntityHttpException('End date must be on or after start date.'); } $policy = $this->policyRepository->findOneByType($type); $workingDaysOnly = $policy?->isCountWorkingDaysOnly() ?? true; $countedDays = $this->calculator->countWorkingDays( $start, $end, isset($payload['startHalfDay']) ? HalfDay::tryFrom((string) $payload['startHalfDay']) : null, isset($payload['endHalfDay']) ? HalfDay::tryFrom((string) $payload['endHalfDay']) : null, $workingDaysOnly, ); $user = $this->security->getUser(); assert($user instanceof UserInterface); $available = null; $projectedAvailable = null; $period = null; if ($type->decrementsBalance()) { $period = $this->balanceService->periodFor($user, $type, $start); $balance = $this->balanceRepository->findOneForPeriod($user, $type, $period); $available = $balance?->getAvailable() ?? 0.0; $projectedAvailable = $available - $countedDays; } return $this->json([ 'countedDays' => $countedDays, 'period' => $period, 'available' => $available, 'projectedAvailable' => $projectedAvailable, 'justificationRequired' => $policy?->isJustificationRequired() ?? false, ]); } }