config = $config ?? config('DigitMotor'); $this->api = $api ?? new DigitApiClient($this->config); $this->quoteModel = new MotorQuoteModel(); $this->vehicleModel = new MotorVehicleModel(); $this->kycModel = new MotorKycModel(); $this->paymentModel = new MotorPaymentModel(); $this->policyModel = new MotorPolicyModel(); } /** * Create/update local quote + call motorQuickQuote. * * @throws DigitApiException */ public function quickQuote(array $input): array { $enquiryId = $input['enquiry_id'] ?? ('NH' . date('ymdHis') . random_int(100, 999)); $payload = $this->buildQuickQuotePayload($input, $enquiryId); $quoteId = $this->persistQuoteShell($input, $enquiryId, 'DRAFT'); $response = $this->api->post( $this->config->executorPath, $payload, $this->config->integrationIds['quickQuote'], $quoteId ); $premium = $this->pickNumber($response, ['grossPremium', 'premium', 'netPremium', 'totalPremium']); $idv = $this->pickNumber($response, ['idv', 'vehicleIDV', 'insuredDeclaredValue']); if ($idv === null && isset($response['vehicle']['vehicleIDV']['idv'])) { $idv = (float) $response['vehicle']['vehicleIDV']['idv']; } $vehicleIdv = $response['vehicle']['vehicleIDV'] ?? $response['vehicleIDV'] ?? []; $this->quoteModel->update($quoteId, [ 'premium' => $premium, 'idv' => $idv, 'status' => 'QUOTED', 'coverage_details' => json_encode($input['coverages'] ?? $payload['contract']['coverages'] ?? []), ]); $vehicle = $this->vehicleModel->where('quote_id', $quoteId)->first(); if ($vehicle) { $this->vehicleModel->update($vehicle['id'], [ 'idv' => $idv ?? ($vehicleIdv['idv'] ?? null), 'default_idv' => $vehicleIdv['defaultIdv'] ?? $vehicleIdv['defaultIDV'] ?? null, 'minimum_idv' => $vehicleIdv['minimumIdv'] ?? $vehicleIdv['minIdv'] ?? null, 'maximum_idv' => $vehicleIdv['maximumIdv'] ?? $vehicleIdv['maxIdv'] ?? null, ]); } return [ 'quote_id' => $quoteId, 'enquiry_id' => $enquiryId, 'premium' => $premium, 'idv' => $idv, 'status' => 'QUOTED', 'response' => $response, ]; } /** * Call motorCreateQuote for an existing quoted row. * * @throws DigitApiException */ public function createQuote(int $quoteId, array $input = []): array { $detail = $this->quoteModel->getDetail($quoteId); if (!$detail) { throw new DigitApiException('Quote not found.', '404', 404); } $payload = $this->buildCreateQuotePayload($detail, $input); $response = $this->api->post( $this->config->executorPath, $payload, $this->config->integrationIds['createQuote'], $quoteId ); $quoteNumber = $response['quoteNumber'] ?? $response['policyNumber'] ?? ($response['contract']['quoteNumber'] ?? null); $applicationId = $response['applicationId'] ?? $response['policyId'] ?? ($response['contract']['applicationId'] ?? null); $premium = $this->pickNumber($response, ['grossPremium', 'premium', 'netPremium', 'totalPremium']) ?? $detail['premium']; $this->quoteModel->update($quoteId, [ 'quote_number' => $quoteNumber, 'application_id' => $applicationId, 'premium' => $premium, 'start_date' => $input['start_date'] ?? $detail['start_date'], 'end_date' => $input['end_date'] ?? $detail['end_date'], 'status' => 'CREATED', ]); return [ 'quote_id' => $quoteId, 'quote_number' => $quoteNumber, 'application_id' => $applicationId, 'premium' => $premium, 'status' => 'CREATED', 'response' => $response, ]; } /** * Poll KYC status and upsert motor_kyc. * * @throws DigitApiException */ public function kycStatus(int $quoteId): array { $detail = $this->quoteModel->getDetail($quoteId); if (!$detail || empty($detail['quote_number'])) { throw new DigitApiException('Quote number is required for KYC status. Create quote first.', '400', 400); } $payload = [ 'queryParam' => [ 'policyNumber' => $detail['quote_number'], ], ]; $response = $this->api->post( $this->config->executorPath, $payload, $this->config->integrationIds['kycStatus'], $quoteId ); $status = $response['kycVerificationStatus'] ?? $response['kycStatus'] ?? ($response['kyc']['kycVerificationStatus'] ?? null); $row = [ 'quote_id' => $quoteId, 'kyc_id' => $response['kycId'] ?? ($response['kyc']['kycId'] ?? null), 'kyc_verification_status' => $status, 'reference_id' => $response['referenceId'] ?? ($response['kyc']['referenceId'] ?? null), 'link' => $response['link'] ?? ($response['kyc']['link'] ?? null), 'mismatch_type' => $response['mismatchType'] ?? null, 'id_verification_doc_type' => $response['idVerificationDocType'] ?? null, 'address_verification_doc_type' => $response['addressVerificationDocType'] ?? null, 'mode' => $response['mode'] ?? 'O', 'checked_at' => date('Y-m-d H:i:s'), ]; $existing = $this->kycModel->where('quote_id', $quoteId)->orderBy('id', 'DESC')->first(); if ($existing) { $this->kycModel->update($existing['id'], $row); $row['id'] = $existing['id']; } else { $row['id'] = $this->kycModel->insert($row); } $normalized = strtoupper((string) $status); if (in_array($normalized, ['DONE', 'VERIFIED', 'SUCCESS', 'COMPLETED'], true)) { $this->quoteModel->update($quoteId, ['status' => 'KYC_DONE']); } return [ 'quote_id' => $quoteId, 'kyc' => $row, 'status' => $status, 'response' => $response, ]; } /** * Generate payment link. * * @throws DigitApiException */ public function paymentLink(int $quoteId, array $input = []): array { $detail = $this->quoteModel->getDetail($quoteId); if (!$detail || empty($detail['application_id'])) { throw new DigitApiException('Application ID is required for payment. Create quote first.', '400', 400); } $premiumAmount = $input['premium_amount'] ?? ('INR ' . number_format((float) ($detail['premium'] ?? 0), 2, '.', '')); $successUrl = $input['success_return_url'] ?? base_url('digit-motor/payment/callback/success/' . $quoteId); $cancelUrl = $input['cancel_return_url'] ?? base_url('digit-motor/payment/callback/cancel/' . $quoteId); $payload = [ 'premiumAmount' => $premiumAmount, 'paymentMode' => $input['payment_mode'] ?? 'EB', 'successReturnUrl' => $successUrl, 'cancelReturnUrl' => $cancelUrl, 'applicationId' => $detail['application_id'], ]; $response = $this->api->post( $this->config->executorPath, $payload, $this->config->integrationIds['payment'], $quoteId ); $dispatcher = $response['dispatcherResponse'] ?? $response['paymentLink'] ?? $response['redirectUrl'] ?? null; $row = [ 'quote_id' => $quoteId, 'application_id' => $detail['application_id'], 'digit_payment_id' => $response['digitPaymentId'] ?? $response['paymentId'] ?? null, 'request_reference' => $response['requestReference'] ?? null, 'payment_mode' => $payload['paymentMode'], 'cancel_return_url' => $cancelUrl, 'success_return_url' => $successUrl, 'dispatcher_response' => $dispatcher, 'premium' => $detail['premium'], 'payment_status' => 'LINK_GENERATED', 'created_at' => date('Y-m-d H:i:s'), ]; $row['id'] = $this->paymentModel->insert($row); return [ 'quote_id' => $quoteId, 'payment' => $row, 'dispatcher_response'=> $dispatcher, 'response' => $response, ]; } /** * Poll policy status. * * @throws DigitApiException */ public function policyStatus(int $quoteId): array { $detail = $this->quoteModel->getDetail($quoteId); if (!$detail || empty($detail['quote_number'])) { throw new DigitApiException('Quote/policy number is required for policy status.', '400', 400); } $payload = [ 'queryParam' => [ 'policyNumber' => $detail['quote_number'], ], ]; $response = $this->api->post( $this->config->executorPath, $payload, $this->config->integrationIds['policyStatus'], $quoteId ); $policyStatus = $response['policyStatus'] ?? $response['status'] ?? ($response['policy']['policyStatus'] ?? null); $policyNumber = $response['policyNumber'] ?? $detail['quote_number']; $row = [ 'quote_id' => $quoteId, 'policy_number' => $policyNumber, 'policy_status' => $policyStatus, 'response_code' => isset($response['responseCode']) ? (string) $response['responseCode'] : null, 'response_message' => $response['responseMessage'] ?? null, 'updated_at' => date('Y-m-d H:i:s'), ]; $existing = $this->policyModel->where('quote_id', $quoteId)->first(); if ($existing) { $this->policyModel->update($existing['id'], $row); $row['id'] = $existing['id']; $row['schedule_path'] = $existing['schedule_path']; $row['proposal_path'] = $existing['proposal_path']; } else { $row['id'] = $this->policyModel->insert($row); } $normalized = strtoupper((string) $policyStatus); if (in_array($normalized, ['EFFECTIVE', 'COMPLETE', 'COMPLETED', 'ACTIVE'], true)) { $this->quoteModel->update($quoteId, ['status' => 'EFFECTIVE']); if (!empty($detail['payment'])) { $this->paymentModel->update($detail['payment']['id'], ['payment_status' => 'PAID']); } } return [ 'quote_id' => $quoteId, 'policy' => $row, 'status' => $policyStatus, 'response' => $response, ]; } /** * Fetch policy PDF paths (only after policy is effective-ish). * * @throws DigitApiException */ public function policyPdf(int $quoteId): array { $detail = $this->quoteModel->getDetail($quoteId); if (!$detail) { throw new DigitApiException('Quote not found.', '404', 404); } $policyId = $detail['application_id'] ?? ($detail['policy']['policy_number'] ?? null); if (empty($policyId)) { throw new DigitApiException('Application/policy ID is required for PDF.', '400', 400); } $policyStatus = strtoupper((string) ($detail['policy']['policy_status'] ?? $detail['status'] ?? '')); if (!in_array($policyStatus, ['EFFECTIVE', 'COMPLETE', 'COMPLETED', 'ACTIVE', 'PAID'], true) && !in_array(strtoupper((string) $detail['status']), ['EFFECTIVE', 'PAID'], true)) { throw new DigitApiException( 'Policy PDF is available only after the policy is effective. Current status: ' . ($detail['status'] ?? 'unknown'), '400', 400 ); } $payload = [ 'policyId' => $policyId, 'headerParam' => [ 'Authorization' => $this->config->pdfAuthKey, ], ]; $response = $this->api->post( $this->config->executorPath, $payload, $this->config->integrationIds['policyPdf'], $quoteId ); $schedulePath = $response['schedulePath'] ?? $response['policySchedulePath'] ?? ($response['schedule'] ?? null); $proposalPath = $response['proposalPath'] ?? $response['proposalFormPath'] ?? ($response['proposal'] ?? null); $row = [ 'quote_id' => $quoteId, 'policy_number' => $detail['quote_number'], 'policy_status' => $detail['policy']['policy_status'] ?? $detail['status'], 'schedule_path' => $schedulePath, 'proposal_path' => $proposalPath, 'response_code' => isset($response['responseCode']) ? (string) $response['responseCode'] : null, 'response_message' => $response['responseMessage'] ?? null, 'updated_at' => date('Y-m-d H:i:s'), ]; $existing = $this->policyModel->where('quote_id', $quoteId)->first(); if ($existing) { $this->policyModel->update($existing['id'], $row); $row['id'] = $existing['id']; } else { $row['id'] = $this->policyModel->insert($row); } return [ 'quote_id' => $quoteId, 'policy' => $row, 'response' => $response, ]; } protected function persistQuoteShell(array $input, string $enquiryId, string $status): int { $existing = $this->quoteModel->where('enquiry_id', $enquiryId)->first(); $quoteData = [ 'enquiry_id' => $enquiryId, 'policy_holder_type' => $input['policy_holder_type'] ?? 'INDIVIDUAL', 'insurance_product_code' => (string) ($input['insurance_product_code'] ?? '20101'), 'sub_insurance_product_code' => (string) ($input['sub_insurance_product_code'] ?? 'PB'), 'previous_insurer_code' => $input['previous_insurer_code'] ?? null, 'previous_policy_expiry_date'=> $input['previous_policy_expiry_date'] ?? null, 'external_policy_number' => $input['previous_policy_number'] ?? null, 'is_ncb_transfer' => !empty($input['is_ncb_transfer']) ? 1 : 0, 'start_date' => $input['start_date'] ?? null, 'end_date' => $input['end_date'] ?? null, 'pincode' => (string) ($input['pincode'] ?? ''), 'coverage_details' => json_encode($input['coverages'] ?? []), 'status' => $status, ]; if ($existing) { $quoteId = (int) $existing['id']; $this->quoteModel->update($quoteId, $quoteData); $vehicle = $this->vehicleModel->where('quote_id', $quoteId)->first(); $vehicleData = $this->vehicleRowFromInput($input, $quoteId); if ($vehicle) { $this->vehicleModel->update($vehicle['id'], $vehicleData); } else { $this->vehicleModel->insert($vehicleData); } return $quoteId; } $quoteId = (int) $this->quoteModel->insert($quoteData); $this->vehicleModel->insert($this->vehicleRowFromInput($input, $quoteId)); return $quoteId; } protected function vehicleRowFromInput(array $input, int $quoteId): array { $plate = strtoupper(preg_replace('/\s+/', '', (string) ($input['license_plate_number'] ?? ''))); $authority = $input['registration_authority'] ?? null; if (!$authority && strlen($plate) >= 4) { $authority = substr($plate, 0, 4); } return [ 'quote_id' => $quoteId, 'is_vehicle_new' => !empty($input['is_vehicle_new']) ? 1 : 0, 'vehicle_maincode' => (string) ($input['vehicle_maincode'] ?? ''), 'license_plate_number' => $plate, 'vehicle_identification_number' => $input['vehicle_identification_number'] ?? null, 'engine_number' => $input['engine_number'] ?? null, 'manufacture_date' => $input['manufacture_date'] ?? date('Y-m-d'), 'registration_date' => $input['registration_date'] ?? date('Y-m-d'), 'registration_authority' => $authority, 'idv' => $input['idv'] ?? 0, ]; } protected function buildQuickQuotePayload(array $input, string $enquiryId): array { $plate = strtoupper(preg_replace('/\s+/', '', (string) ($input['license_plate_number'] ?? ''))); $authority = $input['registration_authority'] ?? (strlen($plate) >= 4 ? substr($plate, 0, 4) : ''); $coverages = $this->defaultCoverages($input['coverages'] ?? []); return [ 'vehicle' => [ 'isVehicleNew' => !empty($input['is_vehicle_new']), 'vehicleIDV' => [ 'idv' => (string) ($input['idv'] ?? '0'), ], 'vehicleMaincode' => (string) ($input['vehicle_maincode'] ?? ''), 'licensePlateNumber' => $plate, 'registrationAuthority' => $authority, 'vehicleIdentificationNumber' => $input['vehicle_identification_number'] ?? '', 'engineNumber' => $input['engine_number'] ?? '', 'manufactureDate' => $input['manufacture_date'] ?? null, 'registrationDate' => $input['registration_date'] ?? null, 'fastTagNumber' => null, 'ownershipSerialNumber' => 0, ], 'previousInsurer' => [ 'isPreviousInsurerKnown' => !empty($input['previous_insurer_code']), 'previousInsurerCode' => isset($input['previous_insurer_code']) ? (string) $input['previous_insurer_code'] : '', 'previousPolicyExpiryDate' => $input['previous_policy_expiry_date'] ?? null, 'previousPolicyNumber' => $input['previous_policy_number'] ?? '', 'isClaimInLastYear' => !empty($input['is_claim_in_last_year']), 'previousNoClaimBonus' => $input['previous_ncb'] ?? 'ZERO', 'previousPolicyType' => $input['previous_policy_type'] ?? '', ], 'contract' => [ 'insuranceProductCode' => (int) ($input['insurance_product_code'] ?? 20102), 'startDate' => $input['start_date'] ?? null, 'endDate' => $input['end_date'] ?? null, 'policyTerm' => (int) ($input['policy_term'] ?? 1), 'coverages' => $coverages, 'subInsuranceProductCode' => $input['sub_insurance_product_code'] ?? 'PB', 'policyHolderType' => $input['policy_holder_type'] ?? 'INDIVIDUAL', 'externalPolicyNumber' => $input['external_policy_number'] ?? '', ], 'pinCode' => (int) ($input['pincode'] ?? 0), 'enquiryId' => $enquiryId, ]; } protected function buildCreateQuotePayload(array $detail, array $input): array { $vehicle = $detail['vehicle'] ?? []; $coverages = $input['coverages'] ?? (is_array($detail['coverage_details']) ? $detail['coverage_details'] : $this->defaultCoverages([])); $plate = $vehicle['license_plate_number'] ?? ''; $authority = $vehicle['registration_authority'] ?? (strlen($plate) >= 4 ? substr($plate, 0, 4) : ''); $startDate = $input['start_date'] ?? $detail['start_date']; $endDate = $input['end_date'] ?? $detail['end_date']; $payload = [ 'enquiryId' => $detail['enquiry_id'], 'contract' => [ 'insuranceProductCode' => (string) ($detail['insurance_product_code'] ?? '20101'), 'subInsuranceProductCode' => (string) ($detail['sub_insurance_product_code'] ?? 'PB'), 'startDate' => $startDate, 'endDate' => $endDate, 'policyHolderType' => $detail['policy_holder_type'] ?? 'INDIVIDUAL', 'externalPolicyNumber' => $detail['external_policy_number'], 'isNCBTransfer' => !empty($detail['is_ncb_transfer']) ? true : null, 'coverages' => $coverages, ], 'vehicle' => [ 'isVehicleNew' => !empty($vehicle['is_vehicle_new']) ? 'false' : 'false', 'vehicleMaincode' => $vehicle['vehicle_maincode'] ?? '', 'licensePlateNumber' => $plate, 'vehicleIdentificationNumber' => $vehicle['vehicle_identification_number'] ?? '', 'registrationAuthority' => $authority, 'engineNumber' => $vehicle['engine_number'] ?? '', 'manufactureDate' => $vehicle['manufacture_date'] ?? null, 'registrationDate' => $vehicle['registration_date'] ?? null, 'vehicleIDV' => [ 'idv' => (float) ($vehicle['idv'] ?? $detail['idv'] ?? 0), ], 'usageType' => null, 'permitType' => null, 'motorType' => null, ], 'hypothecation' => [ 'isHypothecation' => false, 'hypothecationAgency' => '', 'hypothecationCIty' => '', ], 'previousInsurer' => [ 'isPreviousInsurerKnown' => !empty($detail['previous_insurer_code']), 'previousInsurerCode' => isset($detail['previous_insurer_code']) ? (string) $detail['previous_insurer_code'] : '', 'previousPolicyNumber' => $detail['external_policy_number'] ?? '', 'previousPolicyExpiryDate' => $detail['previous_policy_expiry_date'] ?? null, 'isClaimInLastYear' => $input['is_claim_in_last_year'] ?? 'false', 'originalPreviousPolicyType' => $input['previous_policy_type'] ?? '1OD_1TP', 'previousPolicyType' => $input['previous_policy_type'] ?? '1OD_1TP', 'previousNoClaimBonus' => $input['previous_ncb'] ?? 'ZERO', 'currentThirdPartyPolicy' => null, ], 'pospInfo' => [ 'isPOSP' => 'false', 'pospName' => null, 'pospUniqueNumber' => null, 'pospLocation' => '', 'pospPanNumber' => null, 'pospAadhaarNumber' => null, 'pospContactNumber' => null, ], 'persons' => $input['persons'] ?? [$this->defaultPerson($input, $detail)], 'dealer' => [ 'dealerName' => '', 'city' => '', 'deliveryDate' => null, ], 'motorQuestions' => [ 'furtherAgreement' => '', 'selfInspection' => false, 'financer' => '', ], 'motorBreakIn' => [ 'isBreakin' => false, 'breakinExcess' => null, 'breakinComments' => null, 'isPreInspectionWaived' => false, 'isPreInspectionCompleted' => null, 'isDocumentUploaded' => null, ], 'kyc' => $input['kyc'] ?? [ 'isKYCDone' => !empty($input['kyc_id']), 'ckycReferenceDocId' => $input['ckyc_doc_id'] ?? 'D07', 'ckycReferenceNumber' => $input['ckyc_reference'] ?? ($input['pan'] ?? ''), 'dateOfBirth' => $input['dob'] ?? null, 'photo' => '', ], 'nominee' => $input['nominee'] ?? [ 'firstName' => $input['nominee_first_name'] ?? 'NOMINEE', 'middleName' => '', 'lastName' => $input['nominee_last_name'] ?? '', 'dateOfBirth' => $input['nominee_dob'] ?? '1990-01-01', 'relation' => $input['nominee_relation'] ?? 'OTHER', 'personType' => 'INDIVIDUAL', ], ]; // Fix isVehicleNew flag properly $payload['vehicle']['isVehicleNew'] = !empty($vehicle['is_vehicle_new']) ? 'true' : 'false'; return $payload; } protected function defaultPerson(array $input, array $detail): array { $pincode = $detail['pincode'] ?? ($input['pincode'] ?? ''); return [ 'personType' => 'INDIVIDUAL', 'addresses' => [[ 'addressType' => 'PRIMARY_RESIDENCE', 'flatNumber' => null, 'streetNumber' => null, 'street' => $input['address'] ?? '', 'district' => '', 'state' => (string) ($input['state_code'] ?? ''), 'city' => $input['city'] ?? '', 'country' => 'IN', 'pincode' => (string) $pincode, ]], 'communications' => [ [ 'communicationType' => 'MOBILE', 'communicationId' => $input['mobile'] ?? '9999999999', 'isPrefferedCommunication' => true, ], [ 'communicationType' => 'EMAIL', 'communicationId' => $input['email'] ?? 'noreply@nhance.local', 'isPrefferedCommunication' => true, ], ], 'identificationDocuments' => [ [ 'issuingPlace' => 'IN', 'documentType' => 'PAN_CARD', 'documentId' => $input['pan'] ?? '', ], ], 'isPolicyHolder' => true, 'isVehicleOwner' => true, 'firstName' => $input['first_name'] ?? 'CUSTOMER', 'middleName' => null, 'lastName' => $input['last_name'] ?? '', 'dateOfBirth' => $input['dob'] ?? '1990-01-01', 'gender' => $input['gender'] ?? 'MALE', 'isDriver' => true, 'isInsuredPerson' => true, ]; } protected function defaultCoverages(array $overrides): array { $base = [ 'isIMT23' => false, 'personalAccident' => [ 'selection' => !empty($overrides['personal_accident'] ?? true), 'insuredAmount' => 1500000, 'coverTerm' => 1, ], 'addons' => [ 'personalBelonging' => ['selection' => !empty($overrides['personal_belonging'])], 'returnToInvoice' => ['selection' => !empty($overrides['return_to_invoice'])], 'rimProtection' => ['selection' => !empty($overrides['rim_protection'])], 'consumables' => ['selection' => !empty($overrides['consumables'])], 'partsDepreciation' => [ 'selection' => !empty($overrides['zero_dep'] ?? $overrides['parts_depreciation']), 'claimsCovered' => $overrides['claims_covered'] ?? 'TWO', ], 'engineProtection' => ['selection' => !empty($overrides['engine_protect'])], 'tyreProtection' => ['selection' => !empty($overrides['tyre_protect'])], 'roadSideAssistance' => ['selection' => !empty($overrides['rsa'] ?? $overrides['roadside_assistance'])], 'keyAndLockProtect' => ['selection' => !empty($overrides['key_protect'])], ], 'accessories' => [ 'electrical' => ['selection' => false, 'insuredAmount' => 0], 'nonElectrical' => ['selection' => false, 'insuredAmount' => 0], 'cng' => ['selection' => false, 'insuredAmount' => 0], ], 'voluntaryDeductible' => $overrides['voluntary_deductible'] ?? 'ZERO', 'isGeoExt' => null, 'legalLiability' => [ 'nonFarePaxLL' => ['selection' => false, 'insuredCount' => 1], 'unnamedPaxLL' => ['selection' => false, 'insuredCount' => 0], 'workersCompensationLL' => ['selection' => false, 'insuredCount' => 1], 'paidDriverLL' => ['selection' => true, 'insuredCount' => 1], 'employeesLL' => ['selection' => false, 'insuredCount' => 1], 'cleanersLL' => ['selection' => false, 'insuredCount' => 1], ], 'thirdPartyLiability' => [ 'isTPPD' => array_key_exists('tppd', $overrides) ? (bool) $overrides['tppd'] : true, ], 'unnamedPA' => [ 'unnamedPaidDriver' => ['selection' => false, 'insuredAmount' => 100000, 'insuredCount' => 1], 'unnamedPax' => ['selection' => false, 'insuredAmount' => 0, 'insuredCount' => 4], 'unnamedConductor' => ['selection' => false, 'insuredAmount' => 100000, 'insuredCount' => 1], 'unnamedHirer' => ['selection' => false, 'insuredAmount' => 100000, 'insuredCount' => 1], 'unnamedPillionRider'=> ['selection' => false, 'insuredAmount' => 100000, 'insuredCount' => 1], 'unnamedCleaner' => ['selection' => false, 'insuredAmount' => 100000, 'insuredCount' => 1], ], 'isOverturningExclusionIMT47' => false, 'isTheftAndConversionRiskIMT43' => false, 'ownDamage' => [ 'discount' => [ 'userSpecialDiscountPercent' => 0, 'discounts' => [], ], 'surcharge' => [ 'loadings' => [], ], ], ]; // If caller passed a Digit-shaped coverages object already, prefer it if (isset($overrides['addons']) || isset($overrides['thirdPartyLiability'])) { return array_replace_recursive($base, $overrides); } return $base; } protected function pickNumber(array $response, array $keys): ?float { foreach ($keys as $key) { if (isset($response[$key]) && is_numeric($response[$key])) { return (float) $response[$key]; } } if (isset($response['premiumBreakUp']) && is_array($response['premiumBreakUp'])) { foreach (['grossPremium', 'totalPremium', 'netPremium'] as $k) { if (isset($response['premiumBreakUp'][$k]) && is_numeric($response['premiumBreakUp'][$k])) { return (float) $response['premiumBreakUp'][$k]; } } } return null; } }