fanavaran driver and owner id (GEN..44 defauts) - culprit type id dynamic

This commit is contained in:
2026-09-28 16:13:32 +03:30
parent a74e20b25f
commit 165afe56ae
7 changed files with 303 additions and 36 deletions

View File

@@ -272,6 +272,7 @@ import {
resolveFanavaranLicenceNo,
resolveOwnerFromParty,
resolvePolicyholderFromParty,
resolveThirdPartyCulpritTypeId,
} from "./fanavaran-party-roles";
import {
buildFanavaranOtherPeoplePayload,
@@ -4294,10 +4295,10 @@ export class ClaimRequestManagementService {
}
this.logger.warn(
`[resolveDriverFanavaranId] NO MATCH for nationalCode=${nationalCode} driverIsInsurer=${driverIsInsurer}. ` +
`[resolveDriverFanavaranId] NO acceptable RoleId 161/166 for nationalCode=${nationalCode} driverIsInsurer=${driverIsInsurer}. ` +
`Available entries: ${asPartyInquiryRows(response)
.map((e) => `{Id=${e.Id}, RoleId=${e.RoleId}, Name=${e.Name} ${e.LastName}}`)
.join("; ")}`,
.join("; ")} — submit will register GEN.44 other-people`,
);
return null;
} catch (error) {
@@ -4308,7 +4309,7 @@ export class ClaimRequestManagementService {
}
}
/** Best-effort OwnerId from parties inquiry (no GEN.44 create). */
/** Best-effort OwnerId from parties inquiry (RoleId 161/166 only; GEN.44 on submit). */
private async resolveOwnerFanavaranId(
clientKey: FanavaranClientKey,
nationalCode: string | null | undefined,
@@ -4327,7 +4328,20 @@ export class ClaimRequestManagementService {
birthDay: parsed.day,
},
);
return selectFanavaranOwnerId(response);
const ownerId = selectFanavaranOwnerId(response);
if (ownerId != null) {
this.logger.log(
`[resolveOwnerFanavaranId] MATCH: Id=${ownerId} for nationalCode=${nationalCode}`,
);
return ownerId;
}
this.logger.warn(
`[resolveOwnerFanavaranId] NO acceptable RoleId 161/166 for nationalCode=${nationalCode}. ` +
`Available: ${asPartyInquiryRows(response)
.map((e) => `{Id=${e.Id}, RoleId=${e.RoleId}}`)
.join("; ")} — submit will register GEN.44 other-people`,
);
return null;
} catch (error) {
this.logger.warn(
`[resolveOwnerFanavaranId] inquiry failed for nationalCode=${nationalCode}: ${
@@ -4877,6 +4891,37 @@ export class ClaimRequestManagementService {
);
}
if (
ownerFanavaranId == null &&
input.registerMissingPerson &&
ownerIdentity.nationalCode &&
ownerIdentity.birthday
) {
const registeredOwner = await this.registerFanavaranOtherPerson({
clientKey: input.clientKey,
person: {
nationalCode: ownerIdentity.nationalCode,
nationalCodeOfDriver: ownerIdentity.nationalCode,
birthday: ownerIdentity.birthday,
driverBirthday: ownerIdentity.birthday,
driverIsInsurer: false,
fullName: (damagedParty as any)?.person?.fullName,
phoneNumber: (damagedParty as any)?.person?.phoneNumber,
userId: (damagedParty as any)?.person?.userId,
},
claimCaseId: input.claimCase?._id
? String(input.claimCase._id)
: undefined,
});
if (registeredOwner != null) {
ownerFanavaranId = registeredOwner;
if (otherPersonId == null) otherPersonId = registeredOwner;
this.logger.log(
`[buildFanavaranDamageCasePayload] OwnerId=${ownerFanavaranId} from GEN.44 other-people`,
);
}
}
if (driverFanavaranId && input.blameCase?._id && damagedParty) {
const partyIndex = (input.blameCase.parties ?? []).findIndex(
(p: any) => p === damagedParty ||
@@ -5726,7 +5771,8 @@ export class ClaimRequestManagementService {
}
/**
* GEN.44: create the damaged party in Fanavaran when parties inquiry has no row.
* GEN.44: create the damaged party in Fanavaran when parties inquiry has no
* RoleId 161/166 row (missing entirely, or only e.g. 162 بیمه‌شده).
* Failures stay best-effort — GEN.12 submit continues without DriverId.
*/
private async registerFanavaranOtherPerson(input: {
@@ -5736,7 +5782,8 @@ export class ClaimRequestManagementService {
}): Promise<number | null> {
const nationalCode = pickPersonNationalCode(input.person);
const birthday = pickPersonBirthday(input.person);
if (!nationalCode || !parseJalaliDateParts(birthday)) {
const parsedBirthday = parseJalaliDateParts(birthday);
if (!nationalCode || !parsedBirthday) {
this.logger.warn(
`[registerFanavaranOtherPerson] SKIP: missing nationalCode or birthday`,
);
@@ -5765,12 +5812,77 @@ export class ClaimRequestManagementService {
}
}
/** Seed GEN.44 from parties inquiry when the person exists under a non-driver role. */
let inquirySeed: {
name?: string;
lastName?: string;
fatherName?: string;
genderId?: number;
identityNo?: string;
} = {};
try {
const inquiryRows =
await this.fanavaranLookupService.inquiryByUniqueIdentifier(
input.clientKey,
{
nationalCode,
birthYear: parsedBirthday.year,
birthMonth: parsedBirthday.month,
birthDay: parsedBirthday.day,
},
);
const parties = asPartyInquiryRows(inquiryRows);
const seedRow =
parties.find(
(row) =>
(typeof row.Name === "string" && row.Name.trim()) ||
(typeof row.LastName === "string" && row.LastName.trim()),
) ?? parties[0];
if (seedRow) {
const roleId = Number(seedRow.RoleId);
this.logger.log(
`[registerFanavaranOtherPerson] inquiry seed Id=${seedRow.Id} RoleId=${roleId} — creating GEN.44 سایر (adds RoleId 166 entry; existing roles stay)`,
);
inquirySeed = {
name:
typeof seedRow.Name === "string" ? seedRow.Name : undefined,
lastName:
typeof seedRow.LastName === "string"
? seedRow.LastName
: undefined,
fatherName:
typeof seedRow.FatherName === "string"
? seedRow.FatherName
: undefined,
genderId: (() => {
const g = Number(seedRow.GenderId);
return Number.isFinite(g) && g > 0 ? g : undefined;
})(),
identityNo:
typeof seedRow.IdentityNo === "string"
? seedRow.IdentityNo
: undefined,
};
}
} catch (error) {
this.logger.warn(
`[registerFanavaranOtherPerson] pre-create inquiry failed (continuing with local data): ${
error instanceof Error ? error.message : error
}`,
);
}
const lookups = await this.loadFanavaranOtherPeopleLookups(input.clientKey);
const payload = buildFanavaranOtherPeoplePayload(
{
nationalCode,
birthday,
fullName: input.person?.fullName ?? user?.fullName,
name: inquirySeed.name,
lastName: inquirySeed.lastName,
fatherName: inquirySeed.fatherName,
identityNo: inquirySeed.identityNo,
genderId: inquirySeed.genderId,
mobile: input.person?.phoneNumber ?? user?.mobile,
address: user?.address,
cityName: user?.city,
@@ -6203,7 +6315,9 @@ export class ClaimRequestManagementService {
},
});
// GEN.03 CulpritLicence*: guilty-party DRIVER for THIRD_PARTY, FIRST-party DRIVER for CAR_BODY.
// GEN.03 CulpritLicence* + CulpritTypeId: guilty-party DRIVER for THIRD_PARTY,
// FIRST-party DRIVER for CAR_BODY. CulpritTypeId uses accident-culprit-type
// (337 بیمه‌گذار / 338 راننده غير از بيمه گذار) — hull remaps separately.
{
const culpritParty =
blameCase.type === BlameRequestType.CAR_BODY
@@ -6226,6 +6340,10 @@ export class ClaimRequestManagementService {
);
payload.CulpritLicenceIssuDate =
resolveFanavaranLicenceIssuDate(culpritDriver);
if (blameCase.type !== BlameRequestType.CAR_BODY) {
payload.CulpritTypeId =
resolveThirdPartyCulpritTypeId(culpritParty as any);
}
}
const carBodyAccidentTime = (
@@ -6445,7 +6563,7 @@ export class ClaimRequestManagementService {
}
if (payload.DriverId == null) {
warnings.push(
"Damaged party is not in Fanavaran yet; submit will register them via other-people (GEN.44).",
"Damaged party has no Fanavaran RoleId 161/166 yet; submit will register them via other-people (GEN.44).",
);
}