Recalculates running balance as report is run

This commit is contained in:
2025-02-08 22:14:24 -08:00
parent d078fb8a15
commit 38ed981cba
3 changed files with 79 additions and 70 deletions

View File

@@ -352,18 +352,23 @@
(do (println (count a)) (do (println (count a))
(count a))))) (count a)))))
(defn clients-needing-refresh [db] (defn clients-needing-refresh [db available]
(->> (let [clients (->>
(dc/q '[:find (pull ?c [:client/code :db/id :client/ledger-last-change :client/last-running-balance]) (dc/q '[:find (pull ?c [:client/code :db/id :client/ledger-last-change :client/last-running-balance])
:in $ :in $
:where :where
[?c :client/code] [?c :client/code]
[(get-else $ ?c :client/ledger-last-change #inst "2040-01-01") ?last-change] [(get-else $ ?c :client/ledger-last-change #inst "2040-01-01") ?last-change]
[(get-else $ ?c :client/last-running-balance #inst "2000-01-01") ?last-running-balance] [(get-else $ ?c :client/last-running-balance #inst "2000-01-01") ?last-running-balance]
[(> ?last-change ?last-running-balance)] ] [(> ?last-change ?last-running-balance)]]
db) db)
(map (fn [[client]] (map (fn [[client]]
client)))) client)))]
(if (and (set? available) (seq available))
(filter (comp available :db/id) clients)
clients)))
#_(clients-needing-refresh (dc/db conn) #{ 17592273679867})
#_(comment [17592334354011 #inst "0024-08-03T07:52:58.000-00:00"] #_(comment [17592334354011 #inst "0024-08-03T07:52:58.000-00:00"]
[17592302554688 #inst "0023-07-20T07:52:58.000-00:00"] [17592302554688 #inst "0023-07-20T07:52:58.000-00:00"]
@@ -422,58 +427,60 @@
:bank-account/current-balance running-balance}]))))))) :bank-account/current-balance running-balance}])))))))
;; TODO using iol-ion query as the base, building running balance sets ;; TODO using iol-ion query as the base, building running balance sets
(defn upsert-running-balance [] (defn upsert-running-balance
(mu/with-context {:service "upsert-running-balance" ([] (upsert-running-balance nil))
:source "upsert-running-balance" } ([clients]
(mu/trace ::updating-balance (mu/with-context {:service "upsert-running-balance"
[:service "upsert-running-balance" :source "upsert-running-balance"}
:source "upsert-running-balance" ] (mu/trace ::updating-balance
(let [db (dc/db conn) [:service "upsert-running-balance"
starting-at (c/to-date (t/now)) :source "upsert-running-balance"]
clients (clients-needing-refresh db) (let [db (dc/db conn)
_ (alog/info ::clients-needing-update :clients clients :count (count clients)) starting-at (c/to-date (t/now))
client-change-stats (atom {}) clients (clients-needing-refresh db clients)
changes (for [c clients _ (alog/info ::clients-needing-update :clients clients :count (count clients))
:let [client-id (:db/id c) client-change-stats (atom {})
account-lookup (build-account-lookup client-id)] changes (for [c clients
running-balance-set (account-sets db client-id) :let [client-id (:db/id c)
running-balance-change (->> running-balance-set account-lookup (build-account-lookup client-id)]
(reduce running-balance-set (account-sets db client-id)
(fn [{:keys [changes last-running-balance]} running-balance-change (->> running-balance-set
^Line line-item] (reduce
#_(if (= 0 (rand-int 1000)) (fn [{:keys [changes last-running-balance]}
(println (.-account-id line-item) (.-debit line-item) (.-credit line-item))) ^Line line-item]
(let [delta (if (#{:account-type/asset #_(if (= 0 (rand-int 1000))
:account-type/dividend (println (.-account-id line-item) (.-debit line-item) (.-credit line-item)))
:account-type/expense} (:account_type (account-lookup (.-account-id line-item)))) (let [delta (if (#{:account-type/asset
(- (or (.-debit line-item) 0.0) (or (.-credit line-item) 0.0)) :account-type/dividend
(- (or (.-credit line-item) 0.0) (or (.-debit line-item) 0.0))) :account-type/expense} (:account_type (account-lookup (.-account-id line-item))))
correct-running-balance (+ last-running-balance delta) (- (or (.-debit line-item) 0.0) (or (.-credit line-item) 0.0))
running-balance-changed? (not (dollars= correct-running-balance (or (.-running-balance line-item) 0.0)))] (- (or (.-credit line-item) 0.0) (or (.-debit line-item) 0.0)))
(when running-balance-changed? correct-running-balance (+ last-running-balance delta)
(swap! client-change-stats update (:client/code c) (fnil inc 0))) running-balance-changed? (not (dollars= correct-running-balance (or (.-running-balance line-item) 0.0)))]
(cond-> {:last-account-lookup account-lookup (when running-balance-changed?
:last-running-balance correct-running-balance (swap! client-change-stats update (:client/code c) (fnil inc 0)))
:changes changes} (cond-> {:last-account-lookup account-lookup
:last-running-balance correct-running-balance
:changes changes}
running-balance-changed? running-balance-changed?
(update :changes conj {:db/id (.-id line-item) (update :changes conj {:db/id (.-id line-item)
:journal-entry-line/running-balance correct-running-balance})))) :journal-entry-line/running-balance correct-running-balance}))))
{:last-running-balance 0.0}) {:last-running-balance 0.0})
:changes)] :changes)]
running-balance-change)] running-balance-change)]
(mu/trace ::update-running-balance [] (mu/trace ::update-running-balance []
(auto-ap.datomic/audit-transact-batch changes (auto-ap.datomic/audit-transact-batch changes
{:user/name "running balance updater"})) {:user/name "running balance updater"}))
(auto-ap.datomic/audit-transact (mapv (fn [c] (auto-ap.datomic/audit-transact (mapv (fn [c]
{:db/id (:db/id c) {:db/id (:db/id c)
:client/last-running-balance starting-at}) :client/last-running-balance starting-at})
clients) clients)
{:user/name "running balance updater"}) {:user/name "running balance updater"})
(alog/info ::change-stats :stats @client-change-stats) (alog/info ::change-stats :stats @client-change-stats)
(refresh-bank-account-balances (map :db/id clients)) (refresh-bank-account-balances (map :db/id clients))
(count changes))))) (count changes))))))
(comment (comment
(pull-id (dc/db conn) [:client/code "SCCB"]) (pull-id (dc/db conn) [:client/code "SCCB"])

View File

@@ -4,7 +4,7 @@
[auto-ap.datomic [auto-ap.datomic
:refer [conn pull-many]] :refer [conn pull-many]]
[auto-ap.graphql.utils :refer [assert-can-see-client]] [auto-ap.graphql.utils :refer [assert-can-see-client]]
[auto-ap.ledger :refer [build-account-lookup]] [auto-ap.ledger :refer [build-account-lookup upsert-running-balance]]
[auto-ap.ledger.reports :as l-reports] [auto-ap.ledger.reports :as l-reports]
[auto-ap.logging :as alog] [auto-ap.logging :as alog]
[auto-ap.pdf.ledger :refer [table->pdf]] [auto-ap.pdf.ledger :refer [table->pdf]]
@@ -72,6 +72,8 @@
_ (doseq [client-id client-ids] _ (doseq [client-id client-ids]
(assert-can-see-client (:identity request) client-id)) (assert-can-see-client (:identity request) client-id))
_ (upsert-running-balance (into #{} client-ids))
lookup-account (->> client-ids lookup-account (->> client-ids
(map (fn build-lookup [client-id] (map (fn build-lookup [client-id]
[client-id (build-account-lookup client-id)])) [client-id (build-account-lookup client-id)]))
@@ -184,10 +186,10 @@
(defn make-balance-sheet-pdf [request report] (defn make-balance-sheet-pdf [request report]
(let [ output-stream (ByteArrayOutputStream.) (let [output-stream (ByteArrayOutputStream.)
client-count (count (or (seq (:client (:query-params request))) client-count (count (or (seq (:client (:query-params request)))
(seq (:client (:form-params request))))) (seq (:client (:form-params request)))))
date (:date (:query-params request))] date (:date (:query-params request)) ]
(pdf/pdf (pdf/pdf
(-> [{:left-margin 10 :right-margin 10 :top-margin 15 :bottom-margin 15 (-> [{:left-margin 10 :right-margin 10 :top-margin 15 :bottom-margin 15
:size :letter :size :letter

View File

@@ -4,7 +4,7 @@
[auto-ap.datomic [auto-ap.datomic
:refer [conn pull-many]] :refer [conn pull-many]]
[auto-ap.graphql.utils :refer [assert-can-see-client]] [auto-ap.graphql.utils :refer [assert-can-see-client]]
[auto-ap.ledger :refer [build-account-lookup]] [auto-ap.ledger :refer [build-account-lookup upsert-running-balance]]
[auto-ap.ledger.reports :as l-reports] [auto-ap.ledger.reports :as l-reports]
[auto-ap.logging :as alog] [auto-ap.logging :as alog]
[auto-ap.pdf.ledger :refer [table->pdf]] [auto-ap.pdf.ledger :refer [table->pdf]]
@@ -33,8 +33,7 @@
[config.core :refer [env] :as env] [config.core :refer [env] :as env]
[datomic.api :as dc] [datomic.api :as dc]
[iol-ion.utils :refer [by]] [iol-ion.utils :refer [by]]
[malli.core :as mc] [malli.core :as mc])
[medley.core :refer [map-vals]])
(:import (:import
[java.util UUID] [java.util UUID]
[org.apache.commons.io.output ByteArrayOutputStream])) [org.apache.commons.io.output ByteArrayOutputStream]))
@@ -76,6 +75,7 @@
(when (and (seq periods) client) (when (and (seq periods) client)
(let [client (if (= :all client) (take 5 (:clients request)) client) (let [client (if (= :all client) (take 5 (:clients request)) client)
client-ids (map :db/id client) client-ids (map :db/id client)
_ (upsert-running-balance (into #{} client-ids))
_ (doseq [client-id client-ids] _ (doseq [client-id client-ids]
(assert-can-see-client (:identity request) client-id)) (assert-can-see-client (:identity request) client-id))