forked from Yara724/api
Added sign endpoint for claim
This commit is contained in:
@@ -5131,6 +5131,152 @@ export class ClaimRequestManagementService {
|
||||
return userRating;
|
||||
}
|
||||
|
||||
/**
|
||||
* V2: Claim owner signs final priced expert reply (single-party), same intent as blame
|
||||
* `PUT …/sign/:requestId` — only when case status is WAITING_FOR_INSURER_APPROVAL and
|
||||
* workflow is at INSURER_REVIEW (not factor-validation queue at EXPERT_COST_EVALUATION).
|
||||
*/
|
||||
async submitOwnerInsurerApprovalSignV2(
|
||||
claimRequestId: string,
|
||||
agree: boolean,
|
||||
signFile: Express.Multer.File,
|
||||
currentUserId: string,
|
||||
actor?: { sub: string; role?: string; fullName?: string },
|
||||
): Promise<{
|
||||
message: string;
|
||||
claimRequestId: string;
|
||||
status: ClaimCaseStatus;
|
||||
claimStatus: ClaimStatus;
|
||||
currentStep?: ClaimWorkflowStep;
|
||||
accepted: boolean;
|
||||
}> {
|
||||
if (!Types.ObjectId.isValid(claimRequestId)) {
|
||||
throw new BadRequestException("Invalid claim request id");
|
||||
}
|
||||
if (!signFile) {
|
||||
throw new BadRequestException("A signature file is required");
|
||||
}
|
||||
|
||||
const claimCase = await this.claimCaseDbService.findById(claimRequestId);
|
||||
if (!claimCase) {
|
||||
throw new NotFoundException("Claim request not found");
|
||||
}
|
||||
|
||||
const effectiveUserId = await this.resolveClaimEffectiveUserId(
|
||||
claimCase,
|
||||
currentUserId,
|
||||
actor?.role,
|
||||
);
|
||||
if (!claimCase.owner?.userId || claimCase.owner.userId.toString() !== effectiveUserId) {
|
||||
throw new ForbiddenException(
|
||||
"Only the claim owner (damaged party) can sign at this step.",
|
||||
);
|
||||
}
|
||||
|
||||
if (claimCase.status !== ClaimCaseStatus.WAITING_FOR_INSURER_APPROVAL) {
|
||||
throw new BadRequestException(
|
||||
`Claim is not waiting for your approval signature. Current status: ${String(claimCase.status)}`,
|
||||
);
|
||||
}
|
||||
if (claimCase.workflow?.currentStep !== ClaimWorkflowStep.INSURER_REVIEW) {
|
||||
throw new BadRequestException(
|
||||
`Signing is only allowed at workflow step ${ClaimWorkflowStep.INSURER_REVIEW}. Current: ${String(claimCase.workflow?.currentStep ?? "")}`,
|
||||
);
|
||||
}
|
||||
if (claimCase.claimStatus !== ClaimStatus.APPROVED) {
|
||||
throw new BadRequestException(
|
||||
`Claim must be insurer-approved before owner signature. Current claimStatus: ${String(claimCase.claimStatus)}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (claimCase.evaluation?.ownerInsurerApproval?.signedAt) {
|
||||
throw new ConflictException("You have already submitted a signature for this claim.");
|
||||
}
|
||||
|
||||
const activeReply =
|
||||
claimCase.evaluation?.damageExpertReplyFinal ||
|
||||
claimCase.evaluation?.damageExpertReply;
|
||||
if (!activeReply?.submittedAt) {
|
||||
throw new BadRequestException("No expert reply is available to sign off on yet.");
|
||||
}
|
||||
|
||||
const signDoc = await this.claimSignDbService.create({
|
||||
fileName: signFile.filename,
|
||||
userId: effectiveUserId,
|
||||
path: signFile.path,
|
||||
requestId: new Types.ObjectId(claimRequestId),
|
||||
} as any);
|
||||
const signId = new Types.ObjectId(String((signDoc as any)._id));
|
||||
const signedAt = new Date();
|
||||
const approvalPayload = {
|
||||
agree,
|
||||
signDetailId: signId,
|
||||
signedAt,
|
||||
};
|
||||
|
||||
const historyActor = {
|
||||
actorId: new Types.ObjectId(effectiveUserId),
|
||||
actorName: claimCase.owner?.fullName || "User",
|
||||
actorType: "user",
|
||||
};
|
||||
|
||||
if (!agree) {
|
||||
await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, {
|
||||
$set: {
|
||||
status: ClaimCaseStatus.REJECTED,
|
||||
claimStatus: ClaimStatus.REJECTED,
|
||||
"evaluation.ownerInsurerApproval": approvalPayload,
|
||||
"workflow.nextStep": null,
|
||||
},
|
||||
$push: {
|
||||
history: {
|
||||
type: "OWNER_REJECTED_INSURER_APPROVAL_PRICING",
|
||||
actor: historyActor,
|
||||
timestamp: signedAt,
|
||||
metadata: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
return {
|
||||
message:
|
||||
"Your rejection has been recorded. This claim is marked rejected and will not proceed.",
|
||||
claimRequestId,
|
||||
status: ClaimCaseStatus.REJECTED,
|
||||
claimStatus: ClaimStatus.REJECTED,
|
||||
currentStep: claimCase.workflow?.currentStep,
|
||||
accepted: false,
|
||||
};
|
||||
}
|
||||
|
||||
await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, {
|
||||
$set: {
|
||||
status: ClaimCaseStatus.COMPLETED,
|
||||
claimStatus: ClaimStatus.APPROVED,
|
||||
"evaluation.ownerInsurerApproval": approvalPayload,
|
||||
"workflow.currentStep": ClaimWorkflowStep.CLAIM_COMPLETED,
|
||||
"workflow.nextStep": ClaimWorkflowStep.CLAIM_COMPLETED,
|
||||
},
|
||||
$push: {
|
||||
"workflow.completedSteps": ClaimWorkflowStep.INSURER_REVIEW,
|
||||
history: {
|
||||
type: "OWNER_SIGNED_INSURER_APPROVAL",
|
||||
actor: historyActor,
|
||||
timestamp: signedAt,
|
||||
metadata: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
message: "Your signature has been recorded. The claim is completed.",
|
||||
claimRequestId,
|
||||
status: ClaimCaseStatus.COMPLETED,
|
||||
claimStatus: ClaimStatus.APPROVED,
|
||||
currentStep: ClaimWorkflowStep.CLAIM_COMPLETED,
|
||||
accepted: true,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 API: Get list of claims for current user (or for FIELD_EXPERT: claims from their expert-initiated IN_PERSON blame files).
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user