This commit is contained in:
2026-07-01 18:05:09 +03:30
parent b43f1a86dc
commit d525b8dd0d
6 changed files with 148 additions and 13 deletions

View File

@@ -241,6 +241,15 @@ const FANAVARAN_ACCIDENT_LOCATION_ADDRESS = "استان تهران شهر تهر
const FANAVARAN_DEFAULT_ACCIDENT_CAUSE_ID = 6;
const FANAVARAN_PROVISIONAL_ESTIMATE_AMOUNT = 1000;
/** Local carType → Fanavaran vehicle-kind Caption keywords for matching. */
const VEHICLE_KIND_KEYWORDS: Record<ClaimVehicleTypeV2, string[]> = {
[ClaimVehicleTypeV2.SEDAN]: ["سواری", "سواري", "sedan"],
[ClaimVehicleTypeV2.SUV]: ["شاسی", "شاسي", "suv", "بلند"],
[ClaimVehicleTypeV2.HATCHBACK]: ["هاچبک", "هاچ بک", "hatchback"],
[ClaimVehicleTypeV2.PICKUP]: ["وانت", "پیکاپ", "pick", "pickup"],
[ClaimVehicleTypeV2.VAN]: ["ون", "van"],
};
const FANAVARAN_PLATE_LETTER_CODE: Record<string, number> = {
الف: 1,
ب: 2,
@@ -3593,10 +3602,52 @@ export class ClaimRequestManagementService {
return `${plate.centerDigits}${plate.centerAlphabet}${plate.leftDigits}`;
}
private buildFanavaranDamageCasePayload(input: {
private async resolveVehicleKindId(
clientKey: FanavaranClientKey,
carType?: string,
): Promise<number | null> {
if (!carType) return null;
const vehicleType = carType as ClaimVehicleTypeV2;
const keywords = VEHICLE_KIND_KEYWORDS[vehicleType];
if (!keywords) return null;
try {
const lookup = this.fanavaranLookupService;
const definition = FANAVARAN_REMOTE_LOOKUPS.find(
(l) => l.name === "vehicle-kinds",
);
if (!definition) return null;
const data = (await lookup.getRemoteLookup(
clientKey,
definition.url,
definition.cacheFile,
)) as Array<{ Id?: number; Caption?: string; IsActive?: number }>;
if (!Array.isArray(data)) return null;
const normalizedKeywords = keywords.map((k) => k.toLowerCase());
const match = data.find((item) => {
if (!item.Caption || item.IsActive === 0) return false;
const caption = item.Caption.toLowerCase();
return normalizedKeywords.some((kw) => caption.includes(kw));
});
return match?.Id ?? null;
} catch {
this.logger.warn(
`Failed to resolve VehicleKindId for carType=${carType}`,
);
return null;
}
}
private async buildFanavaranDamageCasePayload(input: {
claimCase: any;
blameCase?: any;
selectedParts: unknown[];
clientKey: FanavaranClientKey;
defaults: {
AccidentVehicleUsedId: number;
CulpritLicenceTypeId: number;
@@ -3607,7 +3658,7 @@ export class ClaimRequestManagementService {
DriverIsOwner: number;
FaultPercent: number;
};
}): Record<string, unknown> {
}): Promise<Record<string, unknown>> {
const plate = this.resolveOwnershipPlateForClaim(
input.claimCase,
input.blameCase,
@@ -3625,6 +3676,12 @@ export class ClaimRequestManagementService {
const inquiryMapped = vehicle?.inquiry?.mapped ?? {};
const inquiryRaw = vehicle?.inquiry?.raw ?? {};
const carType = input.claimCase?.vehicle?.carType as string | undefined;
const vehicleKindId = await this.resolveVehicleKindId(
input.clientKey,
carType,
);
return {
BeginDate: insurance.startDate ?? null,
BuiltYear:
@@ -3659,7 +3716,7 @@ export class ClaimRequestManagementService {
PlaqueSerial: plate ? String(plate.ir) : null,
PolicyNo: insurance.policyNumber ?? null,
PreviousPolicyEndDate: insurance.endDate ?? "",
VehicleKindId: null,
VehicleKindId: vehicleKindId,
VIN: inquiryMapped.VIN ?? inquiryRaw.VIN ?? null,
AccidentVehicleUsedId: input.defaults.AccidentVehicleUsedId,
PolicyCINumber: null,
@@ -4454,9 +4511,10 @@ export class ClaimRequestManagementService {
async submitFanavaranV2(
claimCaseId: string,
clientKey: FanavaranClientKey,
bodyOverride?: Record<string, unknown>,
): Promise<any> {
try {
return await this.executeFanavaranV2Submit(claimCaseId, clientKey);
return await this.executeFanavaranV2Submit(claimCaseId, clientKey, bodyOverride);
} catch (error) {
this.logger.error(
`[Fanavaran ${clientKey} V2] Error submitting to Fanavaran`,
@@ -4495,10 +4553,11 @@ export class ClaimRequestManagementService {
);
}
const payload = this.buildFanavaranDamageCasePayload({
const payload = await this.buildFanavaranDamageCasePayload({
claimCase,
blameCase,
selectedParts: claimCase.damage?.selectedParts ?? [],
clientKey,
defaults: profile.defaults,
});
@@ -4520,6 +4579,7 @@ export class ClaimRequestManagementService {
async submitFanavaranDamageCaseV2(
claimCaseId: string,
clientKey: FanavaranClientKey,
bodyOverride?: Record<string, unknown>,
): Promise<any> {
try {
return await this.executeFanavaranDamageCaseSubmit(
@@ -4527,6 +4587,7 @@ export class ClaimRequestManagementService {
clientKey,
undefined,
FanavaranAuditSource.SUBMIT,
bodyOverride,
);
} catch (error) {
this.logger.error(
@@ -5112,15 +5173,22 @@ export class ClaimRequestManagementService {
async submitFanavaranExpertiseV2(
claimCaseId: string,
clientKey: FanavaranClientKey,
bodyOverride?: Record<string, unknown>,
): Promise<any> {
try {
const claimCase = await this.claimCaseDbService.findById(claimCaseId);
if (!claimCase) throw new NotFoundException("Claim case not found");
const { payload, warnings } = await this.buildFanavaranExpertisePayload({
claimCase,
clientKey,
});
this.assertFanavaranExpertisePayloadReady(payload, warnings);
let payload: Record<string, unknown>;
if (bodyOverride) {
payload = bodyOverride;
} else {
const built = await this.buildFanavaranExpertisePayload({
claimCase,
clientKey,
});
payload = built.payload;
this.assertFanavaranExpertisePayloadReady(payload, built.warnings);
}
return await this.executeFanavaranExpertiseSubmit(
claimCaseId,
clientKey,
@@ -5625,6 +5693,7 @@ export class ClaimRequestManagementService {
clientKey: FanavaranClientKey,
selectedParts?: unknown[],
auditSource: FanavaranAuditSource = FanavaranAuditSource.AUTO_SUBMIT,
bodyOverride?: Record<string, unknown>,
): Promise<any> {
const profile = getFanavaranClientProfile(clientKey);
const claimCase = await this.claimCaseDbService.findById(claimCaseId);
@@ -5652,10 +5721,11 @@ export class ClaimRequestManagementService {
);
}
const payload = this.buildFanavaranDamageCasePayload({
const payload = bodyOverride ?? await this.buildFanavaranDamageCasePayload({
claimCase,
blameCase,
selectedParts: selectedParts ?? claimCase.damage?.selectedParts ?? [],
clientKey,
defaults: profile.defaults,
});
const url = `${this.FANAVARAN_SUBMIT_URL}/${claimCase.claimId}/dmg-cases`;
@@ -6059,6 +6129,7 @@ export class ClaimRequestManagementService {
private async executeFanavaranV2Submit(
claimCaseId: string,
clientKey: FanavaranClientKey,
bodyOverride?: Record<string, unknown>,
): Promise<any> {
const profile = getFanavaranClientProfile(clientKey);
const logPrefix = `[Fanavaran ${clientKey} V2]`;
@@ -6066,7 +6137,7 @@ export class ClaimRequestManagementService {
this.logger.log(
`${logPrefix} Starting submission for claimCaseId: ${claimCaseId}`,
);
const fanavaranData = await this.previewFanavaranSubmitV2(
const fanavaranData = bodyOverride ?? await this.previewFanavaranSubmitV2(
claimCaseId,
clientKey,
);