feat: split nights off an accommodation booking as separate periods

addresses #869f6z36v
This commit is contained in:
fromme committed 2026-09-30 18:06:20 +02:00
1 parent 972839286c
commit 7001bc0cf2
35 files changed
+2221 -25

No files matched your search

@@ -26,7 +26,15 @@ class AccommodationBookingBreakdownCalculator
{
$breakdown = $booking->getPriceBreakdown() ?? $this->computeCurrent($booking);
return null !== $breakdown ? $this->withDiscounts($booking, $breakdown) : null;
if (null === $breakdown) {
return null;
}
// Snapshots frozen before split-off periods existed (pricing version 1) read as a
// booking without any, so templates only ever handle one shape.
$breakdown += ['periods' => [], 'periodsTotal' => 0];
return $this->withDiscounts($booking, $breakdown);
}
/**
@@ -100,6 +108,10 @@ class AccommodationBookingBreakdownCalculator
* Calculates against the current catalog. Use only while creating or explicitly editing
* a booking, or as a compatibility fallback for records created before price snapshots.
*
* The catalog prices the main period only; the split-off periods add their lines on top,
* so `total` is the grand total the discounts are taken from. The price rows are loaded for
* the whole stay, which the includedPax floor and the short-term surcharge are judged on.
*
* @return array<string, mixed>|null
*/
public function computeCurrent(AccommodationBooking $booking): ?array
@@ -118,16 +130,40 @@ class AccommodationBookingBreakdownCalculator
$dateTo,
);
return $this->priceCalculator->calculateFromSnapshots(
$breakdown = $this->priceCalculator->calculateFromSnapshots(
$booking->getPaxCount(),
$booking->getMinorsCount(),
$booking->getNights(),
$booking->getMainNights(),
$booking->getMainDateFrom() ?? $dateFrom,
$booking->getMainDateTo() ?? $dateTo,
$dateFrom,
$dateTo,
$booking->getNights(),
$prices,
$booking->getBoardServicePrice(),
$booking->getAdditionalServices(),
$accommodation->getCurrency(),
);
$periods = [];
foreach (array_filter([$booking->getLeadingPeriod(), $booking->getTrailingPeriod()]) as $period) {
$periods[] = [
'position' => $period->getPosition()->value,
'label' => $period->getLabel(),
'dateFrom' => $period->getDateFrom()->format('Y-m-d'),
'dateTo' => $period->getDateTo()->format('Y-m-d'),
'nights' => $period->getNights(),
'lines' => $period->getLines(),
'total' => $period->getTotal(),
];
}
$periodsTotal = $booking->getPeriodsTotal();
return [
...$breakdown,
'periods' => $periods,
'periodsTotal' => $periodsTotal,
'total' => $breakdown['total'] + $periodsTotal,
];
}
}