diff --git a/migrator/migrations/1522981446-DOWN-add-vendor-code.sql b/migrator/migrations/1522981446-DOWN-add-vendor-code.sql new file mode 100644 index 00000000..5335ccc1 --- /dev/null +++ b/migrator/migrations/1522981446-DOWN-add-vendor-code.sql @@ -0,0 +1,2 @@ +-- 1522981446 DOWN add-vendor-code +ALTER TABLE vendors drop column code; diff --git a/migrator/migrations/1522981446-UP-add-vendor-code.sql b/migrator/migrations/1522981446-UP-add-vendor-code.sql new file mode 100644 index 00000000..0dd339cd --- /dev/null +++ b/migrator/migrations/1522981446-UP-add-vendor-code.sql @@ -0,0 +1,2 @@ +-- 1522981446 UP add-vendor-code +ALTER TABLE vendors add column code varchar(255) unique; diff --git a/src/clj/auto_ap/db/vendors.clj b/src/clj/auto_ap/db/vendors.clj index 7fc9fdf3..d7a0b8b7 100644 --- a/src/clj/auto_ap/db/vendors.clj +++ b/src/clj/auto_ap/db/vendors.clj @@ -12,7 +12,6 @@ merge-data )) - (defn get-all [] (->> (j/query (get-conn) "SELECT * FROM vendors") (map parse))) @@ -20,3 +19,8 @@ (defn upsert [id data] (j/update! (get-conn) :vendors (clj->db data) ["id = ?" (Integer/parseInt id)] ) (merge-data (db->clj (first (j/query (get-conn) ["SELECT * FROM vendors WHERE id = ?" (Integer/parseInt id)]))))) + +(defn insert [data] + (parse (first (j/insert! (get-conn) + :vendors + (clj->db data))))) diff --git a/src/clj/auto_ap/handler.clj b/src/clj/auto_ap/handler.clj index e54690d6..a98811f4 100644 --- a/src/clj/auto_ap/handler.clj +++ b/src/clj/auto_ap/handler.clj @@ -133,6 +133,11 @@ :body (pr-str (vendors/upsert id edn-params)) :headers {"Content-Type" "application/edn"}}) + (POST "/api/vendors" {:keys [edn-params] :as r} + {:status 200 + :body (pr-str (vendors/insert edn-params)) + :headers {"Content-Type" "application/edn"}}) + (POST "/api/invoices" {:keys [edn-params]} (invoices/insert-multi! (:rows edn-params)) {:status 200 diff --git a/src/cljs/auto_ap/events/admin/companies.cljs b/src/cljs/auto_ap/events/admin/companies.cljs index a1cbac25..f8e99682 100644 --- a/src/cljs/auto_ap/events/admin/companies.cljs +++ b/src/cljs/auto_ap/events/admin/companies.cljs @@ -8,14 +8,14 @@ (re-frame/reg-event-db ::edit (fn [db [_ company-id]] - (assoc-in db [:admin-companies :editing] - (get (:companies db) company-id)))) + (assoc-in db [:admin :company] + (get (:companies db) company-id)))) (re-frame/reg-event-fx ::save (fn [{:keys [db]} _] - (let [edited-company (get-in db [:admin-companies :editing])] - {:db (assoc-in db [:admin-companies :editing :saving?] true) + (let [edited-company (get-in db [:admin :company])] + {:db (assoc-in db [:admin :company :saving?] true) :http {:method :put :token (:user db) :body (pr-str (select-keys edited-company [:name :email :data :invoice-reminder-schedule])) @@ -28,11 +28,11 @@ (fn [db [_ company]] (-> db - (assoc-in [:admin-companies :editing] nil) + (assoc-in [:admin :company] nil) (assoc-in [:companies (:id company)] company)))) (re-frame/reg-event-db ::change (fn [db [_ path value]] - (assoc-in db (concat [:admin-companies :editing] path) + (assoc-in db (concat [:admin :company] path) value))) diff --git a/src/cljs/auto_ap/events/admin/vendors.cljs b/src/cljs/auto_ap/events/admin/vendors.cljs index 1b34b61e..06f5dda5 100644 --- a/src/cljs/auto_ap/events/admin/vendors.cljs +++ b/src/cljs/auto_ap/events/admin/vendors.cljs @@ -8,33 +8,46 @@ (re-frame/reg-event-db ::edit (fn [db [_ vendor-id]] - (assoc-in db [:admin-vendors :editing] + (assoc-in db [:admin :vendor] (get (:vendors db) vendor-id)))) +(re-frame/reg-event-db + ::new + (fn [db _] + (assoc-in db [:admin :vendor] + {}))) + (re-frame/reg-event-fx ::save (fn [{:keys [db]} _] - (let [edited-vendor (get-in db [:admin-vendors :editing])] - {:db (assoc-in db [:admin-vendors :editing :saving?] true) - :http {:method :put - :token (:user db) - :body (pr-str (select-keys edited-vendor [:name :email :data :invoice-reminder-schedule])) - :headers {"Content-Type" "application/edn"} - :uri (str "/api/vendors/" (:id edited-vendor)) - :on-success [::save-complete]}}))) + (let [edited-vendor (get-in db [:admin :vendor]) + fx {:db (assoc-in db [:admin :vendor :saving?] true)}] + (if (:id edited-vendor) + (assoc fx :http {:method :put + :token (:user db) + :body (pr-str (select-keys edited-vendor [:name :email :data :invoice-reminder-schedule :code])) + :headers {"Content-Type" "application/edn"} + :uri (str "/api/vendors/" (:id edited-vendor)) + :on-success [::save-complete]}) + (assoc fx :http {:method :post + :token (:user db) + :body (pr-str (select-keys edited-vendor [:name :email :data :invoice-reminder-schedule :code])) + :headers {"Content-Type" "application/edn"} + :uri (str "/api/vendors") + :on-success [::save-complete]}))))) (re-frame/reg-event-db ::save-complete (fn [db [_ vendor]] (-> db - (assoc-in [:admin-vendors :editing] nil) + (assoc-in [:admin :vendor] nil) (assoc-in [:vendors (:id vendor)] vendor)))) (re-frame/reg-event-db ::change (fn [db [_ path value]] - (assoc-in db (concat [:admin-vendors :editing] path) + (assoc-in db (concat [:admin :vendor] path) value))) (re-frame/reg-event-fx diff --git a/src/cljs/auto_ap/subs.cljs b/src/cljs/auto_ap/subs.cljs index e88c94e0..69c7b338 100644 --- a/src/cljs/auto_ap/subs.cljs +++ b/src/cljs/auto_ap/subs.cljs @@ -24,20 +24,15 @@ (fn [db] (:user db))) -(re-frame/reg-sub - ::admin-companies - (fn [db] - (:admin-companies db))) - (re-frame/reg-sub ::vendors (fn [db] (vals (:vendors db)))) (re-frame/reg-sub - ::admin-vendors + ::admin (fn [db] - (:admin-vendors db))) + (:admin db))) (re-frame/reg-sub ::user diff --git a/src/cljs/auto_ap/views/pages/admin/companies.cljs b/src/cljs/auto_ap/views/pages/admin/companies.cljs index 6f7ed7b8..5e4d0ccd 100644 --- a/src/cljs/auto_ap/views/pages/admin/companies.cljs +++ b/src/cljs/auto_ap/views/pages/admin/companies.cljs @@ -10,8 +10,7 @@ [bidi.bidi :as bidi])) (defn companies-table [] (let [companies (re-frame/subscribe [::subs/companies]) - admin-companies (re-frame/subscribe [::subs/admin-companies]) - editing-company (:editing @admin-companies)] + editing-company (:company @(re-frame/subscribe [::subs/admin]))] [:table {:class "table", :style {:width "100%"}} [:thead [:tr @@ -32,9 +31,7 @@ [:div.hero-body [:div.container (let [companies (re-frame/subscribe [::subs/companies]) - admin-companies (re-frame/subscribe [::subs/admin-companies]) - editing-company (:editing @admin-companies)] - (println editing-company) + editing-company (:company @(re-frame/subscribe [::subs/admin]))] [:div [:h1.title "Companies"] diff --git a/src/cljs/auto_ap/views/pages/admin/vendors.cljs b/src/cljs/auto_ap/views/pages/admin/vendors.cljs index f30399c4..a70cb0b5 100644 --- a/src/cljs/auto_ap/views/pages/admin/vendors.cljs +++ b/src/cljs/auto_ap/views/pages/admin/vendors.cljs @@ -4,15 +4,13 @@ [reagent.core :as reagent] [auto-ap.subs :as subs] [auto-ap.events.admin.vendors :as events] - [auto-ap.views.utils :refer [login-url dispatch-value-change]] + [auto-ap.views.utils :refer [login-url dispatch-value-change dispatch-event]] [cljs.reader :as edn] [auto-ap.routes :as routes] [bidi.bidi :as bidi])) (defn vendors-table [] (let [vendors (re-frame/subscribe [::subs/vendors]) - admin-vendors (re-frame/subscribe [::subs/admin-vendors]) - editing-vendor (:editing @admin-vendors)] - (println @vendors) + editing-vendor (:editing @(re-frame/subscribe [::subs/admin]))] [:table {:class "table", :style {:width "100%"}} [:thead [:tr @@ -27,6 +25,70 @@ [:td email] [:td invoice-reminder-schedule]])]])) +(defn edit-dialog [] + (let [{:keys [name email invoice-reminder-schedule id code] :as editing-vendor} (:vendor @(re-frame/subscribe [::subs/admin]))] + [:div.modal.is-active + [:div.modal-background {:on-click (fn [] (re-frame/dispatch [::events/edit nil]))}] + + [:div.modal-card + [:header.modal-card-head + [:p.modal-card-title + (if id + (str "Edit " (or name "")) + (str "Add " (or name "")))] + [:button.delete {:on-click (fn [] (re-frame/dispatch [::events/edit nil]))}]] + [:section.modal-card-body + [:div.field + [:label.label "Name"] + [:div.control + [:input.input {:type "text" :value name + :on-change (dispatch-value-change [::events/change [:name]])}]]] + [:div.field + [:label.label "Code"] + [:div.control + [:input.input {:type "text" :value code + :on-change (dispatch-value-change [::events/change [:code]])}]] + [:p.help "The vendor code is used for invoice parsing. Only one vendor at a time can use a code"]] + + [:div.field + [:label.label "Email"] + [:div.control + [:input.input {:type "email" + :value email + :on-change (dispatch-value-change [::events/change [:email]])}]]] + + [:div.field + [:labal.label "Invoice Reminders"] + [:div.control + [:label.radio + [:input {:type "radio" + :name "schedule" + :value "Weekly" + :checked (if (= "Weekly" invoice-reminder-schedule) + "checked" + "") + :on-change (dispatch-value-change [::events/change [:invoice-reminder-schedule]])}] + " Send weekly"]] + [:div.control + [:label.radio + [:input {:type "radio" + :name "schedule" + :value "Never" + :checked (if (= "Never" invoice-reminder-schedule) + "checked" + "") + :on-change (dispatch-value-change [::events/change [:invoice-reminder-schedule]])}] + " Never"]]] + + (when (:saving? editing-vendor) [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])] + + [:footer.modal-card-foot + [:a.button.is-primary {:on-click (fn [] (re-frame/dispatch [::events/save]))} + [:span "Save"] + (when (:saving? editing-vendor) + [:span.icon + [:i.fa.fa-spin.fa-spinner]])]]]])) + (defn admin-vendors-page [] [(with-meta (fn [] @@ -35,68 +97,16 @@ [:div.hero-body [:div.container (let [vendors (re-frame/subscribe [::subs/vendors]) - admin-vendors (re-frame/subscribe [::subs/admin-vendors]) - editing-vendor (:editing @admin-vendors)] + editing-vendor (:vendor @(re-frame/subscribe [::subs/admin]))] [:div [:h1.title "Vendors"] [vendors-table] - + [:a.button.is-primary.is-large {:on-click (dispatch-event [::events/new])} "New vendor"] (when editing-vendor - [:div.modal.is-active - [:div.modal-background {:on-click (fn [] (re-frame/dispatch [::events/edit nil]))}] - - [:div.modal-card - [:header.modal-card-head - [:p.modal-card-title - (str "Edit " (:name editing-vendor))] - [:button.delete {:on-click (fn [] (re-frame/dispatch [::events/edit nil]))}]] - [:section.modal-card-body - [:div.field - [:label.label "Name"] - [:div.control - [:input.input {:type "text" :value (:name editing-vendor) - :on-change (dispatch-value-change [::events/change [:name]])}]]] - - [:div.field - [:label.label "Email"] - [:div.control - [:input.input {:type "email" - :value (:email editing-vendor) - :on-change (dispatch-value-change [::events/change [:email]])}]]] - - [:div.field - [:labal.label "Invoice Reminders"] - [:div.control - [:label.radio - [:input {:type "radio" - :name "schedule" - :value "Weekly" - :checked (if (= "Weekly" (:invoice-reminder-schedule editing-vendor)) - "checked" - "") - :on-change (dispatch-value-change [::events/change [:invoice-reminder-schedule]])}] - " Send weekly"]] - [:div.control - [:label.radio - [:input {:type "radio" - :name "schedule" - :value "Never" - :checked (if (= "Never" (:invoice-reminder-schedule editing-vendor)) - "checked" - "") - :on-change (dispatch-value-change [::events/change [:invoice-reminder-schedule]])}] - " Never"]]] - - (when (:saving? editing-vendor) [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])] - - [:footer.modal-card-foot - [:a.button.is-primary {:on-click (fn [] (re-frame/dispatch [::events/save]))} - [:span "Save"] - (when (:saving? editing-vendor) - [:span.icon - [:i.fa.fa-spin.fa-spinner]])]]]])])]]]]) + [edit-dialog] + )])]]]]) {:component-did-mount (fn [] (re-frame/dispatch [::events/mounted]))})]) diff --git a/src/cljs/auto_ap/views/utils.cljs b/src/cljs/auto_ap/views/utils.cljs index c0b828ce..5d4d10c1 100644 --- a/src/cljs/auto_ap/views/utils.cljs +++ b/src/cljs/auto_ap/views/utils.cljs @@ -11,4 +11,10 @@ (defn dispatch-value-change [event] (fn [e] + (.preventDefault e) (re-frame/dispatch (conj event (.. e -target -value))))) + +(defn dispatch-event [event] + (fn [e] + (.preventDefault e) + (re-frame/dispatch event))) diff --git a/terraform/main.tf b/terraform/main.tf index 917efbb1..1d7ddc01 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -45,6 +45,36 @@ resource "aws_s3_bucket" "invoices" { } EOF } +resource "aws_sqs_queue" "integreat-mail" { + name = "integreat-mail-prod" + + policy = <