wip: backport booking create flow form handling to edit flow

This commit is contained in:
Björn Fromme
2026-03-16 11:59:10 +01:00
parent e330626b03
commit d70a27f2fd
5 changed files with 143 additions and 32 deletions
@@ -10,6 +10,7 @@ use App\BusProNet\Model\Service;
use App\BusProNet\Utility\DirectionMapper;
use App\Form\Model\BookingCreateDto;
use App\Form\Model\BookingDtoInterface;
use App\Form\Model\BookingEditDto;
use App\Form\Service\Abstract\AbstractFieldOptionsProvider;
use App\Form\Service\Factory\ParticipantRoomChoiceLoaderFactory;
use App\Service\InsuranceMatchingService;
@@ -80,25 +81,44 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
*/
protected function registerFieldOptionProviders(): void
{
// Room assignment field provider (only available for create workflow)
$this->fieldOptionProviders['assignedRoomId'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
'label' => 'Zimmer',
'placeholder' => 'Nicht zugeordnet',
// Use factory to create context-aware choice loader that:
// - Shows only available rooms for this participant
// - Excludes rooms already assigned to other participants
// - Respects room capacity and booking constraints
'choice_loader' => $bookingDto instanceof BookingCreateDto
? $this->roomChoiceLoaderFactory->create(
// Room assignment field provider (available for both create and edit workflows)
$this->fieldOptionProviders['assignedRoomId'] = function (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) {
$choiceLoader = null;
$disabled = false;
if ($bookingDto instanceof BookingCreateDto) {
// Create context: use selected rooms from step 1
$choiceLoader = $this->roomChoiceLoaderFactory->createForCreate(
$bookingDto->participants,
$bookingDto->getSelectedRooms(),
$participantIndex
)
: null,
// Make field read-only when only one room type is selected
// Room is auto-assigned, no user choice needed
'disabled' => $bookingDto instanceof BookingCreateDto && 1 === count($bookingDto->getSelectedRooms()),
];
);
// Disable when only one room type selected (auto-assigned)
$disabled = 1 === count($bookingDto->getSelectedRooms());
} elseif ($bookingDto instanceof BookingEditDto) {
// Edit context: use already-booked rooms from booking
$choiceLoader = $this->roomChoiceLoaderFactory->createForEdit(
$bookingDto->participants,
$bookingDto->booking->rooms,
$participantIndex
);
// Disable when only one room in booking (no reassignment needed)
$disabled = 1 === count($bookingDto->booking->rooms);
}
return [
'label' => 'Zimmer',
'placeholder' => 'Nicht zugeordnet',
// Use factory to create context-aware choice loader that:
// - Shows only available rooms for this participant
// - Excludes rooms already assigned to other participants
// - Respects room capacity and booking constraints
'choice_loader' => $choiceLoader,
// Make field read-only when only one room type is available
// Room is auto-assigned or cannot be changed, no user choice needed
'disabled' => $disabled,
];
};
// Courses field provider - provides age-appropriate courses from travel data
$this->fieldOptionProviders['courses'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
@@ -615,7 +635,6 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
});
}
/**
* Generates label for rental insurance checkbox including pricing information.
*/