This commit is contained in:
Bryce Covert
2018-04-05 18:17:45 -07:00
parent 7fc02c1d04
commit 33cfc395de
10 changed files with 230 additions and 4 deletions

View File

@@ -0,0 +1,2 @@
-- 1522973754 DOWN create-vendors
drop table vendors;

View File

@@ -0,0 +1,12 @@
-- 1522973754 UP create-vendors
CREATE TABLE public.vendors (
id serial PRIMARY KEY,
name character varying(255),
data text,
email character varying(255),
invoice_reminder_schedule character varying(255)
);
INSERT into vendors (name, data, email, invoice_reminder_schedule) values ('CINTAS', '{}', 'ses@brycecovertoperations.com', 'Weekly');

View File

@@ -0,0 +1,22 @@
(ns auto-ap.db.vendors
(:require [clojure.java.jdbc :as j]
[auto-ap.db.utils :refer [clj->db db->clj get-conn]]
[clojure.edn :as edn]))
(defn merge-data [{:keys [data] :as x}]
(merge x (edn/read-string data)))
(defn parse [x]
(-> x
(db->clj)
merge-data
))
(defn get-all []
(->> (j/query (get-conn) "SELECT * FROM vendors")
(map parse)))
(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)])))))

View File

@@ -24,6 +24,7 @@
[buddy.auth.backends.token :refer [jws-backend]]
[buddy.auth.middleware :refer [wrap-authorization wrap-authentication]]
[auto-ap.db.companies :as companies]
[auto-ap.db.vendors :as vendors]
[amazonica.core :refer [defcredential]]
[amazonica.aws.simpleemail :as ses]))
(defn best-match [companies company-identifier]
@@ -88,6 +89,11 @@
{:status 200
:body (pr-str (companies/get-all))
:headers {"Content-Type" "application/edn"}})
(GET "/api/vendors" []
{:status 200
:body (pr-str (vendors/get-all))
:headers {"Content-Type" "application/edn"}})
(GET "/api/invoices" []
{:status 200
@@ -105,7 +111,7 @@
:headers {"Content-Type" "application/edn"}})
(POST "/api/reminders/send" {:keys [query-params]}
(doseq [{:keys [name email invoice-reminder-schedule]} (companies/get-all)]
(doseq [{:keys [name email invoice-reminder-schedule]} (vendors/get-all)]
(when (= "Weekly" invoice-reminder-schedule)
(println "Sending email to" email)
(ses/send-email :destination {:to-addresses [email]}
@@ -122,6 +128,11 @@
:body (pr-str (companies/upsert id edn-params))
:headers {"Content-Type" "application/edn"}})
(PUT "/api/vendors/:id" {:keys [edn-params] {:keys [id]} :route-params :as r}
{:status 200
:body (pr-str (vendors/upsert id edn-params))
:headers {"Content-Type" "application/edn"}})
(POST "/api/invoices" {:keys [edn-params]}
(invoices/insert-multi! (:rows edn-params))
{:status 200

View File

@@ -0,0 +1,55 @@
(ns auto-ap.events.admin.vendors
(:require [re-frame.core :as re-frame]
[auto-ap.db :as db]
[auto-ap.routes :as routes]
[auto-ap.effects :as effects]
[bidi.bidi :as bidi]))
(re-frame/reg-event-db
::edit
(fn [db [_ vendor-id]]
(assoc-in db [:admin-vendors :editing]
(get (:vendors db) vendor-id))))
(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]}})))
(re-frame/reg-event-db
::save-complete
(fn [db [_ vendor]]
(-> db
(assoc-in [:admin-vendors :editing] 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)
value)))
(re-frame/reg-event-fx
::mounted
(fn [{:keys [db]} _]
{:http {:method :get
:token (:user db)
:uri "/api/vendors"
:on-success [::received-vendors]}}))
(re-frame/reg-event-db
::received-vendors
(fn [db [_ vendors]]
(assoc db :vendors (reduce (fn [vendors vendor]
(assoc vendors (:id vendor) vendor))
{}
vendors))))

View File

@@ -4,7 +4,8 @@
(def routes ["/" {"" :index
"login/" :login
"admin/" {"" :admin
"companies" :admin-companies}
"companies" :admin-companies
"vendors" :admin-vendors}
"invoices/" {"" :invoices
"import" :import-invoices
"unpaid" :unpaid-invoices

View File

@@ -29,6 +29,16 @@
(fn [db]
(:admin-companies db)))
(re-frame/reg-sub
::vendors
(fn [db]
(vals (:vendors db))))
(re-frame/reg-sub
::admin-vendors
(fn [db]
(:admin-vendors db)))
(re-frame/reg-sub
::user
(fn [db]

View File

@@ -17,6 +17,7 @@
:paid-invoices :left-panel
:admin :admin-left-panel
:admin-companies :admin-left-panel
:admin-vendors :admin-left-panel
:new-invoice :blank} page))
(defn login-dropdown []
@@ -70,6 +71,12 @@
[:i {:class "fa fa-star-o"}]]
[:span {:class "name"} "Companies"]]]
[:li.menu-item
[:a {:href (bidi/path-for routes/routes :admin-vendors) , :class (str "item" (active-when= ap :admin-vendors))}
[:span {:class "icon"}
[:i {:class "fa fa-star-o"}]]
[:span {:class "name"} "Vendors"]]]
[:li.menu-item
[:a {:href (bidi/path-for routes/routes :admin-users), :class (str "item" (active-when= ap :admin-users))}
[:span {:class "icon"}

View File

@@ -8,6 +8,7 @@
[auto-ap.views.pages.index :refer [index-page]]
[auto-ap.views.pages.admin :refer [admin-page]]
[auto-ap.views.pages.admin.companies :refer [admin-companies-page]]
[auto-ap.views.pages.admin.vendors :refer [admin-vendors-page]]
[auto-ap.views.pages.unpaid-invoices :refer [unpaid-invoices-page]]
[auto-ap.views.pages.new-invoice :refer [new-invoice-page]]
[auto-ap.views.pages.import-invoices :refer [import-invoices-page]]
@@ -34,12 +35,15 @@
(defmethod active-page :admin-companies []
[admin-companies-page])
(defmethod active-page :admin-vendors []
[admin-vendors-page])
(defmethod active-page :unpaid-invoices []
[unpaid-invoices-page])
(defmethod active-page :paid-invoices []
paid-invoices-page
)
paid-invoices-page)
(defmethod active-page :invoices []
[(with-meta

View File

@@ -0,0 +1,102 @@
(ns auto-ap.views.pages.admin.vendors
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [re-frame.core :as re-frame]
[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]]
[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)
[:table {:class "table", :style {:width "100%"}}
[:thead
[:tr
[:th "Name"]
[:th "Email"]
[:th "Invoice Reminders"]]]
[:tbody (for [{:keys [id name email data invoice-reminder-schedule]} @vendors]
^{:key (str name "-" id )}
[:tr {:on-click (fn [] (re-frame/dispatch [::events/edit id]))
:style {"cursor" "pointer"}}
[:td name]
[:td email]
[:td invoice-reminder-schedule]])]]))
(defn admin-vendors-page []
[(with-meta
(fn []
[:div {:class "inbox-messages"}
[:div.hero
[: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)]
[:div
[:h1.title "Vendors"]
[vendors-table]
(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]])]]]])])]]]])
{:component-did-mount (fn []
(re-frame/dispatch [::events/mounted]))})])