wip: skipass-duration based rentals filtering

This commit is contained in:
Björn Fromme
2025-09-10 14:26:18 +02:00
parent 5469c834a6
commit b6f991b291
8 changed files with 288 additions and 17 deletions
@@ -183,7 +183,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
'choice_label' => fn (?Service $service) => $this->formatServiceLabelWithPrice($service),
];
// Rentals field provider - provides age-appropriate rental options from travel data filtered by date range
// Rentals field provider - provides age-appropriate rental options filtered by selected skipass duration
$this->fieldOptionProviders['rentals'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
'label' => 'Leihmaterial',
'multiple' => true,
@@ -191,7 +191,11 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
'required' => false,
'choices' => $this->filterServicesByAvailability(
$this->filterServicesByAgeConstraints(
$bookingDto->travel->getAdditionalServicesBySubTypes(Constants::TOKEN_RENTALS, true, true),
$this->filterRentalsBySkiPassDuration(
$bookingDto->travel->getAdditionalServicesBySubTypes(Constants::TOKEN_RENTALS, true, true),
$bookingDto,
$participantIndex
),
$bookingDto,
$participantIndex
),
@@ -364,6 +368,45 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
// ];
}
/**
* Filters rental services by selected skipass duration.
*
* Only returns rentals that have exactly the same dateFrom and dateTo
* as the participant's selected skipass. This ensures rental equipment
* is only available for the exact duration of the skipass.
*
* @param array $rentals Array of rental Service objects to filter
* @param BookingDtoInterface $bookingDto The booking DTO containing participant data
* @param int $participantIndex Index of the participant to evaluate
*
* @return array Filtered array of rentals matching skipass duration
*/
private function filterRentalsBySkiPassDuration(array $rentals, BookingDtoInterface $bookingDto, int $participantIndex): array
{
$participant = $bookingDto->getParticipant($participantIndex);
if (null === $participant || null === $participant->skiPass) {
return []; // No skipass selected = no rentals available
}
$selectedSkiPass = $participant->skiPass;
// If skipass has no valid dates, return empty rentals
if (null === $selectedSkiPass->dateFrom || null === $selectedSkiPass->dateTo) {
return [];
}
return array_filter($rentals, function (Service $rental) use ($selectedSkiPass) {
// Rental must have valid dates to be considered
if (null === $rental->dateFrom || null === $rental->dateTo) {
return false;
}
// Exact date matching: rental dates must match skipass dates exactly
return $rental->dateFrom->format('Y-m-d') === $selectedSkiPass->dateFrom->format('Y-m-d')
&& $rental->dateTo->format('Y-m-d') === $selectedSkiPass->dateTo->format('Y-m-d');
});
}
/**
* Formats service label with pricing information.
*