diff --git a/src/claim-request-management/claim-request-management.service.ts b/src/claim-request-management/claim-request-management.service.ts index 9308b1e..3da9d1c 100644 --- a/src/claim-request-management/claim-request-management.service.ts +++ b/src/claim-request-management/claim-request-management.service.ts @@ -3643,6 +3643,88 @@ export class ClaimRequestManagementService { } } + private parseJalaliBirthday( + birthday: string | null | undefined, + ): { year: number; month: number; day: number } | null { + if (!birthday) return null; + const parts = String(birthday).split(/[/\-]/); + if (parts.length < 3) return null; + const year = parseInt(parts[0], 10); + const month = parseInt(parts[1], 10); + const day = parseInt(parts[2], 10); + if (isNaN(year) || isNaN(month) || isNaN(day)) return null; + return { year, month, day }; + } + + private async resolveDriverFanavaranId( + clientKey: FanavaranClientKey, + nationalCode: string | null | undefined, + driverBirthday: string | null | undefined, + driverIsInsurer: boolean | undefined, + ): Promise { + if (!nationalCode) { + this.logger.warn( + `resolveDriverFanavaranId: no nationalCode provided, skipping party inquiry`, + ); + return null; + } + + const parsed = this.parseJalaliBirthday(driverBirthday); + if (!parsed) { + this.logger.warn( + `resolveDriverFanavaranId: could not parse driverBirthday "${driverBirthday}" for nationalCode=${nationalCode}`, + ); + return null; + } + + const targetRoleId = driverIsInsurer ? 161 : 166; + + try { + const response = (await this.fanavaranLookupService.inquiryByUniqueIdentifier( + clientKey, + { + nationalCode, + birthYear: parsed.year, + birthMonth: parsed.month, + birthDay: parsed.day, + }, + )) as Array<{ + Id: number; + RoleId: number; + NationalCode: string; + Name?: string; + LastName?: string; + }>; + + if (!Array.isArray(response) || response.length === 0) { + this.logger.warn( + `resolveDriverFanavaranId: empty response for nationalCode=${nationalCode}`, + ); + return null; + } + + const match = response.find((entry) => entry.RoleId === targetRoleId); + if (match) { + this.logger.log( + `resolveDriverFanavaranId: foundRoleId=${targetRoleId} Id=${match.Id} for nationalCode=${nationalCode} (${match.Name} ${match.LastName})`, + ); + return match.Id; + } + + this.logger.warn( + `resolveDriverFanavaranId: no person with RoleId=${targetRoleId} (driverIsInsurer=${driverIsInsurer}) for nationalCode=${nationalCode}. ` + + `Available RoleIds: ${response.map((e) => e.RoleId).join(", ")}. ` + + `Person is not defined in Fanavaran system for this role.`, + ); + return null; + } catch (error) { + this.logger.error( + `resolveDriverFanavaranId: failed to call inquiry-by-unique-identifier for nationalCode=${nationalCode}: ${error instanceof Error ? error.message : error}`, + ); + return null; + } + } + private async buildFanavaranDamageCasePayload(input: { claimCase: any; blameCase?: any; @@ -3695,6 +3777,13 @@ export class ClaimRequestManagementService { carType, ); + const driverFanavaranId = await this.resolveDriverFanavaranId( + input.clientKey, + person.nationalCodeOfDriver, + person.driverBirthday, + person.driverIsInsurer, + ); + return { BeginDate: insurance.startDate ?? null, BuiltYear: @@ -3708,7 +3797,7 @@ export class ClaimRequestManagementService { DmgHistoryStatus: input.defaults.DmgHistoryStatus, Desc: this.formatFanavaranSelectedPartsDesc(input.selectedParts), DmgCaseTypeId: input.defaults.DmgCaseTypeId, - DriverId: person.nationalCodeOfDriver ?? null, + DriverId: driverFanavaranId ?? person.nationalCodeOfDriver ?? null, EndDate: insurance.endDate ?? null, EstimateAmount: FANAVARAN_PROVISIONAL_ESTIMATE_AMOUNT, FaultPercent: input.defaults.FaultPercent, diff --git a/src/fanavaran/fanavaran-lookup.config.ts b/src/fanavaran/fanavaran-lookup.config.ts index 921b00f..785abe5 100644 --- a/src/fanavaran/fanavaran-lookup.config.ts +++ b/src/fanavaran/fanavaran-lookup.config.ts @@ -71,6 +71,11 @@ export const FANAVARAN_REMOTE_LOOKUPS: FanavaranRemoteLookupDefinition[] = [ url: `${FANAVARAN_LOOKUP_BASE_URL}/car/base-info/vehicle-kinds`, cacheFile: "vehicle-kinds.json", }, + { + name: "person-role", + url: `${FANAVARAN_LOOKUP_BASE_URL}/common/code-list/person-role`, + cacheFile: "person-role.json", + }, ]; export const TEJARAT_STATIC_ACCIDENT_FILES = { diff --git a/src/fanavaran/fanavaran-lookup.service.ts b/src/fanavaran/fanavaran-lookup.service.ts index b7e4ecd..9df8365 100644 --- a/src/fanavaran/fanavaran-lookup.service.ts +++ b/src/fanavaran/fanavaran-lookup.service.ts @@ -255,6 +255,24 @@ export class FanavaranLookupService { return this.fetchFromFanavaran(clientKey, url); } + async inquiryByUniqueIdentifier( + clientKey: FanavaranClientKey, + params: { + nationalCode: string; + birthYear: number; + birthMonth: number; + birthDay: number; + }, + ): Promise { + const url = + `${FANAVARAN_LOOKUP_BASE_URL}/common/parties/inquiry-by-unique-identifier` + + `?NationalCode=${encodeURIComponent(params.nationalCode)}` + + `&BirthYear=${params.birthYear}` + + `&BirthMonth=${params.birthMonth}` + + `&BirthDay=${params.birthDay}`; + return this.fetchFromFanavaran(clientKey, url); + } + mapFanavaranAccidentCausesToReasonOptions( causes: unknown, ): { id: number; label: string; fanavaran: number }[] { diff --git a/src/lookups/lookups.controller.ts b/src/lookups/lookups.controller.ts index ea77575..88f1265 100644 --- a/src/lookups/lookups.controller.ts +++ b/src/lookups/lookups.controller.ts @@ -186,6 +186,30 @@ export class LookupsController { return await this.lookupsService.getVehicleKinds(); } + @Get("person-role") + @ApiOperation({ + summary: "Fanavaran person role lookup", + description: + "Returns person role codes from common/code-list/person-role.", + }) + @ApiOkResponse({ + description: "Returns Fanavaran person role lookup data", + schema: { + type: "array", + items: { + type: "object", + properties: { + Caption: { type: "string" }, + Id: { type: "number" }, + IsActive: { type: "number" }, + }, + }, + }, + }) + async getPersonRole() { + return await this.lookupsService.getPersonRole(); + } + @Get("inquiry-by-vin") @ApiOperation({ summary: "Fanavaran vehicle inquiry by VIN", diff --git a/src/lookups/lookups.service.ts b/src/lookups/lookups.service.ts index e8a69e5..346dd93 100644 --- a/src/lookups/lookups.service.ts +++ b/src/lookups/lookups.service.ts @@ -119,6 +119,10 @@ export class LookupsService { return await this.getClientRemoteLookup("vehicle-kinds"); } + async getPersonRole(): Promise { + return await this.getClientRemoteLookup("person-role"); + } + async inquiryByVin(vin: string): Promise { const clientKey = this.activeClientKey(); return this.fanavaranLookupService.inquiryByVin(clientKey, vin);