feat: export report csv endpoint
All checks were successful
Spell Check / Spell Check with Typos (push) Successful in 6s

This commit is contained in:
Methapon2001 2025-03-05 17:49:47 +07:00
parent 90246bb3a8
commit 35fe9c69d1
3 changed files with 59 additions and 0 deletions

View file

@ -45,6 +45,7 @@
"dotenv": "^16.4.7",
"express": "^4.21.2",
"fast-jwt": "^5.0.5",
"json-2-csv": "^5.5.8",
"kysely": "^0.27.5",
"minio": "^8.0.2",
"morgan": "^1.10.0",

24
pnpm-lock.yaml generated
View file

@ -47,6 +47,9 @@ importers:
fast-jwt:
specifier: ^5.0.5
version: 5.0.5
json-2-csv:
specifier: ^5.5.8
version: 5.5.8
kysely:
specifier: ^0.27.5
version: 0.27.5
@ -904,6 +907,10 @@ packages:
resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==}
engines: {node: '>=0.10'}
deeks@3.1.0:
resolution: {integrity: sha512-e7oWH1LzIdv/prMQ7pmlDlaVoL64glqzvNgkgQNgyec9ORPHrT2jaOqMtRyqJuwWjtfb6v+2rk9pmaHj+F137A==}
engines: {node: '>= 16'}
define-data-property@1.1.4:
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
engines: {node: '>= 0.4'}
@ -932,6 +939,10 @@ packages:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
doc-path@4.1.1:
resolution: {integrity: sha512-h1ErTglQAVv2gCnOpD3sFS6uolDbOKHDU1BZq+Kl3npPqroU3dYL42lUgMfd5UimlwtRgp7C9dLGwqQ5D2HYgQ==}
engines: {node: '>=16'}
docx-templates@4.13.0:
resolution: {integrity: sha512-tTmR3WhROYctuyVReQ+PfCU3zprmC45/VuSVzn8EjovzpRkXYUdXiDatB9M8pasj0V+wuuOyY8bcSHvlQ2GNag==}
engines: {node: '>=6'}
@ -1535,6 +1546,10 @@ packages:
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
json-2-csv@5.5.8:
resolution: {integrity: sha512-eMQHOwV+av8Sgo+fkbEbQWOw/kwh89AZ5fNA8TYfcooG6TG1ZOL2WcPUrngIMIK8dBJitQ8QEU0zbncQ0CX4CQ==}
engines: {node: '>= 16'}
json-bignum@0.0.3:
resolution: {integrity: sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg==}
engines: {node: '>=0.8'}
@ -3778,6 +3793,8 @@ snapshots:
decode-uri-component@0.2.2: {}
deeks@3.1.0: {}
define-data-property@1.1.4:
dependencies:
es-define-property: 1.0.1
@ -3811,6 +3828,8 @@ snapshots:
dependencies:
path-type: 4.0.0
doc-path@4.1.1: {}
docx-templates@4.13.0:
dependencies:
jszip: 3.10.1
@ -4568,6 +4587,11 @@ snapshots:
js-tokens@4.0.0: {}
json-2-csv@5.5.8:
dependencies:
deeks: 3.1.0
doc-path: 4.1.1
json-bignum@0.0.3: {}
json-parse-even-better-errors@2.3.1: {}

View file

@ -14,6 +14,7 @@ import { RequestWithUser } from "../interfaces/user";
import { PaymentStatus } from "../generated/kysely/types";
import { precisionRound } from "../utils/arithmetic";
import dayjs from "dayjs";
import { json2csv } from "json-2-csv";
const permissionCondCompany = createPermCondition((_) => true);
@ -23,6 +24,17 @@ const VAT_DEFAULT = config.vat;
@Security("keycloak")
@Tags("Report")
export class StatsController extends Controller {
@Get("quotation/download")
async downloadQuotationReport(
@Request() req: RequestWithUser,
@Query() limit?: number,
@Query() startDate?: Date,
@Query() endDate?: Date,
) {
this.setHeader("Content-Type", "text/csv");
return json2csv(await this.quotationReport(req, limit, startDate, endDate));
}
@Get("quotation")
async quotationReport(
@Request() req: RequestWithUser,
@ -54,6 +66,17 @@ export class StatsController extends Controller {
}));
}
@Get("invoice/download")
async downloadInvoiceReport(
@Request() req: RequestWithUser,
@Query() limit?: number,
@Query() startDate?: Date,
@Query() endDate?: Date,
) {
this.setHeader("Content-Type", "text/csv");
return json2csv(await this.invoiceReport(req, limit, startDate, endDate));
}
@Get("invoice")
async invoiceReport(
@Request() req: RequestWithUser,
@ -92,6 +115,17 @@ export class StatsController extends Controller {
}));
}
@Get("receipt/download")
async downloadReceiptReport(
@Request() req: RequestWithUser,
@Query() limit?: number,
@Query() startDate?: Date,
@Query() endDate?: Date,
) {
this.setHeader("Content-Type", "text/csv");
return json2csv(await this.receiptReport(req, limit, startDate, endDate));
}
@Get("receipt")
async receiptReport(
@Request() req: RequestWithUser,