forked from Yara724/api
fanavaran car body and third_party lookup codings applied
This commit is contained in:
@@ -291,9 +291,10 @@ export class FanavaranLookupService {
|
|||||||
async customerById(
|
async customerById(
|
||||||
clientKey: FanavaranClientKey,
|
clientKey: FanavaranClientKey,
|
||||||
customerId: number,
|
customerId: number,
|
||||||
|
options?: { contractIdOverride?: string },
|
||||||
): Promise<unknown> {
|
): Promise<unknown> {
|
||||||
const url = `${FANAVARAN_LOOKUP_BASE_URL}/common/customers/${customerId}`;
|
const url = `${FANAVARAN_LOOKUP_BASE_URL}/common/customers/${customerId}`;
|
||||||
return this.fetchFromFanavaran(clientKey, url);
|
return this.fetchFromFanavaran(clientKey, url, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async inquiryByUniqueIdentifier(
|
async inquiryByUniqueIdentifier(
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import {
|
import {
|
||||||
filterPoliciesByLine,
|
filterPoliciesByLine,
|
||||||
|
insuranceLineLabel,
|
||||||
parseLastCarPolicyInput,
|
parseLastCarPolicyInput,
|
||||||
pickVehicleId,
|
pickVehicleId,
|
||||||
|
plaqueLetterFromMiddleCode,
|
||||||
plaqueMatchesVehicle,
|
plaqueMatchesVehicle,
|
||||||
selectLastAmongCarMatches,
|
selectLastAmongCarMatches,
|
||||||
|
toAppPlaque,
|
||||||
vehicleMatchesCar,
|
vehicleMatchesCar,
|
||||||
} from "./fanavaran-last-car-policy";
|
} from "./fanavaran-last-car-policy";
|
||||||
|
|
||||||
@@ -40,6 +43,28 @@ describe("fanavaran last car policy", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("maps insurance line ids to CAR_BODY and THIRD_PARTY", () => {
|
||||||
|
expect(insuranceLineLabel(4)).toBe("CAR_BODY");
|
||||||
|
expect(insuranceLineLabel(5)).toBe("THIRD_PARTY");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("converts PlaqueMiddleCodeId 5 to د and builds app plaque parts", () => {
|
||||||
|
expect(plaqueLetterFromMiddleCode(5)).toBe("د");
|
||||||
|
expect(
|
||||||
|
toAppPlaque({
|
||||||
|
PlaqueLeftNo: "29",
|
||||||
|
PlaqueMiddleCodeId: 5,
|
||||||
|
PlaqueRightNo: "782",
|
||||||
|
PlaqueSerial: "60",
|
||||||
|
}),
|
||||||
|
).toEqual({
|
||||||
|
leftTwoDigits: "29",
|
||||||
|
serialLetter: "د",
|
||||||
|
threeDigits: "782",
|
||||||
|
rightTwoDigits: "60",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("keeps only the requested insurance line", () => {
|
it("keeps only the requested insurance line", () => {
|
||||||
const rows = filterPoliciesByLine(
|
const rows = filterPoliciesByLine(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -94,6 +94,52 @@ export function insuranceLineIdForProduct(
|
|||||||
: FANAVARAN_THIRD_PARTY_LINE_ID;
|
: FANAVARAN_THIRD_PARTY_LINE_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function insuranceLineLabel(
|
||||||
|
insuranceLineId: number,
|
||||||
|
): "CAR_BODY" | "THIRD_PARTY" | null {
|
||||||
|
if (insuranceLineId === FANAVARAN_CAR_BODY_LINE_ID) return "CAR_BODY";
|
||||||
|
if (insuranceLineId === FANAVARAN_THIRD_PARTY_LINE_ID) return "THIRD_PARTY";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function plaqueLetterFromMiddleCode(code: unknown): string | null {
|
||||||
|
const id = parseFanavaranId(code);
|
||||||
|
if (id === null) return null;
|
||||||
|
const found = Object.entries(FANAVARAN_PLATE_LETTER_CODE).find(
|
||||||
|
([, value]) => value === id,
|
||||||
|
);
|
||||||
|
return found?.[0] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AppPlaque = {
|
||||||
|
leftTwoDigits: string;
|
||||||
|
serialLetter: string;
|
||||||
|
threeDigits: string;
|
||||||
|
rightTwoDigits: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function toAppPlaque(
|
||||||
|
vehicle: Record<string, unknown> | null,
|
||||||
|
): AppPlaque | null {
|
||||||
|
if (!vehicle) return null;
|
||||||
|
const leftTwoDigits = normalizePlaquePart(
|
||||||
|
vehicle.PlaqueLeftNo ?? vehicle.plaqueLeftNo,
|
||||||
|
);
|
||||||
|
const threeDigits = normalizePlaquePart(
|
||||||
|
vehicle.PlaqueRightNo ?? vehicle.plaqueRightNo,
|
||||||
|
);
|
||||||
|
const rightTwoDigits = normalizePlaquePart(
|
||||||
|
vehicle.PlaqueSerial ?? vehicle.plaqueSerial,
|
||||||
|
);
|
||||||
|
const serialLetter = plaqueLetterFromMiddleCode(
|
||||||
|
vehicle.PlaqueMiddleCodeId ?? vehicle.plaqueMiddleCodeId,
|
||||||
|
);
|
||||||
|
if (!leftTwoDigits || !serialLetter || !threeDigits || !rightTwoDigits) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return { leftTwoDigits, serialLetter, threeDigits, rightTwoDigits };
|
||||||
|
}
|
||||||
|
|
||||||
export function toEnglishDigits(value: unknown): string {
|
export function toEnglishDigits(value: unknown): string {
|
||||||
return String(value ?? "")
|
return String(value ?? "")
|
||||||
.split("")
|
.split("")
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ describe("LookupsService.findLastProcessedCarPolicy", () => {
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
getRemoteLookup: jest.fn().mockResolvedValue([]),
|
getRemoteLookup: jest.fn().mockResolvedValue([]),
|
||||||
|
customerById: jest.fn().mockResolvedValue(null),
|
||||||
};
|
};
|
||||||
|
|
||||||
const service = createService(lookup);
|
const service = createService(lookup);
|
||||||
@@ -68,10 +69,15 @@ describe("LookupsService.findLastProcessedCarPolicy", () => {
|
|||||||
|
|
||||||
expect(result.policyId).toBe(20);
|
expect(result.policyId).toBe(20);
|
||||||
expect(result.product).toBe("third-party");
|
expect(result.product).toBe("third-party");
|
||||||
|
expect(result.insuranceLine).toBe("THIRD_PARTY");
|
||||||
expect(result.insuranceLineId).toBe(5);
|
expect(result.insuranceLineId).toBe(5);
|
||||||
expect(result.vehicle).toEqual({
|
expect(result.vehicle).toEqual({
|
||||||
Id: 500,
|
Id: 500,
|
||||||
VIN: "IRNKAEK4150012345",
|
VIN: "IRNKAEK4150012345",
|
||||||
|
color: null,
|
||||||
|
vehicleKind: null,
|
||||||
|
used: null,
|
||||||
|
plaque: null,
|
||||||
});
|
});
|
||||||
expect(lookup.thirdPartyPolicyById).toHaveBeenCalled();
|
expect(lookup.thirdPartyPolicyById).toHaveBeenCalled();
|
||||||
expect(lookup.myPolicies.mock.calls[0][2]).toBe(5);
|
expect(lookup.myPolicies.mock.calls[0][2]).toBe(5);
|
||||||
@@ -103,6 +109,7 @@ describe("LookupsService.findLastProcessedCarPolicy", () => {
|
|||||||
PlaqueSerial: "67",
|
PlaqueSerial: "67",
|
||||||
}),
|
}),
|
||||||
getRemoteLookup: jest.fn().mockResolvedValue([]),
|
getRemoteLookup: jest.fn().mockResolvedValue([]),
|
||||||
|
customerById: jest.fn().mockResolvedValue(null),
|
||||||
};
|
};
|
||||||
|
|
||||||
const service = createService(lookup);
|
const service = createService(lookup);
|
||||||
@@ -116,6 +123,13 @@ describe("LookupsService.findLastProcessedCarPolicy", () => {
|
|||||||
|
|
||||||
expect(result.policyId).toBe(44);
|
expect(result.policyId).toBe(44);
|
||||||
expect(result.product).toBe("car-body");
|
expect(result.product).toBe("car-body");
|
||||||
|
expect(result.insuranceLine).toBe("CAR_BODY");
|
||||||
|
expect(result.vehicle?.plaque).toEqual({
|
||||||
|
leftTwoDigits: "12",
|
||||||
|
serialLetter: "ب",
|
||||||
|
threeDigits: "345",
|
||||||
|
rightTwoDigits: "67",
|
||||||
|
});
|
||||||
expect(lookup.bodyPolicyById).toHaveBeenCalled();
|
expect(lookup.bodyPolicyById).toHaveBeenCalled();
|
||||||
expect(lookup.thirdPartyPolicyById).not.toHaveBeenCalled();
|
expect(lookup.thirdPartyPolicyById).not.toHaveBeenCalled();
|
||||||
expect(lookup.inquiryByVin).not.toHaveBeenCalled();
|
expect(lookup.inquiryByVin).not.toHaveBeenCalled();
|
||||||
@@ -147,6 +161,7 @@ describe("LookupsService.findLastProcessedCarPolicy", () => {
|
|||||||
ChassisNo: "RDE07024",
|
ChassisNo: "RDE07024",
|
||||||
}),
|
}),
|
||||||
getRemoteLookup: jest.fn().mockResolvedValue([]),
|
getRemoteLookup: jest.fn().mockResolvedValue([]),
|
||||||
|
customerById: jest.fn().mockResolvedValue(null),
|
||||||
};
|
};
|
||||||
|
|
||||||
const service = createService(lookup);
|
const service = createService(lookup);
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ import {
|
|||||||
asObjectRecord,
|
asObjectRecord,
|
||||||
filterPoliciesByLine,
|
filterPoliciesByLine,
|
||||||
insuranceLineIdForProduct,
|
insuranceLineIdForProduct,
|
||||||
|
insuranceLineLabel,
|
||||||
parseFanavaranId,
|
parseFanavaranId,
|
||||||
parseLastCarPolicyInput,
|
parseLastCarPolicyInput,
|
||||||
pickVehicleId,
|
pickVehicleId,
|
||||||
selectLastAmongCarMatches,
|
selectLastAmongCarMatches,
|
||||||
sortPoliciesNewestEndDateFirst,
|
sortPoliciesNewestEndDateFirst,
|
||||||
|
toAppPlaque,
|
||||||
vehicleMatchesCar,
|
vehicleMatchesCar,
|
||||||
type FanavaranCarPolicyProduct,
|
type FanavaranCarPolicyProduct,
|
||||||
type HydratedFanavaranCarPolicy,
|
type HydratedFanavaranCarPolicy,
|
||||||
@@ -203,9 +205,11 @@ export class LookupsService {
|
|||||||
},
|
},
|
||||||
): Promise<{
|
): Promise<{
|
||||||
product: FanavaranCarPolicyProduct;
|
product: FanavaranCarPolicyProduct;
|
||||||
|
insuranceLine: "CAR_BODY" | "THIRD_PARTY" | null;
|
||||||
insuranceLineId: number;
|
insuranceLineId: number;
|
||||||
policyId: number;
|
policyId: number;
|
||||||
policy: any;
|
policy: any;
|
||||||
|
customer: Record<string, unknown> | null;
|
||||||
vehicle: Record<string, unknown> | null;
|
vehicle: Record<string, unknown> | null;
|
||||||
}> {
|
}> {
|
||||||
const parsed = parseLastCarPolicyInput(query);
|
const parsed = parseLastCarPolicyInput(query);
|
||||||
@@ -355,10 +359,77 @@ export class LookupsService {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
product,
|
product,
|
||||||
|
insuranceLine: insuranceLineLabel(insuranceLineId),
|
||||||
insuranceLineId,
|
insuranceLineId,
|
||||||
policyId: selected.policyId,
|
policyId: selected.policyId,
|
||||||
policy: await this.mapPolicyDetails(selected.policy),
|
policy: await this.mapPolicyDetails(selected.policy),
|
||||||
vehicle: selected.vehicle,
|
customer: await this.fetchCustomer(
|
||||||
|
clientKey,
|
||||||
|
parseFanavaranId(selected.policy.CustomerId),
|
||||||
|
requestOptions,
|
||||||
|
),
|
||||||
|
vehicle: await this.enrichVehicle(selected.vehicle),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async fetchCustomer(
|
||||||
|
clientKey: ReturnType<LookupsService["activeClientKey"]>,
|
||||||
|
customerId: number | null,
|
||||||
|
requestOptions: { contractIdOverride?: string },
|
||||||
|
): Promise<Record<string, unknown> | null> {
|
||||||
|
if (customerId === null) return null;
|
||||||
|
try {
|
||||||
|
return asObjectRecord(
|
||||||
|
await this.fanavaranLookupService.customerById(
|
||||||
|
clientKey,
|
||||||
|
customerId,
|
||||||
|
requestOptions,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.warn(
|
||||||
|
`Customer GET failed for CustomerId=${customerId}: ${
|
||||||
|
error instanceof Error ? error.message : error
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async lookupRowById(
|
||||||
|
lookupName: string,
|
||||||
|
id: number | null,
|
||||||
|
): Promise<Record<string, unknown> | null> {
|
||||||
|
if (id === null) return null;
|
||||||
|
try {
|
||||||
|
const rows = await this.getClientRemoteLookup(lookupName);
|
||||||
|
if (!Array.isArray(rows)) return null;
|
||||||
|
const match = rows.find(
|
||||||
|
(row) => parseFanavaranId((row as { Id?: unknown })?.Id) === id,
|
||||||
|
);
|
||||||
|
return asObjectRecord(match);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.warn(
|
||||||
|
`Failed to resolve ${lookupName} id=${id}: ${
|
||||||
|
error instanceof Error ? error.message : error
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async enrichVehicle(
|
||||||
|
vehicle: Record<string, unknown> | null,
|
||||||
|
): Promise<Record<string, unknown> | null> {
|
||||||
|
if (!vehicle) return null;
|
||||||
|
const vehicleKindId = parseFanavaranId(vehicle.VehicleKindId);
|
||||||
|
const usedId = parseFanavaranId(vehicle.UsedId);
|
||||||
|
return {
|
||||||
|
...vehicle,
|
||||||
|
color: null,
|
||||||
|
vehicleKind: await this.lookupRowById("vehicle-kinds", vehicleKindId),
|
||||||
|
used: await this.lookupRowById("vehicle-use-types", usedId),
|
||||||
|
plaque: toAppPlaque(vehicle),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user