From 35fe9c69d1b2735797d4358dcde519cea0ee5748 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Wed, 5 Mar 2025 17:49:47 +0700 Subject: [PATCH] feat: export report csv endpoint --- package.json | 1 + pnpm-lock.yaml | 24 ++++++++++++++++++ src/controllers/00-stats-controller.ts | 34 ++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/package.json b/package.json index ced7595..eafc24f 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7495ebe..85397d2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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: {} diff --git a/src/controllers/00-stats-controller.ts b/src/controllers/00-stats-controller.ts index 54edbce..65e057c 100644 --- a/src/controllers/00-stats-controller.ts +++ b/src/controllers/00-stats-controller.ts @@ -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,