|
|
|
|
@@ -72,6 +72,13 @@ import { BranchDbService } from "src/client/entities/db-service/branch.db.servic
|
|
|
|
|
import { CreationMethod } from "src/request-management/entities/schema/request-management.schema";
|
|
|
|
|
import { RoleEnum } from "src/Types&Enums/role.enum";
|
|
|
|
|
import { UserRatingDto } from "./dto/user-rating.dto";
|
|
|
|
|
import {
|
|
|
|
|
canFinalizeExpertResend,
|
|
|
|
|
documentKeyAllowedForExpertResend,
|
|
|
|
|
normalizeResendDocumentKeys,
|
|
|
|
|
normalizeResendPartKeys,
|
|
|
|
|
partKeyAllowedForExpertResend,
|
|
|
|
|
} from "src/helpers/claim-expert-resend";
|
|
|
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
|
export class ClaimRequestManagementService {
|
|
|
|
|
@@ -4132,6 +4139,105 @@ export class ClaimRequestManagementService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* When the owner has uploaded every expert-requested document/part (or acknowledged description-only resend),
|
|
|
|
|
* move the claim back to the damage expert queue (same posture as after initial submission).
|
|
|
|
|
*/
|
|
|
|
|
private async tryFinalizeExpertResendAfterUserAction(
|
|
|
|
|
claimRequestId: string,
|
|
|
|
|
actorUserId: string,
|
|
|
|
|
ownerDisplayName: string,
|
|
|
|
|
): Promise<void> {
|
|
|
|
|
const claim = await this.claimCaseDbService.findById(claimRequestId);
|
|
|
|
|
if (!claim || !canFinalizeExpertResend(claim)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, {
|
|
|
|
|
$set: {
|
|
|
|
|
status: ClaimCaseStatus.WAITING_FOR_DAMAGE_EXPERT,
|
|
|
|
|
claimStatus: ClaimStatus.PENDING,
|
|
|
|
|
"workflow.currentStep": ClaimWorkflowStep.USER_SUBMISSION_COMPLETE,
|
|
|
|
|
"workflow.nextStep": ClaimWorkflowStep.EXPERT_DAMAGE_ASSESSMENT,
|
|
|
|
|
"evaluation.damageExpertResend.fulfilledAt": new Date(),
|
|
|
|
|
},
|
|
|
|
|
$push: {
|
|
|
|
|
history: {
|
|
|
|
|
type: "EXPERT_RESEND_FULFILLED",
|
|
|
|
|
actor: {
|
|
|
|
|
actorId: new Types.ObjectId(actorUserId),
|
|
|
|
|
actorName: ownerDisplayName,
|
|
|
|
|
actorType: "user",
|
|
|
|
|
},
|
|
|
|
|
timestamp: new Date(),
|
|
|
|
|
metadata: {},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* V2: Owner acknowledges a description-only expert resend (no extra documents or part photos requested).
|
|
|
|
|
*/
|
|
|
|
|
async acknowledgeExpertResendInstructionsV2(
|
|
|
|
|
claimRequestId: string,
|
|
|
|
|
currentUserId: string,
|
|
|
|
|
actor?: { sub: string; role?: string },
|
|
|
|
|
): Promise<{
|
|
|
|
|
claimRequestId: string;
|
|
|
|
|
status: string;
|
|
|
|
|
claimStatus: string;
|
|
|
|
|
currentStep: string;
|
|
|
|
|
message: string;
|
|
|
|
|
}> {
|
|
|
|
|
const claimCase = await this.claimCaseDbService.findById(claimRequestId);
|
|
|
|
|
if (!claimCase) {
|
|
|
|
|
throw new NotFoundException(`Claim case with ID ${claimRequestId} 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 can complete this step");
|
|
|
|
|
}
|
|
|
|
|
if (claimCase.workflow?.currentStep !== ClaimWorkflowStep.USER_EXPERT_RESEND) {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
`No expert resend step is active. Current step: ${claimCase.workflow?.currentStep ?? "none"}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (claimCase.status !== ClaimCaseStatus.WAITING_FOR_USER_RESEND) {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
`Claim is not waiting for resend action. Current status: ${claimCase.status}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
const r = claimCase.evaluation?.damageExpertResend;
|
|
|
|
|
if (!r || r.fulfilledAt) {
|
|
|
|
|
throw new BadRequestException("There is no active expert resend request to acknowledge.");
|
|
|
|
|
}
|
|
|
|
|
if (
|
|
|
|
|
normalizeResendDocumentKeys(r.resendDocuments).length > 0 ||
|
|
|
|
|
normalizeResendPartKeys(r.resendCarParts).length > 0
|
|
|
|
|
) {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
"Upload all requested documents and part photos before completing the resend step.",
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
await this.tryFinalizeExpertResendAfterUserAction(
|
|
|
|
|
claimRequestId,
|
|
|
|
|
effectiveUserId,
|
|
|
|
|
claimCase.owner?.fullName || "User",
|
|
|
|
|
);
|
|
|
|
|
const updated = await this.claimCaseDbService.findById(claimRequestId);
|
|
|
|
|
return {
|
|
|
|
|
claimRequestId,
|
|
|
|
|
status: String(updated?.status ?? ""),
|
|
|
|
|
claimStatus: String(updated?.claimStatus ?? ""),
|
|
|
|
|
currentStep: String(updated?.workflow?.currentStep ?? ""),
|
|
|
|
|
message: "Claim returned to the damage expert queue.",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* V2 API: Upload required document
|
|
|
|
|
*/
|
|
|
|
|
@@ -4158,11 +4264,25 @@ export class ClaimRequestManagementService {
|
|
|
|
|
throw new ForbiddenException('Only the claim owner can upload documents');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (claimCase.workflow?.currentStep !== ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS) {
|
|
|
|
|
const step = claimCase.workflow?.currentStep;
|
|
|
|
|
const isResendUpload = step === ClaimWorkflowStep.USER_EXPERT_RESEND;
|
|
|
|
|
if (!isResendUpload && step !== ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS) {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
`Invalid workflow step. Expected ${ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS}, but current step is ${claimCase.workflow?.currentStep}`
|
|
|
|
|
`Invalid workflow step. Expected ${ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS} or ${ClaimWorkflowStep.USER_EXPERT_RESEND}, but current step is ${claimCase.workflow?.currentStep}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (isResendUpload) {
|
|
|
|
|
if (claimCase.status !== ClaimCaseStatus.WAITING_FOR_USER_RESEND) {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
`Claim is not waiting for expert resend uploads. Status: ${claimCase.status}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (!documentKeyAllowedForExpertResend(claimCase, body.documentKey)) {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
`Document "${body.documentKey}" was not requested by the damage expert for this resend.`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CAR_BODY claims only allow 7 document types (no guilty_*)
|
|
|
|
|
const blameForUpload = claimCase.blameRequestId
|
|
|
|
|
@@ -4174,10 +4294,13 @@ export class ClaimRequestManagementService {
|
|
|
|
|
throw new BadRequestException(`Document type ${body.documentKey} is not required for CAR_BODY claims`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if document already uploaded
|
|
|
|
|
const existingDoc = (claimCase.requiredDocuments as any)?.get?.(body.documentKey);
|
|
|
|
|
if (existingDoc?.uploaded) {
|
|
|
|
|
throw new ConflictException(`Document ${body.documentKey} has already been uploaded`);
|
|
|
|
|
// Initial flow: each document once. Expert resend: allow replacement.
|
|
|
|
|
if (!isResendUpload) {
|
|
|
|
|
const existingDoc = (claimCase.requiredDocuments as any)?.get?.(body.documentKey)
|
|
|
|
|
?? (claimCase.requiredDocuments as any)?.[body.documentKey];
|
|
|
|
|
if (existingDoc?.uploaded) {
|
|
|
|
|
throw new ConflictException(`Document ${body.documentKey} has already been uploaded`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const fileUrl = buildFileLink(file.path);
|
|
|
|
|
@@ -4218,59 +4341,86 @@ export class ClaimRequestManagementService {
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Check if all documents are uploaded (7 for CAR_BODY, 13 for THIRD_PARTY)
|
|
|
|
|
const totalDocsRequired = isCarBodyUpload ? 7 : 13;
|
|
|
|
|
const currentDocs = claimCase.requiredDocuments || new Map();
|
|
|
|
|
const uploadedCount = (currentDocs instanceof Map ? currentDocs.size : Object.keys(currentDocs).length) + 1;
|
|
|
|
|
const allDocumentsUploaded = uploadedCount >= totalDocsRequired;
|
|
|
|
|
let allDocumentsUploaded = false;
|
|
|
|
|
let remaining = 0;
|
|
|
|
|
|
|
|
|
|
// If all documents uploaded, user flow complete (captures were done earlier in v2)
|
|
|
|
|
if (allDocumentsUploaded) {
|
|
|
|
|
updateData['status'] = ClaimCaseStatus.WAITING_FOR_DAMAGE_EXPERT;
|
|
|
|
|
updateData['claimStatus'] = ClaimStatus.PENDING;
|
|
|
|
|
updateData['workflow.currentStep'] =
|
|
|
|
|
ClaimWorkflowStep.USER_SUBMISSION_COMPLETE;
|
|
|
|
|
updateData['workflow.nextStep'] =
|
|
|
|
|
ClaimWorkflowStep.EXPERT_DAMAGE_ASSESSMENT;
|
|
|
|
|
updateData.$push.history = [
|
|
|
|
|
updateData.$push.history,
|
|
|
|
|
{
|
|
|
|
|
type: 'STEP_COMPLETED',
|
|
|
|
|
actor: {
|
|
|
|
|
actorId: new Types.ObjectId(currentUserId),
|
|
|
|
|
actorName: claimCase.owner?.fullName || 'User',
|
|
|
|
|
actorType: 'user',
|
|
|
|
|
if (!isResendUpload) {
|
|
|
|
|
// Check if all documents are uploaded (7 for CAR_BODY, 13 for THIRD_PARTY)
|
|
|
|
|
const totalDocsRequired = isCarBodyUpload ? 7 : 13;
|
|
|
|
|
const currentDocs = claimCase.requiredDocuments || new Map();
|
|
|
|
|
const uploadedCount =
|
|
|
|
|
(currentDocs instanceof Map ? currentDocs.size : Object.keys(currentDocs).length) + 1;
|
|
|
|
|
allDocumentsUploaded = uploadedCount >= totalDocsRequired;
|
|
|
|
|
remaining = totalDocsRequired - uploadedCount;
|
|
|
|
|
|
|
|
|
|
// If all documents uploaded, user flow complete (captures were done earlier in v2)
|
|
|
|
|
if (allDocumentsUploaded) {
|
|
|
|
|
updateData["status"] = ClaimCaseStatus.WAITING_FOR_DAMAGE_EXPERT;
|
|
|
|
|
updateData["claimStatus"] = ClaimStatus.PENDING;
|
|
|
|
|
updateData["workflow.currentStep"] =
|
|
|
|
|
ClaimWorkflowStep.USER_SUBMISSION_COMPLETE;
|
|
|
|
|
updateData["workflow.nextStep"] =
|
|
|
|
|
ClaimWorkflowStep.EXPERT_DAMAGE_ASSESSMENT;
|
|
|
|
|
updateData.$push.history = [
|
|
|
|
|
updateData.$push.history,
|
|
|
|
|
{
|
|
|
|
|
type: "STEP_COMPLETED",
|
|
|
|
|
actor: {
|
|
|
|
|
actorId: new Types.ObjectId(currentUserId),
|
|
|
|
|
actorName: claimCase.owner?.fullName || "User",
|
|
|
|
|
actorType: "user",
|
|
|
|
|
},
|
|
|
|
|
timestamp: new Date(),
|
|
|
|
|
metadata: {
|
|
|
|
|
stepKey: ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS,
|
|
|
|
|
description: "All required documents uploaded",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
timestamp: new Date(),
|
|
|
|
|
metadata: {
|
|
|
|
|
stepKey: ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS,
|
|
|
|
|
description: 'All required documents uploaded',
|
|
|
|
|
{
|
|
|
|
|
type: "STEP_COMPLETED",
|
|
|
|
|
actor: {
|
|
|
|
|
actorId: new Types.ObjectId(currentUserId),
|
|
|
|
|
actorName: claimCase.owner?.fullName || "User",
|
|
|
|
|
actorType: "user",
|
|
|
|
|
},
|
|
|
|
|
timestamp: new Date(),
|
|
|
|
|
metadata: {
|
|
|
|
|
stepKey: ClaimWorkflowStep.USER_SUBMISSION_COMPLETE,
|
|
|
|
|
description:
|
|
|
|
|
"User submission complete. Claim ready for damage expert review.",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 'STEP_COMPLETED',
|
|
|
|
|
actor: {
|
|
|
|
|
actorId: new Types.ObjectId(currentUserId),
|
|
|
|
|
actorName: claimCase.owner?.fullName || 'User',
|
|
|
|
|
actorType: 'user',
|
|
|
|
|
},
|
|
|
|
|
timestamp: new Date(),
|
|
|
|
|
metadata: {
|
|
|
|
|
stepKey: ClaimWorkflowStep.USER_SUBMISSION_COMPLETE,
|
|
|
|
|
description:
|
|
|
|
|
'User submission complete. Claim ready for damage expert review.',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
updateData.$push['workflow.completedSteps'] =
|
|
|
|
|
ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS;
|
|
|
|
|
];
|
|
|
|
|
updateData.$push["workflow.completedSteps"] =
|
|
|
|
|
ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, updateData);
|
|
|
|
|
|
|
|
|
|
const remaining = totalDocsRequired - uploadedCount;
|
|
|
|
|
if (isResendUpload) {
|
|
|
|
|
await this.tryFinalizeExpertResendAfterUserAction(
|
|
|
|
|
claimRequestId,
|
|
|
|
|
currentUserId,
|
|
|
|
|
claimCase.owner?.fullName || "User",
|
|
|
|
|
);
|
|
|
|
|
const refreshed = await this.claimCaseDbService.findById(claimRequestId);
|
|
|
|
|
const expertResendComplete = !!refreshed?.evaluation?.damageExpertResend?.fulfilledAt;
|
|
|
|
|
return {
|
|
|
|
|
claimRequestId: claimCase._id.toString(),
|
|
|
|
|
documentKey: body.documentKey,
|
|
|
|
|
fileUrl,
|
|
|
|
|
allDocumentsUploaded: false,
|
|
|
|
|
expertResendComplete,
|
|
|
|
|
currentStep: refreshed?.workflow?.currentStep || ClaimWorkflowStep.USER_EXPERT_RESEND,
|
|
|
|
|
message: expertResendComplete
|
|
|
|
|
? "Expert resend requirements are complete. Your claim is back in the damage expert queue."
|
|
|
|
|
: "Document uploaded for expert resend.",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const message = allDocumentsUploaded
|
|
|
|
|
? 'All documents uploaded successfully. Your claim is now ready for damage expert review.'
|
|
|
|
|
? "All documents uploaded successfully. Your claim is now ready for damage expert review."
|
|
|
|
|
: `Document uploaded successfully. ${remaining} documents remaining.`;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
@@ -4316,11 +4466,30 @@ export class ClaimRequestManagementService {
|
|
|
|
|
throw new ForbiddenException('Only the claim owner can capture parts');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (claimCase.workflow?.currentStep !== ClaimWorkflowStep.CAPTURE_PART_DAMAGES) {
|
|
|
|
|
const capStep = claimCase.workflow?.currentStep;
|
|
|
|
|
const isResendCapture = capStep === ClaimWorkflowStep.USER_EXPERT_RESEND;
|
|
|
|
|
if (!isResendCapture && capStep !== ClaimWorkflowStep.CAPTURE_PART_DAMAGES) {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
`Invalid workflow step. Expected ${ClaimWorkflowStep.CAPTURE_PART_DAMAGES}, but current step is ${claimCase.workflow?.currentStep}`
|
|
|
|
|
`Invalid workflow step. Expected ${ClaimWorkflowStep.CAPTURE_PART_DAMAGES} or ${ClaimWorkflowStep.USER_EXPERT_RESEND}, but current step is ${claimCase.workflow?.currentStep}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (isResendCapture) {
|
|
|
|
|
if (claimCase.status !== ClaimCaseStatus.WAITING_FOR_USER_RESEND) {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
`Claim is not waiting for expert resend uploads. Status: ${claimCase.status}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (body.captureType !== "part") {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
"During expert resend only damaged-part photos can be uploaded (not car angles).",
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (!partKeyAllowedForExpertResend(claimCase, body.captureKey)) {
|
|
|
|
|
throw new BadRequestException(
|
|
|
|
|
`Part "${body.captureKey}" was not requested by the damage expert for this resend.`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const fileUrl = buildFileLink(file.path);
|
|
|
|
|
const captureData = {
|
|
|
|
|
@@ -4355,11 +4524,43 @@ export class ClaimRequestManagementService {
|
|
|
|
|
updateData[`media.damagedParts.${body.captureKey}`] = captureData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const selectedBefore = (claimCase.damage?.selectedParts || []) as string[];
|
|
|
|
|
if (
|
|
|
|
|
isResendCapture &&
|
|
|
|
|
body.captureType === "part" &&
|
|
|
|
|
!selectedBefore.includes(body.captureKey)
|
|
|
|
|
) {
|
|
|
|
|
updateData.$addToSet = { "damage.selectedParts": body.captureKey };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const updatedClaim = await this.claimCaseDbService.findByIdAndUpdate(
|
|
|
|
|
claimRequestId,
|
|
|
|
|
updateData,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (isResendCapture) {
|
|
|
|
|
await this.tryFinalizeExpertResendAfterUserAction(
|
|
|
|
|
claimRequestId,
|
|
|
|
|
currentUserId,
|
|
|
|
|
claimCase.owner?.fullName || "User",
|
|
|
|
|
);
|
|
|
|
|
const refreshed = await this.claimCaseDbService.findById(claimRequestId);
|
|
|
|
|
const expertResendComplete = !!refreshed?.evaluation?.damageExpertResend?.fulfilledAt;
|
|
|
|
|
return {
|
|
|
|
|
claimRequestId: claimCase._id.toString(),
|
|
|
|
|
captureType: body.captureType,
|
|
|
|
|
captureKey: body.captureKey,
|
|
|
|
|
fileUrl,
|
|
|
|
|
allCapturesComplete: expertResendComplete,
|
|
|
|
|
expertResendComplete,
|
|
|
|
|
currentStep:
|
|
|
|
|
refreshed?.workflow?.currentStep || ClaimWorkflowStep.USER_EXPERT_RESEND,
|
|
|
|
|
message: expertResendComplete
|
|
|
|
|
? "Expert resend requirements are complete. Your claim is back in the damage expert queue."
|
|
|
|
|
: "Part photo uploaded for expert resend.",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const hasCapture = (data: any, key: string) =>
|
|
|
|
|
data && (data instanceof Map ? data.get(key) : data[key]);
|
|
|
|
|
|
|
|
|
|
@@ -4810,7 +5011,14 @@ export class ClaimRequestManagementService {
|
|
|
|
|
|
|
|
|
|
const damagedPartsData = claim.media?.damagedParts as any;
|
|
|
|
|
const damagedParts: Record<string, { captured: boolean; url?: string }> = {};
|
|
|
|
|
for (const p of claim.damage?.selectedParts || []) {
|
|
|
|
|
const resendPartKeys = normalizeResendPartKeys(
|
|
|
|
|
claim.evaluation?.damageExpertResend?.resendCarParts,
|
|
|
|
|
);
|
|
|
|
|
const partKeysForDetails = new Set<string>([
|
|
|
|
|
...((claim.damage?.selectedParts || []) as string[]),
|
|
|
|
|
...resendPartKeys,
|
|
|
|
|
]);
|
|
|
|
|
for (const p of partKeysForDetails) {
|
|
|
|
|
const cap = hasCapture(damagedPartsData, p);
|
|
|
|
|
damagedParts[p] = {
|
|
|
|
|
captured: !!cap,
|
|
|
|
|
@@ -4818,6 +5026,17 @@ export class ClaimRequestManagementService {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const er = claim.evaluation?.damageExpertResend;
|
|
|
|
|
const expertResend =
|
|
|
|
|
er && (er.resendDescription || (er.resendDocuments?.length ?? 0) > 0 || (er.resendCarParts?.length ?? 0) > 0)
|
|
|
|
|
? {
|
|
|
|
|
resendDescription: er.resendDescription,
|
|
|
|
|
resendDocuments: normalizeResendDocumentKeys(er.resendDocuments),
|
|
|
|
|
resendCarParts: Array.isArray(er.resendCarParts) ? er.resendCarParts : [],
|
|
|
|
|
fulfilledAt: er.fulfilledAt,
|
|
|
|
|
}
|
|
|
|
|
: undefined;
|
|
|
|
|
|
|
|
|
|
const maskSheba = (s?: string) =>
|
|
|
|
|
s ? s.replace(/^(.{4})(.*)(.{4})$/, 'IR$1************$3') : undefined;
|
|
|
|
|
const maskNationalCode = (s?: string) =>
|
|
|
|
|
@@ -4851,6 +5070,7 @@ export class ClaimRequestManagementService {
|
|
|
|
|
requiredDocuments: Object.keys(requiredDocumentsStatus).length > 0 ? requiredDocumentsStatus : undefined,
|
|
|
|
|
carAngles,
|
|
|
|
|
damagedParts,
|
|
|
|
|
expertResend,
|
|
|
|
|
userRating: claim.userRating
|
|
|
|
|
? {
|
|
|
|
|
progressSpeed: claim.userRating.progressSpeed,
|
|
|
|
|
|