feat: selectable drop-offs for inbound bus travel
This commit is contained in:
1 parent
f8a56b7de2
commit
f795a3ea21
31 files changed
+701
-200
No files matched your search
@@ -124,6 +124,10 @@ class BookingDataProcessor
|
||||
// Pickup location
|
||||
$participantData->pickup = $booking->getPickupForParticipant($index);
|
||||
|
||||
// Drop-off location
|
||||
$participantData->dropOff = $booking->getDropOffForParticipant($index);
|
||||
$participantData->differentDropOff = null !== $participantData->dropOff;
|
||||
|
||||
// Parking service (for self-organized PKW transportation)
|
||||
$parkingServices = $booking->getAdditionalServicesForParticipantByGroup($index, Constants::TOKEN_PARKING);
|
||||
if (false === empty($parkingServices)) {
|
||||
@@ -236,9 +240,9 @@ class BookingDataProcessor
|
||||
}
|
||||
|
||||
// Enrich pickup with data from travel (includes both outbound and inbound prices)
|
||||
// The outbound pickups already have inbound prices merged in from TravelParser
|
||||
if (null !== $participant->pickup && isset($travel->pickupsOutbound[$participant->pickup->id])) {
|
||||
$enrichedPickup = $travel->pickupsOutbound[$participant->pickup->id];
|
||||
// The pickups already have inbound prices merged in from TravelParser
|
||||
if (null !== $participant->pickup && isset($travel->pickups[$participant->pickup->id])) {
|
||||
$enrichedPickup = $travel->pickups[$participant->pickup->id];
|
||||
|
||||
// Copy all properties from enriched pickup to participant's pickup
|
||||
$participant->pickup->price = $enrichedPickup->price;
|
||||
@@ -251,6 +255,19 @@ class BookingDataProcessor
|
||||
$participant->pickup->code = $enrichedPickup->code;
|
||||
}
|
||||
|
||||
// Enrich drop-off with data from travel
|
||||
if (null !== $participant->dropOff && isset($travel->dropOffs[$participant->dropOff->id])) {
|
||||
$enrichedDropOff = $travel->dropOffs[$participant->dropOff->id];
|
||||
$participant->dropOff->price = $enrichedDropOff->price;
|
||||
$participant->dropOff->priceOutbound = $enrichedDropOff->priceOutbound;
|
||||
$participant->dropOff->priceInbound = $enrichedDropOff->priceInbound;
|
||||
$participant->dropOff->time = $enrichedDropOff->time;
|
||||
$participant->dropOff->city = $enrichedDropOff->city;
|
||||
$participant->dropOff->street = $enrichedDropOff->street;
|
||||
$participant->dropOff->postalCode = $enrichedDropOff->postalCode;
|
||||
$participant->dropOff->code = $enrichedDropOff->code;
|
||||
}
|
||||
|
||||
// Enrich insurance
|
||||
if (null !== $participant->insurance && isset($travel->insurances[$participant->insurance->id])) {
|
||||
$participant->insurance = $travel->insurances[$participant->insurance->id];
|
||||
@@ -301,6 +318,7 @@ class BookingDataProcessor
|
||||
$this->payloadBuilder->buildParticipantPayload($payload, $bookingData, $formData->participants);
|
||||
$this->payloadBuilder->buildServicesPayload($payload, $bookingData);
|
||||
$this->payloadBuilder->buildPickupPayload($payload, $bookingData);
|
||||
$this->payloadBuilder->buildDropOffPayload($payload, $bookingData);
|
||||
|
||||
// Add purchase vouchers if any exist
|
||||
$purchaseVouchers = $this->mappingCollector->collectPurchaseVouchers($formData);
|
||||
|
||||
@@ -203,9 +203,9 @@ class BookingPayloadBuilder
|
||||
*/
|
||||
public function buildPickupPayload(array &$payload, Booking $bookingData): void
|
||||
{
|
||||
if (0 < count($bookingData->pickupsOutbound)) {
|
||||
if (0 < count($bookingData->pickups)) {
|
||||
$payload['zustiege']['zustieg'] = [];
|
||||
foreach ($bookingData->pickupsOutbound as $pickup) {
|
||||
foreach ($bookingData->pickups as $pickup) {
|
||||
$uniqueMapping = array_unique($pickup->mapping);
|
||||
$payload['zustiege']['zustieg'][] = [
|
||||
'@idzustieg' => $pickup->id,
|
||||
@@ -216,6 +216,29 @@ class BookingPayloadBuilder
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the drop-off locations section of the payload.
|
||||
*
|
||||
* Only included in payload if there are actual drop-off assignments for bus transportation.
|
||||
*
|
||||
* @param array $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
*/
|
||||
public function buildDropOffPayload(array &$payload, Booking $bookingData): void
|
||||
{
|
||||
if (0 < count($bookingData->dropOffs)) {
|
||||
$payload['ausstiege']['ausstieg'] = [];
|
||||
foreach ($bookingData->dropOffs as $dropOff) {
|
||||
$uniqueMapping = array_unique($dropOff->mapping);
|
||||
$payload['ausstiege']['ausstieg'][] = [
|
||||
'@idzustieg' => $dropOff->id,
|
||||
'@anzahl' => count($uniqueMapping),
|
||||
'@zuordnung' => implode(',', array_map(fn ($index) => $index + 1, $uniqueMapping)),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a create booking request payload.
|
||||
*
|
||||
@@ -367,6 +390,10 @@ class BookingPayloadBuilder
|
||||
$this->addRoomMappingsToPayload($payload, $roomMap, $bookingDto);
|
||||
$this->addServicesFromMap($payload, 'zusatzleistungen', 'zusatzleistung', '@idleistung', $serviceMap);
|
||||
$this->addServicesFromMap($payload, 'zustiege', 'zustieg', '@idzustieg', $pickupMap);
|
||||
|
||||
$dropOffMap = $this->mappingCollector->collectDropOffMappings($bookingDto);
|
||||
$this->addServicesFromMap($payload, 'ausstiege', 'ausstieg', '@idzustieg', $dropOffMap);
|
||||
|
||||
$this->addServicesFromMap($payload, 'versicherungen', 'versicherung', '@idversicherung', $insuranceMap);
|
||||
|
||||
// Add purchase vouchers (regular purchase vouchers, excluding goodwill vouchers)
|
||||
|
||||
@@ -36,8 +36,8 @@ class ParticipantServiceProcessor
|
||||
$servicesToReset = [
|
||||
...$bookingData->additionalServices,
|
||||
...$bookingData->transportationServices,
|
||||
...$bookingData->pickupsOutbound,
|
||||
...$bookingData->pickupsInbound,
|
||||
...$bookingData->pickups,
|
||||
...$bookingData->dropOffs,
|
||||
...$bookingData->rooms,
|
||||
...$bookingData->insurances,
|
||||
];
|
||||
@@ -66,6 +66,7 @@ class ParticipantServiceProcessor
|
||||
$this->processAdditionalServices($participant, $bookingData, $travelData);
|
||||
$this->processTransportationServices($participant, $bookingData, $travelData);
|
||||
$this->processPickupLocations($participant, $bookingData);
|
||||
$this->processDropOffLocations($participant, $bookingData);
|
||||
$this->processRoomAssignment($participant, $bookingData);
|
||||
$this->processInsurance($participant, $bookingData, $travelData);
|
||||
}
|
||||
@@ -92,15 +93,15 @@ class ParticipantServiceProcessor
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($bookingData->pickupsOutbound as $pickup) {
|
||||
foreach ($bookingData->pickups as $pickup) {
|
||||
if (0 === count($pickup->mapping)) {
|
||||
unset($bookingData->pickupsOutbound[$pickup->id]);
|
||||
unset($bookingData->pickups[$pickup->id]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($bookingData->pickupsInbound as $pickup) {
|
||||
if (0 === count($pickup->mapping)) {
|
||||
unset($bookingData->pickupsInbound[$pickup->id]);
|
||||
foreach ($bookingData->dropOffs as $dropOff) {
|
||||
if (0 === count($dropOff->mapping)) {
|
||||
unset($bookingData->dropOffs[$dropOff->id]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,10 +233,34 @@ class ParticipantServiceProcessor
|
||||
$hasInboundBus = null !== $participant->transportationInbound && 'BUS' === $participant->transportationInbound->subType;
|
||||
|
||||
if (($hasOutboundBus || $hasInboundBus) && null !== $selectedPickup = $participant->pickup) {
|
||||
if (false === isset($bookingData->pickupsOutbound[$selectedPickup->id])) {
|
||||
$bookingData->pickupsOutbound[$selectedPickup->id] = $selectedPickup;
|
||||
if (false === isset($bookingData->pickups[$selectedPickup->id])) {
|
||||
$bookingData->pickups[$selectedPickup->id] = $selectedPickup;
|
||||
}
|
||||
$bookingData->pickupsOutbound[$selectedPickup->id]->mapping[] = $participant->index;
|
||||
$bookingData->pickups[$selectedPickup->id]->mapping[] = $participant->index;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes drop-off locations for participants using bus transportation.
|
||||
*
|
||||
* Only processes drop-off locations for bus transportation services and maps the participant
|
||||
* to their selected drop-off location.
|
||||
*
|
||||
* @param ParticipantDto $participant The participant data from the form
|
||||
* @param Booking $bookingData The booking data object to update
|
||||
*/
|
||||
private function processDropOffLocations(ParticipantDto $participant, Booking $bookingData): void
|
||||
{
|
||||
$hasOutboundBus = null !== $participant->transportationOutbound
|
||||
&& 'BUS' === $participant->transportationOutbound->subType;
|
||||
$hasInboundBus = null !== $participant->transportationInbound
|
||||
&& 'BUS' === $participant->transportationInbound->subType;
|
||||
|
||||
if (($hasOutboundBus || $hasInboundBus) && null !== $selectedDropOff = $participant->dropOff) {
|
||||
if (false === isset($bookingData->dropOffs[$selectedDropOff->id])) {
|
||||
$bookingData->dropOffs[$selectedDropOff->id] = $selectedDropOff;
|
||||
}
|
||||
$bookingData->dropOffs[$selectedDropOff->id]->mapping[] = $participant->index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,14 +31,14 @@ class PersonalDataSynchronizer
|
||||
* IMPORTANT: The applicant's address must never be modified. This method updates
|
||||
* participant addresses independently to ensure applicant data remains intact.
|
||||
*
|
||||
* @param array<ParticipantDto> $participants The participants array from the form
|
||||
* @param Booking $bookingData The booking data object to update
|
||||
* @param bool $isInternalAgencyBooking Whether to fill default names for canceled participants
|
||||
* @param array<ParticipantDto> $participants The participants array from the form
|
||||
* @param Booking $bookingData The booking data object to update
|
||||
* @param bool $isInternalAgencyBooking Whether to fill default names for canceled participants
|
||||
*/
|
||||
public function updateParticipantPersonalData(
|
||||
array $participants,
|
||||
Booking $bookingData,
|
||||
bool $isInternalAgencyBooking = false
|
||||
bool $isInternalAgencyBooking = false,
|
||||
): void {
|
||||
// Fill missing mandatory fields on applicant (for company bookings by travel agencies)
|
||||
// This is separate from participants - applicant may be a company while participants are real people
|
||||
|
||||
@@ -143,6 +143,28 @@ class ServiceMappingCollector
|
||||
return $pickupMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects drop-off location mappings.
|
||||
*
|
||||
* Collects the drop-off selection for the inbound/return direction.
|
||||
*
|
||||
* @return array<string, array<int>> Map of drop-off ID to participant IDs
|
||||
*/
|
||||
public function collectDropOffMappings(BookingDto $bookingDto): array
|
||||
{
|
||||
$dropOffMap = [];
|
||||
|
||||
foreach ($bookingDto->participants as $index => $participant) {
|
||||
$participantId = $index + 1;
|
||||
|
||||
if (null !== $participant->dropOff) {
|
||||
$dropOffMap[$participant->dropOff->id][] = $participantId;
|
||||
}
|
||||
}
|
||||
|
||||
return $dropOffMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects insurance mappings.
|
||||
*
|
||||
|
||||
Reference in new issue
Block a user