forked from Yara724/api
Fixed bugs of car-body steps
This commit is contained in:
@@ -3525,7 +3525,23 @@ export class ClaimRequestManagementService {
|
||||
}
|
||||
|
||||
// 5. Convert selected parts to storage format (simple array of strings)
|
||||
const selectedParts = body.selectedParts;
|
||||
// Backward compatibility: some clients may still send legacy `carPartDamage` object.
|
||||
let selectedParts = Array.isArray((body as any)?.selectedParts)
|
||||
? ((body as any).selectedParts as string[])
|
||||
: [];
|
||||
if (selectedParts.length === 0 && (body as any)?.carPartDamage) {
|
||||
this.assertCarPartDamageAtMostTwoOfFourSides(
|
||||
(body as any).carPartDamage as CarDamagePartDto,
|
||||
);
|
||||
selectedParts = this.carDamagePartDtoToOuterPartSlugs(
|
||||
(body as any).carPartDamage as CarDamagePartDto,
|
||||
);
|
||||
}
|
||||
if (selectedParts.length === 0) {
|
||||
throw new BadRequestException(
|
||||
"selectedParts is required and must contain at least one item",
|
||||
);
|
||||
}
|
||||
|
||||
// 6. Update claim case with selected parts and move to next step
|
||||
const updatedClaim = await this.claimCaseDbService.findByIdAndUpdate(
|
||||
@@ -3548,8 +3564,8 @@ export class ClaimRequestManagementService {
|
||||
metadata: {
|
||||
stepKey: ClaimWorkflowStep.SELECT_OUTER_PARTS,
|
||||
selectedParts: selectedParts,
|
||||
partsCount: selectedParts.length,
|
||||
description: `User selected ${selectedParts.length} damaged outer parts`,
|
||||
partsCount: selectedParts?.length,
|
||||
description: `User selected ${selectedParts?.length} damaged outer parts`,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3561,7 +3577,7 @@ export class ClaimRequestManagementService {
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
`Outer parts selected for claim ${claimRequestId}: ${selectedParts.length} parts`,
|
||||
`Outer parts selected for claim ${claimRequestId}: ${selectedParts?.length} parts`,
|
||||
);
|
||||
|
||||
// 7. Return response
|
||||
@@ -3607,6 +3623,7 @@ export class ClaimRequestManagementService {
|
||||
body: SelectOtherPartsV2Dto,
|
||||
currentUserId: string,
|
||||
actor?: { sub: string; role?: string },
|
||||
file?: Express.Multer.File,
|
||||
): Promise<SelectOtherPartsV2ResponseDto> {
|
||||
try {
|
||||
// 1. Validate claim exists
|
||||
@@ -3645,40 +3662,108 @@ export class ClaimRequestManagementService {
|
||||
}
|
||||
|
||||
// 5. Prepare data
|
||||
const otherParts = body.otherParts || [];
|
||||
const shebaNumber = body.shebaNumber;
|
||||
const nationalCode = body.nationalCodeOfOwner;
|
||||
// Backward compatibility aliases:
|
||||
// - shebaNumber <- sheba
|
||||
// - nationalCodeOfOwner <- nationalCodeOfInsurer
|
||||
let otherParts = Array.isArray((body as any)?.otherParts)
|
||||
? (body as any).otherParts
|
||||
: [];
|
||||
// Multipart clients may send otherParts as JSON string
|
||||
if (!Array.isArray((body as any)?.otherParts) && typeof (body as any)?.otherParts === "string") {
|
||||
try {
|
||||
const parsed = JSON.parse((body as any).otherParts);
|
||||
otherParts = Array.isArray(parsed) ? parsed : [];
|
||||
} catch {
|
||||
otherParts = [];
|
||||
}
|
||||
}
|
||||
const shebaInput = String(
|
||||
((body as any).shebaNumber ?? (body as any).sheba ?? "") as string,
|
||||
)
|
||||
.replace(/\s/g, "");
|
||||
|
||||
// 6. Update claim case with other parts, bank info and move to next step
|
||||
const updatedClaim = await this.claimCaseDbService.findByIdAndUpdate(
|
||||
claimRequestId,
|
||||
{
|
||||
'damage.otherParts': otherParts.length > 0 ? otherParts : undefined,
|
||||
'money.sheba': shebaNumber,
|
||||
'money.nationalCodeOfInsurer': nationalCode,
|
||||
'status': ClaimCaseStatus.UPLOADING_REQUIRED_DOCUMENTS,
|
||||
'workflow.currentStep': ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS,
|
||||
'workflow.nextStep': ClaimWorkflowStep.CAPTURE_PART_DAMAGES,
|
||||
$push: {
|
||||
'workflow.completedSteps': ClaimWorkflowStep.SELECT_OTHER_PARTS,
|
||||
history: {
|
||||
type: 'STEP_COMPLETED',
|
||||
actor: {
|
||||
actorId: new Types.ObjectId(currentUserId),
|
||||
actorName: claimCase.owner?.fullName || 'User',
|
||||
actorType: 'user',
|
||||
},
|
||||
timestamp: new Date(),
|
||||
metadata: {
|
||||
stepKey: ClaimWorkflowStep.SELECT_OTHER_PARTS,
|
||||
otherParts: otherParts,
|
||||
otherPartsCount: otherParts.length,
|
||||
hasBankInfo: true,
|
||||
description: `User selected ${otherParts.length} other damaged parts and provided bank information`,
|
||||
},
|
||||
const shebaDigits = shebaInput.replace(/^IR/i, "");
|
||||
const shebaNumber = `IR${shebaDigits}`;
|
||||
const nationalCode = String(
|
||||
((body as any).nationalCodeOfOwner ??
|
||||
(body as any).nationalCodeOfInsurer ??
|
||||
"") as string,
|
||||
).replace(/\s/g, "");
|
||||
if (!/^[0-9]{24}$/.test(shebaDigits)) {
|
||||
throw new BadRequestException(
|
||||
"shebaNumber is required and must be valid (IR + 24 digits or only 24 digits)",
|
||||
);
|
||||
}
|
||||
if (!/^[0-9]{10}$/.test(nationalCode)) {
|
||||
throw new BadRequestException(
|
||||
"nationalCodeOfOwner is required and must be exactly 10 digits",
|
||||
);
|
||||
}
|
||||
|
||||
const updatePayload: any = {
|
||||
'damage.otherParts': otherParts.length > 0 ? otherParts : undefined,
|
||||
'money.sheba': shebaNumber,
|
||||
'money.nationalCodeOfInsurer': nationalCode,
|
||||
'status': ClaimCaseStatus.UPLOADING_REQUIRED_DOCUMENTS,
|
||||
'workflow.currentStep': ClaimWorkflowStep.UPLOAD_REQUIRED_DOCUMENTS,
|
||||
'workflow.nextStep': ClaimWorkflowStep.CAPTURE_PART_DAMAGES,
|
||||
$push: {
|
||||
'workflow.completedSteps': ClaimWorkflowStep.SELECT_OTHER_PARTS,
|
||||
history: {
|
||||
type: 'STEP_COMPLETED',
|
||||
actor: {
|
||||
actorId: new Types.ObjectId(currentUserId),
|
||||
actorName: claimCase.owner?.fullName || 'User',
|
||||
actorType: 'user',
|
||||
},
|
||||
timestamp: new Date(),
|
||||
metadata: {
|
||||
stepKey: ClaimWorkflowStep.SELECT_OTHER_PARTS,
|
||||
otherParts: otherParts,
|
||||
otherPartsCount: otherParts.length,
|
||||
hasBankInfo: true,
|
||||
hasGreenCardUpload: !!file,
|
||||
description: `User selected ${otherParts.length} other damaged parts and provided bank information`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (file) {
|
||||
const existingGreen =
|
||||
(claimCase.requiredDocuments as any)?.get?.(
|
||||
ClaimRequiredDocumentType.CAR_GREEN_CARD,
|
||||
) ||
|
||||
(claimCase.requiredDocuments as any)?.[
|
||||
ClaimRequiredDocumentType.CAR_GREEN_CARD
|
||||
];
|
||||
if (existingGreen?.uploaded) {
|
||||
throw new ConflictException(
|
||||
"car_green_card has already been uploaded for this claim",
|
||||
);
|
||||
}
|
||||
const docRef = await this.claimRequiredDocumentDbService.create({
|
||||
path: file.path,
|
||||
fileName: file.filename,
|
||||
claimId: new Types.ObjectId(claimRequestId),
|
||||
documentType: ClaimRequiredDocumentType.CAR_GREEN_CARD,
|
||||
uploadedAt: new Date(),
|
||||
});
|
||||
updatePayload[
|
||||
`requiredDocuments.${ClaimRequiredDocumentType.CAR_GREEN_CARD}`
|
||||
] = {
|
||||
fileId: docRef._id,
|
||||
filePath: file.path,
|
||||
fileName: file.filename,
|
||||
uploaded: true,
|
||||
uploadedAt: new Date(),
|
||||
};
|
||||
}
|
||||
|
||||
// 6. Update claim case with other parts, bank info and optional green card file
|
||||
const updatedClaim = await this.claimCaseDbService.findByIdAndUpdate(
|
||||
claimRequestId,
|
||||
updatePayload,
|
||||
);
|
||||
|
||||
if (!updatedClaim) {
|
||||
@@ -3690,8 +3775,8 @@ export class ClaimRequestManagementService {
|
||||
);
|
||||
|
||||
// 7. Mask sensitive data for response
|
||||
const maskedSheba = shebaNumber.replace(/^(.{4})(.*)(.{4})$/, 'IR$1************$3');
|
||||
const maskedNationalCode = nationalCode.replace(/^(.{2})(.*)(.{2})$/, '$1******$3');
|
||||
const maskedSheba = `IR${shebaDigits.slice(0, 4)}************${shebaDigits.slice(-4)}`;
|
||||
const maskedNationalCode = `${nationalCode.slice(0, 2)}******${nationalCode.slice(-2)}`;
|
||||
|
||||
// 8. Return response
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user