feat: unassign rooms from other participants when unavailable
This commit is contained in:
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Form\ChoiceLoader;
|
||||
|
||||
use App\Form\Model\ParticipantDto;
|
||||
use App\Form\Model\RoomSelectionDto;
|
||||
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
|
||||
use Symfony\Component\Form\ChoiceList\Factory\ChoiceListFactoryInterface;
|
||||
@@ -13,25 +12,21 @@ use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
|
||||
/**
|
||||
* Choice loader for participant room assignments.
|
||||
*
|
||||
* Generates room choices for each participant based on availability,
|
||||
* current assignments, and room capacity constraints. This loader
|
||||
* ensures participants can only select rooms with available capacity
|
||||
* while maintaining their current assignment if applicable.
|
||||
* Generates room choices for each participant from all selected room types
|
||||
* in Step 1, regardless of current capacity or assignments. Capacity conflicts
|
||||
* are automatically resolved by the field handler through intelligent
|
||||
* auto-unassignment when needed.
|
||||
*/
|
||||
class ParticipantRoomChoiceLoader implements ChoiceLoaderInterface
|
||||
{
|
||||
private ?ChoiceListInterface $choiceList = null;
|
||||
|
||||
/**
|
||||
* @param ParticipantDto[] $allParticipants all participant DTOs from the root form
|
||||
* @param RoomSelectionDto[] $selectedRooms the rooms selected in the previous step
|
||||
* @param int $participantIndex the index of the current participant
|
||||
* @param RoomSelectionDto[] $selectedRooms the rooms selected in the previous step
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly ChoiceListFactoryInterface $factory,
|
||||
private readonly array $allParticipants,
|
||||
private readonly array $selectedRooms,
|
||||
private readonly int $participantIndex,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -66,50 +61,20 @@ class ParticipantRoomChoiceLoader implements ChoiceLoaderInterface
|
||||
/**
|
||||
* Generates room choices for the specific participant.
|
||||
*
|
||||
* Always includes all selected rooms from Step 1 regardless of current capacity.
|
||||
* Capacity conflicts are handled by the field handler during assignment.
|
||||
*
|
||||
* @return array<string, int>
|
||||
*/
|
||||
private function generateRoomChoicesForParticipant(): array
|
||||
{
|
||||
$roomOccupancy = $this->calculateRoomOccupancy();
|
||||
$participantRoomChoices = [];
|
||||
$assignedRoomId = $this->allParticipants[$this->participantIndex]->assignedRoomId ?? null;
|
||||
|
||||
foreach ($this->selectedRooms as $roomSelection) {
|
||||
$currentOccupancy = $roomOccupancy[$roomSelection->roomId] ?? 0;
|
||||
|
||||
// If this participant is already assigned to this room, exclude them from occupancy count
|
||||
$adjustedOccupancy = $currentOccupancy;
|
||||
if ($assignedRoomId === $roomSelection->roomId) {
|
||||
--$adjustedOccupancy;
|
||||
}
|
||||
|
||||
$totalCapacity = $roomSelection->quantity * $roomSelection->capacity;
|
||||
$remainingCapacity = $totalCapacity - $adjustedOccupancy;
|
||||
|
||||
// Include room if it has capacity OR if it's the participant's current assignment
|
||||
if ($remainingCapacity > 0 || $assignedRoomId === $roomSelection->roomId) {
|
||||
$participantRoomChoices[$roomSelection->roomLabel] = $roomSelection->roomId;
|
||||
}
|
||||
// Always include all selected rooms - capacity conflicts handled in field handler
|
||||
$participantRoomChoices[$roomSelection->roomLabel] = $roomSelection->roomId;
|
||||
}
|
||||
|
||||
return $participantRoomChoices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates room occupancy based on all participant assignments.
|
||||
*
|
||||
* @return array<int, int>
|
||||
*/
|
||||
private function calculateRoomOccupancy(): array
|
||||
{
|
||||
$roomOccupancy = [];
|
||||
|
||||
foreach ($this->allParticipants as $participant) {
|
||||
if (null !== $participant->assignedRoomId) {
|
||||
$roomOccupancy[$participant->assignedRoomId] = ($roomOccupancy[$participant->assignedRoomId] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $roomOccupancy;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user