wip: group inquiries and bookings
This commit is contained in:
1 parent
6a6051e92b
commit
505bda46cf
115 files changed
+8107
-424
No files matched your search
@@ -8,7 +8,6 @@
|
||||
</div>
|
||||
{{ form_row(form.calendarCode) }}
|
||||
{{ form_row(form.cmsCode) }}
|
||||
{{ form_row(form.minPaxSummer) }}
|
||||
{{ form_row(form.maxAdolescentAge) }}
|
||||
{{ form_row(form.currency) }}
|
||||
</div>
|
||||
@@ -54,118 +53,128 @@
|
||||
|
||||
<hr class="my-8">
|
||||
|
||||
<h2 class="text-xl font-bold">
|
||||
Preise
|
||||
</h2>
|
||||
<div class="data-table-wrapper mb-4">
|
||||
<div class="data-table-wrapper__inner text-sm">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
von
|
||||
</th>
|
||||
<th>
|
||||
bis
|
||||
</th>
|
||||
<th>
|
||||
Typ
|
||||
</th>
|
||||
<th>
|
||||
Saison
|
||||
</th>
|
||||
<th>
|
||||
Pax bis
|
||||
</th>
|
||||
<th>
|
||||
Mindestmiete pro Nacht
|
||||
</th>
|
||||
<th>
|
||||
weitere Personen pro Nacht
|
||||
</th>
|
||||
<th>
|
||||
Unterbelegung
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for price in accommodation.accommodationPrices %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ price.dateFrom | date('d.m.Y') }}
|
||||
</td>
|
||||
<td>
|
||||
{{ price.dateTo | date('d.m.Y') }}
|
||||
</td>
|
||||
<td>
|
||||
{% if price.type is not null %}
|
||||
{% if price.type.value == 'discount' %}
|
||||
{{ icon('discount', 'w-5 h-5') }}
|
||||
{% elseif price.type.value == 'override' %}
|
||||
{{ icon('stack', 'w-5 h-5') }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ price.season.token | trans }}
|
||||
</td>
|
||||
<td>
|
||||
{{ price.includedPax }}
|
||||
</td>
|
||||
<td>
|
||||
{{ (price.pricePerNight / 100) | format_currency(accommodation.currency) }}
|
||||
</td>
|
||||
<td>
|
||||
{{ (price.priceAdditionalPerson / 100) | format_currency(accommodation.currency) }}
|
||||
</td>
|
||||
<td>
|
||||
{% if price.acceptUndersubscription %}
|
||||
{{ icon('check', 'w-4 h-4') }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<twig:dropdown>
|
||||
<twig:dropdown:link url="{{ path('app_admin_accommodationprice_edit', { 'id': price.id }) }}">
|
||||
bearbeiten
|
||||
</twig:dropdown:link>
|
||||
<twig:dropdown:link url="{{ path('app_admin_accommodationprice_duplicate', { 'id': price.id }) }}">
|
||||
duplizieren
|
||||
</twig:dropdown:link>
|
||||
<twig:dropdown:hxbutton url="{{ path('app_admin_accommodationprice_delete', { 'id': price.id }) }}" warning>
|
||||
löschen
|
||||
</twig:dropdown:hxbutton>
|
||||
</twig:dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="7" class="text-center">
|
||||
Keine Daten
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<a href="{{ path('app_admin_accommodationprice_create', { 'id': accommodation.id }) }}" class="button button--primary button--small">
|
||||
neu
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr class="my-8">
|
||||
|
||||
<h2 class="text-xl font-bold">
|
||||
Verpflegungsleistungen
|
||||
</h2>
|
||||
<div class="data-table-wrapper mb-4">
|
||||
<section id="prices">
|
||||
<h2 class="text-xl font-bold">
|
||||
Preise
|
||||
</h2>
|
||||
<div class="data-table-wrapper mb-4">
|
||||
<div class="data-table-wrapper__inner text-sm">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
von
|
||||
</th>
|
||||
<th>
|
||||
bis
|
||||
</th>
|
||||
<th>
|
||||
Typ
|
||||
</th>
|
||||
<th>
|
||||
Saison
|
||||
</th>
|
||||
<th>
|
||||
Pax bis
|
||||
</th>
|
||||
<th>
|
||||
Mindestmiete pro Nacht
|
||||
</th>
|
||||
<th>
|
||||
weitere Personen pro Nacht
|
||||
</th>
|
||||
<th>
|
||||
Unterbel.
|
||||
</th>
|
||||
<th>
|
||||
Kurzzeit
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for price in accommodation.accommodationPrices %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ price.dateFrom | date('d.m.Y') }}
|
||||
</td>
|
||||
<td>
|
||||
{{ price.dateTo | date('d.m.Y') }}
|
||||
</td>
|
||||
<td>
|
||||
{% if price.type is not null %}
|
||||
{% if price.type.value == 'discount' %}
|
||||
{{ icon('discount', 'w-5 h-5') }}
|
||||
{% elseif price.type.value == 'override' %}
|
||||
{{ icon('stack', 'w-5 h-5') }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{{ price.season.token | trans }}
|
||||
</td>
|
||||
<td>
|
||||
{{ price.includedPax }}
|
||||
</td>
|
||||
<td>
|
||||
{{ (price.pricePerNight / 100) | format_currency(accommodation.currency) }}
|
||||
</td>
|
||||
<td>
|
||||
{{ (price.priceAdditionalPerson / 100) | format_currency(accommodation.currency) }}
|
||||
</td>
|
||||
<td>
|
||||
{% if price.acceptUndersubscription %}
|
||||
{{ icon('check', 'w-4 h-4') }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if price.acceptShortterm %}
|
||||
{{ icon('check', 'w-4 h-4') }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<twig:dropdown>
|
||||
<twig:dropdown:link url="{{ path('app_admin_accommodationprice_edit', { 'id': price.id }) }}">
|
||||
bearbeiten
|
||||
</twig:dropdown:link>
|
||||
<twig:dropdown:link url="{{ path('app_admin_accommodationprice_duplicate', { 'id': price.id }) }}">
|
||||
duplizieren
|
||||
</twig:dropdown:link>
|
||||
<twig:dropdown:hxbutton url="{{ path('app_admin_accommodationprice_delete', { 'id': price.id }) }}" warning>
|
||||
löschen
|
||||
</twig:dropdown:hxbutton>
|
||||
</twig:dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="7" class="text-center">
|
||||
Keine Daten
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<a href="{{ path('app_admin_accommodationprice_create', { 'id': accommodation.id }) }}" class="button button--primary button--small">
|
||||
neu
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="my-8">
|
||||
|
||||
<section id="board-services">
|
||||
<h2 class="text-xl font-bold">
|
||||
Verpflegungsleistungen
|
||||
</h2>
|
||||
<div class="data-table-wrapper mb-4">
|
||||
<div class="data-table-wrapper__inner text-sm">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Datums-Bereich
|
||||
</th>
|
||||
@@ -178,18 +187,14 @@
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-controller="sortable" data-sortable-url-value="{{ path('app_admin_boardservice_sort', { 'id': accommodation.id }) }}">
|
||||
<tbody>
|
||||
{% for service in accommodation.boardServices %}
|
||||
<tr data-sortable-target="item">
|
||||
<td class="cursor-grab w-6" data-sortable-target="handle">
|
||||
{{ icon('draggable', 'w-4 h-4') }}
|
||||
</td>
|
||||
<tr>
|
||||
<td>
|
||||
{{ service.dateFrom | date('d.m.Y') }} - {{ service.dateTo | date('d.m.Y') }}
|
||||
</td>
|
||||
<td>
|
||||
{{ service.label }}
|
||||
<input type="hidden" name="sorting[{{ service.id }}]" value="{{ loop.index }}" data-sortable-target="positionField" data-id="{{ service.id }}">
|
||||
</td>
|
||||
<td>
|
||||
{{ (service.price / 100) | format_currency(accommodation.currency) }}
|
||||
@@ -210,7 +215,7 @@
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">
|
||||
<td colspan="4" class="text-center">
|
||||
Keine Daten
|
||||
</td>
|
||||
</tr>
|
||||
@@ -224,79 +229,77 @@
|
||||
neu
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="my-8">
|
||||
|
||||
<h2 class="text-xl font-bold">
|
||||
Optionale Zusatzleistungen
|
||||
</h2>
|
||||
<div class="data-table-wrapper mb-4">
|
||||
<div class="data-table-wrapper__inner text-sm">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>
|
||||
Datums-Bereich
|
||||
</th>
|
||||
<th>
|
||||
Bezeichnung
|
||||
</th>
|
||||
<th>
|
||||
Preistyp
|
||||
</th>
|
||||
<th>
|
||||
Preis
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-controller="sortable" data-sortable-url-value="{{ path('app_admin_additionalservice_sort', { 'id': accommodation.id }) }}">
|
||||
{% for service in accommodation.additionalServices %}
|
||||
<tr data-sortable-target="item">
|
||||
<td class="cursor-grab w-6" data-sortable-target="handle">
|
||||
{{ icon('draggable', 'w-4 h-4') }}
|
||||
</td>
|
||||
<td>
|
||||
{{ service.dateFrom | date('d.m.Y') }} - {{ service.dateTo | date('d.m.Y') }}
|
||||
</td>
|
||||
<td>
|
||||
{{ service.label }}
|
||||
<input type="hidden" name="sorting[{{ service.id }}]" value="{{ loop.index }}" data-sortable-target="positionField" data-id="{{ service.id }}">
|
||||
</td>
|
||||
<td>
|
||||
{{ service.type.label | trans }}
|
||||
</td>
|
||||
<td>
|
||||
{{ (service.price / 100) | format_currency(accommodation.currency) }}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<twig:dropdown>
|
||||
<twig:dropdown:link url="{{ path('app_admin_additionalservice_edit', { 'id': service.id }) }}">
|
||||
bearbeiten
|
||||
</twig:dropdown:link>
|
||||
<twig:dropdown:link url="{{ path('app_admin_additionalservice_duplicate', { 'id': service.id }) }}">
|
||||
duplizieren
|
||||
</twig:dropdown:link>
|
||||
<twig:dropdown:hxbutton url="{{ path('app_admin_additionalservice_delete', { 'id': service.id }) }}" warning>
|
||||
löschen
|
||||
</twig:dropdown:hxbutton>
|
||||
</twig:dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<section id="additional-services">
|
||||
<h2 class="text-xl font-bold">
|
||||
Optionale Zusatzleistungen
|
||||
</h2>
|
||||
<div class="data-table-wrapper mb-4">
|
||||
<div class="data-table-wrapper__inner text-sm">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center">
|
||||
Keine Daten
|
||||
</td>
|
||||
<th>
|
||||
Datums-Bereich
|
||||
</th>
|
||||
<th>
|
||||
Bezeichnung
|
||||
</th>
|
||||
<th>
|
||||
Preistyp
|
||||
</th>
|
||||
<th>
|
||||
Preis
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for service in accommodation.additionalServices %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ service.dateFrom | date('d.m.Y') }} - {{ service.dateTo | date('d.m.Y') }}
|
||||
</td>
|
||||
<td>
|
||||
{{ service.label }}
|
||||
</td>
|
||||
<td>
|
||||
{{ service.type.label | trans }}
|
||||
</td>
|
||||
<td>
|
||||
{{ (service.price / 100) | format_currency(accommodation.currency) }}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<twig:dropdown>
|
||||
<twig:dropdown:link url="{{ path('app_admin_additionalservice_edit', { 'id': service.id }) }}">
|
||||
bearbeiten
|
||||
</twig:dropdown:link>
|
||||
<twig:dropdown:link url="{{ path('app_admin_additionalservice_duplicate', { 'id': service.id }) }}">
|
||||
duplizieren
|
||||
</twig:dropdown:link>
|
||||
<twig:dropdown:hxbutton url="{{ path('app_admin_additionalservice_delete', { 'id': service.id }) }}" warning>
|
||||
löschen
|
||||
</twig:dropdown:hxbutton>
|
||||
</twig:dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">
|
||||
Keine Daten
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<a href="{{ path('app_admin_additionalservice_create', { 'id': accommodation.id }) }}" class="button button--primary button--small">
|
||||
neu
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<a href="{{ path('app_admin_additionalservice_create', { 'id': accommodation.id }) }}" class="button button--primary button--small">
|
||||
neu
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
@@ -26,7 +26,9 @@
|
||||
{% for accommodation in accommodations %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ accommodation.name }}
|
||||
<a href="{{ path('app_admin_accommodation_edit', { 'id': accommodation.id, 'r': return_url() }) }}">
|
||||
{{ accommodation.name }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ accommodation.calendarCode }}
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
{{ form_start(form) }}
|
||||
<div class="grid lg:grid-cols-2 gap-y-4 lg:gap-x-8">
|
||||
{{ form_row(form.name) }}
|
||||
{{ form_row(form.code) }}
|
||||
{{ form_row(form.minPaxSummer) }}
|
||||
{{ form_row(form.calendarCode) }}
|
||||
{{ form_row(form.maxAdolescentAge) }}
|
||||
{{ form_row(form.currency) }}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
{% extends 'layout_admin.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<twig:page:heading>Neue Buchung</twig:page:heading>
|
||||
|
||||
{% form_theme form 'forms_admin.html.twig' %}
|
||||
|
||||
{{ form_start(form) }}
|
||||
<div class="grid lg:grid-cols-2 gap-y-4 lg:gap-x-8">
|
||||
<div class="lg:col-span-2">
|
||||
{{ form_row(form.accommodation) }}
|
||||
</div>
|
||||
|
||||
<h2 class="lg:col-span-2 text-base font-bold pt-2">Kontaktdaten</h2>
|
||||
{{ form_row(form.groupName) }}
|
||||
{{ form_row(form.salutation) }}
|
||||
{{ form_row(form.firstName) }}
|
||||
{{ form_row(form.lastName) }}
|
||||
{{ form_row(form.email) }}
|
||||
{{ form_row(form.phone) }}
|
||||
{{ form_row(form.street) }}
|
||||
{{ form_row(form.zip) }}
|
||||
{{ form_row(form.city) }}
|
||||
|
||||
<h2 class="lg:col-span-2 text-base font-bold pt-2">Reisedaten</h2>
|
||||
{{ form_row(form.dateFrom) }}
|
||||
{{ form_row(form.dateTo) }}
|
||||
{{ form_row(form.paxCount) }}
|
||||
{{ form_row(form.minorsCount) }}
|
||||
{{ form_row(form.childrenCount) }}
|
||||
|
||||
<h2 class="lg:col-span-2 text-base font-bold pt-2">Status & Rabatt</h2>
|
||||
<div class="lg:col-span-2">
|
||||
{{ form_row(form.isInquiry) }}
|
||||
</div>
|
||||
{{ form_row(form.discount) }}
|
||||
<div class="lg:col-span-2">
|
||||
{{ form_row(form.remarks) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between pt-8">
|
||||
<a href="{{ path('app_admin_accommodationbooking') }}" class="button button--secondary button--small">
|
||||
zurück
|
||||
</a>
|
||||
<button type="submit" class="button button--primary button--small">
|
||||
speichern
|
||||
</button>
|
||||
</div>
|
||||
{{ form_rest(form) }}
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,60 @@
|
||||
{% extends 'layout_admin.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<twig:page:heading>Buchung {{ booking.groupName }}</twig:page:heading>
|
||||
<p class="text-sm text-gray-500 mb-6">{{ booking.accommodation.name }}</p>
|
||||
|
||||
{% form_theme form 'forms_admin.html.twig' %}
|
||||
|
||||
{{ form_start(form) }}
|
||||
<div class="grid lg:grid-cols-2 gap-y-4 lg:gap-x-8">
|
||||
<h2 class="lg:col-span-2 text-base font-bold">Kontaktdaten</h2>
|
||||
{{ form_row(form.groupName) }}
|
||||
{{ form_row(form.salutation) }}
|
||||
{{ form_row(form.firstName) }}
|
||||
{{ form_row(form.lastName) }}
|
||||
{{ form_row(form.email) }}
|
||||
{{ form_row(form.phone) }}
|
||||
{{ form_row(form.street) }}
|
||||
{{ form_row(form.zip) }}
|
||||
{{ form_row(form.city) }}
|
||||
|
||||
<h2 class="lg:col-span-2 text-base font-bold pt-2">Reisedaten</h2>
|
||||
{{ form_row(form.dateFrom) }}
|
||||
{{ form_row(form.dateTo) }}
|
||||
{{ form_row(form.paxCount) }}
|
||||
{{ form_row(form.minorsCount) }}
|
||||
{{ form_row(form.childrenCount) }}
|
||||
|
||||
{% 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 %}
|
||||
{{ form_row(form.boardService) }}
|
||||
{% endif %}
|
||||
{% if form.selectedAdditionalServices is defined %}
|
||||
<div class="lg:col-span-2">
|
||||
{{ form_row(form.selectedAdditionalServices) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<h2 class="lg:col-span-2 text-base font-bold pt-2">Status & Rabatt</h2>
|
||||
<div class="lg:col-span-2">
|
||||
{{ form_row(form.isInquiry) }}
|
||||
</div>
|
||||
{{ form_row(form.discount) }}
|
||||
<div class="lg:col-span-2">
|
||||
{{ form_row(form.remarks) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between pt-8">
|
||||
<a href="{{ path('app_admin_accommodationbooking_show', { 'id': booking.id }) }}" class="button button--secondary button--small">
|
||||
zurück
|
||||
</a>
|
||||
<button type="submit" class="button button--primary button--small">
|
||||
speichern
|
||||
</button>
|
||||
</div>
|
||||
{{ form_rest(form) }}
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,94 @@
|
||||
{% extends 'layout_admin.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<twig:page:heading>Buchungen & Anfragen</twig:page:heading>
|
||||
<div class="data-table-wrapper">
|
||||
<div class="data-table-wrapper__inner text-sm">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
{{ knp_pagination_sortable(pagination, 'Eingang', 'booking.createdAt') }}
|
||||
</th>
|
||||
<th>
|
||||
{{ knp_pagination_sortable(pagination, 'Gruppenhaus', 'accommodation.name') }}
|
||||
</th>
|
||||
<th>
|
||||
{{ knp_pagination_sortable(pagination, 'Gruppe', 'booking.groupName') }}
|
||||
</th>
|
||||
<th>
|
||||
{{ knp_pagination_sortable(pagination, 'Anreise', 'booking.dateFrom') }}
|
||||
</th>
|
||||
<th>
|
||||
Personen
|
||||
</th>
|
||||
<th>
|
||||
Status
|
||||
</th>
|
||||
<th>
|
||||
Rabatt
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for booking in pagination %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ booking.createdAt | date('d.m.Y, H:i') }}
|
||||
</td>
|
||||
<td>
|
||||
{{ booking.accommodation.name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ booking.groupName }}
|
||||
</td>
|
||||
<td>
|
||||
{{ booking.dateFrom | date('d.m.Y') }} – {{ booking.dateTo | date('d.m.Y') }}
|
||||
</td>
|
||||
<td>
|
||||
{{ booking.paxCount }}
|
||||
</td>
|
||||
<td>
|
||||
{% if booking.isInquiry %}
|
||||
Anfrage
|
||||
{% else %}
|
||||
Buchung
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if booking.discount is not null %}
|
||||
{{ booking.discount }} %
|
||||
{% else %}
|
||||
–
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<twig:dropdown>
|
||||
<twig:dropdown:link url="{{ path('app_admin_accommodationbooking_show', { 'id': booking.id, 'r': return_url() }) }}">
|
||||
Details
|
||||
</twig:dropdown:link>
|
||||
<twig:dropdown:link url="{{ path('app_admin_accommodationbooking_edit', { 'id': booking.id }) }}">
|
||||
bearbeiten
|
||||
</twig:dropdown:link>
|
||||
</twig:dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="8">
|
||||
Keine Daten...
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ knp_pagination_render(pagination) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<a href="{{ path('app_admin_accommodationbooking_create') }}" class="button button--primary button--small">
|
||||
neu
|
||||
</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,200 @@
|
||||
{% extends 'layout_admin.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<twig:page:heading>
|
||||
{% if booking.isInquiry %}Anfrage{% else %}Buchung{% endif %}
|
||||
{{ booking.groupName }}
|
||||
</twig:page:heading>
|
||||
|
||||
<div class="grid lg:grid-cols-2 gap-8">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold mb-4">Kontakt</h2>
|
||||
<dl class="grid grid-cols-2 gap-y-2 text-sm">
|
||||
<dt class="font-medium">Gruppenname</dt>
|
||||
<dd>{{ booking.groupName }}</dd>
|
||||
<dt class="font-medium">Anrede</dt>
|
||||
<dd>{{ booking.salutation | default('–') }}</dd>
|
||||
<dt class="font-medium">Name</dt>
|
||||
<dd>{{ booking.firstName }} {{ booking.lastName }}</dd>
|
||||
<dt class="font-medium">E-Mail</dt>
|
||||
<dd>{{ booking.email }}</dd>
|
||||
<dt class="font-medium">Telefon</dt>
|
||||
<dd>{{ booking.phone | default('–') }}</dd>
|
||||
<dt class="font-medium">Adresse</dt>
|
||||
<dd>
|
||||
{% if booking.street %}
|
||||
{{ booking.street }}<br>
|
||||
{{ booking.zip }} {{ booking.city }}
|
||||
{% else %}
|
||||
–
|
||||
{% endif %}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 class="text-lg font-bold mb-4">Reisedaten</h2>
|
||||
<dl class="grid grid-cols-2 gap-y-2 text-sm">
|
||||
<dt class="font-medium">Gruppenhaus</dt>
|
||||
<dd>{{ booking.accommodation.name }}</dd>
|
||||
<dt class="font-medium">Anreise</dt>
|
||||
<dd>{{ booking.dateFrom | date('d.m.Y') }}</dd>
|
||||
<dt class="font-medium">Abreise</dt>
|
||||
<dd>{{ booking.dateTo | date('d.m.Y') }}</dd>
|
||||
<dt class="font-medium">Nächte</dt>
|
||||
<dd>{{ booking.nights }}</dd>
|
||||
<dt class="font-medium">Anzahl Personen</dt>
|
||||
<dd>{{ booking.paxCount }}</dd>
|
||||
{% if booking.minorsCount > 0 %}
|
||||
<dt class="font-medium">davon Kinder (0–3 Jahre)</dt>
|
||||
<dd>{{ booking.minorsCount }}</dd>
|
||||
{% endif %}
|
||||
{% if booking.childrenCount > 0 %}
|
||||
<dt class="font-medium">davon Kinder (4–{{ booking.accommodation.maxAdolescentAge }} Jahre)</dt>
|
||||
<dd>{{ booking.childrenCount }}</dd>
|
||||
{% endif %}
|
||||
<dt class="font-medium">Status</dt>
|
||||
<dd>{% if booking.isInquiry %}Anfrage{% else %}Buchung{% endif %}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
{% if booking.boardServiceLabel or booking.additionalServices | length > 0 %}
|
||||
<div>
|
||||
<h2 class="text-lg font-bold mb-4">Gebuchte Leistungen</h2>
|
||||
<dl class="grid grid-cols-2 gap-y-2 text-sm">
|
||||
{% if booking.boardServiceLabel %}
|
||||
<dt class="font-medium">Verpflegung</dt>
|
||||
<dd>{{ booking.boardServiceLabel }}</dd>
|
||||
{% endif %}
|
||||
{% for service in booking.additionalServices %}
|
||||
<dt class="font-medium">{{ loop.first ? 'Zusatzleistungen' : '' }}</dt>
|
||||
<dd>{{ service.label }}</dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if priceBreakdown is not null %}
|
||||
<div>
|
||||
<h2 class="text-lg font-bold mb-4">Preise</h2>
|
||||
{% set currency = booking.accommodation.currency %}
|
||||
<table class="w-full text-sm">
|
||||
{% if priceBreakdown.basePrice > 0 %}
|
||||
<tr>
|
||||
<td class="py-1">
|
||||
Basispreis
|
||||
<span class="text-xs text-gray-500">für {{ priceBreakdown.includedPax }} Pers.</span>
|
||||
</td>
|
||||
<td class="py-1 text-right whitespace-nowrap">{{ (priceBreakdown.basePrice / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if priceBreakdown.additionalPersonsPrice > 0 %}
|
||||
<tr>
|
||||
<td class="py-1">
|
||||
Aufpreis Personenzahl
|
||||
<span class="text-xs text-gray-500">für {{ priceBreakdown.effectivePax - priceBreakdown.includedPax }} Pers.</span>
|
||||
</td>
|
||||
<td class="py-1 text-right whitespace-nowrap">{{ (priceBreakdown.additionalPersonsPrice / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if priceBreakdown.shortTermSurcharge > 0 %}
|
||||
<tr>
|
||||
<td class="py-1">Aufpreis Kurzzeit</td>
|
||||
<td class="py-1 text-right whitespace-nowrap">{{ (priceBreakdown.shortTermSurcharge / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if priceBreakdown.boardPrice > 0 %}
|
||||
<tr>
|
||||
<td class="py-1">Verpflegung</td>
|
||||
<td class="py-1 text-right whitespace-nowrap">{{ (priceBreakdown.boardPrice / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if priceBreakdown.undersubscriptionSurcharge > 0 %}
|
||||
<tr>
|
||||
<td class="py-1">Verpflegungs-Aufschlag für Gruppen unter {{ priceBreakdown.undersubscriptionThreshold }} Personen</td>
|
||||
<td class="py-1 text-right whitespace-nowrap">{{ (priceBreakdown.undersubscriptionSurcharge / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% for service in priceBreakdown.serviceDetails %}
|
||||
{% if service.price > 0 %}
|
||||
<tr>
|
||||
<td class="py-1">{{ service.label }}</td>
|
||||
<td class="py-1 text-right whitespace-nowrap">{{ (service.price / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if priceBreakdown.runningCosts > 0 %}
|
||||
<tr>
|
||||
<td class="py-1">Strom- und Abfallgebühren</td>
|
||||
<td class="py-1 text-right whitespace-nowrap">{{ (priceBreakdown.runningCosts / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr class="border-t border-gray-200 font-semibold">
|
||||
<td class="pt-2">
|
||||
Gesamtpreis
|
||||
<span class="block text-xs font-normal text-gray-500">zzgl. ortsabhängiger Gebühren</span>
|
||||
</td>
|
||||
<td class="pt-2 text-right whitespace-nowrap">{{ (priceBreakdown.total / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
{% if booking.discount is not null %}
|
||||
{% set discountAmount = (priceBreakdown.total * booking.discount / 100) | round | number_format(0, '.', '') %}
|
||||
{% set discountedTotal = priceBreakdown.total - discountAmount %}
|
||||
<tr class="text-green-700">
|
||||
<td class="pt-1">Rabatt {{ booking.discount }} %</td>
|
||||
<td class="pt-1 text-right whitespace-nowrap">– {{ (discountAmount / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
<tr class="border-t border-gray-200 font-bold text-green-700">
|
||||
<td class="pt-2">Gesamtpreis nach Rabatt</td>
|
||||
<td class="pt-2 text-right whitespace-nowrap">{{ (discountedTotal / 100) | format_currency(currency) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if booking.remarks %}
|
||||
<div class="lg:col-span-2">
|
||||
<h2 class="text-lg font-bold mb-4">Bemerkungen</h2>
|
||||
<p class="text-sm">{{ booking.remarks | nl2br }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="text-xs text-gray-400 mt-6">
|
||||
Eingegangen: {{ booking.createdAt | date('d.m.Y, H:i') }}
|
||||
{% if booking.updatedAt is not null and booking.updatedAt != booking.createdAt %}
|
||||
· Aktualisiert: {{ booking.updatedAt | date('d.m.Y, H:i') }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mt-6 border-t border-gray-200 pt-6">
|
||||
<h2 class="text-lg font-bold mb-2">Zugangslink</h2>
|
||||
{% if accessLink %}
|
||||
<p class="text-sm break-all">
|
||||
<a href="{{ accessLink }}" target="_blank">{{ accessLink }}</a>
|
||||
</p>
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
Gültig bis {{ accessLinkExpiresAt | date('d.m.Y') }}
|
||||
{% if accessLinkExpiresAt < date() %}
|
||||
<span class="text-red-600 font-medium">(abgelaufen)</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% else %}
|
||||
<p class="text-sm text-gray-500">Es wurde noch kein Zugangslink generiert.</p>
|
||||
{% endif %}
|
||||
<form method="post" action="{{ path('app_admin_accommodationbooking_generate_access_link', { 'id': booking.id }) }}" class="mt-2">
|
||||
<button type="submit" class="button button--secondary button--small">
|
||||
{{ accessLink ? 'Link erneut generieren' : 'Link generieren' }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between pt-8">
|
||||
<a href="{{ returnUrl }}" class="button button--secondary button--small">
|
||||
zurück
|
||||
</a>
|
||||
<a href="{{ path('app_admin_accommodationbooking_edit', { 'id': booking.id }) }}" class="button button--primary button--small">
|
||||
bearbeiten
|
||||
</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -13,12 +13,15 @@
|
||||
{{ form_row(form.includedPax) }}
|
||||
{{ form_row(form.minNights) }}
|
||||
{{ form_row(form.acceptUndersubscription) }}
|
||||
{{ form_row(form.acceptShortTerm) }}
|
||||
</div>
|
||||
<div class="flex justify-between pt-8">
|
||||
<a href="{{ path('app_admin_accommodation_edit', { 'id': accommodation.id }) }}" class="button button--secondary button--small">
|
||||
<a href="{{ path('app_admin_accommodation_edit', { 'id': accommodation.id }) }}#prices"
|
||||
class="button button--secondary button--small">
|
||||
zurück
|
||||
</a>
|
||||
<button type="submit" class="button button--primary button--small">
|
||||
<button type="submit"
|
||||
class="button button--primary button--small">
|
||||
speichern
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -4,16 +4,21 @@
|
||||
<div class="grid lg:grid-cols-2 gap-y-4 lg:gap-x-8">
|
||||
{{ form_row(form.label) }}
|
||||
{{ form_row(form.type) }}
|
||||
<div class="lg:col-span-2">
|
||||
{{ form_row(form.description) }}
|
||||
</div>
|
||||
{{ form_row(form.price) }}
|
||||
{{ form_row(form.selectionGroup) }}
|
||||
{{ form_row(form.dateFrom) }}
|
||||
{{ form_row(form.dateTo) }}
|
||||
</div>
|
||||
<div class="flex justify-between pt-8">
|
||||
<a href="{{ path('app_admin_accommodation_edit', { 'id': accommodation.id }) }}" class="button button--secondary button--small">
|
||||
<a href="{{ path('app_admin_accommodation_edit', { 'id': accommodation.id }) }}#additional-services"
|
||||
class="button button--secondary button--small">
|
||||
zurück
|
||||
</a>
|
||||
<button type="submit" class="button button--primary button--small">
|
||||
<button type="submit"
|
||||
class="button button--primary button--small">
|
||||
speichern
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -4,14 +4,19 @@
|
||||
<div class="grid lg:grid-cols-2 gap-y-4 lg:gap-x-8">
|
||||
{{ form_row(form.label) }}
|
||||
{{ form_row(form.price) }}
|
||||
<div class="lg:col-span-2">
|
||||
{{ form_row(form.description) }}
|
||||
</div>
|
||||
{{ form_row(form.dateFrom) }}
|
||||
{{ form_row(form.dateTo) }}
|
||||
</div>
|
||||
<div class="flex justify-between pt-8">
|
||||
<a href="{{ path('app_admin_accommodation_edit', { 'id': accommodation.id }) }}" class="button button--secondary button--small">
|
||||
<a href="{{ path('app_admin_accommodation_edit', { 'id': accommodation.id }) }}#board-services"
|
||||
class="button button--secondary button--small">
|
||||
zurück
|
||||
</a>
|
||||
<button type="submit" class="button button--primary button--small">
|
||||
<button type="submit"
|
||||
class="button button--primary button--small">
|
||||
speichern
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user