Files
integreat/src/clj/auto_ap/ssr/company/yodlee.clj
2024-03-20 14:48:44 -07:00

214 lines
9.7 KiB
Clojure

(ns auto-ap.ssr.company.yodlee
(:require [auto-ap.datomic
:refer [add-sorter-fields apply-pagination apply-sort-3 conn merge-query
pull-attr pull-many query2]]
[auto-ap.graphql.utils :refer [assert-can-see-client is-admin?]]
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com]
[auto-ap.ssr.grid-page-helper :as helper]
[auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils :refer [html-response modal-response]]
[auto-ap.time :as atime]
[auto-ap.yodlee.core2 :as yodlee]
[bidi.bidi :as bidi]
[config.core :refer [env]]
[datomic.api :as dc]
[hiccup2.core :as hiccup]))
(def default-read '[:db/id
[:yodlee-provider-account/last-updated :xform clj-time.coerce/from-date]
:yodlee-provider-account/status
:yodlee-provider-account/id
:yodlee-provider-account/detailed-status
{:yodlee-provider-account/accounts [:yodlee-account/name :yodlee-account/number]
:yodlee-provider-account/client [:client/code]}])
(defn fetch-ids [db request]
(let [query-params (:parsed-query-params request)]
(->> (cond-> {:query {:find []
:in ['$ '[?xx ...]]
:where ['[?e :yodlee-provider-account/id]
'[?e :yodlee-provider-account/client ?xx]]}
:args [db (:trimmed-clients request)]}
(:sort query-params) (add-sorter-fields {"status" ['[?e :yodlee-provider-account/status ?sort-status]]
"last-updated" ['[?e :yodlee-provider-account/last-updated ?sort-last-updated]]}
query-params)
true
(merge-query {:query {:find ['?e ]
:where ['[?e :yodlee-provider-account/id]]}}))
(query2)
(apply-sort-3 query-params)
(apply-pagination query-params))))
(defn hydrate-results [ids db _]
(let [results (->> (pull-many db default-read ids)
(group-by :db/id))]
(->> ids
(map results)
(map first))))
(defn fetch-page [request]
(let [db (dc/db conn)
{ids-to-retrieve :ids matching-count :count} (fetch-ids db request)]
[(->> (hydrate-results ids-to-retrieve db request))
matching-count]))
(defn fastlink-dialog [{:keys [client]}]
(modal-response
(com/modal
{}
(com/modal-card
{}
[:div.flex [:div.p-2 "Yodlee Fastlink"] ]
[:div
[:div#fa-spot]
[:script {:lang "text/javascript"}
(hiccup/raw
(format "
fastlink.open({fastLinkURL: '%s',
accessToken: '%s',
params: {'configName': 'Aggregation'},
onError: function(e) {
console.log(e);
htmx.trigger(\"#yodlee-table\", \"notification\", {value: \"Yodlee returned the following error: '\" + e.message + \"'.\\n\\nYou may want to refresh your browser and try again.\"});
setTimeout(hideModal, 300);
}},
'fa-spot');
" (:yodlee2-fastlink env) (yodlee/get-access-token (:client/code client))))]
]
[:div]))))
(defn reauthenticate [{:keys [form-params identity]}]
(assert-can-see-client identity (-> (dc/pull (dc/db conn) '[{:yodlee-provider-account/client [:db/id]}] (Long/parseLong (get form-params "id")))
:yodlee-provider-account/client
:db/id))
(html-response
(com/modal
{}
(com/modal-card
{}
[:div.flex [:div.p-2 "Yodlee Fastlink"] ]
[:div
[:div#fa-spot]
[:script {:lang "text/javascript"}
(hiccup/raw
(format "
fastlink.open({fastLinkURL: '%s',
accessToken: '%s',
params: {'configName': 'Aggregation',
'providerAccountId': %d,
'flow': 'edit'}},
'fa-spot');
"
(:yodlee2-fastlink env)
(yodlee/get-access-token (-> (dc/pull (dc/db conn)
[{:yodlee-provider-account/client [:client/code]}]
(Long/parseLong (get form-params "id")))
:yodlee-provider-account/client
:client/code))
(pull-attr (dc/db conn) :yodlee-provider-account/id (Long/parseLong (get form-params "id")))))]]
[:div]))))
(def grid-page
(helper/build
{:id "yodlee-table"
:nav com/company-aside-nav
:id-fn :db/id
:fetch-page fetch-page
:breadcrumbs [[:a {:href (bidi/path-for ssr-routes/only-routes
:company)}
"My Company"]
[:a {:href (bidi/path-for ssr-routes/only-routes
:company-yodlee)}
"Yodlee"]]
:title "Yodlee Accounts"
:entity-name "Yodlee accounts"
:route :company-yodlee-table
:action-buttons (fn [request]
[[:div.flex.flex-col.flex-shrink
[:div.flex-shrink
(com/button {:color :primary
:on-click "openFastlink()"
:disabled (if (:client request)
false
true)
:hx-get (bidi/path-for ssr-routes/only-routes
:company-yodlee-fastlink-dialog)
:hx-target "#modal-holder"}
(com/button-icon {} svg/refresh)
"Link new account")]
(when-not (:client request)
[:div.text-xs "Note: please select a specific customer to link a new account."])]])
:row-buttons (fn [request _]
[
(com/button {:hx-put (bidi/path-for ssr-routes/only-routes
:company-yodlee-provider-account-reauthenticate)
:color :primary
:hx-target "#modal-holder"}
"Reauthenticate")
(when (is-admin? (:identity request))
(com/icon-button {:hx-put (bidi/path-for ssr-routes/only-routes
:company-yodlee-provider-account-refresh)
:hx-target "closest tr"}
svg/refresh))])
:headers [{:key "client"
:name "Client"
:sort-key "client"
:hide? (fn [args]
(= (count (:clients args)) 1))
:render #(-> % :yodlee-provider-account/client :client/code)}
{:key "provider-account"
:name "Provider Account"
:sort-key "provider-account"
:render :yodlee-provider-account/id}
{:key "status"
:name "Status"
:sort-key "status"
:render #(when-let [status (:yodlee-provider-account/status %)]
(com/pill {:color (if (not= status "SUCCESS")
:yellow
:primary) }
status))}
{:key "detailed-status"
:name "Detailed Status"
:sort-key "detailed-status"
:render #(when-let [status (:yodlee-provider-account/detailed-status %)]
status)}
{:key "last-updated"
:name "Last Updated"
:sort-key "last-updated"
:render #(atime/unparse-local (:yodlee-provider-account/last-updated %)
atime/normal-date)}
{:key "accounts"
:name "Accounts"
:show-starting "md"
:render (fn [e]
[:ul
(for [a (:yodlee-provider-account/accounts e)]
[:li (:yodlee-account/name a) " - " (:yodlee-account/number a)])])}]}))
(def page (helper/page-route grid-page))
(def table (helper/table-route grid-page))
(defn refresh-provider-account [{:keys [form-params identity]}]
(let [provider-account (dc/pull (dc/db conn) default-read (some-> (get form-params "id") not-empty Long/parseLong))]
(yodlee/refresh-provider-account (:client/code (:yodlee-provider-account/client provider-account))
(:yodlee-provider-account/id provider-account))
(html-response
(helper/row*
grid-page
identity
provider-account
{:flash? true}))))