Files
Classeo/backend/src/Scolarite/Application/Query/GetBlockedDates/GetBlockedDatesHandler.php
Mathias STRASSER 713e408773
Some checks failed
CI / Naming Conventions (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Frontend Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Build Check (push) Has been cancelled
feat: Provisionner automatiquement un nouvel établissement
Lorsqu'un super-admin crée un établissement via l'interface, le système
doit automatiquement créer la base tenant, exécuter les migrations,
créer le premier utilisateur admin et envoyer l'invitation — le tout
de manière asynchrone pour ne pas bloquer la réponse HTTP.

Ce mécanisme rend chaque établissement opérationnel dès sa création
sans intervention manuelle sur l'infrastructure.
2026-04-10 15:24:27 +02:00

83 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Scolarite\Application\Query\GetBlockedDates;
use App\Administration\Domain\Model\SchoolCalendar\SchoolCalendarRepository;
use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
use App\Scolarite\Application\Port\HomeworkRulesChecker;
use App\Shared\Domain\Clock;
use App\Shared\Domain\Tenant\TenantId;
use DateInterval;
use DateTimeImmutable;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
/**
* Retourne les dates bloquées (jours fériés, vacances, journées pédagogiques, weekends,
* et dates non conformes aux règles de devoirs) pour une plage de dates donnée.
*
* Utilisé par le frontend pour griser les jours non disponibles dans le calendrier.
*/
#[AsMessageHandler(bus: 'query.bus')]
final readonly class GetBlockedDatesHandler
{
public function __construct(
private SchoolCalendarRepository $calendarRepository,
private HomeworkRulesChecker $rulesChecker,
private Clock $clock,
) {
}
/** @return array<BlockedDateDto> */
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;
}
}