forked from Yara724/api
update the fanavaran which accepts unknown person too
This commit is contained in:
@@ -185,7 +185,10 @@ import {
|
||||
import { FanavaranAuditService } from "src/fanavaran/fanavaran-audit.service";
|
||||
import { FanavaranAuthService } from "src/fanavaran/fanavaran-auth.service";
|
||||
import { FanavaranLookupService } from "src/fanavaran/fanavaran-lookup.service";
|
||||
import { FANAVARAN_REMOTE_LOOKUPS } from "src/fanavaran/fanavaran-lookup.config";
|
||||
import {
|
||||
FANAVARAN_LOOKUP_BASE_URL,
|
||||
FANAVARAN_REMOTE_LOOKUPS,
|
||||
} from "src/fanavaran/fanavaran-lookup.config";
|
||||
import type { FanavaranAuditSession } from "src/fanavaran/fanavaran-audit.types";
|
||||
import {
|
||||
FanavaranAuditSource,
|
||||
@@ -207,6 +210,10 @@ import {
|
||||
pickPersonNationalCode,
|
||||
selectFanavaranDriverId,
|
||||
} from "./fanavaran-driver-inquiry";
|
||||
import {
|
||||
buildFanavaranOtherPeoplePayload,
|
||||
pickFanavaranRecordId,
|
||||
} from "./fanavaran-other-people";
|
||||
import {
|
||||
asObjectRecord,
|
||||
collectPartyVinCandidates,
|
||||
@@ -4127,6 +4134,8 @@ export class ClaimRequestManagementService {
|
||||
DriverIsOwner: number;
|
||||
FaultPercent: number;
|
||||
};
|
||||
/** GEN.44 write: register the damaged party in Fanavaran when inquiry misses. */
|
||||
registerMissingPerson?: boolean;
|
||||
}): Promise<Record<string, unknown>> {
|
||||
const damagedParty = this.pickDamagedPartyForFanavaran(
|
||||
input.blameCase,
|
||||
@@ -4288,9 +4297,11 @@ export class ClaimRequestManagementService {
|
||||
// Prefer claim-level cache, then party.person.fanavaranDriverId, then live inquiry, then last payload
|
||||
let driverFanavaranId = this.firstPositiveFanavaranId(
|
||||
cachedDamage.driverId,
|
||||
cachedDamage.otherPersonId,
|
||||
person.fanavaranDriverId,
|
||||
lastDamagePayload?.DriverId,
|
||||
);
|
||||
let otherPersonId = this.firstPositiveFanavaranId(cachedDamage.otherPersonId);
|
||||
|
||||
if (driverFanavaranId) {
|
||||
this.logger.log(
|
||||
@@ -4304,6 +4315,20 @@ export class ClaimRequestManagementService {
|
||||
input.claimCase,
|
||||
);
|
||||
|
||||
if (!driverFanavaranId && input.registerMissingPerson) {
|
||||
const registered = await this.registerFanavaranOtherPerson({
|
||||
clientKey: input.clientKey,
|
||||
person,
|
||||
claimCaseId: input.claimCase?._id
|
||||
? String(input.claimCase._id)
|
||||
: undefined,
|
||||
});
|
||||
if (registered != null) {
|
||||
driverFanavaranId = registered;
|
||||
otherPersonId = registered;
|
||||
}
|
||||
}
|
||||
|
||||
// Persist the resolved ID back to the blame case party for future use
|
||||
if (driverFanavaranId && input.blameCase?._id && damagedParty) {
|
||||
const partyIndex = (input.blameCase.parties ?? []).findIndex(
|
||||
@@ -4473,6 +4498,9 @@ export class ClaimRequestManagementService {
|
||||
...(driverFanavaranId != null
|
||||
? { "fanavaranSync.damageCase.driverId": driverFanavaranId }
|
||||
: {}),
|
||||
...(otherPersonId != null
|
||||
? { "fanavaranSync.damageCase.otherPersonId": otherPersonId }
|
||||
: {}),
|
||||
...(vehicleKindId != null
|
||||
? { "fanavaranSync.damageCase.vehicleKindId": vehicleKindId }
|
||||
: {}),
|
||||
@@ -5075,6 +5103,158 @@ export class ClaimRequestManagementService {
|
||||
return null;
|
||||
}
|
||||
|
||||
private async loadFanavaranOtherPeopleLookups(
|
||||
clientKey: FanavaranClientKey,
|
||||
): Promise<{
|
||||
cities: unknown[];
|
||||
gender: unknown[];
|
||||
maritalStatus: unknown[];
|
||||
ans: unknown[];
|
||||
countries: unknown[];
|
||||
personKind: unknown[];
|
||||
}> {
|
||||
const [cities, gender, maritalStatus, ans, countries, personKind] =
|
||||
await Promise.all([
|
||||
this.getFanavaranLookupRows(clientKey, "cities"),
|
||||
this.getFanavaranLookupRows(clientKey, "gender"),
|
||||
this.getFanavaranLookupRows(clientKey, "marital-status"),
|
||||
this.getFanavaranLookupRows(clientKey, "ans"),
|
||||
this.getFanavaranLookupRows(clientKey, "countries"),
|
||||
this.getFanavaranLookupRows(clientKey, "person-kind"),
|
||||
]);
|
||||
return { cities, gender, maritalStatus, ans, countries, personKind };
|
||||
}
|
||||
|
||||
/**
|
||||
* GEN.44: create the damaged party in Fanavaran when parties inquiry has no row.
|
||||
* Failures stay best-effort — GEN.12 submit continues without DriverId.
|
||||
*/
|
||||
private async registerFanavaranOtherPerson(input: {
|
||||
clientKey: FanavaranClientKey;
|
||||
person: any;
|
||||
claimCaseId?: string;
|
||||
}): Promise<number | null> {
|
||||
const nationalCode = pickPersonNationalCode(input.person);
|
||||
const birthday = pickPersonBirthday(input.person);
|
||||
if (!nationalCode || !parseJalaliDateParts(birthday)) {
|
||||
this.logger.warn(
|
||||
`[registerFanavaranOtherPerson] SKIP: missing nationalCode or birthday`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
let user: {
|
||||
fullName?: string;
|
||||
mobile?: string;
|
||||
city?: string;
|
||||
address?: string;
|
||||
gender?: string;
|
||||
} | null = null;
|
||||
const userId = input.person?.userId;
|
||||
if (userId && Types.ObjectId.isValid(String(userId))) {
|
||||
try {
|
||||
user = await this.userDbService.findOne({
|
||||
_id: new Types.ObjectId(String(userId)),
|
||||
});
|
||||
} catch (error) {
|
||||
this.logger.warn(
|
||||
`[registerFanavaranOtherPerson] user lookup failed: ${
|
||||
error instanceof Error ? error.message : error
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const lookups = await this.loadFanavaranOtherPeopleLookups(input.clientKey);
|
||||
const payload = buildFanavaranOtherPeoplePayload(
|
||||
{
|
||||
nationalCode,
|
||||
birthday,
|
||||
fullName: input.person?.fullName ?? user?.fullName,
|
||||
mobile: input.person?.phoneNumber ?? user?.mobile,
|
||||
address: user?.address,
|
||||
cityName: user?.city,
|
||||
gender: user?.gender,
|
||||
},
|
||||
lookups,
|
||||
);
|
||||
if (!payload) {
|
||||
this.logger.warn(
|
||||
`[registerFanavaranOtherPerson] SKIP: could not build GEN.44 payload for nationalCode=${nationalCode}`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const url = `${FANAVARAN_LOOKUP_BASE_URL}/common/other-people`;
|
||||
const startedAt = Date.now();
|
||||
const auditSession: FanavaranAuditSession = {
|
||||
trackingCode: this.fanavaranAuditService.generateTrackingCode(),
|
||||
clientKey: input.clientKey,
|
||||
source: FanavaranAuditSource.AUTO_SUBMIT,
|
||||
claimCaseId: input.claimCaseId,
|
||||
};
|
||||
|
||||
await this.fanavaranAuditService.recordStep({
|
||||
session: auditSession,
|
||||
step: FanavaranAuditStep.CREATE_OTHER_PERSON,
|
||||
status: FanavaranAuditStatus.STARTED,
|
||||
requestUrl: url,
|
||||
requestMethod: "POST",
|
||||
requestBody: payload,
|
||||
requestMeta: { nationalCode },
|
||||
});
|
||||
|
||||
try {
|
||||
const created = await this.fanavaranLookupService.createOtherPerson(
|
||||
input.clientKey,
|
||||
payload,
|
||||
);
|
||||
const personId = pickFanavaranRecordId(created);
|
||||
await this.fanavaranAuditService.recordStep({
|
||||
session: auditSession,
|
||||
step: FanavaranAuditStep.CREATE_OTHER_PERSON,
|
||||
status: FanavaranAuditStatus.SUCCESS,
|
||||
requestUrl: url,
|
||||
requestMethod: "POST",
|
||||
requestBody: payload,
|
||||
responseBody: created,
|
||||
responseMeta: { otherPersonId: personId, nationalCode },
|
||||
durationMs: Date.now() - startedAt,
|
||||
});
|
||||
if (personId != null) {
|
||||
this.logger.log(
|
||||
`[registerFanavaranOtherPerson] CREATED Id=${personId} for nationalCode=${nationalCode}`,
|
||||
);
|
||||
return personId;
|
||||
}
|
||||
this.logger.warn(
|
||||
`[registerFanavaranOtherPerson] create returned no Id for nationalCode=${nationalCode}; retrying inquiry`,
|
||||
);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
await this.fanavaranAuditService.recordStep({
|
||||
session: auditSession,
|
||||
step: FanavaranAuditStep.CREATE_OTHER_PERSON,
|
||||
status: FanavaranAuditStatus.FAILURE,
|
||||
requestUrl: url,
|
||||
requestMethod: "POST",
|
||||
requestBody: payload,
|
||||
errorMessage: message,
|
||||
durationMs: Date.now() - startedAt,
|
||||
});
|
||||
this.logger.warn(
|
||||
`[registerFanavaranOtherPerson] CREATE failed for nationalCode=${nationalCode}: ${message}; retrying inquiry`,
|
||||
);
|
||||
}
|
||||
|
||||
return this.resolveDriverFanavaranId(
|
||||
input.clientKey,
|
||||
nationalCode,
|
||||
birthday,
|
||||
input.person?.driverIsInsurer,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* زیاندیده for GEN.12: claim owner when linked to a blame party,
|
||||
* else the party that is not the guilty one.
|
||||
@@ -5521,6 +5701,16 @@ export class ClaimRequestManagementService {
|
||||
defaults: profile.defaults,
|
||||
});
|
||||
|
||||
const warnings: string[] = [];
|
||||
if (!claimCase.claimId) {
|
||||
warnings.push("Fanavaran base claimId is required before submit.");
|
||||
}
|
||||
if (payload.DriverId == null) {
|
||||
warnings.push(
|
||||
"Damaged party is not in Fanavaran yet; submit will register them via other-people (GEN.44).",
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
clientKey,
|
||||
claimCaseId,
|
||||
@@ -5529,9 +5719,7 @@ export class ClaimRequestManagementService {
|
||||
submitUrl: claimCase.claimId
|
||||
? `${this.FANAVARAN_SUBMIT_URL}/${claimCase.claimId}/dmg-cases`
|
||||
: null,
|
||||
warning: claimCase.claimId
|
||||
? undefined
|
||||
: "Fanavaran base claimId is required before submit.",
|
||||
warning: warnings.length ? warnings.join(" ") : undefined,
|
||||
payload,
|
||||
};
|
||||
}
|
||||
@@ -7021,6 +7209,7 @@ export class ClaimRequestManagementService {
|
||||
selectedParts: selectedParts ?? claimCase.damage?.selectedParts ?? [],
|
||||
clientKey,
|
||||
defaults: profile.defaults,
|
||||
registerMissingPerson: true,
|
||||
});
|
||||
|
||||
// Guardrail: never send empty/null licence fields even if manual overrides arrive.
|
||||
|
||||
Reference in New Issue
Block a user