2 Commits

Author SHA1 Message Date
ab27d3a4da fix(ledger): match bank accounts sharing a code in register account search
A client's bank account and the financial account it posts to share a
numeric code, and :journal-entry-line/account points at either entity.
The register's Account search matched the selected entity id exactly, so
picking a financial account missed every line posted to the bank account
on that code -- while the Account Code range filter, which already
or-joins both namespaces, found them.

Resolve the shared bank accounts up front and pass the id set into the
existing clause rather than or-joining inside the query: an or-join turns
a selective indexed lookup into per-line work and measured 2.5-3.4x
slower on every account search, including ones that share no code. When
nothing shares the code the emitted query is unchanged, so the common
case stays at parity (0.97-1.04x, plus ~0.2ms to resolve).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 21:23:01 -07:00
19d936693a Merge pull request 'fix(reports): collapse accounts sharing a numeric code to one row' (#16) from integreat-fix-report into staging
Reviewed-on: #16
2026-08-14 16:40:45 -07:00

View File

@@ -209,6 +209,37 @@
;; 3. CSVs
;; 4. better date range / advanced mode for dialog
(defn- accounts-sharing-code
"The searched account, plus any of `clients`' bank accounts on the same numeric
code. :journal-entry-line/account points at either entity, so a search for the
financial account has to match lines posted to the bank account too."
[db clients account-id]
(into [account-id]
(when-let [code (:account/numeric-code (dc/entity db account-id))]
(dc/q '[:find [?ba ...]
:in $ [?client ...] ?code
:where
[?client :client/bank-accounts ?ba]
[?ba :bank-account/numeric-code ?code]]
db clients code))))
(defn- account-filter-query
"Ledger clause for the Account search. Stays a scalar binding when nothing
shares the account's code, so the common case costs what it always did."
[db clients account-id]
(let [ids (accounts-sharing-code db clients account-id)]
(if (second ids)
{:query {:in ['[?a3 ...]]
:where ['[?li :journal-entry-line/account ?a3]]}
:args [ids]}
{:query {:in ['?a3]
:where ['[?li :journal-entry-line/account ?a3]]}
:args [account-id]})))
(defn fetch-ids [db {:keys [query-params route-params] :as request}]
(let [valid-clients (extract-client-ids (:clients request)
(:client-id request)
@@ -288,9 +319,7 @@
'[(<= ?c ?to-numeric-code)]]}
:args [(map (juxt :from :to) (:numeric-code args))]})
(seq (:account args))
(merge-query {:query {:in ['?a3]
:where ['[?li :journal-entry-line/account ?a3]]}
:args [(:db/id (:account args))]})
(merge-query (account-filter-query db valid-clients (:db/id (:account args))))
(:amount-gte args)
(merge-query {:query {:in ['?amount-gte]