feat: refactoring and cleanup

This commit is contained in:
Björn Fromme
2025-12-06 15:02:13 +01:00
parent f4691ec67e
commit 696800aafd
41 changed files with 2591 additions and 2233 deletions
+59 -52
View File
@@ -8,6 +8,7 @@ use App\BusProNet\Model\Travel;
use App\Exception\BookingSessionNotFoundException;
use App\Exception\NoRoomsAvailableException;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Form\Model\RoomSelectionDto;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -37,7 +38,7 @@ class BookingService
$baselineKey = self::BOOKING_CREATE_BASELINE_KEY;
if (!$request->getSession()->has($baselineKey) || $request->query->has('reset_baseline')) {
$baseline = $this->createRoomSelectionSnapshot($bookingCreateDto);
$baseline = $bookingCreateDto->createRoomSelectionSnapshot();
$request->getSession()->set($baselineKey, $baseline);
return $baseline;
@@ -143,31 +144,6 @@ class BookingService
return BookingDto::MODE_EDIT === $mode ? self::BOOKING_EDIT_KEY : self::BOOKING_CREATE_KEY;
}
/**
* Saves the booking creation DTO to the session.
*
* Persists the current booking state to the session for retrieval
* across multiple HTTP requests during the booking flow.
*
* @param Request $request The HTTP request with session
* @param BookingDto $bookingCreateDto The booking DTO to persist
*/
public function saveBookingCreateDto(Request $request, BookingDto $bookingCreateDto): void
{
$this->saveBookingDto($request, $bookingCreateDto, BookingDto::MODE_CREATE);
}
/**
* Clears the booking creation DTO from the session.
*
* This method removes only the booking DTO while preserving other session data.
* Used after successful booking submission to clear the booking flow state.
*/
public function clearBookingCreateDto(Request $request): void
{
$request->getSession()->remove(self::BOOKING_CREATE_KEY);
}
/**
* Clears all booking-related session data.
*
@@ -229,7 +205,7 @@ class BookingService
$bookingCreateDto->agencyId = $agencyId;
$bookingCreateDto->bookingStatus = $bookingStatus;
$this->saveBookingCreateDto($request, $bookingCreateDto);
$this->saveBookingDto($request, $bookingCreateDto, BookingDto::MODE_CREATE);
return $bookingCreateDto;
}
@@ -286,17 +262,12 @@ class BookingService
* Calculates the number of participants assigned to each room ID.
*
* @return array<int, int> an array where the key is the room ID and the value is the count of assigned participants
*
* @deprecated Use BookingDto::getRoomAssignmentCounts() instead
*/
public function getRoomAssignmentCounts(BookingDto $bookingDto): array
{
$counts = [];
foreach ($bookingDto->getParticipants() as $participant) {
if (null !== $participant->assignedRoomId) {
$counts[$participant->assignedRoomId] = ($counts[$participant->assignedRoomId] ?? 0) + 1;
}
}
return $counts;
return $bookingDto->getRoomAssignmentCounts();
}
/**
@@ -380,48 +351,40 @@ class BookingService
/**
* Resets all participant room assignments in the DTO.
*
* Clears room assignments when room selections change to prevent
* invalid assignments. Called when users modify their room selections
* in step 1 to ensure participants are reassigned appropriately.
*
* @param BookingDto $dto The booking DTO to reset assignments for
*
* @deprecated Use BookingDto::resetParticipantAssignments() instead
*/
public function resetParticipantAssignments(BookingDto $dto): void
{
foreach ($dto->participants as $participant) {
$participant->assignedRoomId = null;
}
$dto->resetParticipantAssignments();
}
/**
* Creates a snapshot of the current room selection state.
*
* @return array<int, array{int, int}> Array of [roomId, quantity] pairs
*
* @deprecated Use BookingDto::createRoomSelectionSnapshot() instead
*/
public function createRoomSelectionSnapshot(BookingDto $dto): array
{
return array_map(
fn ($roomSelection) => [(int) $roomSelection->roomId, (int) $roomSelection->quantity],
$dto->roomSelections
);
return $dto->createRoomSelectionSnapshot();
}
/**
* Checks if room selection has changed compared to a previous snapshot.
*
* Compares the current room selection state with a baseline snapshot
* to detect changes that would require participant reassignment.
*
* @param array $oldSnapshot The baseline room selection snapshot
* @param BookingDto $newDto The current booking DTO
*
* @return bool True if room selections have changed, false otherwise
*
* @deprecated Use BookingDto::hasRoomSelectionChanged() instead
*/
public function hasRoomSelectionChanged(array $oldSnapshot, BookingDto $newDto): bool
{
$newSnapshot = $this->createRoomSelectionSnapshot($newDto);
return $oldSnapshot !== $newSnapshot;
return $newDto->hasRoomSelectionChanged($oldSnapshot);
}
/**
@@ -545,4 +508,48 @@ class BookingService
}
}
}
/**
* Ensures the booking DTO has the correct number of participant objects.
*
* Creates or removes ParticipantDto objects based on room selections.
* Preserves existing participant data when adjusting the count.
* Optionally prepopulates the applicant (index 0) from an authenticated user.
*
* @param BookingDto $bookingDto The booking DTO to update
* @param \Symfony\Component\Security\Core\User\UserInterface|null $user Optional authenticated user for prepopulation
* @param callable|null $prepopulateCallback Callback to prepopulate applicant: fn(UserInterface, ParticipantDto): ParticipantDto
*/
public function ensureCorrectNumberOfParticipants(
BookingDto $bookingDto,
?\Symfony\Component\Security\Core\User\UserInterface $user = null,
?callable $prepopulateCallback = null,
): void {
$participantsCount = $this->getParticipantsCount($bookingDto->roomSelections, $bookingDto->travel);
$existingParticipants = $bookingDto->participants;
$bookingDto->participants = [];
for ($i = 0; $i < $participantsCount; ++$i) {
$participant = $existingParticipants[$i] ?? new ParticipantDto();
$participant->index = $i;
// Prepopulate applicant from authenticated user (index 0 only)
if (0 === $i && null !== $user && null !== $prepopulateCallback && $this->shouldPrepopulate($participant)) {
$participant = $prepopulateCallback($user, $participant);
}
$bookingDto->participants[$i] = $participant;
}
}
/**
* Determines if a participant should be prepopulated.
*
* Only prepopulates if the participant is "fresh" (no name set yet).
*/
private function shouldPrepopulate(ParticipantDto $participant): bool
{
return null === $participant->firstName || '' === $participant->firstName;
}
}