feat: correct determination of inquiry status and conditional voucher field display

This commit is contained in:
Björn Fromme committed 2026-03-16 11:59:11 +01:00
1 parent 85998534fe
commit 1f2f2751e4
19 files changed
+468 -193

No files matched your search

@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace App\BusProNet\Model;
/**
* Response model for service availability API calls.
*
* Contains both service-level availability data and travel-level
* booking status information from the VERFUEGBARKEIT endpoint.
*/
class ServiceAvailabilityResponse
{
/**
* @param array<int, Availability> $services Service availability data indexed by service ID
* @param array<string> $allowedBookingStatus Allowed booking status codes (e.g., ['F', 'O', 'A'])
* @param string|null $travelStatus Travel status from API (e.g., 'frei', 'anfrage')
*/
public function __construct(
private readonly array $services,
public readonly array $allowedBookingStatus = [],
public readonly ?string $travelStatus = null,
) {
}
/**
* @return array<int, Availability>
*/
public function getServices(): array
{
return $this->services;
}
}
+70 -6
View File
@@ -56,6 +56,15 @@ class Travel
#[Groups(['api:single'])]
public ?string $status = null;
/**
* Allowed booking status codes from buchungstatusmoeglich attribute.
* Array of status codes (F, A, O) indicating which booking types are permitted.
*
* @var array<string>
*/
#[Groups(['api:single'])]
public array $allowedBookingStatus = [];
#[Groups(['api:list', 'api:single'])]
public ?float $priceFrom = null;
@@ -223,19 +232,18 @@ class Travel
}
/**
* Retrieves all available rooms for booking.
* Retrieves all bookable rooms (both regular and inquiry).
*
* Filters the rooms collection to return only rooms that have availability
* greater than zero and have an available status. This ensures only
* bookable rooms are returned for selection.
* Returns rooms that have availability greater than zero and a bookable status
* (either 'Frei' for regular booking or 'Anfrage' for inquiry booking).
*
* @return array<int, Room> The filtered array of available rooms, indexed by room ID
* @return array<int, Room> The filtered array of bookable rooms, indexed by room ID
*/
public function getAvailableRooms(): array
{
$result = [];
foreach ($this->rooms as $room) {
if ($room->available > 0 && Constants::STATUS_AVAILABLE === $room->status) {
if ($room->available > 0 && $this->isBookableRoomStatus($room->status)) {
$result[$room->id] = $room;
}
}
@@ -243,6 +251,50 @@ class Travel
return $result;
}
/**
* Checks if the travel has any bookable rooms.
*
* @return bool True if at least one room is bookable
*/
public function hasBookableRooms(): bool
{
return [] !== $this->getAvailableRooms();
}
/**
* Checks if all bookable rooms require inquiry booking.
*
* Returns true if there are bookable rooms but none with 'Frei' status.
* This indicates the booking must be submitted as an inquiry.
*
* @return bool True if only inquiry rooms are available
*/
public function requiresInquiryBooking(): bool
{
$bookableRooms = $this->getAvailableRooms();
if ([] === $bookableRooms) {
return false;
}
foreach ($bookableRooms as $room) {
if (Constants::STATUS_AVAILABLE === $room->status) {
return false;
}
}
return true;
}
/**
* Checks if a room status allows booking.
*/
private function isBookableRoomStatus(?string $status): bool
{
return Constants::STATUS_AVAILABLE === $status
|| Constants::STATUS_ON_REQUEST === $status;
}
/**
* Retrieves a room by its ID.
*
@@ -260,4 +312,16 @@ class Travel
return false === empty($rooms) ? reset($rooms) : null;
}
/**
* Checks if a specific booking status code is allowed for this travel.
*
* @param string $statusCode The booking status code to check (F, A, or O)
*
* @return bool True if the status is allowed, false otherwise
*/
public function isBookingStatusAllowed(string $statusCode): bool
{
return in_array($statusCode, $this->allowedBookingStatus, true);
}
}