Files
bigcapital/temp/BalanceSheet/BalanceSheetAccounts.ts
2025-01-18 22:32:45 +02:00

206 lines
6.6 KiB
TypeScript

import * as R from 'ramda';
import { defaultTo, toArray } from 'lodash';
import { FinancialSheetStructure } from '../../common/FinancialSheetStructure';
import {
BALANCE_SHEET_SCHEMA_NODE_TYPE,
IBalanceSheetAccountNode,
IBalanceSheetAccountsNode,
IBalanceSheetDataNode,
IBalanceSheetSchemaAccountNode,
IBalanceSheetSchemaNode,
} from './BalanceSheet.types';
import { BalanceSheetNetIncome } from './BalanceSheetNetIncome';
import { BalanceSheetFiltering } from './BalanceSheetFiltering';
import { BalanceSheetDatePeriods } from './BalanceSheetDatePeriods';
import { BalanceSheetComparsionPreviousPeriod } from './BalanceSheetComparsionPreviousPeriod';
import { BalanceSheetComparsionPreviousYear } from './BalanceSheetComparsionPreviousYear';
import { BalanceSheetPercentage } from './BalanceSheetPercentage';
import { BalanceSheetSchema } from './BalanceSheetSchema';
import { BalanceSheetBase } from './BalanceSheetBase';
import { BalanceSheetQuery } from './BalanceSheetQuery';
import { BalanceSheetRepository } from './BalanceSheetRepository';
import { Constructor } from '@/common/types/Constructor';
import { INumberFormatQuery } from '../../types/Report.types';
import { Account } from '@/modules/Accounts/models/Account.model';
import { flatToNestedArray } from '@/utils/flat-to-nested-array';
export const BalanceSheetAccounts = <T extends Constructor>(Base: T) =>
class extends R.compose(
BalanceSheetNetIncome,
BalanceSheetFiltering,
BalanceSheetDatePeriods,
BalanceSheetComparsionPreviousPeriod,
BalanceSheetComparsionPreviousYear,
BalanceSheetPercentage,
BalanceSheetSchema,
BalanceSheetBase,
FinancialSheetStructure
)(Base) {
/**
* Balance sheet query.
* @param {BalanceSheetQuery}
*/
readonly query: BalanceSheetQuery;
/**
* Balance sheet number format query.
* @param {INumberFormatQuery}
*/
readonly numberFormat: INumberFormatQuery;
/**
* Base currency of the organization.
* @param {string}
*/
readonly baseCurrency: string;
/**
* Localization.
*/
readonly i18n: any;
/**
* Balance sheet repository.
*/
readonly repository: BalanceSheetRepository;
/**
* Retrieve the accounts node of accounts types.
* @param {string} accountsTypes
* @returns {IAccount[]}
*/
private getAccountsByAccountTypes = (
accountsTypes: string[]
): Account[] => {
const mapAccountsByTypes = R.map((accountType) =>
defaultTo(this.repository.accountsByType.get(accountType), [])
);
return R.compose(R.flatten, mapAccountsByTypes)(accountsTypes);
};
/**
* Mappes the account model to report account node.
* @param {Account} account
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountNodeMapper = (
account: Account
): IBalanceSheetAccountNode => {
const childrenAccountsIds = this.repository.accountsGraph.dependenciesOf(
account.id
);
const accountIds = R.uniq(R.append(account.id, childrenAccountsIds));
const total = this.repository.totalAccountsLedger
.whereAccountsIds(accountIds)
.getClosingBalance();
return {
id: account.id,
index: account.index,
name: account.name,
code: account.code,
total: this.getAmountMeta(total),
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNT,
};
};
/**
* Mappes the given account model to the balance sheet account node.
* @param {IAccount} account
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountNodeComposer = (
account: Account
): IBalanceSheetAccountNode => {
return R.compose(
R.when(
this.query.isPreviousYearActive,
this.previousYearAccountNodeComposer
),
R.when(
this.query.isPreviousPeriodActive,
this.previousPeriodAccountNodeComposer
),
R.when(
this.query.isDatePeriodsColumnsType,
this.assocAccountNodeDatePeriods
),
this.reportSchemaAccountNodeMapper
)(account);
};
// -----------------------------
// - Accounts Node Praser
// -----------------------------
/**
* Retrieve the report accounts node by the given accounts types.
* @param {string[]} accountsTypes
* @returns {IBalanceSheetAccountNode[]}
*/
private getAccountsNodesByAccountTypes = (
accountsTypes: string[]
): IBalanceSheetAccountNode[] => {
// Retrieves accounts from the given defined node account types.
const accounts = this.getAccountsByAccountTypes(accountsTypes);
// Converts the flatten accounts to tree.
const accountsTree = flatToNestedArray(accounts, {
id: 'id',
parentId: 'parentAccountId',
});
// Maps over the accounts tree.
return this.mapNodesDeep(
accountsTree,
this.reportSchemaAccountNodeComposer
);
};
/**
* Mappes the accounts schema node type.
* @param {IBalanceSheetSchemaNode} node - Schema node.
* @returns {IBalanceSheetAccountNode}
*/
private reportSchemaAccountsNodeMapper = (
node: IBalanceSheetSchemaAccountNode
): IBalanceSheetAccountsNode => {
const accounts = this.getAccountsNodesByAccountTypes(node.accountsTypes);
const children = toArray(node?.children);
return {
id: node.id,
name: this.i18n.__(node.name),
nodeType: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS,
type: BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS,
children: [...accounts, ...children],
total: this.getTotalAmountMeta(0),
};
};
/**
* Mappes the given report schema node.
* @param {IBalanceSheetSchemaNode | IBalanceSheetDataNode} node - Schema node.
* @return {IBalanceSheetSchemaNode | IBalanceSheetDataNode}
*/
private reportAccountSchemaParser = (
node: IBalanceSheetSchemaNode | IBalanceSheetDataNode
): IBalanceSheetSchemaNode | IBalanceSheetDataNode => {
return R.compose(
R.when(
this.isSchemaNodeType(BALANCE_SHEET_SCHEMA_NODE_TYPE.ACCOUNTS),
this.reportSchemaAccountsNodeMapper
)
)(node);
};
/**
* Parses the report accounts schema nodes.
* @param {IBalanceSheetSchemaNode[]} nodes -
* @return {IBalanceSheetStructureSection[]}
*/
public accountsSchemaParser = (
nodes: (IBalanceSheetSchemaNode | IBalanceSheetDataNode)[]
): (IBalanceSheetDataNode | IBalanceSheetSchemaNode)[] => {
return this.mapNodesDeepReverse(nodes, this.reportAccountSchemaParser);
};
};