licence number dummy data fills and never empty

This commit is contained in:
2026-08-05 14:26:13 +03:30
parent 07cd4776e9
commit d4487776fb
2 changed files with 79 additions and 3 deletions

View File

@@ -274,6 +274,12 @@ const FANAVARAN_ACCIDENT_LOCATION_ADDRESS = "استان تهران شهر تهر
const FANAVARAN_DEFAULT_ACCIDENT_CAUSE_ID = 6;
const FANAVARAN_DEFAULT_ACCIDENT_LEVEL = 5456;
const FANAVARAN_PROVISIONAL_ESTIMATE_AMOUNT = 1000;
/**
* Fanavaran sometimes rejects missing/empty/whitespace licence numbers.
* We always send either the user-entered value (from DB) or this 10-digit dummy.
*/
const FANAVARAN_DUMMY_LICENCE_NO =
process.env.FANAVARAN_DUMMY_LICENCE_NO?.trim() || "9705463515";
/** Local carType → Fanavaran vehicle-kind Caption keywords for matching. */
const VEHICLE_KIND_KEYWORDS: Record<ClaimVehicleTypeV2, string[]> = {
@@ -3522,6 +3528,58 @@ export class ClaimRequestManagementService {
};
}
/**
* Extract digits-only licence number from a possibly-null/empty value.
* Returns `null` when the value is "null", "undefined", "", '' or whitespace.
*/
private extractNonEmptyLicenceDigits(
value: unknown,
): string | null {
if (value === null || value === undefined) return null;
const asString =
typeof value === "number" ? String(value) : String(value);
const trimmed = asString.trim();
if (!trimmed) return null;
const lowered = trimmed.toLowerCase();
if (lowered === "null" || lowered === "undefined") return null;
const digits = trimmed.replace(/[^\d]/g, "");
return digits ? digits : null;
}
/**
* Resolve licence number to send to Fanavaran.
* Preference order:
* - use the first non-empty value from DB (driverLicense/insurerLicense)
* - else use the configured 10-digit dummy
*/
private resolveFanavaranLicenceNoFromParty(input: {
driverIsInsurer?: boolean;
driverLicense?: unknown;
insurerLicense?: unknown;
}): string {
const { driverIsInsurer, driverLicense, insurerLicense } = input;
// When driverIsInsurer === true, UI usually mirrors insurer/driver values,
// but DB can still miss one of the two fields — prefer both.
const candidates = driverIsInsurer
? [driverLicense, insurerLicense]
: [driverLicense, insurerLicense];
for (const c of candidates) {
const digits = this.extractNonEmptyLicenceDigits(c);
if (digits) return digits;
}
return FANAVARAN_DUMMY_LICENCE_NO;
}
/** Last-resort sanitization for payload values coming from manual overrides. */
private ensureFanavaranNonEmptyLicenceNo(value: unknown): string {
return (
this.extractNonEmptyLicenceDigits(value) ?? FANAVARAN_DUMMY_LICENCE_NO
);
}
private applyFanavaranDefaultFields(result: Record<string, unknown>): void {
result.ActualPremium = null;
result.ArchiveNo = null;
@@ -3536,7 +3594,8 @@ export class ClaimRequestManagementService {
result.CulpritLicenceCountryId = null;
result.CulpritLicenceForeignCityName = null;
result.CulpritLicenceIssuDate = "1394/10/13";
result.CulpritLicenceNo = "1124242";
// Must never be empty/null.
result.CulpritLicenceNo = FANAVARAN_DUMMY_LICENCE_NO;
result.DamagedCount = 1;
result.DmgAssessorFirstCreationTime = null;
result.EntryDate = null;
@@ -4055,7 +4114,12 @@ export class ClaimRequestManagementService {
LicenceCountryId: null,
LicenceForeignCityName: null,
LicenceIssuDate: person.driverBirthday ?? "1394/10/13",
LicenceNo: person.driverLicense ?? "1124242",
// Must never be empty/null; prefer stored DB value, else use dummy.
LicenceNo: this.resolveFanavaranLicenceNoFromParty({
driverIsInsurer: person.driverIsInsurer,
driverLicense: person.driverLicense,
insurerLicense: person.insurerLicense,
}),
LicenceTypeId: input.defaults.CulpritLicenceTypeId,
MotorNo: this.pickPartyInquiryField(inquiryMapped, inquiryRaw, [
"MtrNum",
@@ -6324,6 +6388,10 @@ export class ClaimRequestManagementService {
clientKey,
defaults: profile.defaults,
});
// Guardrail: never send empty/null licence fields even if manual overrides arrive.
payload.LicenceNo = this.ensureFanavaranNonEmptyLicenceNo(payload.LicenceNo);
const url = `${this.FANAVARAN_SUBMIT_URL}/${claimCase.claimId}/dmg-cases`;
this.logger.log(
`[executeFanavaranDamageCaseSubmit] claimCaseId=${claimCaseId} claimId=${claimCase.claimId} payload.DriverId=${payload.DriverId ?? "NULL"} payload keys=${Object.keys(payload).join(", ")}`,
@@ -7124,6 +7192,12 @@ export class ClaimRequestManagementService {
auditSession,
persistPayload: true,
}));
// Guardrail: never send empty/null licence fields even if manual overrides arrive.
fanavaranData.CulpritLicenceNo = this.ensureFanavaranNonEmptyLicenceNo(
fanavaranData.CulpritLicenceNo,
);
this.logger.log(
`${logPrefix} Mapped data prepared:`,
JSON.stringify(fanavaranData, null, 2),

View File

@@ -138,7 +138,9 @@ export const SEED_FANAVARAN_CLIENT_PROFILES: Record<
ClaimExpertId: 154,
// GEN.08 — ارزیاب خسارت ثالث مالی (رسول کرکی / شعبه غرب → 29)
ExpertiseClaimExpertId: 29,
ClaimFileTypeId: 70,
// GEN.07 — proven 2026-08-03 (CL68535): 63 = سایر مدارک خسارت in parsian file-types.
// Do not use 70 — not in Parsian lookup → "نوع فايل با منبع لوکاپ مطابقت ندارد".
ClaimFileTypeId: 63,
},
},
moallem: {