feat(server): wip printing financial reports

This commit is contained in:
Ahmed Bouhuolia
2024-02-10 22:20:54 +02:00
parent ecaf8c99bb
commit 9395ef094a
36 changed files with 738 additions and 6 deletions

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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(

View File

@@ -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(

View File

@@ -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<Buffer>}
*/
public pdf(tenantId: number, query: IAPAgingSummaryQuery) {
return this.APAgingSumaryPdf.pdf(tenantId, query);
}
}

View File

@@ -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<Buffer>}
*/
public async pdf(
tenantId: number,
query: IAPAgingSummaryQuery
): Promise<Buffer> {
const table = await this.APAgingSummaryTable.table(tenantId, query);
const sheetName = 'AR Aging Summary';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}

View File

@@ -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<Buffer>}
*/
public pdf(tenantId: number, query: IARAgingSummaryQuery) {
return this.ARAgingSummaryPdf.pdf(tenantId, query);
}
}

View File

@@ -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<Buffer>}
*/
public async pdf(
tenantId: number,
query: IARAgingSummaryQuery
): Promise<Buffer> {
const table = await this.ARAgingSummaryTable.table(tenantId, query);
const sheetName = 'AR Aging Summary';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}

View File

@@ -54,4 +54,14 @@ export class BalanceSheetApplication {
public csv(tenantId: number, query: IBalanceSheetQuery): Promise<string> {
return this.balanceSheetExport.csv(tenantId, query);
}
/**
* Retrieves the balance sheet in pdf format.
* @param {number} tenantId
* @param {IBalanceSheetQuery} query
* @returns {Promise<Buffer>}
*/
public pdf(tenantId: number, query: IBalanceSheetQuery) {
return this.balanceSheetExport.pdf(tenantId, query);
}
}

View File

@@ -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<Buffer>}
*/
public async pdf(
tenantId: number,
query: IBalanceSheetQuery
): Promise<Buffer> {
return this.balanceSheetPdf.pdf(tenantId, query);
}
}

View File

@@ -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<Buffer>}
*/
public async pdf(
tenantId: number,
query: IBalanceSheetQuery
): Promise<Buffer> {
const table = await this.balanceSheetTable.table(tenantId, query);
const sheetName = 'Balance Sheet';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}

View File

@@ -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.

View File

@@ -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<string> {
return this.cashflowExport.csv(tenantId, query);
}
/**
* Retrieves the cashflow sheet in pdf format.
* @param {number} tenantId
* @param {ICashFlowStatementQuery} query
* @returns {Promise<Buffer>}
*/
public async pdf(
tenantId: number,
query: ICashFlowStatementQuery
): Promise<Buffer> {
return this.cashflowPdf.pdf(tenantId, query);
}
}

View File

@@ -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<Buffer>}
*/
public async pdf(
tenantId: number,
query: ICashFlowStatementQuery
): Promise<Buffer> {
const table = await this.cashflowTable.table(tenantId, query);
const sheetName = 'Cashflow Sheet';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}

View File

@@ -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<Buffer>}
*/
public pdf(tenantId: number, query: ICustomerBalanceSummaryQuery) {
return this.customerBalanceSummaryPdf.pdf(tenantId, query);
}
}

View File

@@ -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<Buffer>}
*/
public async pdf(
tenantId: number,
query: ICustomerBalanceSummaryQuery
): Promise<Buffer> {
const table = await this.customerBalanceSummaryTable.table(tenantId, query);
const sheetName = 'Customer Balance Summary';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}

View File

@@ -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<Buffer>}
*/
public pdf(tenantId: number, query: IJournalReportQuery) {
return this.journalPdf.pdf(tenantId, query);
}
}

View File

@@ -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<Buffer>}
*/
public async pdf(
tenantId: number,
query: IJournalReportQuery
): Promise<Buffer> {
const table = await this.journalSheetTable.table(tenantId, query);
const sheetName = 'Journal Sheet';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}

View File

@@ -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<Buffer> {
return this.profitLossExport.xlsx(tenantId, query);
}
/**
* Retrieves the profit/loss sheet in pdf format.
* @param {number} tenantId
* @param {IProfitLossSheetQuery} query
* @returns {Promise<Buffer>}
*/
public pdf(tenantId: number, query: IProfitLossSheetQuery): Promise<Buffer> {
return this.profitLossPdf.pdf(tenantId, query);
}
}

View File

@@ -40,4 +40,11 @@ export class ProfitLossSheetExportInjectable {
return tableCsv;
}
public async pdf(
tenantId: number,
query: IProfitLossSheetQuery
): Promise<Buffer> {
const table = await this.profitLossSheetTable.table(tenantId, query);
}
}

View File

@@ -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<IBalanceSheetTable>}
*/
public async pdf(
tenantId: number,
query: IProfitLossSheetQuery
): Promise<Buffer> {
const table = await this.profitLossTable.table(tenantId, query);
const sheetName = 'Profit & Loss Sheet';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}

View File

@@ -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<Buffer> {
return this.salesByItemsExport.xlsx(tenantId, filter);
}
/**
* Retrieves the sales by items in pdf format.
* @param {number} tenantId
* @param {ISalesByItemsReportQuery} query
* @returns {Promise<Buffer>}
*/
public pdf(
tenantId: number,
query: ISalesByItemsReportQuery
): Promise<Buffer> {
return this.salesByItemsPdf.pdf(tenantId, query);
}
}

View File

@@ -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<IBalanceSheetTable>}
*/
public async pdf(
tenantId: number,
query: ISalesByItemsReportQuery
): Promise<Buffer> {
const table = await this.salesByItemsTable.table(tenantId, query);
const sheetName = 'Sales By Items';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}

View File

@@ -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);
};
}

View File

@@ -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<Buffer>}
*/
public async pdf(
tenantId: number,
query: ITrialBalanceSheetQuery
): Promise<Buffer> {
return this.trialBalanceSheetPdf.pdf(tenantId, query);
}
}

View File

@@ -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<Buffer>}
*/
public async pdf(tenantId: number, query: ITrialBalanceSheetQuery) {
return this.exportable.pdf(tenantId, query);
}
}

View File

@@ -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<Buffer>}
*/
public async pdf(
tenantId: number,
query: ITrialBalanceSheetQuery
): Promise<Buffer> {
const table = await this.trialBalanceSheetTable.table(tenantId, query);
const sheetName = 'Trial Balance Sheet';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}

View File

@@ -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<string> {
return this.vendorBalanceSummaryExport.csv(tenantId, query);
}
/**
* Retrieves the vendor balance summary sheet in pdf format.
* @param {number} tenantId
* @param {IVendorBalanceSummaryQuery} query
* @returns {Promise<Buffer>}
*/
public pdf(tenantId: number, query: IVendorBalanceSummaryQuery) {
return this.vendorBalanceSummaryPdf.pdf(tenantId, query);
}
}

View File

@@ -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<IBalanceSheetTable>}
*/
public async pdf(
tenantId: number,
query: IVendorBalanceSummaryQuery
): Promise<Buffer> {
const table = await this.vendorBalanceSummaryTable.table(tenantId, query);
const sheetName = 'Sales By Items';
return this.tableSheetPdf.convertToPdf(
tenantId,
table.table,
sheetName,
table.meta.baseCurrency
);
}
}