forked from Yara724/api
Merge pull request 'main' (#150) from s.hajizadeh/yara724api:main into main
Reviewed-on: Yara724/api#150
This commit is contained in:
@@ -10,6 +10,7 @@ import { AuthModule } from "./auth/auth.module";
|
||||
import { ClaimRequestManagementModule } from "./claim-request-management/claim-request-management.module";
|
||||
import { ClientModule } from "./client/client.module";
|
||||
import { ExpertBlameModule } from "./expert-blame/expert-blame.module";
|
||||
import { FanavaranModule } from "./fanavaran/fanavaran.module";
|
||||
import { ExpertClaimModule } from "./expert-claim/expert-claim.module";
|
||||
import { ExpertInsurerModule } from "./expert-insurer/expert-insurer.module";
|
||||
import { LookupsModule } from "./lookups/lookups.module";
|
||||
@@ -49,6 +50,7 @@ import { AppConfigModule } from "./core/config/config.module";
|
||||
SystemSettingsModule,
|
||||
ExpertBlameModule,
|
||||
ClaimRequestManagementModule,
|
||||
FanavaranModule,
|
||||
ExpertClaimModule,
|
||||
AiModule,
|
||||
ReportsModule,
|
||||
|
||||
@@ -163,6 +163,12 @@ import {
|
||||
import { HttpService } from "@nestjs/axios";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { buildEnrichedDamagedParts } from "src/expert-claim/dto/claim-damaged-part.enricher";
|
||||
import {
|
||||
type FanavaranClientKey,
|
||||
fanavaranSubmitPath,
|
||||
getFanavaranClientProfile,
|
||||
resolveFanavaranClientKey,
|
||||
} from "src/core/config/fanavaran-client.config";
|
||||
|
||||
export interface FanavaranAutoSubmitResult {
|
||||
attempted: boolean;
|
||||
@@ -175,6 +181,9 @@ export interface FanavaranAutoSubmitResult {
|
||||
fanavaranResponse?: unknown;
|
||||
}
|
||||
|
||||
/** Placeholder for Fanavaran fields not yet mapped from claim/blame data. */
|
||||
const FANAVARAN_UNMAPPED_FIELD = "empty";
|
||||
|
||||
@Injectable()
|
||||
export class ClaimRequestManagementService {
|
||||
private readonly logger = new Logger(ClaimRequestManagementService.name);
|
||||
@@ -3349,9 +3358,15 @@ export class ClaimRequestManagementService {
|
||||
}
|
||||
|
||||
private applyFanavaranDefaultFields(result: Record<string, unknown>): void {
|
||||
result.ActualPremium = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.ArchiveNo = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.AuthorityCulpritId = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.AccidentCulpritId = null;
|
||||
result.ClaimCompletionDate = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.CostSeparationToDmgSections = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.CouponNo = null;
|
||||
result.CourtArchiveNo = null;
|
||||
result.CustomerFaultPercent = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.CulpritLicenceCityId = null;
|
||||
result.CulpritLicenceCountryId = null;
|
||||
result.CulpritLicenceForeignCityName = null;
|
||||
@@ -3360,11 +3375,14 @@ export class ClaimRequestManagementService {
|
||||
result.DamagedCount = 1;
|
||||
result.DmgAssessorFirstCreationTime = null;
|
||||
result.EntryDate = null;
|
||||
result.GlassBreakReasonId = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.IsLicenseMatchWithVehicleKind = 1;
|
||||
result.HasOtherCulprit = 0;
|
||||
result.IsAccidentOutOfBorder = 0;
|
||||
result.IsFatalAccident = 0;
|
||||
result.IsOwnerChanged = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.IsPlaqueChanged = 0;
|
||||
result.IsSurplusArticleEighthLaw = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.PlaqueCityId = null;
|
||||
result.PlaqueKindId = null;
|
||||
result.PlaqueLeftNo = null;
|
||||
@@ -3379,6 +3397,7 @@ export class ClaimRequestManagementService {
|
||||
result.PoliceReportSerial = null;
|
||||
result.PolicyId = null;
|
||||
result.PreviousPolicyEndDate = "";
|
||||
result.StatusChangeDate = FANAVARAN_UNMAPPED_FIELD;
|
||||
result.TrackingCode = null;
|
||||
result.IsLicenseReplacement = 0;
|
||||
result.UnknownCulpritCauseId = null;
|
||||
@@ -3610,39 +3629,7 @@ export class ClaimRequestManagementService {
|
||||
}
|
||||
|
||||
// Keep other fields from template with default values
|
||||
result.AccidentCulpritId = null; //todo
|
||||
result.CouponNo = null;
|
||||
result.CourtArchiveNo = null;
|
||||
result.CulpritLicenceCityId = null;
|
||||
result.CulpritLicenceCountryId = null;
|
||||
result.CulpritLicenceForeignCityName = null;
|
||||
result.CulpritLicenceIssuDate = "1394/10/13"; //todo
|
||||
result.CulpritLicenceNo = "1124242";
|
||||
result.DamagedCount = 1;
|
||||
result.DmgAssessorFirstCreationTime = null;
|
||||
result.EntryDate = null;
|
||||
result.IsLicenseMatchWithVehicleKind = 1;
|
||||
result.HasOtherCulprit = 0;
|
||||
result.IsAccidentOutOfBorder = 0;
|
||||
result.IsFatalAccident = 0;
|
||||
result.IsPlaqueChanged = 0;
|
||||
result.PlaqueCityId = null;
|
||||
result.PlaqueKindId = null;
|
||||
result.PlaqueLeftNo = null;
|
||||
result.PlaqueMiddleCodeId = null;
|
||||
result.PlaqueNo = null;
|
||||
result.PlaqueRightNo = null;
|
||||
result.PlaqueSampleId = null;
|
||||
result.PlaqueSerial = null;
|
||||
result.PoliceOfficerId = 1;
|
||||
result.PoliceReportDesc = null;
|
||||
result.PoliceReportSeri = null;
|
||||
result.PoliceReportSerial = null;
|
||||
result.PolicyId = null;
|
||||
result.PreviousPolicyEndDate = "";
|
||||
result.TrackingCode = null;
|
||||
result.IsLicenseReplacement = 0;
|
||||
result.UnknownCulpritCauseId = null;
|
||||
this.applyFanavaranDefaultFields(result);
|
||||
|
||||
// Get PolicyId from external API
|
||||
try {
|
||||
@@ -3964,14 +3951,19 @@ export class ClaimRequestManagementService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fanavaran Submit (Parsian / V2) - Map data from claimCases + blameCases
|
||||
* Preview Fanavaran submit body (V2 claimCases + blameCases) for a specific client.
|
||||
*/
|
||||
async fanavaranSubmitParsianV2(
|
||||
async previewFanavaranSubmitV2(
|
||||
claimCaseId: string,
|
||||
clientKey: FanavaranClientKey,
|
||||
options?: { debug?: boolean },
|
||||
): Promise<any> {
|
||||
const profile = getFanavaranClientProfile(clientKey);
|
||||
const logPrefix = `[Fanavaran ${clientKey} V2] claimCaseId=${claimCaseId}`;
|
||||
|
||||
try {
|
||||
const debug = {
|
||||
clientKey,
|
||||
claimCaseId,
|
||||
steps: {
|
||||
claimCaseFound: false,
|
||||
@@ -4022,7 +4014,8 @@ export class ClaimRequestManagementService {
|
||||
|
||||
const expertDecision = blameCase.expert?.decision;
|
||||
debug.steps.expertDecisionFound = !!expertDecision;
|
||||
const fallbackAccidentReason = claimCase.snapshot?.accident?.classification?.accidentReason;
|
||||
const fallbackAccidentReason =
|
||||
claimCase.snapshot?.accident?.classification?.accidentReason;
|
||||
if (!expertDecision?.fields?.accidentReason && fallbackAccidentReason) {
|
||||
debug.steps.accidentReasonFallbackFromSnapshot = true;
|
||||
}
|
||||
@@ -4051,8 +4044,8 @@ export class ClaimRequestManagementService {
|
||||
createdAt: (blameCase as { createdAt?: Date }).createdAt,
|
||||
location: firstParty?.location,
|
||||
damageParts,
|
||||
defaults: this.PARSIAN_FANAVARAN_DEFAULTS,
|
||||
logPrefix: `[Fanavaran Parsian V2] claimCaseId=${claimCaseId}`,
|
||||
defaults: profile.defaults,
|
||||
logPrefix,
|
||||
resolvePolicyId: async () => {
|
||||
const guiltyPartyId = this.resolveGuiltyPartyIdV2(
|
||||
blameCase.parties ?? [],
|
||||
@@ -4065,7 +4058,8 @@ export class ClaimRequestManagementService {
|
||||
debug.values.guiltyPartyId = guiltyPartyId
|
||||
? guiltyPartyId.toString()
|
||||
: null;
|
||||
const nationalCodeOfInsurer = this.getNationalCodeOfInsurerForGuiltyPartyV2(
|
||||
const nationalCodeOfInsurer =
|
||||
this.getNationalCodeOfInsurerForGuiltyPartyV2(
|
||||
blameCase.parties ?? [],
|
||||
guiltyPartyId,
|
||||
);
|
||||
@@ -4074,7 +4068,7 @@ export class ClaimRequestManagementService {
|
||||
|
||||
if (!guiltyPartyId) {
|
||||
this.logger.warn(
|
||||
`[Fanavaran Parsian V2] guiltyPartyId not found in expert.decision`,
|
||||
`${logPrefix} guiltyPartyId not found in expert.decision`,
|
||||
);
|
||||
debug.failureReason = "expert.decision.guiltyPartyId is missing";
|
||||
return null;
|
||||
@@ -4082,7 +4076,7 @@ export class ClaimRequestManagementService {
|
||||
|
||||
if (!nationalCodeOfInsurer) {
|
||||
this.logger.warn(
|
||||
`[Fanavaran Parsian V2] nationalCodeOfInsurer not found for guiltyPartyId: ${guiltyPartyId}`,
|
||||
`${logPrefix} nationalCodeOfInsurer not found for guiltyPartyId: ${guiltyPartyId}`,
|
||||
);
|
||||
debug.failureReason =
|
||||
"nationalCodeOfInsurer not found for guilty party in blameCase.parties";
|
||||
@@ -4092,8 +4086,8 @@ export class ClaimRequestManagementService {
|
||||
debug.steps.policyInquiryAttempted = true;
|
||||
const policyId = await this.getPolicyIdFromNationalCode(
|
||||
nationalCodeOfInsurer,
|
||||
this.PARSIAN_FANAVARAN_CONFIG,
|
||||
`[Fanavaran Parsian V2] claimCaseId=${claimCaseId}`,
|
||||
profile.auth,
|
||||
logPrefix,
|
||||
);
|
||||
debug.values.policyId = policyId;
|
||||
debug.steps.policyInquirySucceeded = policyId !== null;
|
||||
@@ -4108,6 +4102,7 @@ export class ClaimRequestManagementService {
|
||||
|
||||
if (options?.debug) {
|
||||
return {
|
||||
clientKey,
|
||||
payload,
|
||||
debug,
|
||||
};
|
||||
@@ -4115,34 +4110,52 @@ export class ClaimRequestManagementService {
|
||||
|
||||
return payload;
|
||||
} catch (error) {
|
||||
this.logger.error("Error in fanavaranSubmitParsianV2", error);
|
||||
this.logger.error(`Error in previewFanavaranSubmitV2 (${clientKey})`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated Use previewFanavaranSubmitV2(claimCaseId, "parsian", options) */
|
||||
async fanavaranSubmitParsianV2(
|
||||
claimCaseId: string,
|
||||
options?: { debug?: boolean },
|
||||
): Promise<any> {
|
||||
return this.previewFanavaranSubmitV2(claimCaseId, "parsian", options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit Parsian fanavaran data (V2 collections) to external API
|
||||
* Submit Fanavaran data (V2 claimCases + blameCases) for a specific client.
|
||||
*/
|
||||
async submitToFanavaranParsianV2(claimCaseId: string): Promise<any> {
|
||||
async submitFanavaranV2(
|
||||
claimCaseId: string,
|
||||
clientKey: FanavaranClientKey,
|
||||
): Promise<any> {
|
||||
try {
|
||||
return await this.executeFanavaranParsianV2Submit(claimCaseId);
|
||||
return await this.executeFanavaranV2Submit(claimCaseId, clientKey);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`[Fanavaran Parsian V2] Error submitting to Fanavaran`,
|
||||
`[Fanavaran ${clientKey} V2] Error submitting to Fanavaran`,
|
||||
error,
|
||||
);
|
||||
throw new BadGatewayException(this.extractFanavaranErrorMessage(error));
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated Use submitFanavaranV2(claimCaseId, "parsian") */
|
||||
async submitToFanavaranParsianV2(claimCaseId: string): Promise<any> {
|
||||
return this.submitFanavaranV2(claimCaseId, "parsian");
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-submit to Fanavaran when a claim case reaches COMPLETED.
|
||||
* Uses FANAVARAN_CLIENT env (or CLIENT_ID fallback) to pick the tenant.
|
||||
* Never throws — failures are returned as warnings so the main flow continues.
|
||||
*/
|
||||
async autoSubmitToFanavaranParsianV2OnClaimCompleted(
|
||||
async autoSubmitToFanavaranV2OnClaimCompleted(
|
||||
claimCaseId: string,
|
||||
): Promise<FanavaranAutoSubmitResult> {
|
||||
const logPrefix = `[Fanavaran Parsian V2 Auto] claimCaseId=${claimCaseId}`;
|
||||
const clientKey = resolveFanavaranClientKey();
|
||||
const logPrefix = `[Fanavaran ${clientKey} V2 Auto] claimCaseId=${claimCaseId}`;
|
||||
|
||||
try {
|
||||
const claimCase = await this.claimCaseDbService.findById(claimCaseId);
|
||||
@@ -4166,8 +4179,9 @@ export class ClaimRequestManagementService {
|
||||
};
|
||||
}
|
||||
|
||||
const fanavaranResponse = await this.executeFanavaranParsianV2Submit(
|
||||
const fanavaranResponse = await this.executeFanavaranV2Submit(
|
||||
claimCaseId,
|
||||
clientKey,
|
||||
);
|
||||
|
||||
await this.claimCaseDbService.findByIdAndUpdate(claimCaseId, {
|
||||
@@ -4177,6 +4191,7 @@ export class ClaimRequestManagementService {
|
||||
actor: { actorType: "system" },
|
||||
timestamp: new Date(),
|
||||
metadata: {
|
||||
clientKey,
|
||||
claimNo: fanavaranResponse?.ClaimNo,
|
||||
claimId: fanavaranResponse?.Id,
|
||||
},
|
||||
@@ -4202,7 +4217,7 @@ export class ClaimRequestManagementService {
|
||||
type: "FANAVARAN_AUTO_SUBMIT_FAILED",
|
||||
actor: { actorType: "system" },
|
||||
timestamp: new Date(),
|
||||
metadata: { error: warning },
|
||||
metadata: { clientKey, error: warning },
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -4216,11 +4231,18 @@ export class ClaimRequestManagementService {
|
||||
return {
|
||||
attempted: true,
|
||||
submitted: false,
|
||||
warning: `${warning} Case was not sent to Fanavaran. Retry manually via POST /v2/claim-request-management/fanavaran-submit/parsian/${claimCaseId}.`,
|
||||
warning: `${warning} Case was not sent to Fanavaran. Retry manually via POST ${fanavaranSubmitPath(clientKey, claimCaseId)}.`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated Use autoSubmitToFanavaranV2OnClaimCompleted */
|
||||
async autoSubmitToFanavaranParsianV2OnClaimCompleted(
|
||||
claimCaseId: string,
|
||||
): Promise<FanavaranAutoSubmitResult> {
|
||||
return this.autoSubmitToFanavaranV2OnClaimCompleted(claimCaseId);
|
||||
}
|
||||
|
||||
private extractFanavaranErrorMessage(error: unknown): string {
|
||||
if (isAxiosError(error)) {
|
||||
return (
|
||||
@@ -4247,16 +4269,20 @@ export class ClaimRequestManagementService {
|
||||
return "Failed to submit data to Fanavaran API";
|
||||
}
|
||||
|
||||
private async executeFanavaranParsianV2Submit(
|
||||
private async executeFanavaranV2Submit(
|
||||
claimCaseId: string,
|
||||
clientKey: FanavaranClientKey,
|
||||
): Promise<any> {
|
||||
const config = this.PARSIAN_FANAVARAN_CONFIG;
|
||||
const logPrefix = `[Fanavaran Parsian V2]`;
|
||||
const profile = getFanavaranClientProfile(clientKey);
|
||||
const logPrefix = `[Fanavaran ${clientKey} V2]`;
|
||||
|
||||
this.logger.log(
|
||||
`${logPrefix} Starting submission for claimCaseId: ${claimCaseId}`,
|
||||
);
|
||||
const fanavaranData = await this.fanavaranSubmitParsianV2(claimCaseId);
|
||||
const fanavaranData = await this.previewFanavaranSubmitV2(
|
||||
claimCaseId,
|
||||
clientKey,
|
||||
);
|
||||
this.logger.log(
|
||||
`${logPrefix} Mapped data prepared:`,
|
||||
JSON.stringify(fanavaranData, null, 2),
|
||||
@@ -4275,16 +4301,16 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
}
|
||||
|
||||
const appToken = await this.getAppToken(config);
|
||||
const authenticationToken = await this.login(appToken, config);
|
||||
const appToken = await this.getAppToken(profile.auth);
|
||||
const authenticationToken = await this.login(appToken, profile.auth);
|
||||
|
||||
const response = await firstValueFrom(
|
||||
this.httpService.post(this.FANAVARAN_SUBMIT_URL, fanavaranData, {
|
||||
headers: {
|
||||
authenticationToken: authenticationToken,
|
||||
CorpId: config.corpId,
|
||||
ContractId: config.contractId,
|
||||
Location: config.location,
|
||||
CorpId: profile.auth.corpId,
|
||||
ContractId: profile.auth.contractId,
|
||||
Location: profile.auth.location,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}),
|
||||
@@ -4319,6 +4345,13 @@ export class ClaimRequestManagementService {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/** @deprecated Use executeFanavaranV2Submit(claimCaseId, "parsian") */
|
||||
private async executeFanavaranParsianV2Submit(
|
||||
claimCaseId: string,
|
||||
): Promise<any> {
|
||||
return this.executeFanavaranV2Submit(claimCaseId, "parsian");
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit fanavaran data to external API
|
||||
*/
|
||||
@@ -7427,7 +7460,7 @@ export class ClaimRequestManagementService {
|
||||
});
|
||||
|
||||
const fanavaran =
|
||||
await this.autoSubmitToFanavaranParsianV2OnClaimCompleted(claimRequestId);
|
||||
await this.autoSubmitToFanavaranV2OnClaimCompleted(claimRequestId);
|
||||
|
||||
let message = "Your signature has been recorded. The claim is completed.";
|
||||
if (fanavaran.submitted) {
|
||||
|
||||
@@ -1030,43 +1030,4 @@ Returns status of each item (uploaded/captured or not).
|
||||
}
|
||||
}
|
||||
|
||||
@Get("fanavaran-submit/parsian/:claimCaseId")
|
||||
@ApiOperation({
|
||||
summary: "Preview Fanavaran submit body (Parsian / V2)",
|
||||
description:
|
||||
"Builds the third-party-car-financial-claims payload from claimCases + blameCases without calling Fanavaran.",
|
||||
})
|
||||
@ApiParam({
|
||||
name: "claimCaseId",
|
||||
description: "The claim case ID (MongoDB ObjectId)",
|
||||
})
|
||||
async fanavaranSubmitParsianV2(
|
||||
@Param("claimCaseId") claimCaseId: string,
|
||||
@Query("debug") debug?: string,
|
||||
) {
|
||||
return await this.claimRequestManagementService.fanavaranSubmitParsianV2(
|
||||
claimCaseId,
|
||||
{
|
||||
debug: debug === "1" || debug === "true",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@Post("fanavaran-submit/parsian/:claimCaseId")
|
||||
@ApiOperation({
|
||||
summary: "Submit claim to Fanavaran (Parsian / V2)",
|
||||
description:
|
||||
"Authenticates with Parsian Fanavaran credentials and submits the mapped claimCases + blameCases payload.",
|
||||
})
|
||||
@ApiParam({
|
||||
name: "claimCaseId",
|
||||
description: "The claim case ID (MongoDB ObjectId)",
|
||||
})
|
||||
async submitToFanavaranParsianV2(
|
||||
@Param("claimCaseId") claimCaseId: string,
|
||||
) {
|
||||
return await this.claimRequestManagementService.submitToFanavaranParsianV2(
|
||||
claimCaseId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
export type FanavaranClientKey = "parsian" | "tejaratno";
|
||||
|
||||
export const FANAVARAN_CLIENT_KEYS: readonly FanavaranClientKey[] = [
|
||||
"parsian",
|
||||
"tejaratno",
|
||||
] as const;
|
||||
|
||||
export function isFanavaranClientKey(value: string): value is FanavaranClientKey {
|
||||
const normalized = value?.trim().toLowerCase();
|
||||
return normalized === "parsian" || normalized === "tejaratno";
|
||||
}
|
||||
|
||||
export function normalizeFanavaranClientKey(value: string): FanavaranClientKey {
|
||||
const normalized = value?.trim().toLowerCase();
|
||||
if (normalized === "parsian" || normalized === "tejaratno") {
|
||||
return normalized;
|
||||
}
|
||||
throw new Error(
|
||||
`Invalid Fanavaran client "${value}". Expected one of: ${FANAVARAN_CLIENT_KEYS.join(", ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
export interface FanavaranAuthConfig {
|
||||
appName: string;
|
||||
secret: string;
|
||||
@@ -93,6 +113,30 @@ export function resolveFanavaranClientProfile(): FanavaranClientProfile {
|
||||
return FANAVARAN_CLIENT_PROFILES[resolveFanavaranClientKey()];
|
||||
}
|
||||
|
||||
export function fanavaranManualSubmitPath(claimCaseId: string): string {
|
||||
return `/v2/claim-request-management/fanavaran-submit/${claimCaseId}`;
|
||||
export function getFanavaranClientProfile(
|
||||
clientKey: FanavaranClientKey,
|
||||
): FanavaranClientProfile {
|
||||
return FANAVARAN_CLIENT_PROFILES[clientKey];
|
||||
}
|
||||
|
||||
export function listFanavaranClientProfiles(): FanavaranClientProfile[] {
|
||||
return FANAVARAN_CLIENT_KEYS.map((key) => FANAVARAN_CLIENT_PROFILES[key]);
|
||||
}
|
||||
|
||||
export function fanavaranPreviewPath(
|
||||
clientKey: FanavaranClientKey,
|
||||
claimCaseId: string,
|
||||
): string {
|
||||
return `/v2/fanavaran/${clientKey}/claim-cases/${claimCaseId}`;
|
||||
}
|
||||
|
||||
export function fanavaranSubmitPath(
|
||||
clientKey: FanavaranClientKey,
|
||||
claimCaseId: string,
|
||||
): string {
|
||||
return `/v2/fanavaran/${clientKey}/claim-cases/${claimCaseId}`;
|
||||
}
|
||||
|
||||
export function fanavaranManualSubmitPath(claimCaseId: string): string {
|
||||
return fanavaranSubmitPath(resolveFanavaranClientKey(), claimCaseId);
|
||||
}
|
||||
|
||||
@@ -2364,7 +2364,7 @@ export class ExpertClaimService {
|
||||
{ replyField },
|
||||
);
|
||||
const fanavaran =
|
||||
await this.claimRequestManagementService.autoSubmitToFanavaranParsianV2OnClaimCompleted(
|
||||
await this.claimRequestManagementService.autoSubmitToFanavaranV2OnClaimCompleted(
|
||||
claimRequestId,
|
||||
);
|
||||
return {
|
||||
@@ -2390,7 +2390,7 @@ export class ExpertClaimService {
|
||||
);
|
||||
|
||||
const fanavaran =
|
||||
await this.claimRequestManagementService.autoSubmitToFanavaranParsianV2OnClaimCompleted(
|
||||
await this.claimRequestManagementService.autoSubmitToFanavaranV2OnClaimCompleted(
|
||||
claimRequestId,
|
||||
);
|
||||
|
||||
|
||||
124
src/fanavaran/fanavaran.controller.ts
Normal file
124
src/fanavaran/fanavaran.controller.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import {
|
||||
BadRequestException,
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
Post,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from "@nestjs/common";
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
ApiOperation,
|
||||
ApiParam,
|
||||
ApiQuery,
|
||||
ApiTags,
|
||||
} from "@nestjs/swagger";
|
||||
import { LocalActorAuthGuard } from "src/auth/guards/actor-local.guard";
|
||||
import { RolesGuard } from "src/auth/guards/role.guard";
|
||||
import { Roles } from "src/decorators/roles.decorator";
|
||||
import { RoleEnum } from "src/Types&Enums/role.enum";
|
||||
import { ClaimRequestManagementService } from "src/claim-request-management/claim-request-management.service";
|
||||
import {
|
||||
isFanavaranClientKey,
|
||||
listFanavaranClientProfiles,
|
||||
normalizeFanavaranClientKey,
|
||||
resolveFanavaranClientKey,
|
||||
} from "src/core/config/fanavaran-client.config";
|
||||
|
||||
@ApiTags("fanavaran")
|
||||
@Controller("v2/fanavaran")
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(LocalActorAuthGuard, RolesGuard)
|
||||
@Roles(RoleEnum.ADMIN, RoleEnum.FIELD_EXPERT)
|
||||
export class FanavaranController {
|
||||
constructor(
|
||||
private readonly claimRequestManagementService: ClaimRequestManagementService,
|
||||
) {}
|
||||
|
||||
@Get("clients")
|
||||
@ApiOperation({
|
||||
summary: "List supported Fanavaran insurance clients",
|
||||
description:
|
||||
"Returns configured Fanavaran tenants (parsian, tejaratno) and which client is active for this deployment.",
|
||||
})
|
||||
listClients() {
|
||||
const activeClient = resolveFanavaranClientKey();
|
||||
return {
|
||||
activeClient,
|
||||
clients: listFanavaranClientProfiles().map((profile) => ({
|
||||
key: profile.key,
|
||||
defaults: profile.defaults,
|
||||
isActive: profile.key === activeClient,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
@Get(":client/claim-cases/:claimCaseId")
|
||||
@ApiOperation({
|
||||
summary: "Preview Fanavaran submit payload (V2)",
|
||||
description:
|
||||
"Builds the third-party-car-financial-claims body from claimCases + blameCases without calling Fanavaran.",
|
||||
})
|
||||
@ApiParam({
|
||||
name: "client",
|
||||
description: "Fanavaran tenant key",
|
||||
enum: ["parsian", "tejaratno"],
|
||||
})
|
||||
@ApiParam({
|
||||
name: "claimCaseId",
|
||||
description: "Claim case MongoDB ObjectId",
|
||||
})
|
||||
@ApiQuery({
|
||||
name: "debug",
|
||||
required: false,
|
||||
description: "When true, returns payload plus mapping debug steps",
|
||||
})
|
||||
async preview(
|
||||
@Param("client") client: string,
|
||||
@Param("claimCaseId") claimCaseId: string,
|
||||
@Query("debug") debug?: string,
|
||||
) {
|
||||
const clientKey = this.parseClientParam(client);
|
||||
return await this.claimRequestManagementService.previewFanavaranSubmitV2(
|
||||
claimCaseId,
|
||||
clientKey,
|
||||
{ debug: debug === "1" || debug === "true" },
|
||||
);
|
||||
}
|
||||
|
||||
@Post(":client/claim-cases/:claimCaseId")
|
||||
@ApiOperation({
|
||||
summary: "Submit claim to Fanavaran (V2)",
|
||||
description:
|
||||
"Authenticates with the selected client credentials and submits the mapped claimCases + blameCases payload.",
|
||||
})
|
||||
@ApiParam({
|
||||
name: "client",
|
||||
description: "Fanavaran tenant key",
|
||||
enum: ["parsian", "tejaratno"],
|
||||
})
|
||||
@ApiParam({
|
||||
name: "claimCaseId",
|
||||
description: "Claim case MongoDB ObjectId",
|
||||
})
|
||||
async submit(
|
||||
@Param("client") client: string,
|
||||
@Param("claimCaseId") claimCaseId: string,
|
||||
) {
|
||||
const clientKey = this.parseClientParam(client);
|
||||
return await this.claimRequestManagementService.submitFanavaranV2(
|
||||
claimCaseId,
|
||||
clientKey,
|
||||
);
|
||||
}
|
||||
|
||||
private parseClientParam(client: string) {
|
||||
if (!isFanavaranClientKey(client)) {
|
||||
throw new BadRequestException(
|
||||
`Invalid Fanavaran client "${client}". Expected one of: parsian, tejaratno`,
|
||||
);
|
||||
}
|
||||
return normalizeFanavaranClientKey(client);
|
||||
}
|
||||
}
|
||||
9
src/fanavaran/fanavaran.module.ts
Normal file
9
src/fanavaran/fanavaran.module.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { ClaimRequestManagementModule } from "src/claim-request-management/claim-request-management.module";
|
||||
import { FanavaranController } from "./fanavaran.controller";
|
||||
|
||||
@Module({
|
||||
imports: [ClaimRequestManagementModule],
|
||||
controllers: [FanavaranController],
|
||||
})
|
||||
export class FanavaranModule {}
|
||||
Reference in New Issue
Block a user