fix: preserve selected services from booking even when unavailable
When editing a booking, services that were previously booked but are no
longer available in the travel catalog were being dropped. This caused
API error 650 ("Anzahl Leistung stimmt nicht mit Teilnehmerzuordnung
überein") because the service participant counts no longer matched.
The fix ensures that in edit mode, booked services are merged with
travel data services in both:
- Form rendering (ParticipantFieldOptionsProvider): so checkboxes appear
- Handler validation (AbstractParticipantFieldHandler): so selections
are accepted
This allows users to keep their existing service selections or
deliberately replace them with other available options. Create mode
remains unchanged.
This commit is contained in:
1 parent
029a87c6ca
commit
957e20d763
16 files changed
+204
-37
No files matched your search
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Form\Service\Abstract;
|
||||
|
||||
use App\BusProNet\Model\Booking;
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Service\Contract\ParticipantFieldHandlerInterface;
|
||||
@@ -83,7 +84,7 @@ abstract class AbstractParticipantFieldHandler implements ParticipantFieldHandle
|
||||
*/
|
||||
protected function isEditMode(BookingDto $bookingDto): bool
|
||||
{
|
||||
return BookingDto::MODE_EDIT === $bookingDto->mode;
|
||||
return BookingDto::MODE_EDIT === $bookingDto->getMode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +96,7 @@ abstract class AbstractParticipantFieldHandler implements ParticipantFieldHandle
|
||||
*/
|
||||
protected function isCreateMode(BookingDto $bookingDto): bool
|
||||
{
|
||||
return BookingDto::MODE_CREATE === $bookingDto->mode;
|
||||
return BookingDto::MODE_CREATE === $bookingDto->getMode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,4 +270,65 @@ abstract class AbstractParticipantFieldHandler implements ParticipantFieldHandle
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves available services from travel data, merged with booked services in edit mode.
|
||||
*
|
||||
* In edit mode, services that were previously booked for the participant are included
|
||||
* even if they're no longer available in travel data. This prevents booked services
|
||||
* from being dropped during form validation when the travel catalog has changed.
|
||||
*
|
||||
* @param BookingDto $bookingDto The booking DTO containing travel and booking data
|
||||
* @param int $participantIndex The participant index to retrieve booked services for
|
||||
* @param mixed $serviceGroup The service group(s) to filter by (e.g., TOKEN_RENTALS)
|
||||
* @param bool $filterByTravelDateRange Whether to filter travel services by date range
|
||||
*
|
||||
* @return Service[] Array of available services keyed by service ID
|
||||
*/
|
||||
protected function getAvailableServicesWithBooked(
|
||||
BookingDto $bookingDto,
|
||||
int $participantIndex,
|
||||
mixed $serviceGroup,
|
||||
bool $filterByTravelDateRange = false,
|
||||
): array {
|
||||
$availableServices = $bookingDto->travel->getAdditionalServicesBySubTypes($serviceGroup, $filterByTravelDateRange);
|
||||
|
||||
if ($this->isEditMode($bookingDto) && null !== $bookingDto->booking) {
|
||||
$availableServices = $this->mergeBookedServices(
|
||||
$availableServices,
|
||||
$bookingDto->booking,
|
||||
$participantIndex,
|
||||
$serviceGroup
|
||||
);
|
||||
}
|
||||
|
||||
return $availableServices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges booked services into the available services array.
|
||||
*
|
||||
* @param Service[] $availableServices The services available from travel data
|
||||
* @param Booking $booking The booking containing previously booked services
|
||||
* @param int $participantIndex The participant index to retrieve booked services for
|
||||
* @param mixed $serviceGroup The service group(s) to filter by
|
||||
*
|
||||
* @return Service[] Merged array of services keyed by service ID
|
||||
*/
|
||||
private function mergeBookedServices(
|
||||
array $availableServices,
|
||||
Booking $booking,
|
||||
int $participantIndex,
|
||||
mixed $serviceGroup,
|
||||
): array {
|
||||
$bookedServices = $booking->getAdditionalServicesForParticipantByGroup($participantIndex, $serviceGroup);
|
||||
|
||||
foreach ($bookedServices as $bookedService) {
|
||||
if (false === isset($availableServices[$bookedService->id])) {
|
||||
$availableServices[$bookedService->id] = $bookedService;
|
||||
}
|
||||
}
|
||||
|
||||
return $availableServices;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user