mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-13 19:30:30 +00:00
323 lines
10 KiB
TypeScript
323 lines
10 KiB
TypeScript
import * as R from 'ramda';
|
|
import {
|
|
IColumnMapperMeta,
|
|
IGeneralLedgerMeta,
|
|
IGeneralLedgerSheetAccount,
|
|
IGeneralLedgerSheetAccountTransaction,
|
|
IGeneralLedgerSheetData,
|
|
IGeneralLedgerSheetQuery,
|
|
ITableColumn,
|
|
ITableColumnAccessor,
|
|
ITableRow,
|
|
} from '@/interfaces';
|
|
import FinancialSheet from '../FinancialSheet';
|
|
import { FinancialSheetStructure } from '../FinancialSheetStructure';
|
|
import { FinancialTable } from '../FinancialTable';
|
|
import { tableRowMapper } from '@/utils';
|
|
import { ROW_TYPE } from './utils';
|
|
|
|
export class GeneralLedgerTable extends R.compose(
|
|
FinancialTable,
|
|
FinancialSheetStructure
|
|
)(FinancialSheet) {
|
|
private data: IGeneralLedgerSheetData;
|
|
private query: IGeneralLedgerSheetQuery;
|
|
private meta: IGeneralLedgerMeta;
|
|
|
|
/**
|
|
* Creates an instance of `GeneralLedgerTable`.
|
|
* @param {IGeneralLedgerSheetData} data
|
|
* @param {IGeneralLedgerSheetQuery} query
|
|
*/
|
|
constructor(
|
|
data: IGeneralLedgerSheetData,
|
|
query: IGeneralLedgerSheetQuery,
|
|
meta: IGeneralLedgerMeta
|
|
) {
|
|
super();
|
|
|
|
this.data = data;
|
|
this.query = query;
|
|
this.meta = meta;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the common table accessors.
|
|
* @returns {ITableColumnAccessor[]}
|
|
*/
|
|
private accountColumnsAccessors(): ITableColumnAccessor[] {
|
|
return [
|
|
{ key: 'date', accessor: 'name' },
|
|
{ key: 'account_name', accessor: '_empty_' },
|
|
{ key: 'reference_type', accessor: '_empty_' },
|
|
{ key: 'reference_number', accessor: '_empty_' },
|
|
{ key: 'description', accessor: 'description' },
|
|
{ key: 'credit', accessor: '_empty_' },
|
|
{ key: 'debit', accessor: '_empty_' },
|
|
{ key: 'amount', accessor: 'amount.formattedAmount' },
|
|
{ key: 'running_balance', accessor: 'closingBalance.formattedAmount' },
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Retrieves the transaction column accessors.
|
|
* @returns {ITableColumnAccessor[]}
|
|
*/
|
|
private transactionColumnAccessors(): ITableColumnAccessor[] {
|
|
return [
|
|
{ key: 'date', accessor: 'dateFormatted' },
|
|
{ key: 'account_name', accessor: 'account.name' },
|
|
{ key: 'reference_type', accessor: 'transactionTypeFormatted' },
|
|
{ key: 'reference_number', accessor: 'transactionNumber' },
|
|
{ key: 'description', accessor: 'note' },
|
|
{ key: 'credit', accessor: 'formattedCredit' },
|
|
{ key: 'debit', accessor: 'formattedDebit' },
|
|
{ key: 'amount', accessor: 'formattedAmount' },
|
|
{ key: 'running_balance', accessor: 'formattedRunningBalance' },
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Retrieves the opening row column accessors.
|
|
* @returns {ITableRowIColumnMapperMeta[]}
|
|
*/
|
|
private openingBalanceColumnsAccessors(): IColumnMapperMeta[] {
|
|
return [
|
|
{ key: 'date', value: 'Opening Balance' },
|
|
{ key: 'account_name', value: '' },
|
|
{ key: 'reference_type', accessor: '_empty_' },
|
|
{ key: 'reference_number', accessor: '_empty_' },
|
|
{ key: 'description', accessor: 'description' },
|
|
{ key: 'credit', accessor: '_empty_' },
|
|
{ key: 'debit', accessor: '_empty_' },
|
|
{ key: 'amount', accessor: 'openingBalance.formattedAmount' },
|
|
{ key: 'running_balance', accessor: 'openingBalance.formattedAmount' },
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Closing balance row column accessors.
|
|
* @param {IGeneralLedgerSheetAccount} account -
|
|
* @returns {ITableColumnAccessor[]}
|
|
*/
|
|
private closingBalanceColumnAccessors(
|
|
account: IGeneralLedgerSheetAccount
|
|
): IColumnMapperMeta[] {
|
|
return [
|
|
{ key: 'date', value: `Closing balance for ${account.name}` },
|
|
{ key: 'account_name', value: `` },
|
|
{ key: 'reference_type', accessor: '_empty_' },
|
|
{ key: 'reference_number', accessor: '_empty_' },
|
|
{ key: 'description', accessor: '_empty_' },
|
|
{ key: 'credit', accessor: '_empty_' },
|
|
{ key: 'debit', accessor: '_empty_' },
|
|
{ key: 'amount', accessor: 'closingBalance.formattedAmount' },
|
|
{ key: 'running_balance', accessor: 'closingBalance.formattedAmount' },
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Closing balance row column accessors.
|
|
* @param {IGeneralLedgerSheetAccount} account -
|
|
* @returns {ITableColumnAccessor[]}
|
|
*/
|
|
private closingBalanceWithSubaccountsColumnAccessors(
|
|
account: IGeneralLedgerSheetAccount
|
|
): IColumnMapperMeta[] {
|
|
return [
|
|
{
|
|
key: 'date',
|
|
value: `Closing Balance for ${account.name} with sub-accounts`,
|
|
},
|
|
{
|
|
key: 'account_name',
|
|
value: ``,
|
|
},
|
|
{ key: 'reference_type', accessor: '_empty_' },
|
|
{ key: 'reference_number', accessor: '_empty_' },
|
|
{ key: 'description', accessor: '_empty_' },
|
|
{ key: 'credit', accessor: '_empty_' },
|
|
{ key: 'debit', accessor: '_empty_' },
|
|
{ key: 'amount', accessor: 'closingBalanceSubaccounts.formattedAmount' },
|
|
{
|
|
key: 'running_balance',
|
|
accessor: 'closingBalanceSubaccounts.formattedAmount',
|
|
},
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Retrieves the common table columns.
|
|
* @returns {ITableColumn[]}
|
|
*/
|
|
private commonColumns(): ITableColumn[] {
|
|
return [
|
|
{ key: 'date', label: 'Date' },
|
|
{ key: 'account_name', label: 'Account Name' },
|
|
{ key: 'reference_type', label: 'Transaction Type' },
|
|
{ key: 'reference_number', label: 'Transaction #' },
|
|
{ key: 'description', label: 'Description' },
|
|
{ key: 'credit', label: 'Credit' },
|
|
{ key: 'debit', label: 'Debit' },
|
|
{ key: 'amount', label: 'Amount' },
|
|
{ key: 'running_balance', label: 'Running Balance' },
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Maps the given transaction node to table row.
|
|
* @param {IGeneralLedgerSheetAccountTransaction} transaction
|
|
* @returns {ITableRow}
|
|
*/
|
|
private transactionMapper = R.curry(
|
|
(
|
|
account: IGeneralLedgerSheetAccount,
|
|
transaction: IGeneralLedgerSheetAccountTransaction
|
|
): ITableRow => {
|
|
const columns = this.transactionColumnAccessors();
|
|
const data = { ...transaction, account };
|
|
const meta = {
|
|
rowTypes: [ROW_TYPE.TRANSACTION],
|
|
};
|
|
return tableRowMapper(data, columns, meta);
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Maps the given transactions nodes to table rows.
|
|
* @param {IGeneralLedgerSheetAccountTransaction[]} transactions
|
|
* @returns {ITableRow[]}
|
|
*/
|
|
private transactionsMapper = (
|
|
account: IGeneralLedgerSheetAccount
|
|
): ITableRow[] => {
|
|
const transactionMapper = this.transactionMapper(account);
|
|
|
|
return R.map(transactionMapper)(account.transactions);
|
|
};
|
|
|
|
/**
|
|
* Maps the given account node to opening balance table row.
|
|
* @param {IGeneralLedgerSheetAccount} account
|
|
* @returns {ITableRow}
|
|
*/
|
|
private openingBalanceMapper = (
|
|
account: IGeneralLedgerSheetAccount
|
|
): ITableRow => {
|
|
const columns = this.openingBalanceColumnsAccessors();
|
|
const meta = {
|
|
rowTypes: [ROW_TYPE.OPENING_BALANCE],
|
|
};
|
|
return tableRowMapper(account, columns, meta);
|
|
};
|
|
|
|
/**
|
|
* Maps the given account node to closing balance table row.
|
|
* @param {IGeneralLedgerSheetAccount} account
|
|
* @returns {ITableRow}
|
|
*/
|
|
private closingBalanceMapper = (account: IGeneralLedgerSheetAccount) => {
|
|
const columns = this.closingBalanceColumnAccessors(account);
|
|
const meta = {
|
|
rowTypes: [ROW_TYPE.CLOSING_BALANCE],
|
|
};
|
|
return tableRowMapper(account, columns, meta);
|
|
};
|
|
|
|
/**
|
|
* Maps the given account node to opening balance table row.
|
|
* @param {IGeneralLedgerSheetAccount} account
|
|
* @returns {ITableRow}
|
|
*/
|
|
private closingBalanceWithSubaccountsMapper = (
|
|
account: IGeneralLedgerSheetAccount
|
|
): ITableRow => {
|
|
const columns = this.closingBalanceWithSubaccountsColumnAccessors(account);
|
|
const meta = {
|
|
rowTypes: [ROW_TYPE.CLOSING_BALANCE],
|
|
};
|
|
return tableRowMapper(account, columns, meta);
|
|
};
|
|
|
|
/**
|
|
* Maps the given account node to transactions table rows.
|
|
* @param {IGeneralLedgerSheetAccount} account
|
|
* @returns {ITableRow[]}
|
|
*/
|
|
private transactionsNode = (
|
|
account: IGeneralLedgerSheetAccount
|
|
): ITableRow[] => {
|
|
const openingBalance = this.openingBalanceMapper(account);
|
|
const transactions = this.transactionsMapper(account);
|
|
const closingBalance = this.closingBalanceMapper(account);
|
|
|
|
return R.when(
|
|
R.always(R.not(R.isEmpty(transactions))),
|
|
R.prepend(openingBalance)
|
|
)([...transactions, closingBalance]) as ITableRow[];
|
|
};
|
|
|
|
/**
|
|
* Maps the given account node to the table rows.
|
|
* @param {IGeneralLedgerSheetAccount} account
|
|
* @returns {ITableRow}
|
|
*/
|
|
private accountMapper = (account: IGeneralLedgerSheetAccount): ITableRow => {
|
|
const columns = this.accountColumnsAccessors();
|
|
const transactions = this.transactionsNode(account);
|
|
const meta = {
|
|
rowTypes: [ROW_TYPE.ACCOUNT],
|
|
};
|
|
const row = tableRowMapper(account, columns, meta);
|
|
const closingBalanceWithSubaccounts =
|
|
this.closingBalanceWithSubaccountsMapper(account);
|
|
|
|
// Appends the closing balance with sub-accounts row if the account
|
|
// has children accounts and the node is define.
|
|
const isAppendClosingSubaccounts = () =>
|
|
account.children?.length > 0 && !!account.closingBalanceSubaccounts;
|
|
|
|
const children = R.compose(
|
|
R.when(
|
|
isAppendClosingSubaccounts,
|
|
R.append(closingBalanceWithSubaccounts)
|
|
),
|
|
R.concat(R.defaultTo([], transactions)),
|
|
R.when(
|
|
() => account?.children?.length > 0,
|
|
R.concat(R.defaultTo([], account.children))
|
|
)
|
|
)([]);
|
|
|
|
return R.assoc('children', children)(row);
|
|
};
|
|
|
|
/**
|
|
* Maps the given account node to table rows.
|
|
* @param {IGeneralLedgerSheetAccount[]} accounts
|
|
* @returns {ITableRow[]}
|
|
*/
|
|
private accountsMapper = (
|
|
accounts: IGeneralLedgerSheetAccount[]
|
|
): ITableRow[] => {
|
|
return this.mapNodesDeepReverse(accounts, this.accountMapper);
|
|
};
|
|
|
|
/**
|
|
* Retrieves the table rows.
|
|
* @returns {ITableRow[]}
|
|
*/
|
|
public tableRows(): ITableRow[] {
|
|
return R.compose(this.accountsMapper)(this.data);
|
|
}
|
|
|
|
/**
|
|
* Retrieves the table columns.
|
|
* @returns {ITableColumn[]}
|
|
*/
|
|
public tableColumns(): ITableColumn[] {
|
|
const columns = this.commonColumns();
|
|
return R.compose(this.tableColumnsCellIndexing)(columns);
|
|
}
|
|
}
|