*/ 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> $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 $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 $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; } }