forked from Yara724/api
Added in-person expert
This commit is contained in:
32
src/request-management/dto/expert-complete-claim-data.dto.ts
Normal file
32
src/request-management/dto/expert-complete-claim-data.dto.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { ApiPropertyOptional } from "@nestjs/swagger";
|
||||
import { CarDamagePartDto } from "src/claim-request-management/dto/car-part.dto";
|
||||
|
||||
/**
|
||||
* DTO for field expert to submit claim-needed data in one go (IN_PERSON flow).
|
||||
* All fields optional so expert can submit in one or two steps (e.g. car parts first, then sheba/other).
|
||||
*/
|
||||
export class ExpertCompleteClaimDataDto {
|
||||
@ApiPropertyOptional({
|
||||
description: "Car part damage selection (same as selectCarPartDamage). Required for first claim data step.",
|
||||
type: CarDamagePartDto,
|
||||
})
|
||||
carPartDamage?: CarDamagePartDto;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description: "Sheba number",
|
||||
example: "IR123456789012345678901234",
|
||||
})
|
||||
sheba?: string;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description: "National code of insurer",
|
||||
example: "1234567890",
|
||||
})
|
||||
nationalCodeOfInsurer?: string;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description: "Other parts / extra damage items",
|
||||
example: [{ "حسگر درها": true }],
|
||||
})
|
||||
otherParts?: any[];
|
||||
}
|
||||
@@ -34,17 +34,83 @@ import { CreateExpertInitiatedFileDto } from "./dto/expert-initiated.dto";
|
||||
import { ExpertCompleteThirdPartyFormDto } from "./dto/expert-complete-third-party-form.dto";
|
||||
import { ExpertCompleteCarBodyFormDto } from "./dto/expert-complete-car-body-form.dto";
|
||||
import { ExpertAccidentFieldsDto } from "./dto/expert-accident-fields.dto";
|
||||
import { ExpertCompleteClaimDataDto } from "./dto/expert-complete-claim-data.dto";
|
||||
import { ClaimRequestManagementService } from "src/claim-request-management/claim-request-management.service";
|
||||
|
||||
@ApiTags("expert-initiated-blame")
|
||||
@Controller("expert-initiated-blame")
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(LocalActorAuthGuard, RolesGuard)
|
||||
@Roles(RoleEnum.EXPERT, RoleEnum.DAMAGE_EXPERT)
|
||||
@Roles(RoleEnum.FIELD_EXPERT)
|
||||
export class ExpertInitiatedController {
|
||||
constructor(
|
||||
private readonly requestManagementService: RequestManagementService,
|
||||
private readonly claimRequestManagementService: ClaimRequestManagementService,
|
||||
) {}
|
||||
|
||||
@Get("my-files")
|
||||
@ApiOperation({
|
||||
summary: "List my expert-initiated files",
|
||||
description:
|
||||
"Returns all blame files created by the current field expert (their panel).",
|
||||
})
|
||||
@ApiResponse({ status: 200, description: "List of expert-initiated files" })
|
||||
async getMyFiles(@CurrentUser() expert: any) {
|
||||
return await this.requestManagementService.getMyExpertInitiatedFiles(
|
||||
expert,
|
||||
);
|
||||
}
|
||||
|
||||
@Post("complete-blame-data/:requestId")
|
||||
@ApiOperation({
|
||||
summary: "Submit all blame-needed data",
|
||||
description:
|
||||
"Single endpoint to complete blame form: send THIRD_PARTY or CAR_BODY form data according to file type. " +
|
||||
"Video and voice can be uploaded separately.",
|
||||
})
|
||||
@ApiParam({ name: "requestId", description: "ID of the expert-initiated file" })
|
||||
@ApiBody({
|
||||
description:
|
||||
"Send ExpertCompleteThirdPartyFormDto for THIRD_PARTY files or ExpertCompleteCarBodyFormDto for CAR_BODY files (according to file type).",
|
||||
})
|
||||
@ApiResponse({ status: 200, description: "Blame form completed successfully" })
|
||||
async completeBlameData(
|
||||
@CurrentUser() expert: any,
|
||||
@Param("requestId") requestId: string,
|
||||
@Body() formData: any,
|
||||
) {
|
||||
return await this.requestManagementService.completeBlameData(
|
||||
expert,
|
||||
requestId,
|
||||
formData,
|
||||
);
|
||||
}
|
||||
|
||||
@Post("complete-claim-data/:claimRequestId")
|
||||
@ApiOperation({
|
||||
summary: "Submit claim-needed data",
|
||||
description:
|
||||
"Field expert fills claim data for expert-initiated IN_PERSON files (car part damage, sheba, national code, other parts). " +
|
||||
"Only the initiating expert can call this.",
|
||||
})
|
||||
@ApiParam({
|
||||
name: "claimRequestId",
|
||||
description: "ID of the claim file (created from the expert-initiated blame file)",
|
||||
})
|
||||
@ApiBody({ type: ExpertCompleteClaimDataDto })
|
||||
@ApiResponse({ status: 200, description: "Claim data updated successfully" })
|
||||
async completeClaimData(
|
||||
@CurrentUser() expert: any,
|
||||
@Param("claimRequestId") claimRequestId: string,
|
||||
@Body() dto: ExpertCompleteClaimDataDto,
|
||||
) {
|
||||
return await this.claimRequestManagementService.expertCompleteClaimData(
|
||||
claimRequestId,
|
||||
expert,
|
||||
dto,
|
||||
);
|
||||
}
|
||||
|
||||
@Post("create")
|
||||
@ApiOperation({
|
||||
summary: "Create expert-initiated blame file",
|
||||
|
||||
@@ -2005,8 +2005,13 @@ export class RequestManagementService {
|
||||
request: RequestManagementModel,
|
||||
user: any,
|
||||
): Promise<void> {
|
||||
// If user is not an expert, no verification needed (normal flow)
|
||||
if (user.role !== RoleEnum.EXPERT && user.role !== RoleEnum.DAMAGE_EXPERT) {
|
||||
// If user is not an expert type, no verification needed (normal flow)
|
||||
const expertRoles = [
|
||||
RoleEnum.EXPERT,
|
||||
RoleEnum.DAMAGE_EXPERT,
|
||||
RoleEnum.FIELD_EXPERT,
|
||||
];
|
||||
if (!expertRoles.includes(user.role)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2155,6 +2160,60 @@ export class RequestManagementService {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* List all expert-initiated blame files for the current field expert (their panel).
|
||||
* Only files where initiatedBy === current user are returned.
|
||||
*/
|
||||
async getMyExpertInitiatedFiles(expert: any): Promise<any[]> {
|
||||
const expertId = new Types.ObjectId(expert.sub);
|
||||
const files = await this.requestManagementDbService.findAll({
|
||||
expertInitiated: true,
|
||||
initiatedBy: expertId,
|
||||
});
|
||||
return (files || []).map((f) => ({
|
||||
_id: f._id,
|
||||
requestNumber: f.requestNumber,
|
||||
type: f.type,
|
||||
creationMethod: f.creationMethod,
|
||||
blameStatus: f.blameStatus,
|
||||
currentStep: f.currentStep,
|
||||
nextStep: f.nextStep,
|
||||
createdAt: f.createdAt,
|
||||
steps: f.steps,
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Single endpoint handler: complete all blame-needed data.
|
||||
* Routes to THIRD_PARTY or CAR_BODY completion based on request type.
|
||||
*/
|
||||
async completeBlameData(
|
||||
expert: any,
|
||||
requestId: string,
|
||||
formData: any,
|
||||
): Promise<RequestManagementDtoRs> {
|
||||
const request = await this.requestManagementDbService.findOne(requestId);
|
||||
if (!request) {
|
||||
throw new NotFoundException("Request not found");
|
||||
}
|
||||
if (!request.expertInitiated) {
|
||||
throw new BadRequestException(
|
||||
"This endpoint is only for expert-initiated files",
|
||||
);
|
||||
}
|
||||
await this.verifyExpertAccess(request, expert);
|
||||
|
||||
if (request.type === "THIRD_PARTY") {
|
||||
return this.expertCompleteThirdPartyForm(expert, requestId, formData);
|
||||
}
|
||||
if (request.type === "CAR_BODY") {
|
||||
return this.expertCompleteCarBodyForm(expert, requestId, formData);
|
||||
}
|
||||
throw new BadRequestException(
|
||||
"Unknown file type. Must be THIRD_PARTY or CAR_BODY.",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expert completes all information for IN_PERSON THIRD_PARTY file at once
|
||||
* This replaces the step-by-step flow for experts filling files on-site
|
||||
|
||||
Reference in New Issue
Block a user