Pin the two least-covered SalesInvoiceGLComposer methods before refactor:
- stock_delivered_but_not_billed_gl_entries: billing a perpetual Delivery
Note via Sales Invoice reverses the SDBNB account into COGS for an equal
amount.
- get_gle_for_change_amount: empty without change, mandatory-account error,
and the debit-to / change-account entry pair.
Extract two cross-cutting helpers used across the GL methods:
- _amount_in_account_currency: the repeated 'base if account is in company
currency else transaction amount' ternary (customer, tax, item, POS and
write-off entries).
- _return_aware_against_voucher: the return/self-outstanding against_voucher
rule duplicated in the customer and POS entries.
Pull the per-item income and discount rows into their own builders and
flatten make_item_gl_entries with a guard clause. Complexity drops:
make_customer C11->B7, make_pos C12->B7, make_item C14->B10,
make_discount C13->B10, make_tax->A3. No behaviour change; entry dicts and
amounts are identical (full Sales Invoice suite green).
stock_delivered_but_not_billed_gl_entries is left for a coverage-first pass
(it is the least-tested GL branch).
3-way merged onto develop (preserving the get_party_bank_account import move).
get_subscription_details passes order_by="" so get_all does not inject the
doctype default sort the raw query never had.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3-way merged onto develop, preserving develop's set_exchange_rate(ref_doc=doc) change.
One portable raw query is intentionally kept (as on the source branch).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The raw get_fiscal_years query had no ORDER BY (de-facto oldest-first); the
get_all port adds explicit order_by="name asc" so the Fiscal Year doctype
default (name DESC) does not reverse the report column order / cumulative values.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Most queries are straight raw-SQL -> query-builder ports. One rider:
get_future_payments_from_journal_entry sums future amounts with no GROUP BY,
so its non-aggregated identity columns (invoice_no/party/future_date/future_ref)
are wrapped in Max() to satisfy postgres strict GROUP BY. The summed amount is
unchanged; the attributed invoice/party label stays within MariaDB's existing
arbitrary-row indeterminacy for that already-aggregated single-row query.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Also sort the distinct income / unrealized P&L account lists in python:
frame drops ORDER BY for distinct queries on postgres, so the generated
account-column order must be pinned in python to stay deterministic on
both backends.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
disable_rounded_total and is_pos are smallint Check fields; postgres rejects
using them as bare boolean conditions in CASE WHEN / bitwise-AND, so compare
explicitly against 1. No-op on MariaDB.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>