wip: continue implementation

This commit is contained in:
Björn Fromme
2024-11-27 11:31:48 +01:00
parent b5d52b0053
commit 84ab6446ea
81 changed files with 9127 additions and 898 deletions
+26 -8
View File
@@ -24,11 +24,11 @@ final class BookingType extends AbstractType
$form->add('participants', CollectionType::class, [
'entry_type' => ParticipantType::class,
'entry_options' => [
'selectable_courses' => $travelData->getAdditionalServicesByGroup(Service::TOKEN_COURSES),
'selectable_ski_passes' => $travelData->getAdditionalServicesByGroup(Service::TOKEN_SKI_PASS),
'selectable_services' => $travelData->getAdditionalServicesByGroup(Service::TOKEN_ADDITIONAL),
'selectable_board' => $travelData->getAdditionalServicesByGroup(Service::TOKEN_BOARD),
'selectable_rentals' => $travelData->getAdditionalServicesByGroup(Service::TOKEN_RENTALS),
'selectable_courses' => $this->mergeSelectableServices($data, Service::TOKEN_COURSES),
'selectable_ski_passes' => $this->mergeSelectableServices($data, Service::TOKEN_SKI_PASS),
'selectable_services' => $this->mergeSelectableServices($data, Service::TOKEN_ADDITIONAL),
'selectable_board' => $this->mergeSelectableServices($data, Service::TOKEN_BOARD),
'selectable_rentals' => $this->mergeSelectableServices($data, Service::TOKEN_RENTALS),
'selectable_transportation_services_to' => $travelData
->getTransportationServicesByDirection('HIN'),
'selectable_transportation_services_fro' => $travelData
@@ -46,10 +46,28 @@ final class BookingType extends AbstractType
});
}
private function mergeSelectableServices(BookingData $data, mixed $subType): array
{
// combine selectable services from travel data with additional services
// from booking data
$selectableServices = $data->travel->getAdditionalServicesByGroup($subType);
$selectableServiceIds = array_map(function (Service $service) {
return $service->id;
}, $selectableServices);
foreach ($data->booking->getAdditionalServicesByGroup($subType) as $item) {
if (false === in_array($item->id, $selectableServiceIds)) {
$selectableServices[] = $item;
}
}
return $selectableServices;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver
->setDefaults(['data_class' => BookingData::class])
;
$resolver->setDefaults([
'data_class' => BookingData::class,
]);
}
}
+173 -125
View File
@@ -51,7 +51,7 @@ class ParticipantType extends AbstractType
'preferred_choices' => ['D', 'A', 'CH'],
])
->add('email', EmailType::class, [
'label' => 'Email',
'label' => 'E-Mail',
])
->add('mobile', TextType::class, [
'label' => 'Telefon (mobil)',
@@ -71,142 +71,190 @@ class ParticipantType extends AbstractType
;
}
$builder
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
/** @var ParticipantData $participantData */
$participantData = $event->getData();
$participantIndex = $participantData->index;
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
/** @var ParticipantData $participantData */
$participantData = $event->getData();
$participantIndex = $participantData->index;
$form = $event->getForm();
$form = $event->getForm();
$commonChoiceFieldOptions = [
'multiple' => true,
'expanded' => true,
'choice_value' => 'id',
'choice_label' => function (?Service $service) use ($participantIndex) {
if (null === $service) {
return null;
}
$price = $service->individualPrice[$participantIndex] ?? $service->price;
if (null === $price || 0.0 === $price) {
return $service->label;
}
$commonChoiceFieldOptions = [
'required' => false,
'multiple' => true,
'expanded' => true,
'choice_value' => 'id',
'choice_label' => function (?Service $service) use ($participantIndex) {
if (null === $service) {
return null;
}
$price = $service->individualPrice[$participantIndex] ?? $service->price;
if (null === $price || 0.0 === $price) {
return $service->label;
}
return sprintf('%s (%s€)',
$service->label,
number_format($price, 2, ',', '.')
);
},
'choice_attr' => function (?Service $service) {
if (true === $service->mandatory) {
return sprintf('%s (%s €)',
$service->label,
number_format($price, 2, ',', '.')
);
},
'choice_attr' => function (?Service $service) {
$attributes = [
'data-available' => $service->available,
'data-availabilities-target' => 'field',
];
// forcibly select mandatory services
if (true === $service->mandatory) {
$attributes['checked'] = true;
$attributes['disabled'] = true;
}
// disable selection of services only available in booking data
if (Service::SOURCE_BOOKING === $service->source) {
$attributes['disabled'] = true;
}
return $attributes;
},
'choice_filter' => function (Service $service) use ($participantData) {
// remove choices only available in booking data and
// which are not mapped to the current participant
if (
Service::SOURCE_TRAVEL === $service->source ||
Service::CATEGORY_ADDITIONAL !== $service->category
) {
return true;
}
return in_array($participantData->index, $service->mapping);
},
];
// Additional services
if (true === $options['additional_services_mutable']) {
if (0 < count($options['selectable_courses'])) {
$form->add('courses', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Kurse',
'choices' => $options['selectable_courses'],
]);
}
if (0 < count($options['selectable_services'])) {
$form->add('additionalServices', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Zusatzleistungen',
'choices' => $options['selectable_services'],
]);
}
if (0 < count($options['selectable_ski_passes'])) {
$form->add('skiPass', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Skipass',
'choices' => $options['selectable_ski_passes'],
]);
}
if (0 < count($options['selectable_board'])) {
$form->add('board', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verpflegung',
'choices' => $options['selectable_board'],
]);
}
if (0 < count($options['selectable_rentals'])) {
$form->add('rentals', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verleih',
'choices' => $options['selectable_rentals'],
]);
}
}
// Transportation
if (true === $options['transportation_services_mutable']) {
$form
->add('transportationServiceTo', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Anreise',
'multiple' => false,
'choices' => $options['selectable_transportation_services_to'],
'choice_attr' => function (?Service $service) {
return [
'checked' => true,
'disabled' => true,
'data-available' => $service->available,
'data-availabilities-target' => 'field',
'data-action' => 'select-toggle#toggle',
'data-select-toggle-value' => $service->subType,
];
}
},
])
->add('transportationServiceFro', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Rückreise',
'multiple' => false,
'choices' => $options['selectable_transportation_services_fro'],
]);
}
return [];
},
];
// Pickup
if (true === $options['pickups_mutable']) {
$form
->add('pickup', ChoiceType::class, [
'label' => 'Zustieg',
'multiple' => false,
'expanded' => false,
'choices' => $options['selectable_pickups'],
'choice_value' => 'id',
'choice_label' => function (?Pickup $pickup) {
if (null === $pickup) {
return null;
}
// Additional services
if (true === $options['additional_services_mutable']) {
$price = $pickup->price;
if (0 < count($options['selectable_courses'])) {
$form->add('courses', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Kurse',
'choices' => $options['selectable_courses'],
]);
}
if (0 < count($options['selectable_services'])) {
$form->add('additionalServices', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Zusatzleistungen',
'choices' => $options['selectable_services'],
]);
}
if (0 < count($options['selectable_ski_passes'])) {
$form->add('skiPass', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Skipass',
'choices' => $options['selectable_ski_passes'],
]);
}
if (0 < count($options['selectable_board'])) {
$form->add('board', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verpflegung',
'choices' => $options['selectable_board'],
]);
}
if (0 < count($options['selectable_rentals'])) {
$form->add('rentals', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verleih',
'choices' => $options['selectable_rentals'],
]);
}
if (null === $price || 0.0 === $price) {
return $pickup->city;
}
return sprintf('%s (%s €)',
$pickup->city,
number_format($price, 2, ',', '.')
);
},
]);
}
})
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) {
$data = $event->getData();
$form = $event->getForm();
$transportationId = $data['transportationServiceTo'];
$transportation = $options['travel']->pickups[$transportationId] ?? null;
if (null !== $transportation && 'PKW' === $transportation->subType) {
$form->remove('pickup');
unset($data['pickup']);
}
// forcibly select mandatory services that potentially have been disabled in PRE_SET_DATA
$mandatoryServices = array_filter($options['selectable_services'], function (Service $service) use ($data) {
return true === $service->mandatory ||
(Service::SOURCE_BOOKING === $service->source && in_array($data['index'], $service->mapping));
});
if (0 < count($mandatoryServices)) {
if (false === isset($data['additionalServices'])) {
$data['additionalServices'] = [];
}
// Transportation
if (true === $options['transportation_services_mutable']) {
$form
->add('transportationServiceTo', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Anreise',
'multiple' => false,
'choices' => $options['selectable_transportation_services_to'],
])
->add('transportationServiceFro', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Rückreise',
'multiple' => false,
'choices' => $options['selectable_transportation_services_fro'],
]);
}
$mandatoryServiceIds = array_map(function (Service $service) {
return $service->id;
}, $mandatoryServices);
// Pickup
if (true === $options['pickups_mutable']) {
$form
->add('pickup', ChoiceType::class, [
'label' => 'Zustieg (bei Busanreise)',
'multiple' => false,
'expanded' => false,
'choices' => $options['selectable_pickups'],
'choice_value' => 'id',
'choice_label' => function (?Pickup $pickup) {
if (null === $pickup) {
return null;
}
$allServiceIds = [...$mandatoryServiceIds, ...$data['additionalServices']];
$data['additionalServices'] = array_unique($allServiceIds);
}
$price = $pickup->price;
if (null === $price || 0.0 === $price) {
return $pickup->city;
}
return sprintf('%s (%s€)',
$pickup->city,
number_format($price, 2, ',', '.')
);
},
]);
}
})
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) {
$data = $event->getData();
$form = $event->getForm();
$transportationId = $data['transportationServiceTo'];
$transportation = $options['travel']->pickups[$transportationId] ?? null;
if (null !== $transportation && 'PKW' === $transportation->subType) {
$form->remove('pickup');
unset($data['pickup']);
}
})
;
$event->setData($data);
});
}
public function configureOptions(OptionsResolver $resolver): void
+3 -3
View File
@@ -18,9 +18,9 @@ class PersonalDataType extends AbstractType
->add('gender', ChoiceType::class, [
'label' => 'Gender',
'choices' => [
'M' => 'M',
'W' => 'W',
'D' => 'D',
'männlich' => 'M',
'weiblich' => 'W',
'divers' => 'D',
],
])
->add('firstName', TextType::class, [