diff --git a/config/services.yaml b/config/services.yaml index b04fcf1..0c126bb 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -86,8 +86,7 @@ services: - 'App\Form\Service\ParticipantSkiPassFieldHandler' - 'App\Form\Service\ParticipantTransportationOutboundFieldHandler' - 'App\Form\Service\ParticipantTransportationInboundFieldHandler' - - 'App\Form\Service\ParticipantPickupOutboundFieldHandler' - - 'App\Form\Service\ParticipantPickupInboundFieldHandler' + - 'App\Form\Service\ParticipantPickupFieldHandler' - 'App\Form\Service\ParticipantParkingFieldHandler' - 'App\Form\Service\ParticipantRentalInsuranceFieldHandler' - 'App\Form\Service\ParticipantLicensePlateFieldHandler' diff --git a/src/BusProNet/DataProcessor/BookingDataProcessor.php b/src/BusProNet/DataProcessor/BookingDataProcessor.php index 00842d2..4f4607b 100644 --- a/src/BusProNet/DataProcessor/BookingDataProcessor.php +++ b/src/BusProNet/DataProcessor/BookingDataProcessor.php @@ -178,7 +178,11 @@ class BookingDataProcessor */ private function processPickupLocations(object $participant, object $bookingData): void { - if ('BUS' === $participant->transportationOutbound->subType && null !== $selectedPickup = $participant->pickupOutbound) { + // Check if either transportation direction is BUS and pickup is selected + $hasOutboundBus = null !== $participant->transportationOutbound && 'BUS' === $participant->transportationOutbound->subType; + $hasInboundBus = null !== $participant->transportationInbound && 'BUS' === $participant->transportationInbound->subType; + + if (($hasOutboundBus || $hasInboundBus) && null !== $selectedPickup = $participant->pickup) { if (false === isset($bookingData->pickupsOutbound[$selectedPickup->id])) { $bookingData->pickupsOutbound[$selectedPickup->id] = $selectedPickup; } @@ -729,8 +733,8 @@ class BookingDataProcessor /** * Collects pickup location mappings. * - * Only collects outbound pickups as the API doesn't support different pickups - * for inbound direction. Both directions use the same pickup location. + * Collects the unified pickup selection which applies to both directions. + * The API receives this as outbound pickup data. * * @return array> Map of pickup ID to participant IDs */ @@ -741,9 +745,8 @@ class BookingDataProcessor foreach ($bookingDto->participants as $index => $participant) { $participantId = $index + 1; - // Only use outbound pickups (inbound uses same location) - if (null !== $participant->pickupOutbound) { - $pickupMap[$participant->pickupOutbound->id][] = $participantId; + if (null !== $participant->pickup) { + $pickupMap[$participant->pickup->id][] = $participantId; } } diff --git a/src/Form/BookingEditParticipantType.php b/src/Form/BookingEditParticipantType.php index 49e3197..ff16c07 100644 --- a/src/Form/BookingEditParticipantType.php +++ b/src/Form/BookingEditParticipantType.php @@ -231,9 +231,9 @@ class BookingEditParticipantType extends AbstractType 'choice_attr' => $transportationChoiceAttributes, ]); - // Pickup - $form->add('pickupOutbound', ChoiceType::class, [ - 'label' => 'Zustieg', + // Pickup (unified for both directions) + $form->add('pickup', ChoiceType::class, [ + 'label' => 'Zu- und Ausstieg', 'multiple' => false, 'expanded' => false, 'choices' => $options['selectable_pickups'], @@ -323,8 +323,8 @@ class BookingEditParticipantType extends AbstractType $transportation = $options['travel']->pickups[$transportationId] ?? null; if (null !== $transportation && 'PKW' === $transportation->subType) { - $form->remove('pickupOutbound'); - unset($data['pickupOutbound']); + $form->remove('pickup'); + unset($data['pickup']); } // forcibly select mandatory services that potentially have been disabled in PRE_SET_DATA diff --git a/src/Form/BookingParticipantType.php b/src/Form/BookingParticipantType.php index d3a70b1..f0b191a 100644 --- a/src/Form/BookingParticipantType.php +++ b/src/Form/BookingParticipantType.php @@ -233,8 +233,7 @@ class BookingParticipantType extends AbstractType 'skiPass' => ChoiceType::class, 'transportationOutbound' => ChoiceType::class, 'transportationInbound' => ChoiceType::class, - 'pickupOutbound' => ChoiceType::class, - 'pickupInbound' => ChoiceType::class, + 'pickup' => ChoiceType::class, 'parking' => CheckboxType::class, 'licensePlate' => TextType::class, 'bulkInsuranceBooking' => CheckboxType::class, diff --git a/src/Form/Model/BookingEditDto.php b/src/Form/Model/BookingEditDto.php index 0c4aa50..cc49552 100644 --- a/src/Form/Model/BookingEditDto.php +++ b/src/Form/Model/BookingEditDto.php @@ -57,8 +57,8 @@ class BookingEditDto implements BookingDtoInterface $participantData->transportationInbound = $inboundTransportation; // Pickup handling (currently only supports outbound pickup) - $pickupOutbound = $booking->getPickupForParticipant($index); - $participantData->pickupOutbound = $pickupOutbound; + $pickup = $booking->getPickupForParticipant($index); + $participantData->pickup = $pickup; $instance->participants[$index] = $participantData; } diff --git a/src/Form/Model/ParticipantDto.php b/src/Form/Model/ParticipantDto.php index b208307..c3a1175 100644 --- a/src/Form/Model/ParticipantDto.php +++ b/src/Form/Model/ParticipantDto.php @@ -27,8 +27,7 @@ class ParticipantDto 'skiPass', 'transportationOutbound', 'transportationInbound', - 'pickupOutbound', - 'pickupInbound', + 'pickup', 'parking', 'licensePlate', 'bulkInsuranceBooking', @@ -86,9 +85,8 @@ class ParticipantDto public ?Service $transportationOutbound = null; public ?Service $transportationInbound = null; - // Pickup locations for each direction - public ?Pickup $pickupOutbound = null; - public ?Pickup $pickupInbound = null; + // Pickup location (applies to both directions) + public ?Pickup $pickup = null; // Parking service for self-organized transportation (boolean: true if parking requested) public bool $parking = false; diff --git a/src/Form/Service/CreateFieldStateProvider.php b/src/Form/Service/CreateFieldStateProvider.php index 2ab887f..e2ef97a 100644 --- a/src/Form/Service/CreateFieldStateProvider.php +++ b/src/Form/Service/CreateFieldStateProvider.php @@ -179,17 +179,13 @@ class CreateFieldStateProvider extends AbstractFieldStateProvider ), ]; - // Show outbound pickup only when transportation is BUS (hidden by default) - $this->fieldStateConditions['pickupOutbound'] = [ + // Show pickup only when either outbound or inbound transportation is BUS (hidden by default) + $this->fieldStateConditions['pickup'] = [ 'hidden' => CompositeCondition::not( - ServiceSubTypeCondition::equals('transportationOutbound', DirectionMapper::SUBTYPE_BUS_API) - ), - ]; - - // Show inbound pickup only when transportation is BUS (hidden by default) - $this->fieldStateConditions['pickupInbound'] = [ - 'hidden' => CompositeCondition::not( - ServiceSubTypeCondition::equals('transportationInbound', DirectionMapper::SUBTYPE_BUS_API) + CompositeCondition::or( + ServiceSubTypeCondition::equals('transportationOutbound', DirectionMapper::SUBTYPE_BUS_API), + ServiceSubTypeCondition::equals('transportationInbound', DirectionMapper::SUBTYPE_BUS_API) + ) ), ]; diff --git a/src/Form/Service/EditFieldStateProvider.php b/src/Form/Service/EditFieldStateProvider.php index ca0dc67..150125e 100644 --- a/src/Form/Service/EditFieldStateProvider.php +++ b/src/Form/Service/EditFieldStateProvider.php @@ -121,17 +121,13 @@ class EditFieldStateProvider extends AbstractFieldStateProvider 'readonly' => $transportationServicesMutabilityCondition, ]; - // Pickup fields - shown only when transportation is BUS, readonly if pickups not mutable - $this->fieldStateConditions['pickupOutbound'] = [ + // Pickup field (unified) - shown only when either transportation direction is BUS, readonly if pickups not mutable + $this->fieldStateConditions['pickup'] = [ 'hidden' => CompositeCondition::not( - ServiceSubTypeCondition::equals('transportationOutbound', DirectionMapper::SUBTYPE_BUS_API) - ), - 'readonly' => $pickupsMutabilityCondition, - ]; - - $this->fieldStateConditions['pickupInbound'] = [ - 'hidden' => CompositeCondition::not( - ServiceSubTypeCondition::equals('transportationInbound', DirectionMapper::SUBTYPE_BUS_API) + CompositeCondition::or( + ServiceSubTypeCondition::equals('transportationOutbound', DirectionMapper::SUBTYPE_BUS_API), + ServiceSubTypeCondition::equals('transportationInbound', DirectionMapper::SUBTYPE_BUS_API) + ) ), 'readonly' => $pickupsMutabilityCondition, ]; diff --git a/src/Form/Service/ParticipantFieldOptionsProvider.php b/src/Form/Service/ParticipantFieldOptionsProvider.php index 7d55cb0..bd16376 100644 --- a/src/Form/Service/ParticipantFieldOptionsProvider.php +++ b/src/Form/Service/ParticipantFieldOptionsProvider.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace App\Form\Service; use App\BusProNet\Constants; -use App\BusProNet\Model\Insurance; use App\BusProNet\Model\Pickup; use App\BusProNet\Model\Service; use App\BusProNet\Utility\DirectionMapper; @@ -377,28 +376,17 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider ], ]; - // Outbound Pickup (conditional - only shown when outbound transportation is bus) - $this->fieldOptionProviders['pickupOutbound'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [ - 'label' => 'Zustieg Hinfahrt', + // Pickup (conditional - only shown when either transportation direction is bus) + // Uses outbound pickups list, applies to both directions + $this->fieldOptionProviders['pickup'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [ + 'label' => 'Zu- und Ausstieg', 'choices' => $bookingDto->travel->pickupsOutbound, 'choice_label' => fn (?Pickup $pickup) => $this->formatPickupLabelWithPrice($pickup), 'choice_value' => 'id', 'expanded' => false, // Dropdown for pickups 'multiple' => false, 'required' => true, - 'placeholder' => 'Zustieg auswählen', - ]; - - // Inbound Pickup (conditional - only shown when inbound transportation is bus) - $this->fieldOptionProviders['pickupInbound'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [ - 'label' => 'Ausstieg Rückfahrt', - 'choices' => $bookingDto->travel->pickupsInbound, - 'choice_label' => fn (?Pickup $pickup) => $this->formatPickupLabelWithPrice($pickup), - 'choice_value' => 'id', - 'expanded' => false, - 'multiple' => false, - 'required' => true, - 'placeholder' => 'Ausstieg auswählen', + 'placeholder' => 'Zu- und Ausstieg auswählen', ]; // Parking (conditional - only shown when outbound transportation is PKW) @@ -574,29 +562,6 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider return $this->formatServiceLabelWithPrice($parkingService); } - /** - * Filters services based on remaining availability in the current booking session. - * - * Removes services that have been fully booked by other participants in - * the current booking session. This prevents overbooking within a single - * booking workflow while maintaining accurate availability counts. - * - * @param array $services Array of Service objects to filter - * @param BookingDtoInterface $bookingDto The booking DTO containing participant data - * @param int $participantIndex Index of the participant currently selecting services - * - * @return array Filtered array containing only services with remaining availability - */ - private function filterServicesByAvailability(array $services, BookingDtoInterface $bookingDto, int $participantIndex): array - { - if (!$bookingDto instanceof BookingCreateDto) { - // For non-create workflows, return all services (no availability tracking needed) - return $services; - } - - return $this->serviceAvailabilityCalculator->filterAvailableServices($services, $bookingDto, $participantIndex); - } - /** * Checks if a service should be rendered as read-only due to unavailability. * @@ -710,27 +675,4 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider $bookingDto ); } - - /** - * Formats insurance label with pricing and type information. - * - * @param Insurance|null $insurance The insurance to format, or null for "No Insurance" option - * - * @return string The formatted insurance label - */ - private function formatInsuranceLabel(?Insurance $insurance): string - { - if (null === $insurance) { - return 'Keine Versicherung'; - } - - $label = $insurance->label; - - // Add pricing information (consistent with other services) - if (null !== $insurance->price && $insurance->price > 0) { - $label .= sprintf(' (€%s)', number_format($insurance->price, 2, ',', '.')); - } - - return $label; - } } diff --git a/src/Form/Service/ParticipantInsuranceFieldHandler.php b/src/Form/Service/ParticipantInsuranceFieldHandler.php index 737d2c5..f1a3ab5 100644 --- a/src/Form/Service/ParticipantInsuranceFieldHandler.php +++ b/src/Form/Service/ParticipantInsuranceFieldHandler.php @@ -69,8 +69,7 @@ class ParticipantInsuranceFieldHandler extends AbstractParticipantFieldHandler 'board', // Affects travel price 'transportationOutbound', // Affects travel price 'transportationInbound', // Affects travel price - 'pickupOutbound', // Affects travel price - 'pickupInbound', // Affects travel price + 'pickup', // Affects travel price 'parking', // Affects travel price ]; } diff --git a/src/Form/Service/ParticipantPickupOutboundFieldHandler.php b/src/Form/Service/ParticipantPickupFieldHandler.php similarity index 56% rename from src/Form/Service/ParticipantPickupOutboundFieldHandler.php rename to src/Form/Service/ParticipantPickupFieldHandler.php index 5585cb2..0c315ff 100644 --- a/src/Form/Service/ParticipantPickupOutboundFieldHandler.php +++ b/src/Form/Service/ParticipantPickupFieldHandler.php @@ -10,36 +10,26 @@ use App\Form\Model\BookingDtoInterface; use App\Form\Service\Abstract\AbstractParticipantFieldHandler; /** - * Handles outbound pickup location selection. + * Handles unified pickup location selection. * - * Pickup selection is only processed when outbound transportation - * is bus type. Automatically clears pickup when transportation - * changes to self-organized (PKW). + * Pickup selection is only processed when either outbound or inbound + * transportation is bus type. Automatically clears pickup when both + * transportation services change to self-organized (PKW). + * + * The pickup applies to both directions and uses the outbound pickup list. */ -class ParticipantPickupOutboundFieldHandler extends AbstractParticipantFieldHandler +class ParticipantPickupFieldHandler extends AbstractParticipantFieldHandler { public function getFieldName(): string { - return 'pickupOutbound'; + return 'pickup'; } public function getDependencies(): array { - return ['transportationOutbound']; // Must process transportation first + return ['transportationOutbound', 'transportationInbound']; } - /** - * Determines if this handler should process the field based on submitted data. - * - * For pickup selection fields, we always need to process to handle cases - * where the pickup is cleared due to transportation changes. This ensures the - * participant DTO is updated correctly when transportation switches from bus to PKW. - * - * @param array $submittedData The submitted participant form data - * @param int $participantIndex The index of the participant being processed - * - * @return bool Always returns true for pickup selection fields - */ public function shouldProcess(array $submittedData, int $participantIndex): bool { return true; // Always process to handle clearing pickup @@ -52,10 +42,15 @@ class ParticipantPickupOutboundFieldHandler extends AbstractParticipantFieldHand return; } - // Only process pickup if outbound transportation is bus - if (null === $participant->transportationOutbound || DirectionMapper::SUBTYPE_BUS_API !== $participant->transportationOutbound->subType) { - $participant->pickupOutbound = null; // Clear pickup for non-bus transport - $participant->pickup = null; // Backward compatibility + // Check if either outbound or inbound transportation is bus + $hasOutboundBus = null !== $participant->transportationOutbound + && DirectionMapper::SUBTYPE_BUS_API === $participant->transportationOutbound->subType; + $hasInboundBus = null !== $participant->transportationInbound + && DirectionMapper::SUBTYPE_BUS_API === $participant->transportationInbound->subType; + + // Only process pickup if at least one direction has bus transport + if (false === $hasOutboundBus && false === $hasInboundBus) { + $participant->pickup = null; // Clear pickup for non-bus transport return; } @@ -68,8 +63,7 @@ class ParticipantPickupOutboundFieldHandler extends AbstractParticipantFieldHand $validSelection = $this->findValidPickup($selectedPickup, $bookingDto->travel->pickupsOutbound); } - $participant->pickupOutbound = $validSelection; - $participant->pickup = $validSelection; // Backward compatibility + $participant->pickup = $validSelection; } /** @@ -96,4 +90,4 @@ class ParticipantPickupOutboundFieldHandler extends AbstractParticipantFieldHand return null; } -} +} \ No newline at end of file diff --git a/src/Form/Service/ParticipantPickupInboundFieldHandler.php b/src/Form/Service/ParticipantPickupInboundFieldHandler.php deleted file mode 100644 index eee134b..0000000 --- a/src/Form/Service/ParticipantPickupInboundFieldHandler.php +++ /dev/null @@ -1,97 +0,0 @@ - $submittedData The submitted participant form data - * @param int $participantIndex The index of the participant being processed - * - * @return bool Always returns true for pickup selection fields - */ - public function shouldProcess(array $submittedData, int $participantIndex): bool - { - return true; // Always process to handle clearing pickup - } - - public function processField(array $submittedData, BookingDtoInterface $bookingDto, int $participantIndex): void - { - $participant = $this->getParticipant($bookingDto, $participantIndex); - if (null === $participant) { - return; - } - - // Only process pickup if inbound transportation is bus - if (null === $participant->transportationInbound || DirectionMapper::SUBTYPE_BUS_API !== $participant->transportationInbound->subType) { - $participant->pickupInbound = null; // Clear pickup for non-bus transport - - return; - } - - $selectedPickup = $this->getFieldValue($submittedData, $this->getFieldName()); - - // Validate pickup selection against available inbound pickups - $validSelection = null; - if (null !== $selectedPickup) { - $validSelection = $this->findValidPickup($selectedPickup, $bookingDto->travel->pickupsInbound); - } - - $participant->pickupInbound = $validSelection; - } - - /** - * Finds a valid pickup from available pickups. - * - * @param mixed $selectedPickupId The submitted pickup ID - * @param array $availablePickups Array of available pickup locations - * - * @return Pickup|null The valid pickup object, or null if invalid - */ - private function findValidPickup(mixed $selectedPickupId, array $availablePickups): ?Pickup - { - if (null === $selectedPickupId || false === is_string($selectedPickupId) && false === is_int($selectedPickupId)) { - return null; - } - - $pickupId = (int) $selectedPickupId; - - foreach ($availablePickups as $pickup) { - if ($pickup->id === $pickupId) { - return $pickup; - } - } - - return null; - } -} diff --git a/src/Service/BookingPriceCalculatorService.php b/src/Service/BookingPriceCalculatorService.php index 560b0f5..3df563f 100644 --- a/src/Service/BookingPriceCalculatorService.php +++ b/src/Service/BookingPriceCalculatorService.php @@ -333,14 +333,9 @@ class BookingPriceCalculatorService $participantPickupCost += $participant->transportationInbound->price; } - // Pickup pricing (outbound) - if (null !== $participant->pickupOutbound && null !== $participant->pickupOutbound->price) { - $participantPickupCost += $participant->pickupOutbound->price; - } - - // Pickup pricing (inbound) - if (null !== $participant->pickupInbound && null !== $participant->pickupInbound->price) { - $participantPickupCost += $participant->pickupInbound->price; + // Pickup pricing (unified for both directions) + if (null !== $participant->pickup && null !== $participant->pickup->price) { + $participantPickupCost += $participant->pickup->price; } // Parking service pricing @@ -563,12 +558,8 @@ class BookingPriceCalculatorService $serviceTotal += $participant->transportationInbound->price; } - if (null !== $participant->pickupOutbound && null !== $participant->pickupOutbound->price) { - $serviceTotal += $participant->pickupOutbound->price; - } - - if (null !== $participant->pickupInbound && null !== $participant->pickupInbound->price) { - $serviceTotal += $participant->pickupInbound->price; + if (null !== $participant->pickup && null !== $participant->pickup->price) { + $serviceTotal += $participant->pickup->price; } if (null !== $participant->parkingService && null !== $participant->parkingService->price) { diff --git a/src/Validator/Constraints/ParticipantValidator.php b/src/Validator/Constraints/ParticipantValidator.php index e7e3e36..4224fa2 100644 --- a/src/Validator/Constraints/ParticipantValidator.php +++ b/src/Validator/Constraints/ParticipantValidator.php @@ -54,13 +54,16 @@ class ParticipantValidator extends ConstraintValidator public function assertPickupSelected(ParticipantDto $participant): void { - if ( - null !== $participant->transportationOutbound - && 'BUS' === $participant->transportationOutbound->subType - && null === $participant->pickupOutbound - ) { + // Check if either outbound or inbound transportation is bus + $hasOutboundBus = null !== $participant->transportationOutbound + && 'BUS' === $participant->transportationOutbound->subType; + $hasInboundBus = null !== $participant->transportationInbound + && 'BUS' === $participant->transportationInbound->subType; + + // Require pickup if at least one direction has bus transport + if (($hasOutboundBus || $hasInboundBus) && null === $participant->pickup) { $this->context->buildViolation('Bitte auswählen') - ->atPath('pickupOutbound') + ->atPath('pickup') ->addViolation() ; } diff --git a/templates/booking/create_step_2.html.twig b/templates/booking/create_step_2.html.twig index fd21928..5af0030 100644 --- a/templates/booking/create_step_2.html.twig +++ b/templates/booking/create_step_2.html.twig @@ -103,15 +103,12 @@ {{ form_row(participant.mobile) }} {% if participant.address is defined %} -
- {{ participant.address.vars.label }} -
- {{ form_row(participant.address.street) }} - {{ form_row(participant.address.postCode) }} - {{ form_row(participant.address.city) }} - {{ form_row(participant.address.country) }} -
-
+
+ {{ form_row(participant.address.street) }} + {{ form_row(participant.address.postCode) }} + {{ form_row(participant.address.city) }} + {{ form_row(participant.address.country) }} +
{% endif %} {% if participant.bodyDimensions is defined %}
@@ -268,34 +265,35 @@ } }) }} {% endif %} - {% if participant.pickupOutbound is defined %} -
- {{ form_row(participant.pickupOutbound, { - 'attr': { - 'hx-trigger': 'change', - 'hx-post': path('app_booking_create_step_2_refresh'), - 'hx-swap': 'none' - } - }) }} -
+ {% if participant.pickup is defined or participant.parking is defined or participant.licensePlate is defined %} + {% if participant.pickup is defined %} +
+ {{ form_row(participant.pickup, { + 'attr': { + 'hx-trigger': 'change', + 'hx-post': path('app_booking_create_step_2_refresh'), + 'hx-swap': 'none' + } + }) }} +
+ {% endif %} + {% if participant.parking is defined %} +
+ {{ form_row(participant.parking, { + 'attr': { + 'hx-trigger': 'change', + 'hx-post': path('app_booking_create_step_2_refresh'), + 'hx-swap': 'none' + } + }) }} +
+ {% endif %} + {% if participant.licensePlate is defined %} +
+ {{ form_row(participant.licensePlate) }} +
+ {% endif %} {% endif %} - {% if participant.parking is defined %} -
- {{ form_row(participant.parking, { - 'attr': { - 'hx-trigger': 'change', - 'hx-post': path('app_booking_create_step_2_refresh'), - 'hx-swap': 'none' - } - }) }} -
- {% endif %} - {% if participant.licensePlate is defined %} -
- {{ form_row(participant.licensePlate) }} -
- {% endif %} -
{% if participant.transportationInbound is defined %} @@ -307,17 +305,6 @@ } }) }} {% endif %} - {% if participant.pickupInbound is defined %} -
- {{ form_row(participant.pickupInbound, { - 'attr': { - 'hx-trigger': 'change', - 'hx-post': path('app_booking_create_step_2_refresh'), - 'hx-swap': 'none' - } - }) }} -
- {% endif %}
diff --git a/templates/booking/create_step_4.html.twig b/templates/booking/create_step_4.html.twig index bb8c956..dcbf27b 100644 --- a/templates/booking/create_step_4.html.twig +++ b/templates/booking/create_step_4.html.twig @@ -128,17 +128,11 @@ {% endif %} - {# Pickup Locations #} - {% if participant.pickupOutbound %} + {# Pickup Location #} + {% if participant.pickup %}
-
Zustieg Hinfahrt
-
{{ participant.pickupOutbound.label }}
-
- {% endif %} - {% if participant.pickupInbound %} -
-
Zustieg Rückfahrt
-
{{ participant.pickupInbound.label }}
+
Zu- und Ausstieg
+
{{ participant.pickup.label }}
{% endif %} diff --git a/templates/booking/edit.html.twig b/templates/booking/edit.html.twig index aafff01..ea051d6 100644 --- a/templates/booking/edit.html.twig +++ b/templates/booking/edit.html.twig @@ -336,9 +336,9 @@ } }) }} {% endif %} - {% if participant.pickupOutbound is defined %} + {% if participant.pickup is defined %}
- {{ form_row(participant.pickupOutbound, { + {{ form_row(participant.pickup, { 'attr': { 'hx-trigger': 'change', 'hx-post': path('app_booking_edit_refresh', {'id': bookingData.id}), @@ -381,17 +381,7 @@ } }) }} {% endif %} - {% if participant.pickupInbound is defined %} -
- {{ form_row(participant.pickupInbound, { - 'attr': { - 'hx-trigger': 'change', - 'hx-post': path('app_booking_edit_refresh', {'id': bookingData.id}), - 'hx-swap': 'none' - } - }) }} -
- {% endif %} + {# Pickup inbound removed - now unified with pickup field #}
diff --git a/tests/BusProNet/DataProcessor/BookingDataProcessorTest.php b/tests/BusProNet/DataProcessor/BookingDataProcessorTest.php index d002a74..7e78016 100644 --- a/tests/BusProNet/DataProcessor/BookingDataProcessorTest.php +++ b/tests/BusProNet/DataProcessor/BookingDataProcessorTest.php @@ -262,7 +262,7 @@ class BookingDataProcessorTest extends TestCase $busService = $this->createMockService(1); $busService->subType = 'BUS'; $participant->transportationOutbound = $busService; - $participant->pickupOutbound = $this->createMockPickup(1); + $participant->pickup = $this->createMockPickup(1); return $formData; } @@ -456,7 +456,7 @@ class BookingDataProcessorTest extends TestCase $participant->rentals = []; $participant->transportationOutbound = $this->createMockService(1); $participant->transportationInbound = $this->createMockService(2); - $participant->pickupOutbound = null; + $participant->pickup = null; return $participant; } diff --git a/tests/Validator/Constraints/ParticipantValidatorTest.php b/tests/Validator/Constraints/ParticipantValidatorTest.php index 6064a3a..32ca795 100644 --- a/tests/Validator/Constraints/ParticipantValidatorTest.php +++ b/tests/Validator/Constraints/ParticipantValidatorTest.php @@ -112,12 +112,12 @@ class ParticipantValidatorTest extends ConstraintValidatorTestCase $busService = new Service(); $busService->subType = 'BUS'; $participant->transportationOutbound = $busService; - $participant->pickupOutbound = null; + $participant->pickup = null; $this->validator->validate($participant, new Participant()); $this->buildViolation('Bitte auswählen') - ->atPath('property.path.pickupOutbound') + ->atPath('property.path.pickup') ->assertRaised(); } @@ -128,7 +128,7 @@ class ParticipantValidatorTest extends ConstraintValidatorTestCase $trainService = new Service(); $trainService->subType = 'TRAIN'; $participant->transportationOutbound = $trainService; - $participant->pickupOutbound = null; // Not required for non-bus + $participant->pickup = null; // Not required for non-bus $this->validator->validate($participant, new Participant());