- Add vendor-changed HTMX handlers for both bulk code and individual edit - Pre-populate default account at 100% when vendor is selected and no accounts exist - Fix render-accounts-section to render from step-params correctly - Change bulk code vendor-changed from hx-get to hx-post to include form data - Add routes for vendor-changed endpoints - Update e2e tests to cover vendor pre-population - Run lein cljfmt fix across codebase
138 lines
6.0 KiB
Clojure
138 lines
6.0 KiB
Clojure
(ns auto-ap.plaid.core
|
|
(:require [auto-ap.logging :as alog]
|
|
[auto-ap.time :as atime]
|
|
[cemerick.url :as url]
|
|
[clj-http.client :as client]
|
|
[clojure.data.json :as json]
|
|
[config.core :as cfg :refer [env]]
|
|
[slingshot.slingshot :refer [try+]]))
|
|
|
|
(def base-url (-> env :plaid :base-url))
|
|
|
|
(def client-id (-> env :plaid :client-id))
|
|
(def secret-key (-> env :plaid :secret-key))
|
|
|
|
(defn get-link-token [client-code]
|
|
(-> (client/post (str base-url "/link/token/create")
|
|
{:as :json
|
|
:headers {"Content-Type" "application/json"}
|
|
:body (json/write-str {"client_id" client-id
|
|
"secret" secret-key
|
|
"client_name" "Integreat Consulting"
|
|
"country_codes" ["US"]
|
|
"language" "en"
|
|
"user" {"client_user_id" client-code}
|
|
"products" ["transactions"]})})
|
|
:body
|
|
:link_token))
|
|
|
|
(defn get-relink-token [client-code access-token]
|
|
(-> (client/post (str base-url "/link/token/create")
|
|
{:as :json
|
|
:headers {"Content-Type" "application/json"}
|
|
:body (json/write-str {"client_id" client-id
|
|
"secret" secret-key
|
|
"client_name" "Integreat Consulting"
|
|
"access_token" access-token
|
|
"country_codes" ["US"]
|
|
"language" "en"
|
|
"user" {"client_user_id" client-code}})})
|
|
:body
|
|
:link_token))
|
|
|
|
(defn exchange-public-token [public-token _]
|
|
(-> (client/post (str base-url "/item/public_token/exchange")
|
|
{:as :json
|
|
:headers {"Content-Type" "application/json"}
|
|
:body (json/write-str {"client_id" client-id
|
|
"secret" secret-key
|
|
"public_token" public-token})})
|
|
:body))
|
|
|
|
(defn get-item [access-token]
|
|
(try+
|
|
(-> (client/post (str base-url "/item/get")
|
|
{:as :json
|
|
:headers {"Content-Type" "application/json"}
|
|
:body (json/write-str {"client_id" client-id
|
|
"secret" secret-key
|
|
"access_token" access-token})})
|
|
:body)
|
|
(catch [:status 400] x
|
|
(let [json (try (json/read-str (:body x)) (catch Exception _
|
|
{}))]
|
|
(throw (ex-info
|
|
(or (get json "error_message")
|
|
(get json "display_message")
|
|
(.getMessage (:throwable &throw-context)))
|
|
json))))))
|
|
|
|
(defn get-accounts [access-token]
|
|
(try+
|
|
(-> (client/post (str base-url "/accounts/get")
|
|
{:as :json
|
|
:headers {"Content-Type" "application/json"}
|
|
:body (json/write-str {"client_id" client-id
|
|
"secret" secret-key
|
|
"access_token" access-token})})
|
|
:body)
|
|
(catch [:status 400] x
|
|
(let [json (try (json/read-str (:body x)) (catch Exception _
|
|
{}))]
|
|
(throw (ex-info
|
|
(or (get json "error_message")
|
|
(get json "display_message")
|
|
(.getMessage (:throwable &throw-context)))
|
|
json))))))
|
|
|
|
(defn get-balance [access-token]
|
|
(-> (client/post (str base-url "/accounts/balance/get")
|
|
{:as :json
|
|
:headers {"Content-Type" "application/json"}
|
|
:body (json/write-str {"access_token" access-token
|
|
"secret" secret-key
|
|
"client_id" client-id})})
|
|
:body))
|
|
|
|
(defn get-transactions [access-token account-id start end]
|
|
(alog/info ::searching
|
|
:start (str start)
|
|
:end (str end)
|
|
:acct (str account-id))
|
|
|
|
(try+
|
|
(-> (client/post (str base-url "/transactions/get")
|
|
{:as :json
|
|
:headers {"Content-Type" "application/json"}
|
|
:body (json/write-str {"client_id" client-id
|
|
"secret" secret-key
|
|
"access_token" access-token
|
|
"start_date" (atime/unparse start atime/iso-date)
|
|
"end_date" (atime/unparse end atime/iso-date)
|
|
"options" {"account_ids" [account-id]
|
|
"count" 500}})})
|
|
:body)
|
|
(catch [:status 400] x
|
|
(let [json (try (json/read-str (:body x)) (catch Exception _
|
|
{}))]
|
|
(throw (ex-info
|
|
(or (get json "error_message")
|
|
(get json "display_message")
|
|
(.getMessage (:throwable &throw-context)))
|
|
json))))))
|
|
|
|
(comment
|
|
(require '[datomic.api :as dc])
|
|
|
|
(require '[auto-ap.datomic :refer [conn]])
|
|
|
|
(doto (dc/q '[:find (pull ?ba [{:bank-account/plaid-account [* {:plaid-item/_accounts [*]}]}])
|
|
:in $ ?ba]
|
|
(dc/db conn)
|
|
[:bank-account/code "NGHW-CB5029"])
|
|
clojure.pprint/pprint)
|
|
(require 'auto-ap.time-reader)
|
|
|
|
(clojure.pprint/pprint
|
|
(get-transactions "access-production-c0e322fa-f33d-4806-bc42-5fc883fb1ba4" "VZ8Y1azZMdhoYo9MQABrfpgz4jm4kPtakyxN5" #clj-time/date-time "2024-03-15" #clj-time/date-time "2024-03-30"))
|
|
(clojure.pprint/pprint (get-accounts "access-production-c0e322fa-f33d-4806-bc42-5fc883fb1ba4"))) |