From 9246b822122ce2a34885d8a2902508d5b177f2d2 Mon Sep 17 00:00:00 2001 From: Tiny_Murky Date: Fri, 11 Oct 2024 11:09:26 +0800 Subject: [PATCH 1/3] fix income statement report --- package.json | 2 +- .../income_statement_report_body_all.tsx | 229 +++--------------- .../income_statement_report_table_row.tsx | 48 ++++ 3 files changed, 77 insertions(+), 202 deletions(-) create mode 100644 src/components/income_statement_report_body/income_statement_report_table_row.tsx diff --git a/package.json b/package.json index dbe9de626..a9c93ac60 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iSunFA", - "version": "0.8.2+41", + "version": "0.8.2+42", "private": false, "scripts": { "dev": "next dev", diff --git a/src/components/income_statement_report_body/income_statement_report_body_all.tsx b/src/components/income_statement_report_body/income_statement_report_body_all.tsx index f6a744bc6..d045a1294 100644 --- a/src/components/income_statement_report_body/income_statement_report_body_all.tsx +++ b/src/components/income_statement_report_body/income_statement_report_body_all.tsx @@ -9,6 +9,7 @@ import Image from 'next/image'; import React, { useState } from 'react'; import { format } from 'date-fns'; import CollapseButton from '@/components/button/collapse_button'; +import IncomeStatementReportTableRow from './income_statement_report_table_row'; interface IIncomeStatementReportBodyAllProps { reportId: string; @@ -180,31 +181,9 @@ const IncomeStatementReportBodyAll = ({ reportId }: IIncomeStatementReportBodyAl {reportFinancial && reportFinancial.general && - reportFinancial.general.slice(0, 10).map((value) => ( - - - {value.code} - - - {value.name} - - - {value.curPeriodAmount} - - - {value.curPeriodPercentage} - - - {value.prePeriodAmount} - - - {value.prePeriodPercentage} - - - ))} + reportFinancial.general + .slice(0, 10) + .map((value) => )} )} @@ -277,28 +256,9 @@ const IncomeStatementReportBodyAll = ({ reportId }: IIncomeStatementReportBodyAl {reportFinancial && reportFinancial.general && - reportFinancial.general.slice(10, 24).map((value) => ( - - - {value.code} - - - {value.name} - - - {value.curPeriodAmount} - - - {value.curPeriodPercentage} - - - {value.prePeriodAmount} - - - {value.prePeriodPercentage} - - - ))} + reportFinancial.general + .slice(10, 24) + .map((value) => )} @@ -368,28 +328,9 @@ const IncomeStatementReportBodyAll = ({ reportId }: IIncomeStatementReportBodyAl {reportFinancial && reportFinancial.general && - reportFinancial.general.slice(24, 33).map((value) => ( - - - {value.code} - - - {value.name} - - - {value.curPeriodAmount} - - - {value.curPeriodPercentage} - - - {value.prePeriodAmount} - - - {value.prePeriodPercentage} - - - ))} + reportFinancial.general + .slice(24, 33) + .map((value) => )}   @@ -411,28 +352,9 @@ const IncomeStatementReportBodyAll = ({ reportId }: IIncomeStatementReportBodyAl {reportFinancial && reportFinancial.general && - reportFinancial.general.slice(34, 36).map((value) => ( - - - {value.code} - - - {value.name} - - - {value.curPeriodAmount} - - -   - - - {value.prePeriodAmount} - - -   - - - ))} + reportFinancial.general + .slice(34, 36) + .map((value) => )}
@@ -515,28 +437,9 @@ const IncomeStatementReportBodyAll = ({ reportId }: IIncomeStatementReportBodyAl {reportFinancial && reportFinancial.details && - reportFinancial.details.slice(0, 15).map((value) => ( - - - {value.code} - - - {value.name} - - - {value.curPeriodAmount} - - - {value.curPeriodPercentage} - - - {value.prePeriodAmount} - - - {value.prePeriodPercentage} - - - ))} + reportFinancial.details + .slice(0, 15) + .map((value) => )} )} @@ -607,28 +510,9 @@ const IncomeStatementReportBodyAll = ({ reportId }: IIncomeStatementReportBodyAl {reportFinancial && reportFinancial.details && - reportFinancial.details.slice(15, 28).map((value) => ( - - - {value.code} - - - {value.name} - - - {value.curPeriodAmount} - - - {value.curPeriodPercentage} - - - {value.prePeriodAmount} - - - {value.prePeriodPercentage} - - - ))} + reportFinancial.details + .slice(15, 28) + .map((value) => )} @@ -698,28 +582,9 @@ const IncomeStatementReportBodyAll = ({ reportId }: IIncomeStatementReportBodyAl {reportFinancial && reportFinancial.details && - reportFinancial.details.slice(28, 39).map((value) => ( - - - {value.code} - - - {value.name} - - - {value.curPeriodAmount} - - - {value.curPeriodPercentage} - - - {value.prePeriodAmount} - - - {value.prePeriodPercentage} - - - ))} + reportFinancial.details + .slice(28, 39) + .map((value) => )} @@ -791,28 +656,9 @@ const IncomeStatementReportBodyAll = ({ reportId }: IIncomeStatementReportBodyAl {reportFinancial && reportFinancial.details && - reportFinancial.details.slice(39, 49).map((value) => ( - - - {value.code} - - - {value.name} - - - {value.curPeriodAmount} - - - {value.curPeriodPercentage} - - - {value.prePeriodAmount} - - - {value.prePeriodPercentage} - - - ))} + reportFinancial.details + .slice(39, 49) + .map((value) => )} @@ -882,28 +728,9 @@ const IncomeStatementReportBodyAll = ({ reportId }: IIncomeStatementReportBodyAl {reportFinancial && reportFinancial.details && - reportFinancial.details.slice(49, 58).map((value) => ( - - - {value.code} - - - {value.name} - - - {value.curPeriodAmount} - - - {value.curPeriodPercentage} - - - {value.prePeriodAmount} - - - {value.prePeriodPercentage} - - - ))} + reportFinancial.details + .slice(49, 58) + .map((value) => )} {reportFinancial && diff --git a/src/components/income_statement_report_body/income_statement_report_table_row.tsx b/src/components/income_statement_report_body/income_statement_report_table_row.tsx new file mode 100644 index 000000000..f8553e340 --- /dev/null +++ b/src/components/income_statement_report_body/income_statement_report_table_row.tsx @@ -0,0 +1,48 @@ +import { FinancialReportItem } from '@/interfaces/report'; +import { numberBeDashIfFalsy } from '@/lib/utils/common'; + +function IncomeStatementReportTableRow({ + code, + curPeriodAmount, + curPeriodPercentage, + prePeriodAmount, + prePeriodPercentage, + name, +}: FinancialReportItem) { + /** + * Info: (20241011 - Murky) + * 將Income statement 當中沒有code 的欄位,呈現的數字變成空字串 + */ + const isCodeExist = code.length > 0; + const idCode = isCodeExist ? code : Math.random().toString(36).slice(0, 4); + const displayCode = isCodeExist ? code : ''; + const displayCurPeriodAmount: string = isCodeExist ? numberBeDashIfFalsy(curPeriodAmount) : ''; + const displayCurPeriodPercentage: string = isCodeExist + ? numberBeDashIfFalsy(curPeriodPercentage) + : ''; + const displayPrePeriodAmount: string = isCodeExist ? numberBeDashIfFalsy(prePeriodAmount) : ''; + const displayPrePeriodPercentage: string = isCodeExist + ? numberBeDashIfFalsy(prePeriodPercentage) + : ''; + + return ( + + {displayCode} + {name} + + {displayCurPeriodAmount} + + + {displayCurPeriodPercentage} + + + {displayPrePeriodAmount} + + + {displayPrePeriodPercentage} + + + ); +} + +export default IncomeStatementReportTableRow; From 4f39f6707fdad3eb5f6d6d69dcab354d4e3ba610 Mon Sep 17 00:00:00 2001 From: Tiny_Murky Date: Fri, 11 Oct 2024 13:53:47 +0800 Subject: [PATCH 2/3] balance sheet Accumulate complete --- package.json | 2 +- src/constants/account.ts | 12 +++ src/lib/utils/common.ts | 7 +- .../utils/report/balance_sheet_generator.ts | 84 ++++++++++++++++--- 4 files changed, 92 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index a9c93ac60..1e5effa30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iSunFA", - "version": "0.8.2+42", + "version": "0.8.2+43", "private": false, "scripts": { "dev": "next dev", diff --git a/src/constants/account.ts b/src/constants/account.ts index dc46aeb94..899bfb996 100644 --- a/src/constants/account.ts +++ b/src/constants/account.ts @@ -306,6 +306,18 @@ export const SPECIAL_ACCOUNTS: { rootCode: '3350', level: 3, }, + ACCUMULATED_PROFIT_AND_LOSS: { + system: 'IFRS', + type: AccountType.EQUITY, + debit: false, + liquidity: false, + code: '3351', + name: '累積盈虧', + forUser: true, + parentCode: '3350', + rootCode: '3350', + level: 3, + }, OTHER_EQUITY_OTHER: { system: 'IFRS', type: AccountType.EQUITY, diff --git a/src/lib/utils/common.ts b/src/lib/utils/common.ts index 4f478bcd7..6211d7506 100644 --- a/src/lib/utils/common.ts +++ b/src/lib/utils/common.ts @@ -459,8 +459,11 @@ export function setTimestampToDayStart(timestamp: number) { return timestampInSeconds(date.getTime()); } -export function getTimestampOfFirstDateOfThisYear() { - const year = new Date().getFullYear(); +export function getTimestampOfFirstDateOfThisYear(currentDateInSecond?: number) { + const dateToGetYear = currentDateInSecond + ? new Date(timestampInMilliSeconds(currentDateInSecond)) + : new Date(); + const year = dateToGetYear.getFullYear(); const date = new Date(year, 0, 1); const timestamp = date.getTime(); const timestampInSecond = setTimestampToDayStart(timestamp); diff --git a/src/lib/utils/report/balance_sheet_generator.ts b/src/lib/utils/report/balance_sheet_generator.ts index 188297b88..ccedef30e 100644 --- a/src/lib/utils/report/balance_sheet_generator.ts +++ b/src/lib/utils/report/balance_sheet_generator.ts @@ -17,28 +17,42 @@ import IncomeStatementGenerator from '@/lib/utils/report/income_statement_genera import { DAY_IN_YEAR } from '@/constants/common'; import { EMPTY_I_ACCOUNT_READY_FRONTEND } from '@/constants/financial_report'; import { ASSET_CODE, SPECIAL_ACCOUNTS } from '@/constants/account'; -import { timestampToString } from '@/lib/utils/common'; +import { getTimestampOfFirstDateOfThisYear, timestampToString } from '@/lib/utils/common'; import { ILineItemIncludeAccount } from '@/interfaces/line_item'; import { findUniqueAccountByCodeInPrisma } from '@/lib/utils/repo/account.repo'; export default class BalanceSheetGenerator extends FinancialReportGenerator { + private startSecondOfYear: number; + private incomeStatementGenerator: IncomeStatementGenerator; - private incomeStatementGeneratorFromTimeZero: IncomeStatementGenerator; + private incomeStatementGeneratorFromTimeZeroToBeginOfYear: IncomeStatementGenerator; + + private incomeStatementGeneratorFromBeginOfYearToEndDate: IncomeStatementGenerator; constructor(companyId: number, startDateInSecond: number, endDateInSecond: number) { const reportSheetType = ReportSheetType.BALANCE_SHEET; super(companyId, 0, endDateInSecond, reportSheetType); + this.startSecondOfYear = getTimestampOfFirstDateOfThisYear(startDateInSecond); + this.incomeStatementGenerator = new IncomeStatementGenerator( companyId, startDateInSecond, endDateInSecond ); - this.incomeStatementGeneratorFromTimeZero = new IncomeStatementGenerator( + // Info: (20241011 - Murky) For Accumulate Profit and Loss + this.incomeStatementGeneratorFromTimeZeroToBeginOfYear = new IncomeStatementGenerator( companyId, 0, + this.startSecondOfYear + ); + + // Info: (20241011 - Murky) For NetIncome + this.incomeStatementGeneratorFromBeginOfYearToEndDate = new IncomeStatementGenerator( + companyId, + this.startSecondOfYear, endDateInSecond ); } @@ -48,14 +62,29 @@ export default class BalanceSheetGenerator extends FinancialReportGenerator { private async closeAccountFromIncomeStatement( curPeriod: boolean ): Promise { - const incomeStatementContent = - await this.incomeStatementGeneratorFromTimeZero.generateIAccountReadyForFrontendArray(); + const currentYearISContent = + await this.incomeStatementGeneratorFromBeginOfYearToEndDate.generateIAccountReadyForFrontendArray(); + const beforeISContent = + await this.incomeStatementGeneratorFromTimeZeroToBeginOfYear.generateIAccountReadyForFrontendArray(); + + // Info: (20241011 - Murky) net income 是本期範圍內的營收 const netIncome = - incomeStatementContent.find((account) => account.code === SPECIAL_ACCOUNTS.NET_INCOME.code) || + currentYearISContent.find((account) => account.code === SPECIAL_ACCOUNTS.NET_INCOME.code) || + EMPTY_I_ACCOUNT_READY_FRONTEND; + + // Info: (20241011 - Murky) Accumulate Profit and loss是本期以前的營收 + const accumulateProfitAndLoss = + beforeISContent.find((account) => account.code === SPECIAL_ACCOUNTS.NET_INCOME.code) || EMPTY_I_ACCOUNT_READY_FRONTEND; - const otherComprehensiveIncome = - incomeStatementContent.find( + + const currentOtherComprehensiveIncome = + currentYearISContent.find( + (account) => account.code === SPECIAL_ACCOUNTS.OTHER_COMPREHENSIVE_INCOME.code + ) || EMPTY_I_ACCOUNT_READY_FRONTEND; + + const beforeOtherComprehensiveIncome = + beforeISContent.find( (account) => account.code === SPECIAL_ACCOUNTS.OTHER_COMPREHENSIVE_INCOME.code ) || EMPTY_I_ACCOUNT_READY_FRONTEND; @@ -64,6 +93,7 @@ export default class BalanceSheetGenerator extends FinancialReportGenerator { const netIncomeAccount = await findUniqueAccountByCodeInPrisma( SPECIAL_ACCOUNTS.NET_INCOME.code ); + const otherComprehensiveIncomeAccount = await findUniqueAccountByCodeInPrisma( SPECIAL_ACCOUNTS.OTHER_COMPREHENSIVE_INCOME.code ); @@ -72,6 +102,10 @@ export default class BalanceSheetGenerator extends FinancialReportGenerator { SPECIAL_ACCOUNTS.NET_INCOME_IN_EQUITY.code ); + const accumulateProfitAndLossInEquity = await findUniqueAccountByCodeInPrisma( + SPECIAL_ACCOUNTS.ACCUMULATED_PROFIT_AND_LOSS.code + ); + const otherEquityOther = await findUniqueAccountByCodeInPrisma( SPECIAL_ACCOUNTS.OTHER_EQUITY_OTHER.code ); @@ -102,11 +136,41 @@ export default class BalanceSheetGenerator extends FinancialReportGenerator { }, }); + closeAccount.push({ + id: accumulateProfitAndLossInEquity?.id || -1, + amount: curPeriod + ? accumulateProfitAndLoss.curPeriodAmount + : accumulateProfitAndLoss.prePeriodAmount, + description: SPECIAL_ACCOUNTS.ACCUMULATED_PROFIT_AND_LOSS.name, + debit: SPECIAL_ACCOUNTS.ACCUMULATED_PROFIT_AND_LOSS.debit, + accountId: accumulateProfitAndLossInEquity?.id || -1, + voucherId: -1, + createdAt: 1, + updatedAt: 1, + deletedAt: null, + account: netIncomeAccount + ? { + ...netIncomeAccount, + code: SPECIAL_ACCOUNTS.ACCUMULATED_PROFIT_AND_LOSS.code, + debit: SPECIAL_ACCOUNTS.ACCUMULATED_PROFIT_AND_LOSS.debit, + } + : { + ...SPECIAL_ACCOUNTS.ACCUMULATED_PROFIT_AND_LOSS, + id: -1, + companyId: this.companyId, + createdAt: 1, + updatedAt: 1, + deletedAt: null, + }, + }); + closeAccount.push({ id: otherEquityOther?.id || -1, amount: curPeriod - ? otherComprehensiveIncome.curPeriodAmount - : otherComprehensiveIncome.prePeriodAmount, + ? currentOtherComprehensiveIncome.curPeriodAmount + + beforeOtherComprehensiveIncome.curPeriodAmount + : beforeOtherComprehensiveIncome.prePeriodAmount + + beforeOtherComprehensiveIncome.prePeriodAmount, description: SPECIAL_ACCOUNTS.OTHER_EQUITY_OTHER.name, debit: SPECIAL_ACCOUNTS.OTHER_EQUITY_OTHER.debit, accountId: otherEquityOther?.id || -1, From 40a0aad0264bdd72c000cc9aef0bfa99a3c7a14e Mon Sep 17 00:00:00 2001 From: Tiny_Murky Date: Fri, 11 Oct 2024 16:46:30 +0800 Subject: [PATCH 3/3] recursive account complete --- package.json | 2 +- src/interfaces/accounting_account.ts | 1 + src/lib/utils/account/common.ts | 70 +++++++++++++++++-- .../utils/report/balance_sheet_generator.ts | 1 - .../report/cash_flow_statement_generator.ts | 11 +++ .../report/financial_report_generator.ts | 40 +++++++---- 6 files changed, 105 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 1e5effa30..ab96a1204 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iSunFA", - "version": "0.8.2+43", + "version": "0.8.2+44", "private": false, "scripts": { "dev": "next dev", diff --git a/src/interfaces/accounting_account.ts b/src/interfaces/accounting_account.ts index fb43dfdbf..f60420724 100644 --- a/src/interfaces/accounting_account.ts +++ b/src/interfaces/accounting_account.ts @@ -38,6 +38,7 @@ export interface IAccountForSheetDisplay { amount: number | null; percentage: number | null; indent: number; + children: IAccountForSheetDisplay[]; debit?: boolean; } diff --git a/src/lib/utils/account/common.ts b/src/lib/utils/account/common.ts index 5a1b1fa3a..237caf2ba 100644 --- a/src/lib/utils/account/common.ts +++ b/src/lib/utils/account/common.ts @@ -110,17 +110,48 @@ export function updateAccountAmounts(forest: IAccountNode[], lineItemsMap: Map { + maxChildDepth = Math.max(maxChildDepth, calculateMaxHeighOfNode(child)); + }); + + return maxChildDepth + 1; +} + export function addAccountNodeToMapRecursively( accountMap: Map, account: IAccountNode, - rootAmount: number + rootAmount: number, + currentDepth: number, + maxHeight?: number ) { - const newAccountNode = { ...account, children: [] }; + // Info: (20241011 - Murky) 倒數第二層可以保有自己的child + const isSecondLastLayer = maxHeight === 1; + const newAccountNode = isSecondLastLayer ? account : { ...account, children: [] }; const percentage = rootAmount === 0 ? 0 : account.amount / rootAmount; // Info: (20240702 - Murky) Calculate percentage accountMap.set(account.code, { accountNode: newAccountNode, percentage }); + account.children.forEach((child) => { - addAccountNodeToMapRecursively(accountMap, child, rootAmount); + const maxHeightOfChild = calculateMaxHeighOfNode(child); + addAccountNodeToMapRecursively( + accountMap, + child, + rootAmount, + currentDepth + 1, + maxHeightOfChild + ); }); + + return false; } export function transformForestToMap( @@ -129,12 +160,30 @@ export function transformForestToMap( const accountMap = new Map(); forest.forEach((accountNode) => { - addAccountNodeToMapRecursively(accountMap, accountNode, accountNode.amount); + const maxHeight = calculateMaxHeighOfNode(accountNode); + addAccountNodeToMapRecursively(accountMap, accountNode, accountNode.amount, 0, maxHeight); }); return accountMap; } +export function iAccountNode2IAccountForSheetDisplay( + accountNode: IAccountNode, + percentage: number, + children?: IAccountForSheetDisplay[] +): IAccountForSheetDisplay { + const iAccountForSheetDisplay: IAccountForSheetDisplay = { + code: accountNode.code, + name: accountNode.name, + amount: accountNode.amount, + indent: accountNode.level, + debit: accountNode.debit, + percentage, + children: children || [], + }; + return iAccountForSheetDisplay; +} + export function mappingAccountToSheetDisplay( accountMap: Map, sheetMappingRow: { @@ -162,8 +211,20 @@ export function mappingAccountToSheetDisplay( indent: row.indent, debit: undefined, percentage: 0, + children: [], }); } else { + const hasChildren = account.accountNode.children.length > 0; + const children = hasChildren + ? account.accountNode.children.map((child) => { + const childAccount = accountMap.get(child.code)!; + // Info: (20241011 - Murky) 最多只有兩層,所以最底不會再有children + return iAccountNode2IAccountForSheetDisplay( + childAccount.accountNode, + childAccount.percentage + ); + }) + : []; sheetDisplay.push({ code: row.code, name: row.name, @@ -171,6 +232,7 @@ export function mappingAccountToSheetDisplay( indent: row.indent, debit: account.accountNode.debit, percentage: account.percentage, + children, }); } }); diff --git a/src/lib/utils/report/balance_sheet_generator.ts b/src/lib/utils/report/balance_sheet_generator.ts index ccedef30e..8f306cfa8 100644 --- a/src/lib/utils/report/balance_sheet_generator.ts +++ b/src/lib/utils/report/balance_sheet_generator.ts @@ -236,7 +236,6 @@ export default class BalanceSheetGenerator extends FinancialReportGenerator { const accountForest = await this.generateFinancialReportTree(curPeriod); BalanceSheetGenerator.calculateLiabilityAndEquity(accountForest); const accountMap = transformForestToMap(accountForest); - return accountMap; } diff --git a/src/lib/utils/report/cash_flow_statement_generator.ts b/src/lib/utils/report/cash_flow_statement_generator.ts index afec4c42b..bd788d12a 100644 --- a/src/lib/utils/report/cash_flow_statement_generator.ts +++ b/src/lib/utils/report/cash_flow_statement_generator.ts @@ -194,6 +194,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator indent: level, debit, percentage: null, + children: [], }; const newReportSheetMapping = new Map([ @@ -247,6 +248,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: sum, indent: 0, percentage: null, + children: [], }); return indirectOperatingCashFlow; @@ -311,6 +313,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: null, indent: 0, percentage: null, + children: [], }); let directCashFlow = 0; @@ -337,6 +340,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: total, indent: 1, percentage: null, + children: [], }; directCashFlow += total; @@ -359,6 +363,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: directCashFlow, indent: 1, percentage: null, + children: [], }); return reportSheetMapping; } @@ -374,6 +379,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: directCashFlow, indent: 1, percentage: null, + children: [], }); return reportSheetMapping; } @@ -414,6 +420,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: 0, indent: 0, percentage: null, + children: [], }); result.set(SPECIAL_ACCOUNTS.CASH_INCREASE_THIS_PERIOD.code, { @@ -422,6 +429,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: cashFlowFromOperating, indent: 0, percentage: null, + children: [], }); result.set(SPECIAL_ACCOUNTS.CASH_AMOUNT_IN_BEGINNING.code, { @@ -430,6 +438,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: startCashBalance, indent: 0, percentage: null, + children: [], }); result.set(SPECIAL_ACCOUNTS.CASH_AMOUNT_IN_END.code, { @@ -438,6 +447,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: endCashBalance, indent: 0, percentage: null, + children: [], }); return result; } @@ -457,6 +467,7 @@ export default class CashFlowStatementGenerator extends FinancialReportGenerator amount: 0, indent: account.indent, percentage: 0, + children: [], }; }); return result; diff --git a/src/lib/utils/report/financial_report_generator.ts b/src/lib/utils/report/financial_report_generator.ts index 82fca8d53..5d92be2b1 100644 --- a/src/lib/utils/report/financial_report_generator.ts +++ b/src/lib/utils/report/financial_report_generator.ts @@ -144,22 +144,20 @@ export default abstract class FinancialReportGenerator extends ReportGenerator { return lineItemsFromDB; } - public async generateIAccountReadyForFrontendArray(): Promise { + private combineTwoFSReportArray( + curPeriodContent: IAccountForSheetDisplay[], + prePeriodContent: IAccountForSheetDisplay[] + ) { const curPeriodAccountReadyForFrontendArray: IAccountReadyForFrontend[] = []; - - this.curPeriodContent = await this.generateFinancialReportArray(true); - - this.prePeriodContent = await this.generateFinancialReportArray(false); - if ( - this.curPeriodContent && - this.prePeriodContent && - this.curPeriodContent.length > 0 && - this.prePeriodContent.length > 0 && - this.curPeriodContent.length === this.prePeriodContent.length + curPeriodContent && + prePeriodContent && + curPeriodContent.length > 0 && + prePeriodContent.length > 0 && + curPeriodContent.length === prePeriodContent.length ) { - this.curPeriodContent.forEach((curPeriodAccount, index) => { - const lastPeriodAccount = this.prePeriodContent[index]; + curPeriodContent.forEach((curPeriodAccount, index) => { + const lastPeriodAccount = prePeriodContent[index]; const curPeriodAmount = curPeriodAccount.amount || 0; const prePeriodAmount = lastPeriodAccount.amount || 0; const curPeriodAmountString = formatNumberSeparateByComma(curPeriodAmount); @@ -171,6 +169,11 @@ export default abstract class FinancialReportGenerator extends ReportGenerator { ? Math.round(lastPeriodAccount.percentage * 100) : 0; + const children = this.combineTwoFSReportArray( + curPeriodAccount.children, + lastPeriodAccount.children + ); + const curPeriodPercentageString = numberBeDashIfFalsy(curPeriodPercentage); const prePeriodPercentageString = numberBeDashIfFalsy(prePeriodPercentage); const accountReadyForFrontend: IAccountReadyForFrontend = { @@ -185,12 +188,21 @@ export default abstract class FinancialReportGenerator extends ReportGenerator { prePeriodAmountString, prePeriodPercentageString, indent: curPeriodAccount.indent, - children: [], + children, }; curPeriodAccountReadyForFrontendArray.push(accountReadyForFrontend); }); } + return curPeriodAccountReadyForFrontendArray; + } + + public async generateIAccountReadyForFrontendArray(): Promise { + this.curPeriodContent = await this.generateFinancialReportArray(true); + + this.prePeriodContent = await this.generateFinancialReportArray(false); + const curPeriodAccountReadyForFrontendArray: IAccountReadyForFrontend[] = + this.combineTwoFSReportArray(this.curPeriodContent, this.prePeriodContent); return curPeriodAccountReadyForFrontendArray; }