diff --git a/src/clj/auto_ap/routes/yodlee.clj b/src/clj/auto_ap/routes/yodlee.clj index 3e2621ef..72a4b80c 100644 --- a/src/clj/auto_ap/routes/yodlee.clj +++ b/src/clj/auto_ap/routes/yodlee.clj @@ -35,5 +35,11 @@ (let [[session token] (yodlee/get-access-token)] {:status 200 :headers {"Content-Type" "application/edn"} - :body (pr-str (yodlee/get-accounts)) }))) + :body (pr-str (yodlee/get-accounts)) })) + (POST "/accounts/:id" {:keys [query-params identity] {:keys [id]} :route-params :as request} + (assert-admin identity) + (let [[session token] (yodlee/get-access-token)] + {:status 200 + :headers {"Content-Type" "application/edn"} + :body (pr-str (yodlee/update-yodlee (Long/parseLong id))) }))) wrap-secure)) diff --git a/src/clj/auto_ap/yodlee/core.clj b/src/clj/auto_ap/yodlee/core.clj index 225bc415..6c147577 100644 --- a/src/clj/auto_ap/yodlee/core.clj +++ b/src/clj/auto_ap/yodlee/core.clj @@ -92,18 +92,33 @@ (defn get-provider-accounts [] (let [cob-session (login-cobrand) user-session (login-user cob-session) - batch-size 100 - get-transaction-batch (fn [] - (-> (str (:yodlee-base-url env) "/providerAccounts") + batch-size 100] - (client/get {:headers (doto - (merge base-headers {"Authorization" (auth-header cob-session user-session)}) - println) - :as :json}) - :body - ))] + (-> (str (:yodlee-base-url env) "/providerAccounts") - (get-transaction-batch))) + (client/get {:headers (doto + (merge base-headers {"Authorization" (auth-header cob-session user-session)}) + println) + :as :json}) + :body + :providerAccount + ))) + + + +(defn get-provider-account [id] + (let [cob-session (login-cobrand) + user-session (login-user cob-session) + batch-size 100] + + (-> (str (:yodlee-base-url env) "/providerAccounts/" id) + + (client/get {:headers (doto + (merge base-headers {"Authorization" (auth-header cob-session user-session)}) + println) + :as :json}) + :body + :providerAccount))) (defn update-provider-account [pa] (let [cob-session (login-cobrand) @@ -118,12 +133,16 @@ :body "{\"dataSetName\": [\"BASIC_AGG_DATA\"]}" :as :json})))) -(defn get-specific-transactions [] +(defn update-yodlee [id] + (update-provider-account (:providerAccountId (first (filter #(= (:id %) id) (get-accounts))))) + (get-provider-account (:providerAccountId (first (filter #(= (:id %) id) (get-accounts)))))) + +(defn get-specific-transactions [account] (let [cob-session (login-cobrand) user-session (login-user cob-session) batch-size 100 get-transaction-batch (fn [skip] - (-> (str (:yodlee-base-url env) "/transactions?top=" batch-size "&skip=" skip "&accountId=16422358") + (-> (str (:yodlee-base-url env) "/transactions?top=" batch-size "&skip=" skip "&accountId=" account) (doto println) (client/get {:headers (doto diff --git a/src/cljc/auto_ap/entities/shared.cljc b/src/cljc/auto_ap/entities/shared.cljc index d83cea24..b2363b46 100644 --- a/src/cljc/auto_ap/entities/shared.cljc +++ b/src/cljc/auto_ap/entities/shared.cljc @@ -3,7 +3,7 @@ [clojure.string :as str])) (def date-regex #"[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}") -(def money-regex #"[0-9]+(\.[0-9]{1,2})?$") +(def money-regex #"\-?[0-9]+(\.[0-9]{1,2})?$") (s/def ::identifier (s/nilable string?)) (s/def ::date (s/and string? #(re-matches date-regex %))) diff --git a/src/cljc/auto_ap/entities/vendors.cljc b/src/cljc/auto_ap/entities/vendors.cljc index b0805117..bacdc4ab 100644 --- a/src/cljc/auto_ap/entities/vendors.cljc +++ b/src/cljc/auto_ap/entities/vendors.cljc @@ -5,8 +5,7 @@ (def email-regex #"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$") (s/def ::id int) -(s/def ::identifier (s/nilable string?)) -(s/def ::required-identifier (s/and string? +(s/def ::identifier (s/nilable string?)) (s/def ::required-identifier (s/and string? #(not (str/blank? %)))) (s/def ::name ::required-identifier) @@ -17,14 +16,14 @@ (s/def ::phone (s/nilable string?)) (s/def ::invoice-reminder-schedule (s/nilable #{"Weekly" "Never" nil})) -(s/def ::primary-contact ::identifier) -(s/def ::primary-email ::email) -(s/def ::primary-phone ::phone) +(s/def ::primary-contact (s/nilable ::identifier)) +(s/def ::primary-email (s/nilable ::email)) +(s/def ::primary-phone (s/nilable ::phone)) -(s/def ::secondary-contact ::identifier) -(s/def ::secondary-email ::email) -(s/def ::secondary-phone ::phone) -(s/def ::address ::address/address) +(s/def ::secondary-contact (s/nilable ::identifier)) +(s/def ::secondary-email (s/nilable ::email)) +(s/def ::secondary-phone (s/nilable ::phone)) +(s/def ::address (s/nilable ::address/address)) (s/def ::default-expense-account int?) (s/def ::code (s/nilable string?)) diff --git a/src/cljs/auto_ap/views/components/vendor_dialog.cljs b/src/cljs/auto_ap/views/components/vendor_dialog.cljs index 4f945896..b77303f5 100644 --- a/src/cljs/auto_ap/views/components/vendor_dialog.cljs +++ b/src/cljs/auto_ap/views/components/vendor_dialog.cljs @@ -11,6 +11,7 @@ [auto-ap.subs :as subs])) (defn vendor-dialog [{:keys [vendor save-event change-event id] {:keys [name]} :vendor}] + (let [companies-by-id @(re-frame/subscribe [::subs/companies-by-id])] [action-modal {:id id :title [:span (if (:id vendor) @@ -23,7 +24,7 @@ :save-event save-event :can-submit? (s/valid? ::entity/vendor vendor)} - (doto (s/explain ::entity/vendor vendor) println) + [horizontal-field [:label.label "Name"] diff --git a/src/cljs/auto_ap/views/pages/admin/yodlee.cljs b/src/cljs/auto_ap/views/pages/admin/yodlee.cljs index 5cc5e558..361859f2 100644 --- a/src/cljs/auto_ap/views/pages/admin/yodlee.cljs +++ b/src/cljs/auto_ap/views/pages/admin/yodlee.cljs @@ -2,6 +2,7 @@ (:require-macros [cljs.core.async.macros :refer [go]]) (:require [re-frame.core :as re-frame] [reagent.core :as reagent] + [clojure.string :as str] [auto-ap.subs :as subs] [auto-ap.events.admin.companies :as events] [auto-ap.entities.companies :as entity] @@ -56,6 +57,28 @@ :on-success [::got-accounts] :on-error [::save-error]}})) +(re-frame/reg-event-fx + ::kicked + (fn [{:keys [db]} [_ id state]] + {:db (update-in db [::yodlee :accounts] + (fn [as] + (map (fn [a] + (if (= (:id a) id) + (assoc a :status state) + a)) + as)))})) + + +(re-frame/reg-event-fx + ::kick + (fn [{:keys [db]} [_ id]] + {:http {:token (:user db) + :method :post + :headers {"Content-Type" "application/edn"} + :uri (str "/api/yodlee/accounts/" id) + :on-success [::kicked id :kicking] + :on-error [::kicked id :errored]}})) + (re-frame/reg-event-fx ::got-accounts (fn [{:keys [db]} [_ accounts]] @@ -106,15 +129,30 @@ [:tr [:th "Account Name"] [:th "Account Number"] - [:th "Yodlee Account Number"]]] + [:th "Yodlee Account Number"] + [:th "Yodlee Last updated"] + [:th "Yodlee Status"] + [:th]]] + (if @(re-frame/subscribe [::accounts-loading?]) - [:tr [:td {:col-span "3"} "Loading..."] + [:tr [:td {:col-span "6"} "Loading..."] ] (for [account @(re-frame/subscribe [::accounts])] [:tr [:td (:accountName account)] [:td (:accountNumber account)] - [:td (:id account)]]))]]) + [:td (:id account)] + [:td (str/join ", " (map :lastUpdated (:dataset account)))] + [:td (str/join ", " (map :additionalStatus (:dataset account)))] + [:td + (cond (= (:status account) :kicking) + [:button.button.is-success.is-loading {:disabled "disabled"} "Kick."] + + (= (:status account) :error) + [:button.button.is-error.is-loading {:disabled "disabled"} "Error."] + + :else + [:button.button.is-success {:on-click (dispatch-event [::kick (:id account)] )} "Kick." ])]]))]]) (defn admin-yodlee-page []