wip: continue implemntation

This commit is contained in:
Björn Fromme
2024-11-22 17:30:20 +01:00
parent bd13ae6537
commit d3786795e4
26 changed files with 798 additions and 494 deletions
+32 -24
View File
@@ -3,45 +3,53 @@
namespace App\Form;
use App\BusProNet\Model\Service;
use App\BusProNet\Model\Travel;
use App\Form\Model\BookingData;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
final class BookingType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('participants', CollectionType::class, [
'entry_type' => ParticipantType::class,
'entry_options' => [
'selectable_courses' => $options['travel']->getAdditionalServicesByGroup(Service::TOKEN_COURSES),
'selectable_ski_passes' => $options['travel']->getAdditionalServicesByGroup(Service::TOKEN_SKI_PASS),
'selectable_services' => $options['travel']->getAdditionalServicesByGroup(Service::TOKEN_ADDITIONAL),
'selectable_board' => $options['travel']->getAdditionalServicesByGroup(Service::TOKEN_BOARD),
'selectable_rentals' => $options['travel']->getAdditionalServicesByGroup(Service::TOKEN_RENTALS),
'selectable_transportation_services_to' => $options['travel']
->getTransportationServicesByDirection('HIN'),
'selectable_transportation_services_fro' => $options['travel']
->getTransportationServicesByDirection('RUECK'),
'selectable_pickups' => $options['travel']->pickups,
],
'allow_add' => false,
'allow_delete' => false,
]);
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
/** @var BookingData $data */
$data = $event->getData();
$form = $event->getForm();
$travelData = $data->travel;
$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_transportation_services_to' => $travelData
->getTransportationServicesByDirection('HIN'),
'selectable_transportation_services_fro' => $travelData
->getTransportationServicesByDirection('RUECK'),
'selectable_pickups' => $travelData->pickups,
'personal_data_mutable' => $travelData->participantDataMutable,
'additional_services_mutable' => $travelData->additionalServicesMutable,
'transportation_services_mutable' => $travelData->transportationServicesMutable,
'pickups_mutable' => $travelData->pickupsMutable,
],
'allow_add' => false,
'allow_delete' => false,
]);
});
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver
->setDefaults([
'data_class' => BookingData::class,
'mutable_fields' => [],
])
->setRequired(['travel'])
->setAllowedTypes('travel', Travel::class)
->setDefaults(['data_class' => BookingData::class])
;
}
}
+8 -2
View File
@@ -5,22 +5,26 @@ namespace App\Form\Model;
use App\BusProNet\Model\Booking;
use App\BusProNet\Model\PersonalData;
use App\BusProNet\Model\Service;
use App\BusProNet\Model\Travel;
use App\Validator\Constraints as AppAssert;
use Symfony\Component\Validator\Constraints as Assert;
#[AppAssert\Booking]
#[Assert\GroupSequence(['BookingData', 'Api'])]
#[AppAssert\Booking(groups:['Api'])]
class BookingData
{
public ?Booking $booking = null;
public ?Travel $travel = null;
#[Assert\Valid]
public array $participants = [];
public static function fromBooking(Booking $booking): static
public static function fromBooking(Booking $booking, Travel $travel): static
{
$instance = new static();
$instance->booking = $booking;
$instance->travel = $travel;
foreach ($booking->participants as $index => $participant) {
/** @var PersonalData $participant */
@@ -41,6 +45,8 @@ class BookingData
->getTransportationServiceForParticipantAndDirection($index, 'H');
$participantData->transportationServiceFro = $booking
->getTransportationServiceForParticipantAndDirection($index, 'R');
$participantData->pickup = $booking->getPickupForParticipant($index);
$instance->participants[$index] = $participantData;
}
+135 -104
View File
@@ -21,52 +21,57 @@ class ParticipantType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
if (true === $options['personal_data_mutable']) {
$builder
->add('firstName', TextType::class, [
'label' => 'Vorname',
])
->add('lastName', TextType::class, [
'label' => 'Nachname',
])
->add('dateOfBirth', BirthdayType::class, [
'label' => 'Geburtsdatum',
'html5' => true,
'widget' => 'single_text',
'input' => 'datetime_immutable',
])
->add('gender', ChoiceType::class, [
'label' => 'Geschlecht',
'required' => false,
'placeholder' => 'keine Angabe',
'choices' => [
'männlich' => 'M',
'weiblich' => 'W',
'divers' => 'D',
],
])
->add('nationality', CountryType::class, [
'label' => 'Nationalität',
'property' => 'nationality',
'preferred_choices' => ['D', 'A', 'CH'],
])
->add('email', EmailType::class, [
'label' => 'Email',
])
->add('mobile', TextType::class, [
'label' => 'Telefon (mobil)',
])
->add('height', IntegerType::class, [
'label' => 'Körpergröße [cm]',
'required' => false,
])
->add('shoeSize', IntegerType::class, [
'label' => 'Schuhgröße',
'required' => false,
])
->add('weight', IntegerType::class, [
'label' => 'Gewicht [kg]',
'required' => false,
])
;
}
$builder
->add('firstName', TextType::class, [
'label' => 'Vorname',
])
->add('lastName', TextType::class, [
'label' => 'Nachname',
])
->add('dateOfBirth', BirthdayType::class, [
'label' => 'Geburtsdatum',
'html5' => true,
'widget' => 'single_text',
'input' => 'datetime_immutable',
])
->add('gender', ChoiceType::class, [
'label' => 'Geschlecht',
'required' => false,
'placeholder' => 'keine Angabe',
'choices' => [
'männlich' => 'M',
'weiblich' => 'W',
'divers' => 'D',
],
])
->add('nationality', CountryType::class, [
'label' => 'Nationalität',
'property' => 'nationality',
'preferred_choices' => ['D', 'A', 'CH'],
])
->add('email', EmailType::class, [
'label' => 'Email',
])
->add('mobile', TextType::class, [
'label' => 'Telefon (mobil)',
])
->add('height', IntegerType::class, [
'label' => 'Körpergröße [cm]',
'required' => false,
])
->add('shoeSize', IntegerType::class, [
'label' => 'Schuhgröße',
'required' => false,
])
->add('weight', IntegerType::class, [
'label' => 'Gewicht [kg]',
'required' => false,
])
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
/** @var ParticipantData $participantData */
$participantData = $event->getData();
@@ -104,68 +109,90 @@ class ParticipantType extends AbstractType
},
];
$form
->add('courses', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Kurse',
'choices' => $options['selectable_courses'],
])
->add('additionalServices', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Zusatzleistungen',
'choices' => $options['selectable_services'],
])
->add('skiPass', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Skipass',
'choices' => $options['selectable_ski_passes'],
])
->add('board', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verpflegung',
'choices' => $options['selectable_board'],
])
->add('rentals', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verleih',
'choices' => $options['selectable_rentals'],
])
->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'],
])
->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;
}
// 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;
}
// 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'],
]);
}
return sprintf('%s (%s€)',
$pickup->city,
number_format($price, 2, ',', '.')
);
},
])
;
// 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;
}
$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();
@@ -194,6 +221,10 @@ class ParticipantType extends AbstractType
'selectable_transportation_services_to' => [],
'selectable_transportation_services_fro' => [],
'selectable_pickups' => [],
'personal_data_mutable' => true,
'additional_services_mutable' => true,
'transportation_services_mutable' => true,
'pickups_mutable' => true,
]);
}
}