Files
myep/src/Service/RoomAssignmentService.php
T

90 lines
3.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Service;
use App\Form\Model\BookingDto;
/**
* Handles automatic room assignment for booking participants.
*
* This service automatically assigns participants to selected rooms based on room capacity
* and quantity, eliminating the need for manual room selection in the booking flow.
*/
class RoomAssignmentService
{
/**
* Determines if automatic room assignment should be performed.
*
* Auto-assignment is only performed when exactly one room type is selected to avoid
* UX issues with individual participant forms. With multiple room types, users should
* manually select rooms to avoid having to unselect preassigned rooms.
*
* @param BookingDto $dto The booking DTO containing room selections
*
* @return bool True if auto-assignment should proceed, false otherwise
*/
public function shouldAutoAssignRooms(BookingDto $dto): bool
{
$selectedRoomTypeCount = 0;
foreach ($dto->roomSelections as $roomSelection) {
if (null !== $roomSelection->quantity && $roomSelection->quantity > 0) {
++$selectedRoomTypeCount;
}
}
return 1 === $selectedRoomTypeCount;
}
/**
* Automatically assigns participants to rooms based on selected room quantities and capacities.
*
* Assignment algorithm:
* - Iterates through selected rooms in order
* - For each room quantity, assigns minPax participants to that room ID
* - Ensures sequential assignment (participant 0, 1, 2, etc.)
*
* Example:
* - 2x "Doppelzimmer" (capacity 2) = participants 0-1 → room A, participants 2-3 → room A
* - 1x "3-Bett-Zimmer" (capacity 3) = participants 4-6 → room B
*
* Note: Only performs assignment if shouldAutoAssignRooms() returns true.
*
* @param BookingDto $dto The booking DTO containing room selections and participants
*/
public function assignParticipantsToRooms(BookingDto $dto): void
{
// Skip auto-assignment if multiple room types selected
if (false === $this->shouldAutoAssignRooms($dto)) {
return;
}
$participantIndex = 0;
$selectedRooms = $dto->getSelectedRooms();
$availableRooms = $dto->travel->getAvailableRooms();
foreach ($selectedRooms as $roomSelection) {
$room = $availableRooms[$roomSelection->roomId] ?? null;
if (null === $room) {
continue; // Skip if room not found
}
$capacityPerRoom = $room->minPax ?? 1;
// Assign participants for each room quantity
for ($i = 0; $i < $roomSelection->quantity; ++$i) {
// Assign participants according to room capacity
for ($j = 0; $j < $capacityPerRoom; ++$j) {
if (isset($dto->participants[$participantIndex])) {
$dto->participants[$participantIndex]->assignedRoomId = $room->id;
++$participantIndex;
}
}
}
}
}
}