Files
bigcapital/packages/server/src/services/FinancialStatements/ProfitLossSheet/ProfitLossSheetDatePeriods.ts
2023-02-03 11:57:50 +02:00

237 lines
6.8 KiB
TypeScript

import * as R from 'ramda';
import { sumBy } from 'lodash';
import { FinancialDatePeriods } from '../FinancialDatePeriods';
import {
IDateRange,
IProfitLossHorizontalDatePeriodNode,
IProfitLossSheetAccountNode,
IProfitLossSheetAccountsNode,
IProfitLossSheetCommonNode,
IProfitLossSheetNode,
} from '@/interfaces';
export const ProfitLossSheetDatePeriods = (Base) =>
class extends R.compose(FinancialDatePeriods)(Base) {
/**
* Retrieves the date periods based on the report query.
* @returns {IDateRange[]}
*/
get datePeriods(): IDateRange[] {
return this.getDateRanges(
this.query.fromDate,
this.query.toDate,
this.query.displayColumnsBy
);
}
/**
* Retrieves the date periods of the given node based on the report query.
* @param {IProfitLossSheetCommonNode} node
* @param {Function} callback
* @returns {}
*/
protected getReportNodeDatePeriods = (
node: IProfitLossSheetCommonNode,
callback: (
node: IProfitLossSheetCommonNode,
fromDate: Date,
toDate: Date,
index: number
) => any
) => {
return this.getNodeDatePeriods(
this.query.fromDate,
this.query.toDate,
this.query.displayColumnsBy,
node,
callback
);
};
// --------------------------
// # Account Nodes.
// --------------------------
/**
* Retrieve account node date period total.
* @param {IProfitLossSheetAccount} node
* @param {Date} fromDate
* @param {Date} toDate
* @returns {}
*/
private getAccountNodeDatePeriodTotal = (
node: IProfitLossSheetAccountNode,
fromDate: Date,
toDate: Date
) => {
const periodTotal = this.repository.periodsAccountsLedger
.whereAccountId(node.id)
.whereFromDate(fromDate)
.whereToDate(toDate)
.getClosingBalance();
return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate);
};
/**
* Retrieve account node date period.
* @param {IProfitLossSheetAccountNode} node
* @returns {IProfitLossSheetAccountNode}
*/
public getAccountNodeDatePeriod = (node: IProfitLossSheetAccountNode) => {
return this.getReportNodeDatePeriods(
node,
this.getAccountNodeDatePeriodTotal
);
};
/**
* Account date periods to the given account node.
* @param {IProfitLossSheetAccountNode} node
* @returns {IProfitLossSheetAccountNode}
*/
public assocAccountNodeDatePeriod = (
node: IProfitLossSheetAccountNode
): IProfitLossSheetAccountNode => {
const datePeriods = this.getAccountNodeDatePeriod(node);
return R.assoc('horizontalTotals', datePeriods, node);
};
// --------------------------
// # Aggregate nodes.
// --------------------------
/**
* Retrieves sumation of the given aggregate node children totals.
* @param {IProfitLossSheetAccountsNode} node
* @param {number} index
* @returns {number}
*/
private getAggregateDatePeriodIndexTotal = (
node: IProfitLossSheetAccountsNode,
index: number
): number => {
return sumBy(node.children, `horizontalTotals[${index}].total.amount`);
};
/**
*
* @param {IProfitLossSheetAccount} node
* @param {Date} fromDate
* @param {Date} toDate
* @param {number} index
* @returns {IProfitLossSheetAccount}
*/
private getAggregateNodeDatePeriodTotal = R.curry(
(
node: IProfitLossSheetAccountsNode,
fromDate: Date,
toDate: Date,
index: number
): IProfitLossHorizontalDatePeriodNode => {
const periodTotal = this.getAggregateDatePeriodIndexTotal(node, index);
return this.getDatePeriodTotalMeta(periodTotal, fromDate, toDate);
}
);
/**
* Retrieves aggregate horizontal date periods.
* @param {IProfitLossSheetAccountsNode} node
* @returns {IProfitLossSheetAccountsNode}
*/
private getAggregateNodeDatePeriod = (
node: IProfitLossSheetAccountsNode
): IProfitLossHorizontalDatePeriodNode[] => {
return this.getReportNodeDatePeriods(
node,
this.getAggregateNodeDatePeriodTotal
);
};
/**
* Assoc horizontal date periods to aggregate node.
* @param {IProfitLossSheetAccountsNode} node
* @returns {IProfitLossSheetAccountsNode}
*/
protected assocAggregateDatePeriod = (
node: IProfitLossSheetAccountsNode
): IProfitLossSheetAccountsNode => {
const datePeriods = this.getAggregateNodeDatePeriod(node);
return R.assoc('horizontalTotals', datePeriods, node);
};
// --------------------------
// # Equation nodes.
// --------------------------
/**
* Retrieves equation date period node.
* @param {IProfitLossSheetNode[]} accNodes
* @param {IProfitLossSheetNode} node
* @param {Date} fromDate
* @param {Date} toDate
* @param {number} index
* @returns {IProfitLossHorizontalDatePeriodNode}
*/
private getEquationNodeDatePeriod = R.curry(
(
accNodes: IProfitLossSheetNode[],
equation: string,
node: IProfitLossSheetNode,
fromDate: Date,
toDate: Date,
index: number
): IProfitLossHorizontalDatePeriodNode => {
const tableNodes = this.getNodesTableForEvaluating(
`horizontalTotals[${index}].total.amount`,
accNodes
);
// Evaluate the given equation.
const total = this.evaluateEquation(equation, tableNodes);
return this.getDatePeriodTotalMeta(total, fromDate, toDate);
}
);
/**
* Retrieves the equation node date periods.
* @param {IProfitLossSheetNode[]} node
* @param {string} equation
* @param {IProfitLossSheetNode} node
* @returns {IProfitLossHorizontalDatePeriodNode[]}
*/
private getEquationNodeDatePeriods = R.curry(
(
accNodes: IProfitLossSheetNode[],
equation: string,
node: IProfitLossSheetNode
): IProfitLossHorizontalDatePeriodNode[] => {
return this.getReportNodeDatePeriods(
node,
this.getEquationNodeDatePeriod(accNodes, equation)
);
}
);
/**
* Assoc equation node date period.
* @param {IProfitLossSheetNode[]}
* @param {IProfitLossSheetNode} node
* @returns {IProfitLossSheetNode}
*/
protected assocEquationNodeDatePeriod = R.curry(
(
accNodes: IProfitLossSheetNode[],
equation: string,
node: IProfitLossSheetNode
): IProfitLossSheetNode => {
const periods = this.getEquationNodeDatePeriods(
accNodes,
equation,
node
);
return R.assoc('horizontalTotals', periods, node);
}
);
};