feat: extended price mismatch diagnostics in logs
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user