for better or worse, moving to localized events and subs.

This commit is contained in:
Bryce Covert
2018-04-12 21:37:27 -07:00
parent 78ced354de
commit e1e0835bee
5 changed files with 120 additions and 53 deletions

View File

@@ -52,9 +52,12 @@
(excel/parse-file file filename)) (excel/parse-file file filename))
(defn best-match [companies company-identifier] (defn best-match [companies company-identifier]
(println companies)
(->> companies (->> companies
(map (fn [company] (map (fn [company]
[company (apply min (map #(m/jaccard (.toLowerCase company-identifier) %) (:matches (:data company))))])) (if-let [matches (:matches (:data company))]
[company (apply min (map #(m/jaccard (.toLowerCase company-identifier) %) matches))]
[company 1])))
(filter #(< (second %) 0.25)) (filter #(< (second %) 0.25))
(sort-by second) (sort-by second)

View File

@@ -56,10 +56,6 @@
(fn [db] (fn [db]
(:pending (:invoices db)))) (:pending (:invoices db))))
(re-frame/reg-sub
::unpaid-invoices
(fn [db]
(:unpaid (:invoices db))))
(re-frame/reg-sub (re-frame/reg-sub
::status ::status

View File

@@ -4,11 +4,10 @@
[reagent.core :as reagent])) [reagent.core :as reagent]))
(defn toggle-sort-by [params key] (defn toggle-sort-by [params key]
(-> params (-> params
(assoc :sort-by key) (assoc :sort-by key)
(assoc :asc (if (:asc params) (update :asc not)))
false
true))))
(defn sort-icon [which sort-by asc] (defn sort-icon [which sort-by asc]
(cond (cond
@@ -24,14 +23,21 @@
[:span.icon [:span.icon
[:i.fa.fa-sort]])) [:i.fa.fa-sort]]))
(defn invoice-table [{:keys [id invoices status on-params-change vendors]}] (defn query [params]
(let [state (reagent/atom {})] {:venia/queries [[:invoice
(fn [] (assoc params
:company-id (:id @(re-frame/subscribe [::subs/company])))
[:id :total :invoice-number :date [:vendor [:name :id]] [:company [:name :id]]]]]})
(defn invoice-table [{:keys [id invoices status on-params-change vendors params]}]
(let [state (reagent/atom (or @params {}))]
(fn [{:keys [id invoices status on-params-change vendors]}]
(let [{:keys [sort-by asc]} @state] (let [{:keys [sort-by asc]} @state]
[:table.table.is-fullwidth [:table.table.is-fullwidth
[:thead [:thead
[:tr [:tr
[:th {:on-click (fn [e] (on-params-change (swap! state toggle-sort-by "vendor"))) :style {:width "25%" :cursor "pointer"}} "Vendor" [:th {:on-click (fn [e]
(on-params-change (swap! state toggle-sort-by "vendor"))) :style {:width "25%" :cursor "pointer"}} "Vendor"
(sort-icon "vendor" sort-by asc)] (sort-icon "vendor" sort-by asc)]
[:th {:on-click (fn [e] (on-params-change (swap! state toggle-sort-by "company"))) :style {:width "25%" :cursor "pointer"}} "Company" [:th {:on-click (fn [e] (on-params-change (swap! state toggle-sort-by "company"))) :style {:width "25%" :cursor "pointer"}} "Company"
(sort-icon "company" sort-by asc)] (sort-icon "company" sort-by asc)]
@@ -47,7 +53,7 @@
[:td {:col-span 5} [:td {:col-span 5}
[:i.fa.fa-spin.fa-spinner]]] [:i.fa.fa-spin.fa-spinner]]]
(for [{:keys [company invoice-number date total id vendor] :as i} @invoices] (for [{:keys [company invoice-number date total id vendor] :as i} @invoices]
^{:key (str company "-" invoice-number "-" date "-" total "-" id)} ^{:key id}
[:tr [:tr
[:td (:name vendor)] [:td (:name vendor)]
[:td (:name company)] [:td (:name company)]

View File

@@ -5,6 +5,7 @@
[auto-ap.subs :as subs] [auto-ap.subs :as subs]
[auto-ap.entities.companies :as company] [auto-ap.entities.companies :as company]
[auto-ap.entities.vendors :as vendor] [auto-ap.entities.vendors :as vendor]
[auto-ap.views.components.invoice-table :refer [invoice-table] :as invoice-table]
[cljsjs.dropzone :as dropzone] [cljsjs.dropzone :as dropzone]
[cljs.reader :as edn])) [cljs.reader :as edn]))
(def dropzone (def dropzone
@@ -23,7 +24,7 @@
(js/Dropzone. (reagent/dom-node this) (js/Dropzone. (reagent/dom-node this)
(clj->js {:init (fn [] (clj->js {:init (fn []
(.on (js-this) "success" (fn [_ files] (.on (js-this) "success" (fn [_ files]
(re-frame/dispatch [::events/view-pending-invoices])))) (re-frame/dispatch [::invalidated]))))
:paramName "file" :paramName "file"
:headers {"Authorization" (str "Token " @token)} :headers {"Authorization" (str "Token " @token)}
:url (str "/api/invoices/upload" :url (str "/api/invoices/upload"
@@ -31,10 +32,66 @@
(str "?company=" company-name))) (str "?company=" company-name)))
:previewsContainer "#dz-hidden" :previewsContainer "#dz-hidden"
:previewTemplate "<div class='dz-hidden-preview'></div>"})))}))) :previewTemplate "<div class='dz-hidden-preview'></div>"})))})))
(re-frame/reg-sub
::invoices
(fn [db]
(-> db ::invoices)))
(re-frame/reg-sub
::params
(fn [db]
(-> db (::params {}))))
(re-frame/reg-event-fx
::invalidated
(fn [cofx [_ params]]
{:dispatch [::params-change @(re-frame/subscribe [::params])]}))
(re-frame/reg-event-fx
::params-change
(fn [cofx [_ params]]
{:db (-> (:db cofx)
(assoc-in [:status :loading] true)
(assoc-in [::params] params))
:graphql {:token (-> cofx :db :user)
:query-obj (invoice-table/query (assoc params :imported false))
:on-success [::received]}}))
(re-frame/reg-event-db
::received
(fn [db [_ data]]
(-> db
(assoc ::invoices (:invoice data))
(assoc-in [:status :loading] false))))
(re-frame/reg-event-fx
::reject-invoices
(fn [cofx [_ on-success]]
{:http {:method :post
:token (-> cofx :db :user)
:uri (str "/api/invoices/reject"
(when-let [company-id (:id @(re-frame/subscribe [::subs/company]))]
(str "?company=" company-id)))
:on-success on-success
}}))
(re-frame/reg-event-fx
::approve-invoices
(fn [cofx [_ on-success]]
{:http {:method :post
:token (-> cofx :db :user)
:uri (str "/api/invoices/approve"
(when-let [company-id (:id @(re-frame/subscribe [::subs/company]))]
(str "?company=" company-id)))
:on-success on-success
}}))
(def import-invoices-page (def import-invoices-page
(with-meta (with-meta
(fn [] (fn []
(let [invoices (re-frame/subscribe [::subs/pending-invoices]) (let [invoices (re-frame/subscribe [::invoices])
status (re-frame/subscribe [::subs/status])] status (re-frame/subscribe [::subs/status])]
[:div {:class "inbox-messages"} [:div {:class "inbox-messages"}
[:h1.title "Upload invoices"] [:h1.title "Upload invoices"]
@@ -49,40 +106,26 @@
[:h1.title [:h1.title
[:i.fa.fa-spin.fa-spinner]] [:i.fa.fa-spin.fa-spinner]]
(if (seq @invoices) (if (seq @invoices)
[:table {:class "table", :style {:width "100%"}} [invoice-table {:id :approved
[:thead :invoices invoices
[:tr :status (re-frame/subscribe [::subs/status])
[:th "Vendor"] :params (re-frame/subscribe [::params])
[:th "Customer"] :on-params-change (fn [params]
[:th "Invoice #"] (re-frame/dispatch [::params-change params])) }]
[:th "Date"]
[:th "Amount"]
[:th]]]
[:tbody (for [{:keys [vendor vendor-id potential-duplicate company customer-identifier invoice-number date total id] :as i} @invoices]
^{:key id}
[:tr
[:td (:name (:vendor i))]
(if company
[:td (:name (:company i))]
[:td [:i.icon.fa.fa-warning {:title "potential duplicate"}]
(str "'" customer-identifier "' doesn't match any known company")])
[:td invoice-number]
[:td date]
[:td total]
[:td (when potential-duplicate
[:i.icon.fa.fa-warning {:title "potential duplicate"}])]])]]
[:span "No pending invoices"]))] [:span "No pending invoices"]))]
(if (and (seq @invoices) (not (:loading @status))) (if (and (seq @invoices) (not (:loading @status)))
[:div.card-footer [:div.card-footer
[:a.card-footer-item [:a.card-footer-item
{:on-click (fn [e] {:on-click (fn [e]
(.preventDefault e) (.preventDefault e)
(re-frame/dispatch [::events/approve-invoices]))} (re-frame/dispatch [::approve-invoices
[::invalidated]]))}
"Accept all"] "Accept all"]
[:a.card-footer-item [:a.card-footer-item
{:on-click (fn [e] {:on-click (fn [e]
(.preventDefault e) (.preventDefault e)
(re-frame/dispatch [::events/reject-invoices]))} (re-frame/dispatch [::reject-invoices
[::invalidated]]))}
"Reject all"]])]])) "Reject all"]])]]))
{:component-will-mount (fn [] {:component-will-mount (fn []
(re-frame/dispatch [::events/view-pending-invoices]))})) (re-frame/dispatch-sync [::invalidated]))}))

View File

@@ -3,32 +3,51 @@
[auto-ap.entities.companies :as company] [auto-ap.entities.companies :as company]
[auto-ap.entities.vendors :as vendor] [auto-ap.entities.vendors :as vendor]
[auto-ap.events :as events] [auto-ap.events :as events]
[auto-ap.views.components.invoice-table :refer [invoice-table] :as invoice-table]
[auto-ap.views.components.invoice-table :refer [invoice-table]]
[auto-ap.subs :as subs] [auto-ap.subs :as subs]
[auto-ap.events :as events])) [auto-ap.events :as events]))
(re-frame/reg-sub
::invoices
(fn [db]
(-> db ::invoices)))
(re-frame/reg-sub
::params
(fn [db]
(-> db (::params {}))))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::params-change ::params-change
(fn [cofx [_ params]] (fn [cofx [_ params]]
{:db (assoc-in (:db cofx) [:status :loading] true) {:db (-> (:db cofx)
(assoc-in [:status :loading] true)
(assoc-in [::params] params))
:graphql {:token (-> cofx :db :user) :graphql {:token (-> cofx :db :user)
:query-obj {:venia/queries [[:invoice :query-obj (invoice-table/query (assoc params :imported true))
{:imported true :on-success [::received]}}))
:company_id (:id @(re-frame/subscribe [::subs/company]))
:sort-by (:sort-by params) (re-frame/reg-event-db
:asc (:asc params true)} ::received
[:id :total :invoice-number :date [:vendor [:name :id]] [:company [:name :id]]]]]} (fn [db [_ data]]
:on-success [::events/received-invoices :unpaid]}})) (-> db
(assoc ::invoices (:invoice data))
(assoc-in [:status :loading] false))))
(re-frame/reg-event-fx
::invalidated
(fn [cofx [_ params]]
{:dispatch [::params-change @(re-frame/subscribe [::params])]}))
(def unpaid-invoices-page (def unpaid-invoices-page
(with-meta (with-meta
(fn [] (fn []
[:div {:class "inbox-messages"} [:div
[:h1.title "Unpaid invoices"] [:h1.title "Unpaid invoices"]
[invoice-table {:id :unpaid [invoice-table {:id :unpaid
:invoices (re-frame/subscribe [::subs/unpaid-invoices]) :params (re-frame/subscribe [::params])
:invoices (re-frame/subscribe [::invoices])
:status (re-frame/subscribe [::subs/status]) :status (re-frame/subscribe [::subs/status])
:on-params-change (fn [params] :on-params-change (fn [params]
(re-frame/dispatch [::params-change params])) }]]) (re-frame/dispatch [::params-change params])) }]])
{:component-will-mount #(re-frame/dispatch-sync [::events/view-unpaid-invoices]) })) {:component-will-mount #(re-frame/dispatch-sync [::params-change {}]) }))