diff --git a/backend/src/modules/reports/reports.service.ts b/backend/src/modules/reports/reports.service.ts index 094f73c..0222971 100644 --- a/backend/src/modules/reports/reports.service.ts +++ b/backend/src/modules/reports/reports.service.ts @@ -508,25 +508,25 @@ export class ReportsService { const monthLabels = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; // ── 1) Get current balances as of now ── - // Operating cash (asset accounts with fund_type=operating) + // Use ASSET accounts for both operating and reserve — these represent actual cash holdings. + // Equity accounts are the bookkeeping counterpart and would double-count. const opCashRows = await this.tenant.query(` SELECT COALESCE(SUM(sub.bal), 0) as total FROM ( SELECT COALESCE(SUM(jel.debit), 0) - COALESCE(SUM(jel.credit), 0) as bal FROM accounts a - LEFT JOIN journal_entry_lines jel ON jel.account_id = a.id - LEFT JOIN journal_entries je ON je.id = jel.journal_entry_id AND je.is_posted = true AND je.is_void = false + JOIN journal_entry_lines jel ON jel.account_id = a.id + JOIN journal_entries je ON je.id = jel.journal_entry_id AND je.is_posted = true AND je.is_void = false WHERE a.account_type = 'asset' AND a.fund_type = 'operating' AND a.is_active = true GROUP BY a.id ) sub `); - // Reserve cash (equity fund balance for reserve) const resCashRows = await this.tenant.query(` SELECT COALESCE(SUM(sub.bal), 0) as total FROM ( - SELECT COALESCE(SUM(jel.credit), 0) - COALESCE(SUM(jel.debit), 0) as bal + SELECT COALESCE(SUM(jel.debit), 0) - COALESCE(SUM(jel.credit), 0) as bal FROM accounts a - LEFT JOIN journal_entry_lines jel ON jel.account_id = a.id - LEFT JOIN journal_entries je ON je.id = jel.journal_entry_id AND je.is_posted = true AND je.is_void = false - WHERE a.fund_type = 'reserve' AND a.account_type = 'equity' AND a.is_active = true + JOIN journal_entry_lines jel ON jel.account_id = a.id + JOIN journal_entries je ON je.id = jel.journal_entry_id AND je.is_posted = true AND je.is_void = false + WHERE a.account_type = 'asset' AND a.fund_type = 'reserve' AND a.is_active = true GROUP BY a.id ) sub `); @@ -641,13 +641,14 @@ export class ReportsService { // For historical months, compute cumulative balances from journal entries // We'll track running balances - // First compute opening balance at start of startYear + // First compute opening balance at start of startYear using asset accounts const openingOp = await this.tenant.query(` SELECT COALESCE(SUM(sub.bal), 0) as total FROM ( SELECT COALESCE(SUM(jel.debit), 0) - COALESCE(SUM(jel.credit), 0) as bal FROM accounts a - LEFT JOIN journal_entry_lines jel ON jel.account_id = a.id - LEFT JOIN journal_entries je ON je.id = jel.journal_entry_id AND je.is_posted = true AND je.is_void = false + JOIN journal_entry_lines jel ON jel.account_id = a.id + JOIN journal_entries je ON je.id = jel.journal_entry_id + AND je.is_posted = true AND je.is_void = false AND je.entry_date < $1::date WHERE a.account_type = 'asset' AND a.fund_type = 'operating' AND a.is_active = true GROUP BY a.id @@ -656,12 +657,13 @@ export class ReportsService { const openingRes = await this.tenant.query(` SELECT COALESCE(SUM(sub.bal), 0) as total FROM ( - SELECT COALESCE(SUM(jel.credit), 0) - COALESCE(SUM(jel.debit), 0) as bal + SELECT COALESCE(SUM(jel.debit), 0) - COALESCE(SUM(jel.credit), 0) as bal FROM accounts a - LEFT JOIN journal_entry_lines jel ON jel.account_id = a.id - LEFT JOIN journal_entries je ON je.id = jel.journal_entry_id AND je.is_posted = true AND je.is_void = false + JOIN journal_entry_lines jel ON jel.account_id = a.id + JOIN journal_entries je ON je.id = jel.journal_entry_id + AND je.is_posted = true AND je.is_void = false AND je.entry_date < $1::date - WHERE a.fund_type = 'reserve' AND a.account_type = 'equity' AND a.is_active = true + WHERE a.account_type = 'asset' AND a.fund_type = 'reserve' AND a.is_active = true GROUP BY a.id ) sub `, [`${startYear}-01-01`]); @@ -719,19 +721,13 @@ export class ReportsService { const label = `${monthLabels[month - 1]} ${year}`; if (isHistorical) { - // Use actual journal entry changes + // Use actual journal entry changes from asset accounts const opChange = histIndex[`${year}-${month}-operating`] || 0; runOpCash += opChange; - // For reserve, we need the equity-based changes - const resEquityChange = await this.tenant.query(` - SELECT COALESCE(SUM(jel.credit - jel.debit), 0) as net - FROM journal_entry_lines jel - JOIN journal_entries je ON je.id = jel.journal_entry_id AND je.is_posted = true AND je.is_void = false - JOIN accounts a ON a.id = jel.account_id AND a.fund_type = 'reserve' AND a.account_type = 'equity' - WHERE EXTRACT(YEAR FROM je.entry_date) = $1 AND EXTRACT(MONTH FROM je.entry_date) = $2 - `, [year, month]); - runResCash += parseFloat(resEquityChange[0]?.net || '0'); + // Reserve also uses asset account changes (already in histIndex from section 4) + const resChange = histIndex[`${year}-${month}-reserve`] || 0; + runResCash += resChange; datapoints.push({ month: label,