forked from Yara724/api
third party update , optional body is done
This commit is contained in:
@@ -37,8 +37,11 @@ import { ClaimRequestManagementDbService } from "./entites/db-service/claim-requ
|
||||
import { ClaimCaseDbService } from "./entites/db-service/claim-case.db.service";
|
||||
import { fanavaranClaimReferences } from "./fanavaran-claim-references";
|
||||
import {
|
||||
FANAVARAN_HULL_NO_DAMAGE_CASE_REASON,
|
||||
fanavaranClaimProductFromBlameType,
|
||||
fanavaranClaimsBaseUrl,
|
||||
fanavaranClaimStageUrl,
|
||||
fanavaranHasDamageCaseStage,
|
||||
fanavaranInsuranceLineIdForProduct,
|
||||
fanavaranPartyInquirySources,
|
||||
isFanavaranSubmitSupportedBlameType,
|
||||
@@ -228,18 +231,20 @@ import {
|
||||
import {
|
||||
asObjectRecord,
|
||||
asVehicleInquiryRows,
|
||||
canReuseCachedFanavaranVehicleIds,
|
||||
collectPartyVinCandidates,
|
||||
completePlaqueParts,
|
||||
fanavaranIdOrConfigDefault,
|
||||
fanavaranPayloadMatchesDamagedIdentity,
|
||||
fanavaranVehicleMatchesDamagedIdentity,
|
||||
normalizeVin,
|
||||
applyFanavaranManualPayloadOverrides,
|
||||
FANAVARAN_BASE_MANUAL_OVERRIDE_KEYS,
|
||||
FANAVARAN_DAMAGE_MANUAL_OVERRIDE_KEYS,
|
||||
FANAVARAN_EXPERTISE_MANUAL_OVERRIDE_KEYS,
|
||||
parseFanavaranId,
|
||||
pickFanavaranPlaqueLookupFields,
|
||||
pickFanavaranVehicleFromInquiry,
|
||||
pickVehicleId,
|
||||
pickVinFromPartyVehicle,
|
||||
resolveDamageCasePlaqueLookupIds,
|
||||
selectFanavaranVehicleForDamageCase,
|
||||
type FanavaranDamagedVehicleIdentity,
|
||||
} from "src/lookups/fanavaran-last-car-policy";
|
||||
@@ -4336,17 +4341,6 @@ export class ClaimRequestManagementService {
|
||||
}
|
||||
const cachedDamage =
|
||||
(input.claimCase as any)?.fanavaranSync?.damageCase ?? {};
|
||||
const lastDamagePayload = asObjectRecord(cachedDamage.lastPayload);
|
||||
const cacheMatchesIdentity = fanavaranPayloadMatchesDamagedIdentity(
|
||||
lastDamagePayload,
|
||||
damagedIdentity,
|
||||
);
|
||||
const canReuseCachedPlaque =
|
||||
cacheMatchesIdentity &&
|
||||
canReuseCachedFanavaranVehicleIds(cachedDamage.plaqueKindSource);
|
||||
const canReuseCachedVehicleKind =
|
||||
cacheMatchesIdentity &&
|
||||
canReuseCachedFanavaranVehicleIds(cachedDamage.vehicleKindSource);
|
||||
|
||||
this.logger.log(
|
||||
`[buildFanavaranDamageCasePayload] identity VIN=${damagedIdentity.vin ?? "none"} chassis=${damagedIdentity.chassis ?? "none"} plate=${damagedIdentity.plaque ? `${damagedIdentity.plaque.right}${damagedIdentity.plaque.letter}${damagedIdentity.plaque.left}/${damagedIdentity.plaque.serial}` : "none"} CI=${damagedIdentity.policyCINumber ?? "none"} VIN candidates=${damagedVinCandidates.join(",") || "none"}`,
|
||||
@@ -4358,63 +4352,25 @@ export class ClaimRequestManagementService {
|
||||
product,
|
||||
);
|
||||
const apiPlaque = pickFanavaranPlaqueLookupFields(apiVehicle);
|
||||
const inquiryVehicle =
|
||||
asObjectRecord(inquiryMapped) ?? asObjectRecord(inquiryRaw);
|
||||
const inquiryPlaque = fanavaranVehicleMatchesDamagedIdentity(
|
||||
inquiryVehicle,
|
||||
damagedIdentity,
|
||||
)
|
||||
? pickFanavaranPlaqueLookupFields(inquiryVehicle)
|
||||
: pickFanavaranPlaqueLookupFields(null);
|
||||
const plaqueKindFromApi = this.firstPositiveFanavaranId(
|
||||
apiPlaque.kindId,
|
||||
inquiryPlaque.kindId,
|
||||
canReuseCachedPlaque ? cachedDamage.plaqueKindId : null,
|
||||
canReuseCachedPlaque ? lastDamagePayload?.PlaqueKindId : null,
|
||||
);
|
||||
const plaqueSampleFromApi = this.firstPositiveFanavaranId(
|
||||
apiPlaque.sampleId,
|
||||
inquiryPlaque.sampleId,
|
||||
canReuseCachedPlaque ? cachedDamage.plaqueSampleId : null,
|
||||
canReuseCachedPlaque ? lastDamagePayload?.PlaqueSampleId : null,
|
||||
);
|
||||
const plaqueKindId = fanavaranIdOrConfigDefault(
|
||||
plaqueKindFromApi,
|
||||
input.defaults.PlaqueKindId,
|
||||
);
|
||||
const plaqueSampleId = fanavaranIdOrConfigDefault(
|
||||
plaqueSampleFromApi,
|
||||
input.defaults.PlaqueSampleId,
|
||||
);
|
||||
const plaqueKindSource =
|
||||
plaqueKindFromApi != null ? "vehicle-inquiry" : "config-default";
|
||||
const plaqueSampleSource =
|
||||
plaqueSampleFromApi != null ? "vehicle-inquiry" : "config-default";
|
||||
if (plaqueKindFromApi == null) {
|
||||
const plaqueLookup = resolveDamageCasePlaqueLookupIds(apiVehicle);
|
||||
const plaqueKindId = plaqueLookup.kindId;
|
||||
const plaqueSampleId = plaqueLookup.sampleId;
|
||||
const plaqueKindSource = plaqueLookup.source;
|
||||
const plaqueSampleSource = plaqueLookup.source;
|
||||
if (plaqueLookup.source !== "vehicle-inquiry") {
|
||||
this.logger.log(
|
||||
`[buildFanavaranDamageCasePayload] PlaqueKindId API miss; using config default ${plaqueKindId}`,
|
||||
);
|
||||
}
|
||||
if (plaqueSampleFromApi == null) {
|
||||
this.logger.log(
|
||||
`[buildFanavaranDamageCasePayload] PlaqueSampleId API miss; using config default ${plaqueSampleId}`,
|
||||
`[buildFanavaranDamageCasePayload] PlaqueKindId not on a matched Fanavaran vehicle; using national-plate default ${plaqueKindId}/${plaqueSampleId}`,
|
||||
);
|
||||
}
|
||||
const builtYear =
|
||||
parseFanavaranId(apiVehicle?.BuiltYear) ?? builtYearFromInquiry;
|
||||
|
||||
const carType = input.claimCase?.vehicle?.carType as string | undefined;
|
||||
let vehicleKindId = this.firstPositiveFanavaranId(
|
||||
apiVehicle?.VehicleKindId,
|
||||
canReuseCachedVehicleKind ? cachedDamage.vehicleKindId : null,
|
||||
canReuseCachedVehicleKind ? lastDamagePayload?.VehicleKindId : null,
|
||||
);
|
||||
let vehicleKindId = this.firstPositiveFanavaranId(apiVehicle?.VehicleKindId);
|
||||
let vehicleKindSource: "vehicle-inquiry" | "car-type-lookup" | null =
|
||||
parseFanavaranId(apiVehicle?.VehicleKindId) != null
|
||||
? "vehicle-inquiry"
|
||||
: canReuseCachedVehicleKind
|
||||
? "vehicle-inquiry"
|
||||
: null;
|
||||
: null;
|
||||
if (vehicleKindId == null) {
|
||||
vehicleKindId = await this.resolveVehicleKindId(
|
||||
input.clientKey,
|
||||
@@ -4423,84 +4379,62 @@ export class ClaimRequestManagementService {
|
||||
if (vehicleKindId != null) vehicleKindSource = "car-type-lookup";
|
||||
}
|
||||
|
||||
// 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 driverFanavaranId = await this.resolveDriverFanavaranIdFromBlameCase(
|
||||
input.clientKey,
|
||||
input.blameCase?.parties ?? [],
|
||||
person,
|
||||
input.claimCase,
|
||||
);
|
||||
let otherPersonId = this.firstPositiveFanavaranId(cachedDamage.otherPersonId);
|
||||
|
||||
if (driverFanavaranId) {
|
||||
this.logger.log(
|
||||
`[buildFanavaranDamageCasePayload] Using CACHED DriverId=${driverFanavaranId}`,
|
||||
`[buildFanavaranDamageCasePayload] DriverId=${driverFanavaranId} from live parties inquiry`,
|
||||
);
|
||||
} else {
|
||||
driverFanavaranId = await this.resolveDriverFanavaranIdFromBlameCase(
|
||||
input.clientKey,
|
||||
input.blameCase?.parties ?? [],
|
||||
} else if (otherPersonId) {
|
||||
driverFanavaranId = otherPersonId;
|
||||
this.logger.log(
|
||||
`[buildFanavaranDamageCasePayload] Parties inquiry missed; reusing GEN.44 otherPersonId=${otherPersonId}`,
|
||||
);
|
||||
} else if (input.registerMissingPerson) {
|
||||
const registered = await this.registerFanavaranOtherPerson({
|
||||
clientKey: input.clientKey,
|
||||
person,
|
||||
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(
|
||||
(p: any) => p === damagedParty ||
|
||||
String(p?.person?.userId ?? "") ===
|
||||
String(damagedParty?.person?.userId ?? ""),
|
||||
);
|
||||
if (partyIndex >= 0) {
|
||||
await this.blameRequestDbService.findByIdAndUpdate(
|
||||
String(input.blameCase._id),
|
||||
{ $set: { [`parties.${partyIndex}.person.fanavaranDriverId`]: driverFanavaranId } },
|
||||
);
|
||||
this.logger.log(
|
||||
`[buildFanavaranDamageCasePayload] CACHED DriverId=${driverFanavaranId} on blameCase=${input.blameCase._id} party[${partyIndex}]`,
|
||||
);
|
||||
}
|
||||
claimCaseId: input.claimCase?._id
|
||||
? String(input.claimCase._id)
|
||||
: undefined,
|
||||
});
|
||||
if (registered != null) {
|
||||
driverFanavaranId = registered;
|
||||
otherPersonId = registered;
|
||||
}
|
||||
}
|
||||
|
||||
let insuranceCorpId =
|
||||
cachedDamage.insuranceCorpId != null
|
||||
? Number(cachedDamage.insuranceCorpId)
|
||||
: null;
|
||||
if (insuranceCorpId == null) {
|
||||
insuranceCorpId = await this.fanavaranLookupService.resolveInsuranceCorpId(
|
||||
if (driverFanavaranId && input.blameCase?._id && damagedParty) {
|
||||
const partyIndex = (input.blameCase.parties ?? []).findIndex(
|
||||
(p: any) => p === damagedParty ||
|
||||
String(p?.person?.userId ?? "") ===
|
||||
String(damagedParty?.person?.userId ?? ""),
|
||||
);
|
||||
if (partyIndex >= 0) {
|
||||
await this.blameRequestDbService.findByIdAndUpdate(
|
||||
String(input.blameCase._id),
|
||||
{ $set: { [`parties.${partyIndex}.person.fanavaranDriverId`]: driverFanavaranId } },
|
||||
);
|
||||
this.logger.log(
|
||||
`[buildFanavaranDamageCasePayload] stored DriverId=${driverFanavaranId} on blameCase=${input.blameCase._id} party[${partyIndex}]`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const insuranceCorpId =
|
||||
await this.fanavaranLookupService.resolveInsuranceCorpId(
|
||||
input.clientKey,
|
||||
);
|
||||
}
|
||||
|
||||
const cachedUsedId =
|
||||
cacheMatchesIdentity && cachedDamage.accidentVehicleUsedId != null
|
||||
? Number(cachedDamage.accidentVehicleUsedId)
|
||||
: null;
|
||||
const cachedUsedSource = cachedDamage.accidentVehicleUsedSource;
|
||||
const canReuseApiUsedId =
|
||||
cachedUsedId != null &&
|
||||
cachedUsedId > 0 &&
|
||||
cachedUsedSource === "vehicle-inquiry";
|
||||
let accidentVehicleUsedId: number | null = canReuseApiUsedId
|
||||
? cachedUsedId
|
||||
: null;
|
||||
let accidentVehicleUsedId: number | null = null;
|
||||
let usedSource: "vin-inquiry" | "policy-vehicle" | "vehicle-inquiry" | null =
|
||||
canReuseApiUsedId ? "vehicle-inquiry" : null;
|
||||
null;
|
||||
if (accidentVehicleUsedId == null && apiVehicle) {
|
||||
const fromDamagedVehicle =
|
||||
await this.resolveAccidentVehicleUsedFromVehicleRecord(
|
||||
@@ -4597,10 +4531,7 @@ export class ClaimRequestManagementService {
|
||||
PolicyCINumber: policyCINumber,
|
||||
};
|
||||
|
||||
const persistedPayload = this.keepPreviousPositiveIds(lastDamagePayload, payload, [
|
||||
"DriverId",
|
||||
"InsuranceCorpId",
|
||||
]);
|
||||
const persistedPayload = payload;
|
||||
|
||||
// Persist Fanavaran-sourced IDs + last payload for reuse on later preview/submit
|
||||
if (input.claimCase?._id) {
|
||||
@@ -5502,12 +5433,9 @@ export class ClaimRequestManagementService {
|
||||
/**
|
||||
* Build Fanavaran GEN.03 payload from local claim/blame data.
|
||||
*
|
||||
* Fanavaran-sourced fields (PolicyId) use resolve-once caching:
|
||||
* - If `fanavaranSync.baseClaim.policyId` exists → reuse (no policy HTTP).
|
||||
* - Else → live inquiry-my-policies once, then persist policyId + lastPayload.
|
||||
*
|
||||
* HTTP preview/submit always pass forceRefreshPolicy + forceRefreshUsedId,
|
||||
* so PolicyId and AccidentVehicleUsedId are re-inquired every call.
|
||||
* Auth still uses the shared midnight-TTL token cache (not a new login per preview).
|
||||
* Pass `forceRefreshPolicy: true` to bust the PolicyId cache.
|
||||
*/
|
||||
async previewFanavaranSubmitV2(
|
||||
claimCaseId: string,
|
||||
@@ -5577,7 +5505,7 @@ export class ClaimRequestManagementService {
|
||||
},
|
||||
failureReason: null as string | null,
|
||||
note:
|
||||
"PolicyId is resolve-once: first preview/submit may call Fanavaran policy inquiry; later calls reuse fanavaranSync.baseClaim.policyId. Auth token is shared until Tehran midnight.",
|
||||
"HTTP preview/submit always re-inquire PolicyId and AccidentVehicleUsedId. Auth token is shared until Tehran midnight.",
|
||||
};
|
||||
|
||||
const claimCase = await this.claimCaseDbService.findById(claimCaseId);
|
||||
@@ -5911,6 +5839,21 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
}
|
||||
|
||||
const product = fanavaranClaimProductFromBlameType(blameCase.type);
|
||||
if (!fanavaranHasDamageCaseStage(product)) {
|
||||
return {
|
||||
clientKey,
|
||||
claimCaseId,
|
||||
claimId: claimCase.claimId ?? null,
|
||||
dmgCaseId: claimCase.dmgCaseId ?? null,
|
||||
submitUrl: null,
|
||||
skipped: true,
|
||||
skipReason: FANAVARAN_HULL_NO_DAMAGE_CASE_REASON,
|
||||
warning: FANAVARAN_HULL_NO_DAMAGE_CASE_REASON,
|
||||
payload: null,
|
||||
};
|
||||
}
|
||||
|
||||
const payload = await this.buildFanavaranDamageCasePayload({
|
||||
claimCase,
|
||||
blameCase,
|
||||
@@ -5935,7 +5878,7 @@ export class ClaimRequestManagementService {
|
||||
claimId: claimCase.claimId ?? null,
|
||||
dmgCaseId: claimCase.dmgCaseId ?? null,
|
||||
submitUrl: claimCase.claimId
|
||||
? `${fanavaranClaimsBaseUrl(fanavaranClaimProductFromBlameType(blameCase.type))}/${claimCase.claimId}/dmg-cases`
|
||||
? fanavaranClaimStageUrl(product, "damage-case", claimCase.claimId)
|
||||
: null,
|
||||
warning: warnings.length ? warnings.join(" ") : undefined,
|
||||
payload,
|
||||
@@ -6775,15 +6718,14 @@ export class ClaimRequestManagementService {
|
||||
0,
|
||||
);
|
||||
const submittedAt = reply?.submittedAt ?? new Date();
|
||||
const product = await this.resolveFanavaranClaimProduct(
|
||||
input.claimCase?._id ? String(input.claimCase._id) : undefined,
|
||||
);
|
||||
|
||||
return {
|
||||
replyKey: active?.replyKey,
|
||||
warnings,
|
||||
payload: {
|
||||
const payload: Record<string, unknown> = {
|
||||
ClaimExpertId: claimExpertId,
|
||||
ComponentReplacementCost: componentReplacementCost,
|
||||
DmgAssessmentDate: this.convertToPersianDate(submittedAt),
|
||||
DmgCaseId: input.claimCase.dmgCaseId ?? null,
|
||||
InspectionPlaceId: inspectionPlaceId,
|
||||
InspectionTime: this.getTime24Hour(submittedAt),
|
||||
RepairWage: repairWage,
|
||||
@@ -6795,18 +6737,28 @@ export class ClaimRequestManagementService {
|
||||
DamagedVehicleCurrentPrice:
|
||||
this.parseFanavaranMoney(priceDrop?.carPrice) || null,
|
||||
DmgSections: dmgSections,
|
||||
},
|
||||
};
|
||||
if (fanavaranHasDamageCaseStage(product)) {
|
||||
payload.DmgCaseId = input.claimCase.dmgCaseId ?? null;
|
||||
}
|
||||
|
||||
return {
|
||||
replyKey: active?.replyKey,
|
||||
warnings,
|
||||
payload,
|
||||
};
|
||||
}
|
||||
|
||||
private assertFanavaranExpertisePayloadReady(
|
||||
payload: Record<string, unknown>,
|
||||
warnings: string[],
|
||||
options?: { requireDmgCaseId?: boolean },
|
||||
): void {
|
||||
const sections = Array.isArray(payload.DmgSections)
|
||||
? payload.DmgSections
|
||||
: [];
|
||||
if (!payload.DmgCaseId) warnings.push("DmgCaseId is required.");
|
||||
if (options?.requireDmgCaseId !== false && !payload.DmgCaseId)
|
||||
warnings.push("DmgCaseId is required.");
|
||||
if (!payload.InspectionPlaceId)
|
||||
warnings.push("InspectionPlaceId is required.");
|
||||
if (!payload.DropAmountStatus)
|
||||
@@ -6876,17 +6828,19 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
const claimCase = await this.claimCaseDbService.findById(claimCaseId);
|
||||
if (!claimCase) throw new NotFoundException("Claim case not found");
|
||||
let payload: Record<string, unknown>;
|
||||
if (bodyOverride) {
|
||||
payload = bodyOverride;
|
||||
} else {
|
||||
const built = await this.buildFanavaranExpertisePayload({
|
||||
claimCase,
|
||||
clientKey,
|
||||
});
|
||||
payload = built.payload;
|
||||
this.assertFanavaranExpertisePayloadReady(payload, built.warnings);
|
||||
}
|
||||
const product = await this.resolveFanavaranClaimProduct(claimCaseId);
|
||||
const built = await this.buildFanavaranExpertisePayload({
|
||||
claimCase,
|
||||
clientKey,
|
||||
});
|
||||
const payload = applyFanavaranManualPayloadOverrides(
|
||||
built.payload,
|
||||
bodyOverride,
|
||||
FANAVARAN_EXPERTISE_MANUAL_OVERRIDE_KEYS,
|
||||
);
|
||||
this.assertFanavaranExpertisePayloadReady(payload, built.warnings, {
|
||||
requireDmgCaseId: fanavaranHasDamageCaseStage(product),
|
||||
});
|
||||
return await this.executeFanavaranExpertiseSubmit(
|
||||
claimCaseId,
|
||||
clientKey,
|
||||
@@ -6910,7 +6864,11 @@ export class ClaimRequestManagementService {
|
||||
auditSource: FanavaranAuditSource,
|
||||
): Promise<any> {
|
||||
let claimCase = await this.claimCaseDbService.findById(claimCaseId);
|
||||
if (!claimCase?.claimId || claimCase.dmgCaseId == null) {
|
||||
const product = await this.resolveFanavaranClaimProduct(claimCaseId);
|
||||
if (
|
||||
!claimCase?.claimId ||
|
||||
(fanavaranHasDamageCaseStage(product) && claimCase.dmgCaseId == null)
|
||||
) {
|
||||
await this.ensureFanavaranDamageCase(
|
||||
claimCaseId,
|
||||
clientKey,
|
||||
@@ -7063,7 +7021,8 @@ export class ClaimRequestManagementService {
|
||||
await this.autoSubmitToFanavaranV2OnClaimCreated(claimCaseId);
|
||||
claimCase = await this.claimCaseDbService.findById(claimCaseId);
|
||||
}
|
||||
if (!claimCase?.dmgCaseId) {
|
||||
const product = await this.resolveFanavaranClaimProduct(claimCaseId);
|
||||
if (fanavaranHasDamageCaseStage(product) && !claimCase?.dmgCaseId) {
|
||||
await this.autoSubmitFanavaranDamageCaseOnOuterPartsSelected(
|
||||
claimCaseId,
|
||||
claimCase?.damage?.selectedParts ?? [],
|
||||
@@ -7075,7 +7034,9 @@ export class ClaimRequestManagementService {
|
||||
claimCase,
|
||||
clientKey,
|
||||
});
|
||||
this.assertFanavaranExpertisePayloadReady(payload, warnings);
|
||||
this.assertFanavaranExpertisePayloadReady(payload, warnings, {
|
||||
requireDmgCaseId: fanavaranHasDamageCaseStage(product),
|
||||
});
|
||||
|
||||
const fanavaranResponse = await this.executeFanavaranExpertiseSubmit(
|
||||
claimCaseId,
|
||||
@@ -7245,7 +7206,11 @@ export class ClaimRequestManagementService {
|
||||
clientKey: FanavaranClientKey,
|
||||
auditSource: FanavaranAuditSource,
|
||||
selectedParts?: unknown[],
|
||||
): Promise<{ claimId: number; dmgCaseId: number; created: boolean }> {
|
||||
): Promise<{
|
||||
claimId: number;
|
||||
dmgCaseId: number | null;
|
||||
created: boolean;
|
||||
}> {
|
||||
await this.ensureFanavaranBaseClaim(claimCaseId, clientKey, auditSource);
|
||||
|
||||
const existing = await this.claimCaseDbService.findById(claimCaseId);
|
||||
@@ -7257,6 +7222,20 @@ export class ClaimRequestManagementService {
|
||||
};
|
||||
}
|
||||
|
||||
const product = await this.resolveFanavaranClaimProduct(claimCaseId);
|
||||
if (!fanavaranHasDamageCaseStage(product)) {
|
||||
if (existing?.claimId == null) {
|
||||
throw new BadRequestException(
|
||||
"Fanavaran claimId is required before the next hull stage.",
|
||||
);
|
||||
}
|
||||
return {
|
||||
claimId: Number(existing.claimId),
|
||||
dmgCaseId: null,
|
||||
created: false,
|
||||
};
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
`[Fanavaran ${clientKey}] Soft-ensuring damage case before next stage claimCaseId=${claimCaseId}`,
|
||||
);
|
||||
@@ -7396,7 +7375,7 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
}
|
||||
}
|
||||
if (claimCase.dmgCaseId != null && !bodyOverride) {
|
||||
if (claimCase.dmgCaseId != null) {
|
||||
this.logger.log(
|
||||
`[executeFanavaranDamageCaseSubmit] Already have dmgCaseId=${claimCase.dmgCaseId}; skipping Fanavaran POST`,
|
||||
);
|
||||
@@ -7422,7 +7401,34 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
}
|
||||
|
||||
const payload = bodyOverride ?? await this.buildFanavaranDamageCasePayload({
|
||||
const product = fanavaranClaimProductFromBlameType(blameCase.type);
|
||||
const url = fanavaranClaimStageUrl(
|
||||
product,
|
||||
"damage-case",
|
||||
claimCase.claimId,
|
||||
);
|
||||
if (url == null) {
|
||||
this.logger.log(
|
||||
`[executeFanavaranDamageCaseSubmit] claimCaseId=${claimCaseId} claimId=${claimCase.claimId} skipping hull dmg-cases`,
|
||||
);
|
||||
await this.claimCaseDbService.findByIdAndUpdate(claimCaseId, {
|
||||
$set: {
|
||||
"fanavaranSync.damageCase": {
|
||||
status: "skipped",
|
||||
lastTriedAt: new Date(),
|
||||
lastError: FANAVARAN_HULL_NO_DAMAGE_CASE_REASON,
|
||||
claimId: claimCase.claimId,
|
||||
},
|
||||
},
|
||||
});
|
||||
return {
|
||||
skipped: true,
|
||||
skipReason: FANAVARAN_HULL_NO_DAMAGE_CASE_REASON,
|
||||
claimId: claimCase.claimId,
|
||||
};
|
||||
}
|
||||
|
||||
const builtPayload = await this.buildFanavaranDamageCasePayload({
|
||||
claimCase,
|
||||
blameCase,
|
||||
selectedParts: selectedParts ?? claimCase.damage?.selectedParts ?? [],
|
||||
@@ -7430,11 +7436,15 @@ export class ClaimRequestManagementService {
|
||||
defaults: profile.defaults,
|
||||
registerMissingPerson: true,
|
||||
});
|
||||
const payload = applyFanavaranManualPayloadOverrides(
|
||||
builtPayload,
|
||||
bodyOverride,
|
||||
FANAVARAN_DAMAGE_MANUAL_OVERRIDE_KEYS,
|
||||
);
|
||||
|
||||
// Guardrail: never send empty/null licence fields even if manual overrides arrive.
|
||||
payload.LicenceNo = this.ensureFanavaranNonEmptyLicenceNo(payload.LicenceNo);
|
||||
|
||||
const url = `${fanavaranClaimsBaseUrl(fanavaranClaimProductFromBlameType(blameCase.type))}/${claimCase.claimId}/dmg-cases`;
|
||||
this.logger.log(
|
||||
`[executeFanavaranDamageCaseSubmit] claimCaseId=${claimCaseId} claimId=${claimCase.claimId} payload.DriverId=${payload.DriverId ?? "NULL"} payload keys=${Object.keys(payload).join(", ")}`,
|
||||
);
|
||||
@@ -7583,6 +7593,16 @@ export class ClaimRequestManagementService {
|
||||
clientKey,
|
||||
selectedParts,
|
||||
);
|
||||
if (fanavaranResponse?.skipped) {
|
||||
return {
|
||||
attempted: false,
|
||||
submitted: false,
|
||||
skipped: true,
|
||||
skipReason:
|
||||
fanavaranResponse.skipReason ?? FANAVARAN_HULL_NO_DAMAGE_CASE_REASON,
|
||||
claimId: claimCase.claimId,
|
||||
};
|
||||
}
|
||||
const dmgCaseId = fanavaranResponse?.Id;
|
||||
|
||||
await this.claimCaseDbService.findByIdAndUpdate(claimCaseId, {
|
||||
@@ -8208,7 +8228,7 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
|
||||
const existing = await this.claimCaseDbService.findById(claimCaseId);
|
||||
if (existing?.claimId != null && !bodyOverride) {
|
||||
if (existing?.claimId != null) {
|
||||
this.logger.log(
|
||||
`${logPrefix} Base claim already exists claimId=${existing.claimId}; skipping Fanavaran POST`,
|
||||
);
|
||||
@@ -8227,14 +8247,19 @@ export class ClaimRequestManagementService {
|
||||
claimCaseId,
|
||||
};
|
||||
|
||||
const fanavaranData =
|
||||
bodyOverride ??
|
||||
(await this.previewFanavaranSubmitV2(claimCaseId, clientKey, {
|
||||
const built =
|
||||
await this.previewFanavaranSubmitV2(claimCaseId, clientKey, {
|
||||
requirePolicyId: true,
|
||||
auditSession,
|
||||
persistPayload: true,
|
||||
forceRefreshPolicy: true,
|
||||
forceRefreshUsedId: true,
|
||||
}));
|
||||
});
|
||||
const fanavaranData = applyFanavaranManualPayloadOverrides(
|
||||
built,
|
||||
bodyOverride,
|
||||
FANAVARAN_BASE_MANUAL_OVERRIDE_KEYS,
|
||||
);
|
||||
|
||||
// Guardrail: never send empty/null licence fields even if manual overrides arrive.
|
||||
fanavaranData.CulpritLicenceNo = this.ensureFanavaranNonEmptyLicenceNo(
|
||||
|
||||
Reference in New Issue
Block a user