forked from Yara724/api
YARA-743
This commit is contained in:
25
src/expert-claim/dto/update-claim-damaged-parts-v2.dto.ts
Normal file
25
src/expert-claim/dto/update-claim-damaged-parts-v2.dto.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
|
import {
|
||||||
|
ArrayMinSize,
|
||||||
|
ArrayUnique,
|
||||||
|
IsArray,
|
||||||
|
IsEnum,
|
||||||
|
IsNotEmpty,
|
||||||
|
} from "class-validator";
|
||||||
|
import { OuterCarPart } from "src/claim-request-management/dto/select-outer-parts-v2.dto";
|
||||||
|
|
||||||
|
export class UpdateClaimDamagedPartsV2Dto {
|
||||||
|
@ApiProperty({
|
||||||
|
description: "Updated list of selected damaged outer parts",
|
||||||
|
enum: OuterCarPart,
|
||||||
|
isArray: true,
|
||||||
|
example: ["hood", "front_bumper", "front_left_fender"],
|
||||||
|
})
|
||||||
|
@IsNotEmpty()
|
||||||
|
@IsArray()
|
||||||
|
@ArrayMinSize(1)
|
||||||
|
@ArrayUnique()
|
||||||
|
@IsEnum(OuterCarPart, { each: true })
|
||||||
|
selectedParts: OuterCarPart[];
|
||||||
|
}
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@ import { ClaimWorkflowStep } from "src/Types&Enums/claim-request-management/clai
|
|||||||
import { GetClaimListV2ResponseDto, ClaimListItemV2Dto } from "./dto/claim-list-v2.dto";
|
import { GetClaimListV2ResponseDto, ClaimListItemV2Dto } from "./dto/claim-list-v2.dto";
|
||||||
import { ClaimDetailV2ResponseDto } from "./dto/claim-detail-v2.dto";
|
import { ClaimDetailV2ResponseDto } from "./dto/claim-detail-v2.dto";
|
||||||
import { ClaimSubmitReplyDto, ClaimSubmitResendDto } from "./dto/reply.dto";
|
import { ClaimSubmitReplyDto, ClaimSubmitResendDto } from "./dto/reply.dto";
|
||||||
|
import { UpdateClaimDamagedPartsV2Dto } from "./dto/update-claim-damaged-parts-v2.dto";
|
||||||
import { ClaimFactorsImageDbService } from "src/claim-request-management/entites/db-service/factor-image.db.service";
|
import { ClaimFactorsImageDbService } from "src/claim-request-management/entites/db-service/factor-image.db.service";
|
||||||
import { ClaimRequiredDocumentDbService } from "src/claim-request-management/entites/db-service/claim-required-document.db.service";
|
import { ClaimRequiredDocumentDbService } from "src/claim-request-management/entites/db-service/claim-required-document.db.service";
|
||||||
import { FactorStatus } from "src/Types&Enums/claim-request-management/factor-status.enum";
|
import { FactorStatus } from "src/Types&Enums/claim-request-management/factor-status.enum";
|
||||||
@@ -1969,4 +1970,77 @@ export class ExpertClaimService {
|
|||||||
updatedAt: (claim as any).updatedAt,
|
updatedAt: (claim as any).updatedAt,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* V2: Damage expert can modify selected damaged parts before final submit.
|
||||||
|
* Allowed only when claim is EXPERT_REVIEWING and locked by this expert.
|
||||||
|
*/
|
||||||
|
async updateClaimDamagedPartsV2(
|
||||||
|
claimRequestId: string,
|
||||||
|
body: UpdateClaimDamagedPartsV2Dto,
|
||||||
|
actor: any,
|
||||||
|
) {
|
||||||
|
const claim = await this.claimCaseDbService.findById(claimRequestId);
|
||||||
|
if (!claim) {
|
||||||
|
throw new NotFoundException("Claim request not found");
|
||||||
|
}
|
||||||
|
if (claim.status !== ClaimCaseStatus.EXPERT_REVIEWING) {
|
||||||
|
throw new BadRequestException(
|
||||||
|
`Claim is not in EXPERT_REVIEWING state. Current status: ${claim.status}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!claim.workflow?.locked) {
|
||||||
|
throw new ForbiddenException(
|
||||||
|
"You must lock the claim before modifying damaged parts",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (claim.workflow.lockedBy?.actorId?.toString() !== actor.sub) {
|
||||||
|
throw new ForbiddenException("This claim is locked by another expert");
|
||||||
|
}
|
||||||
|
|
||||||
|
const previous = Array.isArray((claim as any).damage?.selectedParts)
|
||||||
|
? [...(claim as any).damage.selectedParts]
|
||||||
|
: [];
|
||||||
|
const selectedParts = body.selectedParts as string[];
|
||||||
|
|
||||||
|
if (!(claim as any).damage) (claim as any).damage = {};
|
||||||
|
(claim as any).damage.selectedParts = selectedParts;
|
||||||
|
|
||||||
|
// Keep damaged-parts captures consistent with updated selection.
|
||||||
|
const damagedPartsMedia = (claim as any).media?.damagedParts;
|
||||||
|
if (damagedPartsMedia) {
|
||||||
|
const selectedSet = new Set(selectedParts);
|
||||||
|
if (damagedPartsMedia instanceof Map) {
|
||||||
|
for (const key of Array.from(damagedPartsMedia.keys())) {
|
||||||
|
if (!selectedSet.has(key)) damagedPartsMedia.delete(key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const key of Object.keys(damagedPartsMedia)) {
|
||||||
|
if (!selectedSet.has(key)) delete damagedPartsMedia[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray((claim as any).history)) (claim as any).history = [];
|
||||||
|
(claim as any).history.push({
|
||||||
|
event: "EXPERT_DAMAGED_PARTS_UPDATED",
|
||||||
|
performedBy: actor.sub,
|
||||||
|
performedByName: actor.fullName,
|
||||||
|
performedAt: new Date(),
|
||||||
|
note: "Damage expert edited selected damaged parts",
|
||||||
|
metadata: {
|
||||||
|
previousSelectedParts: previous,
|
||||||
|
selectedParts,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await (claim as any).save();
|
||||||
|
|
||||||
|
return {
|
||||||
|
claimRequestId: claim._id.toString(),
|
||||||
|
selectedParts,
|
||||||
|
previousSelectedParts: previous,
|
||||||
|
message: "Damaged parts updated successfully.",
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { CurrentUser } from "src/decorators/user.decorator";
|
|||||||
import { RoleEnum } from "src/Types&Enums/role.enum";
|
import { RoleEnum } from "src/Types&Enums/role.enum";
|
||||||
import { ExpertClaimService } from "./expert-claim.service";
|
import { ExpertClaimService } from "./expert-claim.service";
|
||||||
import { SubmitExpertReplyV2Dto } from "./dto/expert-claim-v2.dto";
|
import { SubmitExpertReplyV2Dto } from "./dto/expert-claim-v2.dto";
|
||||||
|
import { UpdateClaimDamagedPartsV2Dto } from "./dto/update-claim-damaged-parts-v2.dto";
|
||||||
|
|
||||||
class InPersonVisitV2Dto {
|
class InPersonVisitV2Dto {
|
||||||
@ApiPropertyOptional({ example: 'Paint damage requires physical inspection' })
|
@ApiPropertyOptional({ example: 'Paint damage requires physical inspection' })
|
||||||
@@ -107,4 +108,24 @@ export class ExpertClaimV2Controller {
|
|||||||
body?.note,
|
body?.note,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Patch("request/:claimRequestId/damaged-parts")
|
||||||
|
@ApiOperation({
|
||||||
|
summary: "Edit selected damaged parts (V2)",
|
||||||
|
description:
|
||||||
|
"Damage expert can modify selected damaged parts while claim is in EXPERT_REVIEWING and locked by the same expert.",
|
||||||
|
})
|
||||||
|
@ApiParam({ name: "claimRequestId" })
|
||||||
|
@ApiBody({ type: UpdateClaimDamagedPartsV2Dto })
|
||||||
|
async updateClaimDamagedPartsV2(
|
||||||
|
@Param("claimRequestId") claimRequestId: string,
|
||||||
|
@Body() body: UpdateClaimDamagedPartsV2Dto,
|
||||||
|
@CurrentUser() actor,
|
||||||
|
) {
|
||||||
|
return await this.expertClaimService.updateClaimDamagedPartsV2(
|
||||||
|
claimRequestId,
|
||||||
|
body,
|
||||||
|
actor,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user