feat: hide unavailable ski passes from selection in create flow

This commit is contained in:
Björn Fromme
2026-08-06 13:08:46 +02:00
parent b82e017f73
commit 6ee00f2bee
6 changed files with 329 additions and 30 deletions
+18 -15
View File
@@ -51,7 +51,9 @@ class ServiceAvailabilityCalculator
}
/**
* Filter services array to only include those with remaining availability.
* Filter services array to only include those that are still bookable.
*
* Delegates to isServiceUnavailable() so that both entry points share one rule set.
*
* @param array<int, Service> $services Array of Service objects to filter
* @param BookingDto $bookingDto The booking data with participant selections
@@ -61,32 +63,28 @@ class ServiceAvailabilityCalculator
*/
public function filterAvailableServices(array $services, BookingDto $bookingDto, int $participantIndex): array
{
$remainingAvailability = $this->calculateRemainingAvailability($bookingDto, $participantIndex);
return array_filter($services, function (Service $service) use ($remainingAvailability) {
// If service has no availability limit set (null), treat as unlimited
if (null === $service->available) {
return array_filter($services, function (Service $service) use ($bookingDto, $participantIndex) {
// Services without an ID cannot be resolved against travel data - treat as available
if (null === $service->id) {
return true;
}
// If availability is 0, service is sold out at the API level
if (0 === $service->available) {
return false;
}
// For services with positive availability, check remaining availability
return ($remainingAvailability[$service->id] ?? $service->available) > 0;
return false === $this->isServiceUnavailable($service->id, $bookingDto, $participantIndex);
});
}
/**
* Check if a specific service is unavailable (sold out) for the current participant.
* Check if a specific service is unavailable for the current participant.
*
* A service is unavailable when it carries a booking stop (Buchungsstop) or when its
* contingent is exhausted, either at the API level or through selections made by the
* other participants of the current booking.
*
* @param int $serviceId The ID of the service to check
* @param BookingDto $bookingDto The booking data with participant selections
* @param int $participantIndex The index of the participant currently filling the form
*
* @return bool True if the service is unavailable (has availability limit and remaining is 0)
* @return bool True if the service is unavailable
*/
public function isServiceUnavailable(int $serviceId, BookingDto $bookingDto, int $participantIndex): bool
{
@@ -105,6 +103,11 @@ class ServiceAvailabilityCalculator
return false;
}
// A booking stop blocks the service regardless of its contingent
if (Constants::STATUS_BLOCKED === $service->status) {
return true;
}
// If no availability tracking (null), service is unlimited and available
if (null === $service->available) {
return false;