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: { quotation: { registeredBranch: { OR: permissionCondCompany(req.user) }, }, 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, })); } }