From 942bad6c8cff417c6f31c78e6b21c5e0ffff0e00 Mon Sep 17 00:00:00 2001 From: Nitesh Yadav Date: Tue, 1 Sep 2026 21:58:12 +0530 Subject: [PATCH] fix(branchday): count account closures in the day-close cash reconciliation Day Close reported SHORT by exactly the amount a closure had paid out. The "Cash paid out (approved withdrawals)" line only summed m_clerk_withdrawal_request, so a closure -- which pays cash over the same counter but lives in its own register -- was missing from the total. Expected cash stayed high by what had actually been handed over, and a closure that balanced perfectly read as a shortage. Verified against live data: opening 145,304 + deposits 0 - slip withdrawals 0 - closure 12,999 = 132,305, which is exactly the counted branch total. Variance goes from -12,999 to 0. Sums cashier_disbursed_amount rather than closing_amount: the member's ledger gives up the paisa-exact figure, but what physically leaves the drawer is that figure rounded to whole rupees, and this total has to agree with a physical count. Restricted to CLOSED rows dated on disbursed_at, since a closure takes nothing out of the drawer until the cashier hands it over. Note: dividend cash claims (m_share_dividend_claim_request) are also absent from this total and will misreport the same way. Left alone deliberately -- that register splits a claim across loan/savings/cash with its own cash_status column that nothing in the Java sets, so the right predicate cannot be established from the code as it stands. Co-Authored-By: Claude Opus 5 (1M context) --- .../api/BranchDayRegisterApiResource.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/branchday/api/BranchDayRegisterApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/branchday/api/BranchDayRegisterApiResource.java index ab0a6d421..249622985 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/branchday/api/BranchDayRegisterApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/branchday/api/BranchDayRegisterApiResource.java @@ -853,12 +853,29 @@ public class BranchDayRegisterApiResource { // disbursements use APPROVED; withdrawal is the one register that doesn't) -- filtering on // APPROVED alone silently excluded every completed withdrawal from this total, overstating // the branch's expected cash by exactly what had actually been paid out that day. - final BigDecimal withdrawals = zero(jdbcTemplate.queryForObject(""" + final BigDecimal slipWithdrawals = zero(jdbcTemplate.queryForObject(""" SELECT COALESCE(SUM(amount), 0) FROM m_clerk_withdrawal_request WHERE status = 'WITHDRAWN' AND COALESCE(txn_date, CAST(submitted_at AS DATE)) = ? """, BigDecimal.class, date)); + // Account closures pay cash over the same counter but live in their own register, so they + // were missing from this total entirely -- the branch's expected cash stayed high by exactly + // what had been handed over, reporting a shortage for a closure that balanced perfectly. + // + // cashier_disbursed_amount, not closing_amount: the member's ledger gives up the paisa-exact + // figure, but what physically leaves the drawer is that figure rounded to whole rupees, and + // this total has to agree with a physical count. Only CLOSED rows, dated on disbursed_at, + // since a closure takes nothing out of the drawer until the cashier hands it over (a + // nil-balance closure never reaches a cashier at all, hence the closure_date fallback). + final BigDecimal closureWithdrawals = zero(jdbcTemplate.queryForObject(""" + SELECT COALESCE(SUM(cashier_disbursed_amount), 0) FROM m_clerk_closure_request + WHERE status = 'CLOSED' + AND COALESCE(CAST(disbursed_at AS DATE), closure_date) = ? + """, BigDecimal.class, date)); + + final BigDecimal withdrawals = slipWithdrawals.add(closureWithdrawals); + // Cash drawn from the vault to a cashier — more physical cash sitting in the branch. final BigDecimal vaultIn = zero(jdbcTemplate.queryForObject(""" SELECT COALESCE(SUM(transfer_amount), 0) FROM m_cash_transfer