fix: refresh live room availability during create flow
This commit is contained in:
1 parent
a73e8a593f
commit
cdce7d57e0
26 files changed
+1976
-54
No files matched your search
@@ -21,9 +21,11 @@ class BookingSessionManager
|
||||
{
|
||||
public const BOOKING_CREATE_KEY = 'booking_create';
|
||||
public const BOOKING_CREATE_BASELINE_KEY = 'booking_create_baseline_snapshot';
|
||||
public const BOOKING_CREATE_AVAILABILITY_REFRESHED_AT_KEY = 'booking_create_availability_refreshed_at';
|
||||
public const BOOKING_EDIT_KEY = 'booking_edit';
|
||||
public const RETURN_URL_KEY = 'booking_return_url';
|
||||
public const DEFAULT_RETURN_URL = 'https://www.ep-reisen.de';
|
||||
private const CREATE_AVAILABILITY_REFRESH_INTERVAL = 600;
|
||||
|
||||
public function __construct(
|
||||
private readonly TravelDataProvider $travelDataService,
|
||||
@@ -51,22 +53,32 @@ class BookingSessionManager
|
||||
/**
|
||||
* Gets or creates the baseline room selection snapshot for change detection.
|
||||
*
|
||||
* @return array<int, array{int, int}>
|
||||
* @return array<int, array{int, int, float}>
|
||||
*/
|
||||
public function getOrCreateBaselineSnapshot(Request $request, BookingDto $bookingCreateDto): array
|
||||
{
|
||||
$baselineKey = self::BOOKING_CREATE_BASELINE_KEY;
|
||||
|
||||
if (!$request->getSession()->has($baselineKey) || $request->query->has('reset_baseline')) {
|
||||
$baseline = $bookingCreateDto->createRoomSelectionSnapshot();
|
||||
$request->getSession()->set($baselineKey, $baseline);
|
||||
|
||||
return $baseline;
|
||||
return $this->saveBaselineSnapshot($request, $bookingCreateDto);
|
||||
}
|
||||
|
||||
return $request->getSession()->get($baselineKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the current room selection snapshot in the session.
|
||||
*
|
||||
* @return array<int, array{int, int, float}>
|
||||
*/
|
||||
public function saveBaselineSnapshot(Request $request, BookingDto $bookingCreateDto): array
|
||||
{
|
||||
$baseline = $bookingCreateDto->createRoomSelectionSnapshot();
|
||||
$request->getSession()->set(self::BOOKING_CREATE_BASELINE_KEY, $baseline);
|
||||
|
||||
return $baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the baseline snapshot from the session.
|
||||
*/
|
||||
@@ -97,7 +109,12 @@ class BookingSessionManager
|
||||
}
|
||||
|
||||
$bookingDto = $session->get($sessionKey);
|
||||
$this->hydrate($bookingDto);
|
||||
$shouldCheck = BookingDto::MODE_CREATE === $mode && $this->shouldRefreshCreateAvailability($request);
|
||||
$hydrated = $this->hydrate($bookingDto, $shouldCheck);
|
||||
|
||||
if (BookingDto::MODE_CREATE === $mode && true === $shouldCheck && true === $hydrated) {
|
||||
$this->markCreateAvailabilityRefreshed($request);
|
||||
}
|
||||
|
||||
return $bookingDto;
|
||||
}
|
||||
@@ -111,6 +128,39 @@ class BookingSessionManager
|
||||
$request->getSession()->remove($sessionKey);
|
||||
}
|
||||
|
||||
public function refreshCreateAvailability(
|
||||
Request $request,
|
||||
BookingDto $bookingDto,
|
||||
bool $forceRefresh = false,
|
||||
): BookingAvailabilityRefreshResult {
|
||||
$beforeSnapshot = $bookingDto->createRoomSelectionSnapshot();
|
||||
$availabilityRefreshed = $this->travelDataService->enrichWithFreshAvailabilities(
|
||||
$bookingDto->travel,
|
||||
true,
|
||||
$forceRefresh,
|
||||
refreshRooms: true,
|
||||
);
|
||||
$roomSelectionQuantityReset = $bookingDto->syncRoomSelectionsWithAvailableRooms();
|
||||
$afterSnapshot = $bookingDto->createRoomSelectionSnapshot();
|
||||
|
||||
if (true === $roomSelectionQuantityReset) {
|
||||
$bookingDto->resetParticipantAssignments();
|
||||
}
|
||||
|
||||
$this->saveBookingDto($request, $bookingDto, BookingDto::MODE_CREATE);
|
||||
|
||||
if (true === $forceRefresh && true === $availabilityRefreshed) {
|
||||
$this->markCreateAvailabilityRefreshed($request);
|
||||
}
|
||||
|
||||
return new BookingAvailabilityRefreshResult(
|
||||
availabilityRefreshed: $availabilityRefreshed,
|
||||
roomSelectionQuantityReset: $roomSelectionQuantityReset,
|
||||
roomSelectionSnapshotChanged: $beforeSnapshot !== $afterSnapshot,
|
||||
hasAvailableRooms: [] !== $bookingDto->travel->getAvailableRooms(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all booking-related session data except the return URL.
|
||||
*/
|
||||
@@ -119,6 +169,7 @@ class BookingSessionManager
|
||||
$session = $request->getSession();
|
||||
$session->remove(self::BOOKING_CREATE_KEY);
|
||||
$session->remove(self::BOOKING_CREATE_BASELINE_KEY);
|
||||
$session->remove(self::BOOKING_CREATE_AVAILABILITY_REFRESHED_AT_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,7 +205,20 @@ class BookingSessionManager
|
||||
/**
|
||||
* Restores the full Travel object after session deserialization.
|
||||
*/
|
||||
private function hydrate(BookingDto $bookingDto): void
|
||||
public function markCreateAvailabilityRefreshed(Request $request): void
|
||||
{
|
||||
$request->getSession()->set(self::BOOKING_CREATE_AVAILABILITY_REFRESHED_AT_KEY, time());
|
||||
}
|
||||
|
||||
private function shouldRefreshCreateAvailability(Request $request): bool
|
||||
{
|
||||
$lastRefreshedAt = (int) $request->getSession()->get(self::BOOKING_CREATE_AVAILABILITY_REFRESHED_AT_KEY, 0);
|
||||
|
||||
return 0 === $lastRefreshedAt
|
||||
|| (time() - $lastRefreshedAt) >= self::CREATE_AVAILABILITY_REFRESH_INTERVAL;
|
||||
}
|
||||
|
||||
private function hydrate(BookingDto $bookingDto, bool $forceRefresh = false): bool
|
||||
{
|
||||
$travel = $this->travelDataService->getTravelData(
|
||||
$bookingDto->travel->id,
|
||||
@@ -162,13 +226,16 @@ class BookingSessionManager
|
||||
);
|
||||
|
||||
if (null === $travel) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$availabilityRefreshed = $this->travelDataService->enrichWithFreshAvailabilities($travel, true, $forceRefresh, refreshRooms: true);
|
||||
$bookingDto->travel = $travel;
|
||||
|
||||
if (null !== $bookingDto->booking) {
|
||||
$bookingDto->booking->travelData = $travel;
|
||||
}
|
||||
|
||||
return $availabilityRefreshed;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user