forked from Yara724/api
YARA-720, YARA-721
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { ClaimRequestManagementModule } from "src/claim-request-management/claim-request-management.module";
|
||||
import { RequestManagementModule } from "src/request-management/request-management.module";
|
||||
import { ClientModule } from "src/client/client.module";
|
||||
import { ReportsController } from "./reports.controller";
|
||||
import { ReportsService } from "./reports.service";
|
||||
|
||||
@Module({
|
||||
imports: [RequestManagementModule, ClaimRequestManagementModule],
|
||||
imports: [
|
||||
RequestManagementModule,
|
||||
ClaimRequestManagementModule,
|
||||
ClientModule,
|
||||
],
|
||||
controllers: [ReportsController],
|
||||
providers: [ReportsService],
|
||||
})
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { Types } from "mongoose";
|
||||
import { ClaimRequestManagementDbService } from "src/claim-request-management/entites/db-service/claim-request-management.db.service";
|
||||
import { RequestManagementDbService } from "src/request-management/entities/db-service/request-management.db.service";
|
||||
import { ClientDbService } from "src/client/entities/db-service/client.db.service";
|
||||
import { ReqBlameStatus } from "src/Types&Enums/blame-request-management/status.enum";
|
||||
import { ReqClaimStatus } from "src/Types&Enums/claim-request-management/status.enum";
|
||||
import { UserType } from "src/Types&Enums/userType.enum";
|
||||
import {
|
||||
CompanyAllRequestsCountReportDtoRs,
|
||||
DamageExpertAllRequestsCountReportDtoRs,
|
||||
@@ -12,9 +14,12 @@ import {
|
||||
|
||||
@Injectable()
|
||||
export class ReportsService {
|
||||
private readonly logger = new Logger(ReportsService.name);
|
||||
|
||||
constructor(
|
||||
private readonly requestManagementDbService: RequestManagementDbService,
|
||||
private readonly claimRequestManagementDbService: ClaimRequestManagementDbService,
|
||||
private readonly clientDbService: ClientDbService,
|
||||
) {}
|
||||
|
||||
async getAllCheckedRequestsCountFn(role: string, client: string) {
|
||||
@@ -81,7 +86,91 @@ export class ReportsService {
|
||||
return data;
|
||||
}
|
||||
|
||||
async getAllRequestsCountByRole(role: string, client: string) {
|
||||
private isVisibleToClientType(client: any, actor: any): boolean {
|
||||
if (actor.userType === UserType.GENUINE) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
actor.userType === UserType.LEGAL &&
|
||||
String(client._id) === actor.clientKey
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private wasHandledByActor(request: any, actorSub: string): boolean {
|
||||
type ActorCheckerEntry = { CheckedRequest?: { actorId: string } };
|
||||
const actorChecker = request.actorsChecker as ActorCheckerEntry[];
|
||||
|
||||
if (!Array.isArray(actorChecker)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const matchingEntry = actorChecker.find(
|
||||
(entry) => String(entry?.CheckedRequest?.actorId) === actorSub,
|
||||
);
|
||||
|
||||
return !!matchingEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters claim requests using the same logic as expert-claim service
|
||||
* to ensure consistency between endpoints
|
||||
*/
|
||||
private async filterClaimRequestsForExpert(
|
||||
requests: any[],
|
||||
actor: any,
|
||||
): Promise<any[]> {
|
||||
const filteredRequests = [];
|
||||
|
||||
for (const r of requests) {
|
||||
// For expert-initiated blame files, only show to the initiating expert
|
||||
if (r.blameFile?.expertInitiated && r.blameFile?.initiatedBy) {
|
||||
if (String(r.blameFile.initiatedBy) !== actor.sub) {
|
||||
continue; // Skip if not the initiating expert
|
||||
}
|
||||
// Expert-initiated claim files are always visible to the initiating expert
|
||||
filteredRequests.push(r);
|
||||
continue;
|
||||
}
|
||||
|
||||
const client = await this.clientDbService.findOne({
|
||||
_id: r.userClientKey,
|
||||
});
|
||||
|
||||
if (!client) {
|
||||
this.logger.warn(
|
||||
`Client not found for claim request with ID: ${r._id}. Skipping.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
const specialHandlingStatuses = [
|
||||
ReqClaimStatus.CheckAgain,
|
||||
ReqClaimStatus.ReviewRequest,
|
||||
ReqClaimStatus.PendingFactorValidation,
|
||||
];
|
||||
|
||||
const requiresSpecificActorCheck = specialHandlingStatuses.includes(
|
||||
r.claimStatus,
|
||||
);
|
||||
|
||||
if (requiresSpecificActorCheck) {
|
||||
if (this.wasHandledByActor(r, actor.sub)) {
|
||||
filteredRequests.push(r);
|
||||
}
|
||||
} else {
|
||||
if (this.isVisibleToClientType(client, actor)) {
|
||||
filteredRequests.push(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filteredRequests;
|
||||
}
|
||||
|
||||
async getAllRequestsCountByRole(role: string, client: string, actor?: any) {
|
||||
if (role === "expert") {
|
||||
const statuses = Object.values(ReqBlameStatus);
|
||||
const data: Record<string, number> = { all: 0 };
|
||||
@@ -115,16 +204,51 @@ export class ReportsService {
|
||||
const statuses = Object.values(ReqClaimStatus);
|
||||
const data: Record<string, number> = { all: 0 };
|
||||
|
||||
for (const status of statuses) {
|
||||
const filter = {
|
||||
claimStatus: status,
|
||||
userClientKey: new Types.ObjectId(client),
|
||||
};
|
||||
// For damage_expert, we need to apply the same filtering as expert-claim service
|
||||
if (actor) {
|
||||
// Fetch all requests with the statuses that expert-claim service shows
|
||||
// This matches the statuses in getClaimRequestsListForExpert
|
||||
const relevantStatuses = [
|
||||
ReqClaimStatus.UnChecked,
|
||||
ReqClaimStatus.ReviewRequest,
|
||||
ReqClaimStatus.CheckAgain,
|
||||
ReqClaimStatus.CloseRequest,
|
||||
ReqClaimStatus.InPersonVisit,
|
||||
ReqClaimStatus.CheckedRequest,
|
||||
ReqClaimStatus.PendingFactorValidation,
|
||||
];
|
||||
|
||||
const count =
|
||||
await this.claimRequestManagementDbService.countByFilter(filter);
|
||||
data[status] = count;
|
||||
data.all += count;
|
||||
// Fetch all requests with relevant statuses (matching expert-claim query)
|
||||
const allRequests =
|
||||
await this.claimRequestManagementDbService.findAllByStatus({
|
||||
claimStatus: { $in: relevantStatuses },
|
||||
});
|
||||
|
||||
// Filter requests using the same logic as expert-claim service
|
||||
const filteredRequests =
|
||||
await this.filterClaimRequestsForExpert(allRequests, actor);
|
||||
|
||||
// Count by status from filtered results
|
||||
for (const status of statuses) {
|
||||
const count = filteredRequests.filter(
|
||||
(r) => r.claimStatus === status,
|
||||
).length;
|
||||
data[status] = count;
|
||||
data.all += count;
|
||||
}
|
||||
} else {
|
||||
// Fallback to simple count if actor not provided (shouldn't happen for damage_expert)
|
||||
for (const status of statuses) {
|
||||
const filter = {
|
||||
claimStatus: status,
|
||||
userClientKey: new Types.ObjectId(client),
|
||||
};
|
||||
|
||||
const count =
|
||||
await this.claimRequestManagementDbService.countByFilter(filter);
|
||||
data[status] = count;
|
||||
data.all += count;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
@@ -174,7 +298,12 @@ export class ReportsService {
|
||||
|
||||
async getAllRequestsReportCount(actor, client) {
|
||||
if (actor.role === "damage_expert") {
|
||||
const data = await this.getAllRequestsCountByRole(actor.role, client);
|
||||
// Pass actor to apply filtering logic for damage_expert
|
||||
const data = await this.getAllRequestsCountByRole(
|
||||
actor.role,
|
||||
client,
|
||||
actor,
|
||||
);
|
||||
return new DamageExpertAllRequestsCountReportDtoRs(data);
|
||||
} else if (actor.role === "expert") {
|
||||
const data = await this.getAllRequestsCountByRole(actor.role, client);
|
||||
|
||||
Reference in New Issue
Block a user