started work on bank comparisons.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -215,6 +215,11 @@
|
||||
:db/cardinality #:db{:ident :db.cardinality/one},
|
||||
:db/doc "A precomputed balance for the account",
|
||||
:db/ident :bank-account/current-balance}
|
||||
{:db/valueType #:db{:ident :db.type/instant},
|
||||
:db/noHistory true,
|
||||
:db/cardinality #:db{:ident :db.cardinality/one},
|
||||
:db/doc "A precomputed balance for the account",
|
||||
:db/ident :bank-account/current-balance-synced}
|
||||
{:db/valueType #:db{:ident :db.type/long},
|
||||
:db/cardinality #:db{:ident :db.cardinality/one},
|
||||
:db/doc "The numeric code for the balance sheet",
|
||||
@@ -1619,6 +1624,11 @@
|
||||
:db/cardinality #:db{:ident :db.cardinality/one},
|
||||
:db/doc "Yodlee account id",
|
||||
:db/ident :yodlee-account/id}
|
||||
{:db/valueType #:db{:ident :db.type/instant},
|
||||
:db/noHistory true,
|
||||
:db/cardinality #:db{:ident :db.cardinality/one},
|
||||
:db/doc "A precomputed balance for the account",
|
||||
:db/ident :yodlee-account/last-synced}
|
||||
{:db/valueType #:db{:ident :db.type/string},
|
||||
:db/cardinality #:db{:ident :db.cardinality/one},
|
||||
:db/doc "account name",
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
[auto-ap.graphql.utils
|
||||
:refer [->graphql <-graphql assert-admin attach-tracing-resolvers
|
||||
can-see-client? is-admin? result->page]]
|
||||
[clj-time.coerce :as c]
|
||||
[clj-time.core :as time]
|
||||
[clojure.set :as set]
|
||||
[com.brunobonacci.mulog :as mu]
|
||||
[datomic.api :as dc]))
|
||||
@@ -13,24 +15,27 @@
|
||||
(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 )]
|
||||
(doseq [[{client :db/id code :client/code bank-accounts :client/bank-accounts}] clients
|
||||
{bank-account :db/id bac :bank-account/code} bank-accounts]
|
||||
db)]
|
||||
(doseq [[{client :db/id code :client/code bank-accounts :client/bank-accounts}] clients
|
||||
{bank-account :db/id bac :bank-account/code} bank-accounts]
|
||||
@(dc/transact conn [{: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"]]
|
||||
: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)}])))))
|
||||
:bank-account/current-balance-synced (c/to-date (time/now))
|
||||
: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"]]
|
||||
:reverse true})
|
||||
(take 3)
|
||||
|
||||
(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
|
||||
|
||||
@@ -96,4 +96,3 @@
|
||||
:intuit-bank-account/last-synced (coerce/to-date (:last-updated ba))
|
||||
:intuit-bank-account/current-balance (:current-balance ba)}))
|
||||
bank-accounts))))
|
||||
|
||||
|
||||
@@ -35,5 +35,39 @@
|
||||
|
||||
(require 'auto-ap.time_reader)
|
||||
|
||||
(let [start #clj-time/date-time "2024-02-01"
|
||||
end #clj-time/date-time "2024-04-01"]
|
||||
(for [[ib ba c] (seq (get-intuit-bank-accounts (dc/db conn) "BCFM"))
|
||||
:let [raw-transactions (i/get-transactions (atime/unparse-local start atime/iso-date)
|
||||
(atime/unparse-local end atime/iso-date)
|
||||
ib)
|
||||
ideal-transactions (intuits->transactions raw-transactions ba c)
|
||||
|
||||
found-transactions (when (seq ideal-transactions)
|
||||
(into {} (dc/q '[:find ?si (count ?t)
|
||||
:in $ [?eid ...]
|
||||
:where
|
||||
[?t :transaction/id ?eid]
|
||||
[?t :transaction/approval-status ?s]
|
||||
[?s :db/ident ?si]]
|
||||
(dc/db conn)
|
||||
(map :transaction/id ideal-transactions))))
|
||||
|
||||
missing-transaction-ids (when (seq ideal-transactions)
|
||||
(->>
|
||||
(dc/q '[:find ?eid
|
||||
:in $ [?eid ...]
|
||||
:where (not [_ :transaction/id ?eid])]
|
||||
(dc/db conn)
|
||||
(map :transaction/id ideal-transactions))
|
||||
(map first)
|
||||
(into #{})))
|
||||
missing-transactions (filter (comp missing-transaction-ids :transaction/id) ideal-transactions)]]
|
||||
{:bank-account/name (pull-attr (dc/db conn) :bank-account/name ba)
|
||||
:external-transaction-count (count raw-transactions)
|
||||
:integreat-transaction-count (reduce + 0 (vals found-transactions))
|
||||
:approved-count (:transaction-approval-status/approved found-transactions 0)
|
||||
:unapproved-count (:transaction-approval-status/unapproved found-transactions 0)
|
||||
:requires-feedback-count (:transaction-approval-status/requires-feedback found-transactions 0)
|
||||
:missing-transactions missing-transactions}))
|
||||
|
||||
|
||||
@@ -575,7 +575,6 @@
|
||||
(refresh-running-balance-accounts accounts-needing-rebuild clients c i db)
|
||||
(mu/log ::client-completed))))))))
|
||||
|
||||
|
||||
;; TODO only enable once IOL is set up in clod
|
||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||
(mount/defstate running-balance-cache-worker
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
[auto-ap.ssr.admin.transaction-rules :as admin-rules]
|
||||
[auto-ap.ssr.admin.vendors :as admin-vendors]
|
||||
[auto-ap.ssr.auth :as auth]
|
||||
[auto-ap.ssr.dashboard :as dashboard]
|
||||
[auto-ap.ssr.company :as company]
|
||||
[auto-ap.ssr.company-dropdown :as company-dropdown]
|
||||
[auto-ap.ssr.company.company-1099 :as company-1099]
|
||||
@@ -98,6 +99,7 @@
|
||||
(into admin-vendors/key->handler)
|
||||
(into admin-clients/key->handler)
|
||||
(into admin-rules/key->handler)
|
||||
(into dashboard/key->handler)
|
||||
(into indicators/key->handler)
|
||||
(into payments/key->handler)
|
||||
(into oin/route->handler)))
|
||||
|
||||
73
src/clj/auto_ap/ssr/dashboard.clj
Normal file
73
src/clj/auto_ap/ssr/dashboard.clj
Normal file
@@ -0,0 +1,73 @@
|
||||
(ns auto-ap.ssr.dashboard
|
||||
(:require [auto-ap.datomic :refer [conn]]
|
||||
[auto-ap.routes.dashboard :as d-routes]
|
||||
[auto-ap.routes.utils :refer [wrap-admin
|
||||
wrap-client-redirect-unauthenticated]]
|
||||
[auto-ap.ssr-routes :as ssr-routes]
|
||||
[auto-ap.ssr.components :as com]
|
||||
[auto-ap.ssr.ui :refer [base-page]]
|
||||
[auto-ap.ssr.utils :refer [apply-middleware-to-all-handlers]]
|
||||
[bidi.bidi :as bidi]
|
||||
[datomic.api :as dc]
|
||||
[auto-ap.time :as atime]))
|
||||
|
||||
(defn- page-contents [request]
|
||||
[:div
|
||||
[:h1.text-2xl.font-bold "Bank Accounts"]
|
||||
(com/card {:class "inline-block"}
|
||||
[:div.inline-flex.flex-wrap
|
||||
(for [c (:clients request)
|
||||
b (:client/bank-accounts (dc/pull (dc/db conn) '[{ :client/bank-accounts
|
||||
[:bank-account/current-balance
|
||||
[ :bank-account/current-balance-synced :xform clj-time.coerce/from-date]
|
||||
:bank-account/name
|
||||
{:bank-account/intuit-bank-account [:intuit-bank-account/current-balance
|
||||
[ :intuit-bank-account/last-synced :xform clj-time.coerce/from-date]]}
|
||||
{:bank-account/yodlee-account [:yodlee-account/available-balance
|
||||
[:yodlee-account/last-synced :xform clj-time.coerce/from-date]]}]}]
|
||||
(:db/id c)))]
|
||||
[:div.flex.flex-col.p-4.border-l-2
|
||||
[:div (:client/name c)]
|
||||
[:div (:bank-account/name b)]
|
||||
[:div.inline-flex.justify-between [:div "Ledger Balance"] (format "$%,.2f" (or (:bank-account/current-balance b) 0.0)) ]
|
||||
[:div.inline-flex.justify-end.text-xs.text-gray-400.it (some-> (:bank-account/current-balance-synced b)
|
||||
(atime/unparse-local atime/standard-time)
|
||||
(#(str "Synced " %))) ]
|
||||
[:div.inline-flex.justify-between [:div "Source Balance"] (format "$%,.2f" (or (-> b :bank-account/intuit-bank-account :intuit-bank-account/current-balance)
|
||||
(-> b :bank-account/yodlee-account :yodlee-account/available-balance)
|
||||
0.0))]
|
||||
[:div.inline-flex.justify-end.text-xs.text-gray-400.it (or (some-> (:bank-account/intuit-bank-account b)
|
||||
(:intuit-bank-account/last-synced)
|
||||
(atime/unparse-local atime/standard-time)
|
||||
(#(str "Synced " %)))
|
||||
(some-> (:bank-account/yodlee-account b)
|
||||
(:yodlee-account/last-synced)
|
||||
(atime/unparse-local atime/standard-time)
|
||||
(#(str "Synced " %))))]])]) ])
|
||||
|
||||
(defn page [request]
|
||||
(base-page
|
||||
request
|
||||
(com/page {:nav com/main-aside-nav
|
||||
:client-selection (:client-selection request)
|
||||
:clients (:clients request)
|
||||
:client (:client request)
|
||||
:identity (:identity request)
|
||||
:app-params {:hx-get (bidi/path-for ssr-routes/only-routes
|
||||
::d-routes/page)
|
||||
:hx-trigger "clientSelected from:body"
|
||||
:hx-select "#app-contents"
|
||||
:hx-swap "outerHTML swap:300ms"}
|
||||
|
||||
:request request}
|
||||
(com/breadcrumbs {}
|
||||
[:a {:href (bidi/path-for ssr-routes/only-routes ::d-routes/page)}
|
||||
"Dashboard"])
|
||||
(page-contents request))
|
||||
"Dashboard"))
|
||||
|
||||
(def key->handler
|
||||
( apply-middleware-to-all-handlers
|
||||
{::d-routes/page page}
|
||||
(fn [h]
|
||||
(wrap-client-redirect-unauthenticated (wrap-admin h)))))
|
||||
3
src/cljc/auto_ap/routes/dashboard.cljc
Normal file
3
src/cljc/auto_ap/routes/dashboard.cljc
Normal file
@@ -0,0 +1,3 @@
|
||||
(ns auto-ap.routes.dashboard)
|
||||
(def routes {""
|
||||
{:get ::page }})
|
||||
@@ -6,6 +6,7 @@
|
||||
[auto-ap.routes.admin.vendors :as v-routes]
|
||||
[auto-ap.routes.outgoing-invoice :as oi-routes]
|
||||
[auto-ap.routes.payments :as p-routes]
|
||||
[auto-ap.routes.dashboard :as d-routes]
|
||||
[auto-ap.routes.invoice :as i-routes]
|
||||
[auto-ap.routes.admin.clients :as ac-routes]
|
||||
[auto-ap.routes.admin.sales-summaries :as ss-routes]
|
||||
@@ -16,6 +17,7 @@
|
||||
"search" :search
|
||||
"indicators" indicator-routes/routes
|
||||
|
||||
"dashboard" {:get ::d-routes/page}
|
||||
"account" {"/search" {:get :account-search}}
|
||||
"admin" {"" :auto-ap.routes.admin/page
|
||||
"/client" ac-routes/routes
|
||||
|
||||
Reference in New Issue
Block a user