(cloud) running balance update way more streamlined now

This commit is contained in:
2023-03-30 16:44:25 -07:00
parent f7d21e2bbf
commit 5df47c8837
5 changed files with 78 additions and 147 deletions

View File

@@ -170,77 +170,34 @@
lms)))
->graphql)))
(defn refresh-bank-account-current-balance [bank-account-id]
(let [all-transactions (dc/q
{:query {:find ['?e '?debit '?credit]
:in ['$ '?bank-account-id]
:where '[[?e :journal-entry-line/account ?bank-account-id]
[(get-else $ ?e :journal-entry-line/debit 0.0) ?debit]
[(get-else $ ?e :journal-entry-line/credit 0.0) ?credit]]}
:args [(dc/db conn) bank-account-id]})
debits (->> all-transactions
(map (fn [[_ debit _]]
debit))
(reduce + 0.0))
credits (->> all-transactions
(map (fn [[_ _ credit]]
credit))
(reduce + 0.0))
current-balance (if (= :bank-account-type/check (:db/ident (:bank-account/type (dc/pull (dc/db conn) [:bank-account/type] bank-account-id))))
(- debits credits)
(- credits debits))]
(dc/transact conn {:tx-data [{:db/id bank-account-id
:bank-account/current-balance current-balance}]})))
(defn bank-accounts-needing-refresh []
(let [last-refreshed (->> (dc/q {:query {:find ['?ba '?tx]
:in ['$ ]
:where ['[?ba :bank-account/current-balance _ ?tx true]]}
:args [(dc/history (dc/db conn))]})
(group-by first)
(map (fn [[ba balance-txes]]
[ba (->> balance-txes
(map second)
(sort-by #(- %))
first)])))
has-newer-transaction (->> (dc/q
{:query {:find ['?ba]
:in '[$ [[?ba ?last-refreshed] ...] ]
:where ['[_ :journal-entry-line/account ?ba ?tx]
'[(>= ?tx ?last-refreshed)]]}
:args [(dc/history (dc/db conn))
last-refreshed]})
(map first)
(set))
no-current-balance (->> (dc/q {:query {:find ['?ba]
:in '[$]
:where ['[?ba :bank-account/code]
'(not [?ba :bank-account/current-balance])
]}
:args [(dc/db conn)]})
(map first))]
(into has-newer-transaction no-current-balance)))
(defn build-current-balance [bank-accounts]
(doseq [bank-account bank-accounts]
(log/info "Refreshing bank account" (-> (dc/db conn) (dc/pull [:bank-account/code] bank-account)))
(try
(refresh-bank-account-current-balance bank-account)
(catch Exception e
(log/error "Can't refresh current balance" e)))))
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
(defn refresh-all-current-balance []
(lc/with-context {:source "current-balance-cache"}
(build-current-balance (->> (dc/q {:query {:find ['?ba]
:in '[$]
:where ['[?ba :bank-account/code]]}
:args [(dc/db conn)]})
(map first)))))
(defn refresh-current-balance []
(build-current-balance (bank-accounts-needing-refresh)))
(lc/with-context {:source "current-balance-refresh"}
(let [db (dc/db conn)
clients (dc/q '[:find (pull ?c [:db/id :client/code {:client/bank-accounts [:db/id :bank-account/code]}])
:where [?c :client/code]]
db )]
(dc/transact conn
{:tx-data
(for [[{client :db/id code :client/code bank-accounts :client/bank-accounts}] clients
{bank-account :db/id bac :bank-account/code} bank-accounts]
{:db/id bank-account
:bank-account/current-balance
(or
(->> (dc/index-pull db
{:index :avet
:selector [:db/id :journal-entry-line/location :journal-entry-line/account :journal-entry-line/running-balance :journal-entry-line/client+account+location+date {:journal-entry/_line-items [:journal-entry/date :journal-entry/client]}]
:start [:journal-entry-line/client+account+location+date [client bank-account "A" #inst "2030-01-01"]]
:limit 1
:reverse true
})
(filter (fn [{[c b] :journal-entry-line/client+account+location+date}]
(and (= c client)
(= b bank-account))))
(map :journal-entry-line/running-balance)
(first))
0.0)})})))
)
(defn get-client [context _ _]
(->graphql

View File

@@ -5,7 +5,7 @@
[auto-ap.jobs.core :refer [execute]]))
(defn -main [& _]
(execute "current-balance-cache" clients/refresh-current-balance))
(execute "current-balance-cache" clients/refresh-all-current-balance))

View File

@@ -2,13 +2,12 @@
(:require
[auto-ap.datomic
:refer [audit-transact
audit-transact-batch
transact-with-backoff
conn
pull-id
pull-ref
remove-nils]]
[auto-ap.utils :refer [by dollars-0? dollars=]]
remove-nils
transact-with-backoff]]
[auto-ap.utils :refer [by dollars-0? dollars= heartbeat]]
[clj-time.coerce :as c]
[clj-time.core :as t]
[clojure.tools.logging :as log]
@@ -17,7 +16,9 @@
[datomic.client.api :as dc]
[iol-ion.tx :refer [upsert-ledger]]
[manifold.deferred :as de]
[manifold.stream :as s]))
[manifold.stream :as s]
[mount.core :as mount]
[yang.scheduler :as scheduler]))
(defn datums->impacted-entity [db [e changes]]
(let [entity (dc/pull db '[{:invoice/_expense-accounts [:db/id] :transaction/_accounts [:db/id]}] e)
@@ -754,6 +755,6 @@
;; TODO only enable once IOL is set up in clod
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
#_(mount/defstate running-balance-cache-worker
(mount/defstate running-balance-cache-worker
:start (scheduler/every (* 15 60 (+ 500 (rand-int 500))) (heartbeat refresh-running-balance-cache "running-balance-cache"))
:stop (scheduler/stop running-balance-cache-worker))