diff --git a/src/Controller/Booking/CreateStep1Controller.php b/src/Controller/Booking/CreateStep1Controller.php index f225675..d9fb319 100644 --- a/src/Controller/Booking/CreateStep1Controller.php +++ b/src/Controller/Booking/CreateStep1Controller.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Controller\Booking; +use App\Exception\NoRoomsAvailableException; use App\Form\BookingCreateStep1Type; use App\Service\BookingService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -32,7 +33,13 @@ class CreateStep1Controller extends AbstractController #[Route('/bookings/create', name: 'app_booking_create_step_1')] public function index(Request $request): Response { - $bookingCreateDto = $this->bookingService->getOrCreateBookingCreateDto($request); + try { + $bookingCreateDto = $this->bookingService->getOrCreateBookingCreateDto($request); + } catch (NoRoomsAvailableException $e) { + $this->addFlash('error', 'Leider sind für diese Reise aktuell keine Zimmer verfügbar.'); + // TODO: Redirect to travel listing or hotel details page + throw $this->createNotFoundException('No rooms available for this travel.'); + } // Get or create baseline snapshot for change detection $oldRoomSelectionSnapshot = $this->bookingService->getOrCreateBaselineSnapshot($request, $bookingCreateDto); @@ -83,7 +90,12 @@ class CreateStep1Controller extends AbstractController #[Route('/bookings/create/room-summary', name: 'app_booking_create_step_1_room_summary', methods: ['POST'])] public function roomSummary(Request $request): Response { - $bookingCreateDto = $this->bookingService->getOrCreateBookingCreateDto($request); + try { + $bookingCreateDto = $this->bookingService->getOrCreateBookingCreateDto($request); + } catch (NoRoomsAvailableException $e) { + // For HTMX requests, return a simple error message + return new Response('
Keine Zimmer verfügbar
', 400); + } // Process the form to update the DTO with the latest room selection $form = $this->createForm(BookingCreateStep1Type::class, $bookingCreateDto, [ diff --git a/src/Controller/Booking/CreateStep2Controller.php b/src/Controller/Booking/CreateStep2Controller.php index 1269772..b095a70 100644 --- a/src/Controller/Booking/CreateStep2Controller.php +++ b/src/Controller/Booking/CreateStep2Controller.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace App\Controller\Booking; use App\Controller\Traits\HtmxControllerTrait; +use App\Exception\NoRoomsAvailableException; use App\Form\BookingCreateStep2Type; use App\Form\Model\BookingCreateDto; use App\Form\Model\ParticipantDto; @@ -38,9 +39,15 @@ class CreateStep2Controller extends AbstractController #[Route('/bookings/create/participants', name: 'app_booking_create_step_2')] public function participants(Request $request): Response { - $bookingCreateDto = $this - ->bookingService - ->getOrCreateBookingCreateDto($request); + try { + $bookingCreateDto = $this + ->bookingService + ->getOrCreateBookingCreateDto($request); + } catch (NoRoomsAvailableException $e) { + $this->addFlash('error', 'Leider sind für diese Reise aktuell keine Zimmer verfügbar.'); + // TODO: Redirect to travel listing or hotel details page + throw $this->createNotFoundException('No rooms available for this travel.'); + } // Enrich with fresh availability data $this->enrichWithFreshAvailabilities($bookingCreateDto); @@ -93,7 +100,12 @@ class CreateStep2Controller extends AbstractController #[Route('/bookings/create/participants/refresh', name: 'app_booking_create_step_2_refresh', methods: ['POST'])] public function refreshParticipantForm(Request $request): Response { - $bookingCreateDto = $this->bookingService->getOrCreateBookingCreateDto($request); + try { + $bookingCreateDto = $this->bookingService->getOrCreateBookingCreateDto($request); + } catch (NoRoomsAvailableException $e) { + // For HTMX requests, return a simple error message + return new Response('
Keine Zimmer verfügbar
', 400); + } // Enrich with fresh availability data $this->enrichWithFreshAvailabilities($bookingCreateDto); diff --git a/src/Controller/Booking/CreateStep3Controller.php b/src/Controller/Booking/CreateStep3Controller.php index 28189f6..065e19f 100644 --- a/src/Controller/Booking/CreateStep3Controller.php +++ b/src/Controller/Booking/CreateStep3Controller.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Controller\Booking; +use App\Exception\NoRoomsAvailableException; use App\Service\BookingService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; @@ -31,7 +32,13 @@ class CreateStep3Controller extends AbstractController #[Route('/bookings/create/confirm', name: 'app_booking_create_step_3')] public function confirm(Request $request): Response { - $bookingCreateDto = $this->bookingCreateService->getOrCreateBookingCreateDto($request); + try { + $bookingCreateDto = $this->bookingCreateService->getOrCreateBookingCreateDto($request); + } catch (NoRoomsAvailableException $e) { + $this->addFlash('error', 'Leider sind für diese Reise aktuell keine Zimmer verfügbar.'); + // TODO: Redirect to travel listing or hotel details page + throw $this->createNotFoundException('No rooms available for this travel.'); + } // Validate step access $this->validateStepAccess($bookingCreateDto, 3); diff --git a/src/Exception/NoRoomsAvailableException.php b/src/Exception/NoRoomsAvailableException.php new file mode 100644 index 0000000..9d8a012 --- /dev/null +++ b/src/Exception/NoRoomsAvailableException.php @@ -0,0 +1,27 @@ +processRoomQuantities($request); $availableRooms = $travelData->getAvailableRooms(); + // Prevent booking flow entry when no rooms are available + if (empty($availableRooms)) { + throw new NoRoomsAvailableException($dateId, $hotelId); + } + $roomSelections = array_map( fn (Room $room) => $this->createRoomSelection($room, $roomsIdsAndQuantities), $availableRooms