1
0
forked from Yara724/api

merge upstream

This commit is contained in:
2026-06-27 09:30:55 +03:30
20 changed files with 1186 additions and 169 deletions

View File

@@ -53,10 +53,12 @@ import { ClaimAccessGuard } from "src/auth/guards/claim-access.guard";
import { JwtModule } from "@nestjs/jwt";
import { MediaPolicyModule } from "src/media-policy/media-policy.module";
import { HttpModule } from "@nestjs/axios";
import { FanavaranAuditModule } from "src/fanavaran/fanavaran-audit.module";
@Module({
imports: [
HttpModule,
FanavaranAuditModule,
PublicIdModule,
UsersModule,
RequestManagementModule,

View File

@@ -163,6 +163,19 @@ 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";
import { FanavaranAuditService } from "src/fanavaran/fanavaran-audit.service";
import type { FanavaranAuditSession } from "src/fanavaran/fanavaran-audit.types";
import {
FanavaranAuditSource,
FanavaranAuditStatus,
FanavaranAuditStep,
} from "src/fanavaran/schema/fanavaran-audit-log.schema";
export interface FanavaranAutoSubmitResult {
attempted: boolean;
@@ -175,15 +188,17 @@ export interface FanavaranAutoSubmitResult {
fanavaranResponse?: unknown;
}
const FANAVARAN_ACCIDENT_LOCATION_ADDRESS = "استان تهران شهر تهران";
@Injectable()
export class ClaimRequestManagementService {
private readonly logger = new Logger(ClaimRequestManagementService.name);
// Authentication URLs and credentials (same as lookups service)
private readonly GET_APP_TOKEN_URL =
"https://insapm.ir/bimeapimanager/api/EITAuthentication/GetAppToken";
"https://apimanager.iraneit.com/BimeApiManager/api/EITAuthentication/GetAppToken";
private readonly LOGIN_URL =
"https://insapm.ir/bimeapimanager/api/EITAuthentication/Login";
"https://apimanager.iraneit.com/BimeApiManager/api/EITAuthentication/Login";
private readonly FANAVARAN_SUBMIT_URL =
"https://apimanager.iraneit.com/BimeApiManager/api/BimeApi/v2.0/car/third-party-car-financial-claims";
@@ -253,6 +268,7 @@ export class ClaimRequestManagementService {
private readonly publicIdService: PublicIdService,
private readonly sandHubService: SandHubService,
private readonly httpService: HttpService,
private readonly fanavaranAuditService: FanavaranAuditService,
) {}
private requiredDocumentKeysV2(isCarBody: boolean): string[] {
@@ -3349,9 +3365,15 @@ export class ClaimRequestManagementService {
}
private applyFanavaranDefaultFields(result: Record<string, unknown>): void {
result.ActualPremium = null;
result.ArchiveNo = null;
result.AuthorityCulpritId = null;
result.AccidentCulpritId = null;
result.ClaimCompletionDate = null;
result.CostSeparationToDmgSections = null;
result.CouponNo = null;
result.CourtArchiveNo = null;
result.CustomerFaultPercent = null;
result.CulpritLicenceCityId = null;
result.CulpritLicenceCountryId = null;
result.CulpritLicenceForeignCityName = null;
@@ -3360,11 +3382,14 @@ export class ClaimRequestManagementService {
result.DamagedCount = 1;
result.DmgAssessorFirstCreationTime = null;
result.EntryDate = null;
result.GlassBreakReasonId = null;
result.IsLicenseMatchWithVehicleKind = 1;
result.HasOtherCulprit = 0;
result.IsAccidentOutOfBorder = 0;
result.IsFatalAccident = 0;
result.IsOwnerChanged = null;
result.IsPlaqueChanged = 0;
result.IsSurplusArticleEighthLaw = null;
result.PlaqueCityId = null;
result.PlaqueKindId = null;
result.PlaqueLeftNo = null;
@@ -3379,6 +3404,7 @@ export class ClaimRequestManagementService {
result.PoliceReportSerial = null;
result.PolicyId = null;
result.PreviousPolicyEndDate = "";
result.StatusChangeDate = null;
result.TrackingCode = null;
result.IsLicenseReplacement = 0;
result.UnknownCulpritCauseId = null;
@@ -3425,12 +3451,7 @@ export class ClaimRequestManagementService {
result.AccidentTime = this.getTime24Hour(input.createdAt);
}
if (input.location?.lat && input.location?.lon) {
result.AccidentLocationAddress = await this.getAddressFromCoordinates(
input.location.lat,
input.location.lon,
);
}
result.AccidentLocationAddress = FANAVARAN_ACCIDENT_LOCATION_ADDRESS;
result.EstimateAmount = input.damageParts
? this.calculateEstimateAmount(input.damageParts)
@@ -3589,16 +3610,7 @@ export class ClaimRequestManagementService {
result.AccidentTime = this.getTime24Hour(blameRequest.createdAt);
}
// AccidentLocationAddress: Get from reverse geocoding API
if (
blameRequest.firstPartyLocation?.lat &&
blameRequest.firstPartyLocation?.lon
) {
result.AccidentLocationAddress = await this.getAddressFromCoordinates(
blameRequest.firstPartyLocation.lat,
blameRequest.firstPartyLocation.lon,
);
}
result.AccidentLocationAddress = FANAVARAN_ACCIDENT_LOCATION_ADDRESS;
// EstimateAmount: Sum of totalPayment from damageExpertReply parts
const damageReply =
@@ -3610,39 +3622,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 {
@@ -3676,7 +3656,19 @@ export class ClaimRequestManagementService {
appName: string;
secret: string;
} = this.getTejaratnoFanavaranConfig(),
auditSession?: FanavaranAuditSession,
): Promise<string> {
const startedAt = Date.now();
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.GET_APP_TOKEN,
status: FanavaranAuditStatus.STARTED,
requestUrl: this.GET_APP_TOKEN_URL,
requestMeta: { appName: config.appName },
});
}
try {
const requestHeaders: any = {
appname: config.appName,
@@ -3712,9 +3704,34 @@ export class ClaimRequestManagementService {
);
}
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.GET_APP_TOKEN,
status: FanavaranAuditStatus.SUCCESS,
requestUrl: this.GET_APP_TOKEN_URL,
httpStatus: response.status,
responseMeta: { hasAppToken: true },
durationMs: Date.now() - startedAt,
});
}
this.logger.log(`Successfully obtained appToken`);
return appToken;
} catch (error) {
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.GET_APP_TOKEN,
status: FanavaranAuditStatus.FAILURE,
requestUrl: this.GET_APP_TOKEN_URL,
httpStatus: isAxiosError(error) ? error.response?.status : undefined,
errorMessage: this.fanavaranAuditService.extractErrorMessage(error),
errorDetails: this.fanavaranAuditService.sanitizeErrorDetails(error),
durationMs: Date.now() - startedAt,
});
}
this.logger.error("Failed to get appToken", error);
if (isAxiosError(error)) {
const errorMessage =
@@ -3723,9 +3740,19 @@ export class ClaimRequestManagementService {
error.response?.data ||
error.message ||
"Failed to get appToken from external API";
throw new BadGatewayException(errorMessage);
throw new BadGatewayException(
this.fanavaranAuditService.formatErrorWithTrackingCode(
String(errorMessage),
auditSession?.trackingCode,
),
);
}
throw new BadGatewayException("Failed to get appToken from external API");
throw new BadGatewayException(
this.fanavaranAuditService.formatErrorWithTrackingCode(
"Failed to get appToken from external API",
auditSession?.trackingCode,
),
);
}
}
@@ -3738,7 +3765,19 @@ export class ClaimRequestManagementService {
username: string;
password: string;
} = this.getTejaratnoFanavaranConfig(),
auditSession?: FanavaranAuditSession,
): Promise<string> {
const startedAt = Date.now();
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.LOGIN,
status: FanavaranAuditStatus.STARTED,
requestUrl: this.LOGIN_URL,
requestMeta: { userName: config.username },
});
}
try {
const requestHeaders: any = {
appToken: appToken,
@@ -3763,7 +3802,6 @@ export class ClaimRequestManagementService {
}),
);
// Check response headers first (authenticationToken is in headers)
const authenticationToken =
response.headers.authenticationtoken ||
response.headers.authenticationToken ||
@@ -3780,9 +3818,34 @@ export class ClaimRequestManagementService {
);
}
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.LOGIN,
status: FanavaranAuditStatus.SUCCESS,
requestUrl: this.LOGIN_URL,
httpStatus: response.status,
responseMeta: { hasAuthenticationToken: true },
durationMs: Date.now() - startedAt,
});
}
this.logger.log(`Successfully obtained authenticationToken`);
return authenticationToken;
} catch (error) {
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.LOGIN,
status: FanavaranAuditStatus.FAILURE,
requestUrl: this.LOGIN_URL,
httpStatus: isAxiosError(error) ? error.response?.status : undefined,
errorMessage: this.fanavaranAuditService.extractErrorMessage(error),
errorDetails: this.fanavaranAuditService.sanitizeErrorDetails(error),
durationMs: Date.now() - startedAt,
});
}
this.logger.error("Failed to login", error);
if (isAxiosError(error)) {
const errorMessage =
@@ -3791,9 +3854,19 @@ export class ClaimRequestManagementService {
error.response?.data ||
error.message ||
"Failed to login to external API";
throw new BadGatewayException(errorMessage);
throw new BadGatewayException(
this.fanavaranAuditService.formatErrorWithTrackingCode(
String(errorMessage),
auditSession?.trackingCode,
),
);
}
throw new BadGatewayException("Failed to login to external API");
throw new BadGatewayException(
this.fanavaranAuditService.formatErrorWithTrackingCode(
"Failed to login to external API",
auditSession?.trackingCode,
),
);
}
}
@@ -3809,12 +3882,31 @@ export class ClaimRequestManagementService {
location: string;
},
logPrefix: string,
auditSession?: FanavaranAuditSession,
): Promise<number | null> {
try {
const appToken = await this.getAppToken(config);
const authenticationToken = await this.login(appToken, config);
const policyInquiryUrl = `https://apimanager.iraneit.com/BimeApiManager/api/BimeApi/v2.0/common/Policies/inquiry-my-policies?InsuranceLineId=5&NationalCode=${nationalCodeOfInsurer}`;
const startedAt = Date.now();
const policyInquiryUrl = `https://apimanager.iraneit.com/BimeApiManager/api/BimeApi/v2.0/common/Policies/inquiry-my-policies?InsuranceLineId=5&NationalCode=${nationalCodeOfInsurer}`;
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.POLICY_INQUIRY,
status: FanavaranAuditStatus.STARTED,
requestUrl: policyInquiryUrl,
requestMeta: {
corpId: config.corpId,
contractId: config.contractId,
location: config.location,
nationalCode: this.fanavaranAuditService.maskNationalCode(
nationalCodeOfInsurer,
),
},
});
}
try {
const appToken = await this.getAppToken(config, auditSession);
const authenticationToken = await this.login(appToken, config, auditSession);
this.logger.log(
`${logPrefix} Calling policy inquiry API for nationalCode: ${nationalCodeOfInsurer}`,
@@ -3840,15 +3932,55 @@ export class ClaimRequestManagementService {
this.logger.log(
`${logPrefix} Successfully retrieved PolicyId from last policy entry: ${policyId}`,
);
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.POLICY_INQUIRY,
status: FanavaranAuditStatus.SUCCESS,
requestUrl: policyInquiryUrl,
httpStatus: response.status,
responseMeta: {
policyId,
policyCount: response.data.length,
},
durationMs: Date.now() - startedAt,
});
}
return policyId;
}
}
this.logger.warn(`${logPrefix} No PolicyId found in API response`);
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.POLICY_INQUIRY,
status: FanavaranAuditStatus.SUCCESS,
requestUrl: policyInquiryUrl,
httpStatus: response.status,
responseMeta: {
policyId: null,
policyCount: Array.isArray(response.data) ? response.data.length : 0,
},
durationMs: Date.now() - startedAt,
});
}
return null;
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : "unknown policy inquiry error";
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.POLICY_INQUIRY,
status: FanavaranAuditStatus.FAILURE,
requestUrl: policyInquiryUrl,
httpStatus: isAxiosError(error) ? error.response?.status : undefined,
errorMessage,
errorDetails: this.fanavaranAuditService.sanitizeErrorDetails(error),
durationMs: Date.now() - startedAt,
});
}
this.logger.warn(
`${logPrefix} Policy inquiry failed; continuing with empty PolicyId: ${errorMessage}`,
);
@@ -3964,14 +4096,37 @@ 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,
options?: { debug?: boolean },
clientKey: FanavaranClientKey,
options?: {
debug?: boolean;
auditSession?: FanavaranAuditSession;
},
): Promise<any> {
const profile = getFanavaranClientProfile(clientKey);
const logPrefix = `[Fanavaran ${clientKey} V2] claimCaseId=${claimCaseId}`;
const auditSession =
options?.auditSession ??
({
trackingCode: this.fanavaranAuditService.generateTrackingCode(),
clientKey,
source: FanavaranAuditSource.PREVIEW,
claimCaseId,
} satisfies FanavaranAuditSession);
const buildStartedAt = Date.now();
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.BUILD_PAYLOAD,
status: FanavaranAuditStatus.STARTED,
});
try {
const debug = {
clientKey,
claimCaseId,
steps: {
claimCaseFound: false,
@@ -4022,7 +4177,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 +4207,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,16 +4221,17 @@ export class ClaimRequestManagementService {
debug.values.guiltyPartyId = guiltyPartyId
? guiltyPartyId.toString()
: null;
const nationalCodeOfInsurer = this.getNationalCodeOfInsurerForGuiltyPartyV2(
blameCase.parties ?? [],
guiltyPartyId,
);
const nationalCodeOfInsurer =
this.getNationalCodeOfInsurerForGuiltyPartyV2(
blameCase.parties ?? [],
guiltyPartyId,
);
debug.steps.nationalCodeOfInsurerFound = !!nationalCodeOfInsurer;
debug.values.nationalCodeOfInsurer = nationalCodeOfInsurer;
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 +4239,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 +4249,9 @@ 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,
auditSession,
);
debug.values.policyId = policyId;
debug.steps.policyInquirySucceeded = policyId !== null;
@@ -4108,6 +4266,7 @@ export class ClaimRequestManagementService {
if (options?.debug) {
return {
clientKey,
payload,
debug,
};
@@ -4115,34 +4274,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 +4343,9 @@ export class ClaimRequestManagementService {
};
}
const fanavaranResponse = await this.executeFanavaranParsianV2Submit(
const fanavaranResponse = await this.executeFanavaranV2Submit(
claimCaseId,
clientKey,
);
await this.claimCaseDbService.findByIdAndUpdate(claimCaseId, {
@@ -4177,6 +4355,7 @@ export class ClaimRequestManagementService {
actor: { actorType: "system" },
timestamp: new Date(),
metadata: {
clientKey,
claimNo: fanavaranResponse?.ClaimNo,
claimId: fanavaranResponse?.Id,
},
@@ -4202,7 +4381,7 @@ export class ClaimRequestManagementService {
type: "FANAVARAN_AUTO_SUBMIT_FAILED",
actor: { actorType: "system" },
timestamp: new Date(),
metadata: { error: warning },
metadata: { clientKey, error: warning },
},
},
});
@@ -4216,11 +4395,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 +4433,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 +4465,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 +4509,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 +7624,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) {

View File

@@ -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,
);
}
}