diff --git a/src/BusProNet/Model/Travel.php b/src/BusProNet/Model/Travel.php index 88bd49d..ac2816c 100644 --- a/src/BusProNet/Model/Travel.php +++ b/src/BusProNet/Model/Travel.php @@ -95,14 +95,15 @@ class Travel * @param mixed $group The service group(s) to filter by * @param bool $availableOnly Whether to include only available services * - * @return array The filtered and sorted services array + * @return array The filtered and sorted services array */ public function getAdditionalServicesByGroup(mixed $group, bool $availableOnly = true): array { $group = (array) $group; $services = array_filter($this->additionalServices, function (Service $service) use ($group, $availableOnly) { - return true === in_array($service->subType, $group) && (false === $availableOnly || 0 < $service->available); + return true === in_array($service->subType, $group) + && (false === $availableOnly || 0 < $service->available || null === $service->available); }); usort($services, function (Service $a, Service $b) { @@ -121,14 +122,14 @@ class Travel * @param string $direction The travel direction to filter by * @param bool $availableOnly Whether to include only available services * - * @return array The filtered and sorted transportation services + * @return array The filtered and sorted transportation services */ public function getTransportationServicesByDirection(string $direction, bool $availableOnly = true): array { $services = array_filter($this->transportationServices, function (Service $service) use ($direction, $availableOnly) { return $direction === $service->direction && $service->price >= 0 - && (false === $availableOnly || $service->available > 0); + && (false === $availableOnly || $service->available > 0 || null === $service->available); }); usort($services, function (Service $a, Service $b) { @@ -144,7 +145,7 @@ class Travel * Maps selection group IDs to their corresponding services based on * the predefined included services mapping. * - * @return array The included services from selection groups + * @return array The included services from selection groups */ public function getIncludedServices(): array { @@ -168,7 +169,7 @@ class Travel * * @param array $ids The array of room IDs to filter by * - * @return array The filtered rooms array + * @return array The filtered rooms array */ public function getRoomsByIds(array $ids): array { @@ -198,6 +199,7 @@ class Travel $result[$room->id] = $room; } } + return $result; } } diff --git a/src/Form/BookingCreateParticipantType.php b/src/Form/BookingCreateParticipantType.php index bcbffad..7581f58 100644 --- a/src/Form/BookingCreateParticipantType.php +++ b/src/Form/BookingCreateParticipantType.php @@ -163,7 +163,7 @@ class BookingCreateParticipantType extends AbstractType */ private function addDynamicFields(FormInterface $form, BookingDtoInterface $bookingDto, int $participantIndex): void { - $dynamicFields = ['assignedRoomId']; // List of fields that need dynamic configuration + $dynamicFields = ['assignedRoomId', 'courses']; // List of fields that need dynamic configuration foreach ($dynamicFields as $fieldName) { if ($this->fieldOptionsProvider->hasFieldOptions($fieldName)) { diff --git a/src/Form/BookingEditType.php b/src/Form/BookingEditType.php index 6d4911a..158127b 100644 --- a/src/Form/BookingEditType.php +++ b/src/Form/BookingEditType.php @@ -17,7 +17,8 @@ class BookingEditType extends AbstractType { public function __construct( private readonly ParticipantFieldHandlerRegistry $participantFieldHandlerRegistry, - ) {} + ) { + } public function buildForm(FormBuilderInterface $builder, array $options): void { diff --git a/src/Form/Service/Abstract/AbstractFieldOptionsProvider.php b/src/Form/Service/Abstract/AbstractFieldOptionsProvider.php index 80becd4..0aca2fa 100644 --- a/src/Form/Service/Abstract/AbstractFieldOptionsProvider.php +++ b/src/Form/Service/Abstract/AbstractFieldOptionsProvider.php @@ -78,7 +78,7 @@ abstract class AbstractFieldOptionsProvider implements FieldOptionsProviderInter * Symfony form field options. * * Example implementation: - * + * * protected function registerFieldOptionProviders(): void * { * $this->fieldOptionProviders['fieldName'] = fn($bookingDto, $participantIndex) => [ @@ -88,4 +88,4 @@ abstract class AbstractFieldOptionsProvider implements FieldOptionsProviderInter * } */ abstract protected function registerFieldOptionProviders(): void; -} \ No newline at end of file +} diff --git a/src/Form/Service/ParticipantFieldOptionsProvider.php b/src/Form/Service/ParticipantFieldOptionsProvider.php index 9ed746b..a2453b8 100644 --- a/src/Form/Service/ParticipantFieldOptionsProvider.php +++ b/src/Form/Service/ParticipantFieldOptionsProvider.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace App\Form\Service; +use App\BusProNet\Constants; +use App\BusProNet\Model\Service; use App\Form\Model\BookingCreateDto; use App\Form\Model\BookingDtoInterface; use App\Form\Service\Abstract\AbstractFieldOptionsProvider; @@ -84,6 +86,23 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider : null, ]; + // Courses field provider - provides available courses from travel data + $this->fieldOptionProviders['courses'] = fn (BookingDtoInterface $bookingDto) => [ + 'label' => 'Kurse', + 'multiple' => true, + 'expanded' => true, + 'required' => false, + 'choices' => array_reduce( + $bookingDto->travel->getAdditionalServicesByGroup(Constants::TOKEN_COURSES), + function (array $choices, Service $service) { + $choices[$service->label] = $service->id; + + return $choices; + }, + [] + ), + ]; + // Future field providers would be added here, for example: // // $this->fieldOptionProviders['mealPreference'] = fn($bookingDto, $participantIndex) => [ diff --git a/templates/booking/create_step_2.html.twig b/templates/booking/create_step_2.html.twig index 59b248d..054d56f 100644 --- a/templates/booking/create_step_2.html.twig +++ b/templates/booking/create_step_2.html.twig @@ -40,7 +40,7 @@ {{ form_row(participant.bodyDimensions.shoeSize) }} {{ form_row(participant.bodyDimensions.weight) }} -
+
{# hx-swap="none" tells HTMX not to do a normal swap, as OOB will handle it #} {{ form_row(participant.assignedRoomId, { 'attr': { @@ -49,6 +49,11 @@ } }) }}
+
+ {% if participant.courses is defined %} + {{ form_row(participant.courses) }} + {% endif %} +