getOrCreateBookingCreateDto($this->bookingSessionService, $request); if ($result instanceof Response) { return $result; } $bookingCreateDto = $result; // Get or create baseline snapshot for change detection $oldRoomSelectionSnapshot = $this->bookingSessionService->getOrCreateBaselineSnapshot($request, $bookingCreateDto); // Validate step access - allow step 1 or redirect to current step if ($redirect = $this->validateStepAccess($bookingCreateDto, 1)) { return $redirect; } $form = $this->createForm(BookingCreateStep1Type::class, $bookingCreateDto, [ 'validation_groups' => ['booking_create_step_1'], ]); $form->handleRequest($request); if (true === $form->isSubmitted() && true === $form->isValid()) { if ($bookingCreateDto->hasRoomSelectionChanged($oldRoomSelectionSnapshot)) { $bookingCreateDto->resetParticipantAssignments(); } // Check if room selection forces inquiry mode $this->bookingService->updateBookingStatusFromRoomSelection($bookingCreateDto); $bookingCreateDto->currentStep = 2; $this->bookingSessionService->saveBookingDto($request, $bookingCreateDto, BookingDto::MODE_CREATE); // Clear baseline snapshot when moving to step 2 $this->bookingSessionService->clearBaselineSnapshot($request); return $this->redirectToRoute('app_booking_create_step_2'); } $context = $this->createContextFactory->create( $bookingCreateDto, RoomPricingCalculator::PRICING_MODE_SELECTION ); return $this->render('booking/create/step_1.html.twig', [ 'bookingCreateContext' => $context, 'form' => $form->createView(), ]); } /** * Handles HTMX requests for dynamic form updates when room selections change by submitting the form * without validation and returning freshly rendered blocks. */ #[Route('/bookings/create/refresh', name: 'app_booking_create_step_1_refresh', methods: ['POST'])] public function refresh(Request $request): Response { $result = $this->getOrCreateBookingCreateDtoForHtmx($this->bookingSessionService, $request); if ($result instanceof Response) { return $result; } $bookingCreateDto = $result; // Process form data without validation to capture current state $form = $this->createForm(BookingCreateStep1Type::class, $bookingCreateDto, [ 'validation_groups' => false, ]); $form->handleRequest($request); $context = $this->createContextFactory->create( $bookingCreateDto, RoomPricingCalculator::PRICING_MODE_SELECTION ); // The DTO is now updated with the latest selection. // We can now render the blocks with the fresh data. return $this->htmxOobResponse( 'booking/create/step_1.html.twig', ['room_selection_form', 'booking_summary'], [ 'form' => $form->createView(), 'bookingCreateContext' => $context, ] ); } }