forked from Yara724/api
Initial commit after migration to gitea
This commit is contained in:
51
src/reports/dto/reports.dto.ts
Normal file
51
src/reports/dto/reports.dto.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
export class DamageExpertAllRequestsCountReportDtoRs {
|
||||
all: number;
|
||||
UnChecked: number;
|
||||
CheckedRequest: number;
|
||||
CheckAgain: number;
|
||||
WaitingForUserToResend: number;
|
||||
CloseRequest: number;
|
||||
WaitingForUserCompleted: number;
|
||||
InPersonVisit: number;
|
||||
|
||||
constructor(report: any) {
|
||||
this.all = report.all;
|
||||
this.UnChecked = report.UnChecked;
|
||||
this.CheckedRequest = report.CheckedRequest;
|
||||
this.CheckAgain = report.CheckAgain;
|
||||
this.WaitingForUserToResend = report.WaitingForUserToResend;
|
||||
this.CloseRequest = report.CloseRequest;
|
||||
this.WaitingForUserCompleted = report.WaitingForUserCompleted;
|
||||
this.InPersonVisit = report.InPersonVisit;
|
||||
}
|
||||
}
|
||||
|
||||
export class ExpertAllRequestsCountReportDtoRs {
|
||||
all: number;
|
||||
UnChecked: number;
|
||||
CheckedRequest: number;
|
||||
CheckAgain: number;
|
||||
WaitingForUserToResend: number;
|
||||
CloseRequest: number;
|
||||
WaitingForUserCompleted: number;
|
||||
|
||||
constructor(report: any) {
|
||||
this.all = report.all;
|
||||
this.UnChecked = report.UnChecked;
|
||||
this.CheckedRequest = report.CheckedRequest;
|
||||
this.CheckAgain = report.CheckAgain;
|
||||
this.WaitingForUserToResend = report.WaitingForUserToResend;
|
||||
this.CloseRequest = report.CloseRequest;
|
||||
this.WaitingForUserCompleted = report.WaitingForUserCompleted;
|
||||
}
|
||||
}
|
||||
|
||||
export class CompanyAllRequestsCountReportDtoRs {
|
||||
blame: object;
|
||||
claim: object;
|
||||
|
||||
constructor(blame: object, claim: object) {
|
||||
this.blame = blame;
|
||||
this.claim = claim;
|
||||
}
|
||||
}
|
||||
39
src/reports/reports.controller.ts
Normal file
39
src/reports/reports.controller.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Controller, Get, UseGuards } from "@nestjs/common";
|
||||
import { ApiBearerAuth, ApiTags } from "@nestjs/swagger";
|
||||
import { LocalActorAuthGuard } from "src/auth/guards/actor-local.guard";
|
||||
import { RolesGuard } from "src/auth/guards/role.guard";
|
||||
import { ClientKey } from "src/decorators/clientKey.decorator";
|
||||
import { Roles } from "src/decorators/roles.decorator";
|
||||
import { CurrentUser } from "src/decorators/user.decorator";
|
||||
import { RoleEnum } from "src/Types&Enums/role.enum";
|
||||
import { ReportsService } from "./reports.service";
|
||||
|
||||
@ApiTags("reports")
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(LocalActorAuthGuard, RolesGuard)
|
||||
@Roles(RoleEnum.DAMAGE_EXPERT, RoleEnum.EXPERT, RoleEnum.COMPANY)
|
||||
@Controller("reports")
|
||||
export class ReportsController {
|
||||
constructor(private readonly reportsService: ReportsService) {}
|
||||
|
||||
@Get("/report/requests")
|
||||
async getAllRequestsReport(@CurrentUser() actor, @ClientKey() client) {
|
||||
return await this.reportsService.getAllRequestsReportCount(actor, client);
|
||||
}
|
||||
|
||||
@Get("/report/perMonthRequests")
|
||||
async getAllRequestsReportPerMonth(
|
||||
@CurrentUser() actor,
|
||||
@ClientKey() client,
|
||||
) {
|
||||
return await this.reportsService.getAllRequestsReportPerMonth(
|
||||
actor,
|
||||
client,
|
||||
);
|
||||
}
|
||||
|
||||
@Get("/report/checkedRequests")
|
||||
async getAllCheckedRequestsCount(@CurrentUser() actor, @ClientKey() client) {
|
||||
return await this.reportsService.getAllCheckedRequestsCount(actor, client);
|
||||
}
|
||||
}
|
||||
12
src/reports/reports.module.ts
Normal file
12
src/reports/reports.module.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
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 { ReportsController } from "./reports.controller";
|
||||
import { ReportsService } from "./reports.service";
|
||||
|
||||
@Module({
|
||||
imports: [RequestManagementModule, ClaimRequestManagementModule],
|
||||
controllers: [ReportsController],
|
||||
providers: [ReportsService],
|
||||
})
|
||||
export class ReportsModule {}
|
||||
284
src/reports/reports.service.ts
Normal file
284
src/reports/reports.service.ts
Normal file
@@ -0,0 +1,284 @@
|
||||
import { Injectable } 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 { ReqBlameStatus } from "src/Types&Enums/blame-request-management/status.enum";
|
||||
import { ReqClaimStatus } from "src/Types&Enums/claim-request-management/status.enum";
|
||||
import {
|
||||
CompanyAllRequestsCountReportDtoRs,
|
||||
DamageExpertAllRequestsCountReportDtoRs,
|
||||
ExpertAllRequestsCountReportDtoRs,
|
||||
} from "./dto/reports.dto";
|
||||
|
||||
@Injectable()
|
||||
export class ReportsService {
|
||||
constructor(
|
||||
private readonly requestManagementDbService: RequestManagementDbService,
|
||||
private readonly claimRequestManagementDbService: ClaimRequestManagementDbService,
|
||||
) {}
|
||||
|
||||
async getAllCheckedRequestsCountFn(role: string, client: string) {
|
||||
const statuses = ["UnChecked", "CheckedRequest"];
|
||||
const data: Record<string, number> = { all: 0 };
|
||||
const clientId = new Types.ObjectId(client);
|
||||
|
||||
for (const status of statuses) {
|
||||
let count = 0;
|
||||
if (role === "damage_expert") {
|
||||
count = await this.claimRequestManagementDbService.countByFilter({
|
||||
claimStatus: status,
|
||||
userClientKey: clientId,
|
||||
});
|
||||
} else {
|
||||
count = await this.requestManagementDbService.countByFilter({
|
||||
blameStatus: status,
|
||||
$or: [
|
||||
{ "firstPartyDetails.firstPartyClient.clientId": clientId },
|
||||
{ "secondPartyDetails.secondPartyClient.clientId": clientId },
|
||||
],
|
||||
});
|
||||
}
|
||||
data[status] = count;
|
||||
data.all += count;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
async getDateFilteredRequestByStatus(
|
||||
role: string,
|
||||
client: string,
|
||||
start: Date,
|
||||
end: Date,
|
||||
) {
|
||||
const statuses = ["UnChecked", "CheckedRequest", "CheckAgain"];
|
||||
const data: Record<string, number> = {};
|
||||
const clientId = new Types.ObjectId(client);
|
||||
|
||||
for (const status of statuses) {
|
||||
let blameCount = 0;
|
||||
let claimCount = 0;
|
||||
|
||||
if (role === "expert" || role === "company") {
|
||||
blameCount = await this.requestManagementDbService.countByFilter({
|
||||
blameStatus: status,
|
||||
createdAt: { $gte: start, $lte: end },
|
||||
$or: [
|
||||
{ "firstPartyDetails.firstPartyClient.clientId": clientId },
|
||||
{ "secondPartyDetails.secondPartyClient.clientId": clientId },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (role === "damage_expert" || role === "company") {
|
||||
claimCount = await this.claimRequestManagementDbService.countByFilter({
|
||||
claimStatus: status,
|
||||
userClientKey: clientId,
|
||||
createdAt: { $gte: start, $lte: end },
|
||||
});
|
||||
}
|
||||
data[status] = blameCount + claimCount;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
async getAllRequestsCountByRole(role: string, client: string) {
|
||||
if (role === "expert") {
|
||||
const statuses = Object.values(ReqBlameStatus);
|
||||
const data: Record<string, number> = { all: 0 };
|
||||
|
||||
for (const status of statuses) {
|
||||
const filter = {
|
||||
blameStatus: status,
|
||||
$or: [
|
||||
{
|
||||
"firstPartyDetails.firstPartyClient.clientId": new Types.ObjectId(
|
||||
client,
|
||||
),
|
||||
},
|
||||
// {
|
||||
// "secondPartyDetails.secondPartyClient.clientId":
|
||||
// new Types.ObjectId(client),
|
||||
// },
|
||||
],
|
||||
};
|
||||
|
||||
const count =
|
||||
await this.requestManagementDbService.countByFilter(filter);
|
||||
data[status] = count;
|
||||
data.all += count;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
if (role === "damage_expert") {
|
||||
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),
|
||||
};
|
||||
|
||||
const count =
|
||||
await this.claimRequestManagementDbService.countByFilter(filter);
|
||||
data[status] = count;
|
||||
data.all += count;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// ✅ Company logic
|
||||
if (role === "company") {
|
||||
const blameStatuses = Object.values(ReqBlameStatus);
|
||||
const claimStatuses = Object.values(ReqClaimStatus);
|
||||
|
||||
const blameData: Record<string, number> = { all: 0 };
|
||||
const claimData: Record<string, number> = { all: 0 };
|
||||
|
||||
// Only count files where this company is FIRST party in Blame
|
||||
for (const status of blameStatuses) {
|
||||
const filter = {
|
||||
blameStatus: status,
|
||||
"firstPartyDetails.firstPartyClient.clientId": new Types.ObjectId(
|
||||
client,
|
||||
),
|
||||
};
|
||||
|
||||
const count =
|
||||
await this.requestManagementDbService.countByFilter(filter);
|
||||
blameData[status] = count;
|
||||
blameData.all += count;
|
||||
}
|
||||
|
||||
// Claims always use `userClientKey`
|
||||
for (const status of claimStatuses) {
|
||||
const filter = {
|
||||
claimStatus: status,
|
||||
userClientKey: new Types.ObjectId(client),
|
||||
};
|
||||
|
||||
const count =
|
||||
await this.claimRequestManagementDbService.countByFilter(filter);
|
||||
claimData[status] = count;
|
||||
claimData.all += count;
|
||||
}
|
||||
|
||||
return { blameData, claimData };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async getAllRequestsReportCount(actor, client) {
|
||||
if (actor.role === "damage_expert") {
|
||||
const data = await this.getAllRequestsCountByRole(actor.role, client);
|
||||
return new DamageExpertAllRequestsCountReportDtoRs(data);
|
||||
} else if (actor.role === "expert") {
|
||||
const data = await this.getAllRequestsCountByRole(actor.role, client);
|
||||
return new ExpertAllRequestsCountReportDtoRs(data);
|
||||
} else {
|
||||
// company
|
||||
const damageExpertData = await this.getAllRequestsCountByRole(
|
||||
"damage_expert",
|
||||
client,
|
||||
);
|
||||
const expertData = await this.getAllRequestsCountByRole("expert", client);
|
||||
return new CompanyAllRequestsCountReportDtoRs(
|
||||
expertData,
|
||||
damageExpertData,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async getAllRequestsReportPerMonth(actor, client) {
|
||||
const result = [];
|
||||
const now = new Date();
|
||||
|
||||
if (actor.role === "company") {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const monthStart = new Date(now.getFullYear(), now.getMonth() - i, 1);
|
||||
const monthEnd = new Date(
|
||||
now.getFullYear(),
|
||||
now.getMonth() - i + 1,
|
||||
0,
|
||||
23,
|
||||
59,
|
||||
59,
|
||||
);
|
||||
const label = monthStart.toLocaleDateString("fa-IR", {
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
});
|
||||
|
||||
const blameData = await this.getDateFilteredRequestByStatus(
|
||||
"expert",
|
||||
client,
|
||||
monthStart,
|
||||
monthEnd,
|
||||
);
|
||||
const claimData = await this.getDateFilteredRequestByStatus(
|
||||
"damage_expert",
|
||||
client,
|
||||
monthStart,
|
||||
monthEnd,
|
||||
);
|
||||
|
||||
result.unshift({
|
||||
stDate: monthStart,
|
||||
enDate: monthEnd,
|
||||
faLabel: label,
|
||||
data: {
|
||||
blame: blameData,
|
||||
claim: claimData,
|
||||
},
|
||||
});
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const monthStart = new Date(now.getFullYear(), now.getMonth() - i, 1);
|
||||
const monthEnd = new Date(
|
||||
now.getFullYear(),
|
||||
now.getMonth() - i + 1,
|
||||
0,
|
||||
23,
|
||||
59,
|
||||
59,
|
||||
);
|
||||
const label = monthStart.toLocaleDateString("fa-IR", {
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
});
|
||||
const data = await this.getDateFilteredRequestByStatus(
|
||||
actor.role,
|
||||
client,
|
||||
monthStart,
|
||||
monthEnd,
|
||||
);
|
||||
result.unshift({
|
||||
stDate: monthStart,
|
||||
enDate: monthEnd,
|
||||
faLabel: label,
|
||||
data,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
async getAllCheckedRequestsCount(actor, client) {
|
||||
if (actor.role === "damage_expert" || actor.role === "expert") {
|
||||
return this.getAllCheckedRequestsCountFn(actor.role, client);
|
||||
} else {
|
||||
const blame = await this.getAllCheckedRequestsCountFn("expert", client);
|
||||
const claim = await this.getAllCheckedRequestsCountFn(
|
||||
"damage_expert",
|
||||
client,
|
||||
);
|
||||
return { blame, claim };
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user