import * as R from 'ramda'; import { sumBy } from 'lodash'; import { IBalanceSheetAccountNode, IBalanceSheetDataNode, IBalanceSheetAggregateNode, IBalanceSheetTotal, IBalanceSheetCommonNode, } from './BalanceSheet.types'; import { FinancialPreviousPeriod } from '../../common/FinancialPreviousPeriod'; import { FinancialHorizTotals } from '../../common/FinancialHorizTotals'; import { Constructor } from '@/common/types/Constructor'; export const BalanceSheetComparsionPreviousPeriod = ( Base: T, ) => class BalanceSheetComparsionPreviousPeriod extends R.compose( FinancialPreviousPeriod, FinancialHorizTotals, )(Base) { // ------------------------------ // # Account // ------------------------------ /** * Associates the previous period to account node. * @param {IBalanceSheetDataNode} node * @returns {IBalanceSheetDataNode} */ public assocPreviousPeriodAccountNode = ( node: IBalanceSheetDataNode, ): IBalanceSheetDataNode => { const total = this.repository.PPTotalAccountsLedger.whereAccountId( node.id, ).getClosingBalance(); return R.assoc('previousPeriod', this.getAmountMeta(total), node); }; /** * Previous period account node composer. * @param {IBalanceSheetAccountNode} node * @returns {IBalanceSheetAccountNode} */ public previousPeriodAccountNodeComposer = ( node: IBalanceSheetAccountNode, ): IBalanceSheetAccountNode => { return R.compose( R.when( this.isNodeHasHorizTotals, this.assocPreivousPeriodAccountHorizNodeComposer, ), R.when( this.query.isPreviousPeriodPercentageActive, this.assocPreviousPeriodPercentageNode, ), R.when( this.query.isPreviousPeriodChangeActive, this.assocPreviousPeriodChangeNode, ), R.when( this.query.isPreviousPeriodActive, this.assocPreviousPeriodAccountNode, ), )(node); }; // ------------------------------ // # Aggregate // ------------------------------ /** * Assoc previous period total to aggregate node. * @param {IBalanceSheetAggregateNode} node * @returns {IBalanceSheetAggregateNode} */ public assocPreviousPeriodAggregateNode = ( node: IBalanceSheetAggregateNode, ): IBalanceSheetAggregateNode => { const total = sumBy(node.children, 'previousYear.amount'); return R.assoc('previousPeriod', this.getTotalAmountMeta(total), node); }; /** * Previous period aggregate node composer. * @param {IBalanceSheetAccountNode} node * @returns {IBalanceSheetAccountNode} */ public previousPeriodAggregateNodeComposer = ( node: IBalanceSheetAccountNode, ): IBalanceSheetAccountNode => { return R.compose( R.when( this.isNodeHasHorizTotals, this.assocPreviousPeriodAggregateHorizNode, ), R.when( this.query.isPreviousPeriodPercentageActive, this.assocPreviousPeriodTotalPercentageNode, ), R.when( this.query.isPreviousPeriodChangeActive, this.assocPreviousPeriodTotalChangeNode, ), R.when( this.query.isPreviousPeriodActive, this.assocPreviousPeriodAggregateNode, ), )(node); }; // ------------------------------ // # Horizontal Nodes - Account. // ------------------------------ /** * Retrieve the given account total in the given period. * @param {number} accountId - Account id. * @param {Date} fromDate - From date. * @param {Date} toDate - To date. * @returns {number} */ private getAccountPPDatePeriodTotal = R.curry( (accountId: number, fromDate: Date, toDate: Date): number => { const PPPeriodsTotal = this.repository.PPPeriodsAccountsLedger.whereAccountId(accountId) .whereToDate(toDate) .getClosingBalance(); const PPPeriodsOpeningTotal = this.repository.PPPeriodsOpeningAccountLedger.whereAccountId( accountId, ).getClosingBalance(); return PPPeriodsOpeningTotal + PPPeriodsTotal; }, ); /** * Assoc preivous period to account horizontal total node. * @param {IBalanceSheetAccountNode} node * @returns {} */ private assocPreviousPeriodAccountHorizTotal = R.curry( (node: IBalanceSheetAccountNode, totalNode) => { const total = this.getAccountPPDatePeriodTotal( node.id, totalNode.previousPeriodFromDate.date, totalNode.previousPeriodToDate.date, ); return R.assoc('previousPeriod', this.getAmountMeta(total), totalNode); }, ); /** * Previous year account horizontal node composer. * @param {IBalanceSheetAccountNode} node - * @param {IBalanceSheetTotal} * @returns {IBalanceSheetTotal} */ private previousPeriodAccountHorizNodeCompose = R.curry( ( node: IBalanceSheetAccountNode, horizontalTotalNode: IBalanceSheetTotal, ): IBalanceSheetTotal => { return R.compose( R.when( this.query.isPreviousPeriodPercentageActive, this.assocPreviousPeriodPercentageNode, ), R.when( this.query.isPreviousPeriodChangeActive, this.assocPreviousPeriodChangeNode, ), R.when( this.query.isPreviousPeriodActive, this.assocPreviousPeriodAccountHorizTotal(node), ), R.when( this.query.isPreviousPeriodActive, this.assocPreviousPeriodHorizNodeFromToDates( this.query.displayColumnsBy, ), ), )(horizontalTotalNode); }, ); /** * * @param {IBalanceSheetAccountNode} node * @returns */ private assocPreivousPeriodAccountHorizNodeComposer = ( node: IBalanceSheetAccountNode, ) => { const horizontalTotals = R.map( this.previousPeriodAccountHorizNodeCompose(node), node.horizontalTotals, ); return R.assoc('horizontalTotals', horizontalTotals, node); }; // ------------------------------ // # Horizontal Nodes - Aggregate // ------------------------------ /** * Assoc previous year total to horizontal node. * @param node * @returns */ private assocPreviousPeriodAggregateHorizTotalNode = R.curry( (node, index: number, totalNode) => { const total = this.getPPHorizNodesTotalSumation(index, node); return R.assoc( 'previousPeriod', this.getTotalAmountMeta(total), totalNode, ); }, ); /** * Compose previous period to aggregate horizontal nodes. * @param {IBalanceSheetTotal} node * @returns {IBalanceSheetTotal} */ private previousPeriodAggregateHorizNodeComposer = R.curry( ( node: IBalanceSheetCommonNode, horiontalTotalNode: IBalanceSheetTotal, index: number, ): IBalanceSheetTotal => { return R.compose( R.when( this.query.isPreviousPeriodPercentageActive, this.assocPreviousPeriodTotalPercentageNode, ), R.when( this.query.isPreviousPeriodChangeActive, this.assocPreviousPeriodTotalChangeNode, ), R.when( this.query.isPreviousPeriodActive, this.assocPreviousPeriodAggregateHorizTotalNode(node, index), ), R.when( this.query.isPreviousPeriodActive, this.assocPreviousPeriodHorizNodeFromToDates( this.query.displayColumnsBy, ), ), )(horiontalTotalNode); }, ); /** * Assoc * @param {IBalanceSheetCommonNode} node * @returns {IBalanceSheetCommonNode} */ private assocPreviousPeriodAggregateHorizNode = ( node: IBalanceSheetCommonNode, ) => { const horizontalTotals = R.addIndex(R.map)( this.previousPeriodAggregateHorizNodeComposer(node), node.horizontalTotals, ); return R.assoc('horizontalTotals', horizontalTotals, node); }; };