forked from Yara724/api
Centralized car body inquiry
This commit is contained in:
@@ -1118,13 +1118,44 @@ export class RequestManagementService {
|
|||||||
party.insurance.startDate = inquiryMapped?.IssueDate;
|
party.insurance.startDate = inquiryMapped?.IssueDate;
|
||||||
party.insurance.endDate = inquiryMapped?.EndDate;
|
party.insurance.endDate = inquiryMapped?.EndDate;
|
||||||
|
|
||||||
// CAR_BODY: persist mocked car-body insurance in party's insurance (same place as usual inquiry)
|
// CAR BODY EXTERNAL API INQUIRY
|
||||||
if (req.type === BlameRequestType.CAR_BODY && role === PartyRole.FIRST) {
|
if (req.type === BlameRequestType.CAR_BODY && role === PartyRole.FIRST) {
|
||||||
const carBodyInfo = await this.sandHubService.getTejaratCarBodyInquiry({
|
const carBodyInfo = await this.sandHubService.getTejaratCarBodyInquiry({
|
||||||
nationalCodeOfInsurer: body.nationalCodeOfInsurer,
|
nationalCodeOfInsurer: body.nationalCodeOfInsurer,
|
||||||
plate: body.plate,
|
plate: body.plate,
|
||||||
});
|
});
|
||||||
(party.insurance as any).carBodyInsurance = carBodyInfo;
|
|
||||||
|
// Raw + mapped stored under vehicle (same pattern as third-party inquiry)
|
||||||
|
party.vehicle.inquiry = {
|
||||||
|
...party.vehicle.inquiry, // preserve existing third-party inquiry if present
|
||||||
|
carBody: {
|
||||||
|
source: "TEJARAT_CAR_BODY_INQUIRY",
|
||||||
|
raw: carBodyInfo.raw,
|
||||||
|
mapped: carBodyInfo.mapped,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Flat key fields extracted alongside third-party insurance fields
|
||||||
|
const m = carBodyInfo.mapped;
|
||||||
|
(party.insurance as any).carBodyInsurance = {
|
||||||
|
policyNumber: m.policyNumber ?? null,
|
||||||
|
companyId: m.companyId ?? null,
|
||||||
|
companyName: m.CompanyName ?? null,
|
||||||
|
insurerName: m.insurerName ?? null,
|
||||||
|
insurerNationalCode: m.insurerNationalCode ?? null,
|
||||||
|
ownerNationalCode: m.ownerNationalCode ?? null,
|
||||||
|
chassisNumber: m.ChassisNumberField ?? null,
|
||||||
|
vin: m.VinNumberField ?? null,
|
||||||
|
motorNumber: m.EngineNumberField ?? null,
|
||||||
|
vehicleGroup: m.vehicleGroupTitle ?? null,
|
||||||
|
vehicleSystem: m.vehicleSystemTitle ?? null,
|
||||||
|
startDate: m.StartDate ?? null,
|
||||||
|
endDate: m.EndDate ?? null,
|
||||||
|
issueDate: m.IssueDate ?? null,
|
||||||
|
noLossYearsCount: m.noLossYearsCount ?? null,
|
||||||
|
lossDocuments: m.lossDocuments ?? [],
|
||||||
|
hasEndorsement: m.hasEndorsement ?? null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance workflow
|
// Advance workflow
|
||||||
|
|||||||
@@ -355,17 +355,13 @@ export class SandHubService {
|
|||||||
return await this.sandHubDbService.findOneBySandHubId(sandHubId);
|
return await this.sandHubDbService.findOneBySandHubId(sandHubId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tejarat block inquiry for Car Body Insurance (Badane).
|
|
||||||
* Returns both raw API response and mapped old-format response structure.
|
|
||||||
*/
|
|
||||||
async getTejaratCarBodyInquiry(userDetail: SandHubDetailDto): Promise<{
|
async getTejaratCarBodyInquiry(userDetail: SandHubDetailDto): Promise<{
|
||||||
raw: any;
|
raw: any;
|
||||||
|
mapped: Record<string, unknown>;
|
||||||
}> {
|
}> {
|
||||||
const baseUrl =
|
const baseUrl =
|
||||||
process.env.TEJARAT_INQUIRY_BASE_URL ?? "http://82.99.202.245:3027";
|
process.env.TEJARAT_INQUIRY_BASE_URL ?? "http://82.99.202.245:3027";
|
||||||
|
|
||||||
// 1. Build payload following the strict data requirements of the external API
|
|
||||||
const requestPayload = {
|
const requestPayload = {
|
||||||
part1: Number(userDetail.plate.leftDigits),
|
part1: Number(userDetail.plate.leftDigits),
|
||||||
part2: String(userDetail.plate.centerAlphabet),
|
part2: String(userDetail.plate.centerAlphabet),
|
||||||
@@ -380,11 +376,8 @@ export class SandHubService {
|
|||||||
let raw: any;
|
let raw: any;
|
||||||
|
|
||||||
if (live) {
|
if (live) {
|
||||||
// 2. Safely obtain a fresh or cached access token using your helper
|
|
||||||
const token = await this.getTejaratAccessToken();
|
const token = await this.getTejaratAccessToken();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 3. Make the live call using NestJS HttpService + firstValueFrom pattern
|
|
||||||
const response = await firstValueFrom(
|
const response = await firstValueFrom(
|
||||||
this.httpService.post(requestUrl, requestPayload, {
|
this.httpService.post(requestUrl, requestPayload, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -403,8 +396,103 @@ export class SandHubService {
|
|||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Mock — reuse the default mock and adapt it to the car-body shape
|
||||||
|
this.logger.debug(
|
||||||
|
`[MOCK] getTejaratCarBodyInquiry plate=${JSON.stringify(requestPayload)}`,
|
||||||
|
);
|
||||||
|
raw = {
|
||||||
|
data: {
|
||||||
|
printNumber: "MOCK-BADANE-001",
|
||||||
|
companyId: 34,
|
||||||
|
companyName: "بیمه تجارت نو",
|
||||||
|
beginDate: "1404/06/15",
|
||||||
|
endDate: "1405/06/15",
|
||||||
|
issueDate: "1404/06/13",
|
||||||
|
hasEndorsement: null,
|
||||||
|
motorNumber: "MOCK-ENGINE",
|
||||||
|
chassisNumber: "MOCK-CHASSIS",
|
||||||
|
vin: "MOCK-VIN",
|
||||||
|
vehicleSystemTitle: "سایپا",
|
||||||
|
vehicleGroupTitle: "سواری چهار سیلندر",
|
||||||
|
insurerNationalCode: userDetail.nationalCodeOfInsurer,
|
||||||
|
insurerName: "نام آزمایشی",
|
||||||
|
ownerNationalCode: userDetail.nationalCodeOfInsurer,
|
||||||
|
noLossYearsCount: 0,
|
||||||
|
lossDocuments: [],
|
||||||
|
},
|
||||||
|
isSuccess: true,
|
||||||
|
statusCode: 200,
|
||||||
|
message: "mock-ok",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return { raw };
|
|
||||||
|
const mapped = this.mapCarBodyInquiryResponse(raw);
|
||||||
|
return { raw, mapped };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps the Tejarat car-body (badane) API response to a consistent
|
||||||
|
* shape that mirrors the third-party inquiry mapped format.
|
||||||
|
* Callers should always use `mapped` for display; `raw` is kept for audit.
|
||||||
|
*/
|
||||||
|
private mapCarBodyInquiryResponse(raw: any): Record<string, unknown> {
|
||||||
|
if (!raw) return {};
|
||||||
|
|
||||||
|
const data = raw?.data ?? raw; // some responses nest under `data`
|
||||||
|
|
||||||
|
return {
|
||||||
|
// Identity
|
||||||
|
policyNumber: data.printNumber ?? data.insuranceNumber ?? null,
|
||||||
|
companyId: data.companyId ?? null,
|
||||||
|
CompanyCode: data.companyId ?? null,
|
||||||
|
CompanyName: data.companyName ?? data.companyPersianName ?? null,
|
||||||
|
|
||||||
|
// Insurer
|
||||||
|
insurerNationalCode:
|
||||||
|
data.insurerNationalCode ?? data.ownerNationalCode ?? null,
|
||||||
|
insurerName: data.insurerName ?? null,
|
||||||
|
ownerNationalCode: data.ownerNationalCode ?? null,
|
||||||
|
InsuranceFullName: data.insurerName ?? data.ownerName ?? null,
|
||||||
|
|
||||||
|
// Vehicle
|
||||||
|
motorNumber: data.motorNumber ?? data.EngineNumberField ?? null,
|
||||||
|
EngineNumberField: data.motorNumber ?? data.EngineNumberField ?? null,
|
||||||
|
chassisNumber: data.chassisNumber ?? data.ChassisNumberField ?? null,
|
||||||
|
ChassisNumberField: data.chassisNumber ?? data.ChassisNumberField ?? null,
|
||||||
|
vin: data.vin ?? data.VinNumberField ?? null,
|
||||||
|
VinNumberField: data.vin ?? data.VinNumberField ?? null,
|
||||||
|
vehicleGroupTitle: data.vehicleGroupTitle ?? null,
|
||||||
|
vehicleSystemTitle: data.vehicleSystemTitle ?? null,
|
||||||
|
MapTypNam: data.vehicleGroupTitle ?? data.vehicleSystemTitle ?? null,
|
||||||
|
|
||||||
|
// Policy dates (Jalali strings from the API)
|
||||||
|
IssueDate: data.issueDate ?? data.persianStartDate ?? null,
|
||||||
|
StartDate: data.beginDate ?? data.persianStartDate ?? null,
|
||||||
|
EndDate: data.endDate ?? data.persianEndDate ?? null,
|
||||||
|
|
||||||
|
// Plate
|
||||||
|
plateTypeTitle: data.plateTypeTitle ?? null,
|
||||||
|
platePartOne: data.platePartOne ?? null,
|
||||||
|
platePartThree: data.platePartThree ?? null,
|
||||||
|
plateSerialNumber: data.plateSerialNumber ?? null,
|
||||||
|
plateLetterTitle: data.plateLetterTitle ?? null,
|
||||||
|
|
||||||
|
// Loss / no-claim history
|
||||||
|
noLossYearsCount: data.noLossYearsCount ?? null,
|
||||||
|
lossDocuments: Array.isArray(data.lossDocuments)
|
||||||
|
? data.lossDocuments
|
||||||
|
: [],
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
hasEndorsement: data.hasEndorsement ?? null,
|
||||||
|
previousId: data.previousId ?? null,
|
||||||
|
|
||||||
|
// Status passthrough
|
||||||
|
isSuccess: raw?.isSuccess ?? true,
|
||||||
|
statusCode: raw?.statusCode ?? 200,
|
||||||
|
message: raw?.message ?? null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async makeSandHubRequest(url: string, payload: any, maxRetries = 3) {
|
private async makeSandHubRequest(url: string, payload: any, maxRetries = 3) {
|
||||||
|
|||||||
Reference in New Issue
Block a user