nhance/app/Libraries/DigitMotor/DigitExecutorService.php
2026-07-21 09:32:13 +05:30

744 lines
32 KiB
PHP

<?php
namespace App\Libraries\DigitMotor;
use App\Models\MotorKycModel;
use App\Models\MotorPaymentModel;
use App\Models\MotorPolicyModel;
use App\Models\MotorQuoteModel;
use App\Models\MotorVehicleModel;
use Config\DigitMotor as DigitMotorConfig;
/**
* Business actions against Digit OneAPI executor services.
*/
class DigitExecutorService
{
protected DigitMotorConfig $config;
protected DigitApiClient $api;
protected MotorQuoteModel $quoteModel;
protected MotorVehicleModel $vehicleModel;
protected MotorKycModel $kycModel;
protected MotorPaymentModel $paymentModel;
protected MotorPolicyModel $policyModel;
public function __construct(?DigitMotorConfig $config = null, ?DigitApiClient $api = null)
{
$this->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;
}
}