diff --git a/docs/blame-claim-flow-architecture.html b/docs/blame-claim-flow-architecture.html
index 684dfb1..b9e7c14 100644
--- a/docs/blame-claim-flow-architecture.html
+++ b/docs/blame-claim-flow-architecture.html
@@ -1364,14 +1364,15 @@
10
- Owner sign on expert pricing (FileReviewer acts on
- behalf of user)
+ Claim completes after expert work (no final owner
+ signature)
- PUT /claim-sign/:claimId
+ Expert submits to Fanavaran manually when ready
- Submits agree + branchId + signature image
+ Mixed priced/factor claims still require priced-line
+ acceptance before factor uploads
@@ -1395,11 +1396,13 @@
FileMaker steps are identical to V4 except
requiresFileMakerApproval=true is set at creation. The
FileReviewer steps are also identical to V4. The only difference is the
- tail: after the damage expert completes their review and the owner signs,
+ tail: after the damage expert completes their review (and any required factors
+ are validated),
the claim moves to
WAITING_FOR_FILE_MAKER_APPROVAL instead of proceeding
- directly to fanavaran submission. The FileMaker then approves (→ fanavaran)
- or rejects (→ back to WAITING_FOR_DAMAGE_EXPERT, max 2 rejections).
+ directly to completion. The FileMaker then approves (→ COMPLETED; manual
+ Fanavaran submission) or rejects (→ back to WAITING_FOR_DAMAGE_EXPERT,
+ max 2 rejections).
@@ -1468,7 +1471,7 @@
Claim → WAITING_FOR_FILE_MAKER_APPROVAL
- (instead of direct fanavaran submit)
+ (before final completion; no owner signature)
@@ -1496,7 +1499,7 @@
✓
- Fanavaran submission (on approve)
+ Claim COMPLETED (on approve)
@@ -1845,8 +1848,8 @@
DAMAGE_EXPERT |
DAMAGE_EXPERT |
DAMAGE_EXPERT |
- DAMAGE_EXPERT → owner sign (FileReviewer) |
- DAMAGE_EXPERT → owner sign → FileMaker approval |
+ DAMAGE_EXPERT → COMPLETED (manual Fanavaran submit) |
+ DAMAGE_EXPERT → FileMaker approval → COMPLETED (manual Fanavaran submit) |
DAMAGE_EXPERT (standard V2) |
diff --git a/docs/panel-roles-reference.fa.html b/docs/panel-roles-reference.fa.html
index a5f13ca..b23c284 100644
--- a/docs/panel-roles-reference.fa.html
+++ b/docs/panel-roles-reference.fa.html
@@ -220,7 +220,7 @@
file_maker |
- | ارزیابی خسارت V4/V5 (فیلدهای تصادف، قطعات، عکسها، امضای مالک) |
+ ارزیابی خسارت V4/V5 (فیلدهای تصادف، قطعات و عکسها؛ تأیید خطوط قیمتگذاریشده در جریان ترکیبیِ فاکتور در صورت نیاز) |
فایلهای تخصیصیافته |
پنل بازبین فایل |
file_reviewer |
@@ -451,7 +451,8 @@
OTPها، استعلامها، موقعیت/توضیحات/صدا و امضاها برای هر دو طرف.
همچنین اسناد اولیه خسارت (گواهینامهها، کارتهای خودرو) را بارگذاری میکند. پس از
امضای دوم، فایل برای تحویل به بازبین فایل «مهرومومه» میشود. در V5، فایلساز
- در انتها بازمیگردد تا خسارت تکمیلشده را قبل از ارسال به فناوران تأیید یا رد کند.
+ در انتها بازمیگردد تا خسارت تکمیلشده را تأیید یا رد کند. پس از تأیید،
+ کارشناس پرونده را بهصورت دستی به فناوران ارسال میکند.
@@ -475,10 +476,10 @@
تأیید خسارت V5 — v5/file-maker/claim-approval/
-
فقط در V5 استفاده میشود. پس از بررسی کارشناس خسارت و امضای مالک، خسارت وارد WAITING_FOR_FILE_MAKER_APPROVAL میشود.
+
فقط در V5 استفاده میشود. پس از بررسی کارشناس خسارت و اعتبارسنجی فاکتورهای لازم، خسارت وارد WAITING_FOR_FILE_MAKER_APPROVAL میشود؛ امضای نهایی مالک لازم نیست.
| متد | مسیر | توضیح |
- | POST | approve/:claimId | تأیید خسارت تکمیلشده ← ارسال SMS امضای مالک را فعال میکند ← پس از امضای مالک به فناوران ارسال میشود. |
+ | POST | approve/:claimId | تأیید خسارت تکمیلشده ← وضعیت خسارت COMPLETED میشود. کارشناس در زمان مناسب آن را بهصورت دستی به فناوران ارسال میکند. |
| POST | reject/:claimId | رد به بازبین فایل ← خسارت به WAITING_FOR_DAMAGE_EXPERT برمیگردد. محدودیت: حداکثر ۲ رد در هر خسارت؛ تلاش سوم ۴۲۲ با کد FILE_MAKER_REJECTION_LIMIT_EXCEEDED برمیگرداند. |
@@ -489,7 +490,7 @@
دومین اکتور در تقسیم V4/V5. بازبین فایل فایلهای مهرومومهشده (پس از اتمام کار
فایلساز) را تحویل میگیرد و مرحله کامل ارزیابی خسارت را انجام میدهد: فیلدهای
تصادف، دریافت الزامات عکسبرداری، بارگذاری اسناد (شاسی/موتور)، انتخاب قطعات،
- عکسهای قطعات، ویدیوی دور زدن خودرو، امضای مالک. تقصیر با car-capture به
+ عکسهای قطعات و ویدیوی دور زدن خودرو. تقصیر با car-capture به
COMPLETED علامتگذاری میشود. بازبین فایل همچنین دسترسی خواندن به پنل expert-claim
برای خسارتهایی که بررسی میکند دارد.
@@ -499,8 +500,8 @@
اندپوینتهای V4 و V5 یکسان هستند — فقط پیشوند تغییر میکند.
| متد | مسیر | توضیح |
- | GET | my-files | فهرست تمام فایلهای تخصیصیافته به این بازبین فایل. |
- | GET | my-files/:requestId | جزئیات کامل یک فایل (طرفین، گردش کار، فیلدهای کارشناس، شناسه خسارت مرتبط). |
+ | GET | my-files | فهرست فایلهای مهرومومشدهٔ فایلساز که در شرکت بیمهٔ این بازبین برای دریافت آمادهاند، بهعلاوهٔ فایلهای تخصیصیافته به خود او. |
+ | GET | my-files/:requestId | جزئیات کامل یک فایل آماده برای دریافت یا تخصیصیافته، در شرکت بیمهٔ همین بازبین (طرفین، گردش کار، فیلدهای کارشناس، شناسه خسارت مرتبط). |
| GET | claim-id/:requestId | دریافت شناسه خسارت ایجادشده بهصورت خودکار (از استعلام طرف مقصر فایلساز). |
| POST | accident-fields/:requestId | مرحله ۱ (بازبین): ذخیره فیلدهای تصادف (accidentWay، accidentReason، accidentType). |
| GET | capture-requirements/:claimId | الزامات عکسبرداری آگاه از مرحله (فاز اسناد پیش از عکسبرداری در مقابل فاز عکسبرداری قطعات). |
@@ -509,7 +510,7 @@
| PATCH | select-other-parts/:claimId | انتخاب سایر قطعات آسیبدیده (غیر بدنه). |
| POST | capture-part/:claimId | عکسبرداری از قطعات + زوایا برای هر قطعه آسیبدیده انتخابشده. |
| PATCH | car-capture/:claimId | ویدیوی دور زدن خودرو (آخرین مرحله عکسبرداری بازبین). خسارت ← WAITING_FOR_DAMAGE_EXPERT، تقصیر ← COMPLETED. |
- | PUT | claim-sign/:claimId | ثبت امضای مالک روی قیمتگذاری کارشناس به نمایندگی از طرف زیاندیده (موافقت + branchId + تصویر امضا). |
+ | PUT | claim-sign/:claimId | فقط برای خسارتهای ترکیبیِ قیمت/فاکتور: ثبت موافقت با خطوط قیمتگذاریشده پیش از بارگذاری فاکتور. امضای نهایی مالک دیگر لازم نیست. |
| POST | upload-video/:requestId | در V4/V5 بیاثر است — تقصیر از قبل توسط car-capture COMPLETED شده. موفقیت idempotent برمیگرداند. |
diff --git a/docs/panel-roles-reference.html b/docs/panel-roles-reference.html
index 84eab3e..145fc3d 100644
--- a/docs/panel-roles-reference.html
+++ b/docs/panel-roles-reference.html
@@ -217,7 +217,7 @@
file_reviewer |
FileReviewer panel |
Assigned files |
- V4/V5 damage assessment (accident fields, parts, captures, owner sign) |
+ V4/V5 damage assessment (accident fields, parts, captures; mixed-factor priced-line acceptance when needed) |
registrar |
@@ -367,7 +367,7 @@
| POST | v2/expert-claim/assign/:claimRequestId | Lock claim to this expert. Returns assigned, already_assigned_to_you, or 409. |
| GET | v2/expert-claim/request/:claimRequestId/price-drop | Price-drop context: severity labels, coefficient catalog, damaged parts + mapping, suggested car year from blame inquiry. |
| PUT | v2/expert-claim/request/:claimRequestId/price-drop | Calculate and persist price-drop: carPrice × yearCoeff × sumOfCoeffs ÷ 400. |
- | PUT | v2/expert-claim/reply/submit/:claimRequestId | Submit damage assessment reply (priced parts list, daghi, branchId). Cap: total ≤ 53 000 000 Toman. Depending on factorNeeded flags moves claim to owner-sign, mixed-factors-pending, or factor-validation queue. |
+ | PUT | v2/expert-claim/reply/submit/:claimRequestId | Submit damage assessment reply (priced parts list, daghi, branchId). Cap: total ≤ 53 000 000 Toman. A priced-only claim completes immediately; factor claims continue through factor collection/validation. No final owner signature or automatic Fanavaran submission. |
| PUT | v2/expert-claim/reply/resend/:claimRequestId | Request user to resend documents/photos. One resend per claim lifecycle; returns 422 if already fulfilled. |
| PATCH | v2/expert-claim/:claimRequestId/visit | Ask user to come in person. Unlocks claim, sets claimStatus to NEEDS_REVISION. |
| PATCH | v2/expert-claim/validate-factors/:claimRequestId | Validate uploaded repair factor invoices. Approve or reject each factor line with totalPayment. Cap applies across all lines (≤ 53 000 000 Toman). Auto-completes when all lines are decided. |
@@ -444,7 +444,8 @@
OTPs, inquiries, location/description/voice, and signatures for both parties.
They also upload the initial claim documents (licences, car cards). After the second
signature the file is "sealed" for FileReviewer pickup. In V5, FileMaker comes
- back at the end to approve or reject the completed claim before fanavaran submission.
+ back at the end to approve or reject the completed claim. After approval, an
+ expert submits the case to Fanavaran manually.
@@ -468,10 +469,10 @@
V5 claim approval — v5/file-maker/claim-approval/
-
Used only in V5. After damage expert review and owner sign, claim enters WAITING_FOR_FILE_MAKER_APPROVAL.
+
Used only in V5. After damage expert review and any required factor validation, claim enters WAITING_FOR_FILE_MAKER_APPROVAL; no final owner signature is needed.
| Method | Route | What it does |
- | POST | approve/:claimId | Approve the completed claim → triggers owner sign SMS → fanavaran submission after owner signs. |
+ | POST | approve/:claimId | Approve the completed claim → claim becomes COMPLETED. An expert submits to Fanavaran manually when ready. |
| POST | reject/:claimId | Reject back to FileReviewer → claim returns to WAITING_FOR_DAMAGE_EXPERT. Limit: max 2 rejections per claim; 3rd attempt returns 422 FILE_MAKER_REJECTION_LIMIT_EXCEEDED. |
@@ -482,7 +483,7 @@
The second actor in the V4/V5 split. FileReviewer picks up sealed files (after
FileMaker is done) and performs the full damage assessment pass: accident fields,
capture requirements lookup, document upload (chassis/engine), part selection,
- part photos, walk-around video, owner signature. The blame is marked COMPLETED
+ part photos and walk-around video. The blame is marked COMPLETED
by car-capture. FileReviewer also has read access to the expert-claim panel for
claims they are reviewing.
@@ -492,8 +493,8 @@
V4 and V5 endpoints are identical — only the prefix changes.
| Method | Route | What it does |
- | GET | my-files | List all files assigned to this FileReviewer. |
- | GET | my-files/:requestId | Full detail for one file (parties, workflow, expert fields, linked claim ID). |
+ | GET | my-files | List FileMaker-sealed files available to claim in this reviewer’s insurer, plus files already assigned to this FileReviewer. |
+ | GET | my-files/:requestId | Full detail for one available or assigned file in this reviewer’s insurer (parties, workflow, expert fields, linked claim ID). |
| GET | claim-id/:requestId | Get the auto-created claim ID (from FileMaker's guilty-party inquiry). |
| POST | accident-fields/:requestId | Step 1 (FileReviewer): save accident fields (accidentWay, accidentReason, accidentType). |
| GET | capture-requirements/:claimId | Step-aware capture requirements (pre-capture docs phase vs capture-parts phase). |
@@ -502,7 +503,7 @@
| PATCH | select-other-parts/:claimId | Select other (non-body) damaged parts. |
| POST | capture-part/:claimId | Capture part photos + angles for each selected damaged part. |
| PATCH | car-capture/:claimId | Walk-around video (final FileReviewer capture step). Claim → WAITING_FOR_DAMAGE_EXPERT, blame → COMPLETED. |
- | PUT | claim-sign/:claimId | Submit owner signature on expert pricing on behalf of the damaged party (agree + branchId + signature image). |
+ | PUT | claim-sign/:claimId | For mixed priced/factor claims only: record acceptance of priced lines before factor uploads. A final owner signature is no longer required. |
| POST | upload-video/:requestId | No-op in V4/V5 — blame already COMPLETED by car-capture. Returns idempotent success. |
diff --git a/src/claim-request-management/claim-request-management.v2.controller.ts b/src/claim-request-management/claim-request-management.v2.controller.ts
index b3628bb..823cc37 100644
--- a/src/claim-request-management/claim-request-management.v2.controller.ts
+++ b/src/claim-request-management/claim-request-management.v2.controller.ts
@@ -322,7 +322,8 @@ export class ClaimRequestManagementV2Controller {
}
/**
- * V2: Owner signature — priced-line gate (mixed factors) or final accept/reject.
+ * V2–V5: owner signature used only as the priced-line gate for mixed-factor claims.
+ * The final accept/reject phase is retained for legacy rows only.
*/
@Put("request/:claimRequestId/owner-insurer-approval/sign")
@ApiParam({
@@ -332,12 +333,12 @@ export class ClaimRequestManagementV2Controller {
})
@ApiConsumes("multipart/form-data")
@ApiOperation({
- summary: "Sign priced lines or final claim pricing (owner)",
+ summary: "Sign priced lines before factor uploads (owner; final phase is legacy only)",
description:
"Multipart: `sign`, `agree`, `branchId`. Requires `ClaimCaseStatus` **`INSURER_REVIEW_AWAITING_OWNER_SIGN`**, **`INSURER_REVIEW_MIXED_FACTORS_PENDING`**, or legacy **`WAITING_FOR_INSURER_APPROVAL`**, and `workflow.currentStep=INSURER_REVIEW` (not during owner factor upload or `EXPERT_COST_EVALUATION`).\n\n" +
"**Phase A — Mixed reply, priced lines only:** `claimStatus=NEEDS_REVISION`, no `evaluation.ownerPricedPartsApproval` yet. `agree=true` records that signature and moves to `OWNER_UPLOAD_FACTOR_DOCUMENTS` for factor uploads; `agree=false` rejects the whole case (`REJECTED`).\n\n" +
- "**Phase B — Final:** `claimStatus=APPROVED`, no `evaluation.ownerInsurerApproval` yet. `agree=true` → `COMPLETED`; `agree=false` → `REJECTED`.\n\n" +
- "Response may include `phase`: `PRICED_PARTS_FOR_FACTORS` or `FINAL_APPROVAL` for UI state.",
+ "**Phase B — Legacy final phase only:** pre-existing rows with `claimStatus=APPROVED` may still be accepted or rejected through this endpoint. New V2–V5 claims complete after expert work (and V5 FileMaker approval) without a final owner signature.\n\n" +
+ "Response may include `phase`: `PRICED_PARTS_FOR_FACTORS` or legacy `FINAL_APPROVAL` for UI state.",
})
@ApiBody({
description: "Signature file, agreement, and branch",
diff --git a/src/claim-request-management/dto/claim-details-v2.dto.ts b/src/claim-request-management/dto/claim-details-v2.dto.ts
index a801922..26f84f6 100644
--- a/src/claim-request-management/dto/claim-details-v2.dto.ts
+++ b/src/claim-request-management/dto/claim-details-v2.dto.ts
@@ -102,7 +102,7 @@ export class ClaimDetailsV2ResponseDto {
@ApiProperty({
description:
- "ClaimCaseStatus; see also `ownerGuidance` for UX. Post-expert: INSURER_REVIEW_AWAITING_OWNER_SIGN | INSURER_REVIEW_MIXED_FACTORS_PENDING | OWNER_REPAIR_FACTOR_UPLOAD_PENDING | EXPERT_VALIDATING_REPAIR_FACTORS; legacy WAITING_FOR_INSURER_APPROVAL may still appear.",
+ "ClaimCaseStatus; see also `ownerGuidance` for UX. New V2–V5 priced-only claims are COMPLETED after expert work; factor claims use INSURER_REVIEW_MIXED_FACTORS_PENDING | OWNER_REPAIR_FACTOR_UPLOAD_PENDING | EXPERT_VALIDATING_REPAIR_FACTORS. V5 then uses WAITING_FOR_FILE_MAKER_APPROVAL. Legacy WAITING_FOR_INSURER_APPROVAL or INSURER_REVIEW_AWAITING_OWNER_SIGN may still appear.",
example: "OWNER_REPAIR_FACTOR_UPLOAD_PENDING",
})
status: string;
diff --git a/src/claim-request-management/dto/my-claims-v2.dto.ts b/src/claim-request-management/dto/my-claims-v2.dto.ts
index 2941146..3c98b71 100644
--- a/src/claim-request-management/dto/my-claims-v2.dto.ts
+++ b/src/claim-request-management/dto/my-claims-v2.dto.ts
@@ -12,8 +12,8 @@ export class ClaimListItemV2Dto {
@ApiProperty({
description:
- "ClaimCaseStatus. Post-expert owner phase includes: INSURER_REVIEW_AWAITING_OWNER_SIGN (priced lines only → final owner sign); INSURER_REVIEW_MIXED_FACTORS_PENDING (priced + factor lines); OWNER_REPAIR_FACTOR_UPLOAD_PENDING (all lines factor-needed); EXPERT_VALIDATING_REPAIR_FACTORS (all factors uploaded, expert validating). Legacy DB rows may still use WAITING_FOR_INSURER_APPROVAL for those flows.",
- example: "INSURER_REVIEW_AWAITING_OWNER_SIGN",
+ "ClaimCaseStatus. New V2–V5 priced-only claims become COMPLETED after expert work. Factor claims use INSURER_REVIEW_MIXED_FACTORS_PENDING (priced-line acceptance before factor uploads), OWNER_REPAIR_FACTOR_UPLOAD_PENDING, and EXPERT_VALIDATING_REPAIR_FACTORS. V5 then waits at WAITING_FOR_FILE_MAKER_APPROVAL. Legacy DB rows may still use WAITING_FOR_INSURER_APPROVAL or INSURER_REVIEW_AWAITING_OWNER_SIGN.",
+ example: "COMPLETED",
})
status: string;
diff --git a/src/claim-request-management/expert-initiated-claim.mirror.controller.ts b/src/claim-request-management/expert-initiated-claim.mirror.controller.ts
index 6670bbc..a3474f8 100644
--- a/src/claim-request-management/expert-initiated-claim.mirror.controller.ts
+++ b/src/claim-request-management/expert-initiated-claim.mirror.controller.ts
@@ -527,7 +527,7 @@ Returns status of each item (uploaded/captured or not).
);
}
- // ─── Owner signature on expert pricing ───────────────────────────────────────
+ // ─── Mixed-factor priced-line signature ──────────────────────────────────────
@Put("claim-sign/:claimRequestId")
@ApiParam({ name: "claimRequestId" })
@@ -553,11 +553,12 @@ Returns status of each item (uploaded/captured or not).
})
@ApiOperation({
summary:
- "Owner signature on expert pricing (Flow 3 — expert acts on behalf of user)",
+ "Priced-line acceptance before factor uploads (Flow 3 — expert acts on behalf of user)",
description:
- "Field expert submits the damaged party's signature during the final approval stage. " +
- "Delegates to the same service method as the user sign endpoint; the expert's " +
- "identity is resolved to the claim owner via `resolveClaimEffectiveUserId`.",
+ "For mixed priced/factor claims only, the field expert records the damaged party's " +
+ "acceptance of priced lines before factor uploads. V2–V5 no longer require a final " +
+ "owner signature: they complete after expert work. The expert's identity is resolved " +
+ "to the claim owner via `resolveClaimEffectiveUserId`.",
})
@UseInterceptors(
FileInterceptor("sign", {
diff --git a/src/expert-claim/expert-claim.service.ts b/src/expert-claim/expert-claim.service.ts
index 0d34d82..bfe9f60 100644
--- a/src/expert-claim/expert-claim.service.ts
+++ b/src/expert-claim/expert-claim.service.ts
@@ -2223,10 +2223,16 @@ export class ExpertClaimService {
actorType: string;
},
metadata: Record,
- ): Promise {
+ ): Promise {
+ // V5 retains the FileMaker approval gate, but no longer waits for a
+ // damaged-party final signature after that approval.
+ const completionStatus = (claimForTenant as any).requiresFileMakerApproval
+ ? ClaimCaseStatus.WAITING_FOR_FILE_MAKER_APPROVAL
+ : ClaimCaseStatus.COMPLETED;
+
await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, {
$set: {
- status: ClaimCaseStatus.COMPLETED,
+ status: completionStatus,
claimStatus: ClaimStatus.APPROVED,
"workflow.currentStep": ClaimWorkflowStep.CLAIM_COMPLETED,
"workflow.nextStep": ClaimWorkflowStep.CLAIM_COMPLETED,
@@ -2248,6 +2254,8 @@ export class ExpertClaimService {
eventType: ExpertFileActivityType.HANDLED,
idempotencyKey: `claim:${claimRequestId}:factor_validation:${historyType}:${actor.sub}`,
});
+
+ return completionStatus;
}
/**
@@ -2420,7 +2428,7 @@ export class ExpertClaimService {
};
if (anyRejected) {
- await this.completeClaimCaseAfterFactorValidationV2(
+ const completionStatus = await this.completeClaimCaseAfterFactorValidationV2(
claimRequestId,
claim,
actor,
@@ -2428,28 +2436,19 @@ export class ExpertClaimService {
historyActor,
{ replyField },
);
- const fanavaran =
- await this.claimRequestManagementService.autoSubmitToFanavaranV2OnClaimCompleted(
- claimRequestId,
- );
- // Expertise (stage 4) is intentionally NOT submitted here.
- // It is only triggered after the owner's final approval signature
- // (submitOwnerInsurerApprovalSignV2), because until that point the
- // expert review is not considered final — the user can still object.
return {
- message: this.appendFanavaranAutoSubmitToMessage(
- "Factors were reviewed with expert repricing on rejected lines. The claim is completed without an owner signature (temporary policy; may require owner acceptance later).",
- fanavaran,
- ),
+ message:
+ completionStatus === ClaimCaseStatus.WAITING_FOR_FILE_MAKER_APPROVAL
+ ? "Factors were reviewed with expert repricing. The claim is awaiting FileMaker approval."
+ : "Factors were reviewed with expert repricing. The claim is completed without a final owner signature.",
claimRequestId,
claimStatus: ClaimStatus.APPROVED,
- caseStatus: ClaimCaseStatus.COMPLETED,
+ caseStatus: completionStatus,
outcome: "REJECTED_REPRICED_AUTO_COMPLETED",
- fanavaran,
};
}
- await this.completeClaimCaseAfterFactorValidationV2(
+ const completionStatus = await this.completeClaimCaseAfterFactorValidationV2(
claimRequestId,
claim,
actor,
@@ -2458,25 +2457,15 @@ export class ExpertClaimService {
{ replyField },
);
- const fanavaran =
- await this.claimRequestManagementService.autoSubmitToFanavaranV2OnClaimCompleted(
- claimRequestId,
- );
- // Expertise (stage 4) is intentionally NOT submitted here.
- // It is only triggered after the owner's final approval signature
- // (submitOwnerInsurerApprovalSignV2), because until that point the
- // expert review is not considered final — the user can still object.
-
return {
- message: this.appendFanavaranAutoSubmitToMessage(
- "All factors were approved by the expert. The claim is completed without an additional owner signature.",
- fanavaran,
- ),
+ message:
+ completionStatus === ClaimCaseStatus.WAITING_FOR_FILE_MAKER_APPROVAL
+ ? "All factors were approved. The claim is awaiting FileMaker approval."
+ : "All factors were approved by the expert. The claim is completed without a final owner signature.",
claimRequestId,
claimStatus: ClaimStatus.APPROVED,
- caseStatus: ClaimCaseStatus.COMPLETED,
+ caseStatus: completionStatus,
outcome: "ALL_APPROVED_AUTO_COMPLETED",
- fanavaran,
};
}
@@ -3230,9 +3219,9 @@ export class ExpertClaimService {
* On success:
* - Stores reply; clears owner signature fields (`ownerInsurerApproval`, `ownerPricedPartsApproval`)
* - Unlocks the workflow
- * - Pricing-only (`factorNeeded=false` everywhere): INSURER_REVIEW_AWAITING_OWNER_SIGN, APPROVED, INSURER_REVIEW → owner final sign/reject.
+ * - Pricing-only (`factorNeeded=false` everywhere): COMPLETED, APPROVED, CLAIM_COMPLETED — no final owner signature.
* - All lines `factorNeeded`: NEEDS_REVISION, OWNER_UPLOAD_FACTOR_DOCUMENTS → uploads → UNDER_REVIEW, EXPERT_COST_EVALUATION (validate factors).
- * - Mixed priced + factor: NEEDS_REVISION, INSURER_REVIEW with next OWNER_UPLOAD_FACTOR_DOCUMENTS → owner signs priced lines first → upload factors → expert validates → final sign.
+ * - Mixed priced + factor: NEEDS_REVISION, INSURER_REVIEW with next OWNER_UPLOAD_FACTOR_DOCUMENTS → owner signs priced lines first → upload factors → expert validates → complete.
*/
async submitExpertReplyV2(
claimRequestId: string,
@@ -3398,14 +3387,23 @@ export class ExpertClaimService {
let currentStep = ClaimWorkflowStep.INSURER_REVIEW;
let nextWorkflowStep = ClaimWorkflowStep.CLAIM_COMPLETED;
- const nextCaseStatus = claimCaseStatusAfterExpertReplyV2(processedParts);
+ const blameForFlow = claim.blameRequestId
+ ? await this.blameRequestDbService.findById(String(claim.blameRequestId))
+ : undefined;
+ const skipsFinalOwnerSignature =
+ !!(blameForFlow as any)?.expertInitiated &&
+ (blameForFlow as any)?.creationMethod === "IN_PERSON";
+ const nextCaseStatus = claimCaseStatusAfterExpertReplyV2(
+ processedParts,
+ skipsFinalOwnerSignature,
+ );
let nextClaimStatus = ClaimStatus.APPROVED;
- // V5 flow: FileMaker must approve before the owner is asked to sign.
- // When no factor upload is needed, skip the owner-sign step entirely here
- // and park the claim at WAITING_FOR_FILE_MAKER_APPROVAL. The owner SMS
- // and INSURER_REVIEW status are emitted by fileMakerApproveV5 instead.
+ // V5 retains a FileMaker approval gate after expert work. Expert-initiated
+ // in-person V2–V5 flows do not request a final damaged-party signature.
const isV5Claim = !!(claim as any).requiresFileMakerApproval;
+ const completesWithoutFactors =
+ !needsFactorUpload && !isV5Claim && skipsFinalOwnerSignature;
if (needsFactorUpload) {
nextClaimStatus = ClaimStatus.NEEDS_REVISION;
@@ -3418,7 +3416,10 @@ export class ExpertClaimService {
}
} else if (isV5Claim) {
// V5, no factors: hold at WAITING_FOR_FILE_MAKER_APPROVAL
- currentStep = ClaimWorkflowStep.INSURER_REVIEW;
+ currentStep = ClaimWorkflowStep.CLAIM_COMPLETED;
+ nextWorkflowStep = ClaimWorkflowStep.CLAIM_COMPLETED;
+ } else if (completesWithoutFactors) {
+ currentStep = ClaimWorkflowStep.CLAIM_COMPLETED;
nextWorkflowStep = ClaimWorkflowStep.CLAIM_COMPLETED;
}
@@ -3436,10 +3437,11 @@ export class ExpertClaimService {
}
}
- const updatePayload: Record = {
- status: isV5Claim && !needsFactorUpload
+ const persistedCaseStatus = isV5Claim && !needsFactorUpload
? ClaimCaseStatus.WAITING_FOR_FILE_MAKER_APPROVAL
- : nextCaseStatus,
+ : nextCaseStatus;
+ const updatePayload: Record = {
+ status: persistedCaseStatus,
claimStatus: nextClaimStatus,
...(expertAddedParts.length > 0
? { "damage.selectedParts": mergedSelectedParts }
@@ -3454,9 +3456,7 @@ export class ExpertClaimService {
"evaluation.ownerPricedPartsApproval": "",
},
"workflow.currentStep": currentStep,
- "workflow.nextStep": needsFactorUpload
- ? nextWorkflowStep
- : ClaimWorkflowStep.CLAIM_COMPLETED,
+ "workflow.nextStep": nextWorkflowStep,
[`evaluation.${replyField}`]: replyPayload,
$push: {
"workflow.completedSteps": completedStep,
@@ -3495,30 +3495,36 @@ export class ExpertClaimService {
idempotencyKey: `claim:${claimRequestId}:handled:${actor.sub}`,
});
- // V5: owner SMS is sent by fileMakerApproveV5 after FileMaker approval.
- const ownerPhoneNotify = await this.resolveClaimOwnerPhone(claim);
- if (ownerPhoneNotify && !needsFactorUpload && !isV5Claim) {
- const expertLastName =
- actor?.fullName?.trim()?.split(/\s+/).pop() || "کارشناس";
- await this.smsOrchestrationService.sendSignatureReviewNotice({
- receptor: ownerPhoneNotify,
- fileKind: "claim",
- publicId: claim.publicId,
- expertLastName,
- link: this.smsOrchestrationService.buildClaimLink(String(claim._id), "v2"),
- });
+ // V1 retains its existing final owner-signature notification. V2–V5 do not
+ // send this notification because their completion policy is manual Fanavaran
+ // submission after expert work (and FileMaker approval for V5).
+ if (!needsFactorUpload && !isV5Claim && !skipsFinalOwnerSignature) {
+ const ownerPhoneNotify = await this.resolveClaimOwnerPhone(claim);
+ if (ownerPhoneNotify) {
+ const expertLastName =
+ actor?.fullName?.trim()?.split(/\s+/).pop() || "کارشناس";
+ await this.smsOrchestrationService.sendSignatureReviewNotice({
+ receptor: ownerPhoneNotify,
+ fileKind: "claim",
+ publicId: claim.publicId,
+ expertLastName,
+ link: this.smsOrchestrationService.buildClaimLink(
+ String(claim._id),
+ "v2",
+ ),
+ });
+ }
}
- // Fanavaran expertise is now triggered on owner final sign, not here.
+ // V2–V5 completion and FileMaker approval do not trigger a Fanavaran
+ // submission; the expert submits manually when ready.
return {
claimRequestId,
- status: nextCaseStatus,
+ status: persistedCaseStatus,
claimStatus: nextClaimStatus,
currentStep,
- workflowNextStep: needsFactorUpload
- ? nextWorkflowStep
- : ClaimWorkflowStep.CLAIM_COMPLETED,
+ workflowNextStep: nextWorkflowStep,
factorNeeded: needsFactorUpload,
mixedPricingAndFactors: mixedFactorAndPrice,
allPartsFactorNeeded: !!needsFactorUpload && !!allFactorLines,
diff --git a/src/expert-claim/expert-claim.v2.controller.ts b/src/expert-claim/expert-claim.v2.controller.ts
index c506e11..85f6a59 100644
--- a/src/expert-claim/expert-claim.v2.controller.ts
+++ b/src/expert-claim/expert-claim.v2.controller.ts
@@ -270,7 +270,7 @@ export class ExpertClaimV2Controller {
"**Frontend routing by `ClaimCaseStatus` (`status`):**\n" +
"- **All parts `factorNeeded`:** `OWNER_REPAIR_FACTOR_UPLOAD_PENDING`, `claimStatus=NEEDS_REVISION`, `workflow.currentStep=OWNER_UPLOAD_FACTOR_DOCUMENTS`, `workflow.nextStep=EXPERT_COST_EVALUATION` → owner uploads all factors; then `status` becomes **`EXPERT_VALIDATING_REPAIR_FACTORS`**, `claimStatus=UNDER_REVIEW`, `currentStep=EXPERT_COST_EVALUATION` for expert **validate-factors**.\n" +
"- **Mixed (some priced, some factorNeeded):** `INSURER_REVIEW_MIXED_FACTORS_PENDING`, `claimStatus=NEEDS_REVISION`, `currentStep=INSURER_REVIEW`, `nextStep=OWNER_UPLOAD_FACTOR_DOCUMENTS` → owner must call **owner-insurer-approval/sign** first (priced-line acceptance); `currentStep` then moves to `OWNER_UPLOAD_FACTOR_DOCUMENTS` (same case `status` until factors are done).\n" +
- "- **No factors:** **`INSURER_REVIEW_AWAITING_OWNER_SIGN`**, `claimStatus=APPROVED`, `currentStep=INSURER_REVIEW`, `nextStep=CLAIM_COMPLETED` → owner final sign/reject only.\n\n" +
+ "- **No factors (V2–V5):** **`COMPLETED`**, `claimStatus=APPROVED`, `workflow.currentStep=CLAIM_COMPLETED` → no final owner signature. The expert can submit to Fanavaran manually when ready. For V5, the case instead waits for FileMaker approval before becoming `COMPLETED`.\n\n" +
"**Legacy rows** may still use `WAITING_FOR_INSURER_APPROVAL` instead of the specific values above.\n\n" +
"**After the owner fulfilled an expert resend** (`damageExpertResend.fulfilledAt`), this expert **cannot** initiate **another resend**—use **reply/submit**, in-person visit, or **validate-factors** as appropriate.",
})
@@ -352,8 +352,8 @@ export class ExpertClaimV2Controller {
"**Decisions:** each factor line gets `APPROVED` or `REJECTED`. **Every** decided line must include expert-entered `totalPayment` **or** both `price` and `salary` (factor photos are not read for amounts).\n\n" +
"**Cap (when every factor line is decided):** sum of **all** reply lines (priced parts + factor lines) must be ≤ **53,000,000 Toman**; otherwise `PRICE_CAP_ERROR` with message that the maximum acceptable total was exceeded.\n\n" +
"**Outcomes:**\n" +
- "- **All approved:** `caseStatus=COMPLETED`, `claimStatus=APPROVED`, workflow `CLAIM_COMPLETED` — no owner signature.\n" +
- "- **Any rejected (repriced):** same auto-complete for now (owner acceptance may be added later).\n" +
+ "- **All approved:** `caseStatus=COMPLETED`, `claimStatus=APPROVED`, workflow `CLAIM_COMPLETED` — no owner signature. V5 instead waits for FileMaker approval.\n" +
+ "- **Any rejected (repriced):** same completion behavior for now (V5 waits for FileMaker approval).\n" +
"- **Partial batch:** returns pending until every factor line has a non-pending decision (no cap error until the batch is complete).",
})
@ApiParam({ name: "claimRequestId" })
diff --git a/src/helpers/claim-v2-expert-reply-workflow.spec.ts b/src/helpers/claim-v2-expert-reply-workflow.spec.ts
new file mode 100644
index 0000000..0cafb66
--- /dev/null
+++ b/src/helpers/claim-v2-expert-reply-workflow.spec.ts
@@ -0,0 +1,37 @@
+import { ClaimCaseStatus } from "src/Types&Enums/claim-request-management/claim-case-status.enum";
+import { claimCaseStatusAfterExpertReplyV2 } from "./claim-v2-expert-reply-workflow";
+
+describe("claimCaseStatusAfterExpertReplyV2", () => {
+ it("keeps V1 priced-only claims in their final owner-signature state", () => {
+ expect(
+ claimCaseStatusAfterExpertReplyV2([
+ { factorNeeded: false },
+ { factorNeeded: false },
+ ]),
+ ).toBe(ClaimCaseStatus.INSURER_REVIEW_AWAITING_OWNER_SIGN);
+ });
+
+ it("completes a V2–V5 priced-only claim without a final owner signature", () => {
+ expect(
+ claimCaseStatusAfterExpertReplyV2(
+ [{ factorNeeded: false }, { factorNeeded: false }],
+ true,
+ ),
+ ).toBe(ClaimCaseStatus.COMPLETED);
+ });
+
+ it("keeps factor-required claims in their factor collection workflow", () => {
+ expect(
+ claimCaseStatusAfterExpertReplyV2([{ factorNeeded: true }]),
+ ).toBe(ClaimCaseStatus.OWNER_REPAIR_FACTOR_UPLOAD_PENDING);
+ });
+
+ it("keeps the priced-line acceptance gate for mixed factor claims", () => {
+ expect(
+ claimCaseStatusAfterExpertReplyV2([
+ { factorNeeded: false },
+ { factorNeeded: true },
+ ]),
+ ).toBe(ClaimCaseStatus.INSURER_REVIEW_MIXED_FACTORS_PENDING);
+ });
+});
diff --git a/src/helpers/claim-v2-expert-reply-workflow.ts b/src/helpers/claim-v2-expert-reply-workflow.ts
index 894b23f..02f329a 100644
--- a/src/helpers/claim-v2-expert-reply-workflow.ts
+++ b/src/helpers/claim-v2-expert-reply-workflow.ts
@@ -95,11 +95,16 @@ export function claimIsAwaitingExpertFactorValidationV2(claim: {
);
}
-export function claimCaseStatusAfterExpertReplyV2(parts: ClaimPricingPartLite[]): ClaimCaseStatus {
+export function claimCaseStatusAfterExpertReplyV2(
+ parts: ClaimPricingPartLite[],
+ completeWithoutFinalOwnerSignature = false,
+): ClaimCaseStatus {
const { mixedFactorAndPrice } = classifyV2ExpertPricingParts(parts);
const needsFactorUpload = parts.some((p) => p.factorNeeded === true);
if (!needsFactorUpload) {
- return ClaimCaseStatus.INSURER_REVIEW_AWAITING_OWNER_SIGN;
+ return completeWithoutFinalOwnerSignature
+ ? ClaimCaseStatus.COMPLETED
+ : ClaimCaseStatus.INSURER_REVIEW_AWAITING_OWNER_SIGN;
}
if (mixedFactorAndPrice) {
return ClaimCaseStatus.INSURER_REVIEW_MIXED_FACTORS_PENDING;
diff --git a/src/request-management/file-maker-claim-approval-v5.controller.ts b/src/request-management/file-maker-claim-approval-v5.controller.ts
index b186981..e14aea3 100644
--- a/src/request-management/file-maker-claim-approval-v5.controller.ts
+++ b/src/request-management/file-maker-claim-approval-v5.controller.ts
@@ -37,12 +37,13 @@ class FileMakerRejectDto {
* V5 FileMaker approval panel.
*
* After the full claim flow completes (FileReviewer does damage assessment via
- * expert-claim APIs, user signs), the claim lands in WAITING_FOR_FILE_MAKER_APPROVAL.
+ * expert-claim APIs and any required factors are validated), the claim lands in
+ * WAITING_FOR_FILE_MAKER_APPROVAL.
* The FileMaker who created the blame file can then:
*
- * approve → triggers fanavaran submission (claim → COMPLETED)
+ * approve → claim → COMPLETED; an expert submits to Fanavaran manually
* reject → sends claim back to WAITING_FOR_DAMAGE_EXPERT so the FileReviewer
- * can re-lock, adjust pricing, and redo the user interaction
+ * can re-lock, adjust pricing, and redo the claim work
*
* All endpoints operate on `claimRequestId` (the claim case ID, not the blame ID).
* Use `GET v5/file-maker/blame-request-management/claim-id/:requestId` to obtain
@@ -65,9 +66,8 @@ export class FileMakerClaimApprovalV5Controller {
summary: "Approve the completed claim (FileMaker V5)",
description:
"Approves a claim that is in `WAITING_FOR_FILE_MAKER_APPROVAL` status. " +
- "Moves the claim to `INSURER_REVIEW_AWAITING_OWNER_SIGN` and sends the owner an SMS " +
- "with a signature link. Fanavaran submission is triggered automatically after the " +
- "owner signs.",
+ "Moves the claim to `COMPLETED`. No final owner signature is requested and " +
+ "Fanavaran submission remains a manual expert action.",
})
async approve(
@Param("claimRequestId") claimRequestId: string,
diff --git a/src/request-management/file-maker-claim-approval-v5.spec.ts b/src/request-management/file-maker-claim-approval-v5.spec.ts
new file mode 100644
index 0000000..e8089a4
--- /dev/null
+++ b/src/request-management/file-maker-claim-approval-v5.spec.ts
@@ -0,0 +1,56 @@
+import { Types } from "mongoose";
+import { ClaimCaseStatus } from "src/Types&Enums/claim-request-management/claim-case-status.enum";
+import { RoleEnum } from "src/Types&Enums/role.enum";
+import { RequestManagementService } from "./request-management.service";
+
+describe("RequestManagementService V5 FileMaker approval", () => {
+ it("completes the claim without notifying the owner for a final signature", async () => {
+ const fileMakerId = new Types.ObjectId();
+ const claimId = new Types.ObjectId();
+ const claimCaseDbService = {
+ findById: jest.fn().mockResolvedValue({
+ _id: claimId,
+ publicId: "CLM-V5",
+ status: ClaimCaseStatus.WAITING_FOR_FILE_MAKER_APPROVAL,
+ requiresFileMakerApproval: true,
+ fileMakerApprovalActorId: fileMakerId,
+ }),
+ findByIdAndUpdate: jest.fn().mockResolvedValue({}),
+ };
+ const service = new (RequestManagementService as any)(
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ claimCaseDbService,
+ ) as RequestManagementService;
+
+ const result = await service.fileMakerApproveV5(
+ { sub: String(fileMakerId), role: RoleEnum.FILE_MAKER },
+ String(claimId),
+ );
+
+ expect(result.status).toBe(ClaimCaseStatus.COMPLETED);
+ expect(result.message).toContain("Submit it to Fanavaran manually");
+ expect(claimCaseDbService.findByIdAndUpdate).toHaveBeenCalledWith(
+ String(claimId),
+ expect.objectContaining({
+ $set: expect.objectContaining({
+ status: ClaimCaseStatus.COMPLETED,
+ requiresFileMakerApproval: false,
+ }),
+ }),
+ );
+ });
+});
diff --git a/src/request-management/file-reviewer-blame-v4.controller.ts b/src/request-management/file-reviewer-blame-v4.controller.ts
index fa66740..6710f09 100644
--- a/src/request-management/file-reviewer-blame-v4.controller.ts
+++ b/src/request-management/file-reviewer-blame-v4.controller.ts
@@ -344,7 +344,7 @@ export class FileReviewerBlameV4Controller {
);
}
- // ─── Owner signature on expert pricing ───────────────────────────────────────
+ // ─── Mixed-factor priced-line signature ──────────────────────────────────────
@Put("claim-sign/:claimRequestId")
@ApiParam({ name: "claimRequestId" })
@@ -362,11 +362,12 @@ export class FileReviewerBlameV4Controller {
},
})
@ApiOperation({
- summary: "Owner signature on expert pricing (V4 — FileReviewer acts on behalf of user)",
+ summary: "Priced-line acceptance before factor uploads (V4 — FileReviewer acts for user)",
description:
- "FileReviewer submits the damaged party's signature during the final approval stage. " +
- "Delegates to the same service method as the user sign endpoint; the FileReviewer's " +
- "identity is resolved to the claim owner via `resolveClaimEffectiveUserId`.",
+ "For mixed priced/factor claims only, FileReviewer records the damaged party's " +
+ "acceptance of priced lines before factor uploads. V2–V5 no longer require a final " +
+ "owner signature: they complete after expert work. The FileReviewer's identity is " +
+ "resolved to the claim owner via `resolveClaimEffectiveUserId`.",
})
@UseInterceptors(
FileInterceptor("sign", {
diff --git a/src/request-management/file-reviewer-blame-v5.controller.ts b/src/request-management/file-reviewer-blame-v5.controller.ts
index 7be306c..f67f35e 100644
--- a/src/request-management/file-reviewer-blame-v5.controller.ts
+++ b/src/request-management/file-reviewer-blame-v5.controller.ts
@@ -342,7 +342,7 @@ export class FileReviewerBlameV5Controller {
);
}
- // ─── Owner signature on expert pricing ───────────────────────────────────────
+ // ─── Mixed-factor priced-line signature ──────────────────────────────────────
@Put("claim-sign/:claimRequestId")
@ApiParam({ name: "claimRequestId" })
@@ -360,11 +360,12 @@ export class FileReviewerBlameV5Controller {
},
})
@ApiOperation({
- summary: "Owner signature on expert pricing (V5 — FileReviewer acts on behalf of user)",
+ summary: "Priced-line acceptance before factor uploads (V5 — FileReviewer acts for user)",
description:
- "FileReviewer submits the damaged party's signature during the final approval stage. " +
- "Delegates to the same service method as the user sign endpoint; the FileReviewer's " +
- "identity is resolved to the claim owner via `resolveClaimEffectiveUserId`.",
+ "For mixed priced/factor claims only, FileReviewer records the damaged party's " +
+ "acceptance of priced lines before factor uploads. V2–V5 no longer require a final " +
+ "owner signature: they complete after expert work. The FileReviewer's identity is " +
+ "resolved to the claim owner via `resolveClaimEffectiveUserId`.",
})
@UseInterceptors(
FileInterceptor("sign", {
diff --git a/src/request-management/request-management.service.ts b/src/request-management/request-management.service.ts
index 0f795f9..0afce0b 100644
--- a/src/request-management/request-management.service.ts
+++ b/src/request-management/request-management.service.ts
@@ -10462,9 +10462,9 @@ export class RequestManagementService {
/**
* V5 variant of expertUploadBlameVideoV3.
* Same flow as V3/V4 but additionally marks the linked claim with
- * `requiresFileMakerApproval: true` so that after the owner signs,
- * the claim is held at WAITING_FOR_FILE_MAKER_APPROVAL rather than
- * being auto-submitted to fanavaran.
+ * `requiresFileMakerApproval: true` so that after expert work completes,
+ * the claim is held at WAITING_FOR_FILE_MAKER_APPROVAL. FileMaker approval
+ * completes the claim; Fanavaran submission is manual.
*/
async expertUploadBlameVideoV5(
expert: any,
@@ -10612,7 +10612,7 @@ export class RequestManagementService {
videoId,
status: req.status,
message: file
- ? "Blame accident video uploaded. File is now in expert review queue. After the full claim flow completes and the owner signs, the FileMaker must approve before fanavaran submission."
+ ? "Blame accident video uploaded. File is now in expert review queue. After the full claim flow completes, the FileMaker must approve before manual Fanavaran submission."
: "File completed. Claim is now ready for damage expert review.",
};
}
@@ -10625,7 +10625,7 @@ export class RequestManagementService {
* - claim.status === WAITING_FOR_FILE_MAKER_APPROVAL
* - actor is FILE_MAKER and is the original creator of the linked blame file
*
- * On approval: triggers fanavaran submission and moves claim to COMPLETED.
+ * On approval: completes the claim. Fanavaran submission is manual.
*/
async fileMakerApproveV5(
fileMaker: any,
@@ -10669,16 +10669,14 @@ export class RequestManagementService {
metadata: {},
};
- // V5 approval: move claim to INSURER_REVIEW_AWAITING_OWNER_SIGN so the
- // owner can now sign. Clear requiresFileMakerApproval so that when the
- // owner later signs and autoSubmitToFanavaranV2OnClaimCompleted runs, it
- // does not re-intercept the claim as a pending V5 gate.
+ // V5 approval is the final V5 gate. The damaged-party final signature is
+ // no longer required, and Fanavaran submission is intentionally manual.
await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, {
$set: {
- status: ClaimCaseStatus.INSURER_REVIEW_AWAITING_OWNER_SIGN,
+ status: ClaimCaseStatus.COMPLETED,
claimStatus: ClaimStatus.APPROVED,
requiresFileMakerApproval: false,
- "workflow.currentStep": ClaimWorkflowStep.INSURER_REVIEW,
+ "workflow.currentStep": ClaimWorkflowStep.CLAIM_COMPLETED,
"workflow.nextStep": ClaimWorkflowStep.CLAIM_COMPLETED,
},
$push: {
@@ -10686,36 +10684,12 @@ export class RequestManagementService {
},
});
- // Notify the owner that the claim is ready for their signature.
- const notifyUserId = (claim as any).damagedPartyUserId ?? (claim as any).owner?.userId;
- if (notifyUserId && claim.blameRequestId) {
- const blame = await this.blameRequestDbService.findById(
- String(claim.blameRequestId),
- );
- const ownerParty = (blame?.parties || []).find(
- (p: any) =>
- p?.person?.userId && String(p.person.userId) === String(notifyUserId),
- );
- const ownerPhone = ownerParty?.person?.phoneNumber
- ?? (await this.userDbService.findOne({ _id: new Types.ObjectId(String(notifyUserId)) }))?.mobile;
- if (ownerPhone && typeof ownerPhone === "string") {
- await this.smsOrchestrationService.sendSignatureReviewNotice({
- receptor: ownerPhone,
- fileKind: "claim",
- publicId: claim.publicId,
- expertLastName: actorName.split(/\s+/).pop() || "کارشناس",
- link: this.smsOrchestrationService.buildClaimLink(claimRequestId, "v2"),
- });
- }
- }
-
return {
claimRequestId,
publicId: claim.publicId,
- status: ClaimCaseStatus.INSURER_REVIEW_AWAITING_OWNER_SIGN,
+ status: ClaimCaseStatus.COMPLETED,
message:
- "Claim approved by FileMaker. Owner has been notified to sign. " +
- "Once the owner signs, the claim will be completed and submitted to Fanavaran.",
+ "Claim approved by FileMaker and completed. Submit it to Fanavaran manually when ready.",
};
}