feat: extended price mismatch diagnostics in logs

This commit is contained in:
Björn Fromme
2026-03-18 15:24:52 +01:00
parent 02ff28acdd
commit ca7d0b6965
3 changed files with 244 additions and 0 deletions
@@ -0,0 +1,156 @@
<?php
declare(strict_types=1);
namespace App\Service;
use App\BusProNet\Constants;
use App\BusProNet\Model\BookingResponse;
use App\BusProNet\Model\PriceItem;
use App\Form\Model\BookingDto;
/**
* Builds diagnostic payloads for booking price mismatches.
*/
class BookingPriceMismatchDiagnosticsService
{
public function __construct(
private readonly BookingPriceCalculatorService $priceCalculator,
) {
}
/**
* @return array<string, mixed>
*/
public function buildDiagnostics(BookingDto $bookingCreateDto, BookingResponse $response): array
{
$pricingBreakdown = $this->priceCalculator->getPricingBreakdown($bookingCreateDto);
$roomLines = $pricingBreakdown['rooms'] ?? [];
$serviceGroups = $pricingBreakdown['services'] ?? [];
$roomTotal = round(array_sum(array_column($roomLines, 'totalPrice')), 2);
$serviceTotal = round(array_sum(array_column($serviceGroups, 'groupTotal')), 2);
$insuranceTotal = round($this->extractInsuranceTotal($serviceGroups), 2);
$selectedRooms = [];
foreach ($bookingCreateDto->getSelectedRooms() as $roomSelection) {
$selectedRooms[] = [
'roomId' => $roomSelection->id,
'quantity' => $roomSelection->quantity,
'unitPrice' => $roomSelection->price,
'capacity' => $roomSelection->capacity,
];
}
$participantInsurance = [];
foreach ($bookingCreateDto->getParticipants() as $index => $participant) {
$participantInsurance[] = [
'participantIndex' => $index,
'bulkInsuranceBooking' => $participant->bulkInsuranceBooking,
'insuranceId' => $participant->insurance?->id,
'insurancePrice' => $participant->insurance?->price,
'assignedRoomId' => $participant->assignedRoomId,
];
}
$apiPriceItems = array_map(static function (PriceItem $item): array {
return [
'position' => $item->position,
'type' => $item->type,
'subType' => $item->subType,
'id' => $item->id,
'quantity' => $item->quantity,
'totalPrice' => round($item->totalPrice, 2),
];
}, $response->priceItems);
$apiRoomTotal = round($this->sumApiRoomTotal($response->priceItems), 2);
$apiInsuranceTotal = round($this->sumApiInsuranceTotal($response->priceItems), 2);
$apiTotal = round($response->totalPrice ?? 0.0, 2);
$apiServiceTotal = round($apiTotal - $apiRoomTotal, 2);
$deltaTotal = round(($pricingBreakdown['grandTotal'] ?? 0.0) - $apiTotal, 2);
$deltaRoom = round($roomTotal - $apiRoomTotal, 2);
$deltaService = round($serviceTotal - $apiServiceTotal, 2);
$deltaInsurance = round($insuranceTotal - $apiInsuranceTotal, 2);
return [
'localBreakdown' => [
'grandTotal' => round($pricingBreakdown['grandTotal'] ?? 0.0, 2),
'roomTotal' => $roomTotal,
'serviceTotal' => $serviceTotal,
'insuranceTotal' => $insuranceTotal,
],
'apiBreakdown' => [
'total' => $apiTotal,
'roomTotal' => $apiRoomTotal,
'serviceTotal' => $apiServiceTotal,
'insuranceTotal' => $apiInsuranceTotal,
],
'deltaBreakdown' => [
'deltaTotal' => $deltaTotal,
'deltaRoom' => $deltaRoom,
'deltaService' => $deltaService,
'deltaInsurance' => $deltaInsurance,
],
'roomLines' => $roomLines,
'serviceGroups' => $serviceGroups,
'selectedRooms' => $selectedRooms,
'roomAssignmentCounts' => $bookingCreateDto->getRoomAssignmentCounts(),
'participantInsurance' => $participantInsurance,
'apiPriceItems' => $apiPriceItems,
];
}
/**
* @param array<int, array<string, mixed>> $serviceGroups
*/
private function extractInsuranceTotal(array $serviceGroups): float
{
$total = 0.0;
foreach ($serviceGroups as $group) {
foreach (($group['services'] ?? []) as $service) {
$subType = $service['subType'] ?? null;
if (null === $subType || false === in_array($subType, Constants::TOKEN_INSURANCES, true)) {
continue;
}
$total += (float) ($service['totalPrice'] ?? 0.0);
}
}
return $total;
}
/**
* @param array<int, PriceItem> $priceItems
*/
private function sumApiRoomTotal(array $priceItems): float
{
$total = 0.0;
foreach ($priceItems as $item) {
if ('UNT' === $item->type) {
$total += $item->totalPrice;
}
}
return $total;
}
/**
* @param array<int, PriceItem> $priceItems
*/
private function sumApiInsuranceTotal(array $priceItems): float
{
$total = 0.0;
foreach ($priceItems as $item) {
if (null !== $item->subType && true === in_array($item->subType, Constants::TOKEN_INSURANCES, true)) {
$total += $item->totalPrice;
}
}
return $total;
}
}