1
0
forked from Yara724/api

Initial commit after migration to gitea

This commit is contained in:
2026-01-18 11:27:43 +03:30
parent a21039410c
commit ea4b8eb543
196 changed files with 45567 additions and 9 deletions

View 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;
}
}

View 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);
}
}

View 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 {}

View 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 };
}
}
}