Files
yara724-api/src/claim-request-management/fanavaran-driver-inquiry.ts

166 lines
5.6 KiB
TypeScript

import { toEnglishDigits } from "src/lookups/fanavaran-last-car-policy";
export const FANAVARAN_INSURER_ROLE_ID = 161;
export const FANAVARAN_PLAQUE_OWNER_ROLE_ID = 163;
export const FANAVARAN_DRIVER_ROLE_ID = 166;
export type FanavaranPartyInquiryRow = {
Id?: unknown;
RoleId?: unknown;
NationalCode?: unknown;
Name?: unknown;
LastName?: unknown;
};
function asPositiveId(value: unknown): number | null {
if (value === null || value === undefined) return null;
const id = Number(value);
return Number.isFinite(id) && id > 0 ? id : null;
}
export function asPartyInquiryRows(value: unknown): FanavaranPartyInquiryRow[] {
if (Array.isArray(value)) {
return value.filter(
(row): row is FanavaranPartyInquiryRow =>
!!row && typeof row === "object" && !Array.isArray(row),
);
}
if (!value || typeof value !== "object") return [];
const record = value as Record<string, unknown>;
for (const key of ["value", "Value", "items", "Items", "data", "Data"]) {
const nested = record[key];
if (Array.isArray(nested)) return asPartyInquiryRows(nested);
}
return [];
}
/**
* DriverId for GEN.12 زیان‌دیده. Prefer insurer (161) or driver (166)
* based on driverIsInsurer, then any returned party id.
*/
export function selectFanavaranDriverId(
rows: unknown,
driverIsInsurer: boolean | undefined,
): number | null {
const parties = asPartyInquiryRows(rows);
if (parties.length === 0) return null;
const preferredRoles = driverIsInsurer
? [FANAVARAN_INSURER_ROLE_ID, FANAVARAN_DRIVER_ROLE_ID, FANAVARAN_PLAQUE_OWNER_ROLE_ID]
: [FANAVARAN_DRIVER_ROLE_ID, FANAVARAN_INSURER_ROLE_ID, FANAVARAN_PLAQUE_OWNER_ROLE_ID];
for (const roleId of preferredRoles) {
const match = parties.find((row) => asPositiveId(row.RoleId) === roleId);
if (match) return asPositiveId(match.Id);
}
return asPositiveId(parties[0].Id);
}
export function normalizeNationalCode(value: unknown): string | null {
const digits = toEnglishDigits(value).replace(/\D/g, "");
if (digits.length === 10) return digits;
if (digits.length === 8 || digits.length === 9) return digits.padStart(10, "0");
return digits.length > 0 ? digits : null;
}
export function pickPersonNationalCode(person: {
driverIsInsurer?: boolean;
nationalCodeOfDriver?: unknown;
nationalCodeOfInsurer?: unknown;
nationalCode?: unknown;
} | null | undefined): string | null {
if (!person) return null;
const driver = normalizeNationalCode(person.nationalCodeOfDriver);
const insurer = normalizeNationalCode(person.nationalCodeOfInsurer);
const generic = normalizeNationalCode(person.nationalCode);
if (person.driverIsInsurer) {
return insurer || driver || generic;
}
return driver || insurer || generic;
}
export function pickPersonBirthday(person: {
driverIsInsurer?: boolean;
driverBirthday?: unknown;
birthday?: unknown;
insurerBirthday?: unknown;
} | null | undefined): string | number | null {
if (!person) return null;
const ordered = person.driverIsInsurer
? [person.insurerBirthday, person.birthday, person.driverBirthday]
: [person.driverBirthday, person.birthday, person.insurerBirthday];
for (const value of ordered) {
if (value == null || String(value).trim() === "") continue;
if (parseJalaliDateParts(value)) return value as string | number;
}
return null;
}
export function collectPersonNationalCodes(
person: {
nationalCodeOfDriver?: unknown;
nationalCodeOfInsurer?: unknown;
nationalCode?: unknown;
} | null | undefined,
): string[] {
const codes = [
normalizeNationalCode(person?.nationalCodeOfDriver),
normalizeNationalCode(person?.nationalCodeOfInsurer),
normalizeNationalCode(person?.nationalCode),
].filter((value): value is string => !!value);
return [...new Set(codes)];
}
export function collectPersonBirthdays(person: {
driverBirthday?: unknown;
birthday?: unknown;
insurerBirthday?: unknown;
} | null | undefined): Array<string | number> {
const values = [
person?.insurerBirthday,
person?.birthday,
person?.driverBirthday,
].filter((value) => value != null && String(value).trim() !== "");
const unique: Array<string | number> = [];
const seen = new Set<string>();
for (const value of values) {
const parsed = parseJalaliDateParts(value);
const key = parsed
? `${parsed.year}-${parsed.month}-${parsed.day}`
: String(value);
if (seen.has(key)) continue;
seen.add(key);
unique.push(value as string | number);
}
return unique;
}
export function parseJalaliDateParts(
birthday: unknown,
): { year: number; month: number; day: number } | null {
if (birthday == null) return null;
if (typeof birthday === "object") {
const year = Number(toEnglishDigits((birthday as any).year ?? (birthday as any).BirthYear));
const month = Number(toEnglishDigits((birthday as any).month ?? (birthday as any).BirthMonth));
const day = Number(toEnglishDigits((birthday as any).day ?? (birthday as any).BirthDay));
if (year > 0 && month > 0 && day > 0) return { year, month, day };
return null;
}
const str = toEnglishDigits(birthday).trim();
if (/^\d{8}$/.test(str)) {
const year = parseInt(str.slice(0, 4), 10);
const month = parseInt(str.slice(4, 6), 10);
const day = parseInt(str.slice(6, 8), 10);
if (!year || !month || !day) return null;
return { year, month, day };
}
const parts = str.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 (!year || !month || !day) return null;
return { year, month, day };
}