From a5d05791640a357b8ebc1c4573b5197aba899670 Mon Sep 17 00:00:00 2001 From: BC Date: Mon, 18 Feb 2019 08:25:23 -0800 Subject: [PATCH] pretty good progress in being able to add/edit all bank accounts. --- src/clj/auto_ap/graphql.clj | 2 +- src/clj/auto_ap/graphql/clients.clj | 2 +- src/cljc/auto_ap/entities/clients.cljc | 2 +- .../auto_ap/views/pages/admin/clients.cljs | 330 ++++++++++-------- 4 files changed, 189 insertions(+), 147 deletions(-) diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index ca540a41..c8e05c92 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -54,7 +54,7 @@ :bank_account {:fields {:id {:type :id } - :type {:type :bank_account_type} + :type {:type :ident} :number {:type 'String} :routing {:type 'String} :code {:type 'String} diff --git a/src/clj/auto_ap/graphql/clients.clj b/src/clj/auto_ap/graphql/clients.clj index 47f5f7e8..b10cc038 100644 --- a/src/clj/auto_ap/graphql/clients.clj +++ b/src/clj/auto_ap/graphql/clients.clj @@ -50,7 +50,7 @@ :bank-account/check-number (:check_number %) :bank-account/yodlee-account-id (:yodlee_account_id %) - :bank-account/type :bank-account-type/check + :bank-account/type (keyword "bank-account-type" (name (:type %))) } ) (:bank_accounts edit_client)) diff --git a/src/cljc/auto_ap/entities/clients.cljc b/src/cljc/auto_ap/entities/clients.cljc index b7e49b19..d39b49f2 100644 --- a/src/cljc/auto_ap/entities/clients.cljc +++ b/src/cljc/auto_ap/entities/clients.cljc @@ -22,7 +22,7 @@ (s/def ::checking-bank-account (s/and (s/keys :req-un [::code ::name ::bank-name ::bank-code ::routing ::number ::type]) #(= (:type %) :check))) -(s/def ::cash-account (s/and (s/keys :req-un [::type]) +(s/def ::cash-account (s/and (s/keys :req-un [::type ::code ::name]) #(= (:type %) :cash))) (s/def ::bank-account (s/or :cash ::cash-account :checking ::checking-bank-account)) (s/def ::bank-accounts (s/coll-of ::bank-account)) diff --git a/src/cljs/auto_ap/views/pages/admin/clients.cljs b/src/cljs/auto_ap/views/pages/admin/clients.cljs index 187dccd2..60f6fd6f 100644 --- a/src/cljs/auto_ap/views/pages/admin/clients.cljs +++ b/src/cljs/auto_ap/views/pages/admin/clients.cljs @@ -61,6 +61,33 @@ (start-form ::new-client (assoc (get (:clients db) client-id) :new-account {:type :check})) (assoc-in [:admin :adding-client? ] true))})) +(re-frame/reg-sub + ::new-client-request + :<- [::form ::new-client] + (fn [{new-client-data :data} _] + {:id (:id new-client-data), + :name (:name new-client-data) + :code (:code new-client-data) ;; TODO add validation can't change + :email (:email new-client-data) + :locations (:locations new-client-data) + :address {:street1 (:street1 (:address new-client-data)) + :street2 (:street2 (:address new-client-data)), + :city (:city (:address new-client-data)) + :state (:state (:address new-client-data)) + :zip (:zip (:address new-client-data))} + :bank-accounts (map (fn [{:keys [number name check-number type id code bank-name routing bank-code new?]}] + {:number number + :name name + :check-number check-number + :type type + :id id + :code (if new? + (str (:code new-client-data) "-" code) + code) + :bank-name bank-name + :routing routing + :bank-code bank-code}) + (:bank-accounts new-client-data))})) (re-frame/reg-event-fx @@ -68,27 +95,7 @@ [(re-frame/path [::forms ::new-client])] (fn [{{new-client-data :data :as new-client-form} :db} _] - (let [new-client-req {:id (:id new-client-data), - :name (:name new-client-data) - :code (:code new-client-data) ;; TODO add validation can't change - :email (:email new-client-data) - :locations (:locations new-client-data) - :address {:street1 (:street1 (:address new-client-data)) - :street2 (:street2 (:address new-client-data)), - :city (:city (:address new-client-data)) - :state (:state (:address new-client-data)) - :zip (:zip (:address new-client-data))} - :bank-accounts (map (fn [{:keys [number name check-number type id code bank-name routing bank-code]}] - {:number number - :name name - :check-number check-number - :type type - :id id - :code (str (:code new-client-data) "-" code) - :bank-name bank-name - :routing routing - :bank-code bank-code}) - (:bank-accounts new-client-data))} + (let [new-client-req @(re-frame/subscribe [::new-client-request]) user @(re-frame/subscribe [::subs/token])] (if (s/valid? ::entity/client new-client-req) @@ -102,7 +109,7 @@ :operation/name "EditClient"} :venia/queries [{:query/data [:edit-client {:edit-client new-client-req} - [:id :name :code :email :locations [:address [:street1 :street2 :city :state :zip]] [:bank-accounts [:id :number :check-number :name :code :bank-code :bank-name :routing]]]]}]} + [:id :name :code :email :locations [:address [:street1 :street2 :city :state :zip]] [:bank-accounts [:id :number :check-number :name :code :bank-code :bank-name :routing :type]]]]}]} :on-success [::save-complete] :on-error [::save-error]}} {:db new-client-form})))) @@ -138,10 +145,28 @@ (update :locations conj (:location client)) (dissoc :location)))) - (re-frame/reg-event-db ::add-new-bank-account [(re-frame/path [::forms ::new-client :data])] + (fn [client [_ type]] + (update client :bank-accounts conj {:type type :active? true :new? true}))) + +(re-frame/reg-event-db + ::bank-account-activated + [(re-frame/path [::forms ::new-client :data :bank-accounts])] + (fn [bank-accounts [_ index]] + (update bank-accounts index assoc :active? true))) + +(re-frame/reg-event-db + ::bank-account-deactivated + [(re-frame/path [::forms ::new-client :data :bank-accounts])] + (fn [bank-accounts [_ index]] + (update bank-accounts index assoc :active? false))) + + +(re-frame/reg-event-db + ::save-new-bank-account + [(re-frame/path [::forms ::new-client :data])] (fn [{:keys [new-account] :as client} _] (let [new-account (-> new-account (update :check-number #(if (seq %) (js/parseInt %) nil)) @@ -155,10 +180,12 @@ (assoc :new-account {:type :check})))))) (re-frame/reg-event-db - ::remove-new-bank-account - [(re-frame/path [::forms ::new-client :data])] - (fn [db [_ code]] - (update db :bank-accounts + ::bank-account-removed + [(re-frame/path [::forms ::new-client :data :bank-accounts ])] + (fn [bank-accounts [_ index]] + (vec (concat (take index bank-accounts) + (drop (inc index) bank-accounts))) + #_(update db :bank-accounts (fn [bas] (filter #(not= (:code %) code) bas))))) @@ -197,6 +224,123 @@ (defn side-bar-form [_ children] [:div [:a.delete.is-pulled-right {:on-click (dispatch-event [::form-closing ::new-client])}] [:div children]]) +(defn bank-account-card [new-client {:keys [active? new? type code name number check-number id] :as bank-account} index] + (println new-client) + [:div.card {:style {:margin-bottom "1em"}} + [:header.card-header + [:p.card-header-title {:style {:text-overflow "ellipsis"}} + [:span.icon + (if ({:check ":check"} type) + [:span.icon-check-payment-sign] + [:span.icon-accounting-bill])] + code ": " name] + (if active? + [:a.card-header-icon + {:on-click (dispatch-event [::bank-account-deactivated index])} + [:span.icon + [:span.fa.fa-angle-up]]] + [:a.card-header-icon + {:on-click (dispatch-event [::bank-account-activated index])} + [:span.icon + [:span.fa.fa-angle-down]]])] + (when active? + [:div.card-content + [:label.label "General"] + [horizontal-field + nil + [:div.control + [:p.help "Account Code"] + (if new? + [:div.field.has-addons.is-extended + [:p.control [:a.button.is-static (:code new-client) "-" ]] + [:p.control + [bind-field + [:input.input {:type "code" + :field [:bank-accounts index :code] + :spec ::entity/code + :event ::change-new + :subscription new-client}]]]] + [:div.field [:p.control code]])] + + [:div.control + [:p.help "Nickname"] + [bind-field + [:input.input {:placeholder "BOA Checking #1" + :type "text" + :field [:bank-accounts index :name] + :event ::change-new + :subscription new-client}]]]] + (when (#{:check ":check"} (doto type println) ) + [:div + + [:label.label "Bank"] + [horizontal-field + nil + [:div.control + [:p.help "Bank Name"] + [bind-field + [:input.input {:placeholder "Bank of America" + :type "text" + :field [:bank-accounts index :bank-name] + :event ::change-new + :subscription new-client}]]] + [:div.control + [:p.help "Routing #"] + [bind-field + [:input.input {:placeholder "104819123" + :type "text" + :field [:bank-accounts index :routing] + :event ::change-new + :subscription new-client}]]] + [:div.control + [:p.help "Bank code"] + [bind-field + [:input.input {:placeholder "12/10123" + :type "text" + :field [:bank-accounts index :bank-code] + :event ::change-new + :subscription new-client}]]]] + + [:label.label "Checking account"] + [horizontal-field + nil + [:div.control + [:p.help "Account #"] + [bind-field + [:input.input {:placeholder "123456789" + :type "text" + :field [:bank-accounts index :number] + :event ::change-new + :subscription new-client}]]] + [:div.control + [:p.help "Check Number"] + [bind-field + [:input.input {:placeholder "10000" + :type "text" + :field [:bank-accounts index :check-number] + :event ::change-new + :subscription new-client}]]]] + [:div.field + [:label.label "Yodlee Account"] + [:div.control + [bind-field + [:input.input {:placeholder "Yodlee Account #" + :type "text" + :field [:bank-accounts :yodlee-account-id] + :event ::change-new + :subscription new-client}]]] + ]] + + )] + + ) + (when active? + [:footer.card-footer + [:a.card-footer-item {:href "#" :on-click (dispatch-event [::bank-account-deactivated index])} "Done"] + (when new? + [:a.card-footer-item.is-warning {:href "#" :on-click (dispatch-event [::bank-account-removed index])} "Remove"])])] + ) + (defn new-client-form [] (let [{error :error new-client :data } @(re-frame/subscribe [::form ::new-client])] @@ -253,124 +397,20 @@ [address-field {:field [:address] :event ::change-new :subscription new-client}]] - [:nav.panel - [:p.panel-heading "Bank accounts"] - (for [{:keys [type code name number check-number id]} (:bank-accounts new-client)] - (if id - ^{:key code} - - [:a.panel-block {:style {:position "relative"}} - [:span.panel-icon - (if (= type :check) - [:span.icon-check-payment-sign] - [:span.icon-accounting-bill])] - code ": " name] - - ^{:key code} - [:li [:strong "* " code ": " name] [:button.button {:on-click (dispatch-event [::remove-new-bank-account code])} [:span.icon [:i.fa.fa-times]]]])) - [:div.panel-block - [:nav.level - [:div.level-item.has-text-centered - [:button.button.is-outlined.is-primary.is-fullwidth "Add Checking Account"]] - [:div.level-item.has-text-centered - - [:button.button.is-outlined.is-primary.is-fullwidth "Add Cash Account"]]]] - #_(for [[index {:keys [name code number check-number]}] (map vector (range) (:new-bank-accounts new-client))] - ^{:key index} [:li [:strong "* " code ": " name] [:button.button {:on-click (dispatch-event [::remove-new-bank-account index])} [:span.icon [:i.fa.fa-times]]]])] + + [:h2.subtitle "Bank accounts"] + (for [[bank-account index] (map vector (:bank-accounts new-client) (range))] + ^{:key index} + [bank-account-card new-client bank-account index]) + + [:div.columns + [:div.column.is-half + [:a.button.is-primary.is-outlined.is-fullwidth {:on-click (dispatch-event [::add-new-bank-account :check])} "Add Checking Account"]] + [:div.column.is-half + [:a.button.is-primary.is-outlined.is-fullwidth {:on-click (dispatch-event [::add-new-bank-account :cash])} "Add Cash Account"]]] #_[:h2.subtitle "Add bank account"] - #_[:div {:style {:padding-bottom "0.75em" :padding-top "0.75em" :background "hsl(0, 0%, 96%)"}} - [:label.label "General"] - [horizontal-field - nil - [:div.control - [:p.help "Account Code"] - [:div.field.has-addons.is-extended - [:p.control [:a.button.is-static (:code new-client) "-" ]] - [:p.control - [bind-field - [:input.input {:type "code" - :field [:new-account :code] - :spec ::entity/code - :event ::change-new - :subscription new-client}]]]]] - - [:div.control - [:p.help "Nickname"] - [bind-field - [:input.input {:placeholder "BOA Checking #1" - :type "text" - :field [:new-account :name] - :event ::change-new - :subscription new-client}]]]] - - [:label.label "Bank"] - [horizontal-field - nil - [:div.control - [:p.help "Bank Name"] - [bind-field - [:input.input {:placeholder "Bank of America" - :type "text" - :field [:new-account :bank-name] - :event ::change-new - :subscription new-client}]]] - [:div.control - [:p.help "Routing #"] - [bind-field - [:input.input {:placeholder "104819123" - :type "text" - :field [:new-account :routing] - :event ::change-new - :subscription new-client}]]] - [:div.control - [:p.help "Bank code"] - [bind-field - [:input.input {:placeholder "12/10123" - :type "text" - :field [:new-account :bank-code] - :event ::change-new - :subscription new-client}]]]] - - [:label.label "Checking account"] - [horizontal-field - nil - [:div.control - [:p.help "Account #"] - [bind-field - [:input.input {:placeholder "123456789" - :type "text" - :field [:new-account :number] - :event ::change-new - :subscription new-client}]]] - [:div.control - [:p.help "Check Number"] - [bind-field - [:input.input {:placeholder "10000" - :type "text" - :field [:new-account :check-number] - :event ::change-new - :subscription new-client}]]]] - - [:div.field - [:label.label "Yodlee Account"] - [:div.control - [bind-field - [:input.input {:placeholder "Yodlee Account #" - :type "text" - :field [:new-account :yodlee-account-id] - :event ::change-new - :subscription new-client}]]] - ] - [:div.field - [:div.control - #_(println (s/explain-data ::entity/bank-account (:new-account new-client))) - [:button.button.is-primary {:disabled (if (and (doto (s/valid? ::entity/bank-account (:new-account new-client)) println) - (not ((set (map :code (:new-bank-accounts new-client))) - (str (:code new-client) "-" (-> new-client :new-account :code))))) - "" - "disabled") - :on-click (dispatch-event [::add-new-bank-account])} "Add"]]]] + @@ -380,8 +420,10 @@ (when error [:div.notification.is-warning.animated.fadeInUp error]) + + (println (s/explain-data ::entity/client @(re-frame/subscribe [::new-client-request]))) - [:submit.button.is-large.is-primary {:disabled (if (s/valid? ::entity/client new-client) + [:submit.button.is-large.is-primary {:disabled (if (s/valid? ::entity/client @(re-frame/subscribe [::new-client-request])) "" "disabled") :on-click (dispatch-event [::save-new-client])