*/ public function __invoke(GetBlockedDatesQuery $query): array { $tenantId = TenantId::fromString($query->tenantId); $academicYearId = AcademicYearId::fromString($query->academicYearId); $calendar = $this->calendarRepository->findByTenantAndYear($tenantId, $academicYearId); $startDate = new DateTimeImmutable($query->startDate); $endDate = new DateTimeImmutable($query->endDate); $oneDay = new DateInterval('P1D'); $now = $this->clock->now(); $blockedDates = []; $current = $startDate; while ($current <= $endDate) { $dayOfWeek = (int) $current->format('N'); $dateStr = $current->format('Y-m-d'); if ($dayOfWeek >= 6) { $blockedDates[] = new BlockedDateDto( date: $dateStr, reason: $dayOfWeek === 6 ? 'Samedi' : 'Dimanche', type: 'weekend', ); } elseif ($calendar !== null && ($entry = $calendar->trouverEntreePourDate($current)) !== null) { $blockedDates[] = new BlockedDateDto( date: $dateStr, reason: $entry->label, type: $entry->type->value, ); } else { $dueDate = new DateTimeImmutable($dateStr); $result = $this->rulesChecker->verifier($tenantId, $dueDate, $now); if (!$result->estValide()) { $blockedDates[] = new BlockedDateDto( date: $dateStr, reason: $result->messages()[0] ?? 'Règle de devoirs', type: $result->estBloquant() ? 'rule_hard' : 'rule_soft', ); } } $current = $current->add($oneDay); } return $blockedDates; } }