wip: submit booking to api

This commit is contained in:
Björn Fromme
2026-03-16 11:59:10 +01:00
parent ee264e88d4
commit 7ea52670b9
34 changed files with 3316 additions and 31 deletions
+49
View File
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace App\Form;
use App\BusProNet\Form\CountryType;
use App\BusProNet\Model\Address;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('street', TextType::class, [
'label' => 'Straße',
'required' => $options['required'],
'sanitize_html' => true,
])
->add('postCode', TextType::class, [
'label' => 'PLZ',
'required' => $options['required'],
'sanitize_html' => true,
])
->add('city', TextType::class, [
'label' => 'Ort',
'required' => $options['required'],
'sanitize_html' => true,
])
->add('country', CountryType::class, [
'label' => 'Land',
'property' => 'country',
'required' => $options['required'],
'preferred_choices' => ['DE', 'AT', 'CH'],
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Address::class,
'required' => false,
]);
}
}
+7 -5
View File
@@ -148,14 +148,16 @@ class BookingParticipantType extends AbstractType
], $getFieldState('nationality')))
->add('email', EmailType::class, $this->mergeFieldState([
'label' => 'E-Mail',
'required' => false,
'sanitize_html' => true,
], $getFieldState('email')))
->add('mobile', TextType::class, $this->mergeFieldState([
'label' => 'Telefon (mobil)',
'required' => false,
'required' => 0 === $participantIndex,
'sanitize_html' => true,
], $getFieldState('mobile')));
], $getFieldState('mobile')))
->add('address', AddressType::class, $this->mergeFieldState([
'label' => 'Adresse',
'required' => 0 === $participantIndex,
], $getFieldState('address')));
// Add body dimensions with state handling - use shouldIncludeField method
if ($this->fieldStateProvider->shouldIncludeField('bodyDimensions', $bookingDto, $participantIndex)) {
@@ -194,7 +196,7 @@ class BookingParticipantType extends AbstractType
// Clear the form and rebuild from scratch with updated states
// Rebuild base fields with updated states
$baseFields = ['firstName', 'lastName', 'dateOfBirth', 'gender', 'nationality', 'email', 'mobile', 'bodyDimensions'];
$baseFields = ['firstName', 'lastName', 'dateOfBirth', 'gender', 'nationality', 'email', 'mobile', 'address', 'bodyDimensions'];
foreach ($baseFields as $fieldName) {
if ($form->has($fieldName)) {
$form->remove($fieldName);
+2
View File
@@ -31,6 +31,8 @@ class BookingCreateDto implements BookingDtoInterface
public ?BankAccountDto $bankAccount = null;
public ?int $agencyId = null;
public function __construct(public Travel $travel, public int $hotelId)
{
}
+11
View File
@@ -2,6 +2,7 @@
namespace App\Form\Model;
use App\BusProNet\Model\Address;
use App\BusProNet\Model\Insurance;
use App\BusProNet\Model\PersonalData;
use App\BusProNet\Model\Pickup;
@@ -56,11 +57,16 @@ class ParticipantDto
#[Assert\NotNull(message: 'Bitte angeben', groups: ['booking_edit', 'booking_create_step_2'])]
public ?\DateTimeImmutable $dateOfBirth = null;
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['booking_edit', 'booking_create_step_2'])]
#[Assert\Email(message: 'Bitte eine gültige E-Mail Adresse angeben', mode: 'strict', groups: ['booking_edit', 'booking_create_step_2'])]
public ?string $email = null;
public ?string $mobile = null;
#[Assert\Valid(groups: ['booking_edit', 'booking_create_step_2'])]
#[Assert\NotNull(message: 'Bitte Adresse angeben', groups: ['applicant_address'])]
public ?Address $address = null;
#[Assert\NotNull(message: 'Bitte ein Zimmer auswählen', groups: ['booking_create_step_2'])]
public ?int $assignedRoomId = null;
@@ -104,6 +110,11 @@ class ParticipantDto
*/
public array $notifications = [];
public function __construct()
{
$this->address = new Address();
}
public static function fromPersonalData(PersonalData $personalData): static
{
$instance = new static();
@@ -85,8 +85,9 @@ class ParticipantBulkInsuranceFieldHandler extends AbstractParticipantFieldHandl
$this->applyBulkInsuranceToAllParticipants($bookingDto, $participant->insurance);
}
// If bulk insurance is disabled, clear dependent participants' insurances
if (false === $isBulkEnabled) {
// If bulk insurance was CHANGED from enabled to disabled, clear dependent participants' insurances
// Don't clear if it was never enabled (to allow independent insurance selection)
if (false === $isBulkEnabled && $this->wasBulkInsurancePreviouslyEnabled($bookingDto)) {
$this->clearDependentParticipantsInsurance($bookingDto);
}
}
@@ -97,8 +98,8 @@ class ParticipantBulkInsuranceFieldHandler extends AbstractParticipantFieldHandl
* Uses InsuranceMatchingService to find the appropriate price tier for each participant
* based on their individual travel price and eligibility criteria.
*
* @param BookingCreateDto $bookingDto The booking DTO with all participants
* @param object $applicantInsurance The insurance selected by the applicant
* @param BookingCreateDto $bookingDto The booking DTO with all participants
* @param object $applicantInsurance The insurance selected by the applicant
*/
private function applyBulkInsuranceToAllParticipants(BookingCreateDto $bookingDto, object $applicantInsurance): void
{
@@ -139,4 +140,38 @@ class ParticipantBulkInsuranceFieldHandler extends AbstractParticipantFieldHandl
$participant->insurance = null;
}
}
}
/**
* Checks if bulk insurance was previously enabled by checking if dependent participants
* have the same insurance type as the applicant.
*
* This prevents clearing independent insurance selections when the checkbox is simply unchecked
* without ever having been enabled.
*
* @param BookingCreateDto $bookingDto The booking DTO with all participants
*
* @return bool True if bulk was previously active (dependent participants have matching insurance)
*/
private function wasBulkInsurancePreviouslyEnabled(BookingCreateDto $bookingDto): bool
{
$applicant = $bookingDto->participants[0] ?? null;
if (null === $applicant || null === $applicant->insurance) {
return false;
}
// Check if any dependent participant has insurance that matches the applicant
// If so, bulk was likely previously enabled
foreach ($bookingDto->participants as $index => $participant) {
if (0 === $index) {
continue; // Skip applicant
}
if (null !== $participant->insurance) {
// If any dependent has insurance, assume bulk was previously enabled
return true;
}
}
return false;
}
}