2022-05-16 10:10:35 +00:00
|
|
|
import { t } from 'fyo';
|
|
|
|
import {
|
|
|
|
AccountRootType,
|
|
|
|
AccountRootTypeEnum,
|
|
|
|
} from 'models/baseModels/Account/types';
|
|
|
|
import {
|
|
|
|
AccountReport,
|
2023-12-01 19:42:14 +00:00
|
|
|
convertAccountRootNodesToAccountList,
|
2022-05-16 10:10:35 +00:00
|
|
|
} from 'reports/AccountReport';
|
2022-05-16 13:01:58 +00:00
|
|
|
import { ReportData, RootTypeRow } from 'reports/types';
|
2022-05-16 10:10:35 +00:00
|
|
|
import { getMapFromList } from 'utils';
|
|
|
|
|
|
|
|
export class BalanceSheet extends AccountReport {
|
|
|
|
static title = t`Balance Sheet`;
|
|
|
|
static reportName = 'balance-sheet';
|
2023-06-22 08:52:54 +00:00
|
|
|
loading = false;
|
2022-05-16 10:10:35 +00:00
|
|
|
|
|
|
|
get rootTypes(): AccountRootType[] {
|
|
|
|
return [
|
|
|
|
AccountRootTypeEnum.Asset,
|
|
|
|
AccountRootTypeEnum.Liability,
|
|
|
|
AccountRootTypeEnum.Equity,
|
2022-01-20 20:57:29 +00:00
|
|
|
];
|
2022-05-16 10:10:35 +00:00
|
|
|
}
|
|
|
|
|
2022-05-30 11:34:25 +00:00
|
|
|
async setReportData(filter?: string, force?: boolean) {
|
2022-05-18 14:58:35 +00:00
|
|
|
this.loading = true;
|
2022-05-30 11:34:25 +00:00
|
|
|
if (force || filter !== 'hideGroupAmounts') {
|
2022-05-16 10:10:35 +00:00
|
|
|
await this._setRawData();
|
|
|
|
}
|
2022-01-20 20:57:29 +00:00
|
|
|
|
2022-05-16 10:10:35 +00:00
|
|
|
const map = this._getGroupedMap(true, 'account');
|
|
|
|
const rangeGroupedMap = await this._getGroupedByDateRanges(map);
|
|
|
|
const accountTree = await this._getAccountTree(rangeGroupedMap);
|
2022-01-20 20:57:29 +00:00
|
|
|
|
2022-05-16 10:10:35 +00:00
|
|
|
for (const name of Object.keys(accountTree)) {
|
|
|
|
const { rootType } = accountTree[name];
|
|
|
|
if (this.rootTypes.includes(rootType)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete accountTree[name];
|
|
|
|
}
|
|
|
|
|
|
|
|
const rootTypeRows: RootTypeRow[] = this.rootTypes
|
|
|
|
.map((rootType) => {
|
2023-12-01 19:42:14 +00:00
|
|
|
const rootNodes = this.getRootNodes(rootType, accountTree)!;
|
|
|
|
const rootList = convertAccountRootNodesToAccountList(rootNodes);
|
2022-05-16 10:10:35 +00:00
|
|
|
return {
|
|
|
|
rootType,
|
2023-12-01 19:42:14 +00:00
|
|
|
rootNodes,
|
2022-05-16 10:10:35 +00:00
|
|
|
rows: this.getReportRowsFromAccountList(rootList),
|
|
|
|
};
|
|
|
|
})
|
2023-12-01 19:42:14 +00:00
|
|
|
.filter((row) => !!row.rootNodes.length);
|
2022-05-16 10:10:35 +00:00
|
|
|
|
2023-06-22 08:52:54 +00:00
|
|
|
this.reportData = this.getReportDataFromRows(
|
2022-05-16 10:10:35 +00:00
|
|
|
getMapFromList(rootTypeRows, 'rootType')
|
|
|
|
);
|
2022-05-18 14:58:35 +00:00
|
|
|
this.loading = false;
|
2022-01-20 20:57:29 +00:00
|
|
|
}
|
2018-04-24 07:58:57 +00:00
|
|
|
|
2023-06-22 08:52:54 +00:00
|
|
|
getReportDataFromRows(
|
2022-05-16 10:10:35 +00:00
|
|
|
rootTypeRows: Record<AccountRootType, RootTypeRow | undefined>
|
2023-06-22 08:52:54 +00:00
|
|
|
): ReportData {
|
2022-05-16 10:10:35 +00:00
|
|
|
const typeNameList = [
|
|
|
|
{
|
|
|
|
rootType: AccountRootTypeEnum.Asset,
|
|
|
|
totalName: t`Total Asset (Debit)`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
rootType: AccountRootTypeEnum.Liability,
|
|
|
|
totalName: t`Total Liability (Credit)`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
rootType: AccountRootTypeEnum.Equity,
|
|
|
|
totalName: t`Total Equity (Credit)`,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const reportData: ReportData = [];
|
|
|
|
const emptyRow = this.getEmptyRow();
|
|
|
|
for (const { rootType, totalName } of typeNameList) {
|
|
|
|
const row = rootTypeRows[rootType];
|
|
|
|
if (!row) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
reportData.push(...row.rows);
|
2022-05-30 11:34:25 +00:00
|
|
|
|
2023-12-01 19:42:14 +00:00
|
|
|
if (row.rootNodes.length) {
|
|
|
|
const totalNode = this.getTotalNode(row.rootNodes, totalName);
|
2022-05-30 11:34:25 +00:00
|
|
|
const totalRow = this.getRowFromAccountListNode(totalNode);
|
|
|
|
reportData.push(totalRow);
|
|
|
|
}
|
|
|
|
|
2022-05-16 10:10:35 +00:00
|
|
|
reportData.push(emptyRow);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (reportData.at(-1)?.isEmpty) {
|
|
|
|
reportData.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
return reportData;
|
|
|
|
}
|
|
|
|
}
|