feat: split nights off an accommodation booking as separate periods

addresses #869f6z36v
This commit is contained in:
fromme committed 2026-09-30 18:06:20 +02:00
1 parent 972839286c
commit 7001bc0cf2
35 files changed
+2221 -25

No files matched your search

@@ -41,6 +41,48 @@
{{ form_row(form.minorsCount) }}
{{ form_row(form.childrenCount) }}
{# Saved by their own modals, which reprice the booking on the spot — see SplitPeriodController. #}
<div class="lg:col-span-2">
<h3 class="font-bold pb-1">Zeiträume</h3>
<p class="text-xs text-gray-500 pb-2">
Anreise und Abreise umfassen den ganzen Aufenthalt. Abgeteilte Zeiträume, etwa für ein
Vorausteam, werden mit eigenen Positionen berechnet; Personen und Leistungen oben gelten
nur für den Zeitraum der Gruppe.
</p>
<table class="w-full text-sm">
{% if booking.leadingPeriod %}
{% set p = booking.leadingPeriod %}
{{ block('period_row') }}
{% endif %}
<tr class="border-t border-gray-200">
<td class="py-1 whitespace-nowrap">{{ booking.mainDateFrom | date('d.m.Y') }} – {{ booking.mainDateTo | date('d.m.Y') }}</td>
<td class="py-1 whitespace-nowrap">{{ booking.mainNights }} {{ booking.mainNights != 1 ? 'Nächte' : 'Nacht' }}</td>
<td class="py-1" colspan="2">Gruppe</td>
<td class="py-1 text-right">
{# One period per side, so only the free sides are offered. #}
{% if booking.leadingPeriod is null or booking.trailingPeriod is null %}
<twig:dropdown>
{% if booking.leadingPeriod is null %}
<twig:dropdown:hxbutton url="{{ path('app_admin_accommodationbooking_period_split', back_params | merge({ position: 'leading' })) }}">
am Anfang abteilen
</twig:dropdown:hxbutton>
{% endif %}
{% if booking.trailingPeriod is null %}
<twig:dropdown:hxbutton url="{{ path('app_admin_accommodationbooking_period_split', back_params | merge({ position: 'trailing' })) }}">
am Ende abteilen
</twig:dropdown:hxbutton>
{% endif %}
</twig:dropdown>
{% endif %}
</td>
</tr>
{% if booking.trailingPeriod %}
{% set p = booking.trailingPeriod %}
{{ block('period_row') }}
{% endif %}
</table>
</div>
{% if form.boardService is defined or form.selectedAdditionalServices is defined %}
<h2 class="lg:col-span-2 text-base font-bold pt-2">Leistungen</h2>
{% if form.boardService is defined %}
@@ -98,3 +140,37 @@
{{ form_rest(form) }}
{{ form_end(form) }}
{% endblock %}
{% block period_row %}
{% set period_params = { id: p.id } %}
{% if app.request.query.get('r') %}
{% set period_params = period_params | merge({ r: app.request.query.get('r') }) %}
{% endif %}
<tr class="border-t border-gray-200 align-top">
<td class="py-1 whitespace-nowrap">{{ p.dateFrom | date('d.m.Y') }} – {{ p.dateTo | date('d.m.Y') }}</td>
<td class="py-1 whitespace-nowrap">{{ p.nights }} {{ p.nights != 1 ? 'Nächte' : 'Nacht' }}</td>
<td class="py-1">
{% if p.label %}
<div class="font-medium">{{ p.label }}</div>
{% endif %}
{% for line in p.lines %}
<div>{{ line.label }}</div>
{% else %}
<div class="text-gray-500">keine Positionen</div>
{% endfor %}
</td>
<td class="py-1 text-right whitespace-nowrap">
{{ (p.total / 100) | format_currency(booking.pricingCurrency ?? booking.accommodation.currency) }}
</td>
<td class="py-1 text-right">
<twig:dropdown>
<twig:dropdown:hxbutton url="{{ path('app_admin_accommodationbooking_period_edit', period_params) }}">
bearbeiten
</twig:dropdown:hxbutton>
<twig:dropdown:hxbutton url="{{ path('app_admin_accommodationbooking_period_remove', period_params) }}" warning>
entfernen
</twig:dropdown:hxbutton>
</twig:dropdown>
</td>
</tr>
{% endblock %}