feat(server): journal sheet csv/xlsx export

This commit is contained in:
Ahmed Bouhuolia
2024-01-02 21:53:37 +02:00
parent 5062d891e1
commit 276ef1c907
5 changed files with 238 additions and 8 deletions

View File

@@ -0,0 +1,59 @@
import { Inject } from 'typedi';
import { JournalSheetService } from './JournalSheetService';
import { JournalSheetTableInjectable } from './JournalSheetTableInjectable';
import { IJournalReportQuery, IJournalTable } from '@/interfaces';
import { JournalSheetExportInjectable } from './JournalSheetExport';
export class JournalSheetApplication {
@Inject()
private journalSheetTable: JournalSheetTableInjectable;
@Inject()
private journalSheet: JournalSheetService;
@Inject()
private journalExport: JournalSheetExportInjectable;
/**
* Retrieves the journal sheet.
* @param {number} tenantId
* @param {IJournalReportQuery} query
* @returns {}
*/
public sheet(tenantId: number, query: IJournalReportQuery) {
return this.journalSheet.journalSheet(tenantId, query);
}
/**
* Retrieves the journal sheet in table format.
* @param {number} tenantId
* @param {IJournalReportQuery} query
* @returns {Promise<IJournalTable>}
*/
public table(
tenantId: number,
query: IJournalReportQuery
): Promise<IJournalTable> {
return this.journalSheetTable.table(tenantId, query);
}
/**
* Retrieves the journal sheet in xlsx format.
* @param {number} tenantId
* @param {IJournalReportQuery} query
* @returns
*/
public xlsx(tenantId: number, query: IJournalReportQuery) {
return this.journalExport.xlsx(tenantId, query);
}
/**
* Retrieves the journal sheet in csv format.
* @param {number} tenantId
* @param {IJournalReportQuery} query
* @returns
*/
public csv(tenantId: number, query: IJournalReportQuery) {
return this.journalExport.csv(tenantId, query);
}
}

View File

@@ -0,0 +1,43 @@
import { Inject, Service } from 'typedi';
import { TableSheet } from '@/lib/Xlsx/TableSheet';
import { IJournalReportQuery } from '@/interfaces';
import { JournalSheetTableInjectable } from './JournalSheetTableInjectable';
@Service()
export class JournalSheetExportInjectable {
@Inject()
private journalSheetTable: JournalSheetTableInjectable;
/**
* Retrieves the trial balance sheet in XLSX format.
* @param {number} tenantId
* @param {IJournalReportQuery} query
* @returns {Promise<Buffer>}
*/
public async xlsx(tenantId: number, query: IJournalReportQuery) {
const table = await this.journalSheetTable.table(tenantId, query);
const tableSheet = new TableSheet(table.table);
const tableCsv = tableSheet.convertToXLSX();
return tableSheet.convertToBuffer(tableCsv, 'xlsx');
}
/**
* Retrieves the trial balance sheet in CSV format.
* @param {number} tenantId
* @param {IJournalReportQuery} query
* @returns {Promise<Buffer>}
*/
public async csv(
tenantId: number,
query: IJournalReportQuery
): Promise<string> {
const table = await this.journalSheetTable.table(tenantId, query);
const tableSheet = new TableSheet(table.table);
const tableCsv = tableSheet.convertToCSV();
return tableCsv;
}
}

View File

@@ -1,16 +1,15 @@
import { Service, Inject } from 'typedi';
import moment from 'moment';
import { IJournalReportQuery, IJournalSheetMeta } from '@/interfaces';
import JournalSheet from './JournalSheet';
import TenancyService from '@/services/Tenancy/TenancyService';
import Journal from '@/services/Accounting/JournalPoster';
import InventoryService from '@/services/Inventory/Inventory';
import { parseBoolean, transformToMap } from 'utils';
import { Tenant } from '@/system/models';
import { parseBoolean, transformToMap } from 'utils';
@Service()
export default class JournalSheetService {
export class JournalSheetService {
@Inject()
tenancy: TenancyService;
@@ -80,11 +79,6 @@ export default class JournalSheetService {
...this.defaultQuery,
...query,
};
this.logger.info('[journal] trying to calculate the report.', {
tenantId,
filter,
});
const tenant = await Tenant.query()
.findById(tenantId)
.withGraphFetched('metadata');

View File

@@ -0,0 +1,95 @@
import * as R from 'ramda';
import {
IJournalReport,
IJournalReportEntriesGroup,
IJournalReportQuery,
IJournalTableData,
ITableColumn,
ITableColumnAccessor,
ITableRow,
} from '@/interfaces';
import { tableRowMapper } from '@/utils';
import { FinancialTable } from '../FinancialTable';
import { FinancialSheetStructure } from '../FinancialSheetStructure';
import FinancialSheet from '../FinancialSheet';
export class JournalSheetTable extends R.compose(
FinancialTable,
FinancialSheetStructure
)(FinancialSheet) {
private data: IJournalTableData;
private query: IJournalReportQuery;
private i18n: any;
constructor(data: IJournalTableData, query: IJournalReportQuery, i18n: any) {
super();
this.data = data;
this.query = query;
this.i18n = i18n;
}
/**
* Retrieves the common table accessors.
* @returns {ITableColumnAccessor[]}
*/
private commonColumnsAccessors = (): ITableColumnAccessor[] => {
return [
{ key: 'date', accessor: 'date' },
{ key: 'reference_type', accessor: 'referenceTypeFormatted' },
{ key: 'reference_number', accessor: 'reference_number' },
{ key: 'currency_code', accessor: 'currencyCode' },
{ key: 'credit', accessor: 'formattedCredit' },
{ key: 'debit', accessor: 'formattedDebit' },
];
};
private commonColumns(): ITableColumn[] {
return [
{ key: 'date', label: 'Date' },
{ key: 'reference_type', label: 'Reference Type' },
{ key: 'reference_type', label: 'Reference Number' },
{ key: 'currency_code', label: 'Currency Code' },
{ key: 'credit', label: 'Credit' },
{ key: 'debit', label: 'Debit' },
];
}
/**
*
*/
private entryGroupMapper = (group: IJournalReportEntriesGroup) => {
const columns = this.commonColumnsAccessors();
return tableRowMapper(group, columns, {});
};
/**
*
*/
private entryMapper = () => {};
/**
*
*/
private entriesGroupsMapper = (entries: IJournalReportEntriesGroup[]) => {
return R.compose(R.map(this.entryGroupMapper))(entries);
};
/**
* Retrieves the table data rows.
* @returns {ITableRow[]}
*/
public tableData(): ITableRow[] {
return R.compose(this.entriesGroupsMapper)(this.data);
}
/**
* Retrieves the table columns.
* @returns {ITableColumn[]}
*/
public tableColumns(): ITableColumn[] {
const columns = this.commonColumns();
return R.compose(this.tableColumnsCellIndexing)(columns);
}
}

View File

@@ -0,0 +1,39 @@
import HasTenancyService from '@/services/Tenancy/TenancyService';
import { Inject } from 'typedi';
import { JournalSheetService } from './JournalSheetService';
import { IJournalReportQuery, IJournalTable } from '@/interfaces';
import { JournalSheetTable } from './JournalSheetTable';
export class JournalSheetTableInjectable {
@Inject()
private tenancy: HasTenancyService;
@Inject()
private journalSheetService: JournalSheetService;
/**
* Retrieves the journal sheet in table format.
* @param {number} tenantId
* @param {IJournalReportQuery} query
* @returns {Promise<IJournalTable>}
*/
public async table(
tenantId: number,
query: IJournalReportQuery
): Promise<IJournalTable> {
const journal = await this.journalSheetService.journalSheet(
tenantId,
query
);
const table = new JournalSheetTable(journal.data, journal.query, {});
return {
table: {
columns: table.tableColumns(),
rows: table.tableData(),
},
query: journal.query,
meta: journal.meta,
};
}
}