feat: stats endpoints
All checks were successful
Spell Check / Spell Check with Typos (push) Successful in 7s

This commit is contained in:
Methapon2001 2025-03-04 11:27:15 +07:00
parent ba697d006a
commit c004c516c6

View file

@ -0,0 +1,187 @@
import { QuotationStatus, RequestWorkStatus } from "@prisma/client";
import { Controller, Get, Query, Request, Route, Security } from "tsoa";
import prisma from "../db";
import { createPermCondition } from "../services/permission";
import { RequestWithUser } from "../interfaces/user";
import { PaymentStatus } from "../generated/kysely/types";
const permissionCondCompany = createPermCondition((_) => true);
@Route("/api/v1/report")
@Security("keycloak")
export class StatsController extends Controller {
@Get("quotation")
async quotationReport(
@Request() req: RequestWithUser,
@Query() limit?: number,
@Query() startDate?: Date,
@Query() endDate?: Date,
) {
const record = await prisma.quotation.findMany({
select: {
code: true,
quotationStatus: true,
createdAt: true,
updatedAt: true,
},
where: {
registeredBranch: { OR: permissionCondCompany(req.user) },
createdAt: { gte: startDate, lte: endDate },
},
take: limit,
});
return record.map((v) => ({
document: "quotation",
code: v.code,
status: v.quotationStatus,
createdAt: v.createdAt,
updatedAt: v.updatedAt,
}));
}
@Get("invoice")
async invoiceReport(
@Request() req: RequestWithUser,
@Query() limit?: number,
@Query() startDate?: Date,
@Query() endDate?: Date,
) {
const record = await prisma.invoice.findMany({
select: {
code: true,
payment: {
select: {
paymentStatus: true,
},
},
createdAt: true,
},
where: {
quotation: {
isDebitNote: false,
registeredBranch: { OR: permissionCondCompany(req.user) },
},
createdAt: { gte: startDate, lte: endDate },
},
take: limit,
});
return record.map((v) => ({
document: "invoice",
code: v.code,
status: v.payment?.paymentStatus,
createdAt: v.createdAt,
}));
}
@Get("receipt")
async receiptReport(
@Request() req: RequestWithUser,
@Query() limit?: number,
@Query() startDate?: Date,
@Query() endDate?: Date,
) {
const record = await prisma.payment.findMany({
select: {
code: true,
paymentStatus: true,
createdAt: true,
},
where: {
paymentStatus: PaymentStatus.PaymentSuccess,
invoice: {
quotation: {
isDebitNote: false,
registeredBranch: { OR: permissionCondCompany(req.user) },
},
},
createdAt: { gte: startDate, lte: endDate },
},
take: limit,
});
return record.map((v) => ({
document: "receipt",
code: v.code,
status: v.paymentStatus,
createdAt: v.createdAt,
}));
}
@Get("product")
async productReport(
@Request() req: RequestWithUser,
@Query() limit?: number,
@Query() startDate?: Date,
@Query() endDate?: Date,
) {
const record = await prisma.product.findMany({
select: {
id: true,
code: true,
name: true,
createdAt: true,
updatedAt: true,
_count: {
select: {
quotationProductServiceList: {
where: {
quotation: {
quotationStatus: {
in: [
QuotationStatus.PaymentInProcess,
QuotationStatus.PaymentSuccess,
QuotationStatus.ProcessComplete,
],
},
},
},
},
},
},
},
where: {
quotationProductServiceList: { some: {} },
productGroup: { registeredBranch: { OR: permissionCondCompany(req.user) } },
createdAt: { gte: startDate, lte: endDate },
},
take: limit,
});
const doing = await prisma.quotationProductServiceList.groupBy({
_count: true,
by: "productId",
where: {
productId: { in: record.map((v) => v.id) },
requestWork: {
some: {
stepStatus: {
some: {
workStatus: {
in: [
RequestWorkStatus.Pending,
RequestWorkStatus.InProgress,
RequestWorkStatus.Validate,
RequestWorkStatus.Completed,
RequestWorkStatus.Ended,
],
},
},
},
},
},
},
});
return record.map((v) => ({
document: "product",
code: v.code,
name: v.name,
sale: v._count.quotationProductServiceList,
did: doing.find((item) => item.productId === v.id)?._count || 0,
createdAt: v.createdAt,
updatedAt: v.updatedAt,
}));
}
}