*/ final readonly class UpdateScheduleSlotProcessor implements ProcessorInterface { public function __construct( private UpdateScheduleSlotHandler $handler, private TenantContext $tenantContext, private MessageBusInterface $eventBus, private AuthorizationCheckerInterface $authorizationChecker, ) { } /** * @param ScheduleSlotResource $data */ #[Override] public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): ScheduleSlotResource { if (!$this->authorizationChecker->isGranted(ScheduleSlotVoter::EDIT)) { throw new AccessDeniedHttpException("Vous n'êtes pas autorisé à modifier l'emploi du temps."); } if (!$this->tenantContext->hasTenant()) { throw new UnauthorizedHttpException('Bearer', 'Tenant non défini.'); } /** @var string|null $slotId */ $slotId = $uriVariables['id'] ?? null; if ($slotId === null) { throw new NotFoundHttpException('Créneau non trouvé.'); } $tenantId = (string) $this->tenantContext->getCurrentTenantId(); try { $command = new UpdateScheduleSlotCommand( tenantId: $tenantId, slotId: $slotId, classId: $data->classId ?? '', subjectId: $data->subjectId ?? '', teacherId: $data->teacherId ?? '', dayOfWeek: $data->dayOfWeek ?? 1, startTime: $data->startTime ?? '', endTime: $data->endTime ?? '', room: $data->room, forceConflicts: $data->forceConflicts ?? false, ); $result = ($this->handler)($command); $slot = $result['slot']; /** @var array $conflicts */ $conflicts = $result['conflicts']; if ($conflicts === [] || $command->forceConflicts) { foreach ($slot->pullDomainEvents() as $event) { $this->eventBus->dispatch($event); } } $resource = ScheduleSlotResource::fromDomain($slot); if ($conflicts !== []) { $resource->conflicts = array_map( static fn (ScheduleConflict $c) => [ 'type' => $c->type, 'description' => $c->description, 'slotId' => (string) $c->conflictingSlot->id, ], $conflicts, ); } return $resource; } catch (EnseignantNonAffecteException) { throw new UnprocessableEntityHttpException( "L'enseignant sélectionné n'est pas affecté à cette classe pour cette matière. " . 'Veuillez vérifier les affectations enseignant-classe-matière.', ); } catch (ScheduleSlotNotFoundException|InvalidUuidStringException) { throw new NotFoundHttpException('Créneau non trouvé.'); } catch (CreneauHoraireInvalideException|ValueError $e) { throw new BadRequestHttpException($e->getMessage()); } } }