Makes integreat run on datomic cloud
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
(ns auto-ap.graphql.clients
|
||||
(:require
|
||||
[amazonica.aws.s3 :as s3]
|
||||
[auto-ap.datomic :refer [audit-transact conn remove-nils]]
|
||||
[auto-ap.datomic :refer [audit-transact conn upsert-entity random-tempid]]
|
||||
[auto-ap.datomic.clients :as d-clients]
|
||||
[auto-ap.square.core :as square]
|
||||
[auto-ap.graphql.utils
|
||||
:refer [->graphql assert-admin can-see-client? is-admin?]]
|
||||
[auto-ap.routes.queries :as q]
|
||||
[auto-ap.square.core :as square]
|
||||
[clj-time.coerce :as coerce]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as str]
|
||||
[clojure.tools.logging :as log]
|
||||
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
|
||||
[datomic.api :as d]
|
||||
[datomic.client.api :as dc]
|
||||
[unilog.context :as lc]
|
||||
[auto-ap.graphql.utils :refer [attach-tracing-resolvers]]
|
||||
[com.brunobonacci.mulog :as mu])
|
||||
@@ -22,10 +22,10 @@
|
||||
(org.apache.commons.codec.binary Base64)))
|
||||
|
||||
(defn assert-client-code-is-unique [code]
|
||||
(when (seq (d/query {:query {:find '[?id]
|
||||
:in ['$ '?code]
|
||||
:where ['[?id :client/code ?code]]}
|
||||
:args [(d/db conn) code]}))
|
||||
(when (seq (dc/q {:query {:find '[?id]
|
||||
:in ['$ '?code]
|
||||
:where ['[?id :client/code ?code]]}
|
||||
:args [(dc/db conn) code]}))
|
||||
(throw (ex-info "Client is not unique" {:validation-error (str "Client code '" code "' is not unique.")}))))
|
||||
|
||||
(defn upload-signature-data [signature-data]
|
||||
@@ -44,9 +44,9 @@
|
||||
(str "https://integreat-signature-images.s3.amazonaws.com/" signature-id ".jpg")))))
|
||||
|
||||
(defn assert-no-shared-transaction-sources [client-code txes]
|
||||
(let [new-db (:db-after (d/with (d/db conn)
|
||||
txes))]
|
||||
(when (seq (->> (d/q '[:find ?src (count ?ba)
|
||||
(let [new-db (:db-after (dc/with (dc/with-db conn)
|
||||
{:tx-data txes}))]
|
||||
(when (seq (->> (dc/q '[:find ?src (count ?ba)
|
||||
:in $ ?c
|
||||
:where [?c :client/bank-accounts ?ba]
|
||||
(or
|
||||
@@ -66,116 +66,84 @@
|
||||
(let [client (when (:id edit_client) (d-clients/get-by-id (:id edit_client)))
|
||||
id (or (:db/id client) "new-client")
|
||||
signature-file (upload-signature-data (:signature_data edit_client))
|
||||
_ (when client
|
||||
(audit-transact (-> []
|
||||
(into (mapv (fn [lm] [:db/retractEntity (:db/id lm)]) (:client/location-matches client)))
|
||||
(into (mapv (fn [m] [:db/retract (:db/id client) :client/matches m]) (:client/matches client)))
|
||||
(into (mapv (fn [m] [:db/retract (:db/id client) :client/feature-flags m]) (:client/feature-flags client))))
|
||||
(:id context)))
|
||||
reverts (-> []
|
||||
(into (->> (:bank_accounts edit_client)
|
||||
(filter #(nil? (:yodlee_account_id %)))
|
||||
(filter #(:bank-account/yodlee-account-id (d/entity (d/db conn) (:id %))))
|
||||
(map (fn [ba] [:db/retract (:id ba) :bank-account/yodlee-account-id (:bank-account/yodlee-account-id (d/entity (d/db conn) (:id ba)))]))))
|
||||
(into (->> (:bank_accounts edit_client)
|
||||
(filter #(nil? (:yodlee_account %)))
|
||||
(filter #(:bank-account/yodlee-account (d/entity (d/db conn) (:id %))))
|
||||
(map (fn [ba] [:db/retract (:id ba) :bank-account/yodlee-account (:db/id (:bank-account/yodlee-account (d/entity (d/db conn) (:id ba))))]))))
|
||||
(into (->> (:bank_accounts edit_client)
|
||||
(filter #(nil? (:intuit_bank_account %)))
|
||||
(filter #(:bank-account/intuit-bank-account (d/entity (d/db conn) (:id %))))
|
||||
(map (fn [ba] [:db/retract (:id ba) :bank-account/intuit-bank-account (:db/id (:bank-account/intuit-bank-account (d/entity (d/db conn) (:id ba))))]))))
|
||||
(into (->> (:bank_accounts edit_client)
|
||||
(filter #(nil? (:plaid_account %)))
|
||||
(filter #(:bank-account/plaid-account (d/entity (d/db conn) (:id %))))
|
||||
(map (fn [ba] [:db/retract (:id ba) :bank-account/plaid-account (:db/id (:bank-account/plaid-account (d/entity (d/db conn) (:id ba))))])))))
|
||||
|
||||
|
||||
client-code (if (str/blank? (:client/code client))
|
||||
(:code edit_client)
|
||||
(:client/code client))
|
||||
transactions (into [(remove-nils {:db/id id
|
||||
:client/code client-code
|
||||
:client/name (:name edit_client)
|
||||
:client/matches (:matches edit_client)
|
||||
:client/signature-file signature-file
|
||||
:client/email (:email edit_client)
|
||||
:client/locked-until (some-> (:locked_until edit_client) (coerce/to-date))
|
||||
:client/locations (filter identity (:locations edit_client))
|
||||
:client/week-a-debits (:week_a_debits edit_client)
|
||||
:client/week-a-credits (:week_a_credits edit_client)
|
||||
:client/week-b-debits (:week_b_debits edit_client)
|
||||
:client/square-auth-token (:square_auth_token edit_client)
|
||||
:client/square-locations (map
|
||||
(fn [sl]
|
||||
(remove-nils
|
||||
{:db/id (:id sl)
|
||||
:square-location/client-location (:client_location sl)}))
|
||||
(:square_locations edit_client))
|
||||
updated-entity {:db/id id
|
||||
:client/code client-code
|
||||
:client/name (:name edit_client)
|
||||
:client/matches (:matches edit_client)
|
||||
:client/signature-file signature-file
|
||||
:client/email (:email edit_client)
|
||||
:client/locked-until (some-> (:locked_until edit_client) (coerce/to-date))
|
||||
:client/locations (filter identity (:locations edit_client))
|
||||
:client/week-a-debits (:week_a_debits edit_client)
|
||||
:client/week-a-credits (:week_a_credits edit_client)
|
||||
:client/week-b-debits (:week_b_debits edit_client)
|
||||
:client/square-auth-token (:square_auth_token edit_client)
|
||||
:client/square-locations (map
|
||||
(fn [sl]
|
||||
{:db/id (or (:id sl) (random-tempid))
|
||||
:square-location/client-location (:client_location sl)})
|
||||
(:square_locations edit_client))
|
||||
|
||||
:client/ezcater-locations (map
|
||||
(fn [el]
|
||||
(remove-nils
|
||||
{:db/id (:id el)
|
||||
:ezcater-location/location (:location el)
|
||||
:ezcater-location/caterer (:caterer el)}))
|
||||
(:ezcater_locations edit_client))
|
||||
:client/week-b-credits (:week_b_credits edit_client)
|
||||
:client/location-matches (->> (:location_matches edit_client)
|
||||
(filter (fn [lm] (and (:location lm) (:match lm))))
|
||||
(map (fn [lm] {:location-match/location (:location lm)
|
||||
:location-match/matches [(:match lm)]})))
|
||||
:client/address (remove-nils {
|
||||
:address/street1 (:street1 (:address edit_client))
|
||||
:address/street2 (:street2 (:address edit_client))
|
||||
:address/city (:city (:address edit_client))
|
||||
:address/state (:state (:address edit_client))
|
||||
:address/zip (:zip (:address edit_client))})
|
||||
:client/feature-flags (:feature_flags edit_client)
|
||||
:client/bank-accounts (map #(remove-nils
|
||||
(cond-> {:db/id (:id %)
|
||||
:bank-account/code (:code %)
|
||||
:bank-account/bank-name (:bank_name %)
|
||||
:bank-account/bank-code (:bank_code %)
|
||||
:bank-account/start-date (-> (:start_date %) (coerce/to-date))
|
||||
:bank-account/routing (:routing %)
|
||||
:bank-account/include-in-reports (:include_in_reports %)
|
||||
:client/emails (map (fn [e]
|
||||
{:db/id (or (:id e)
|
||||
(random-tempid))
|
||||
:email-contact/email (:email e)
|
||||
:email-contact/description (:description e)})
|
||||
(:emails edit_client))
|
||||
|
||||
:bank-account/name (:name %)
|
||||
:bank-account/visible (:visible %)
|
||||
:bank-account/number (:number %)
|
||||
:bank-account/check-number (:check_number %)
|
||||
:bank-account/numeric-code (:numeric_code %)
|
||||
:bank-account/sort-order (:sort_order %)
|
||||
:bank-account/locations (:locations %)
|
||||
:bank-account/use-date-instead-of-post-date? (boolean (:use_date_instead_of_post_date %))
|
||||
:client/feature-flags (:feature_flags edit_client)
|
||||
:client/ezcater-locations (map
|
||||
(fn [el]
|
||||
{:db/id (or (:id el) (random-tempid))
|
||||
:ezcater-location/location (:location el)
|
||||
:ezcater-location/caterer (:caterer el)})
|
||||
(:ezcater_locations edit_client))
|
||||
:client/week-b-credits (:week_b_credits edit_client)
|
||||
:client/location-matches (->> (:location_matches edit_client)
|
||||
(filter (fn [lm] (and (:location lm) (:match lm))))
|
||||
(map (fn [lm] {:db/id (or (:id lm ) (random-tempid))
|
||||
:location-match/location (:location lm)
|
||||
:location-match/matches [(:match lm)]})))
|
||||
:client/address {:db/id (or (:id (:address edit_client)) (random-tempid))
|
||||
:address/street1 (:street1 (:address edit_client))
|
||||
:address/street2 (:street2 (:address edit_client))
|
||||
:address/city (:city (:address edit_client))
|
||||
:address/state (:state (:address edit_client))
|
||||
:address/zip (:zip (:address edit_client))}
|
||||
:client/bank-accounts (map (fn [ba]
|
||||
{:db/id (:id ba)
|
||||
:bank-account/code (:code ba)
|
||||
:bank-account/bank-name (:bank_name ba)
|
||||
:bank-account/bank-code (:bank_code ba)
|
||||
:bank-account/start-date (-> (:start_date ba) (coerce/to-date))
|
||||
:bank-account/routing (:routing ba)
|
||||
:bank-account/include-in-reports (:include_in_reports ba)
|
||||
|
||||
:bank-account/yodlee-account-id (:yodlee_account_id %)
|
||||
:bank-account/type (keyword "bank-account-type" (name (:type %)))}
|
||||
(:yodlee_account %) (assoc :bank-account/yodlee-account [:yodlee-account/id (:yodlee_account %)])
|
||||
(:plaid_account %) (assoc :bank-account/plaid-account (:plaid_account %))
|
||||
(:intuit_bank_account %) (assoc :bank-account/intuit-bank-account (:intuit_bank_account %))))
|
||||
(:bank_accounts edit_client))
|
||||
:bank-account/name (:name ba)
|
||||
:bank-account/visible (:visible ba)
|
||||
:bank-account/number (:number ba)
|
||||
:bank-account/check-number (:check_number ba)
|
||||
:bank-account/numeric-code (:numeric_code ba)
|
||||
:bank-account/sort-order (:sort_order ba)
|
||||
:bank-account/locations (:locations ba)
|
||||
:bank-account/use-date-instead-of-post-date? (boolean (:use_date_instead_of_post_date ba))
|
||||
|
||||
})
|
||||
|
||||
[:reset id :client/emails (map #(remove-nils
|
||||
{:db/id (or (:id %)
|
||||
(str (UUID/randomUUID)))
|
||||
:email-contact/email (:email %)
|
||||
:email-contact/description (:description %)})
|
||||
(:emails edit_client))]
|
||||
[:reset id :client/forecasted-transactions (map #(remove-nils
|
||||
{:db/id (:id %)
|
||||
:forecasted-transaction/day-of-month (:day_of_month %)
|
||||
:forecasted-transaction/identifier (:identifier %)
|
||||
:forecasted-transaction/amount (:amount %)}
|
||||
)
|
||||
(:forecasted_transactions edit_client))]]
|
||||
reverts)
|
||||
_ (assert-no-shared-transaction-sources client-code transactions)
|
||||
_ (log/info "upserting client" transactions)
|
||||
result (audit-transact transactions (:id context))]
|
||||
:bank-account/yodlee-account-id (:yodlee_account_id ba)
|
||||
:bank-account/type (keyword "bank-account-type" (name (:type ba)))
|
||||
:bank-account/yodlee-account (when (:yodlee_account ba)
|
||||
[:yodlee-account/id (:yodlee_account ba)])
|
||||
:bank-account/plaid-account (:plaid_account ba)
|
||||
:bank-account/intuit-bank-account (:intuit_bank_account ba)})
|
||||
(:bank_accounts edit_client))
|
||||
|
||||
}
|
||||
_ (assert-no-shared-transaction-sources client-code [`(upsert-entity ~updated-entity)])
|
||||
_ (log/info "upserting client" updated-entity)
|
||||
|
||||
result (audit-transact [`(upsert-entity ~updated-entity)] (:id context))]
|
||||
(when (:square_auth_token edit_client)
|
||||
(square/upsert-locations (-> result :tempids (get id) (or id) d-clients/get-by-id)))
|
||||
(-> (-> result :tempids (get id) (or id) d-clients/get-by-id)
|
||||
@@ -194,13 +162,13 @@
|
||||
->graphql)))
|
||||
|
||||
(defn refresh-bank-account-current-balance [bank-account-id]
|
||||
(let [all-transactions (d/query
|
||||
(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 [(d/db conn) bank-account-id]})
|
||||
:args [(dc/db conn) bank-account-id]})
|
||||
debits (->> all-transactions
|
||||
(map (fn [[_ debit _]]
|
||||
debit))
|
||||
@@ -209,46 +177,45 @@
|
||||
(map (fn [[_ _ credit]]
|
||||
credit))
|
||||
(reduce + 0.0))
|
||||
current-balance (if (= :bank-account-type/check (:bank-account/type (d/entity (d/db conn) bank-account-id)))
|
||||
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))]
|
||||
@(d/transact conn [{:db/id bank-account-id
|
||||
:bank-account/current-balance current-balance}])))
|
||||
(dc/transact conn {:tx-data [{:db/id bank-account-id
|
||||
:bank-account/current-balance current-balance}]})))
|
||||
|
||||
(defn bank-accounts-needing-refresh []
|
||||
(let [last-refreshed (->> (d/query
|
||||
{:query {:find ['?ba '?tx]
|
||||
(let [last-refreshed (->> (dc/q {:query {:find ['?ba '?tx]
|
||||
:in ['$ ]
|
||||
:where ['[?ba :bank-account/current-balance _ ?tx true]]}
|
||||
:args [(d/history (d/db conn))]})
|
||||
: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 (->> (d/query
|
||||
has-newer-transaction (->> (dc/q
|
||||
{:query {:find ['?ba]
|
||||
:in '[$ [[?ba ?last-refreshed] ...] ]
|
||||
:where ['[_ :journal-entry-line/account ?ba ?tx]
|
||||
'[(>= ?tx ?last-refreshed)]]}
|
||||
:args [(d/history (d/db conn))
|
||||
:args [(dc/history (dc/db conn))
|
||||
last-refreshed]})
|
||||
(map first)
|
||||
(set))
|
||||
|
||||
no-current-balance (->> (d/query {:query {:find ['?ba]
|
||||
no-current-balance (->> (dc/q {:query {:find ['?ba]
|
||||
:in '[$]
|
||||
:where ['[?ba :bank-account/code]
|
||||
'(not [?ba :bank-account/current-balance])
|
||||
]}
|
||||
:args [(d/db conn)]})
|
||||
: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" (-> (d/db conn) (d/entity bank-account) :bank-account/code))
|
||||
(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
|
||||
@@ -257,10 +224,10 @@
|
||||
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||
(defn refresh-all-current-balance []
|
||||
(lc/with-context {:source "current-balance-cache"}
|
||||
(build-current-balance (->> (d/query {:query {:find ['?ba]
|
||||
:in '[$]
|
||||
:where ['[?ba :bank-account/code]]}
|
||||
:args [(d/db conn)]})
|
||||
(build-current-balance (->> (dc/q {:query {:find ['?ba]
|
||||
:in '[$]
|
||||
:where ['[?ba :bank-account/code]]}
|
||||
:args [(dc/db conn)]})
|
||||
(map first)))))
|
||||
|
||||
(defn refresh-current-balance []
|
||||
@@ -410,8 +377,8 @@
|
||||
|
||||
(defn setup-sales-queries [context args _]
|
||||
(assert-admin (:id context))
|
||||
(let [{client-code :client/code feature-flags :client/feature-flags} (d/pull (d/db conn) '[:client/code :client/feature-flags] (:client_id args))
|
||||
is-new-square? ((set feature-flags) "new-square")]
|
||||
(let [{client-code :client/code feature-flags :client/feature-flags} (dc/pull (dc/db conn) '[:client/code :client/feature-flags] (:client_id args))
|
||||
is-new-square? ((set feature-flags) "new-square")]
|
||||
(q/put-query (str (UUID/randomUUID))
|
||||
(format sales-summary-query client-code)
|
||||
(str "sales query for " client-code)
|
||||
@@ -442,12 +409,11 @@
|
||||
(str "refunds query for " client-code)
|
||||
(str client-code "-refund")
|
||||
[:client/code client-code])
|
||||
|
||||
(let [sales-summary-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-sales-summary")]))
|
||||
sales-category-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-sales-category")]))
|
||||
expected-deposit-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-expected-deposit")]))
|
||||
tender-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-tender")]))
|
||||
refund-id (:saved-query/guid (d/pull (d/db auto-ap.datomic/conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-refund")]))]
|
||||
(let [sales-summary-id (:saved-query/guid (dc/pull (dc/db conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-sales-summary")]))
|
||||
sales-category-id (:saved-query/guid (dc/pull (dc/db conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-sales-category")]))
|
||||
expected-deposit-id (:saved-query/guid (dc/pull (dc/db conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-expected-deposit")]))
|
||||
tender-id (:saved-query/guid (dc/pull (dc/db conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-tender")]))
|
||||
refund-id (:saved-query/guid (dc/pull (dc/db conn) [:saved-query/guid] [:saved-query/lookup-key (str client-code "-refund")]))]
|
||||
{:message (str/join "\n"
|
||||
[
|
||||
(str "For " client-code ":")
|
||||
|
||||
Reference in New Issue
Block a user