Implementing running balance, fixing it so A accounts won't show up unless miscoded

This commit is contained in:
Bryce Covert
2020-09-29 13:12:45 -07:00
parent bf17e9582f
commit b4755840ae
6 changed files with 151 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
(ns auto-ap.graphql.ledger
(:require [auto-ap.datomic :refer [audit-transact-batch remove-nils uri]]
(:require [auto-ap.datomic :refer [audit-transact-batch remove-nils uri conn]]
[auto-ap.datomic.accounts :as a]
[auto-ap.datomic.clients :as d-clients]
[auto-ap.datomic.ledger :as l]
@@ -14,11 +14,31 @@
[clojure.string :as str]
[clojure.tools.logging :as log]
[datomic.api :as d]
[unilog.context :as lc]))
[unilog.context :as lc]
[yang.scheduler :as scheduler]
[mount.core :as mount]))
(mount/defstate running-balance-cache
:start (atom {}))
(defn get-ledger-page [context args value]
(let [args (assoc args :id (:id context))
[journal-entries journal-entries-count] (l/get-graphql (<-graphql args))]
[journal-entries journal-entries-count] (l/get-graphql (<-graphql args))
journal-entries (mapv
(fn [je]
(update je :journal-entry/line-items
(fn [jels]
(mapv
(fn [jel]
(log/info (get-in @running-balance-cache [(:db/id (:journal-entry/client je))
(:db/id jel)]))
(assoc jel :running-balance (get-in @running-balance-cache [(:db/id (:journal-entry/client je))
(:db/id jel)])))
jels)
))
)
journal-entries)]
(result->page journal-entries journal-entries-count :journal_entries args)))
;; TODO a better way to do this might be to accumulate ALL credits and ALL debits, and then just do for credits: balance = credits - debits. and for debits balance = debits - credits
@@ -299,3 +319,79 @@
:errors (map (fn [x] {:external_id (:external_id x)
:error (:error x)}) errors)})))
(defn build-running-balance
([lookup-account all-ledger-entries]
(->> all-ledger-entries
(reduce
(fn [[rollup cache] [_ jel account location debit credit]]
(let [rollup (-> rollup
(update-in [[location account] :debit] (fnil + 0.0) debit)
(update-in [[location account] :credit] (fnil + 0.0) credit)
(update-in [[location account] :count] (fnil + 0) 1))]
[rollup
(assoc cache jel (assoc (get rollup [location account]) :account-id account))]))
[{} {}])
(second)
(reduce-kv
(fn [acc jel {:keys [debit credit count account-id]}]
(let [account (lookup-account account-id)
account-type (:account_type account)]
(assoc acc jel
(if account-type (if (#{:account-type/asset
:account-type/dividend
:account-type/expense} account-type)
(- debit credit)
(- credit debit))
0.0))))
{}))))
(defn running-balance-for [client-id]
(let [lookup-account (build-account-lookup client-id)]
(->> (d/query
{:query {:find ['?d '?jel '?account '?location '?debit '?credit]
:in ['$ '?client-id]
:where '[[?e :journal-entry/client ?client-id]
[?e :journal-entry/date ?d]
[?e :journal-entry/line-items ?jel]
(or-join [?e]
(and [?e :journal-entry/original-entity ?i]
(or-join [?e ?i]
(and
[?i :transaction/bank-account ?b]
(or [?b :bank-account/include-in-reports true]
(not [?b :bank-account/include-in-reports])))
(not [?i :transaction/bank-account])))
(not [?e :journal-entry/original-entity ]))
[(get-else $ ?jel :journal-entry-line/account :account/unknown) ?account]
[(get-else $ ?jel :journal-entry-line/debit 0.0) ?debit ]
[(get-else $ ?jel :journal-entry-line/credit 0.0) ?credit]
[(get-else $ ?jel :journal-entry-line/location "") ?location]]
}
:args [(d/db conn) client-id]})
(sort-by first)
(build-running-balance lookup-account))))
(defn build-running-balance-cache []
(reduce
(fn [acc client]
(log/info "Computing running balance cache for " (:client/code client))
(assoc acc (:db/id client) (running-balance-for (:db/id client))))
{}
(d-clients/get-all)))
(defn refresh-running-balance-cache []
(lc/with-context {:source "running-balance-cache"}
(try
(log/info "Refreshing running balance cache")
(reset! running-balance-cache (build-running-balance-cache))
(catch Exception e
(log/error e)))))
(mount/defstate running-balance-cache-worker
:start (scheduler/every (* 5 60 1000) refresh-running-balance-cache)
:stop (scheduler/stop running-balance-cache-worker))