fix: clear inquiry status on room reselection
This commit is contained in:
1 parent
d4296f30a5
commit
32083c7966
3 files changed
+104
-11
No files matched your search
@@ -58,6 +58,15 @@ class BookingDto
|
|||||||
*/
|
*/
|
||||||
public string $bookingStatus = 'F';
|
public string $bookingStatus = 'F';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Booking status the travel itself calls for when the booking starts, before any room is
|
||||||
|
* selected and before the create-flow status rules run. Step 1 falls back to it whenever
|
||||||
|
* no on-request room is selected, so the status can move back from 'A'.
|
||||||
|
*
|
||||||
|
* Null in sessions started before it was introduced.
|
||||||
|
*/
|
||||||
|
public ?string $initialBookingStatus = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to booking entity (only populated in edit mode).
|
* Reference to booking entity (only populated in edit mode).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ class BookingConfigurator
|
|||||||
? $this->agencyLoader->loadById($agencyId)?->code
|
? $this->agencyLoader->loadById($agencyId)?->code
|
||||||
: null;
|
: null;
|
||||||
$bookingCreateDto->bookingStatus = $bookingStatus;
|
$bookingCreateDto->bookingStatus = $bookingStatus;
|
||||||
|
$bookingCreateDto->initialBookingStatus = $bookingStatus;
|
||||||
$this->applyCreateBookingStatusRules($bookingCreateDto);
|
$this->applyCreateBookingStatusRules($bookingCreateDto);
|
||||||
|
|
||||||
$this->bookingSessionService->saveBookingDto($request, $bookingCreateDto, BookingDto::MODE_CREATE);
|
$this->bookingSessionService->saveBookingDto($request, $bookingCreateDto, BookingDto::MODE_CREATE);
|
||||||
@@ -659,31 +660,43 @@ class BookingConfigurator
|
|||||||
/**
|
/**
|
||||||
* Updates booking status based on selected room requirements.
|
* Updates booking status based on selected room requirements.
|
||||||
*
|
*
|
||||||
* Checks if any selected room has inquiry-only status. If so, forces
|
* If ANY selected room is only bookable on request, the whole booking becomes an inquiry.
|
||||||
* the entire booking to inquiry mode. This override happens after room
|
* Otherwise the status returns to what the travel called for when the booking started,
|
||||||
* selection in Step 1 and respects the business rule: if ANY room requires
|
* and the create-flow rules run again, so a customer who swaps an on-request room for a
|
||||||
* inquiry, the whole booking becomes an inquiry.
|
* free one in Step 1 is no longer submitted as an inquiry. An 'A' from the Step 3 BusPro
|
||||||
|
* fallback is cleared the same way; Step 3 validates again and re-applies it if needed.
|
||||||
*
|
*
|
||||||
* @param BookingDto $bookingDto The booking DTO to update
|
* @param BookingDto $bookingDto The booking DTO to update
|
||||||
*/
|
*/
|
||||||
public function updateBookingStatusFromRoomSelection(BookingDto $bookingDto): void
|
public function updateBookingStatusFromRoomSelection(BookingDto $bookingDto): void
|
||||||
{
|
{
|
||||||
// Skip if already inquiry - no need to check
|
if (true === $this->hasOnRequestRoomSelected($bookingDto)) {
|
||||||
if ('A' === $bookingDto->bookingStatus) {
|
$bookingDto->bookingStatus = Constants::BOOKING_STATUS_INQUIRY;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check selected rooms for inquiry-only status
|
// Sessions started before the initial status was recorded keep their current status
|
||||||
|
if (null === $bookingDto->initialBookingStatus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bookingDto->bookingStatus = $bookingDto->initialBookingStatus;
|
||||||
|
$this->applyCreateBookingStatusRules($bookingDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function hasOnRequestRoomSelected(BookingDto $bookingDto): bool
|
||||||
|
{
|
||||||
foreach ($bookingDto->getSelectedRooms() as $roomSelection) {
|
foreach ($bookingDto->getSelectedRooms() as $roomSelection) {
|
||||||
$room = $bookingDto->travel->getRoomById($roomSelection->id);
|
$room = $bookingDto->travel->getRoomById($roomSelection->id);
|
||||||
if ($room
|
if (null !== $room
|
||||||
&& Constants::STATUS_ON_REQUEST === $room->status
|
&& Constants::STATUS_ON_REQUEST === $room->status
|
||||||
&& $room->available > 0) {
|
&& $room->available > 0) {
|
||||||
$bookingDto->bookingStatus = 'A';
|
return true;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -228,6 +228,56 @@ class BookingConfiguratorStatusTest extends TestCase
|
|||||||
$this->assertSame('A', $bookingDto->bookingStatus);
|
$this->assertSame('A', $bookingDto->bookingStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRoomSelectionSwitchesToInquiryForOnRequestRoom(): void
|
||||||
|
{
|
||||||
|
$bookingDto = $this->startMixedRoomsBooking();
|
||||||
|
|
||||||
|
$this->selectRoom($bookingDto, 2);
|
||||||
|
$this->bookingService->updateBookingStatusFromRoomSelection($bookingDto);
|
||||||
|
|
||||||
|
$this->assertSame('A', $bookingDto->bookingStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRoomSelectionRevertsInquiryWhenOnRequestRoomIsDeselected(): void
|
||||||
|
{
|
||||||
|
$bookingDto = $this->startMixedRoomsBooking();
|
||||||
|
|
||||||
|
$this->selectRoom($bookingDto, 2);
|
||||||
|
$this->bookingService->updateBookingStatusFromRoomSelection($bookingDto);
|
||||||
|
$this->selectRoom($bookingDto, 1);
|
||||||
|
$this->bookingService->updateBookingStatusFromRoomSelection($bookingDto);
|
||||||
|
|
||||||
|
$this->assertSame('F', $bookingDto->bookingStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRoomSelectionKeepsInquiryRequiredByTravel(): void
|
||||||
|
{
|
||||||
|
$travel = $this->createTravelWithRooms([
|
||||||
|
['status' => Constants::STATUS_AVAILABLE, 'available' => 5],
|
||||||
|
]);
|
||||||
|
$travel->allowedBookingStatus = ['A'];
|
||||||
|
$this->travelDataService->method('getTravelData')->willReturn($travel);
|
||||||
|
|
||||||
|
$bookingDto = $this->bookingService->startFreshBooking($this->createRequestWithSession(), 123, 456);
|
||||||
|
|
||||||
|
$this->selectRoom($bookingDto, 1);
|
||||||
|
$this->bookingService->updateBookingStatusFromRoomSelection($bookingDto);
|
||||||
|
|
||||||
|
$this->assertSame('A', $bookingDto->bookingStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRoomSelectionKeepsStatusOfSessionsWithoutInitialStatus(): void
|
||||||
|
{
|
||||||
|
$bookingDto = $this->startMixedRoomsBooking();
|
||||||
|
$bookingDto->initialBookingStatus = null;
|
||||||
|
$bookingDto->bookingStatus = 'A';
|
||||||
|
|
||||||
|
$this->selectRoom($bookingDto, 1);
|
||||||
|
$this->bookingService->updateBookingStatusFromRoomSelection($bookingDto);
|
||||||
|
|
||||||
|
$this->assertSame('A', $bookingDto->bookingStatus);
|
||||||
|
}
|
||||||
|
|
||||||
public function testApplyCreateBookingStatusRulesSetsOptionFromRegistry(): void
|
public function testApplyCreateBookingStatusRulesSetsOptionFromRegistry(): void
|
||||||
{
|
{
|
||||||
$bookingStatusRuleRegistry = $this->createStub(BookingStatusRuleRegistry::class);
|
$bookingStatusRuleRegistry = $this->createStub(BookingStatusRuleRegistry::class);
|
||||||
@@ -338,6 +388,27 @@ class BookingConfiguratorStatusTest extends TestCase
|
|||||||
return $group;
|
return $group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a booking on a travel with a free room (id 1) and an on-request room (id 2).
|
||||||
|
*/
|
||||||
|
private function startMixedRoomsBooking(): BookingDto
|
||||||
|
{
|
||||||
|
$travel = $this->createTravelWithRooms([
|
||||||
|
['status' => Constants::STATUS_AVAILABLE, 'available' => 5],
|
||||||
|
['status' => Constants::STATUS_ON_REQUEST, 'available' => 3],
|
||||||
|
]);
|
||||||
|
$this->travelDataService->method('getTravelData')->willReturn($travel);
|
||||||
|
|
||||||
|
return $this->bookingService->startFreshBooking($this->createRequestWithSession(), 123, 456);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function selectRoom(BookingDto $bookingDto, int $roomId): void
|
||||||
|
{
|
||||||
|
foreach ($bookingDto->roomSelections as $roomSelection) {
|
||||||
|
$roomSelection->quantity = $roomId === $roomSelection->id ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function createRequestWithSession(): Request
|
private function createRequestWithSession(): Request
|
||||||
{
|
{
|
||||||
$session = new Session(new MockArraySessionStorage());
|
$session = new Session(new MockArraySessionStorage());
|
||||||
|
|||||||
Reference in new issue
Block a user