diff --git a/src/BusProNet/Model/Service.php b/src/BusProNet/Model/Service.php index 751f093..5c8c011 100644 --- a/src/BusProNet/Model/Service.php +++ b/src/BusProNet/Model/Service.php @@ -79,4 +79,10 @@ class Service #[Groups(['api:single', 'api:list'])] public ?string $direction = null; + + #[Groups(['api:single', 'api:list'])] + public ?int $ageFrom = null; + + #[Groups(['api:single', 'api:list'])] + public ?int $ageTo = null; } diff --git a/src/BusProNet/XmlLoader/TravelLoader.php b/src/BusProNet/XmlLoader/TravelLoader.php index d20edd2..8c6d241 100644 --- a/src/BusProNet/XmlLoader/TravelLoader.php +++ b/src/BusProNet/XmlLoader/TravelLoader.php @@ -203,6 +203,8 @@ class TravelLoader extends AbstractLoader $service->price = $this ->stringToFloat($this->getStringOrNullValue($serviceNode->filterXPath('//preis'))); $service->status = $this->getStringOrNullValue($serviceNode->filterXPath('//status')); + $service->ageFrom = $this->getIntOrNullValue($serviceNode->filterXPath('//altervon')); + $service->ageTo = $this->getIntOrNullValue($serviceNode->filterXPath('//alterbis')); $additionalServices[$serviceId] = $service; }); diff --git a/src/BusProNet/XmlParser/ServicesParser.php b/src/BusProNet/XmlParser/ServicesParser.php index 7142821..13e1d4d 100644 --- a/src/BusProNet/XmlParser/ServicesParser.php +++ b/src/BusProNet/XmlParser/ServicesParser.php @@ -34,6 +34,9 @@ class ServicesParser extends AbstractParser $service->direction = $node->attr('richtung'); } + $service->ageFrom = $this->getIntOrNullValue($node->filterXPath('//altervon')); + $service->ageTo = $this->getIntOrNullValue($node->filterXPath('//alterbis')); + $services[$service->id] = $service; }); diff --git a/src/Form/Model/ParticipantData.php b/src/Form/Model/ParticipantData.php index 2334f30..63158dd 100644 --- a/src/Form/Model/ParticipantData.php +++ b/src/Form/Model/ParticipantData.php @@ -68,6 +68,17 @@ class ParticipantData return $instance; } + public function getAge(): ?int + { + if (null === $this->dateOfBirth) { + return null; + } + + $today = new \DateTimeImmutable('today'); + + return $this->dateOfBirth->diff($today)->y; + } + public function isCanceled(): bool { return 'S' === $this->status; diff --git a/src/Form/ParticipantType.php b/src/Form/ParticipantType.php index 6a81ac8..580d6da 100644 --- a/src/Form/ParticipantType.php +++ b/src/Form/ParticipantType.php @@ -209,18 +209,20 @@ class ParticipantType extends AbstractType 'choices' => $options['selectable_courses'], ]); } - if (0 < count($options['selectable_services'])) { + $additionalServices = $this->filterServicesByAge($participantData->getAge(), $options['selectable_services']); + if (0 < count($additionalServices)) { $form->add('additionalServices', ChoiceType::class, [ ...$commonChoiceFieldOptions, 'label' => 'Zusatzleistungen', - 'choices' => $options['selectable_services'], + 'choices' => $additionalServices, ]); } - if (0 < count($options['selectable_ski_passes'])) { + $skiPasses = $this->filterServicesByAge($participantData->getAge(), $options['selectable_ski_passes']); + if (0 < count($skiPasses)) { $form->add('skiPass', ChoiceType::class, [ ...$commonChoiceFieldOptions, 'label' => 'Skipass', - 'choices' => $options['selectable_ski_passes'], + 'choices' => $skiPasses, ]); } if (0 < count($options['selectable_board'])) { @@ -336,8 +338,18 @@ class ParticipantType extends AbstractType unset($data['pickup']); } + // filter selectable services by participant's age + if (false === isset($data['dateOfBirth'])) { + $allServices = $options['selectable_services']; + } else { + $dateOfBirth = new \DateTimeImmutable($data['dateOfBirth']); + $today = new \DateTimeImmutable('today'); + $age = $dateOfBirth->diff($today)->y; + $allServices = $this->filterServicesByAge($age, $options['selectable_services']); + } + // forcibly select mandatory services that potentially have been disabled in PRE_SET_DATA - $mandatoryServices = array_filter($options['selectable_services'], function (Service $service) use ($form) { + $mandatoryServices = array_filter($allServices, function (Service $service) use ($form) { $participantIndex = $form->getData()->index; return true === $service->mandatory @@ -361,6 +373,26 @@ class ParticipantType extends AbstractType }); } + private function filterServicesByAge(?int $age, array $services): array + { + if (null === $age) { + return $services; + } + + return array_filter($services, function (Service $service) use ($age) { + if (null === $service->ageFrom && null === $service->ageTo) { + return true; + } + if ( + null !== $service->ageTo && $service->ageTo >= $age + && null !== $service->ageFrom && $service->ageFrom <= $age + ) { + return true; + } + return false; + }); + } + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([