resolveDto($request); if ($dto instanceof Response) { return $dto; } $accommodation = $this->loadAccommodationOrFail($dto); $services = $this->bookingService->loadAvailableServices($dto, $accommodation); $ctx = new AccommodationBookingContext( accommodation: $accommodation, hotelCmsData: $this->bookingService->loadHotelCmsData($accommodation), boardServices: $services['boardServices'], additionalServices: $services['additionalServices'], priceBreakdown: $dto->priceBreakdown ?: null, ); $form = $this->createForm(AccommodationStep3Type::class, $dto); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $dto->currentStep = 4; $this->sessionManager->save($request, $dto); return $this->redirectToRoute('app_groups_booking_step_4'); } return $this->render('groups/booking/step_3.html.twig', [ 'dto' => $dto, 'ctx' => $ctx, 'form' => $form, ]); } /** * Loads the session DTO and checks step access, returning an early * response (session failure or step-access redirect) if either fails. */ private function resolveDto(Request $request): AccommodationBookingDto|Response { try { $dto = $this->sessionManager->getOrFail($request); } catch (AccommodationSessionNotFoundException $e) { return $this->createFailureResponse($e, false); } if ($redirect = $this->validateStepAccess($dto, 3)) { return $redirect; } return $dto; } private function loadAccommodationOrFail(AccommodationBookingDto $dto): Accommodation { $accommodation = $this->bookingService->loadAccommodation($dto->accommodationId); if (null === $accommodation) { throw $this->createNotFoundException(); } return $accommodation; } }