feat: correct calculation and display of individual pricing

This commit is contained in:
Björn Fromme
2025-09-26 15:32:22 +02:00
parent 55a24b99f0
commit bd7b70e465
4 changed files with 462 additions and 2 deletions
+130 -1
View File
@@ -66,12 +66,17 @@ class BookingPriceCalculatorService
continue;
}
$totalPrice = $roomSelection->quantity * $room->price;
// Calculate participant count for this room selection
$participantCount = $room->minPax * $roomSelection->quantity;
// Each participant pays the full room price
$totalPrice = $participantCount * $room->price;
$roomPricing[] = [
'roomId' => $room->id,
'label' => $room->label,
'quantity' => $roomSelection->quantity,
'participantCount' => $participantCount,
'unitPrice' => $room->price,
'totalPrice' => $totalPrice,
];
@@ -171,6 +176,68 @@ class BookingPriceCalculatorService
return '€'.$this->formatPrice($price);
}
/**
* Calculates the total price for an individual participant.
*
* This method calculates the complete price breakdown for a single participant,
* including their room allocation (full room price) and all selected services.
*
* @param BookingDtoInterface $bookingDto The booking data containing all participants
* @param int $participantIndex The index of the participant to calculate for
*
* @return float The total price for the specified participant
*/
public function calculateIndividualParticipantPrice(BookingDtoInterface $bookingDto, int $participantIndex): float
{
if (false === $bookingDto instanceof BookingCreateDto) {
return 0.0;
}
$participant = $bookingDto->getParticipant($participantIndex);
if (null === $participant) {
return 0.0;
}
$totalPrice = 0.0;
// Add room price if participant is assigned to a room
if (null !== $participant->assignedRoomId) {
$room = $this->getRoomById($bookingDto, $participant->assignedRoomId);
if (null !== $room && null !== $room->price) {
// Each participant pays the full room price
$totalPrice += $room->price;
}
}
// Add service prices for this participant
$totalPrice += $this->calculateParticipantServiceTotal($participant);
return $totalPrice;
}
/**
* Calculates individual prices for all participants in a booking.
*
* @param BookingDtoInterface $bookingDto The booking data containing all participants
*
* @return array Array indexed by participant index containing individual prices
*/
public function calculateAllParticipantIndividualPrices(BookingDtoInterface $bookingDto): array
{
if (false === $bookingDto instanceof BookingCreateDto) {
return [];
}
$participantPrices = [];
$participants = $bookingDto->getParticipants();
foreach ($participants as $index => $participant) {
$participantPrices[$index] = $this->calculateIndividualParticipantPrice($bookingDto, $index);
}
return $participantPrices;
}
/**
* Aggregates all transportation-related services and pricing into separate line items.
*
@@ -405,6 +472,68 @@ class BookingPriceCalculatorService
$serviceAggregation[$serviceKey]['totalPrice'] += $service->price * $quantity;
}
/**
* Calculates the total service cost for a single participant.
*
* @param ParticipantDto $participant The participant to calculate services for
*
* @return float The total service cost for this participant
*/
private function calculateParticipantServiceTotal(ParticipantDto $participant): float
{
$serviceTotal = 0.0;
// Single service selections
if (null !== $participant->skiPass && null !== $participant->skiPass->price) {
$serviceTotal += $participant->skiPass->price;
}
if (null !== $participant->rentalInsurance && null !== $participant->rentalInsurance->price) {
$serviceTotal += $participant->rentalInsurance->price;
}
// Transportation services
if (null !== $participant->transportationOutbound && null !== $participant->transportationOutbound->price) {
$serviceTotal += $participant->transportationOutbound->price;
}
if (null !== $participant->transportationInbound && null !== $participant->transportationInbound->price) {
$serviceTotal += $participant->transportationInbound->price;
}
if (null !== $participant->pickupOutbound && null !== $participant->pickupOutbound->price) {
$serviceTotal += $participant->pickupOutbound->price;
}
if (null !== $participant->pickupInbound && null !== $participant->pickupInbound->price) {
$serviceTotal += $participant->pickupInbound->price;
}
if (null !== $participant->parkingService && null !== $participant->parkingService->price) {
$serviceTotal += $participant->parkingService->price;
}
// Multiple service selections
$multipleServiceArrays = [
'courses' => $participant->courses,
'additionalServices' => $participant->additionalServices,
'board' => $participant->board,
'rentals' => $participant->rentals,
];
foreach ($multipleServiceArrays as $serviceArray) {
if (true === is_array($serviceArray)) {
foreach ($serviceArray as $service) {
if ($service instanceof Service && null !== $service->price) {
$serviceTotal += $service->price;
}
}
}
}
return $serviceTotal;
}
/**
* Retrieves a room by ID from the booking's travel data.
*/