forked from Yara724/api
car body policy and sales extended
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
import { Injectable, Logger, NotFoundException } from "@nestjs/common";
|
||||
import { resolveFanavaranClientKey } from "src/core/config/fanavaran-client.config";
|
||||
import {
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
Logger,
|
||||
NotFoundException,
|
||||
} from "@nestjs/common";
|
||||
import {
|
||||
resolveFanavaranClientKey,
|
||||
resolveFanavaranProductContractId,
|
||||
} from "src/core/config/fanavaran-client.config";
|
||||
import {
|
||||
FANAVARAN_REMOTE_LOOKUPS,
|
||||
type FanavaranRemoteLookupDefinition,
|
||||
@@ -7,6 +15,19 @@ import {
|
||||
} from "src/fanavaran/fanavaran-lookup.config";
|
||||
import { FanavaranLookupService } from "src/fanavaran/fanavaran-lookup.service";
|
||||
import { LookupDbService } from "./entities/db-service/lookup.db.service";
|
||||
import {
|
||||
asObjectRecord,
|
||||
filterPoliciesByLine,
|
||||
insuranceLineIdForProduct,
|
||||
parseFanavaranId,
|
||||
parseLastCarPolicyInput,
|
||||
pickVehicleId,
|
||||
selectLastAmongCarMatches,
|
||||
sortPoliciesNewestEndDateFirst,
|
||||
vehicleMatchesCar,
|
||||
type FanavaranCarPolicyProduct,
|
||||
type HydratedFanavaranCarPolicy,
|
||||
} from "./fanavaran-last-car-policy";
|
||||
|
||||
type TejaratAccidentReasonRow = {
|
||||
id: number;
|
||||
@@ -170,6 +191,177 @@ export class LookupsService {
|
||||
);
|
||||
}
|
||||
|
||||
async findLastProcessedCarPolicy(
|
||||
product: FanavaranCarPolicyProduct,
|
||||
query: {
|
||||
nationalCode?: string;
|
||||
vin?: string;
|
||||
plaqueLeft?: string;
|
||||
plaqueLetter?: string;
|
||||
plaqueRight?: string;
|
||||
plaqueSerial?: string;
|
||||
},
|
||||
): Promise<{
|
||||
product: FanavaranCarPolicyProduct;
|
||||
insuranceLineId: number;
|
||||
policyId: number;
|
||||
policy: any;
|
||||
vehicle: Record<string, unknown> | null;
|
||||
}> {
|
||||
const parsed = parseLastCarPolicyInput(query);
|
||||
if ("error" in parsed) {
|
||||
throw new BadRequestException(parsed.error);
|
||||
}
|
||||
|
||||
const clientKey = this.activeClientKey();
|
||||
const insuranceLineId = insuranceLineIdForProduct(product);
|
||||
const contractIdOverride = resolveFanavaranProductContractId(
|
||||
clientKey,
|
||||
product,
|
||||
);
|
||||
const requestOptions = { contractIdOverride };
|
||||
|
||||
const listed = await this.fanavaranLookupService.myPolicies(
|
||||
clientKey,
|
||||
parsed.nationalCode,
|
||||
insuranceLineId,
|
||||
requestOptions,
|
||||
);
|
||||
const candidates = sortPoliciesNewestEndDateFirst(
|
||||
filterPoliciesByLine(listed, insuranceLineId),
|
||||
);
|
||||
|
||||
let vinVehicleId: number | null = null;
|
||||
if (parsed.vin) {
|
||||
try {
|
||||
const inquired = await this.fanavaranLookupService.inquiryByVin(
|
||||
clientKey,
|
||||
parsed.vin,
|
||||
requestOptions,
|
||||
);
|
||||
vinVehicleId = pickVehicleId(inquired);
|
||||
} catch (error) {
|
||||
this.logger.warn(
|
||||
`VIN vehicle helper failed; continuing with policy hydrate: ${
|
||||
error instanceof Error ? error.message : error
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const matches: HydratedFanavaranCarPolicy[] = [];
|
||||
let hydrationFailures = 0;
|
||||
|
||||
for (const row of candidates) {
|
||||
const policyId = parseFanavaranId(row.PolicyId);
|
||||
if (policyId === null) continue;
|
||||
|
||||
let policyRaw: unknown;
|
||||
try {
|
||||
policyRaw =
|
||||
product === "car-body"
|
||||
? await this.fanavaranLookupService.bodyPolicyById(
|
||||
clientKey,
|
||||
policyId,
|
||||
requestOptions,
|
||||
)
|
||||
: await this.fanavaranLookupService.thirdPartyPolicyById(
|
||||
clientKey,
|
||||
policyId,
|
||||
requestOptions,
|
||||
);
|
||||
} catch (error) {
|
||||
hydrationFailures += 1;
|
||||
this.logger.warn(
|
||||
`Policy GET failed for PolicyId=${policyId}: ${
|
||||
error instanceof Error ? error.message : error
|
||||
}`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
const policy = asObjectRecord(policyRaw);
|
||||
if (!policy) continue;
|
||||
|
||||
const vehicleId = pickVehicleId(policy.VehicleId ?? policy.vehicleId);
|
||||
if (
|
||||
parsed.vin &&
|
||||
vinVehicleId !== null &&
|
||||
vehicleId !== null &&
|
||||
vehicleId !== vinVehicleId
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let vehicle: Record<string, unknown> | null = null;
|
||||
if (vehicleId !== null) {
|
||||
try {
|
||||
vehicle = asObjectRecord(
|
||||
await this.fanavaranLookupService.vehicleById(
|
||||
clientKey,
|
||||
vehicleId,
|
||||
undefined,
|
||||
requestOptions,
|
||||
),
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.warn(
|
||||
`Vehicle GET failed for VehicleId=${vehicleId} (PolicyId=${policyId}): ${
|
||||
error instanceof Error ? error.message : error
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const matchedByVinVehicleId =
|
||||
parsed.vin != null &&
|
||||
vinVehicleId != null &&
|
||||
vehicleId != null &&
|
||||
vinVehicleId === vehicleId;
|
||||
|
||||
if (
|
||||
!matchedByVinVehicleId &&
|
||||
!vehicleMatchesCar(vehicle, parsed, vinVehicleId)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
matches.push({
|
||||
policyId,
|
||||
beginDate: policy.BeginDate ?? row.BeginDate,
|
||||
endDate: policy.EndDate ?? row.EndDate,
|
||||
vehicleId,
|
||||
policy,
|
||||
vehicle,
|
||||
});
|
||||
}
|
||||
|
||||
const selected = selectLastAmongCarMatches(matches);
|
||||
if (!selected) {
|
||||
if (candidates.length === 0) {
|
||||
throw new NotFoundException(
|
||||
`No Fanavaran ${product} policy was found for this national code and car.`,
|
||||
);
|
||||
}
|
||||
if (hydrationFailures === candidates.length) {
|
||||
throw new NotFoundException(
|
||||
`Fanavaran ${product} policy details could not be loaded for this national code.`,
|
||||
);
|
||||
}
|
||||
throw new NotFoundException(
|
||||
`No Fanavaran ${product} policy of that line was found for this car.`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
product,
|
||||
insuranceLineId,
|
||||
policyId: selected.policyId,
|
||||
policy: await this.mapPolicyDetails(selected.policy),
|
||||
vehicle: selected.vehicle,
|
||||
};
|
||||
}
|
||||
|
||||
async mapPolicyDetails(policy: any): Promise<any> {
|
||||
if (!policy || typeof policy !== "object") {
|
||||
return policy;
|
||||
@@ -222,13 +414,26 @@ export class LookupsService {
|
||||
|
||||
async bodyPolicyById(policyId: number): Promise<unknown> {
|
||||
const clientKey = this.activeClientKey();
|
||||
const policy = await this.fanavaranLookupService.bodyPolicyById(clientKey, policyId);
|
||||
const policy = await this.fanavaranLookupService.bodyPolicyById(
|
||||
clientKey,
|
||||
policyId,
|
||||
{
|
||||
contractIdOverride: resolveFanavaranProductContractId(
|
||||
clientKey,
|
||||
"car-body",
|
||||
),
|
||||
},
|
||||
);
|
||||
return this.mapPolicyDetails(policy);
|
||||
}
|
||||
|
||||
async vehicleById(vehicleId: number, versionNo: number = 1): Promise<unknown> {
|
||||
async vehicleById(vehicleId: number, versionNo?: number): Promise<unknown> {
|
||||
const clientKey = this.activeClientKey();
|
||||
return this.fanavaranLookupService.vehicleById(clientKey, vehicleId, versionNo);
|
||||
return this.fanavaranLookupService.vehicleById(
|
||||
clientKey,
|
||||
vehicleId,
|
||||
versionNo,
|
||||
);
|
||||
}
|
||||
|
||||
async customerById(customerId: number): Promise<unknown> {
|
||||
|
||||
Reference in New Issue
Block a user