From d4cd8c93435dceb89bfc94ff4f808eeaa055b8fd Mon Sep 17 00:00:00 2001 From: SepehrYahyaee <7heycallmegray@gmail.com> Date: Sun, 9 Aug 2026 11:03:16 +0330 Subject: [PATCH] YARA-1217 --- .../required-document-type.enum.ts | 2 + .../claim-request-management.service.ts | 73 ++++++++++++++++++- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/Types&Enums/claim-request-management/required-document-type.enum.ts b/src/Types&Enums/claim-request-management/required-document-type.enum.ts index 5f6312e..d046463 100644 --- a/src/Types&Enums/claim-request-management/required-document-type.enum.ts +++ b/src/Types&Enums/claim-request-management/required-document-type.enum.ts @@ -20,6 +20,8 @@ export enum ClaimRequiredDocumentType { GUILTY_CAR_CARD_FRONT = "guilty_car_card_front", GUILTY_CAR_CARD_BACK = "guilty_car_card_back", GUILTY_METAL_PLATE = "guilty_metal_plate", + /** V4 FileMaker flow only: one photo of the guilty party's car. */ + GUILTY_CAR_PHOTO = "guilty_car_photo", } export enum CarAngle { diff --git a/src/claim-request-management/claim-request-management.service.ts b/src/claim-request-management/claim-request-management.service.ts index db11302..0a1f600 100644 --- a/src/claim-request-management/claim-request-management.service.ts +++ b/src/claim-request-management/claim-request-management.service.ts @@ -460,6 +460,7 @@ export class ClaimRequestManagementService { isCarBody: boolean, assumeUploadedKey?: string, skipMetalPlate?: boolean, + requiresGuiltyCarPhoto?: boolean, ): boolean { for (const k of this.v3PreCaptureDocumentKeys(isCarBody)) { if (skipMetalPlate && OPTIONAL_CAPTURE_PHASE_DOC_KEYS_V4V5.includes(k as any)) continue; @@ -477,6 +478,15 @@ export class ClaimRequestManagementService { : this.isRequiredDocumentUploadedOnClaim(claimCase, g); if (!ok) return false; } + // V4 THIRD_PARTY only: require one photo of the guilty party's car. + if (requiresGuiltyCarPhoto && !isCarBody) { + const k = ClaimRequiredDocumentType.GUILTY_CAR_PHOTO; + const ok = + k === assumeUploadedKey + ? true + : this.isRequiredDocumentUploadedOnClaim(claimCase, k); + if (!ok) return false; + } return true; } @@ -485,6 +495,7 @@ export class ClaimRequestManagementService { isCarBody: boolean, assumeUploadedKey?: string, skipMetalPlate?: boolean, + requiresGuiltyCarPhoto?: boolean, ): number { let n = 0; for (const k of this.v3PreCaptureDocumentKeys(isCarBody)) { @@ -503,6 +514,15 @@ export class ClaimRequestManagementService { : this.isRequiredDocumentUploadedOnClaim(claimCase, g); if (!ok) n++; } + // V4 THIRD_PARTY only: one photo of the guilty party's car. + if (requiresGuiltyCarPhoto && !isCarBody) { + const k = ClaimRequiredDocumentType.GUILTY_CAR_PHOTO; + const ok = + k === assumeUploadedKey + ? true + : this.isRequiredDocumentUploadedOnClaim(claimCase, k); + if (!ok) n++; + } return n; } @@ -9073,7 +9093,7 @@ export class ClaimRequestManagementService { file: Express.Multer.File, currentUserId: string, actor?: { sub: string; role?: string }, - options?: { v3InPersonFlow?: boolean; skipMetalPlate?: boolean; requiresFileMakerApproval?: boolean }, + options?: { v3InPersonFlow?: boolean; skipMetalPlate?: boolean; requiresFileMakerApproval?: boolean; requiresGuiltyCarPhoto?: boolean }, ): Promise { try { const claimCase = await this.claimCaseDbService.findById(claimRequestId); @@ -9306,6 +9326,7 @@ export class ClaimRequestManagementService { isCarBodyUpload, body.documentKey, options?.skipMetalPlate, + options?.requiresGuiltyCarPhoto, ); allDocumentsUploaded = options?.v3InPersonFlow @@ -9321,6 +9342,7 @@ export class ClaimRequestManagementService { isCarBodyUpload, body.documentKey, options?.skipMetalPlate, + options?.requiresGuiltyCarPhoto, ) : this.countRemainingV2OwnerDocuments( claimCase, @@ -9417,10 +9439,14 @@ export class ClaimRequestManagementService { : null; const isCarBodyRecheck = blameForRecheck?.type === BlameRequestType.CAR_BODY; const skipMetalPlateRecheck = !!(blameForRecheck as any)?.isMadeByFileMaker; + // V4 = isMadeByFileMaker + requiresFileMakerApproval is false on the claim. + const requiresGuiltyCarPhotoRecheck = + !!(blameForRecheck as any)?.isMadeByFileMaker && + !(afterWrite as any).requiresFileMakerApproval; const allDoneNow = afterWrite.status === ClaimCaseStatus.UPLOADING_REQUIRED_DOCUMENTS && afterWrite.workflow?.currentStep === ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS && - this.allV3PreCaptureDocumentsComplete(afterWrite, isCarBodyRecheck, undefined, skipMetalPlateRecheck); + this.allV3PreCaptureDocumentsComplete(afterWrite, isCarBodyRecheck, undefined, skipMetalPlateRecheck, requiresGuiltyCarPhotoRecheck); if (allDoneNow) { // Atomic conditional update: only succeeds when status is still @@ -11253,6 +11279,37 @@ export class ClaimRequestManagementService { }; } + // V4 only (isMadeByFileMaker + NOT requiresFileMakerApproval) and THIRD_PARTY: + // inject one photo of the guilty party's car into the pre-capture document list. + const isV4 = + !!(blame as any)?.isMadeByFileMaker && + !(claimCase as any)?.requiresFileMakerApproval; + const isCarBodyBlame = blame?.type === BlameRequestType.CAR_BODY || (blame as any)?.type === "CAR_BODY"; + if (isV4 && !isCarBodyBlame) { + const guiltyCarPhotoKey = ClaimRequiredDocumentType.GUILTY_CAR_PHOTO; + const alreadyPresent = base.requiredDocuments.some( + (d) => d.key === guiltyCarPhotoKey, + ); + if (!alreadyPresent) { + const docData = (claimCase.requiredDocuments as any)?.get?.(guiltyCarPhotoKey) + ?? (claimCase.requiredDocuments as any)?.[guiltyCarPhotoKey]; + base = { + ...base, + requiredDocuments: [ + ...base.requiredDocuments, + { + key: guiltyCarPhotoKey, + label_fa: "عکس خودرو مقصر", + label_en: "Guilty Party Car Photo", + category: "guilty_party", + uploaded: !!docData?.uploaded, + preferUploadDuringCapture: false, + }, + ], + }; + } + } + const step = claimCase.workflow?.currentStep; const capturePartDone = this.claimV3StepCompleted( claimCase, @@ -11397,13 +11454,23 @@ export class ClaimRequestManagementService { } } + // V4 = isMadeByFileMaker + requiresFileMakerApproval is false. + const requiresGuiltyCarPhoto = + !!(blame as any).isMadeByFileMaker && + !(claimCase as any).requiresFileMakerApproval; + return this.uploadRequiredDocumentV2( claimRequestId, body, file, currentUserId, actor, - { v3InPersonFlow: true, skipMetalPlate, requiresFileMakerApproval: !!(claimCase as any).requiresFileMakerApproval }, + { + v3InPersonFlow: true, + skipMetalPlate, + requiresFileMakerApproval: !!(claimCase as any).requiresFileMakerApproval, + requiresGuiltyCarPhoto, + }, ); }