mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-15 23:48:38 +00:00
* fix(accounts): key the payment ledger CTEs on account, not Max(account) QueryPaymentLedger builds two CTEs -- voucher amount and outstanding -- and joins them on account among other columns. Both sides selected Max(account) while grouping without it, so the join key was an aggregate over two different row sets. A voucher posting ledger entries against two party accounts could have the two sides pick different accounts, the join miss, and the outstanding come back NULL. Max() over text is a sort, so which account wins is also collation-dependent, and the engines sort text differently. Group both CTEs by account instead. That makes the join key a real column and scopes each Sum() to a single account -- so amount_in_account_currency is no longer summed across accounts that may not share a currency. Row shape only changes for a voucher that genuinely spans two party accounts for one party, where today's single row is already an arbitrary pick over mixed currencies. cost_center and remarks stay descriptive but genuinely vary per entry, and were aggregated independently, so they could be stitched together from different entries into a row that was never posted. They now come off one real entry, picked by Min(name) -- Payment Ledger Entry declares no autoname rule, so frappe names it by hash, and those are lower-case, which keeps the pick free of the collation divergence. * test(accounts): cover payment ledger metadata coherence A Journal Entry posting two receivable lines for one customer with different cost centers and remarks. Whatever row the ledger returns, its cost center and remarks must be a pair that was actually posted. Guards the fixture itself, so it cannot pass by posting only one distinct pair. * test(accounts): cover the account-keyed payment ledger aggregation The coherence test posts both party lines to one account, so it exercises the representative-row metadata but not the account-keyed grouping or the CTE join. Adds a Journal Entry posting to two receivable accounts for one customer and asserts each account comes back as its own row, with its own amount and a non-null outstanding.