From 2a708f199030bd51a50c57d094b6c5529cee951f Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Sun, 5 Jan 2020 10:28:10 -0800 Subject: [PATCH] added support for merging vendors. --- src/clj/auto_ap/graphql.clj | 6 ++ src/clj/auto_ap/graphql/vendors.clj | 14 ++++ src/cljs/auto_ap/events.cljs | 4 +- src/cljs/auto_ap/events/admin/vendors.cljs | 25 +++++++ src/cljs/auto_ap/subs.cljs | 8 +- src/cljs/auto_ap/views/components/modal.cljs | 51 ++++++------- .../auto_ap/views/pages/admin/vendors.cljs | 74 ++++++++++++++++++- 7 files changed, 144 insertions(+), 38 deletions(-) diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index 2bc56c98..7c7796b9 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -384,6 +384,11 @@ :args {:invoices {:type '(list :id)}} :resolve :mutation/approve-invoices} + :merge_vendors {:type :id + :args {:from {:type :id} + :to {:type :id}} + :resolve :mutation/merge-vendors} + :add_and_print_invoice {:type :check_result :args {:invoice {:type :add_invoice} :bank_account_id {:type :id} @@ -588,6 +593,7 @@ :mutation/edit-invoice gq-invoices/edit-invoice :mutation/edit-client gq-clients/edit-client :mutation/upsert-vendor gq-vendors/upsert-vendor + :mutation/merge-vendors gq-vendors/merge-vendors :mutation/void-invoice gq-invoices/void-invoice :mutation/unvoid-invoice gq-invoices/unvoid-invoice :mutation/void-payment gq-checks/void-check diff --git a/src/clj/auto_ap/graphql/vendors.clj b/src/clj/auto_ap/graphql/vendors.clj index c3126785..d8b0c3df 100644 --- a/src/clj/auto_ap/graphql/vendors.clj +++ b/src/clj/auto_ap/graphql/vendors.clj @@ -50,4 +50,18 @@ id)) (->graphql)))) +(defn merge-vendors [context {:keys [from to]} value] + (let [conn (d/connect uri) + transaction (->> (d/query {:query {:find '[?x ?a2] + :in '[$ ?vendor-from ] + :where ['[?x ?a ?vendor-from] + '[?a :db/ident ?a2]]} + :args [(d/db conn) + from]}) + (mapcat (fn [[src attr]] + [[:db/retract src attr from] + [:db/add src attr to]]))) + transaction (conj transaction [:db/retractEntity from])] + @(d/transact conn transaction) + to)) diff --git a/src/cljs/auto_ap/events.cljs b/src/cljs/auto_ap/events.cljs index fd04f401..07d8a08c 100644 --- a/src/cljs/auto_ap/events.cljs +++ b/src/cljs/auto_ap/events.cljs @@ -96,10 +96,9 @@ ::modal-status (fn [db [_ id state]] (println "changing modal status" id "to") - (println (:auto-ap.forms/forms db)) (-> db (update-in [:modal-state id] #(merge % state)) - (dissoc :auto-ap.forms/forms) + #_(dissoc :auto-ap.forms/forms) ))) (re-frame/reg-event-db @@ -112,7 +111,6 @@ (re-frame/reg-event-db ::modal-completed (fn [db [_ id state]] - (println (:auto-ap.forms/forms db)) (-> db (update-in [:modal-state] #(dissoc % id)) (dissoc :auto-ap.forms/forms)))) diff --git a/src/cljs/auto_ap/events/admin/vendors.cljs b/src/cljs/auto_ap/events/admin/vendors.cljs index 2c220e35..c099ce1e 100644 --- a/src/cljs/auto_ap/events/admin/vendors.cljs +++ b/src/cljs/auto_ap/events/admin/vendors.cljs @@ -4,6 +4,8 @@ [auto-ap.db :as db] [auto-ap.routes :as routes] [auto-ap.effects :as effects] + [auto-ap.forms :as forms] + [auto-ap.subs :as subs] [auto-ap.entities.vendors :as entity] [auto-ap.events :as events] [auto-ap.utils :refer [by]] @@ -31,6 +33,29 @@ {}) :dispatch [::events/modal-status :auto-ap.views.pages.admin.vendors/admin-vendor {:visible? true}]})) + + +#_(re-frame/reg-event-fx + ::merge-submit-clicked + [(forms/in-form :auto-ap.views.pages.admin.vendors/merge-vendors)] + (fn [{{{:keys [from-id to-id]} :data :as merge-vendors-form} :db :as g} _] + (println g) + (let [user @(re-frame/subscribe [::subs/token])] + (if (and from-id to-id) + {:db (-> merge-vendors-form + (assoc :status :loading) + (assoc :error nil)) + :graphql + {:token user + :query-obj {:venia/operation {:operation/type :mutation + :operation/name "MergeVendors"} + :venia/queries [{:query/data [:merge-vendors + {:from from-id :to to-id} + [:id]]}]} + :on-success [::merge-vendors-complete] + :on-error [::forms/save-error :auto-ap.views.pages.admin.vendors/merge-vendors]}} + {:db merge-vendors-form})))) + (re-frame/reg-event-fx ::save (fn [{:keys [db]} _] diff --git a/src/cljs/auto_ap/subs.cljs b/src/cljs/auto_ap/subs.cljs index c6704cd9..1081751e 100644 --- a/src/cljs/auto_ap/subs.cljs +++ b/src/cljs/auto_ap/subs.cljs @@ -53,8 +53,12 @@ (re-frame/reg-sub ::modal-state - (fn [db [_ id]] - (get (:modal-state db) id))) + (fn [db [_ id status-from]] + (if status-from + (assoc (get (:modal-state db) id) + :error-message (get-in db [:auto-ap.forms/forms status-from :error]) + :saving? (= (get-in db [:auto-ap.forms/forms status-from :status]) :loading)) + (get (:modal-state db) id)))) (re-frame/reg-sub ::token diff --git a/src/cljs/auto_ap/views/components/modal.cljs b/src/cljs/auto_ap/views/components/modal.cljs index 3d0d7fcd..a5155e33 100644 --- a/src/cljs/auto_ap/views/components/modal.cljs +++ b/src/cljs/auto_ap/views/components/modal.cljs @@ -21,35 +21,26 @@ [:footer.modal-card-foot foot])]]) -(defn action-modal [{:keys [title action-text id save-event can-submit?] :or {can-submit? true}} & rest] - (let [{:keys [visible? saving? error-message]} @(re-frame/subscribe [::subs/modal-state id])] +(defn action-modal [{:keys [title action-text id save-event can-submit? status-from] :or {can-submit? true}} & rest] + (let [{:keys [visible? saving? error-message]} @(re-frame/subscribe [::subs/modal-state id status-from])] (when visible? - (-> [modal {:title [:span title + [:form {:id id + :on-submit (fn [e] + (.preventDefault e) + (re-frame/dispatch [::events/modal-status id {:saving? true :error-message nil}]) + (re-frame/dispatch save-event))} + (-> [modal {:title [:span title] + :foot [:input.button.is-primary (cond-> {:type "submit" + :form id + :class (when saving? + "is-loading") + :value action-text} + saving? (assoc :disabled "disabled") + (not can-submit?) (assoc :disabled "disabled")) ] - :foot [:input.button.is-primary {:type "submit" - :tabindex "1" - :form id - :disabled (cond saving? - "disabled" - - (not can-submit?) - "disabled" - - :else - "") - :class (when saving? - "is-loading") - :value action-text} - ] - :id id - :hide-event [::events/modal-status id {:visible? false}]} - (into [:form {:id id - :on-submit (fn [e] - (.preventDefault e) - (re-frame/dispatch [::events/modal-status id {:saving? true :error-message nil}]) - (re-frame/dispatch save-event))} - (when error-message - [:div.notification.is-warning error-message])] - - (r/children (r/current-component)) )] - (into [(when saving? [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])]))))) + :id id + :hide-event [::events/modal-status id {:visible? false}]} + (when error-message + [:div.notification.is-warning error-message])] + (into (r/children (r/current-component))) + (into [(when saving? [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])]))]))) diff --git a/src/cljs/auto_ap/views/pages/admin/vendors.cljs b/src/cljs/auto_ap/views/pages/admin/vendors.cljs index e8cb29df..752897b8 100644 --- a/src/cljs/auto_ap/views/pages/admin/vendors.cljs +++ b/src/cljs/auto_ap/views/pages/admin/vendors.cljs @@ -4,11 +4,13 @@ [reagent.core :as reagent] [clojure.string :as str] [auto-ap.subs :as subs] + [auto-ap.events :as e] + [auto-ap.forms :as forms] [auto-ap.events.admin.vendors :as events] [auto-ap.entities.vendors :as entity] [auto-ap.views.components.address :refer [address-field]] [auto-ap.views.components.vendor-dialog :refer [vendor-dialog]] - [auto-ap.views.components.modal :refer [modal]] + [auto-ap.views.components.modal :refer [modal action-modal]] [auto-ap.views.components.admin.side-bar :refer [admin-side-bar]] [auto-ap.views.components.layouts :refer [side-bar-layout]] [clojure.spec.alpha :as s] @@ -56,6 +58,72 @@ keys (dissoc keys :field :subscription)] (vec (concat [dom keys] rest)))) +(re-frame/reg-event-fx + ::merge-clicked + (fn [{:keys [db]} _] + {:db (forms/start-form db ::merge-vendors {}) + :dispatch [::e/modal-status ::merge-vendors {:visible? true :saving? false}]})) + +(re-frame/reg-event-fx + ::merge-vendors-complete + (fn [{:keys [db]} _] + {:db (forms/stop-form db ::merge-vendors) + :dispatch-n (list [::e/modal-status ::merge-vendors {:visible? false}] + [::events/mounted])})) + +(re-frame/reg-event-fx + ::merge-submit-clicked + [(forms/in-form ::merge-vendors)] + (fn [{{{:keys [from-id to-id]} :data :as merge-vendors-form} :db :as g} _] + (let [user @(re-frame/subscribe [::subs/token])] + (if (and from-id to-id) + {:db (-> merge-vendors-form + (assoc :status :loading) + (assoc :error nil)) + :graphql + {:token user + :query-obj {:venia/operation {:operation/type :mutation + :operation/name "MergeVendors"} + :venia/queries [{:query/data [:merge-vendors + {:from from-id :to to-id} + []]}]} + :on-success [::merge-vendors-complete] + :on-error [::forms/save-error ::merge-vendors]}} + {:db merge-vendors-form})))) + +(defn merge-vendors-dialog [] + (let [{:keys [data active? error id]} @(re-frame/subscribe [::forms/form ::merge-vendors]) + change-event [::forms/change ::merge-vendors]] + + [action-modal {:id ::merge-vendors + :title "Merge Vendors" + :action-text "Merge" + :save-event [::merge-submit-clicked] + :status-from ::merge-vendors} + [:div.field + [:label.label + "From Vendor (will be deleted)"] + [:div.control + [bind-field + [typeahead {:matches (map (fn [x] [(:id x) (:name x)]) @(re-frame/subscribe [::subs/vendors])) + :type "typeahead" + :auto-focus true + :field [:from-id] + :text-field [:from-name] + :event change-event + :subscription data}]]]] + [:div.field + [:label.label + "To Vendor"] + [:div.control + [bind-field + [typeahead {:matches (map (fn [x] [(:id x) (:name x)]) @(re-frame/subscribe [::subs/vendors])) + :type "typeahead" + :field [:to-id] + :text-field [:to-name] + :event change-event + :subscription data}]]]]])) + (defn admin-vendors-content [] [(with-meta @@ -65,15 +133,15 @@ [:div.notification banner]) (let [vendors (re-frame/subscribe [::subs/vendors]) editing-vendor (:vendor @(re-frame/subscribe [::subs/admin]))] - - [:div [:h1.title "Vendors"] + [:a.button.is-primary.is-large {:on-click (dispatch-event [::merge-clicked])} "Merge vendors"] [vendors-table] [:div.is-pulled-right [:a.button.is-primary.is-large {:on-click (dispatch-event [::events/new])} "New vendor"]] + [merge-vendors-dialog] [vendor-dialog {:vendor editing-vendor :save-event [::events/save] :change-event ::events/change