From 9395ef094a4edcb1b265208bbfbeb56e2ade7b30 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sat, 10 Feb 2024 22:20:54 +0200 Subject: [PATCH] feat(server): wip printing financial reports --- .../scss/modules/financial-sheet.scss | 41 ++++++++++++ .../views/modules/financial-sheet.pug | 21 +++++++ .../FinancialStatements/APAgingSummary.ts | 10 +++ .../FinancialStatements/ARAgingSummary.ts | 12 +++- .../FinancialStatements/BalanceSheet.ts | 10 +++ .../FinancialStatements/CashFlow/CashFlow.ts | 10 +++ .../FinancialStatements/JournalSheet.ts | 9 +++ .../FinancialStatements/ProfitLossSheet.ts | 9 +++ .../FinancialStatements/SalesByItems.ts | 11 +++- .../FinancialStatements/TrialBalanceSheet.ts | 13 +++- .../VendorBalanceSummary/index.ts | 12 ++++ .../AgingSummary/APAgingSummaryApplication.ts | 14 +++++ .../APAgingSummaryPdfInjectable.ts | 34 ++++++++++ .../AgingSummary/ARAgingSummaryApplication.ts | 14 +++++ .../ARAgingSummaryPdfInjectable.ts | 34 ++++++++++ .../BalanceSheet/BalanceSheetApplication.ts | 10 +++ .../BalanceSheetExportInjectable.ts | 17 +++++ .../BalanceSheet/BalanceSheetPdfInjectable.ts | 34 ++++++++++ .../BalanceSheet/BalanceSheetTable.ts | 4 +- .../CashFlow/CashflowSheetApplication.ts | 17 +++++ .../CashFlow/CashflowTablePdfInjectable.ts | 33 ++++++++++ .../CustomerBalanceSummaryApplication.ts | 14 +++++ .../CustomerBalanceSummaryPdf.ts | 34 ++++++++++ .../JournalSheet/JournalSheetApplication.ts | 14 +++++ .../JournalSheet/JournalSheetPdfInjectable.ts | 34 ++++++++++ .../ProfitLossSheetApplication.ts | 14 +++++ .../ProfitLossSheetExportInjectable.ts | 7 +++ .../ProfitLossTablePdfInjectable.ts | 34 ++++++++++ .../SalesByItems/SalesByItemsApplication.ts | 17 +++++ .../SalesByItems/SalesByItemsPdfInjectable.ts | 34 ++++++++++ .../FinancialStatements/TableSheetPdf.ts | 62 +++++++++++++++++++ .../TrialBalanceExportInjectable.ts | 19 +++++- .../TrialBalanceSheetApplication.ts | 10 +++ .../TrialBalanceSheetPdfInjectsable.ts | 34 ++++++++++ .../VendorBalanceSummaryApplication.ts | 14 +++++ .../VendorBalanceSummaryPdf.ts | 34 ++++++++++ 36 files changed, 738 insertions(+), 6 deletions(-) create mode 100644 packages/server/resources/scss/modules/financial-sheet.scss create mode 100644 packages/server/resources/views/modules/financial-sheet.pug create mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryPdfInjectable.ts create mode 100644 packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryPdfInjectable.ts create mode 100644 packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPdfInjectable.ts create mode 100644 packages/server/src/services/FinancialStatements/CashFlow/CashflowTablePdfInjectable.ts create mode 100644 packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts create mode 100644 packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetPdfInjectable.ts create mode 100644 packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePdfInjectable.ts create mode 100644 packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsPdfInjectable.ts create mode 100644 packages/server/src/services/FinancialStatements/TableSheetPdf.ts create mode 100644 packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts create mode 100644 packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryPdf.ts diff --git a/packages/server/resources/scss/modules/financial-sheet.scss b/packages/server/resources/scss/modules/financial-sheet.scss new file mode 100644 index 000000000..5924dc2a3 --- /dev/null +++ b/packages/server/resources/scss/modules/financial-sheet.scss @@ -0,0 +1,41 @@ + +.sheet{} +.sheet__company-name{ + margin: 0; + font-size: 1.6rem; +} +.sheet__sheet-type { + margin: 0 +} +.sheet__sheet-date { + margin-top: 0.5rem; +} + +.sheet__header { + text-align: center; + margin-bottom: 2rem; +} + +.sheet__table { + border-top: 1px solid #000; + table-layout: fixed; + border-spacing: 0; + text-align: left; +} + +.sheet__table thead th { + color: #000; + border-bottom: 1px solid #000000; + padding: 0.5rem; +} + +.sheet__table tbody td { + border-bottom: 0; + padding-top: 0.32rem; + padding-bottom: 0.32rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + color: #252A31; + border-bottom: 1px solid rgb(37, 42, 49); + +} \ No newline at end of file diff --git a/packages/server/resources/views/modules/financial-sheet.pug b/packages/server/resources/views/modules/financial-sheet.pug new file mode 100644 index 000000000..019c74626 --- /dev/null +++ b/packages/server/resources/views/modules/financial-sheet.pug @@ -0,0 +1,21 @@ +block head + style + //- include ../../css/modules/financial-sheet.css + +block content + .sheet + .sheet__header + .sheet__company-name=organizationName + .sheet__sheet-type=sheetName + .sheet__sheet-date=sheetDate + + table.sheet__table + thead + tr + each column in table.columns + th= column.label + tbody + each row in table.rows + tr + each cell in row.cells + td= cell.value \ No newline at end of file diff --git a/packages/server/src/api/controllers/FinancialStatements/APAgingSummary.ts b/packages/server/src/api/controllers/FinancialStatements/APAgingSummary.ts index 5d626896c..d87873a2b 100644 --- a/packages/server/src/api/controllers/FinancialStatements/APAgingSummary.ts +++ b/packages/server/src/api/controllers/FinancialStatements/APAgingSummary.ts @@ -71,6 +71,7 @@ export default class APAgingSummaryReportController extends BaseFinancialReportC ACCEPT_TYPE.APPLICATION_JSON_TABLE, ACCEPT_TYPE.APPLICATION_CSV, ACCEPT_TYPE.APPLICATION_XLSX, + ACCEPT_TYPE.APPLICATION_PDF ]); // Retrieves the json table format. if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { @@ -98,6 +99,15 @@ export default class APAgingSummaryReportController extends BaseFinancialReportC 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ); return res.send(buffer); + // Retrieves the pdf format. + } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { + const pdfContent = await this.APAgingSummaryApp.pdf(tenantId, filter); + + res.set({ + 'Content-Type': 'application/pdf', + 'Content-Length': pdfContent.length, + }); + return res.send(pdfContent); // Retrieves the json format. } else { const sheet = await this.APAgingSummaryApp.sheet(tenantId, filter); diff --git a/packages/server/src/api/controllers/FinancialStatements/ARAgingSummary.ts b/packages/server/src/api/controllers/FinancialStatements/ARAgingSummary.ts index 10e42e900..86b4b920a 100644 --- a/packages/server/src/api/controllers/FinancialStatements/ARAgingSummary.ts +++ b/packages/server/src/api/controllers/FinancialStatements/ARAgingSummary.ts @@ -11,7 +11,7 @@ import { ACCEPT_TYPE } from '@/interfaces/Http'; @Service() export default class ARAgingSummaryReportController extends BaseFinancialReportController { @Inject() - ARAgingSummaryApp: ARAgingSummaryApplication; + private ARAgingSummaryApp: ARAgingSummaryApplication; /** * Router constructor. @@ -69,6 +69,7 @@ export default class ARAgingSummaryReportController extends BaseFinancialReportC ACCEPT_TYPE.APPLICATION_JSON_TABLE, ACCEPT_TYPE.APPLICATION_CSV, ACCEPT_TYPE.APPLICATION_XLSX, + ACCEPT_TYPE.APPLICATION_PDF ]); // Retrieves the xlsx format. if (ACCEPT_TYPE.APPLICATION_XLSX === acceptType) { @@ -96,6 +97,15 @@ export default class ARAgingSummaryReportController extends BaseFinancialReportC res.setHeader('Content-Type', 'text/csv'); return res.send(buffer); + // Retrieves the pdf format. + } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { + const pdfContent = await this.ARAgingSummaryApp.pdf(tenantId, filter); + + res.set({ + 'Content-Type': 'application/pdf', + 'Content-Length': pdfContent.length, + }); + return res.send(pdfContent); // Retrieves the json format. } else { const sheet = await this.ARAgingSummaryApp.sheet(tenantId, filter); diff --git a/packages/server/src/api/controllers/FinancialStatements/BalanceSheet.ts b/packages/server/src/api/controllers/FinancialStatements/BalanceSheet.ts index 0af53d723..fda717a38 100644 --- a/packages/server/src/api/controllers/FinancialStatements/BalanceSheet.ts +++ b/packages/server/src/api/controllers/FinancialStatements/BalanceSheet.ts @@ -101,6 +101,7 @@ export default class BalanceSheetStatementController extends BaseFinancialReport ACCEPT_TYPE.APPLICATION_JSON_TABLE, ACCEPT_TYPE.APPLICATION_XLSX, ACCEPT_TYPE.APPLICATION_CSV, + ACCEPT_TYPE.APPLICATION_PDF, ]); // Retrieves the json table format. if (ACCEPT_TYPE.APPLICATION_JSON_TABLE == acceptType) { @@ -128,6 +129,15 @@ export default class BalanceSheetStatementController extends BaseFinancialReport 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ); return res.send(buffer); + // Retrieves the pdf format. + } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { + const pdfContent = await this.balanceSheetApp.pdf(tenantId, filter); + + res.set({ + 'Content-Type': 'application/pdf', + 'Content-Length': pdfContent.length, + }); + res.send(pdfContent); } else { const sheet = await this.balanceSheetApp.sheet(tenantId, filter); diff --git a/packages/server/src/api/controllers/FinancialStatements/CashFlow/CashFlow.ts b/packages/server/src/api/controllers/FinancialStatements/CashFlow/CashFlow.ts index bab04246d..bc24b5379 100644 --- a/packages/server/src/api/controllers/FinancialStatements/CashFlow/CashFlow.ts +++ b/packages/server/src/api/controllers/FinancialStatements/CashFlow/CashFlow.ts @@ -79,6 +79,7 @@ export default class CashFlowController extends BaseFinancialReportController { ACCEPT_TYPE.APPLICATION_JSON_TABLE, ACCEPT_TYPE.APPLICATION_CSV, ACCEPT_TYPE.APPLICATION_XLSX, + ACCEPT_TYPE.APPLICATION_PDF ]); // Retrieves the json table format. if (ACCEPT_TYPE.APPLICATION_JSON_TABLE === acceptType) { @@ -106,6 +107,15 @@ export default class CashFlowController extends BaseFinancialReportController { 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ); return res.send(buffer); + // Retrieves the pdf format. + } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { + const pdfContent = await this.cashflowSheetApp.pdf(tenantId, filter); + + res.set({ + 'Content-Type': 'application/pdf', + 'Content-Length': pdfContent.length, + }); + return res.send(pdfContent); // Retrieves the json format. } else { const cashflow = await this.cashflowSheetApp.sheet(tenantId, filter); diff --git a/packages/server/src/api/controllers/FinancialStatements/JournalSheet.ts b/packages/server/src/api/controllers/FinancialStatements/JournalSheet.ts index 871bc9af8..0355766db 100644 --- a/packages/server/src/api/controllers/FinancialStatements/JournalSheet.ts +++ b/packages/server/src/api/controllers/FinancialStatements/JournalSheet.ts @@ -72,6 +72,7 @@ export default class JournalSheetController extends BaseFinancialReportControlle ACCEPT_TYPE.APPLICATION_JSON_TABLE, ACCEPT_TYPE.APPLICATION_XLSX, ACCEPT_TYPE.APPLICATION_CSV, + ACCEPT_TYPE.APPLICATION_PDF, ]); // Retrieves the json table format. @@ -97,6 +98,14 @@ export default class JournalSheetController extends BaseFinancialReportControlle ); return res.send(buffer); // Retrieves the json format. + } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { + const pdfContent = await this.journalSheetApp.pdf(tenantId, filter); + + res.set({ + 'Content-Type': 'application/pdf', + 'Content-Length': pdfContent.length, + }); + res.send(pdfContent); } else { const sheet = await this.journalSheetApp.sheet(tenantId, filter); diff --git a/packages/server/src/api/controllers/FinancialStatements/ProfitLossSheet.ts b/packages/server/src/api/controllers/FinancialStatements/ProfitLossSheet.ts index 8c2404335..995df07b4 100644 --- a/packages/server/src/api/controllers/FinancialStatements/ProfitLossSheet.ts +++ b/packages/server/src/api/controllers/FinancialStatements/ProfitLossSheet.ts @@ -96,6 +96,7 @@ export default class ProfitLossSheetController extends BaseFinancialReportContro ACCEPT_TYPE.APPLICATION_JSON_TABLE, ACCEPT_TYPE.APPLICATION_CSV, ACCEPT_TYPE.APPLICATION_XLSX, + ACCEPT_TYPE.APPLICATION_PDF, ]); try { // Retrieves the csv format. @@ -125,6 +126,14 @@ export default class ProfitLossSheetController extends BaseFinancialReportContro ); return res.send(sheet); // Retrieves the json format. + } else if (acceptType === ACCEPT_TYPE.APPLICATION_PDF) { + const pdfContent = await this.profitLossSheetApp.pdf(tenantId, filter); + + res.set({ + 'Content-Type': 'application/pdf', + 'Content-Length': pdfContent.length, + }); + return res.send(pdfContent); } else { const sheet = await this.profitLossSheetApp.sheet(tenantId, filter); diff --git a/packages/server/src/api/controllers/FinancialStatements/SalesByItems.ts b/packages/server/src/api/controllers/FinancialStatements/SalesByItems.ts index bac67231c..28ab611c0 100644 --- a/packages/server/src/api/controllers/FinancialStatements/SalesByItems.ts +++ b/packages/server/src/api/controllers/FinancialStatements/SalesByItems.ts @@ -11,7 +11,7 @@ import { SalesByItemsApplication } from '@/services/FinancialStatements/SalesByI @Service() export default class SalesByItemsReportController extends BaseFinancialReportController { @Inject() - salesByItemsApp: SalesByItemsApplication; + private salesByItemsApp: SalesByItemsApplication; /** * Router constructor. @@ -71,6 +71,7 @@ export default class SalesByItemsReportController extends BaseFinancialReportCon ACCEPT_TYPE.APPLICATION_JSON_TABLE, ACCEPT_TYPE.APPLICATION_CSV, ACCEPT_TYPE.APPLICATION_XLSX, + ACCEPT_TYPE.APPLICATION_PDF, ]); // Retrieves the csv format. if (ACCEPT_TYPE.APPLICATION_CSV === acceptType) { @@ -96,6 +97,14 @@ export default class SalesByItemsReportController extends BaseFinancialReportCon ); return res.send(buffer); // Retrieves the json format. + } else if (ACCEPT_TYPE.APPLICATION_PDF === acceptType) { + const pdfContent = await this.salesByItemsApp.pdf(tenantId, filter); + + res.set({ + 'Content-Type': 'application/pdf', + 'Content-Length': pdfContent.length, + }); + return res.send(pdfContent); } else { const sheet = await this.salesByItemsApp.sheet(tenantId, filter); return res.status(200).send(sheet); diff --git a/packages/server/src/api/controllers/FinancialStatements/TrialBalanceSheet.ts b/packages/server/src/api/controllers/FinancialStatements/TrialBalanceSheet.ts index ce23c1071..b92e355a2 100644 --- a/packages/server/src/api/controllers/FinancialStatements/TrialBalanceSheet.ts +++ b/packages/server/src/api/controllers/FinancialStatements/TrialBalanceSheet.ts @@ -3,7 +3,6 @@ import { Request, Response, Router, NextFunction } from 'express'; import { query, ValidationChain } from 'express-validator'; import { castArray } from 'lodash'; import asyncMiddleware from '@/api/middleware/asyncMiddleware'; -import TrialBalanceSheetService from '@/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetInjectable'; import BaseFinancialReportController from './BaseFinancialReportController'; import { AbilitySubject, ReportsAction } from '@/interfaces'; import CheckPolicies from '@/api/middleware/CheckPolicies'; @@ -81,6 +80,7 @@ export default class TrialBalanceSheetController extends BaseFinancialReportCont ACCEPT_TYPE.APPLICATION_JSON_TABLE, ACCEPT_TYPE.APPLICATION_CSV, ACCEPT_TYPE.APPLICATION_XLSX, + ACCEPT_TYPE.APPLICATION_PDF, ]); // Retrieves in json table format. if (acceptType === ACCEPT_TYPE.APPLICATION_JSON_TABLE) { @@ -109,6 +109,17 @@ export default class TrialBalanceSheetController extends BaseFinancialReportCont res.setHeader('Content-Type', 'text/csv'); return res.send(buffer); + // Retrieves in pdf format. + } else if (acceptType === ACCEPT_TYPE.APPLICATION_PDF) { + const pdfContent = await this.trialBalanceSheetApp.pdf( + tenantId, + filter + ); + res.set({ + 'Content-Type': 'application/pdf', + 'Content-Length': pdfContent.length, + }); + res.send(pdfContent); // Retrieves in json format. } else { const { data, query, meta } = await this.trialBalanceSheetApp.sheet( diff --git a/packages/server/src/api/controllers/FinancialStatements/VendorBalanceSummary/index.ts b/packages/server/src/api/controllers/FinancialStatements/VendorBalanceSummary/index.ts index ade69cb62..f1e26a0ed 100644 --- a/packages/server/src/api/controllers/FinancialStatements/VendorBalanceSummary/index.ts +++ b/packages/server/src/api/controllers/FinancialStatements/VendorBalanceSummary/index.ts @@ -72,6 +72,7 @@ export default class VendorBalanceSummaryReportController extends BaseFinancialR ACCEPT_TYPE.APPLICATION_JSON_TABLE, ACCEPT_TYPE.APPLICATION_CSV, ACCEPT_TYPE.APPLICATION_XLSX, + ACCEPT_TYPE.APPLICATION_PDF, ]); // Retrieves the csv format. @@ -100,6 +101,17 @@ export default class VendorBalanceSummaryReportController extends BaseFinancialR filter ); return res.status(200).send(table); + // Retrieves the pdf format. + } else if (acceptType === ACCEPT_TYPE.APPLICATION_PDF) { + const pdfContent = await this.vendorBalanceSummaryApp.pdf( + tenantId, + filter + ); + res.set({ + 'Content-Type': 'application/pdf', + 'Content-Length': pdfContent.length, + }); + return res.send(pdfContent); // Retrieves the json format. } else { const sheet = await this.vendorBalanceSummaryApp.sheet( diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryApplication.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryApplication.ts index 73c08b2d8..52e6db251 100644 --- a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryApplication.ts +++ b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryApplication.ts @@ -3,6 +3,7 @@ import { APAgingSummaryExportInjectable } from './APAgingSummaryExportInjectable import { APAgingSummaryTableInjectable } from './APAgingSummaryTableInjectable'; import { IAPAgingSummaryQuery } from '@/interfaces'; import { APAgingSummaryService } from './APAgingSummaryService'; +import { APAgingSummaryPdfInjectable } from './APAgingSummaryPdfInjectable'; @Service() export class APAgingSummaryApplication { @@ -15,6 +16,9 @@ export class APAgingSummaryApplication { @Inject() private APAgingSummarySheet: APAgingSummaryService; + @Inject() + private APAgingSumaryPdf: APAgingSummaryPdfInjectable; + /** * Retrieve the A/P aging summary in sheet format. * @param {number} tenantId @@ -50,4 +54,14 @@ export class APAgingSummaryApplication { public xlsx(tenantId: number, query: IAPAgingSummaryQuery) { return this.APAgingSummaryExport.xlsx(tenantId, query); } + + /** + * Retrieves the A/P aging summary in pdf format. + * @param {number} tenantId + * @param {IAPAgingSummaryQuery} query + * @returns {Promise} + */ + public pdf(tenantId: number, query: IAPAgingSummaryQuery) { + return this.APAgingSumaryPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryPdfInjectable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryPdfInjectable.ts new file mode 100644 index 000000000..e1a74f80a --- /dev/null +++ b/packages/server/src/services/FinancialStatements/AgingSummary/APAgingSummaryPdfInjectable.ts @@ -0,0 +1,34 @@ +import { Inject, Service } from 'typedi'; +import { IAPAgingSummaryQuery } from '@/interfaces'; +import { TableSheetPdf } from '../TableSheetPdf'; +import { APAgingSummaryTableInjectable } from './APAgingSummaryTableInjectable'; + +@Service() +export class APAgingSummaryPdfInjectable { + @Inject() + private APAgingSummaryTable: APAgingSummaryTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Converts the given A/P aging summary sheet table to pdf. + * @param {number} tenantId - Tenant ID. + * @param {IAPAgingSummaryQuery} query - Balance sheet query. + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: IAPAgingSummaryQuery + ): Promise { + const table = await this.APAgingSummaryTable.table(tenantId, query); + const sheetName = 'AR Aging Summary'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +} diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryApplication.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryApplication.ts index d3282ca4b..f24932f13 100644 --- a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryApplication.ts +++ b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryApplication.ts @@ -3,6 +3,7 @@ import { IARAgingSummaryQuery } from '@/interfaces'; import { ARAgingSummaryTableInjectable } from './ARAgingSummaryTableInjectable'; import { ARAgingSummaryExportInjectable } from './ARAgingSummaryExportInjectable'; import ARAgingSummaryService from './ARAgingSummaryService'; +import { ARAgingSummaryPdfInjectable } from './ARAgingSummaryPdfInjectable'; @Service() export class ARAgingSummaryApplication { @@ -15,6 +16,9 @@ export class ARAgingSummaryApplication { @Inject() private ARAgingSummarySheet: ARAgingSummaryService; + @Inject() + private ARAgingSummaryPdf: ARAgingSummaryPdfInjectable; + /** * Retrieve the A/R aging summary sheet. * @param {number} tenantId @@ -50,4 +54,14 @@ export class ARAgingSummaryApplication { public csv(tenantId: number, query: IARAgingSummaryQuery) { return this.ARAgingSummaryExport.csv(tenantId, query); } + + /** + * Retrieves the A/R aging summary in pdf format. + * @param {number} tenantId + * @param {IARAgingSummaryQuery} query + * @returns {Promise} + */ + public pdf(tenantId: number, query: IARAgingSummaryQuery) { + return this.ARAgingSummaryPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryPdfInjectable.ts b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryPdfInjectable.ts new file mode 100644 index 000000000..57ea3fef5 --- /dev/null +++ b/packages/server/src/services/FinancialStatements/AgingSummary/ARAgingSummaryPdfInjectable.ts @@ -0,0 +1,34 @@ +import { Inject, Service } from 'typedi'; +import { IARAgingSummaryQuery } from '@/interfaces'; +import { TableSheetPdf } from '../TableSheetPdf'; +import { ARAgingSummaryTableInjectable } from './ARAgingSummaryTableInjectable'; + +@Service() +export class ARAgingSummaryPdfInjectable { + @Inject() + private ARAgingSummaryTable: ARAgingSummaryTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Converts the given balance sheet table to pdf. + * @param {number} tenantId - Tenant ID. + * @param {IBalanceSheetQuery} query - Balance sheet query. + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: IARAgingSummaryQuery + ): Promise { + const table = await this.ARAgingSummaryTable.table(tenantId, query); + const sheetName = 'AR Aging Summary'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetApplication.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetApplication.ts index 01ab77bfe..0c965a5f5 100644 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetApplication.ts +++ b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetApplication.ts @@ -54,4 +54,14 @@ export class BalanceSheetApplication { public csv(tenantId: number, query: IBalanceSheetQuery): Promise { return this.balanceSheetExport.csv(tenantId, query); } + + /** + * Retrieves the balance sheet in pdf format. + * @param {number} tenantId + * @param {IBalanceSheetQuery} query + * @returns {Promise} + */ + public pdf(tenantId: number, query: IBalanceSheetQuery) { + return this.balanceSheetExport.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetExportInjectable.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetExportInjectable.ts index 2c43d5f80..9198d8536 100644 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetExportInjectable.ts +++ b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetExportInjectable.ts @@ -2,12 +2,16 @@ import { Inject, Service } from 'typedi'; import { BalanceSheetTableInjectable } from './BalanceSheetTableInjectable'; import { TableSheet } from '@/lib/Xlsx/TableSheet'; import { IBalanceSheetQuery } from '@/interfaces'; +import { BalanceSheetPdfInjectable } from './BalanceSheetPdfInjectable'; @Service() export class BalanceSheetExportInjectable { @Inject() private balanceSheetTable: BalanceSheetTableInjectable; + @Inject() + private balanceSheetPdf: BalanceSheetPdfInjectable; + /** * Retrieves the trial balance sheet in XLSX format. * @param {number} tenantId @@ -40,4 +44,17 @@ export class BalanceSheetExportInjectable { return tableCsv; } + + /** + * Retrieves the balance sheet in pdf format. + * @param {number} tenantId + * @param {IBalanceSheetQuery} query + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: IBalanceSheetQuery + ): Promise { + return this.balanceSheetPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPdfInjectable.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPdfInjectable.ts new file mode 100644 index 000000000..44fd991b3 --- /dev/null +++ b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetPdfInjectable.ts @@ -0,0 +1,34 @@ +import { Inject, Service } from 'typedi'; +import { IBalanceSheetQuery } from '@/interfaces'; +import { BalanceSheetTableInjectable } from './BalanceSheetTableInjectable'; +import { TableSheetPdf } from '../TableSheetPdf'; + +@Service() +export class BalanceSheetPdfInjectable { + @Inject() + private balanceSheetTable: BalanceSheetTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Converts the given balance sheet table to pdf. + * @param {number} tenantId - Tenant ID. + * @param {IBalanceSheetQuery} query - Balance sheet query. + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: IBalanceSheetQuery + ): Promise { + const table = await this.balanceSheetTable.table(tenantId, query); + const sheetName = 'Balance Sheet'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +} diff --git a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTable.ts b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTable.ts index 349b1a8f4..088362766 100644 --- a/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTable.ts +++ b/packages/server/src/services/FinancialStatements/BalanceSheet/BalanceSheetTable.ts @@ -43,13 +43,13 @@ export default class BalanceSheetTable extends R.compose( /** * @param {} */ - reportData: IBalanceSheetStatementData; + private reportData: IBalanceSheetStatementData; /** * Balance sheet query. * @parma {} */ - query: BalanceSheetQuery; + private query: BalanceSheetQuery; /** * Constructor method. diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetApplication.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetApplication.ts index 0fd8b7357..72a587f52 100644 --- a/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetApplication.ts +++ b/packages/server/src/services/FinancialStatements/CashFlow/CashflowSheetApplication.ts @@ -3,6 +3,7 @@ import { CashflowExportInjectable } from './CashflowExportInjectable'; import { ICashFlowStatementQuery } from '@/interfaces'; import CashFlowStatementService from './CashFlowService'; import { CashflowTableInjectable } from './CashflowTableInjectable'; +import { CashflowTablePdfInjectable } from './CashflowTablePdfInjectable'; @Service() export class CashflowSheetApplication { @@ -15,6 +16,9 @@ export class CashflowSheetApplication { @Inject() private cashflowTable: CashflowTableInjectable; + @Inject() + private cashflowPdf: CashflowTablePdfInjectable; + /** * Retrieves the cashflow sheet * @param {number} tenantId @@ -55,4 +59,17 @@ export class CashflowSheetApplication { ): Promise { return this.cashflowExport.csv(tenantId, query); } + + /** + * Retrieves the cashflow sheet in pdf format. + * @param {number} tenantId + * @param {ICashFlowStatementQuery} query + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: ICashFlowStatementQuery + ): Promise { + return this.cashflowPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/CashFlow/CashflowTablePdfInjectable.ts b/packages/server/src/services/FinancialStatements/CashFlow/CashflowTablePdfInjectable.ts new file mode 100644 index 000000000..eaab60db4 --- /dev/null +++ b/packages/server/src/services/FinancialStatements/CashFlow/CashflowTablePdfInjectable.ts @@ -0,0 +1,33 @@ +import { Inject } from 'typedi'; +import { CashflowTableInjectable } from './CashflowTableInjectable'; +import { TableSheetPdf } from '../TableSheetPdf'; +import { ICashFlowStatementQuery } from '@/interfaces'; + +export class CashflowTablePdfInjectable { + @Inject() + private cashflowTable: CashflowTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Converts the given cashflow sheet table to pdf. + * @param {number} tenantId - Tenant ID. + * @param {IBalanceSheetQuery} query - Balance sheet query. + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: ICashFlowStatementQuery + ): Promise { + const table = await this.cashflowTable.table(tenantId, query); + const sheetName = 'Cashflow Sheet'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +} diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts index 964cd91a9..a1693e7d8 100644 --- a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts +++ b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryApplication.ts @@ -3,6 +3,7 @@ import { CustomerBalanceSummaryExportInjectable } from './CustomerBalanceSummary import { CustomerBalanceSummaryTableInjectable } from './CustomerBalanceSummaryTableInjectable'; import { ICustomerBalanceSummaryQuery } from '@/interfaces'; import { CustomerBalanceSummaryService } from './CustomerBalanceSummaryService'; +import { CustomerBalanceSummaryPdf } from './CustomerBalanceSummaryPdf'; @Service() export class CustomerBalanceSummaryApplication { @@ -15,6 +16,9 @@ export class CustomerBalanceSummaryApplication { @Inject() private customerBalanceSummarySheet: CustomerBalanceSummaryService; + @Inject() + private customerBalanceSummaryPdf: CustomerBalanceSummaryPdf; + /** * Retrieves the customer balance sheet in json format. * @param {number} tenantId @@ -57,4 +61,14 @@ export class CustomerBalanceSummaryApplication { public csv(tenantId: number, query: ICustomerBalanceSummaryQuery) { return this.customerBalanceSummaryExport.csv(tenantId, query); } + + /** + * Retrieves the customer balance sheet in PDF format. + * @param {number} tenantId + * @param {ICustomerBalanceSummaryQuery} query + * @returns {Promise} + */ + public pdf(tenantId: number, query: ICustomerBalanceSummaryQuery) { + return this.customerBalanceSummaryPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts new file mode 100644 index 000000000..67e74349b --- /dev/null +++ b/packages/server/src/services/FinancialStatements/CustomerBalanceSummary/CustomerBalanceSummaryPdf.ts @@ -0,0 +1,34 @@ +import { Inject, Service } from 'typedi'; +import { IAPAgingSummaryQuery, ICustomerBalanceSummaryQuery } from '@/interfaces'; +import { TableSheetPdf } from '../TableSheetPdf'; +import { CustomerBalanceSummaryTableInjectable } from './CustomerBalanceSummaryTableInjectable'; + +@Service() +export class CustomerBalanceSummaryPdf { + @Inject() + private customerBalanceSummaryTable: CustomerBalanceSummaryTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Converts the given A/P aging summary sheet table to pdf. + * @param {number} tenantId - Tenant ID. + * @param {IAPAgingSummaryQuery} query - Balance sheet query. + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: ICustomerBalanceSummaryQuery + ): Promise { + const table = await this.customerBalanceSummaryTable.table(tenantId, query); + const sheetName = 'Customer Balance Summary'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +} diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetApplication.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetApplication.ts index 4c403ff58..8d3f5d614 100644 --- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetApplication.ts +++ b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetApplication.ts @@ -3,6 +3,7 @@ import { JournalSheetService } from './JournalSheetService'; import { JournalSheetTableInjectable } from './JournalSheetTableInjectable'; import { IJournalReportQuery, IJournalTable } from '@/interfaces'; import { JournalSheetExportInjectable } from './JournalSheetExport'; +import { JournalSheetPdfInjectable } from './JournalSheetPdfInjectable'; export class JournalSheetApplication { @Inject() @@ -14,6 +15,9 @@ export class JournalSheetApplication { @Inject() private journalExport: JournalSheetExportInjectable; + @Inject() + private journalPdf: JournalSheetPdfInjectable; + /** * Retrieves the journal sheet. * @param {number} tenantId @@ -56,4 +60,14 @@ export class JournalSheetApplication { public csv(tenantId: number, query: IJournalReportQuery) { return this.journalExport.csv(tenantId, query); } + + /** + * Retrieves the journal sheet in pdf format. + * @param {number} tenantId + * @param {IJournalReportQuery} query + * @returns {Promise} + */ + public pdf(tenantId: number, query: IJournalReportQuery) { + return this.journalPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetPdfInjectable.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetPdfInjectable.ts new file mode 100644 index 000000000..e3fcbfb26 --- /dev/null +++ b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetPdfInjectable.ts @@ -0,0 +1,34 @@ +import { IJournalReportQuery } from '@/interfaces'; +import { TableSheetPdf } from '../TableSheetPdf'; +import { JournalSheetTableInjectable } from './JournalSheetTableInjectable'; +import { Inject, Service } from 'typedi'; + +@Service() +export class JournalSheetPdfInjectable { + @Inject() + private journalSheetTable: JournalSheetTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Converts the given journal sheet table to pdf. + * @param {number} tenantId - Tenant ID. + * @param {IBalanceSheetQuery} query - Balance sheet query. + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: IJournalReportQuery + ): Promise { + const table = await this.journalSheetTable.table(tenantId, query); + const sheetName = 'Journal Sheet'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +} diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetApplication.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetApplication.ts index eee89e73a..6d15e2cc6 100644 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetApplication.ts +++ b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetApplication.ts @@ -3,6 +3,7 @@ import { ProfitLossSheetExportInjectable } from './ProfitLossSheetExportInjectab import { ProfitLossSheetTableInjectable } from './ProfitLossSheetTableInjectable'; import { IProfitLossSheetQuery, IProfitLossSheetTable } from '@/interfaces'; import ProfitLossSheetService from './ProfitLossSheetService'; +import { ProfitLossTablePdfInjectable } from './ProfitLossTablePdfInjectable'; @Service() export class ProfitLossSheetApplication { @@ -15,6 +16,9 @@ export class ProfitLossSheetApplication { @Inject() private profitLossSheet: ProfitLossSheetService; + @Inject() + private profitLossPdf: ProfitLossTablePdfInjectable; + /** * Retreives the profit/loss sheet. * @param {number} tenantId @@ -57,4 +61,14 @@ export class ProfitLossSheetApplication { public xlsx(tenantId: number, query: IProfitLossSheetQuery): Promise { return this.profitLossExport.xlsx(tenantId, query); } + + /** + * Retrieves the profit/loss sheet in pdf format. + * @param {number} tenantId + * @param {IProfitLossSheetQuery} query + * @returns {Promise} + */ + public pdf(tenantId: number, query: IProfitLossSheetQuery): Promise { + return this.profitLossPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetExportInjectable.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetExportInjectable.ts index ba2371797..4fa9762d3 100644 --- a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetExportInjectable.ts +++ b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetExportInjectable.ts @@ -40,4 +40,11 @@ export class ProfitLossSheetExportInjectable { return tableCsv; } + + public async pdf( + tenantId: number, + query: IProfitLossSheetQuery + ): Promise { + const table = await this.profitLossSheetTable.table(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePdfInjectable.ts b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePdfInjectable.ts new file mode 100644 index 000000000..24b720b1a --- /dev/null +++ b/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossTablePdfInjectable.ts @@ -0,0 +1,34 @@ +import { Inject, Service } from 'typedi'; +import { IProfitLossSheetQuery } from '@/interfaces'; +import { ProfitLossSheetTableInjectable } from './ProfitLossSheetTableInjectable'; +import { TableSheetPdf } from '../TableSheetPdf'; + +@Service() +export class ProfitLossTablePdfInjectable { + @Inject() + private profitLossTable: ProfitLossSheetTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Retrieves the profit/loss sheet in pdf format. + * @param {number} tenantId + * @param {number} query + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: IProfitLossSheetQuery + ): Promise { + const table = await this.profitLossTable.table(tenantId, query); + const sheetName = 'Profit & Loss Sheet'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +} diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsApplication.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsApplication.ts index b3b51869f..498e3eb66 100644 --- a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsApplication.ts +++ b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsApplication.ts @@ -8,6 +8,7 @@ import { import { SalesByItemsReportService } from './SalesByItemsService'; import { SalesByItemsTableInjectable } from './SalesByItemsTableInjectable'; import { SalesByItemsExport } from './SalesByItemsExport'; +import { SalesByItemsPdfInjectable } from './SalesByItemsPdfInjectable'; @Service() export class SalesByItemsApplication { @@ -20,6 +21,9 @@ export class SalesByItemsApplication { @Inject() private salesByItemsExport: SalesByItemsExport; + @Inject() + private salesByItemsPdf: SalesByItemsPdfInjectable; + /** * Retrieves the sales by items report in json format. * @param {number} tenantId @@ -71,4 +75,17 @@ export class SalesByItemsApplication { ): Promise { return this.salesByItemsExport.xlsx(tenantId, filter); } + + /** + * Retrieves the sales by items in pdf format. + * @param {number} tenantId + * @param {ISalesByItemsReportQuery} query + * @returns {Promise} + */ + public pdf( + tenantId: number, + query: ISalesByItemsReportQuery + ): Promise { + return this.salesByItemsPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsPdfInjectable.ts b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsPdfInjectable.ts new file mode 100644 index 000000000..6cf3d98ec --- /dev/null +++ b/packages/server/src/services/FinancialStatements/SalesByItems/SalesByItemsPdfInjectable.ts @@ -0,0 +1,34 @@ +import { Inject, Service } from 'typedi'; +import { ISalesByItemsReportQuery } from '@/interfaces'; +import { SalesByItemsTableInjectable } from './SalesByItemsTableInjectable'; +import { TableSheetPdf } from '../TableSheetPdf'; + +@Service() +export class SalesByItemsPdfInjectable { + @Inject() + private salesByItemsTable: SalesByItemsTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Retrieves the sales by items sheet in pdf format. + * @param {number} tenantId + * @param {number} query + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: ISalesByItemsReportQuery + ): Promise { + const table = await this.salesByItemsTable.table(tenantId, query); + const sheetName = 'Sales By Items'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +} diff --git a/packages/server/src/services/FinancialStatements/TableSheetPdf.ts b/packages/server/src/services/FinancialStatements/TableSheetPdf.ts new file mode 100644 index 000000000..16fd0f6f9 --- /dev/null +++ b/packages/server/src/services/FinancialStatements/TableSheetPdf.ts @@ -0,0 +1,62 @@ +import { Inject, Service } from 'typedi'; +import * as R from 'ramda'; +import { ITableColumn, ITableData, ITableRow } from '@/interfaces'; +import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy'; +import { TemplateInjectable } from '@/services/TemplateInjectable/TemplateInjectable'; +import { FinancialTableStructure } from './FinancialTableStructure'; + +@Service() +export class TableSheetPdf { + @Inject() + private templateInjectable: TemplateInjectable; + + @Inject() + private chromiumlyTenancy: ChromiumlyTenancy; + + /** + * Converts the table to PDF. + * @param {number} tenantId - + * @param {IFinancialTable} table - + * @param {string} sheetName - Sheet name. + * @param {string} sheetDate - Sheet date. + */ + public async convertToPdf( + tenantId: number, + table: ITableData, + sheetName: string, + sheetDate: string + ) { + const columns = this.tablePdfColumns(table.columns); + const rows = this.tablePdfRows(table.rows); + const htmlContent = await this.templateInjectable.render( + tenantId, + 'modules/financial-sheet', + { + sheetName, + sheetDate, + table: { rows, columns }, + } + ); + return this.chromiumlyTenancy.convertHtmlContent(tenantId, htmlContent, { + margins: { top: 0, bottom: 0, left: 0, right: 0 }, + }); + } + + /** + * Converts the table columns to pdf columns. + * @param {ITableColumn[]} columns + * @returns {ITableColumn[]} + */ + private tablePdfColumns = (columns: ITableColumn[]): ITableColumn[] => { + return columns; + }; + + /** + * Converts the table rows to pdf rows. + * @param {ITableRow[]} rows - + * @returns {ITableRow[]} + */ + private tablePdfRows = (rows: ITableRow[]): ITableRow[] => { + return R.compose(FinancialTableStructure.flatNestedTree)(rows); + }; +} diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceExportInjectable.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceExportInjectable.ts index a515f1beb..62b847f7c 100644 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceExportInjectable.ts +++ b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceExportInjectable.ts @@ -1,13 +1,17 @@ +import { Inject, Service } from 'typedi'; import { TableSheet } from '@/lib/Xlsx/TableSheet'; import { ITrialBalanceSheetQuery } from '@/interfaces'; -import { Inject, Service } from 'typedi'; import { TrialBalanceSheetTableInjectable } from './TrialBalanceSheetTableInjectable'; +import { TrialBalanceSheetPdfInjectable } from './TrialBalanceSheetPdfInjectsable'; @Service() export class TrialBalanceExportInjectable { @Inject() private trialBalanceSheetTable: TrialBalanceSheetTableInjectable; + @Inject() + private trialBalanceSheetPdf: TrialBalanceSheetPdfInjectable; + /** * Retrieves the trial balance sheet in XLSX format. * @param {number} tenantId @@ -40,4 +44,17 @@ export class TrialBalanceExportInjectable { return tableCsv; } + + /** + * Retrieves the trial balance sheet in PDF format. + * @param {number} tenantId + * @param {ITrialBalanceSheetQuery} query + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: ITrialBalanceSheetQuery + ): Promise { + return this.trialBalanceSheetPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetApplication.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetApplication.ts index a771c8f15..20c485ecc 100644 --- a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetApplication.ts +++ b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetApplication.ts @@ -57,4 +57,14 @@ export class TrialBalanceSheetApplication { public async xlsx(tenantId: number, query: ITrialBalanceSheetQuery) { return this.exportable.xlsx(tenantId, query); } + + /** + * Retrieve the trial balance sheet in pdf format. + * @param {number} tenantId + * @param {ITrialBalanceSheetQuery} query + * @returns {Promise} + */ + public async pdf(tenantId: number, query: ITrialBalanceSheetQuery) { + return this.exportable.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts new file mode 100644 index 000000000..1907dd26d --- /dev/null +++ b/packages/server/src/services/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetPdfInjectsable.ts @@ -0,0 +1,34 @@ +import { Inject, Service } from 'typedi'; +import { ITrialBalanceSheetQuery } from '@/interfaces'; +import { TableSheetPdf } from '../TableSheetPdf'; +import { TrialBalanceSheetTableInjectable } from './TrialBalanceSheetTableInjectable'; + +@Service() +export class TrialBalanceSheetPdfInjectable { + @Inject() + private trialBalanceSheetTable: TrialBalanceSheetTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Converts the given balance sheet table to pdf. + * @param {number} tenantId - Tenant ID. + * @param {IBalanceSheetQuery} query - Balance sheet query. + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: ITrialBalanceSheetQuery + ): Promise { + const table = await this.trialBalanceSheetTable.table(tenantId, query); + const sheetName = 'Trial Balance Sheet'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +} diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryApplication.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryApplication.ts index 5fe4bc74d..c02eac224 100644 --- a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryApplication.ts +++ b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryApplication.ts @@ -3,6 +3,7 @@ import { IVendorBalanceSummaryQuery } from '@/interfaces'; import { VendorBalanceSummaryTableInjectable } from './VendorBalanceSummaryTableInjectable'; import { VendorBalanceSummaryExportInjectable } from './VendorBalanceSummaryExportInjectable'; import { VendorBalanceSummaryService } from './VendorBalanceSummaryService'; +import { VendorBalanceSummaryPdf } from './VendorBalanceSummaryPdf'; @Service() export class VendorBalanceSummaryApplication { @@ -15,6 +16,9 @@ export class VendorBalanceSummaryApplication { @Inject() private vendorBalanceSummaryExport: VendorBalanceSummaryExportInjectable; + @Inject() + private vendorBalanceSummaryPdf: VendorBalanceSummaryPdf; + /** * Retrieves the vendor balance summary sheet in sheet format. * @param {number} tenantId @@ -59,4 +63,14 @@ export class VendorBalanceSummaryApplication { ): Promise { return this.vendorBalanceSummaryExport.csv(tenantId, query); } + + /** + * Retrieves the vendor balance summary sheet in pdf format. + * @param {number} tenantId + * @param {IVendorBalanceSummaryQuery} query + * @returns {Promise} + */ + public pdf(tenantId: number, query: IVendorBalanceSummaryQuery) { + return this.vendorBalanceSummaryPdf.pdf(tenantId, query); + } } diff --git a/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryPdf.ts b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryPdf.ts new file mode 100644 index 000000000..a404d673e --- /dev/null +++ b/packages/server/src/services/FinancialStatements/VendorBalanceSummary/VendorBalanceSummaryPdf.ts @@ -0,0 +1,34 @@ +import { Inject, Service } from 'typedi'; +import { IVendorBalanceSummaryQuery } from '@/interfaces'; +import { TableSheetPdf } from '../TableSheetPdf'; +import { VendorBalanceSummaryTableInjectable } from './VendorBalanceSummaryTableInjectable'; + +@Service() +export class VendorBalanceSummaryPdf { + @Inject() + private vendorBalanceSummaryTable: VendorBalanceSummaryTableInjectable; + + @Inject() + private tableSheetPdf: TableSheetPdf; + + /** + * Retrieves the sales by items sheet in pdf format. + * @param {number} tenantId + * @param {number} query + * @returns {Promise} + */ + public async pdf( + tenantId: number, + query: IVendorBalanceSummaryQuery + ): Promise { + const table = await this.vendorBalanceSummaryTable.table(tenantId, query); + const sheetName = 'Sales By Items'; + + return this.tableSheetPdf.convertToPdf( + tenantId, + table.table, + sheetName, + table.meta.baseCurrency + ); + } +}