Skip to content

Commit

Permalink
fix(reports): Allow multiple root account to have the same type
Browse files Browse the repository at this point in the history
In French accounting, multiple root accounts can be of the same type,
ensure that reports take all accounts and not only the first one.
  • Loading branch information
mildred committed Dec 5, 2023
1 parent d04b156 commit dd28305
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 50 deletions.
41 changes: 26 additions & 15 deletions reports/AccountReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ export abstract class AccountReport extends LedgerReport {
this._dateRanges = await this._getDateRanges();
}

getRootNode(
getRootNodes(
rootType: AccountRootType,
accountTree: AccountTree
): AccountTreeNode | undefined {
): AccountTreeNode[] | undefined {
const rootNodeList = Object.values(accountTree);
return rootNodeList.find((n) => n.rootType === rootType);
return rootNodeList.filter((n) => n.rootType === rootType);
}

getEmptyRow(): ReportRow {
Expand All @@ -88,8 +88,11 @@ export abstract class AccountReport extends LedgerReport {
};
}

getTotalNode(rootNode: AccountTreeNode, name: string): AccountListNode {
const accountTree = { [rootNode.name]: rootNode };
getTotalNode(rootNodes: AccountTreeNode[], name: string): AccountListNode {
const accountTree: Tree = {};
for (const rootNode of rootNodes) {
accountTree[rootNode.name] = rootNode;
}
const leafNodes = getListOfLeafNodes(accountTree) as AccountTreeNode[];

const totalMap = leafNodes.reduce((acc, node) => {
Expand Down Expand Up @@ -241,9 +244,9 @@ export abstract class AccountReport extends LedgerReport {
// also the last day.
_fixMonthsJump(refDate: DateTime, date: DateTime): DateTime {
if (refDate.day == refDate.daysInMonth && date.day != date.daysInMonth) {
return date.set({day: date.daysInMonth})
return date.set({ day: date.daysInMonth });
} else {
return date
return date;
}
}

Expand All @@ -263,7 +266,10 @@ export abstract class AccountReport extends LedgerReport {

const months: number = monthsMap[this.periodicity];
const dateRanges: DateRange[] = [
{ toDate, fromDate: this._fixMonthsJump(toDate, toDate.minus({ months })) },
{
toDate,
fromDate: this._fixMonthsJump(toDate, toDate.minus({ months })),
},
];

let count = this.count ?? 1;
Expand All @@ -275,7 +281,10 @@ export abstract class AccountReport extends LedgerReport {
const lastRange = dateRanges.at(-1)!;
dateRanges.push({
toDate: lastRange.fromDate,
fromDate: this._fixMonthsJump(toDate, lastRange.fromDate.minus({ months })),
fromDate: this._fixMonthsJump(
toDate,
lastRange.fromDate.minus({ months })
),
});
}

Expand Down Expand Up @@ -457,13 +466,13 @@ export async function getFiscalEndpoints(
const fromDate = [
fromYear,
(fys.getMonth() + 1).toString().padStart(2, '0'),
fys.getDate().toString().padStart(2, '0')
fys.getDate().toString().padStart(2, '0'),
].join('-');

const toDate = [
toYear,
(fye.getMonth() + 1).toString().padStart(2, '0'),
fye.getDate().toString().padStart(2, '0')
fye.getDate().toString().padStart(2, '0'),
].join('-');

return { fromDate, toDate };
Expand Down Expand Up @@ -585,15 +594,17 @@ function getPrunedChildren(children: AccountTreeNode[]): AccountTreeNode[] {
});
}

export function convertAccountRootNodeToAccountList(
rootNode: AccountTreeNode
export function convertAccountRootNodesToAccountList(
rootNodes: AccountTreeNode[]
): AccountList {
if (!rootNode) {
if (!rootNodes || rootNodes.length == 0) {
return [];
}

const accountList: AccountList = [];
pushToAccountList(rootNode, accountList, 0);
for (const rootNode of rootNodes) {
pushToAccountList(rootNode, accountList, 0);
}
return accountList;
}

Expand Down
14 changes: 7 additions & 7 deletions reports/BalanceSheet/BalanceSheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from 'models/baseModels/Account/types';
import {
AccountReport,
convertAccountRootNodeToAccountList,
convertAccountRootNodesToAccountList,
} from 'reports/AccountReport';
import { ReportData, RootTypeRow } from 'reports/types';
import { getMapFromList } from 'utils';
Expand Down Expand Up @@ -44,15 +44,15 @@ export class BalanceSheet extends AccountReport {

const rootTypeRows: RootTypeRow[] = this.rootTypes
.map((rootType) => {
const rootNode = this.getRootNode(rootType, accountTree)!;
const rootList = convertAccountRootNodeToAccountList(rootNode);
const rootNodes = this.getRootNodes(rootType, accountTree)!;
const rootList = convertAccountRootNodesToAccountList(rootNodes);
return {
rootType,
rootNode,
rootNodes,
rows: this.getReportRowsFromAccountList(rootList),
};
})
.filter((row) => !!row.rootNode);
.filter((row) => !!row.rootNodes.length);

this.reportData = this.getReportDataFromRows(
getMapFromList(rootTypeRows, 'rootType')
Expand Down Expand Up @@ -88,8 +88,8 @@ export class BalanceSheet extends AccountReport {

reportData.push(...row.rows);

if (row.rootNode) {
const totalNode = this.getTotalNode(row.rootNode, totalName);
if (row.rootNodes.length) {
const totalNode = this.getTotalNode(row.rootNodes, totalName);
const totalRow = this.getRowFromAccountListNode(totalNode);
reportData.push(totalRow);
}
Expand Down
61 changes: 39 additions & 22 deletions reports/ProfitAndLoss/ProfitAndLoss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from 'models/baseModels/Account/types';
import {
AccountReport,
convertAccountRootNodeToAccountList,
convertAccountRootNodesToAccountList,
} from 'reports/AccountReport';
import {
AccountListNode,
Expand Down Expand Up @@ -45,72 +45,86 @@ export class ProfitAndLoss extends AccountReport {
/**
* Income Rows
*/
const incomeRoot = this.getRootNode(
const incomeRoots = this.getRootNodes(
AccountRootTypeEnum.Income,
accountTree
)!;
const incomeList = convertAccountRootNodeToAccountList(incomeRoot);
const incomeList = convertAccountRootNodesToAccountList(incomeRoots);
const incomeRows = this.getReportRowsFromAccountList(incomeList);

/**
* Expense Rows
*/
const expenseRoot = this.getRootNode(
const expenseRoots = this.getRootNodes(
AccountRootTypeEnum.Expense,
accountTree
)!;
const expenseList = convertAccountRootNodeToAccountList(expenseRoot);
const expenseList = convertAccountRootNodesToAccountList(expenseRoots);
const expenseRows = this.getReportRowsFromAccountList(expenseList);

this.reportData = this.getReportDataFromRows(
incomeRows,
expenseRows,
incomeRoot,
expenseRoot
incomeRoots,
expenseRoots
);
this.loading = false;
}

getReportDataFromRows(
incomeRows: ReportData,
expenseRows: ReportData,
incomeRoot: AccountTreeNode | undefined,
expenseRoot: AccountTreeNode | undefined
incomeRoots: AccountTreeNode[] | undefined,
expenseRoots: AccountTreeNode[] | undefined
): ReportData {
if (incomeRoot && !expenseRoot) {
if (
incomeRoots &&
incomeRoots.length &&
!expenseRoots &&
!expenseRoots.length
) {
return this.getIncomeOrExpenseRows(
incomeRoot,
incomeRoots,
incomeRows,
t`Total Income (Credit)`
);
}

if (expenseRoot && !incomeRoot) {
if (
expenseRoots &&
expenseRoots.length &&
(!incomeRoots || !incomeRoots.length)
) {
return this.getIncomeOrExpenseRows(
expenseRoot,
expenseRoots,
expenseRows,
t`Total Income (Credit)`
);
}

if (!incomeRoot || !expenseRoot) {
if (
!incomeRoots ||
!incomeRoots.length ||
!expenseRoots ||
!expenseRoots.length
) {
return [];
}

return this.getIncomeAndExpenseRows(
incomeRows,
expenseRows,
incomeRoot,
expenseRoot
incomeRoots,
expenseRoots
);
}

getIncomeOrExpenseRows(
root: AccountTreeNode,
roots: AccountTreeNode[],
rows: ReportData,
totalRowName: string
): ReportData {
const total = this.getTotalNode(root, totalRowName);
const total = this.getTotalNode(roots, totalRowName);
const totalRow = this.getRowFromAccountListNode(total);

return [rows, totalRow].flat();
Expand All @@ -119,14 +133,17 @@ export class ProfitAndLoss extends AccountReport {
getIncomeAndExpenseRows(
incomeRows: ReportData,
expenseRows: ReportData,
incomeRoot: AccountTreeNode,
expenseRoot: AccountTreeNode
incomeRoots: AccountTreeNode[],
expenseRoots: AccountTreeNode[]
) {
const totalIncome = this.getTotalNode(incomeRoot, t`Total Income (Credit)`);
const totalIncome = this.getTotalNode(
incomeRoots,
t`Total Income (Credit)`
);
const totalIncomeRow = this.getRowFromAccountListNode(totalIncome);

const totalExpense = this.getTotalNode(
expenseRoot,
expenseRoots,
t`Total Expense (Debit)`
);
const totalExpenseRow = this.getRowFromAccountListNode(totalExpense);
Expand Down
10 changes: 5 additions & 5 deletions reports/TrialBalance/TrialBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
AccountReport,
ACC_BAL_WIDTH,
ACC_NAME_WIDTH,
convertAccountRootNodeToAccountList,
convertAccountRootNodesToAccountList,
getFiscalEndpoints,
} from 'reports/AccountReport';
import {
Expand Down Expand Up @@ -65,15 +65,15 @@ export class TrialBalance extends AccountReport {

const rootTypeRows: RootTypeRow[] = this.rootTypes
.map((rootType) => {
const rootNode = this.getRootNode(rootType, accountTree)!;
const rootList = convertAccountRootNodeToAccountList(rootNode);
const rootNodes = this.getRootNodes(rootType, accountTree)!;
const rootList = convertAccountRootNodesToAccountList(rootNodes);
return {
rootType,
rootNode,
rootNodes,
rows: this.getReportRowsFromAccountList(rootList),
};
})
.filter((row) => !!row.rootNode);
.filter((row) => !!(row.rootNodes && row.rootNodes.length));

this.reportData = await this.getReportDataFromRows(rootTypeRows);
this.loading = false;
Expand Down
2 changes: 1 addition & 1 deletion reports/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,6 @@ export type Tree = Record<string, TreeNode>;

export type RootTypeRow = {
rootType: AccountRootType;
rootNode: AccountTreeNode;
rootNodes: AccountTreeNode[];
rows: ReportData;
};

0 comments on commit dd28305

Please sign in to comment.