for better or worse, moving to localized events and subs.
This commit is contained in:
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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]))}))
|
||||||
|
|||||||
@@ -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 {}]) }))
|
||||||
|
|||||||
Reference in New Issue
Block a user