From 8d6fa3daacf79c87b1ecfc4e1d84ceaeeff422a6 Mon Sep 17 00:00:00 2001 From: Soheil Hajizadeh Date: Tue, 10 Mar 2026 01:06:30 +0330 Subject: [PATCH] update the blame service --- .../request-management.service.ts | 93 +++++++++++-------- .../request-management.v2.controller.ts | 16 +++- 2 files changed, 67 insertions(+), 42 deletions(-) diff --git a/src/request-management/request-management.service.ts b/src/request-management/request-management.service.ts index 2b42af3..dbea7e9 100644 --- a/src/request-management/request-management.service.ts +++ b/src/request-management/request-management.service.ts @@ -269,8 +269,7 @@ export class RequestManagementService { const step = stepByNumber ?? stepByKey; if (!step) { throw new InternalServerErrorException( - `Workflow step not found (${stepNumber ? `stepNumber=${stepNumber}` : ""}${ - stepNumber && stepKey ? ", " : "" + `Workflow step not found (${stepNumber ? `stepNumber=${stepNumber}` : ""}${stepNumber && stepKey ? ", " : "" }${stepKey ? `stepKey=${stepKey}` : ""})`, ); } @@ -304,7 +303,7 @@ export class RequestManagementService { private readonly workflowStepDbService: WorkflowStepDbService, private readonly hashService: HashService, private readonly userAuthService: UserAuthService, - ) {} + ) { } async createRequestV2(user: any, type: BlameRequestType) { const firstStep = await this.getWorkflowStep({ stepNumber: 1 }); @@ -768,8 +767,7 @@ export class RequestManagementService { ); if (err?.response) { this.logger.error( - `[TEJARAT] block inquiry response for request=${req._id}: status=${ - err.response.status + `[TEJARAT] block inquiry response for request=${req._id}: status=${err.response.status }, data=${JSON.stringify(err.response.data)}`, ); } @@ -1310,10 +1308,10 @@ export class RequestManagementService { if (foundRequest.expertInitiated && foundRequest.creationMethod === CreationMethod.LINK) { // User should already be set in firstPartyDetails or secondPartyDetails const isFirstParty = foundRequest.firstPartyDetails?.firstPartyId?.toString() === user.sub || - foundRequest.firstPartyDetails?.firstPartyPhoneNumber === user.username; + foundRequest.firstPartyDetails?.firstPartyPhoneNumber === user.username; const isSecondParty = foundRequest.secondPartyDetails?.secondPartyId?.toString() === user.sub || - foundRequest.secondPartyDetails?.secondPartyPhoneNumber === user.username; - + foundRequest.secondPartyDetails?.secondPartyPhoneNumber === user.username; + if (!isFirstParty && !isSecondParty) { throw new ForbiddenException( "You are not authorized to complete this file. This file was created by an expert for specific parties.", @@ -1357,9 +1355,9 @@ export class RequestManagementService { ); } else if ( foundRequest?.firstPartyDetails?.firstPartyPhoneNumber == user.username || - (foundRequest.expertInitiated && - foundRequest.creationMethod === CreationMethod.LINK && - foundRequest.firstPartyDetails?.firstPartyId?.toString() === user.sub) + (foundRequest.expertInitiated && + foundRequest.creationMethod === CreationMethod.LINK && + foundRequest.firstPartyDetails?.firstPartyId?.toString() === user.sub) ) { // Normal flow or link-based - set full firstPartyDetails const updatePayload: any = { @@ -1373,7 +1371,7 @@ export class RequestManagementService { nextStep: StepsEnum.F_videoUpload, $push: { steps: StepsEnum.F_InitialForm }, }; - + // For link-based expert-initiated files, ensure filledBy is set if (foundRequest.expertInitiated && foundRequest.creationMethod === CreationMethod.LINK) { updatePayload.$set = { filledBy: FilledBy.CUSTOMER }; @@ -1492,7 +1490,7 @@ export class RequestManagementService { partyType === "firstParty" ? StepsEnum.F_addPlate : StepsEnum.S_addPlate; const currentStep = partyType === "firstParty" ? StepsEnum.F_addPlate : StepsEnum.S_addPlate; - + // Determine next step based on request type let nextStep: StepsEnum; if (request.type === "CAR_BODY") { @@ -1635,8 +1633,8 @@ export class RequestManagementService { // Determine if the current user is the first party // Check if nextStep is firstParty-addPlate OR if user is the first party phone number const isFirstParty = - (request.nextStep === StepsEnum.F_addPlate || - request.currentStep === StepsEnum.F_addPlate) && + (request.nextStep === StepsEnum.F_addPlate || + request.currentStep === StepsEnum.F_addPlate) && request.firstPartyDetails.firstPartyPhoneNumber === user.username; if (!isFirstParty) { @@ -1787,7 +1785,7 @@ export class RequestManagementService { const findRequest = await this.requestManagementDbService.findOne(requestId); if (!findRequest) throw new NotFoundException("requestId not found"); - + // Allow first party only if (findRequest.firstPartyDetails.firstPartyId == new Types.ObjectId(userId)) { await this.requestManagementDbService.findAndUpdate( @@ -1799,7 +1797,7 @@ export class RequestManagementService { $push: { steps: StepsEnum.F_addLocation }, // Ensure step is saved }, ); - + return new RequestManagementDtoRs( findRequest.firstPartyDetails.firstPartyId, findRequest?.secondPartyDetails?.secondPartyId || null, @@ -1840,7 +1838,7 @@ export class RequestManagementService { if (!request) { throw new NotFoundException("request is not found"); } - + const voiceDoc = await this.blameVoiceDbService.create({ fileName: voice.filename, path: voice.path, @@ -1990,7 +1988,7 @@ export class RequestManagementService { ); } - const nextStepMessage = request.type === "CAR_BODY" + const nextStepMessage = request.type === "CAR_BODY" ? "Please sign the document to complete your request" : "add secondParty to request"; @@ -2798,7 +2796,7 @@ export class RequestManagementService { const replyField = isObjection ? "expertSubmitReplyFinal" : "expertSubmitReply"; - + // Handle cases where firstPartyId might be undefined (e.g., IN_PERSON expert-filled files) const firstPartyId = request.firstPartyDetails?.firstPartyId; if (!firstPartyId) { @@ -2806,7 +2804,7 @@ export class RequestManagementService { "First party ID is missing. Please ensure the file has been properly initialized.", ); } - + const isFirstParty = userId === firstPartyId.toString(); const currentPartyKey = isFirstParty @@ -2859,13 +2857,13 @@ export class RequestManagementService { // (CAR_BODY requests might not have actorLocked set) if (request.actorLocked?.actorId) { // Convert ObjectIds to strings safely - const actorIdStr = request.actorLocked.actorId.toString ? - request.actorLocked.actorId.toString() : + const actorIdStr = request.actorLocked.actorId.toString ? + request.actorLocked.actorId.toString() : String(request.actorLocked.actorId); - const requestIdStr = request._id.toString ? - request._id.toString() : + const requestIdStr = request._id.toString ? + request._id.toString() : String(request._id); - + await this.updateDamageExpertStats( actorIdStr, requestIdStr, @@ -3777,6 +3775,25 @@ export class RequestManagementService { })); } + async getAllBlameRequestsV2(user: any): Promise { + console.log(user) + try { + const requests = await this.blameRequestDbService.find({ + parties: { + $elemMatch: { + 'person.userId': new Types.ObjectId(user.sub) + } + } + }, { select: "requestNo type status blameStatus createdAt updatedAt" }); + return requests; + } catch (err) { + this.logger.error("Error: ", err); + throw new InternalServerErrorException( + "Something Went Wrong", + ); + } + } + /** * V2: Get one blame request by id. Access allowed if current user is a party (by userId or phone) * or the initiating field expert. For expert-initiated LINK, party access by phone is sufficient. @@ -4562,7 +4579,7 @@ export class RequestManagementService { const clientName = sandHubReport?.CompanyName || sandHubReport?.LastCompanyName; const companyCode = sandHubReport?.CompanyCode; - + // Try to find client by company code first (more reliable) const client = companyCode ? await this.clientService.findClientWithCompanyCode(+companyCode) @@ -4619,7 +4636,7 @@ export class RequestManagementService { const clientName = sandHubReport?.CompanyName || sandHubReport?.LastCompanyName; const companyCode = sandHubReport?.CompanyCode; - + // Try to find client by company code first (more reliable) const client = companyCode ? await this.clientService.findClientWithCompanyCode(+companyCode) @@ -4877,7 +4894,7 @@ export class RequestManagementService { const clientName = sandHubReport?.CompanyName || sandHubReport?.LastCompanyName; const companyCode = sandHubReport?.CompanyCode; - + // Try to find client by company code first (more reliable) const client = companyCode ? await this.clientService.findClientWithCompanyCode(+companyCode) @@ -4941,7 +4958,7 @@ export class RequestManagementService { // For CAR_BODY: Create expertSubmitReply // First party is guilty by default if accident was with another car const guiltyUserId = firstPartyUserId; - + // Accident fields can be added separately via add-accident-fields endpoint updatePayload.$set.expertSubmitReply = { description: "Expert completed all information on-site. Awaiting signature.", @@ -5170,11 +5187,11 @@ export class RequestManagementService { // If description is already added, next step is different const hasDescription = request.steps?.includes(StepsEnum.F_addDescription) || request.steps?.includes(StepsEnum.S_addDescription); - - const currentStep = request.type === "THIRD_PARTY" - ? StepsEnum.F_addVoice + + const currentStep = request.type === "THIRD_PARTY" + ? StepsEnum.F_addVoice : StepsEnum.F_addVoice; - + const nextStep = hasDescription ? (request.type === "THIRD_PARTY" ? StepsEnum.AddSignatures : StepsEnum.AddSignatures) : (request.type === "THIRD_PARTY" ? StepsEnum.F_addDescription : StepsEnum.F_addDescription); @@ -5277,25 +5294,25 @@ export class RequestManagementService { } else { newReplyObject.description = "Expert on-site assessment"; } - + if ('guiltyUserId' in existingReply) { newReplyObject.guiltyUserId = existingReply.guiltyUserId; } else { newReplyObject.guiltyUserId = request.firstPartyDetails?.firstPartyId; } - + if ('submitTime' in existingReply) { newReplyObject.submitTime = existingReply.submitTime; } else { newReplyObject.submitTime = new Date(); } - + if ('firstPartyComment' in existingReply) { newReplyObject.firstPartyComment = existingReply.firstPartyComment; } else { newReplyObject.firstPartyComment = null; } - + if ('secondPartyComment' in existingReply) { newReplyObject.secondPartyComment = existingReply.secondPartyComment; } else { diff --git a/src/request-management/request-management.v2.controller.ts b/src/request-management/request-management.v2.controller.ts index 25c541e..12f4831 100644 --- a/src/request-management/request-management.v2.controller.ts +++ b/src/request-management/request-management.v2.controller.ts @@ -51,7 +51,7 @@ import { RequestManagementService } from "./request-management.service"; export class RequestManagementV2Controller { constructor( private readonly requestManagementService: RequestManagementService, - ) {} + ) { } @Post() @UseGuards(GlobalGuard) @@ -65,6 +65,14 @@ export class RequestManagementV2Controller { ); } + @Get() + @Roles(RoleEnum.USER, RoleEnum.FIELD_EXPERT) + async getAllBlameRequestsV2( + @CurrentUser() user: any, + ) { + return this.requestManagementService.getAllBlameRequestsV2(user); + } + /** * Get one blame request by id. Allowed for the request owner (party) or the initiating field expert. */ @@ -324,10 +332,10 @@ export class RequestManagementV2Controller { @UploadedFile() sign: Express.Multer.File, ) { // Convert string "true"/"false" to boolean - const acceptDecision = typeof isAccept === "string" - ? isAccept === "true" + const acceptDecision = typeof isAccept === "string" + ? isAccept === "true" : Boolean(isAccept); - + return this.requestManagementService.userSignDecisionV2( requestId, user.sub,