feat: selectable drop-offs for inbound bus travel

This commit is contained in:
Björn Fromme
2026-03-16 12:03:00 +01:00
parent f8a56b7de2
commit f795a3ea21
31 changed files with 701 additions and 200 deletions
+22 -1
View File
@@ -401,6 +401,15 @@ class BookingEditDraftService
}
}
// Drop-off (single) - merge strategy: only apply if resolves to valid drop-off
if (true === array_key_exists('dropOff', $data) && null !== $data['dropOff']) {
$resolved = $this->resolveDropOff($data['dropOff'], $travel);
if (null !== $resolved) {
$participant->dropOff = $resolved;
$participant->differentDropOff = true;
}
}
// Parking (boolean) - overwrite strategy: user can uncheck
if (true === array_key_exists('parking', $data)) {
$participant->parking = (bool) $data['parking'];
@@ -482,7 +491,19 @@ class BookingEditDraftService
return null;
}
return $travel->pickupsOutbound[$pickupId] ?? $travel->pickupsInbound[$pickupId] ?? null;
return $travel->pickups[$pickupId] ?? $travel->dropOffs[$pickupId] ?? null;
}
/**
* Resolves a drop-off ID to a Pickup object from the travel drop-offs list.
*/
private function resolveDropOff(?int $dropOffId, Travel $travel): ?object
{
if (null === $dropOffId) {
return null;
}
return $travel->dropOffs[$dropOffId] ?? null;
}
/**
+4 -2
View File
@@ -45,6 +45,7 @@ class BookingExportService
'Hinfahrt',
'Rückfahrt',
'Zustieg',
'Ausstieg',
'Parkplatz',
'Versicherung',
'Sammelversicherung',
@@ -133,13 +134,13 @@ class BookingExportService
}
}
foreach ($travel->pickupsOutbound as $pickup) {
foreach ($travel->pickups as $pickup) {
if (null !== $pickup->id) {
$pickups[$pickup->id] = $pickup->getLabel();
}
}
foreach ($travel->pickupsInbound as $pickup) {
foreach ($travel->dropOffs as $pickup) {
if (null !== $pickup->id) {
$pickups[$pickup->id] = $pickup->getLabel();
}
@@ -242,6 +243,7 @@ class BookingExportService
$this->resolveService($services['transportationOutbound'] ?? null, $lookups['services']),
$this->resolveService($services['transportationInbound'] ?? null, $lookups['services']),
$this->resolvePickup($services['pickup'] ?? null, $lookups['pickups']),
$this->resolvePickup($services['dropOff'] ?? null, $lookups['pickups']),
$this->formatBoolean($services['parking'] ?? false),
$this->resolveService($services['insurance'] ?? null, $lookups['services']),
$this->formatBoolean($services['bulkInsuranceBooking'] ?? false),
@@ -101,6 +101,7 @@ class BookingFingerprintService
'transportationOutbound' => $participant->transportationOutbound?->id,
'transportationInbound' => $participant->transportationInbound?->id,
'pickup' => $participant->pickup?->id,
'dropOff' => $participant->dropOff?->id,
'parking' => $participant->parking,
'insurance' => $participant->insurance?->id,
'bulkInsuranceBooking' => $participant->bulkInsuranceBooking,
@@ -111,6 +111,7 @@ class ParticipantPricingCalculator
'transportationOut' => $participant->transportationOutbound?->id ?? 'none',
'transportationIn' => $participant->transportationInbound?->id ?? 'none',
'pickup' => $participant->pickup?->id ?? 'none',
'dropOff' => $participant->dropOff?->id ?? 'none',
'parking' => $participant->parkingService?->id ?? 'none',
'courses' => implode('_', array_map(fn ($s) => $s->id, $participant->courses ?? [])),
'additionalServices' => implode('_', array_map(fn ($s) => $s->id, $participant->additionalServices ?? [])),
@@ -240,6 +241,11 @@ class ParticipantPricingCalculator
$serviceTotal += $participant->pickup->price;
}
// Drop-off pricing (charged when inbound transportation is BUS and a drop-off is selected)
if (null !== $participant->dropOff && null !== $participant->dropOff->price) {
$serviceTotal += $participant->dropOff->price;
}
if (null !== $participant->parkingService && null !== $participant->parkingService->price) {
if (false === $onlyInsuranceCalculationServices || true === $participant->parkingService->includeInInsuranceCalculation) {
$serviceTotal += $participant->parkingService->price;
+9
View File
@@ -143,6 +143,15 @@ class ServicePricingCalculator
}
}
// Drop-off pricing (charged when inbound is BUS and a drop-off is selected)
if (null !== $participant->dropOff && null !== $participant->dropOff->price) {
if ($participant->dropOff->price < 0) {
$participantTransportationDiscountCost += $participant->dropOff->price;
} else {
$participantTransportationPositiveCost += $participant->dropOff->price;
}
}
// Parking service pricing
if (null !== $participant->parkingService && null !== $participant->parkingService->price) {
$participantParkingCost += $participant->parkingService->price;