1
0
forked from Yara724/api

Merge pull request 'main' (#179) from s.hajizadeh/yara724api:main into main

Reviewed-on: Yara724/api#179
This commit is contained in:
2026-07-07 17:30:48 +03:30
5 changed files with 141 additions and 1 deletions

View File

@@ -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<number | null> {
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,

View File

@@ -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 = {

View File

@@ -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<unknown> {
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 }[] {

View File

@@ -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",

View File

@@ -119,6 +119,10 @@ export class LookupsService {
return await this.getClientRemoteLookup("vehicle-kinds");
}
async getPersonRole(): Promise<any> {
return await this.getClientRemoteLookup("person-role");
}
async inquiryByVin(vin: string): Promise<unknown> {
const clientKey = this.activeClientKey();
return this.fanavaranLookupService.inquiryByVin(clientKey, vin);