import { Injectable, Logger, ServiceUnavailableException } from '@nestjs/common'; import { generateTrackingCode } from '../common/helpers/tracking-code.helper'; import { SubmitThirdPartyClaimDto } from './dto/submit-third-party-claim.dto'; import { FanavaranApiService } from './fanavaran/fanavaran-api.service'; import { FanavaranAuthService } from './fanavaran/fanavaran-auth.service'; import { FanavaranInsuranceLineId, FanavaranPolicySummary, ThirdPartyCarFinancialClaimPayload, } from './fanavaran/fanavaran.types'; import { ClaimExpertResolverService } from './services/claim-expert-resolver.service'; export interface ThirdPartyClaimSubmitResult { success: boolean; trackingCode: string; message: string; duration: number; data: { policyId: number; claimExpertId: number; policy: FanavaranPolicySummary; fanavaranResponse: unknown; } | null; error: { code: string; message: string } | null; } @Injectable() export class ThirdPartyClaimService { private readonly logger = new Logger(ThirdPartyClaimService.name); constructor( private readonly fanavaranAuthService: FanavaranAuthService, private readonly fanavaranApiService: FanavaranApiService, private readonly claimExpertResolver: ClaimExpertResolverService, ) {} async submit(dto: SubmitThirdPartyClaimDto): Promise { const trackingCode = generateTrackingCode(); const start = Date.now(); if (!this.fanavaranAuthService.isEnabled()) { throw new ServiceUnavailableException('Fanavaran integration is not configured'); } try { const insuranceLineId = dto.insuranceLineId ?? FanavaranInsuranceLineId.THIRD_PARTY; const claimExpertId = await this.claimExpertResolver.resolveClaimExpertId({ claimExpertId: dto.claimExpertId, evaluationRequestId: dto.evaluationRequestId, }); const policy = dto.policyId !== undefined ? ({ PolicyId: dto.policyId } as FanavaranPolicySummary) : await this.fanavaranApiService.inquiryLatestPolicy( dto.nationalCode, insuranceLineId, ); const payload = this.buildClaimPayload(dto, policy.PolicyId, claimExpertId); const fanavaranResponse = await this.fanavaranApiService.submitThirdPartyCarFinancialClaim(payload); const duration = Date.now() - start; this.logger.log( `Third-party claim submitted | trackingCode=${trackingCode} | policyId=${policy.PolicyId} | claimExpertId=${claimExpertId} | durationMs=${duration}`, ); return { success: true, trackingCode, message: 'Third-party claim submitted successfully', duration, data: { policyId: policy.PolicyId, claimExpertId, policy, fanavaranResponse, }, error: null, }; } catch (error) { const duration = Date.now() - start; const message = error instanceof Error ? error.message : 'Third-party claim submission failed'; this.logger.error( `Third-party claim failed | trackingCode=${trackingCode} | durationMs=${duration} | ${message}`, ); return { success: false, trackingCode, message, duration, data: null, error: { code: 'THIRD_PARTY_CLAIM_FAILED', message, }, }; } } private buildClaimPayload( dto: SubmitThirdPartyClaimDto, policyId: number, claimExpertId: number, ): ThirdPartyCarFinancialClaimPayload { return { AccidentCityId: dto.AccidentCityId, AccidentReportTypeId: dto.AccidentReportTypeId, AccidentVehicleUsedId: dto.AccidentVehicleUsedId, ClaimExpertId: claimExpertId, CompensationReferenceId: dto.CompensationReferenceId, CulpritLicenceTypeId: dto.CulpritLicenceTypeId, CulpritTypeId: dto.CulpritTypeId, AccidentCauseId: dto.AccidentCauseId, AccidentDate: dto.AccidentDate, AnnouncementDate: dto.AnnouncementDate, DocReceivedDate: dto.DocReceivedDate, AccidentTime: dto.AccidentTime, AccidentLocationAddress: dto.AccidentLocationAddress, EstimateAmount: dto.EstimateAmount, AccidentCulpritId: dto.AccidentCulpritId ?? null, CouponNo: dto.CouponNo ?? null, CourtArchiveNo: dto.CourtArchiveNo ?? null, CulpritLicenceCityId: dto.CulpritLicenceCityId ?? null, CulpritLicenceCountryId: dto.CulpritLicenceCountryId ?? null, CulpritLicenceForeignCityName: dto.CulpritLicenceForeignCityName ?? null, CulpritLicenceIssuDate: dto.CulpritLicenceIssuDate, CulpritLicenceNo: dto.CulpritLicenceNo, DamagedCount: dto.DamagedCount, DmgAssessorFirstCreationTime: dto.DmgAssessorFirstCreationTime ?? null, EntryDate: dto.EntryDate ?? null, IsLicenseMatchWithVehicleKind: dto.IsLicenseMatchWithVehicleKind, HasOtherCulprit: dto.HasOtherCulprit, IsAccidentOutOfBorder: dto.IsAccidentOutOfBorder, IsFatalAccident: dto.IsFatalAccident, IsPlaqueChanged: dto.IsPlaqueChanged, PlaqueCityId: dto.PlaqueCityId ?? null, PlaqueKindId: dto.PlaqueKindId ?? null, PlaqueLeftNo: dto.PlaqueLeftNo ?? null, PlaqueMiddleCodeId: dto.PlaqueMiddleCodeId ?? null, PlaqueNo: dto.PlaqueNo ?? null, PlaqueRightNo: dto.PlaqueRightNo ?? null, PlaqueSampleId: dto.PlaqueSampleId ?? null, PlaqueSerial: dto.PlaqueSerial ?? null, PoliceOfficerId: dto.PoliceOfficerId, PoliceReportDesc: dto.PoliceReportDesc ?? null, PoliceReportSeri: dto.PoliceReportSeri ?? null, PoliceReportSerial: dto.PoliceReportSerial ?? null, PolicyId: policyId, PreviousPolicyEndDate: dto.PreviousPolicyEndDate ?? '', TrackingCode: dto.TrackingCode ?? null, IsLicenseReplacement: dto.IsLicenseReplacement, UnknownCulpritCauseId: dto.UnknownCulpritCauseId ?? null, }; } }