wip: modernized edit flow
This commit is contained in:
@@ -9,7 +9,7 @@ use App\BusProNet\Model\Pickup;
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\BusProNet\Utility\DirectionMapper;
|
||||
use App\Form\Model\BookingCreateDto;
|
||||
use App\Form\Model\BookingDtoInterface;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\BookingEditDto;
|
||||
use App\Form\Service\Abstract\AbstractFieldOptionsProvider;
|
||||
use App\Form\Service\Factory\ParticipantRoomChoiceLoaderFactory;
|
||||
@@ -82,11 +82,11 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
protected function registerFieldOptionProviders(): void
|
||||
{
|
||||
// Room assignment field provider (available for both create and edit workflows)
|
||||
$this->fieldOptionProviders['assignedRoomId'] = function (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) {
|
||||
$this->fieldOptionProviders['assignedRoomId'] = function (BookingDto $bookingDto, int $participantIndex, array $options = []) {
|
||||
$choiceLoader = null;
|
||||
$disabled = false;
|
||||
|
||||
if ($bookingDto instanceof BookingCreateDto) {
|
||||
if (BookingDto::MODE_CREATE === $bookingDto->getMode()) {
|
||||
// Create context: use selected rooms from step 1
|
||||
$choiceLoader = $this->roomChoiceLoaderFactory->createForCreate(
|
||||
$bookingDto->participants,
|
||||
@@ -95,7 +95,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
);
|
||||
// Disable when only one room type selected (auto-assigned)
|
||||
$disabled = 1 === count($bookingDto->getSelectedRooms());
|
||||
} elseif ($bookingDto instanceof BookingEditDto) {
|
||||
} elseif (BookingDto::MODE_EDIT === $bookingDto->getMode()) {
|
||||
// Edit context: use already-booked rooms from booking
|
||||
$choiceLoader = $this->roomChoiceLoaderFactory->createForEdit(
|
||||
$bookingDto->participants,
|
||||
@@ -121,7 +121,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
};
|
||||
|
||||
// Courses field provider - provides age-appropriate courses from travel data
|
||||
$this->fieldOptionProviders['courses'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['courses'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Kurse',
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
@@ -156,7 +156,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
];
|
||||
|
||||
// Additional services field provider - provides age-appropriate additional services with mandatory pre-selection
|
||||
$this->fieldOptionProviders['additionalServices'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['additionalServices'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Zusatzleistungen',
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
@@ -199,7 +199,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
];
|
||||
|
||||
// Board field provider - provides age-appropriate board options from travel data
|
||||
$this->fieldOptionProviders['board'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['board'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Verpflegung',
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
@@ -229,7 +229,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
];
|
||||
|
||||
// Rentals field provider - provides age-appropriate rental options filtered by selected skipass duration
|
||||
$this->fieldOptionProviders['rentals'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['rentals'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Leihmaterial',
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
@@ -268,7 +268,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
];
|
||||
|
||||
// Rental insurance field provider - provides rental insurance options when rental services are selected
|
||||
$this->fieldOptionProviders['rentalInsurance'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['rentalInsurance'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => $this->getRentalInsuranceCheckboxLabel($bookingDto->travel->getAdditionalServicesBySubTypes(Constants::TOKEN_RENTAL_INSURANCE, true, true)),
|
||||
'required' => false,
|
||||
'property_path' => 'rentalInsuranceSelected',
|
||||
@@ -276,7 +276,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
];
|
||||
|
||||
// License plate field provider - provides text input for vehicle license plate when parking is selected
|
||||
$this->fieldOptionProviders['licensePlate'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['licensePlate'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Kennzeichen',
|
||||
'required' => false,
|
||||
'attr' => [
|
||||
@@ -288,7 +288,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
];
|
||||
|
||||
// Skipass field provider - provides age-appropriate skipass options from travel data filtered by date range
|
||||
$this->fieldOptionProviders['skiPass'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['skiPass'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Skipass',
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
@@ -323,7 +323,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
];
|
||||
|
||||
// Room remarks field provider - provides textarea for room-specific remarks (only for 'mbz' rooms)
|
||||
$this->fieldOptionProviders['remarksRoom'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['remarksRoom'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Wünsche oder Anmerkungen zum Zimmer',
|
||||
'required' => false,
|
||||
'sanitize_html' => true,
|
||||
@@ -335,7 +335,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
// Transportation field providers - handles outbound/inbound transportation and pickup selection
|
||||
|
||||
// Outbound Transportation
|
||||
$this->fieldOptionProviders['transportationOutbound'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['transportationOutbound'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Hinfahrt',
|
||||
'choices' => $bookingDto->travel->getTransportationServicesByDirection(DirectionMapper::OUTBOUND_TRAVEL),
|
||||
'choice_label' => fn (Service $service) => $this->formatTransportationServiceLabel($service),
|
||||
@@ -366,7 +366,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
];
|
||||
|
||||
// Inbound Transportation
|
||||
$this->fieldOptionProviders['transportationInbound'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['transportationInbound'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Rückfahrt',
|
||||
'choices' => $bookingDto->travel->getTransportationServicesByDirection(DirectionMapper::INBOUND_TRAVEL),
|
||||
'choice_label' => fn (Service $service) => $this->formatTransportationServiceLabel($service),
|
||||
@@ -398,7 +398,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
|
||||
// Pickup (conditional - only shown when either transportation direction is bus)
|
||||
// Uses outbound pickups list, applies to both directions
|
||||
$this->fieldOptionProviders['pickup'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['pickup'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Zu- und Ausstieg',
|
||||
'choices' => $bookingDto->travel->pickupsOutbound,
|
||||
'choice_label' => fn (?Pickup $pickup) => $this->formatPickupLabelWithPrice($pickup),
|
||||
@@ -411,13 +411,14 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
|
||||
// Parking (conditional - only shown when outbound transportation is PKW)
|
||||
// Simple checkbox since there's only ever one parking type
|
||||
$this->fieldOptionProviders['parking'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
$this->fieldOptionProviders['parking'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => $this->getParkingCheckboxLabel($bookingDto->travel->getAdditionalServicesBySubTypes(Constants::TOKEN_PARKING, true)),
|
||||
'required' => false,
|
||||
];
|
||||
|
||||
// Bulk insurance booking checkbox (applicant only - controls insurance assignment for all participants)
|
||||
$this->fieldOptionProviders['bulkInsuranceBooking'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
// Only registered in create mode - insurance cannot be modified in edit mode due to API limitation
|
||||
$this->fieldOptionProviders['bulkInsuranceBooking'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Für alle Teilnehmer buchen',
|
||||
'required' => false,
|
||||
'attr' => [
|
||||
@@ -428,7 +429,8 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
];
|
||||
|
||||
// Insurance field provider - provides age and eligibility filtered insurances for participants
|
||||
$this->fieldOptionProviders['insurance'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
// Only registered in create mode - insurance cannot be modified in edit mode due to API limitation
|
||||
$this->fieldOptionProviders['insurance'] = fn (BookingDto $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Reiseversicherung',
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
@@ -461,12 +463,12 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
* is only available for the exact duration of the skipass.
|
||||
*
|
||||
* @param array $rentals Array of rental Service objects to filter
|
||||
* @param BookingDtoInterface $bookingDto The booking DTO containing participant data
|
||||
* @param BookingDto $bookingDto The booking DTO containing participant data
|
||||
* @param int $participantIndex Index of the participant to evaluate
|
||||
*
|
||||
* @return array Filtered array of rentals matching skipass duration
|
||||
*/
|
||||
private function filterRentalsBySkiPassDuration(array $rentals, BookingDtoInterface $bookingDto, int $participantIndex): array
|
||||
private function filterRentalsBySkiPassDuration(array $rentals, BookingDto $bookingDto, int $participantIndex): array
|
||||
{
|
||||
$participant = $bookingDto->getParticipant($participantIndex);
|
||||
if (null === $participant || null === $participant->skiPass) {
|
||||
@@ -586,12 +588,12 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
* Checks if a service should be rendered as read-only due to unavailability.
|
||||
*
|
||||
* @param Service $service The service to check
|
||||
* @param BookingDtoInterface $bookingDto The booking DTO containing participant data
|
||||
* @param BookingDto $bookingDto The booking DTO containing participant data
|
||||
* @param int $participantIndex Index of the participant currently selecting services
|
||||
*
|
||||
* @return bool True if the service should be read-only due to unavailability
|
||||
*/
|
||||
private function isServiceUnavailableForParticipant(Service $service, BookingDtoInterface $bookingDto, int $participantIndex): bool
|
||||
private function isServiceUnavailableForParticipant(Service $service, BookingDto $bookingDto, int $participantIndex): bool
|
||||
{
|
||||
if (!$bookingDto instanceof BookingCreateDto) {
|
||||
// For non-create workflows, don't apply availability restrictions
|
||||
@@ -609,12 +611,12 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
* returns empty array to be handled by field visibility conditions.
|
||||
*
|
||||
* @param array $services Array of Service objects to filter
|
||||
* @param BookingDtoInterface $bookingDto The booking DTO containing participant data
|
||||
* @param BookingDto $bookingDto The booking DTO containing participant data
|
||||
* @param int $participantIndex Index of the participant to evaluate
|
||||
*
|
||||
* @return array Filtered array of available services
|
||||
*/
|
||||
private function filterServicesByAgeConstraints(array $services, BookingDtoInterface $bookingDto, int $participantIndex): array
|
||||
private function filterServicesByAgeConstraints(array $services, BookingDto $bookingDto, int $participantIndex): array
|
||||
{
|
||||
$ageEvaluator = new ServiceAgeEvaluator();
|
||||
|
||||
@@ -664,12 +666,12 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
/**
|
||||
* Gets eligible insurances for a participant based on eligibility criteria.
|
||||
*
|
||||
* @param BookingDtoInterface $bookingDto The booking DTO containing travel and participant data
|
||||
* @param BookingDto $bookingDto The booking DTO containing travel and participant data
|
||||
* @param int $participantIndex The index of the participant to get eligible insurances for
|
||||
*
|
||||
* @return array Array of eligible insurance objects filtered by age, family status, and other constraints
|
||||
*/
|
||||
private function getEligibleInsurances(BookingDtoInterface $bookingDto, int $participantIndex): array
|
||||
private function getEligibleInsurances(BookingDto $bookingDto, int $participantIndex): array
|
||||
{
|
||||
$participant = $bookingDto->getParticipant($participantIndex);
|
||||
if (null === $participant) {
|
||||
@@ -682,11 +684,6 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
// They are only available as part of packages
|
||||
$availableInsurances = array_filter($availableInsurances, fn ($insurance) => !$insurance->complementary);
|
||||
|
||||
// Only apply insurance filtering for BookingCreateDto (creation workflow)
|
||||
if (!$bookingDto instanceof BookingCreateDto) {
|
||||
return $availableInsurances;
|
||||
}
|
||||
|
||||
// Use insurance matching service to filter based on eligibility criteria
|
||||
return $this->insuranceMatchingService->getEligibleInsurances(
|
||||
$availableInsurances,
|
||||
|
||||
Reference in New Issue
Block a user