fix: filter selectable services by participant's age

This commit is contained in:
Björn Fromme
2025-09-10 15:25:30 +02:00
parent 7b25fbf28b
commit 297becf7a0
5 changed files with 59 additions and 5 deletions
+6
View File
@@ -79,4 +79,10 @@ class Service
#[Groups(['api:single', 'api:list'])] #[Groups(['api:single', 'api:list'])]
public ?string $direction = null; public ?string $direction = null;
#[Groups(['api:single', 'api:list'])]
public ?int $ageFrom = null;
#[Groups(['api:single', 'api:list'])]
public ?int $ageTo = null;
} }
+2
View File
@@ -203,6 +203,8 @@ class TravelLoader extends AbstractLoader
$service->price = $this $service->price = $this
->stringToFloat($this->getStringOrNullValue($serviceNode->filterXPath('//preis'))); ->stringToFloat($this->getStringOrNullValue($serviceNode->filterXPath('//preis')));
$service->status = $this->getStringOrNullValue($serviceNode->filterXPath('//status')); $service->status = $this->getStringOrNullValue($serviceNode->filterXPath('//status'));
$service->ageFrom = $this->getIntOrNullValue($serviceNode->filterXPath('//altervon'));
$service->ageTo = $this->getIntOrNullValue($serviceNode->filterXPath('//alterbis'));
$additionalServices[$serviceId] = $service; $additionalServices[$serviceId] = $service;
}); });
@@ -34,6 +34,9 @@ class ServicesParser extends AbstractParser
$service->direction = $node->attr('richtung'); $service->direction = $node->attr('richtung');
} }
$service->ageFrom = $this->getIntOrNullValue($node->filterXPath('//altervon'));
$service->ageTo = $this->getIntOrNullValue($node->filterXPath('//alterbis'));
$services[$service->id] = $service; $services[$service->id] = $service;
}); });
+11
View File
@@ -68,6 +68,17 @@ class ParticipantData
return $instance; 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 public function isCanceled(): bool
{ {
return 'S' === $this->status; return 'S' === $this->status;
+37 -5
View File
@@ -209,18 +209,20 @@ class ParticipantType extends AbstractType
'choices' => $options['selectable_courses'], '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, [ $form->add('additionalServices', ChoiceType::class, [
...$commonChoiceFieldOptions, ...$commonChoiceFieldOptions,
'label' => 'Zusatzleistungen', '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, [ $form->add('skiPass', ChoiceType::class, [
...$commonChoiceFieldOptions, ...$commonChoiceFieldOptions,
'label' => 'Skipass', 'label' => 'Skipass',
'choices' => $options['selectable_ski_passes'], 'choices' => $skiPasses,
]); ]);
} }
if (0 < count($options['selectable_board'])) { if (0 < count($options['selectable_board'])) {
@@ -336,8 +338,18 @@ class ParticipantType extends AbstractType
unset($data['pickup']); 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 // 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; $participantIndex = $form->getData()->index;
return true === $service->mandatory 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 public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([