diff --git a/src/expert-insurer/expert-insurer.service.ts b/src/expert-insurer/expert-insurer.service.ts index 12d8e99..9eb1b4d 100644 --- a/src/expert-insurer/expert-insurer.service.ts +++ b/src/expert-insurer/expert-insurer.service.ts @@ -9,6 +9,7 @@ import { InjectModel } from "@nestjs/mongoose"; import { Model, Types } from "mongoose"; import { ClaimRequiredDocumentDbService } from "src/claim-request-management/entites/db-service/claim-required-document.db.service"; import { VideoCaptureDbService } from "src/claim-request-management/entites/db-service/video-capture.db.service"; +import { DamageImageDbService } from "src/claim-request-management/entites/db-service/damage-image.db.service"; import { ClaimRequestManagementModel } from "src/claim-request-management/entites/schema/claim-request-management.schema"; import { CreateBranchDto } from "src/client/dto/create-branch.dto"; import { BranchDbService } from "src/client/entities/db-service/branch.db.service"; @@ -44,6 +45,7 @@ export class ExpertInsurerService { private readonly claimVideoCaptureDbService: VideoCaptureDbService, private readonly branchDbService: BranchDbService, private readonly claimRequiredDocumentDbService: ClaimRequiredDocumentDbService, + private readonly damageImageDbService: DamageImageDbService, ) {} async retrieveAllExpertsOfClient( @@ -189,7 +191,7 @@ export class ExpertInsurerService { : this.requestManagementModel; const expertCollection = role === "claim" ? "damage-expert" : "expert"; - return await model.aggregate([ + const results = await model.aggregate([ { $match: { "actorLocked.actorId": expertObjectId } }, { $lookup: { @@ -232,6 +234,7 @@ export class ExpertInsurerService { currentStep: 1, rating: 1, averageRating: 1, + imageRequired: 1, expertInfo: { _id: 1, fullName: { @@ -244,6 +247,15 @@ export class ExpertInsurerService { }, }, ]); + + // Process imageRequired for claim files + if (role === "claim") { + return await Promise.all( + results.map((file) => this.processImageRequired(file)), + ); + } + + return results; } async rateExpertOnFile( @@ -334,6 +346,7 @@ export class ExpertInsurerService { nationalCodeOfInsurer: 1, carGreenCard: 1, aiImages: 1, + imageRequired: 1, videoCaptureId: 1, damageExpertReply: 1, damageExpertReplyFinal: 1, @@ -353,7 +366,10 @@ export class ExpertInsurerService { blameFilesRaw.map((file) => this.populateBlameFileLinks(file)), ); const populatedClaimFiles = await Promise.all( - claimFilesRaw.map((file) => this.populateClaimFileLinks(file)), + claimFilesRaw.map(async (file) => { + const populated = await this.populateClaimFileLinks(file); + return await this.processImageRequired(populated); + }), ); return { blameFiles: populatedBlameFiles, claimFiles: populatedClaimFiles }; @@ -442,6 +458,99 @@ export class ExpertInsurerService { return claimFile; } + /** + * Processes imageRequired field: + * 1. Removes part_segments from aiReport.distinct_damaged_parts_report.parts[] + * 2. Populates imageId fields with file links + */ + private async processImageRequired(claimFile: any): Promise { + if (!claimFile || !claimFile.imageRequired) { + return claimFile; + } + + const imageRequired = claimFile.imageRequired; + + // Process aroundTheCar array + if (Array.isArray(imageRequired.aroundTheCar)) { + imageRequired.aroundTheCar = await Promise.all( + imageRequired.aroundTheCar.map(async (item: any) => { + // Remove part_segments from aiReport.distinct_damaged_parts_report.parts[] + if ( + item?.aiReport?.distinct_damaged_parts_report?.parts && + Array.isArray(item.aiReport.distinct_damaged_parts_report.parts) + ) { + item.aiReport.distinct_damaged_parts_report.parts = + item.aiReport.distinct_damaged_parts_report.parts.map( + (part: any) => { + const { part_segments, ...partWithoutSegments } = part; + return partWithoutSegments; + }, + ); + } + + // Populate imageId with file link + if (item?.imageId) { + try { + const imageDoc = await this.damageImageDbService.findOne( + item.imageId.toString(), + ); + if (imageDoc && imageDoc.path) { + item.imageId = buildFileLink(imageDoc.path); + } + } catch (error) { + this.logger.warn( + `Failed to populate imageId for aroundTheCar item: ${error.message}`, + ); + } + } + + return item; + }), + ); + } + + // Process selectPartOfCar array + if (Array.isArray(imageRequired.selectPartOfCar)) { + imageRequired.selectPartOfCar = await Promise.all( + imageRequired.selectPartOfCar.map(async (item: any) => { + // Remove part_segments from aiReport.distinct_damaged_parts_report.parts[] + if ( + item?.aiReport?.distinct_damaged_parts_report?.parts && + Array.isArray(item.aiReport.distinct_damaged_parts_report.parts) + ) { + item.aiReport.distinct_damaged_parts_report.parts = + item.aiReport.distinct_damaged_parts_report.parts.map( + (part: any) => { + const { part_segments, ...partWithoutSegments } = part; + return partWithoutSegments; + }, + ); + } + + // Populate imageId with file link + if (item?.imageId) { + try { + const imageDoc = await this.damageImageDbService.findOne( + item.imageId.toString(), + ); + if (imageDoc && imageDoc.path) { + item.imageId = buildFileLink(imageDoc.path); + } + } catch (error) { + this.logger.warn( + `Failed to populate imageId for selectPartOfCar item: ${error.message}`, + ); + } + } + + return item; + }), + ); + } + + return claimFile; + } + private async populatePartyReplyLinks(partyReply: any) { if (!partyReply) return; // --- FIX: Consistently use findById ---