Files
myep/templates/booking/create/step_4.html.twig
T

598 lines
36 KiB
Twig

{% extends 'layout_booking.html.twig' %}
{% block title %}Bitte bestätige deine Buchung{% endblock %}
{% block content %}
{{ form_start(form, {
'attr': {
'class': 'flex-1 flex flex-col min-h-0',
'novalidate': 'novalidate'
}
}) }}
{# Pagination - mobile only #}
<div class="lg:hidden">
{% include 'booking/_pagination.html.twig' with { 'current_step': 4 } %}
</div>
<div class="flex-1 flex flex-col lg:grid lg:grid-cols-3 min-h-0 relative">
{# Sidebar with travel information #}
<div class="hidden lg:block order-2 lg:flex-1 lg:min-h-0 bg-white lg:border-l lg:border-primary-bg">
{# Header #}
<div class="shrink-0 px-4 lg:px-8 py-4 lg:flex lg:flex-col lg:justify-center shadow-md relative z-10">
<div class="flex items-center justify-between pb-2">
<span class="block uppercase font-semibold">Gesamtpreis</span>
<span class="font-semibold">{{ bookingCreateContext.summaryData.vouchers.payableAmount|format_currency('EUR') }}</span>
</div>
<div class="flex items-center justify-between">
<span class="block uppercase font-semibold">Buchungsübersicht</span>
</div>
</div>
{# Travel Information #}
<div class="overflow-y-auto px-4 lg:px-8 py-8">
<div class="pb-4">
<table>
<tr>
<th class="text-left align-top border-r-2 border-gray-300 pr-2">
Reise
</th>
<td class="pl-2">
{{ bookingCreateContext.bookingDto.travel.label }}
</td>
</tr>
<tr>
<th class="text-left align-top border-r-2 border-gray-300 pr-2">
Zeitraum
</th>
<td class="pl-2">
{{ bookingCreateContext.bookingDto.travel.dateFrom|date('d.m.Y') }} - {{ bookingCreateContext.bookingDto.travel.dateTo|date('d.m.Y') }}
</td>
</tr>
<tr>
<th class="text-left align-top border-r-2 border-gray-300 pr-2">
Unterkunft
</th>
<td class="pl-2">
{{ bookingCreateContext.bookingDto.travel.hotel.name }}
</td>
</tr>
<tr>
<th class="text-left align-top border-r-2 border-gray-300 pr-2">
Teilnehmer
</th>
<td class="pl-2">
{{ bookingCreateContext.summaryData.participantCount }}
</td>
</tr>
</table>
</div>
{% include 'booking/_summary_hotel.html.twig' with {
'summaryData': bookingCreateContext.summaryData
} %}
</div>
</div>
<div id="form-wrapper"
class="flex-1 order-1 lg:col-span-2 bg-white flex flex-col min-h-0">
{# Flash messages - must be inside form-wrapper for HTMX swap to display them #}
{% include '_partials/_flashes.html.twig' %}
{# Pagination - desktop only #}
<div class="hidden lg:block shrink-0">
{% include 'booking/_pagination.html.twig' with { 'current_step': 4 } %}
</div>
<div class="flex-1 overflow-y-auto px-4 lg:px-8 py-8">
<h2 class="pb-4">
Bitte bestätige deine Buchung
</h2>
{# Validation errors #}
{% from '_partials/_validation_errors.html.twig' import validation_alert %}
{{ validation_alert(form, 'Bitte bestätige deine Angaben und stimme den AGB zu', false) }}
{# Travel Information - mobile only #}
<div class="lg:hidden pb-4">
<table class="mb-4">
<tr>
<th class="text-left align-top border-r-2 border-gray-300 pr-2">
Reise
</th>
<td class="pl-2">
{{ bookingCreateContext.bookingDto.travel.label }}
</td>
</tr>
<tr>
<th class="text-left align-top border-r-2 border-gray-300 pr-2">
Zeitraum
</th>
<td class="pl-2">
{{ bookingCreateContext.bookingDto.travel.dateFrom|date('d.m.Y') }} - {{ bookingCreateContext.bookingDto.travel.dateTo|date('d.m.Y') }}
</td>
</tr>
<tr>
<th class="text-left align-top border-r-2 border-gray-300 pr-2">
Unterkunft
</th>
<td class="pl-2">
{{ bookingCreateContext.bookingDto.travel.hotel.name }}
</td>
</tr>
<tr>
<th class="text-left align-top border-r-2 border-gray-300 pr-2">
Teilnehmer
</th>
<td class="pl-2">
{{ bookingCreateContext.summaryData.participantCount }}
</td>
</tr>
</table>
{% include 'booking/_summary_hotel.html.twig' with {
'summaryData': bookingCreateContext.summaryData
} %}
</div>
{# Detailed Pricing Breakdown #}
<h3 class="text-xl font-semibold mb-4">
Preisübersicht
</h3>
{# Rooms Section #}
{% if bookingCreateContext.summaryData.pricing.rooms is not empty %}
<div class="border border-primary-bg mb-4">
<div class="p-2 bg-primary-bg uppercase font-semibold">
Unterkunft
</div>
<table class="w-full table-fixed">
{% for roomPricing in bookingCreateContext.summaryData.pricing.rooms %}
<tr>
<td class="p-2 align-top">
<div>{{ roomPricing.quantity }}x {{ roomPricing.label }}</div>
{% if bookingCreateContext.summaryData.pricing.assignmentCounts[roomPricing.roomId] is defined %}
<div class="text-sm text-gray-600">{{ bookingCreateContext.summaryData.pricing.assignmentCounts[roomPricing.roomId] }} Person(en) belegt</div>
{% endif %}
</td>
<td class="p-2 align-top w-24 text-right whitespace-nowrap">
{{ roomPricing.totalPrice|format_currency('EUR') }}
</td>
</tr>
{% endfor %}
</table>
</div>
{% endif %}
{# Services Section #}
{% if bookingCreateContext.summaryData.pricing.services is not empty %}
<div class="border border-primary-bg mb-4">
<div class="p-2 bg-primary-bg uppercase font-semibold">
Leistungen
</div>
{% for serviceGroup in bookingCreateContext.summaryData.pricing.services %}
<div class="p-2 text-primary-dark/70 uppercase font-semibold">
{{ serviceGroup.groupName }}
</div>
<table class="w-full table-fixed">
{% for servicePricing in serviceGroup.services %}
<tr>
<td class="px-2 pb-2 align-top">
{{ servicePricing.participantCount }}x {{ servicePricing.label }}
</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{{ servicePricing.totalPrice|format_currency('EUR') }}
</td>
</tr>
{% endfor %}
</table>
{% endfor %}
</div>
{% endif %}
{# Participants Summary #}
<h3 class="text-xl font-semibold mb-4">
Teilnehmer
</h3>
{% for participant in bookingCreateContext.bookingDto.participants %}
<div class="border border-primary-bg mb-4">
<div class="p-2 bg-primary-bg uppercase font-semibold flex justify-between items-center">
<span>
{{ participant.firstName }} {{ participant.lastName }}
{% if loop.first and not bookingCreateContext.bookingDto.isInternalAgencyBooking() %}<span class="text-sm font-normal">(Anmelder:in)</span>{% endif %}
</span>
{% if bookingCreateContext.participantPrices is defined and bookingCreateContext.participantPrices[loop.index0] is defined %}
<span>{{ bookingCreateContext.participantPrices[loop.index0]|format_currency('EUR') }}</span>
{% endif %}
</div>
{# Personal Data - responsive grid #}
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-2 p-2 text-sm">
{% if participant.dateOfBirth %}
<div>
<span class="text-gray-600 font-semibold">Geburtsdatum:</span>
{{ participant.dateOfBirth|date('d.m.Y') }}
</div>
{% endif %}
{% if participant.gender %}
<div>
<span class="text-gray-600 font-semibold">Geschlecht:</span>
{{ participant.gender == 'M' ? 'Männlich' : 'Weiblich' }}
</div>
{% endif %}
{% if participant.email %}
<div>
<span class="text-gray-600 font-semibold">E-Mail:</span>
{{ participant.email }}
</div>
{% endif %}
{% if participant.mobile %}
<div>
<span class="text-gray-600 font-semibold">Telefon:</span>
{{ participant.mobile }}
</div>
{% endif %}
{% if participant.nationality %}
<div>
<span class="text-gray-600 font-semibold">Nationalität:</span>
{{ participant.nationality }}
</div>
{% endif %}
{% if participant.address and (participant.address.street or participant.address.city) %}
<div>
<span class="text-gray-600 font-semibold">Adresse:</span>
{% if participant.address.street %}{{ participant.address.street }}, {% endif %}
{% if participant.address.postCode or participant.address.city %}
{{ participant.address.postCode }} {{ participant.address.city }}
{% endif %}
{% if participant.address.country %}, {{ participant.address.country }}{% endif %}
</div>
{% endif %}
</div>
{# Unterkunft Section #}
{% set assignedRoom = bookingCreateContext.bookingDto.travel.getRoomById(participant.assignedRoomId) %}
{% if assignedRoom or participant.remarksRoom %}
<div class="px-2 py-1 text-primary-dark/70 text-sm uppercase font-semibold">
Unterkunft
</div>
<table class="w-full table-fixed text-sm">
{% if assignedRoom %}
<tr>
<td class="px-2 pb-2 align-top">{{ assignedRoom.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if assignedRoom.price is not null and assignedRoom.price != 0 %}
{{ assignedRoom.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endif %}
{% if participant.remarksRoom %}
<tr>
<td class="px-2 pb-2 align-top text-gray-600" colspan="2">Wunsch: {{ participant.remarksRoom }}</td>
</tr>
{% endif %}
</table>
{% endif %}
{# An-/Abreise Section #}
{% if participant.hasTransportationData() %}
<div class="px-2 py-1 text-primary-dark/70 text-sm uppercase font-semibold">
An-/Abreise
</div>
<table class="w-full table-fixed text-sm">
{% if participant.transportationOutbound %}
<tr>
<td class="px-2 pb-2 align-top">Hinfahrt: {{ participant.transportationOutbound.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if participant.transportationOutbound.price is not null and participant.transportationOutbound.price != 0 %}
{{ participant.transportationOutbound.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endif %}
{% if participant.transportationInbound %}
<tr>
<td class="px-2 pb-2 align-top">Rückfahrt: {{ participant.transportationInbound.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if participant.transportationInbound.price is not null and participant.transportationInbound.price != 0 %}
{{ participant.transportationInbound.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endif %}
{% if participant.pickup %}
<tr>
<td class="px-2 pb-2 align-top">Zustieg: {{ participant.pickup.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if participant.pickup.price is not null and participant.pickup.price != 0 %}
{{ participant.pickup.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endif %}
{% if participant.dropOff %}
<tr>
<td class="px-2 pb-2 align-top">Ausstieg: {{ participant.dropOff.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if participant.dropOff.price is not null and participant.dropOff.price != 0 %}
{{ participant.dropOff.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endif %}
{% if participant.parking %}
<tr>
<td class="px-2 pb-2 align-top">Parkplatz</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if participant.parkingService is not null and participant.parkingService.price is not null and participant.parkingService.price != 0 %}
{{ participant.parkingService.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endif %}
{% if participant.licensePlate %}
<tr>
<td class="px-2 pb-2 align-top text-gray-600" colspan="2">Kennzeichen: {{ participant.licensePlate }}</td>
</tr>
{% endif %}
</table>
{% endif %}
{# Verpflegung Section #}
{% if participant.board is not empty %}
<div class="px-2 py-1 text-primary-dark/70 text-sm uppercase font-semibold">
Verpflegung
</div>
<table class="w-full table-fixed text-sm">
{% for boardItem in participant.board %}
<tr>
<td class="px-2 pb-2 align-top">{{ boardItem.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if boardItem.price is not null and boardItem.price != 0 %}
{{ boardItem.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
{# Skipass Section #}
{% if participant.skiPass %}
<div class="px-2 py-1 text-primary-dark/70 text-sm uppercase font-semibold">
Skipass
</div>
<table class="w-full table-fixed text-sm">
<tr>
<td class="px-2 pb-2 align-top">{{ participant.skiPass.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if participant.skiPass.price is not null and participant.skiPass.price != 0 %}
{{ participant.skiPass.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
</table>
{% endif %}
{# Leihmaterial Section #}
{% if participant.rentals is not empty or (participant.rentalInsuranceSelected and participant.rentalInsurance) %}
<div class="px-2 py-1 text-primary-dark/70 text-sm uppercase font-semibold">
Leihmaterial
</div>
<table class="w-full table-fixed text-sm">
{% for rental in participant.rentals %}
<tr>
<td class="px-2 pb-2 align-top">{{ rental.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if rental.price is not null and rental.price != 0 %}
{{ rental.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endfor %}
{% if participant.rentalInsuranceSelected and participant.rentalInsurance %}
<tr>
<td class="px-2 pb-2 align-top">{{ participant.rentalInsurance.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if participant.rentalInsurance.price is not null and participant.rentalInsurance.price != 0 %}
{{ participant.rentalInsurance.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endif %}
{% if participant.rentals is not empty and (participant.height or participant.weight or participant.shoeSize) %}
<tr>
<td class="px-2 pb-2 align-top text-gray-600" colspan="2">
{% if participant.height %}Größe: {{ participant.height }} cm{% endif %}
{% if participant.weight %}{% if participant.height %}, {% endif %}Gewicht: {{ participant.weight }} kg{% endif %}
{% if participant.shoeSize %}{% if participant.height or participant.weight %}, {% endif %}Schuhgröße: {{ participant.shoeSize }}{% endif %}
</td>
</tr>
{% endif %}
</table>
{% endif %}
{# Kurse Section #}
{% if participant.courses is not empty %}
<div class="px-2 py-1 text-primary-dark/70 text-sm uppercase font-semibold">
Kurse
</div>
<table class="w-full table-fixed text-sm">
{% for course in participant.courses %}
<tr>
<td class="px-2 pb-2 align-top">{{ course.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if course.price is not null and course.price != 0 %}
{{ course.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
{# Zusatzleistungen Section #}
{% if participant.additionalServices is not empty %}
<div class="px-2 py-1 text-primary-dark/70 text-sm uppercase font-semibold">
Zusatzleistungen
</div>
<table class="w-full table-fixed text-sm">
{% for service in participant.additionalServices %}
<tr>
<td class="px-2 pb-2 align-top">{{ service.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if service.price is not null and service.price != 0 %}
{{ service.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
{# Reiseversicherung Section #}
{% if participant.insurance %}
<div class="px-2 py-1 text-primary-dark/70 text-sm uppercase font-semibold">
Reiseversicherung
</div>
<table class="w-full table-fixed text-sm">
<tr>
<td class="px-2 pb-2 align-top">{{ participant.insurance.label }}</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{% if participant.insurance.price is not null and participant.insurance.price != 0 %}
{{ participant.insurance.price|format_currency('EUR') }}
{% endif %}
</td>
</tr>
</table>
{% endif %}
</div>
{% endfor %}
{# Grand Total #}
{% if bookingCreateContext.summaryData.pricing.grandTotal > 0 %}
{% set acceptedVouchers = bookingCreateContext.summaryData.vouchers.acceptedVouchers %}
{% if acceptedVouchers and acceptedVouchers.hasVouchers() %}
<div class="border border-primary-bg mb-4">
<div class="p-2 bg-primary-bg uppercase font-semibold">
Kostenübersicht
</div>
<table class="w-full table-fixed">
<tr>
<td class="px-2 pb-2 align-top">
Gesamtpreis
</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
{{ bookingCreateContext.summaryData.pricing.grandTotal|format_currency('EUR') }}
</td>
</tr>
{% for voucher in acceptedVouchers.vouchers %}
<tr>
<td class="px-2 pb-2 align-top">
{% if voucher.promotional %}
Aktionsgutschein ({{ voucher.code }})
{% elseif voucher.goodwill %}
Kulanzgutschein ({{ voucher.code }})
{% elseif voucher.purchase %}
Kaufgutschein ({{ voucher.code }})
{% endif %}
</td>
<td class="px-2 pb-2 align-top w-24 text-right whitespace-nowrap">
- {{ voucher.amount|format_currency('EUR') }}
</td>
</tr>
{% endfor %}
</table>
</div>
<div class="flex items-center justify-between px-2 pb-4">
<span class="block uppercase font-semibold">Zu zahlen</span>
<span class="font-semibold">{{ bookingCreateContext.summaryData.vouchers.payableAmount|format_currency('EUR') }}</span>
</div>
{% else %}
<div class="flex items-center justify-between pb-4">
<span class="block uppercase font-semibold">Gesamtpreis</span>
<span class="font-semibold">{{ bookingCreateContext.summaryData.pricing.grandTotal|format_currency('EUR') }}</span>
</div>
{% endif %}
{% endif %}
{# Payment Summary #}
<div class="border border-primary-bg mb-4">
<div class="p-2 bg-primary-bg uppercase font-semibold">
Zahlungsart
</div>
<table class="w-full table-fixed text-sm">
<tr>
<td class="p-2 align-top">
{% if bookingCreateContext.bookingDto.paymentMethod == constant('App\\BusProNet\\Constants::PAYMENT_METHOD_DEBIT') %}
Lastschrift (Einzugsermächtigungsverfahren)
{% else %}
Überweisung
{% endif %}
</td>
</tr>
{% if bookingCreateContext.bookingDto.paymentMethod == constant('App\\BusProNet\\Constants::PAYMENT_METHOD_DEBIT') and bookingCreateContext.bookingDto.bankAccount %}
<tr>
<td class="p-2 align-top">
<span class="text-gray-600 font-semibold">IBAN:</span>
<span class="font-mono">{{ bookingCreateContext.bookingDto.bankAccount.iban }}</span>
</td>
</tr>
<tr>
<td class="p-2 align-top">
<span class="text-gray-600 font-semibold">Kontoinhaber:</span>
{{ bookingCreateContext.bookingDto.bankAccount.accountHolder }}
</td>
</tr>
{% endif %}
</table>
</div>
{# Confirmation Checkboxes #}
<div class="border border-primary-bg">
<div class="p-2 bg-primary-bg uppercase font-semibold">
Bestätigung
</div>
<div class="p-4">
{% if form.newsletterOptIn is defined and newsletterOptInVisible and newsletterTargetEmail %}
{{ form_row(form.newsletterOptIn, {
'label_attr': {'class': 'text-base font-semibold'}
}) }}
{% endif %}
{{ form_row(form.confirmationAccepted, {
'label_attr': {'class': 'text-base font-semibold'}
}) }}
{{ form_row(form.termsAccepted, {
'label_attr': {'class': 'text-base font-semibold'}
}) }}
</div>
</div>
</div>
</div>
</div>
<div class="shrink-0 bg-primary-dark px-4 lg:px-8 py-2 lg:py-4 z-20">
<div class="flex justify-between" hx-disinherit="*">
{% include '_partials/_cancel_button.html.twig' %}
<div class="flex items-center gap-2">
<a href="{{ path('app_booking_create_step_3') }}"
class="button button--secondary"
{{ qa_attribute('btn-back') }}>
Zurück
</a>
<button type="submit" class="button button--primary" {{ qa_attribute('btn-submit') }}>
{% if bookingCreateContext.bookingDto.bookingStatus == 'A' %}
Anfragen
{% else %}
Verbindlich buchen
{% endif %}
</button>
</div>
</div>
</div>
{{ form_rest(form) }}
{{ form_end(form) }}
{% endblock %}
{% block data_layer %}
{% include '_partials/_tracking.html.twig' with {
'url': '/trichter_Z1/schritt4_uerbersicht_bestaetigung',
'title': 'Übersicht und Bestätigung'
} %}
{% endblock %}