From ee264e88d413565f3c1de51a3444f6a67bfd19b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Sun, 5 Oct 2025 13:46:19 +0200 Subject: [PATCH] wip: confirmation step --- src/Controller/Booking/BookingCreateTrait.php | 1 + .../Booking/CreateStep3Controller.php | 6 +- .../Booking/CreateStep4Controller.php | 64 +++++++ src/Form/BookingCreateStep4Type.php | 37 ++++ templates/booking/create_step_4.html.twig | 173 ++++++++++++++++++ 5 files changed, 277 insertions(+), 4 deletions(-) create mode 100644 src/Controller/Booking/CreateStep4Controller.php create mode 100644 src/Form/BookingCreateStep4Type.php create mode 100644 templates/booking/create_step_4.html.twig diff --git a/src/Controller/Booking/BookingCreateTrait.php b/src/Controller/Booking/BookingCreateTrait.php index 0df8d33..705a8c6 100644 --- a/src/Controller/Booking/BookingCreateTrait.php +++ b/src/Controller/Booking/BookingCreateTrait.php @@ -41,6 +41,7 @@ trait BookingCreateTrait $route = match ($bookingCreateDto->currentStep) { 2 => 'app_booking_create_step_2', 3 => 'app_booking_create_step_3', + 4 => 'app_booking_create_step_4', default => 'app_booking_create_step_1', }; diff --git a/src/Controller/Booking/CreateStep3Controller.php b/src/Controller/Booking/CreateStep3Controller.php index 13cad92..5e4d285 100644 --- a/src/Controller/Booking/CreateStep3Controller.php +++ b/src/Controller/Booking/CreateStep3Controller.php @@ -49,12 +49,10 @@ class CreateStep3Controller extends AbstractController $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { + $bookingCreateDto->currentStep = 4; $this->bookingService->saveBookingCreateDto($request, $bookingCreateDto); - // TODO: Redirect to confirmation page or direct API submission - $this->addFlash('success', 'Zahlungsart erfolgreich ausgewählt.'); - - return $this->redirectToRoute('app_booking_create_step_3'); + return $this->redirectToRoute('app_booking_create_step_4'); } return $this->render('booking/create_step_3.html.twig', [ diff --git a/src/Controller/Booking/CreateStep4Controller.php b/src/Controller/Booking/CreateStep4Controller.php new file mode 100644 index 0000000..7040c75 --- /dev/null +++ b/src/Controller/Booking/CreateStep4Controller.php @@ -0,0 +1,64 @@ +getOrCreateBookingCreateDto($this->bookingService, $request); + if ($result instanceof Response) { + return $result; + } + $bookingCreateDto = $result; + + // Validate step access + if ($redirect = $this->validateStepAccess($bookingCreateDto, 4)) { + return $redirect; + } + + $form = $this->createForm(BookingCreateStep4Type::class, $bookingCreateDto); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + // TODO: Perform inquiry API call + // TODO: If inquiry successful, perform booking API call + // TODO: Clear session and redirect to success page + + $this->addFlash('success', 'Buchung erfolgreich abgeschlossen.'); + + return $this->redirectToRoute('app_booking_create_step_4'); + } + + return $this->render('booking/create_step_4.html.twig', [ + 'bookingCreateDto' => $bookingCreateDto, + 'form' => $form->createView(), + ...$this->getSummaryVariables($bookingCreateDto), + ]); + } +} \ No newline at end of file diff --git a/src/Form/BookingCreateStep4Type.php b/src/Form/BookingCreateStep4Type.php new file mode 100644 index 0000000..1120f4b --- /dev/null +++ b/src/Form/BookingCreateStep4Type.php @@ -0,0 +1,37 @@ +add('confirmationAccepted', CheckboxType::class, [ + 'label' => 'Ich bestätige, dass alle Angaben korrekt sind und möchte verbindlich buchen.', + 'mapped' => false, + 'constraints' => [ + new Assert\IsTrue( + message: 'Bitte bestätigen Sie Ihre Buchung.' + ), + ], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => BookingCreateDto::class, + ]); + } +} \ No newline at end of file diff --git a/templates/booking/create_step_4.html.twig b/templates/booking/create_step_4.html.twig new file mode 100644 index 0000000..30c0464 --- /dev/null +++ b/templates/booking/create_step_4.html.twig @@ -0,0 +1,173 @@ +{% extends 'layout.html.twig' %} + +{% block title %}Buchung bestätigen{% endblock %} + +{% block content %} + {% include '_partials/_flashes.html.twig' %} + +

Neue Buchung

+ +
+
+

Buchung bestätigen

+ + {# Travel Summary #} +
+

Reise

+
+
+
Reiseziel
+
{{ bookingCreateDto.travel.label }}
+
+
+
Zeitraum
+
{{ bookingCreateDto.travel.dateFrom|date('d.m.Y') }} - {{ bookingCreateDto.travel.dateTo|date('d.m.Y') }}
+
+
+
+ + {# Rooms Summary #} +
+

Zimmer / Unterkünfte

+ {% if pricingData.rooms is not empty %} +
    + {% for roomPricing in pricingData.rooms %} +
  • + {{ roomPricing.quantity }}x {{ roomPricing.label }} + {{ roomPricing.totalPrice|number_format(2, ',', '.') }} € +
  • + {% endfor %} +
+ {% endif %} +
+ + {# Participants Summary #} +
+

Teilnehmer ({{ participantsCount }})

+ {% for participant in bookingCreateDto.participants %} +
+

+ {{ participant.firstName }} {{ participant.lastName }} + {% if loop.first %}(Anmelder){% endif %} +

+ +
+ {% if participant.dateOfBirth %} +
+
Geburtsdatum
+
{{ participant.dateOfBirth|date('d.m.Y') }}
+
+ {% endif %} + {% if participant.email %} +
+
E-Mail
+
{{ participant.email }}
+
+ {% endif %} + {% if participant.mobile %} +
+
Telefon
+
{{ participant.mobile }}
+
+ {% endif %} + + {# Selected Services #} + {% set services = [] %} + {% if participant.board is not empty %} + {% for boardItem in participant.board %} + {% set services = services|merge(['Verpflegung: ' ~ boardItem.label]) %} + {% endfor %} + {% endif %} + {% if participant.skiPass %} + {% set services = services|merge(['Skipass: ' ~ participant.skiPass.label]) %} + {% endif %} + {% if participant.rentals is not empty %} + {% for rental in participant.rentals %} + {% set services = services|merge(['Ausrüstung: ' ~ rental.label]) %} + {% endfor %} + {% endif %} + {% if participant.courses is not empty %} + {% for course in participant.courses %} + {% set services = services|merge(['Kurs: ' ~ course.label]) %} + {% endfor %} + {% endif %} + {% if participant.additionalServices is not empty %} + {% for service in participant.additionalServices %} + {% set services = services|merge(['Service: ' ~ service.label]) %} + {% endfor %} + {% endif %} + {% if participant.insurance %} + {% set services = services|merge(['Versicherung: ' ~ participant.insurance.label]) %} + {% endif %} + + {% if services is not empty %} +
+
Gebuchte Leistungen
+
+
    + {% for service in services %} +
  • {{ service }}
  • + {% endfor %} +
+
+
+ {% endif %} +
+
+ {% endfor %} +
+ + {# Payment Summary #} +
+

Zahlungsart

+
+
+
Gewählte Zahlungsart
+
+ {% if bookingCreateDto.paymentMethod == constant('App\\BusProNet\\Constants::PAYMENT_METHOD_DEBIT') %} + Lastschrift (Einzugsermächtigungsverfahren) + {% else %} + Überweisung + {% endif %} +
+
+ {% if bookingCreateDto.paymentMethod == constant('App\\BusProNet\\Constants::PAYMENT_METHOD_DEBIT') and bookingCreateDto.bankAccount %} +
+
IBAN
+
{{ bookingCreateDto.bankAccount.iban }}
+
+
+
Kontoinhaber
+
{{ bookingCreateDto.bankAccount.accountHolder }}
+
+ {% endif %} +
+
+ + {# Confirmation Form #} + {{ form_start(form, {'attr': {'novalidate': 'novalidate'}}) }} + +
+ {{ form_row(form.confirmationAccepted, { + 'label_attr': {'class': 'text-base font-semibold'} + }) }} +
+ +
+ Zurück + +
+ + {{ form_end(form) }} +
+ +
+ {% include 'booking/_summary.html.twig' with { + 'bookingCreateDto': bookingCreateDto, + 'participantCount': participantsCount, + 'groupedSelectedRooms': groupedSelectedRooms, + 'assignmentCounts': assignmentCounts + } %} +
+
+{% endblock %} \ No newline at end of file