forked from Yara724/api
mapping problems fixed
This commit is contained in:
@@ -809,7 +809,12 @@ export class ClaimRequestManagementService {
|
||||
throw er;
|
||||
}
|
||||
|
||||
if (er.code === 11000) {
|
||||
if (
|
||||
typeof er === "object" &&
|
||||
er !== null &&
|
||||
"code" in er &&
|
||||
er.code === 11000
|
||||
) {
|
||||
throw new HttpException(
|
||||
"Duplicate claim file reference.",
|
||||
HttpStatus.CONFLICT,
|
||||
@@ -1413,8 +1418,8 @@ export class ClaimRequestManagementService {
|
||||
return new ClaimPartUploadDetail([updatedClaim]);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Error in selectCarOtherPartDamage: ${error.message}`,
|
||||
error.stack,
|
||||
`Error in selectCarOtherPartDamage: ${error instanceof Error ? error.message : String(error)}`,
|
||||
error instanceof Error ? error.stack : undefined,
|
||||
);
|
||||
// Re-throw the specific error from the validation steps or a generic one.
|
||||
throw error;
|
||||
@@ -1516,7 +1521,7 @@ export class ClaimRequestManagementService {
|
||||
}
|
||||
} catch (fileError) {
|
||||
this.logger.warn(
|
||||
`Failed to delete file ${existingDoc.path}: ${fileError.message}`,
|
||||
`Failed to delete file ${existingDoc.path}: ${fileError instanceof Error ? fileError.message : String(fileError)}`,
|
||||
);
|
||||
// Continue even if file deletion fails
|
||||
}
|
||||
@@ -1612,8 +1617,8 @@ export class ClaimRequestManagementService {
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Error in uploadRequiredDocument: ${error.message}`,
|
||||
error.stack,
|
||||
`Error in uploadRequiredDocument: ${error instanceof Error ? error.message : String(error)}`,
|
||||
error instanceof Error ? error.stack : undefined,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
@@ -1658,8 +1663,8 @@ export class ClaimRequestManagementService {
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Error in getRequiredDocumentsStatus: ${error.message}`,
|
||||
error.stack,
|
||||
`Error in getRequiredDocumentsStatus: ${error instanceof Error ? error.message : String(error)}`,
|
||||
error instanceof Error ? error.stack : undefined,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
@@ -1922,8 +1927,8 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`[BACKGROUND AI] Failed to process AI requests for part ${partId}, request ${requestId}: ${error.message}`,
|
||||
error.stack,
|
||||
`[BACKGROUND AI] Failed to process AI requests for part ${partId}, request ${requestId}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
error instanceof Error ? error.stack : undefined,
|
||||
);
|
||||
// Don't throw - we're in background processing
|
||||
}
|
||||
@@ -2013,11 +2018,15 @@ export class ClaimRequestManagementService {
|
||||
`[SUCCESS] Successfully updated AI report and image for part ${partId}`,
|
||||
);
|
||||
} catch (dbError) {
|
||||
const dbErrorMessage =
|
||||
dbError instanceof Error ? dbError.message : String(dbError);
|
||||
this.logger.error(`[ERROR] Database update error for part ${partId}:`);
|
||||
this.logger.error(`[ERROR] ${dbError.message}`);
|
||||
this.logger.error(`[ERROR] Stack: ${dbError.stack}`);
|
||||
this.logger.error(`[ERROR] ${dbErrorMessage}`);
|
||||
this.logger.error(
|
||||
`[ERROR] Stack: ${dbError instanceof Error ? dbError.stack : undefined}`,
|
||||
);
|
||||
throw new HttpException(
|
||||
`Database update failed: ${dbError.message}`,
|
||||
`Database update failed: ${dbErrorMessage}`,
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
@@ -2053,7 +2062,8 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
} catch (error) {
|
||||
// Extract error source from error message if available
|
||||
const errorMessage = error.message || String(error);
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
const errorSource = errorMessage.includes("[ERROR]")
|
||||
? errorMessage.split("[ERROR]")[1]?.split("]")[0] || "UNKNOWN"
|
||||
: "UNKNOWN";
|
||||
@@ -2089,7 +2099,7 @@ export class ClaimRequestManagementService {
|
||||
this.logger.error(`🔴 [FINAL FAILURE] File path: ${newImageDoc.path}`);
|
||||
this.logger.error(`🔴 [FINAL FAILURE] Error source: ${errorSource}`);
|
||||
this.logger.error(`🔴 [FINAL FAILURE] Final error: ${errorMessage}`);
|
||||
if (error.stack) {
|
||||
if (error instanceof Error && error.stack) {
|
||||
this.logger.error(`🔴 [FINAL FAILURE] Stack trace: ${error.stack}`);
|
||||
}
|
||||
// Optional: Update the claim status to indicate an AI failure.
|
||||
@@ -2856,7 +2866,7 @@ export class ClaimRequestManagementService {
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Error during factor upload for claim ${claimId}:`,
|
||||
error.stack,
|
||||
error instanceof Error ? error.stack : String(error),
|
||||
);
|
||||
|
||||
if (error instanceof HttpException) {
|
||||
@@ -3155,7 +3165,12 @@ export class ClaimRequestManagementService {
|
||||
};
|
||||
} catch (err) {
|
||||
this.logger.error(err);
|
||||
return new HttpException(err.message, err.status);
|
||||
return new HttpException(
|
||||
err instanceof HttpException ? err.message : String(err),
|
||||
err instanceof HttpException
|
||||
? err.getStatus()
|
||||
: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3214,7 +3229,12 @@ export class ClaimRequestManagementService {
|
||||
};
|
||||
} catch (err) {
|
||||
this.logger.error(err);
|
||||
return new HttpException(err.message, err.status);
|
||||
return new HttpException(
|
||||
err instanceof HttpException ? err.message : String(err),
|
||||
err instanceof HttpException
|
||||
? err.getStatus()
|
||||
: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3609,6 +3629,53 @@ export class ClaimRequestManagementService {
|
||||
return `${plate.centerDigits}${plate.centerAlphabet}${plate.leftDigits}`;
|
||||
}
|
||||
|
||||
/** First non-empty string from party vehicle.inquiry mapped/raw (ESG + Tejarat aliases). */
|
||||
private pickPartyInquiryField(
|
||||
mapped: Record<string, any> | null | undefined,
|
||||
raw: Record<string, any> | null | undefined,
|
||||
keys: string[],
|
||||
): string | null {
|
||||
for (const key of keys) {
|
||||
const value = mapped?.[key] ?? raw?.[key];
|
||||
if (value == null) continue;
|
||||
const text = String(value).trim();
|
||||
if (text) return text;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private resolvePlateFromPartyInquiry(
|
||||
mapped: Record<string, any> | null | undefined,
|
||||
raw: Record<string, any> | null | undefined,
|
||||
): {
|
||||
leftDigits: number;
|
||||
centerAlphabet: string;
|
||||
centerDigits: number;
|
||||
ir: number;
|
||||
} | null {
|
||||
const left = this.pickPartyInquiryField(mapped, raw, ["plk1", "Plk1"]);
|
||||
const middle = this.pickPartyInquiryField(mapped, raw, ["plk2", "Plk2"]);
|
||||
const right = this.pickPartyInquiryField(mapped, raw, ["plk3", "Plk3"]);
|
||||
const serial = this.pickPartyInquiryField(mapped, raw, [
|
||||
"plksrl",
|
||||
"PlkSrl",
|
||||
]);
|
||||
if (!left || !middle || !right || !serial) return null;
|
||||
const leftDigits = Number(left);
|
||||
const centerDigits = Number(right);
|
||||
const ir = Number(serial);
|
||||
const centerAlphabet = this.plateNormalizer.normalizePlateText(middle);
|
||||
if (
|
||||
!Number.isFinite(leftDigits) ||
|
||||
!Number.isFinite(centerDigits) ||
|
||||
!Number.isFinite(ir) ||
|
||||
!centerAlphabet
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return { leftDigits, centerAlphabet, centerDigits, ir };
|
||||
}
|
||||
|
||||
private async resolveVehicleKindId(
|
||||
clientKey: FanavaranClientKey,
|
||||
carType?: string,
|
||||
@@ -3781,10 +3848,6 @@ export class ClaimRequestManagementService {
|
||||
FaultPercent: number;
|
||||
};
|
||||
}): Promise<Record<string, unknown>> {
|
||||
const plate = this.resolveOwnershipPlateForClaim(
|
||||
input.claimCase,
|
||||
input.blameCase,
|
||||
);
|
||||
const damagedParty = Array.isArray(input.blameCase?.parties)
|
||||
? input.blameCase.parties.find(
|
||||
(party: any) =>
|
||||
@@ -3795,8 +3858,19 @@ export class ClaimRequestManagementService {
|
||||
const person = damagedParty?.person ?? {};
|
||||
const vehicle = damagedParty?.vehicle ?? {};
|
||||
const insurance = damagedParty?.insurance ?? {};
|
||||
const inquiryMapped = vehicle?.inquiry?.mapped ?? {};
|
||||
const inquiryRaw = vehicle?.inquiry?.raw ?? {};
|
||||
// Prefer nested inquiry (ESG/Tejarat) on the damaged party — not flattened insurance.*
|
||||
const inquiryRawPayload =
|
||||
vehicle?.inquiry?.raw?.data != null &&
|
||||
typeof vehicle.inquiry.raw.data === "object" &&
|
||||
!Array.isArray(vehicle.inquiry.raw.data)
|
||||
? vehicle.inquiry.raw.data
|
||||
: (vehicle?.inquiry?.raw ?? {});
|
||||
const inquiryMapped = vehicle?.inquiry?.mapped ?? inquiryRawPayload ?? {};
|
||||
const inquiryRaw = inquiryRawPayload ?? {};
|
||||
|
||||
const plate =
|
||||
this.resolveOwnershipPlateForClaim(input.claimCase, input.blameCase) ??
|
||||
this.resolvePlateFromPartyInquiry(inquiryMapped, inquiryRaw);
|
||||
|
||||
this.logger.log(
|
||||
`[buildFanavaranDamageCasePayload] damagedParty resolved: userId=${damagedParty?.person?.userId ?? "NONE"}, ` +
|
||||
@@ -3812,22 +3886,44 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
}
|
||||
|
||||
const guiltyUserId =
|
||||
input.blameCase?.expertSubmitReplyFinal?.guiltyUserId ??
|
||||
input.blameCase?.expertSubmitReply?.guiltyUserId;
|
||||
const blamedParty =
|
||||
guiltyUserId && Array.isArray(input.blameCase?.parties)
|
||||
? input.blameCase.parties.find(
|
||||
(party: any) =>
|
||||
String(party?.person?.userId ?? "") === String(guiltyUserId),
|
||||
)
|
||||
: null;
|
||||
|
||||
// Get PolicyCINumber from damaged party's inquiry (mapped or raw), not blamed party
|
||||
const policyCINumber =
|
||||
inquiryMapped.ThirdPolicyCode ??
|
||||
inquiryRaw.ThirdPolicyCode ??
|
||||
// Policy document / unique code / coverage dates from damaged party's plate inquiry
|
||||
const policyNo =
|
||||
this.pickPartyInquiryField(inquiryMapped, inquiryRaw, [
|
||||
"PrntCmpDocNo",
|
||||
"PrntPlcyCmpDocNo",
|
||||
"printNumber",
|
||||
"insuranceNumber",
|
||||
]) ??
|
||||
insurance.policyNumber ??
|
||||
null;
|
||||
const policyCINumber = this.pickPartyInquiryField(
|
||||
inquiryMapped,
|
||||
inquiryRaw,
|
||||
["PlcyUnqCod", "ThirdPolicyCode"],
|
||||
);
|
||||
const beginDate =
|
||||
this.pickPartyInquiryField(inquiryMapped, inquiryRaw, [
|
||||
"HBgnDte",
|
||||
"StartDate",
|
||||
"persianStartDate",
|
||||
"SatrtDate",
|
||||
]) ??
|
||||
insurance.startDate ??
|
||||
null;
|
||||
const endDate =
|
||||
this.pickPartyInquiryField(inquiryMapped, inquiryRaw, [
|
||||
"HEndDte",
|
||||
"EndDate",
|
||||
"persianEndDate",
|
||||
]) ??
|
||||
insurance.endDate ??
|
||||
null;
|
||||
const builtYearRaw = this.pickPartyInquiryField(inquiryMapped, inquiryRaw, [
|
||||
"PrdDte",
|
||||
"ModelField",
|
||||
"ModelCii",
|
||||
]);
|
||||
const builtYear = builtYearRaw ? Number(builtYearRaw) || null : null;
|
||||
|
||||
const carType = input.claimCase?.vehicle?.carType as string | undefined;
|
||||
const vehicleKindId = await this.resolveVehicleKindId(
|
||||
@@ -3870,24 +3966,23 @@ export class ClaimRequestManagementService {
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
`[buildFanavaranDamageCasePayload] Final DriverId=${driverFanavaranId ?? "NULL"} for nationalCodeOfDriver=${person.nationalCodeOfDriver ?? "MISSING"}`,
|
||||
`[buildFanavaranDamageCasePayload] Final DriverId=${driverFanavaranId ?? "NULL"} for nationalCodeOfDriver=${person.nationalCodeOfDriver ?? "MISSING"}, ` +
|
||||
`PolicyNo=${policyNo ?? "NULL"}, PolicyCINumber=${policyCINumber ?? "NULL"}`,
|
||||
);
|
||||
|
||||
return {
|
||||
BeginDate: insurance.startDate ?? null,
|
||||
BuiltYear:
|
||||
Number(inquiryMapped.ModelField ?? inquiryMapped.ModelCii) || Number(inquiryMapped.PrdDte) || null,
|
||||
ChassisNo:
|
||||
inquiryMapped.ChassisNumberField ??
|
||||
inquiryMapped.ShsNum ??
|
||||
inquiryRaw.ChassisNumberField ??
|
||||
inquiryRaw.ShsNum ??
|
||||
null,
|
||||
BeginDate: beginDate,
|
||||
BuiltYear: builtYear,
|
||||
ChassisNo: this.pickPartyInquiryField(inquiryMapped, inquiryRaw, [
|
||||
"ShsNum",
|
||||
"ChassisNumberField",
|
||||
"shsNam",
|
||||
]),
|
||||
DmgHistoryStatus: input.defaults.DmgHistoryStatus,
|
||||
Desc: this.formatFanavaranSelectedPartsDesc(input.selectedParts),
|
||||
DmgCaseTypeId: input.defaults.DmgCaseTypeId,
|
||||
DriverId: driverFanavaranId ?? null,
|
||||
EndDate: insurance.endDate ?? null,
|
||||
EndDate: endDate,
|
||||
EstimateAmount: FANAVARAN_PROVISIONAL_ESTIMATE_AMOUNT,
|
||||
FaultPercent: input.defaults.FaultPercent,
|
||||
InsuranceCorpId: await this.fanavaranLookupService.resolveInsuranceCorpId(input.clientKey),
|
||||
@@ -3898,12 +3993,11 @@ export class ClaimRequestManagementService {
|
||||
LicenceIssuDate: person.driverBirthday ?? "1394/10/13",
|
||||
LicenceNo: person.driverLicense ?? "1124242",
|
||||
LicenceTypeId: input.defaults.CulpritLicenceTypeId,
|
||||
MotorNo:
|
||||
inquiryMapped.MtrNum ??
|
||||
inquiryMapped.EngineNumberField ??
|
||||
inquiryRaw.MtrNum ??
|
||||
inquiryRaw.EngineNumberField ??
|
||||
null,
|
||||
MotorNo: this.pickPartyInquiryField(inquiryMapped, inquiryRaw, [
|
||||
"MtrNum",
|
||||
"EngineNumberField",
|
||||
"mtrnum",
|
||||
]),
|
||||
OwnerId: null,
|
||||
PlaqueCityId: null,
|
||||
PlaqueKindId: plate ? input.defaults.PlaqueKindId : null,
|
||||
@@ -3911,14 +4005,20 @@ export class ClaimRequestManagementService {
|
||||
PlaqueMiddleCodeId: this.getFanavaranPlateMiddleCode(
|
||||
plate?.centerAlphabet,
|
||||
),
|
||||
PlaqueNo: this.formatFanavaranPlateNo(plate),
|
||||
PlaqueNo:
|
||||
this.pickPartyInquiryField(inquiryMapped, inquiryRaw, ["Plk"]) ??
|
||||
this.formatFanavaranPlateNo(plate),
|
||||
PlaqueRightNo: plate ? String(plate.centerDigits) : null,
|
||||
PlaqueSampleId: plate ? input.defaults.PlaqueSampleId : null,
|
||||
PlaqueSerial: plate ? String(plate.ir) : null,
|
||||
PolicyNo: insurance.policyNumber ?? null,
|
||||
PreviousPolicyEndDate: insurance.endDate ?? "",
|
||||
PolicyNo: policyNo,
|
||||
PreviousPolicyEndDate: endDate ?? "",
|
||||
VehicleKindId: vehicleKindId,
|
||||
VIN: inquiryMapped.VIN ?? inquiryRaw.VIN ?? null,
|
||||
VIN: this.pickPartyInquiryField(inquiryMapped, inquiryRaw, [
|
||||
"VIN",
|
||||
"vin",
|
||||
"VinNumberField",
|
||||
]),
|
||||
AccidentVehicleUsedId: input.defaults.AccidentVehicleUsedId,
|
||||
PolicyCINumber: policyCINumber,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user