fix: process canceled participants correctly
This commit is contained in:
@@ -17,6 +17,11 @@ class BookingDataProcessor
|
||||
}
|
||||
// Update mappings, add services and pickups
|
||||
foreach ($formData->participants as $participant) {
|
||||
// skip canceled participants
|
||||
if ('F' !== $participant->status) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$servicesToMap = [
|
||||
...$participant->courses,
|
||||
...$participant->additionalServices,
|
||||
@@ -46,12 +51,6 @@ class BookingDataProcessor
|
||||
}
|
||||
$bookingData->pickupsTo[$selectedPickup->id]->mapping[] = $participant->index;
|
||||
}
|
||||
if ('BUS' === $participant->transportationServiceFro->subType && null !== $selectedPickup = $participant->pickupFro) {
|
||||
if (false === isset($bookingData->pickupsFro[$selectedPickup->id])) {
|
||||
$bookingData->pickupsFro[$selectedPickup->id] = $selectedPickup;
|
||||
}
|
||||
$bookingData->pickupsFro[$selectedPickup->id]->mapping[] = $participant->index;
|
||||
}
|
||||
}
|
||||
// Remove services/pickups with empty mappings
|
||||
foreach ($bookingData->additionalServices as $service) {
|
||||
@@ -77,8 +76,12 @@ class BookingDataProcessor
|
||||
|
||||
// Update participants' personal data
|
||||
foreach ($formData->participants as $participant) {
|
||||
// skip canceled participants
|
||||
if ('F' !== $participant->status) {
|
||||
continue;
|
||||
}
|
||||
$bookingData->participants[$participant->index]->firstName = $participant->firstName;
|
||||
$bookingData->participants[$participant->index]->lastName = $participant->lastName;
|
||||
$bookingData->participants[$participant->index]->name = $participant->lastName;
|
||||
$bookingData->participants[$participant->index]->dateOfBirth = $participant->dateOfBirth;
|
||||
$bookingData->participants[$participant->index]->gender = $participant->gender;
|
||||
$bookingData->participants[$participant->index]->nationality = $participant->nationality;
|
||||
@@ -169,17 +172,6 @@ class BookingDataProcessor
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < count($bookingData->pickupsFro)) {
|
||||
$payload['zustiege_rueck']['zustieg_rueck'] = [];
|
||||
foreach ($bookingData->pickupsFro as $pickup) {
|
||||
$payload['zustiege_rueck']['zustieg_rueck'][] = [
|
||||
'@idzustieg' => $pickup->id,
|
||||
'@anzahl' => count($pickup->mapping),
|
||||
'@zuordnung' => implode(',', $pickup->mapping),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ class Booking
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPickupToForParticipant(int $participantIndex): ?Pickup
|
||||
public function getPickupForParticipant(int $participantIndex): ?Pickup
|
||||
{
|
||||
foreach ($this->pickupsTo as $pickup) {
|
||||
if (in_array($participantIndex, $pickup->mapping)) {
|
||||
@@ -87,17 +87,6 @@ class Booking
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPickupFroForParticipant(int $participantIndex): ?Pickup
|
||||
{
|
||||
foreach ($this->pickupsFro as $pickup) {
|
||||
if (in_array($participantIndex, $pickup->mapping)) {
|
||||
return $pickup;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRoomForParticipant(int $participantIndex): ?Room
|
||||
{
|
||||
foreach ($this->rooms as $room) {
|
||||
|
||||
@@ -9,6 +9,7 @@ class PersonalData
|
||||
public ?int $addressId = null;
|
||||
public ?int $personId = null;
|
||||
public bool $mutable = false;
|
||||
public ?string $status = null;
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte angeben')]
|
||||
public ?string $name = null;
|
||||
@@ -57,4 +58,4 @@ class PersonalData
|
||||
'bemerkung' => $this->remarks,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ trait TypeConversionTrait
|
||||
return false;
|
||||
}
|
||||
|
||||
return 'True' === $string;
|
||||
return 'True' === $string || 'J' === $string;
|
||||
}
|
||||
|
||||
protected function boolToString(bool $bool): string
|
||||
@@ -71,4 +71,4 @@ trait TypeConversionTrait
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ class BookingParser extends AbstractParser
|
||||
{
|
||||
$personalData = new PersonalData();
|
||||
|
||||
$personalData->status = $this->getStringOrNullValue($node->filterXPath('//status'));
|
||||
|
||||
$personalData->addressId = $this->getIntOrNullValue($node->filterXPath('//idadresse'));
|
||||
$personalData->personId = $this->getIntOrNullValue($node->filterXPath('//idadresseperson'));
|
||||
$personalData->mutable = $this->getBoolValue($node->filterXPath('//aenderungmoeglich'));
|
||||
|
||||
@@ -33,14 +33,12 @@ final class BookingType extends AbstractType
|
||||
->getTransportationServicesByDirection('HIN'),
|
||||
'selectable_transportation_services_fro' => $travelData
|
||||
->getTransportationServicesByDirection('RUECK'),
|
||||
'selectable_pickups_to' => $travelData->pickupsTo,
|
||||
'selectable_pickups_fro' => $travelData->pickupsFro,
|
||||
'selectable_pickups' => $travelData->pickupsTo,
|
||||
'personal_data_mutable' => $travelData->participantDataMutable,
|
||||
'additional_services_mutable' => $travelData->additionalServicesMutable,
|
||||
'transportation_services_mutable' => $travelData->transportationServicesMutable,
|
||||
'pickups_mutable' => $travelData->pickupsMutable,
|
||||
'applicant_id' => $data->booking->applicant->personId,
|
||||
|
||||
],
|
||||
'allow_add' => false,
|
||||
'allow_delete' => false,
|
||||
|
||||
@@ -27,23 +27,26 @@ class BookingData
|
||||
/** @var PersonalData $participant */
|
||||
$participantData = ParticipantData::fromPersonalData($participant);
|
||||
$participantData->index = $index;
|
||||
$participantData->courses = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_COURSES);
|
||||
$participantData->skiPass = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_SKI_PASS);
|
||||
$participantData->additionalServices = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_ADDITIONAL);
|
||||
$participantData->board = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_BOARD);
|
||||
$participantData->rentals = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_RENTALS);
|
||||
// Different keys for direction used in booking data (H <=> HIN, R <=> RUECK)!
|
||||
$participantData->transportationServiceTo = $booking
|
||||
->getTransportationServiceForParticipantAndDirection($index, 'H');
|
||||
$participantData->transportationServiceFro = $booking
|
||||
->getTransportationServiceForParticipantAndDirection($index, 'R');
|
||||
$participantData->pickupTo = $booking->getPickupToForParticipant($index);
|
||||
$participantData->pickupFro = $booking->getPickupFroForParticipant($index);
|
||||
|
||||
// update services only for active participants
|
||||
if ('F' === $participantData->status) {
|
||||
$participantData->courses = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_COURSES);
|
||||
$participantData->skiPass = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_SKI_PASS);
|
||||
$participantData->additionalServices = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_ADDITIONAL);
|
||||
$participantData->board = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_BOARD);
|
||||
$participantData->rentals = $booking
|
||||
->getAdditionalServicesForParticipantByGroup($index, Service::TOKEN_RENTALS);
|
||||
// Different keys for direction used in booking data (H <=> HIN, R <=> RUECK)!
|
||||
$participantData->transportationServiceTo = $booking
|
||||
->getTransportationServiceForParticipantAndDirection($index, 'H');
|
||||
$participantData->transportationServiceFro = $booking
|
||||
->getTransportationServiceForParticipantAndDirection($index, 'R');
|
||||
$participantData->pickupTo = $booking->getPickupForParticipant($index);
|
||||
}
|
||||
|
||||
$instance->participants[$index] = $participantData;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ class ParticipantData
|
||||
#[Assert\Email(message: 'Bitte eine gültige E-Mail Adresse angeben', mode: 'strict')]
|
||||
public ?string $email = null;
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte angeben')]
|
||||
public ?string $mobile = null;
|
||||
public array $courses = [];
|
||||
public array $additionalServices = [];
|
||||
@@ -43,8 +42,7 @@ class ParticipantData
|
||||
public array $rentals = [];
|
||||
public ?Service $transportationServiceTo = null;
|
||||
public ?Service $transportationServiceFro = null;
|
||||
public ?Pickup $pickupTo = null;
|
||||
public ?Pickup $pickupFro = null;
|
||||
public ?Pickup $pickup = null;
|
||||
|
||||
#[Assert\Callback]
|
||||
public function assertBodyMeasurementsValid(ExecutionContextInterface $context): void
|
||||
@@ -78,15 +76,9 @@ class ParticipantData
|
||||
#[Assert\Callback]
|
||||
public function assertPickupSelected(ExecutionContextInterface $context): void
|
||||
{
|
||||
if (null !== $this->transportationServiceTo && null === $this->pickupTo) {
|
||||
if (null !== $this->transportationServiceTo && null === $this->pickup) {
|
||||
$context->buildViolation('Bitte auswählen')
|
||||
->atPath('pickupTo')
|
||||
->addViolation()
|
||||
;
|
||||
}
|
||||
if (null !== $this->transportationServiceFro && null === $this->pickupFro) {
|
||||
$context->buildViolation('Bitte auswählen')
|
||||
->atPath('pickupFro')
|
||||
->atPath('pickup')
|
||||
->addViolation()
|
||||
;
|
||||
}
|
||||
@@ -96,6 +88,7 @@ class ParticipantData
|
||||
{
|
||||
$instance = new static();
|
||||
|
||||
$instance->status = $personalData->status;
|
||||
$instance->addressId = $personalData->addressId;
|
||||
$instance->personId = $personalData->personId;
|
||||
$instance->mutable = $personalData->mutable;
|
||||
|
||||
@@ -25,6 +25,11 @@ class ParticipantType extends AbstractType
|
||||
$participantData = $event->getData();
|
||||
$participantIndex = $participantData->index;
|
||||
|
||||
// don't add any fields for canceled participants
|
||||
if ('F' !== $participantData->status) {
|
||||
return;
|
||||
}
|
||||
|
||||
$form = $event->getForm();
|
||||
|
||||
$personalDataMutable = $options['personal_data_mutable'] && $participantData->mutable;
|
||||
@@ -83,6 +88,7 @@ class ParticipantType extends AbstractType
|
||||
])
|
||||
->add('mobile', TextType::class, [
|
||||
'label' => 'Telefon (mobil)',
|
||||
'required' => false,
|
||||
'attr' => [
|
||||
'readonly' => false === $personalDataMutable,
|
||||
]
|
||||
@@ -259,11 +265,11 @@ class ParticipantType extends AbstractType
|
||||
;
|
||||
|
||||
// Pickup
|
||||
$form->add('pickupTo', ChoiceType::class, [
|
||||
$form->add('pickup', ChoiceType::class, [
|
||||
'label' => 'Zustieg',
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'choices' => $options['selectable_pickups_to'],
|
||||
'choices' => $options['selectable_pickups'],
|
||||
'choice_value' => 'id',
|
||||
'choice_label' => function (?Pickup $pickup) {
|
||||
if (null === $pickup) {
|
||||
@@ -282,24 +288,16 @@ class ParticipantType extends AbstractType
|
||||
);
|
||||
},
|
||||
]);
|
||||
|
||||
if (0 < count($options['selectable_pickups_fro'])) {
|
||||
$form->add('pickupFro', ChoiceType::class, [
|
||||
'label' => 'Ausstieg',
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'choices' => $options['selectable_pickups_fro'],
|
||||
'choice_value' => 'id',
|
||||
'choice_label' => function (?Pickup $pickup) {
|
||||
return $pickup?->city;
|
||||
},
|
||||
]);
|
||||
}
|
||||
})
|
||||
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) {
|
||||
$data = $event->getData();
|
||||
$form = $event->getForm();
|
||||
|
||||
// skip processing for canceled participants
|
||||
if ('F' !== $form->getData()->status) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transportationId = $data['transportationServiceTo'];
|
||||
$transportation = $options['travel']->pickups[$transportationId] ?? null;
|
||||
|
||||
@@ -342,8 +340,7 @@ class ParticipantType extends AbstractType
|
||||
'selectable_rentals' => [],
|
||||
'selectable_transportation_services_to' => [],
|
||||
'selectable_transportation_services_fro' => [],
|
||||
'selectable_pickups_to' => [],
|
||||
'selectable_pickups_fro' => [],
|
||||
'selectable_pickups' => [],
|
||||
'personal_data_mutable' => true,
|
||||
'additional_services_mutable' => true,
|
||||
'transportation_services_mutable' => true,
|
||||
|
||||
+122
-103
@@ -111,112 +111,22 @@
|
||||
{% for child in form.participants %}
|
||||
<div>
|
||||
{% set participant = child.vars.data %}
|
||||
{% if participant.status != 'F' %}
|
||||
{% do child.setRendered %}
|
||||
{% endif %}
|
||||
<div class="{{ html_classes('p-8 border rounded-md mb-4', { 'border-gray-300': child.vars.valid, 'border-red-500': not child.vars.valid }) }}" {{ stimulus_controller('toggle', {'open': child.vars.valid == false}, { 'closed': 'hidden' }) }}>
|
||||
<div role="button" class="flex items-center justify-between" {{ stimulus_action('toggle', 'toggle', 'click') }}>
|
||||
<div class="text-2xl font-semibold">Teilnehmer:in {{ participant.index }}: {{ participant.firstName }} {{ participant.lastName }}</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-2xl leading-none font-semibold">Teilnehmer:in {{ participant.index }}: {{ participant.firstName }} {{ participant.lastName }}</span>
|
||||
{% if participant.status != 'F' %} <span class="inline-block px-2 py-1 text-xs bg-red-500 text-white">storniert</span>{% endif %}
|
||||
</div>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6" {{ stimulus_target('toggle', 'icon') }}>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="hidden" {{ stimulus_target('toggle', 'toggle') }}>
|
||||
<div class="flex flex-col space-y-4 pt-4">
|
||||
<div class="relative">
|
||||
<h3 class="text-xl font-semibold">
|
||||
Persönliche Daten
|
||||
</h3>
|
||||
{% if not child.vars.data.mutable %}
|
||||
<div class="pt-4">
|
||||
{% include '_partials/_alert.html.twig' with {
|
||||
'level': 'info',
|
||||
'messages': ['Änderungen an den persönlichen Daten sind nur über die Kundenbetreuung möglich und kostenpflichtig']
|
||||
} %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4 pb-4">
|
||||
{{ form_row(child.firstName) }}
|
||||
{{ form_row(child.lastName) }}
|
||||
{{ form_row(child.gender) }}
|
||||
{{ form_row(child.dateOfBirth) }}
|
||||
{{ form_row(child.nationality) }}
|
||||
</fieldset>
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4 pb-4">
|
||||
{{ form_row(child.email) }}
|
||||
{{ form_row(child.mobile) }}
|
||||
</fieldset>
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||
{{ form_row(child.height) }}
|
||||
{{ form_row(child.shoeSize) }}
|
||||
{{ form_row(child.weight) }}
|
||||
</fieldset>
|
||||
{% if not travelData.participantDataMutable %}
|
||||
<div class="absolute top-0 left-0 inset-0 cursor-not-allowed"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold">
|
||||
Unterkunft
|
||||
</h3>
|
||||
{% set room = bookingData.roomForParticipant(participant.index) %}
|
||||
{{ room.label }} ({{ room.individualPrice[participant.index]|format_currency('EUR') }})
|
||||
</div>
|
||||
<div class="relative">
|
||||
<h3 class="text-xl font-semibold">
|
||||
Leistungen
|
||||
</h3>
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||
{% if child.courses is defined %}
|
||||
{{ form_row(child.courses) }}
|
||||
{% endif %}
|
||||
{% if child.skiPass is defined %}
|
||||
{{ form_row(child.skiPass) }}
|
||||
{% endif %}
|
||||
{% if child.additionalServices is defined %}
|
||||
{{ form_row(child.additionalServices) }}
|
||||
{% endif %}
|
||||
{% if child.board is defined %}
|
||||
{{ form_row(child.board) }}
|
||||
{% endif %}
|
||||
{% if child.rentals is defined %}
|
||||
{{ form_row(child.rentals) }}
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
{% if not travelData.additionalServicesMutable %}
|
||||
<div class="absolute inset-0 cursor-not-allowed"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="relative">
|
||||
<h3 class="text-xl font-semibold">
|
||||
Hin-/Rückreise
|
||||
</h3>
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4">
|
||||
<div class="space-y-2" {{ stimulus_controller('select-toggle', { 'show': ['BUS'], 'visible': participant.transportationServiceTo.subType == 'BUS' }, { 'hidden': 'hidden' }) }}>
|
||||
{{ form_row(child.transportationServiceTo) }}
|
||||
{% if child.pickupTo is defined %}
|
||||
<div {{ stimulus_target('select-toggle', 'container') }}>
|
||||
{{ form_row(child.pickupTo) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="space-y-2" {{ stimulus_controller('select-toggle', { 'show': ['BUS'], 'visible': participant.transportationServiceFro.subType == 'BUS' }, { 'hidden': 'hidden' }) }}>
|
||||
{{ form_row(child.transportationServiceFro) }}
|
||||
{% if child.pickupFro is defined %}
|
||||
<div {{ stimulus_target('select-toggle', 'container') }}>
|
||||
{{ form_row(child.pickupFro) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</fieldset>
|
||||
{% if not travelData.transportationServicesMutable %}
|
||||
<div class="absolute inset-0 cursor-not-allowed"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold">
|
||||
Gesamtpreis
|
||||
</h3>
|
||||
<span class="text-2xl font-medium">{{ bookingData.priceForParticipant(participant.index)|format_currency('EUR') }}</span>
|
||||
</div>
|
||||
{% if participant.status != 'F' %}
|
||||
{% set surcharges = bookingData.surchargesForParticipant(participant.index) %}
|
||||
{% if surcharges|length > 0 %}
|
||||
<div>
|
||||
@@ -232,14 +142,123 @@
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="relative">
|
||||
<h3 class="text-xl font-semibold">
|
||||
Persönliche Daten
|
||||
</h3>
|
||||
{% if not child.vars.data.mutable %}
|
||||
<div class="pt-4">
|
||||
{% include '_partials/_alert.html.twig' with {
|
||||
'level': 'info',
|
||||
'messages': ['Änderungen an den persönlichen Daten sind nur über die Kundenbetreuung möglich und kostenpflichtig']
|
||||
} %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4 pb-4">
|
||||
{{ form_row(child.firstName) }}
|
||||
{{ form_row(child.lastName) }}
|
||||
{{ form_row(child.gender) }}
|
||||
{{ form_row(child.dateOfBirth) }}
|
||||
{{ form_row(child.nationality) }}
|
||||
</fieldset>
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4 pb-4">
|
||||
{{ form_row(child.email) }}
|
||||
{{ form_row(child.mobile) }}
|
||||
</fieldset>
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||
{{ form_row(child.height) }}
|
||||
{{ form_row(child.shoeSize) }}
|
||||
{{ form_row(child.weight) }}
|
||||
</fieldset>
|
||||
{% if not travelData.participantDataMutable %}
|
||||
<div class="absolute top-0 left-0 inset-0 cursor-not-allowed"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold">
|
||||
Unterkunft
|
||||
</h3>
|
||||
{% set room = bookingData.roomForParticipant(participant.index) %}
|
||||
{{ room.label }} ({{ room.individualPrice[participant.index]|format_currency('EUR') }})
|
||||
</div>
|
||||
<div class="relative">
|
||||
<h3 class="text-xl font-semibold">
|
||||
Leistungen
|
||||
</h3>
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||
{% if child.courses is defined %}
|
||||
{{ form_row(child.courses) }}
|
||||
{% endif %}
|
||||
{% if child.skiPass is defined %}
|
||||
{{ form_row(child.skiPass) }}
|
||||
{% endif %}
|
||||
{% if child.additionalServices is defined %}
|
||||
{{ form_row(child.additionalServices) }}
|
||||
{% endif %}
|
||||
{% if child.board is defined %}
|
||||
{{ form_row(child.board) }}
|
||||
{% endif %}
|
||||
{% if child.rentals is defined %}
|
||||
{{ form_row(child.rentals) }}
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
{% if not travelData.additionalServicesMutable %}
|
||||
<div class="absolute inset-0 cursor-not-allowed"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="relative">
|
||||
<h3 class="text-xl font-semibold">
|
||||
Hin-/Rückreise
|
||||
</h3>
|
||||
<fieldset class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4">
|
||||
<div class="space-y-2" {{ stimulus_controller('select-toggle', { 'show': ['BUS'], 'visible': participant.transportationServiceTo.subType == 'BUS' }, { 'hidden': 'hidden' }) }}>
|
||||
{{ form_row(child.transportationServiceTo) }}
|
||||
{% if child.pickup is defined %}
|
||||
<div {{ stimulus_target('select-toggle', 'container') }}>
|
||||
{{ form_row(child.pickup) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{{ form_row(child.transportationServiceFro) }}
|
||||
</fieldset>
|
||||
{% if not travelData.transportationServicesMutable %}
|
||||
<div class="absolute inset-0 cursor-not-allowed"></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold">
|
||||
Gesamtpreis
|
||||
</h3>
|
||||
<span class="text-2xl font-medium">{{ bookingData.priceForParticipant(participant.index)|format_currency('EUR') }}</span>
|
||||
</div>
|
||||
{% set surcharges = bookingData.surchargesForParticipant(participant.index) %}
|
||||
{% if surcharges|length > 0 %}
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold">
|
||||
Zuschläge
|
||||
</h3>
|
||||
<ul>
|
||||
{% for surcharge in surcharges %}
|
||||
<li>
|
||||
{{ surcharge.label }}: {{ surcharge.individualPrice[participant.index]|format_currency('EUR') }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit"
|
||||
class="button bg-button bg-button--secondary" {{ stimulus_action('loading', 'toggle', null, { 'scroll': true }) }}>
|
||||
Aktualisieren
|
||||
</button>
|
||||
{% if participant.status == 'F' %}
|
||||
<button type="submit"
|
||||
class="button bg-button bg-button--secondary" {{ stimulus_action('loading', 'toggle', null, { 'scroll': true }) }}>
|
||||
Aktualisieren
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user