lots of QOL improvements.
This commit is contained in:
29
src/clj/auto_ap/background/invoices.clj
Normal file
29
src/clj/auto_ap/background/invoices.clj
Normal file
@@ -0,0 +1,29 @@
|
||||
(ns auto-ap.background.invoices
|
||||
(:require [auto-ap.datomic.invoices :as d-invoices]
|
||||
[auto-ap.datomic :refer [uri]]
|
||||
[datomic.api :as d]
|
||||
[auto-ap.time :as time]
|
||||
[clj-time.coerce :as coerce]))
|
||||
|
||||
(def break (atom false))
|
||||
|
||||
(defn close-auto-invoices []
|
||||
(while (and (not @break)
|
||||
(not (Thread/interrupted)))
|
||||
(println "Clearing automatic invoices")
|
||||
(try
|
||||
(->> (d/query {:query {:find ['?e]
|
||||
:in ['$ '?today]
|
||||
:where ['[?e :invoice/automatically-paid-when-due true]
|
||||
'[?e :invoice/status :invoice-status/unpaid]
|
||||
'[?e :invoice/due ?d]
|
||||
'[(<= ?d ?today)]]}
|
||||
:args [(d/db (d/connect uri)) (coerce/to-date (time/local-now))]})
|
||||
(mapv (fn [[i]] {:db/id i
|
||||
:invoice/outstanding-balance 0.0
|
||||
:invoice/status :invoice-status/paid}))
|
||||
(d/transact (d/connect uri))
|
||||
deref)
|
||||
(Thread/sleep (* 1000 60 60))
|
||||
(catch Exception e
|
||||
(println (.toString e))))))
|
||||
@@ -194,15 +194,27 @@
|
||||
|
||||
|
||||
(defn get-existing-set []
|
||||
(d/query
|
||||
(cond-> {:query {:find ['?vendor '?client '?invoice-number]
|
||||
:in ['$]
|
||||
:where '[[?e :invoice/invoice-number ?invoice-number]
|
||||
[?e :invoice/vendor ?vendor]
|
||||
[?e :invoice/client ?client]
|
||||
(not [?e :invoice/status :invoice-status/voided])
|
||||
]}
|
||||
|
||||
:args [(d/db (d/connect uri))]})))
|
||||
(let [vendored-results (set (d/query {:query {:find ['?vendor '?client '?invoice-number]
|
||||
:in ['$]
|
||||
:where '[[?e :invoice/invoice-number ?invoice-number]
|
||||
[?e :invoice/vendor ?vendor]
|
||||
[?e :invoice/client ?client]
|
||||
(not [?e :invoice/status :invoice-status/voided])
|
||||
]}
|
||||
|
||||
:args [(d/db (d/connect uri))]}))
|
||||
vendorless-results (->> (d/query {:query {:find ['?client '?invoice-number]
|
||||
:in ['$]
|
||||
:where '[[?e :invoice/invoice-number ?invoice-number]
|
||||
(not [?e :invoice/vendor])
|
||||
[?e :invoice/client ?client]
|
||||
(not [?e :invoice/status :invoice-status/voided])
|
||||
]}
|
||||
|
||||
:args [(d/db (d/connect uri))]})
|
||||
(mapv (fn [[client invoice-number]]
|
||||
[nil client invoice-number]) )
|
||||
set)]
|
||||
(into vendored-results vendorless-results)))
|
||||
|
||||
|
||||
|
||||
@@ -107,9 +107,12 @@
|
||||
:extract {:date #"INVOICE DATE(?s:.*)(?= (?:[0-9]+/[0-9]+/[0-9]+)\s+([0-9]+/[0-9]+/[0-9]+)) "
|
||||
:customer-identifier #"SOLD TO:(?:.*)(?=\n)\n(.*)(?=\s{2,})" ;; ([\S ]+)\s{2,}
|
||||
:invoice-number #"INVOICE\n(?:.*?)(?=\d{4,})(\d+)"
|
||||
:total #"PAY THIS AMOUNT(?s:.*)(?= ([0-9,]+\.[0-9]{2}))"}
|
||||
:total #"PAY THIS AMOUNT(?s:.*)(?= ([0-9,]+\.[0-9]{2}))"
|
||||
:account-number #"ACCOUNT #.*\n.*\n\s+(\d+)"}
|
||||
:parser {:date [:clj-time "MM/dd/yy"]
|
||||
:total [:trim-commas nil]}}
|
||||
:total [:trim-commas nil]}
|
||||
:multi #"\f"
|
||||
:multi-match? #"PAY THIS AMOUNT"}
|
||||
|
||||
;; GOLDEN BRANDS
|
||||
{:vendor "Golden Brands San Jose"
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
(defn parse-vendor-id [{:keys [vendor]}]
|
||||
(:db/id vendor))
|
||||
|
||||
(defn parse-automatically-paid-when-due [{:keys [vendor client-id]}]
|
||||
(boolean ((set (map :db/id (:vendor/automatically-paid-when-due vendor))) client-id)))
|
||||
|
||||
(defn parse-amount [i]
|
||||
(try
|
||||
(Double/parseDouble (str/replace (or (second
|
||||
@@ -121,6 +124,7 @@
|
||||
(map (parse-or-error :client-id #(parse-client % all-clients)))
|
||||
(map (parse-or-error :vendor #(parse-vendor % all-vendors)))
|
||||
(map (parse-or-error :vendor-id #(parse-vendor-id %)))
|
||||
(map (parse-or-error :automatically-paid-when-due #(parse-automatically-paid-when-due %)))
|
||||
(map (parse-or-error :account-id parse-account-numeric-code))
|
||||
(map (parse-or-error :invoice-number parse-invoice-number))
|
||||
(map (parse-or-error :total parse-amount))
|
||||
@@ -131,13 +135,14 @@
|
||||
|
||||
(defn invoice-rows->transaction [rows]
|
||||
(->> rows
|
||||
(mapcat (fn [{:keys [vendor-id total client-id amount date invoice-number default-location account-id check vendor]}]
|
||||
(mapcat (fn [{:keys [vendor-id total client-id amount date invoice-number default-location account-id check vendor automatically-paid-when-due]}]
|
||||
(let [invoice (cond->
|
||||
#:invoice {:db/id (.toString (java.util.UUID/randomUUID))
|
||||
:vendor vendor-id
|
||||
:client client-id
|
||||
:default-location default-location
|
||||
:import-status :import-status/imported
|
||||
:automatically-paid-when-due automatically-paid-when-due
|
||||
#_#_:default-expense-account default-expense-account
|
||||
:total total
|
||||
:outstanding-balance (if (= "Cash" check)
|
||||
@@ -245,7 +250,8 @@
|
||||
". "
|
||||
(.toString e))
|
||||
{:args [ invoice-number matching-vendor (:db/id matching-client)]})))
|
||||
))]
|
||||
))
|
||||
automatically-paid-for (set (map :db/id (:vendor/automatically-paid-when-due matching-vendor)))]
|
||||
|
||||
(cond
|
||||
(not (and matching-location matching-client))
|
||||
@@ -259,6 +265,7 @@
|
||||
:invoice/client-identifier customer-identifier
|
||||
:invoice/vendor (:db/id matching-vendor)
|
||||
:invoice/invoice-number invoice-number
|
||||
:invoice/automatically-paid-when-due (boolean (automatically-paid-for (:db/id matching-client)))
|
||||
:invoice/total (Double/parseDouble total)
|
||||
:invoice/date (to-date date)
|
||||
:invoice/import-status :import-status/pending
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[auto-ap.handler :refer [app]]
|
||||
[auto-ap.ledger :refer [process-all keep-up-to-date]]
|
||||
[auto-ap.yodlee.core :refer [load-in-memory-cache]]
|
||||
[auto-ap.background.invoices :refer [close-auto-invoices]]
|
||||
[nrepl.server :refer [start-server stop-server]]
|
||||
[config.core :refer [env]]
|
||||
[ring.adapter.jetty :refer [run-jetty]])
|
||||
@@ -18,5 +19,6 @@
|
||||
(future (process-all))
|
||||
(future (load-in-memory-cache))
|
||||
(future (keep-up-to-date))
|
||||
(future (close-auto-invoices))
|
||||
#_(future (always-process-sqs))
|
||||
(run-jetty app {:port port :join? false})))
|
||||
|
||||
@@ -36,3 +36,12 @@
|
||||
|
||||
(defn dollars= [amt1 amt2]
|
||||
(dollars-0? (- amt1 amt2) ))
|
||||
|
||||
(defn deep-merge [v & vs]
|
||||
(letfn [(rec-merge [v1 v2]
|
||||
(if (and (map? v1) (map? v2))
|
||||
(merge-with deep-merge v1 v2)
|
||||
v2))]
|
||||
(if (some identity vs)
|
||||
(reduce #(rec-merge %1 %2) v vs)
|
||||
(last vs))))
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
(-> params
|
||||
(assoc
|
||||
:client-id (:id @(re-frame/subscribe [::subs/client]))))
|
||||
[[:invoices [:id :total :outstanding-balance :invoice-number :date :due :status :client-identifier
|
||||
[[:invoices [:id :total :outstanding-balance :invoice-number :date :due :status :client-identifier :automatically-paid-when-due
|
||||
[:vendor [:name :id]]
|
||||
[:expense_accounts [:amount :id :location
|
||||
[:account [:id ]]]]
|
||||
@@ -81,17 +81,20 @@
|
||||
{:db (merge table-params params)}))
|
||||
|
||||
(defn row [{:keys [invoice check-boxes checked on-check-changed selected-client overrides expense-event on-edit-invoice on-void-invoice on-unvoid-invoice]}]
|
||||
(let [{:keys [client payments expense-accounts invoice-number date due total outstanding-balance id vendor] :as i} invoice
|
||||
(let [{:keys [client payments expense-accounts invoice-number date due total outstanding-balance id vendor checkable?] :as i} invoice
|
||||
accounts-by-id @(re-frame/subscribe [::subs/accounts-by-id client])
|
||||
account->name #(:name (accounts-by-id (:id %)))]
|
||||
[:tr {:class (:class i)}
|
||||
(when check-boxes
|
||||
[:td [:input.checkbox {:type "checkbox"
|
||||
:checked (if (get checked id)
|
||||
"checked"
|
||||
"")
|
||||
:on-change (fn [x e] (when on-check-changed
|
||||
(on-check-changed id i)))} ]])
|
||||
[:td.expandable
|
||||
[:input.checkbox (cond-> {:type "checkbox"
|
||||
|
||||
:checked (if (get checked id)
|
||||
"checked"
|
||||
"")
|
||||
:on-change (fn [x e] (when on-check-changed
|
||||
(on-check-changed id i)))}
|
||||
(boolean? checkable?) (assoc :disabled (not checkable?))) ]])
|
||||
(when-not selected-client
|
||||
[:td (if-let [client-override (:client overrides)]
|
||||
(client-override i)
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
[cljs-time.core :as c]
|
||||
[goog.string :as gstring]
|
||||
[bidi.bidi :as bidi]
|
||||
[auto-ap.utils :refer [deep-merge ]]
|
||||
[auto-ap.routes :as routes]
|
||||
[auto-ap.views.components.date-range-filter :refer [date-range-filter]]
|
||||
[auto-ap.views.components.number-filter :refer [number-filter]]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
|
||||
[auto-ap.views.utils :refer [active-when dispatch-event bind-field horizontal-field date->str str->date pretty standard query-params]]
|
||||
[auto-ap.views.utils :refer [active-when dispatch-event bind-field horizontal-field date->str str->date pretty standard query-params dispatch-value-change]]
|
||||
[auto-ap.subs :as subs]
|
||||
[auto-ap.events :as events]))
|
||||
|
||||
@@ -25,7 +26,6 @@
|
||||
:<- [::subs/vendors-by-id]
|
||||
:<- [::subs/query-params]
|
||||
(fn [[specific-filters vendors-by-id query-params] ]
|
||||
(println "Q:UERY" query-params)
|
||||
(let [url-filters (-> query-params
|
||||
(select-keys #{:vendor-id
|
||||
:date-range
|
||||
@@ -37,16 +37,13 @@
|
||||
url-filters {:vendor (when-let [vendor-id (:vendor-id url-filters)]
|
||||
{:id (str vendor-id)
|
||||
:name (get-in vendors-by-id [(str vendor-id) :name] "Loading...")})
|
||||
:date-range {:raw (:date-range url-filters)
|
||||
:settled (:date-range url-filters)}
|
||||
:date-range (:date-range url-filters)
|
||||
:due-range (:due-range url-filters)
|
||||
:amount-range {:raw {:amount-gte (:amount-gte url-filters)
|
||||
:amount-lte (:amount-lte url-filters)}
|
||||
:settled {:amount-gte (:amount-gte url-filters)
|
||||
:amount-lte (:amount-lte url-filters)}}
|
||||
:invoice-number-like {:raw (str (:invoice-number-like url-filters))
|
||||
:settled (str (:invoice-number-like url-filters))}}]
|
||||
(merge url-filters specific-filters ))))
|
||||
:amount-range {:amount-gte (:amount-gte url-filters)
|
||||
:amount-lte (:amount-lte url-filters)}
|
||||
:invoice-number-like (str (:invoice-number-like url-filters))}]
|
||||
|
||||
(deep-merge url-filters (or specific-filters {}) ))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::filter
|
||||
@@ -54,24 +51,34 @@
|
||||
(fn [filters [_ which]]
|
||||
(get filters which)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::settled-filters
|
||||
(fn [db ]
|
||||
(::settled-filters db)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::filter-params
|
||||
:<- [::settled-filters]
|
||||
:<- [::filters]
|
||||
:<- [::subs/active-page]
|
||||
|
||||
(fn [[filters ap ]]
|
||||
{:vendor-id (:id (:vendor filters))
|
||||
:date-range (:settled (:date-range filters))
|
||||
:due-range (:due-range filters)
|
||||
:amount-gte (:amount-gte (:settled (:amount-range filters)))
|
||||
:amount-lte (:amount-lte (:settled (:amount-range filters)))
|
||||
:invoice-number-like (:settled (:invoice-number-like filters))
|
||||
:status (condp = ap
|
||||
:invoices nil
|
||||
:unpaid-invoices :unpaid
|
||||
:paid-invoices :paid
|
||||
:voided-invoices :voided)}))
|
||||
(fn [[settled-filters filters ap ]]
|
||||
(let [filters (or settled-filters filters)]
|
||||
{:vendor-id (:id (:vendor filters))
|
||||
:date-range (:date-range filters)
|
||||
:due-range (:due-range filters)
|
||||
:amount-gte (:amount-gte (:amount-range filters))
|
||||
:amount-lte (:amount-lte (:amount-range filters))
|
||||
:invoice-number-like (:invoice-number-like filters)
|
||||
:status (condp = ap
|
||||
:invoices nil
|
||||
:unpaid-invoices :unpaid
|
||||
:paid-invoices :paid
|
||||
:voided-invoices :voided)})))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::filters-settled
|
||||
(fn [{:keys [db]} [_ & params]]
|
||||
{:db (assoc db ::settled-filters @(re-frame/subscribe [::filters]))}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::filter-changed
|
||||
@@ -80,66 +87,17 @@
|
||||
[which val] (if (= 3 (count params))
|
||||
[(into [a] b) c]
|
||||
[[a] b])]
|
||||
{:db (assoc-in db (into [::filters] which) val)})))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::invoice-number-like-settled
|
||||
[(re-frame/path [::filters :invoice-number-like])]
|
||||
(fn [{:keys [db]} [_ invoice-number-like]]
|
||||
{:db (assoc db :settled invoice-number-like)
|
||||
:dispatch [::filter-changed :invoice-number-like [:settled] invoice-number-like]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::amount-range-settled
|
||||
[(re-frame/path [::filters :amount-range])]
|
||||
(fn [{:keys [db]} [_ which value]]
|
||||
{:db (assoc-in db [:settled which] value)
|
||||
:dispatch [::filter-changed :amount-range [:settled] (assoc (:settled db) which value)]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::invoice-number-like-changed
|
||||
[(re-frame/path [::filters :invoice-number-like])]
|
||||
(fn [{:keys [db]} [_ invoice-number-like]]
|
||||
{:dispatch-debounce {:event [::invoice-number-like-settled invoice-number-like]
|
||||
:time 500
|
||||
:key ::invoice-number-like}
|
||||
:db (assoc db :raw invoice-number-like)}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::amount-range-changed
|
||||
[(re-frame/path [::filters :amount-range])]
|
||||
(fn [{:keys [db]} [_ [which] value]]
|
||||
{:dispatch-debounce
|
||||
{:event [::amount-range-settled which value]
|
||||
:time 500
|
||||
:key ::amount-range}
|
||||
:db (assoc-in db [:raw which] value)}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::date-range-settled
|
||||
[(re-frame/path [::filters :date-range])]
|
||||
(fn [{:keys [db]} [_ which value]]
|
||||
{:db (assoc-in db [:settled which] value)
|
||||
:dispatch [::filter-changed :date-range [:settled] (assoc (:settled db) which value)]}))
|
||||
|
||||
;; TODO for some reason reloading is borken, and typing will unset stuff, has nothing to do with it being debounced
|
||||
(re-frame/reg-event-fx
|
||||
::date-range-changed
|
||||
[(re-frame/path [::filters :date-range])]
|
||||
(fn [{:keys [db]} [_ [which] value]]
|
||||
(println which value)
|
||||
{:dispatch-debounce
|
||||
{:event [::date-range-settled which value]
|
||||
:time 1000
|
||||
:key ::date-range}
|
||||
:db (assoc-in db [:raw which] value)}))
|
||||
{:db (assoc-in db (into [::filters] which) val)
|
||||
:dispatch-debounce
|
||||
{:event [::filters-settled]
|
||||
:time 800
|
||||
:key ::filters}})))
|
||||
|
||||
(defn invoice-number-filter []
|
||||
[:div.field
|
||||
[:div.control [:input.input {:placeholder "AP-123"
|
||||
:value (:raw @(re-frame/subscribe [::filter :invoice-number-like]))
|
||||
:on-change (fn [x]
|
||||
(re-frame/dispatch [::invoice-number-like-changed (.. x -target -value) ]))} ]]])
|
||||
:value @(re-frame/subscribe [::filter :invoice-number-like])
|
||||
:on-change (dispatch-value-change [::filter-changed :invoice-number-like ])} ]]])
|
||||
|
||||
(defn invoices-side-bar [params]
|
||||
(let [ap @(re-frame/subscribe [::subs/active-page])
|
||||
@@ -191,8 +149,8 @@
|
||||
[:p.menu-label "Date Range"]
|
||||
[:div
|
||||
[date-range-filter
|
||||
{:on-change-event [::date-range-changed]
|
||||
:value (:raw @(re-frame/subscribe [::filter :date-range]))}]]
|
||||
{:on-change-event [::filter-changed :date-range]
|
||||
:value @(re-frame/subscribe [::filter :date-range])}]]
|
||||
|
||||
[:p.menu-label "Due Range"]
|
||||
[:div
|
||||
@@ -203,8 +161,8 @@
|
||||
[:p.menu-label "Amount"]
|
||||
[:div
|
||||
[number-filter
|
||||
{:on-change-event [::amount-range-changed]
|
||||
:value (:raw @(re-frame/subscribe [::filter :amount-range]))}]]
|
||||
{:on-change-event [::filter-changed :amount-range]
|
||||
:value @(re-frame/subscribe [::filter :amount-range])}]]
|
||||
|
||||
[:p.menu-label "Invoice #"]
|
||||
[:div
|
||||
|
||||
@@ -7,14 +7,15 @@
|
||||
[auto-ap.entities.clients :as client]
|
||||
[auto-ap.views.components.layouts :refer [side-bar-layout]]
|
||||
[auto-ap.views.components.invoices.side-bar :refer [invoices-side-bar]]
|
||||
[auto-ap.views.utils :refer [dispatch-event bind-field]]
|
||||
[auto-ap.views.utils :refer [dispatch-event bind-field with-user]]
|
||||
[auto-ap.utils :refer [by]]
|
||||
[auto-ap.entities.vendors :as vendor]
|
||||
[auto-ap.views.components.typeahead :refer [typeahead-entity]]
|
||||
[auto-ap.views.components.invoice-table :refer [invoice-table] :as invoice-table]
|
||||
[cljsjs.dropzone :as dropzone]
|
||||
[cljs.reader :as edn]
|
||||
[clojure.string :as str]))
|
||||
[clojure.string :as str]
|
||||
[vimsical.re-frame.cofx.inject :as inject]))
|
||||
(defn dropzone []
|
||||
(let [client (re-frame/subscribe [::subs/client])
|
||||
token (re-frame/subscribe [::subs/token])
|
||||
@@ -75,10 +76,6 @@
|
||||
(fn [db]
|
||||
(-> db ::error)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::params
|
||||
(fn [db]
|
||||
(-> db (::params {}))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::batch
|
||||
@@ -98,16 +95,36 @@
|
||||
:db (-> (:db cofx)
|
||||
(update ::batch inc))}))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::last-params
|
||||
(fn [db]
|
||||
(-> db ::last-params)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::params
|
||||
:<- [::last-params]
|
||||
:<- [::subs/client]
|
||||
:<- [::invoice-table/table-params]
|
||||
(fn [[last-params client table-params]]
|
||||
(println "RE-EVALUATING")
|
||||
(let [params (cond-> {:import-status "pending"}
|
||||
client (assoc :client-id (:id client))
|
||||
(seq table-params) (merge table-params))]
|
||||
(when (not= params last-params)
|
||||
(re-frame/dispatch [::params-change]))
|
||||
params)))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::params-change
|
||||
(fn [cofx [_ params]]
|
||||
[with-user (re-frame/inject-cofx ::inject/sub [::params])]
|
||||
(fn [{:keys [db user] ::keys [params]} [_]]
|
||||
|
||||
{:db (-> (:db cofx)
|
||||
{:db (-> db
|
||||
(dissoc ::error)
|
||||
(assoc-in [:status :loading] true)
|
||||
(assoc-in [::params] params))
|
||||
:graphql {:token (-> cofx :db :user)
|
||||
:query-obj (invoice-table/query (assoc params :import-status "pending"))
|
||||
(assoc-in [::last-params] params))
|
||||
:graphql {:token user
|
||||
:query-obj (invoice-table/query params)
|
||||
:on-success [::received]}}))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
@@ -210,6 +227,7 @@
|
||||
status (re-frame/subscribe [::subs/status])
|
||||
error (re-frame/subscribe [::error])
|
||||
batch (re-frame/subscribe [::batch])
|
||||
params @(re-frame/subscribe [::params])
|
||||
client (:id @(re-frame/subscribe [::subs/client]))]
|
||||
^{:key (str client "-" @batch)}
|
||||
[:div
|
||||
@@ -227,24 +245,18 @@
|
||||
[:span {:class "card-header-title"} "Found Invoices"]]
|
||||
[:div {:class "card-content"}
|
||||
[approve-reject-button (:checked @invoice-page)]
|
||||
(if (:loading @status)
|
||||
[:h1.title
|
||||
[:i.fa.fa-spin.fa-spinner]]
|
||||
(if (seq (:invoices @invoice-page))
|
||||
[invoice-table {:id :approved
|
||||
:invoice-page invoice-page
|
||||
:overrides {:client (fn [row]
|
||||
[:p (:name (:client row))
|
||||
[:p [:i.is-size-7 (:client-identifier row)]]])}
|
||||
:check-boxes true
|
||||
:checked (:checked @invoice-page)
|
||||
:on-check-changed (fn [which invoice]
|
||||
(re-frame/dispatch [::toggle-check which invoice]))
|
||||
:status (re-frame/subscribe [::subs/status])
|
||||
:params (re-frame/subscribe [::params])
|
||||
:on-params-change (fn [params]
|
||||
(re-frame/dispatch [::params-change params])) }]
|
||||
[:span "No pending invoices"]))]]]))
|
||||
(if (seq (:invoices @invoice-page))
|
||||
[invoice-table {:id :approved
|
||||
:invoice-page invoice-page
|
||||
:overrides {:client (fn [row]
|
||||
[:p (:name (:client row))
|
||||
[:p [:i.is-size-7 (:client-identifier row)]]])}
|
||||
:check-boxes true
|
||||
:checked (:checked @invoice-page)
|
||||
:on-check-changed (fn [which invoice]
|
||||
(re-frame/dispatch [::toggle-check which invoice]))
|
||||
:status (re-frame/subscribe [::subs/status])}]
|
||||
[:span "No pending invoices"])]]]))
|
||||
{:component-will-mount (fn []
|
||||
(re-frame/dispatch-sync [::invalidated]))}))
|
||||
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
(fn [db ]
|
||||
(::filters db {})))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::settled-filters
|
||||
(fn [db ]
|
||||
(::settled-filters db)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::filters
|
||||
:<- [::specific-filters]
|
||||
@@ -38,7 +43,6 @@
|
||||
:numeric-code (get-in accounts-by-id [(str account-id) :numeric-code] "Loading...")
|
||||
:name (get-in accounts-by-id [(str account-id) :name] "Loading...")})
|
||||
:date-range (:date-range url-filters)}]
|
||||
(println url-filters specific-filters)
|
||||
(merge url-filters specific-filters ))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
@@ -49,13 +53,19 @@
|
||||
|
||||
(re-frame/reg-sub
|
||||
::filter-params
|
||||
:<- [::settled-filters]
|
||||
:<- [::filters]
|
||||
(fn [filters]
|
||||
{:vendor-id (:id (:vendor filters))
|
||||
:account-id (:id (:account filters))
|
||||
:date-range (:date-range filters)
|
||||
:bank-account-id (:id (:bank-account filters))}))
|
||||
(fn [[settled-filters filters]]
|
||||
(let [filters (or settled-filters filters)]
|
||||
{:vendor-id (:id (:vendor filters))
|
||||
:account-id (:id (:account filters))
|
||||
:date-range (:date-range filters)
|
||||
:bank-account-id (:id (:bank-account filters))})))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::filters-settled
|
||||
(fn [{:keys [db]} [_ & params]]
|
||||
{:db (assoc db ::settled-filters @(re-frame/subscribe [::filters]))}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::filter-changed
|
||||
@@ -64,7 +74,11 @@
|
||||
[which val] (if (= 3 (count params))
|
||||
[(into [a] b) c]
|
||||
[[a] b])]
|
||||
{:db (assoc-in db (into [::filters] which) val)})))
|
||||
{:db (assoc-in db (into [::filters] which) val)
|
||||
:dispatch-debounce
|
||||
{:event [::filters-settled]
|
||||
:time 800
|
||||
:key ::filters}})))
|
||||
|
||||
(defn ledger-side-bar []
|
||||
(let [ap @(re-frame/subscribe [::subs/active-page])
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
(re-frame/reg-event-fx
|
||||
::unmounted
|
||||
(fn [{:keys [db]} _]
|
||||
{:db (dissoc db ::last-params ::table/table-params ::side-bar/filters ::payment-page)}))
|
||||
{:db (dissoc db ::last-params ::table/table-params ::side-bar/filters ::side-bar/settled-filters ::payment-page)}))
|
||||
|
||||
(defn content []
|
||||
(let [params @(re-frame/subscribe [::params])]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns auto-ap.views.pages.payments.side-bar
|
||||
(:require [auto-ap.routes :as routes]
|
||||
[auto-ap.subs :as subs]
|
||||
[auto-ap.views.utils :refer [active-when]]
|
||||
[auto-ap.views.utils :refer [active-when dispatch-value-change]]
|
||||
[auto-ap.views.components.vendor-filter :refer [vendor-filter]]
|
||||
[auto-ap.views.components.date-range-filter :refer [date-range-filter]]
|
||||
[auto-ap.views.components.number-filter :refer [number-filter]]
|
||||
@@ -15,6 +15,11 @@
|
||||
(fn [db ]
|
||||
(::filters db {})))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::settled-filters
|
||||
(fn [db ]
|
||||
(::settled-filters db)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::filters
|
||||
:<- [::specific-filters]
|
||||
@@ -32,15 +37,11 @@
|
||||
{:id (str vendor-id)
|
||||
:name (get-in vendors-by-id [(str vendor-id) :name] "Loading...")})
|
||||
:date-range (:date-range url-filters)
|
||||
:amount-range {:raw {:amount-gte (:amount-gte url-filters)
|
||||
:amount-lte (:amount-lte url-filters)}
|
||||
:settled {:amount-gte (:amount-gte url-filters)
|
||||
:amount-lte (:amount-lte url-filters)}}
|
||||
:check-number-like {:raw (:check-number-like url-filters)
|
||||
:settled (:check-number-like url-filters)}
|
||||
:invoice-number {:raw (:invoice-number url-filters)
|
||||
:settled (:invoice-number url-filters)}}]
|
||||
(println "URL filters" url-filters)
|
||||
:amount-range {:amount-gte (:amount-gte url-filters)
|
||||
:amount-lte (:amount-lte url-filters)}
|
||||
:check-number-like (:check-number-like url-filters)
|
||||
:invoice-number (:invoice-number url-filters)}]
|
||||
|
||||
(merge url-filters specific-filters ))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
@@ -51,15 +52,22 @@
|
||||
|
||||
(re-frame/reg-sub
|
||||
::filter-params
|
||||
:<- [::settled-filters]
|
||||
:<- [::filters]
|
||||
(fn [filters]
|
||||
{:vendor-id (:id (:vendor filters))
|
||||
:date-range (:date-range filters)
|
||||
:amount-gte (:amount-gte (:settled (:amount-range filters)))
|
||||
:amount-lte (:amount-lte (:settled (:amount-range filters)))
|
||||
:check-number-like (:settled (:check-number-like filters))
|
||||
:invoice-number (:settled (:invoice-number filters))}))
|
||||
(fn [[settled-filters filters]]
|
||||
(let [filters (or settled-filters filters)]
|
||||
{:vendor-id (:id (:vendor filters))
|
||||
:date-range (:date-range filters)
|
||||
:amount-gte (:amount-gte (:amount-range filters))
|
||||
:amount-lte (:amount-lte (:amount-range filters))
|
||||
:check-number-like (:check-number-like filters)
|
||||
:invoice-number (:invoice-number filters)})))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::filters-settled
|
||||
(fn [{:keys [db]} [_ & params]]
|
||||
|
||||
{:db (assoc db ::settled-filters @(re-frame/subscribe [::filters]))}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::filter-changed
|
||||
@@ -68,72 +76,23 @@
|
||||
[which val] (if (= 3 (count params))
|
||||
[(into [a] b) c]
|
||||
[[a] b])]
|
||||
{:db (assoc-in db (into [::filters] which) val)})))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::check-number-like-settled
|
||||
[(re-frame/path [::filters :check-number-like])]
|
||||
(fn [{:keys [db]} [_ description]]
|
||||
{:db (assoc db :settled description)
|
||||
:dispatch [::filter-changed :check-number-like [:settled] description]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::invoice-number-settled
|
||||
[(re-frame/path [::filters :invoice-number])]
|
||||
(fn [{:keys [db]} [_ description]]
|
||||
{:db (assoc db :settled description)
|
||||
:dispatch [::filter-changed :invoice-number [:settled] description]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::amount-range-settled
|
||||
[(re-frame/path [::filters :amount-range])]
|
||||
(fn [{:keys [db]} [_ which value]]
|
||||
{:db (assoc-in db [:settled which] value)
|
||||
:dispatch [::filter-changed :amount-range [:settled] (assoc (:settled db) which value)]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::check-number-like-changed
|
||||
[(re-frame/path [::filters :check-number-like])]
|
||||
(fn [{:keys [db]} [_ description]]
|
||||
{:dispatch-debounce
|
||||
{:event [::check-number-like-settled description]
|
||||
:time 500
|
||||
:key ::check-number-like}
|
||||
:db (assoc db :raw description)}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::invoice-number-changed
|
||||
[(re-frame/path [::filters :invoice-number])]
|
||||
(fn [{:keys [db]} [_ description]]
|
||||
{:dispatch-debounce
|
||||
{:event [::invoice-number-settled description]
|
||||
:time 500
|
||||
:key ::invoice-number}
|
||||
:db (assoc db :raw description)}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::amount-range-changed
|
||||
[(re-frame/path [::filters :amount-range])]
|
||||
(fn [{:keys [db]} [_ [which] value]]
|
||||
{:dispatch-debounce
|
||||
{:event [::amount-range-settled which value]
|
||||
:time 500
|
||||
:key ::amount-range}
|
||||
:db (assoc-in db [:raw which] value)}))
|
||||
{:db (assoc-in db (into [::filters] which) val)
|
||||
:dispatch-debounce
|
||||
{:event [::filters-settled]
|
||||
:time 800
|
||||
:key ::filters}})))
|
||||
|
||||
(defn check-number-filter []
|
||||
[:div.field
|
||||
[:div.control [:input.input {:placeholder "10001"
|
||||
:value (:raw @(re-frame/subscribe [::filter :check-number-like]))
|
||||
:on-change (fn [x]
|
||||
(re-frame/dispatch [::check-number-like-changed (.. x -target -value) ]))} ]]])
|
||||
:value @(re-frame/subscribe [::filter :check-number-like])
|
||||
:on-change (dispatch-value-change [::filter-changed :check-number-like])} ]]])
|
||||
|
||||
(defn invoice-number-filter []
|
||||
[:div.field
|
||||
[:div.control [:input.input {:placeholder "SJ-12345"
|
||||
:value (:raw @(re-frame/subscribe [::filter :invoice-number]))
|
||||
:on-change (fn [x]
|
||||
(re-frame/dispatch [::invoice-number-changed (.. x -target -value) ]))} ]]])
|
||||
:value @(re-frame/subscribe [::filter :invoice-number])
|
||||
:on-change (dispatch-value-change [::filter-changed :invoice-number])} ]]])
|
||||
|
||||
(defn side-bar []
|
||||
(let [ap @(re-frame/subscribe [::subs/active-page])
|
||||
@@ -156,10 +115,9 @@
|
||||
|
||||
[:p.menu-label "Amount"]
|
||||
[:div
|
||||
(println (:raw @(re-frame/subscribe [::filter :amount-range])))
|
||||
[number-filter
|
||||
{:on-change-event [::amount-range-changed]
|
||||
:value (:raw @(re-frame/subscribe [::filter :amount-range]))}]]
|
||||
{:on-change-event [::filter-changed :amount-range]
|
||||
:value @(re-frame/subscribe [::filter :amount-range])}]]
|
||||
|
||||
[:p.menu-label "Check #"]
|
||||
[:div [check-number-filter]]
|
||||
|
||||
@@ -82,7 +82,8 @@
|
||||
:total
|
||||
:start
|
||||
:end]]]}
|
||||
:on-success [::received]}}))
|
||||
:on-success [::received]}
|
||||
:set-uri-params (dissoc params :status :client-id)}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::unapprove-all
|
||||
@@ -106,7 +107,7 @@
|
||||
(re-frame/reg-event-fx
|
||||
::unmounted
|
||||
(fn [{:keys [db]} _]
|
||||
{:db (dissoc db ::last-params ::table/table-params ::side-bar/filters ::transaction-page)}))
|
||||
{:db (dissoc db ::last-params ::table/table-params ::side-bar/filters ::side-bar/settled-filters ::transaction-page)}))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::received
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns auto-ap.views.pages.transactions.side-bar
|
||||
(:require [auto-ap.routes :as routes]
|
||||
[auto-ap.subs :as subs]
|
||||
[auto-ap.views.utils :refer [active-when]]
|
||||
[auto-ap.views.utils :refer [active-when dispatch-value-change]]
|
||||
[auto-ap.views.components.date-range-filter :refer [date-range-filter]]
|
||||
[auto-ap.views.components.number-filter :refer [number-filter]]
|
||||
[auto-ap.views.components.bank-account-filter :refer [bank-account-filter]]
|
||||
@@ -9,33 +9,72 @@
|
||||
[bidi.bidi :as bidi]
|
||||
[re-frame.core :as re-frame]))
|
||||
(re-frame/reg-sub
|
||||
::filters
|
||||
::specific-filters
|
||||
(fn [db ]
|
||||
(::filters db {})))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::filters
|
||||
:<- [::specific-filters]
|
||||
:<- [::subs/vendors-by-id]
|
||||
:<- [::subs/bank-accounts-by-id]
|
||||
:<- [::subs/query-params]
|
||||
(fn [[specific-filters vendors-by-id bank-accounts-by-id query-params] ]
|
||||
|
||||
|
||||
(let [url-filters (-> query-params
|
||||
(select-keys #{:vendor-id
|
||||
:bank-account-id
|
||||
:date-range
|
||||
:description
|
||||
:amount-gte
|
||||
:amount-lte}))
|
||||
url-filters {:vendor (when-let [vendor-id (:vendor-id url-filters)]
|
||||
{:id (str vendor-id)
|
||||
:name (get-in vendors-by-id [(str vendor-id) :name] "Loading...")})
|
||||
:bank-account (when-let [bank-account-id (:bank-account-id url-filters)]
|
||||
{:id (str bank-account-id)
|
||||
:name (get-in bank-accounts-by-id [(str bank-account-id) :name] "Loading...")})
|
||||
:amount-range {:amount-gte (:amount-gte url-filters)
|
||||
:amount-lte (:amount-lte url-filters)}
|
||||
:description (:description url-filters)
|
||||
:date-range (:date-range url-filters)}]
|
||||
(merge url-filters specific-filters ))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::filter
|
||||
:<- [::filters]
|
||||
(fn [filters [_ which]]
|
||||
(filters which)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::settled-filters
|
||||
(fn [db ]
|
||||
(::settled-filters db)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::filter-params
|
||||
:<- [::settled-filters]
|
||||
:<- [::filters]
|
||||
:<- [::subs/active-page]
|
||||
(fn [[filters ap]]
|
||||
{:vendor-id (:id (:vendor filters))
|
||||
:date-range (:date-range filters)
|
||||
:bank-account-id (:id (:bank-account filters))
|
||||
:amount-gte (:amount-gte (:settled (:amount-range filters)))
|
||||
:amount-lte (:amount-lte (:settled (:amount-range filters)))
|
||||
:description (:settled (:description filters))
|
||||
:approval-status (condp = ap
|
||||
:transactions nil
|
||||
:unapproved-transactions :unapproved
|
||||
:requires-feedback-transactions :requires-feedback
|
||||
:excluded-transactions :excluded
|
||||
:approved-transactions :approved)}))
|
||||
(fn [[settled-filters filters ap]]
|
||||
(let [filters (or settled-filters filters)]
|
||||
{:vendor-id (:id (:vendor filters))
|
||||
:date-range (:date-range filters)
|
||||
:bank-account-id (:id (:bank-account filters))
|
||||
:amount-gte (:amount-gte (:amount-range filters))
|
||||
:amount-lte (:amount-lte (:amount-range filters))
|
||||
:description (:description filters)
|
||||
:approval-status (condp = ap
|
||||
:transactions nil
|
||||
:unapproved-transactions :unapproved
|
||||
:requires-feedback-transactions :requires-feedback
|
||||
:excluded-transactions :excluded
|
||||
:approved-transactions :approved)})))
|
||||
(re-frame/reg-event-fx
|
||||
::filters-settled
|
||||
(fn [{:keys [db]} [_ & params]]
|
||||
{:db (assoc db ::settled-filters @(re-frame/subscribe [::filters]))}))
|
||||
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
@@ -45,42 +84,11 @@
|
||||
[which val] (if (= 3 (count params))
|
||||
[(into [a] b) c]
|
||||
[[a] b])]
|
||||
{:db (assoc-in db (into [::filters] which) val)})))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::description-settled
|
||||
[(re-frame/path [::filters :description])]
|
||||
(fn [{:keys [db]} [_ description]]
|
||||
{:db (assoc db :settled description)
|
||||
:dispatch [::filter-changed :description [:settled] description]}))
|
||||
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::description-changed
|
||||
[(re-frame/path [::filters :description])]
|
||||
(fn [{:keys [db]} [_ description]]
|
||||
{:dispatch-debounce
|
||||
{:event [::description-settled description]
|
||||
:time 500
|
||||
:key ::description}
|
||||
:db (assoc db :raw description)}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::amount-range-settled
|
||||
[(re-frame/path [::filters :amount-range])]
|
||||
(fn [{:keys [db]} [_ which value]]
|
||||
{:db (assoc-in db [:settled which] value)
|
||||
:dispatch [::filter-changed :amount-range [:settled] (assoc (:settled db) which value)]}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::amount-range-changed
|
||||
[(re-frame/path [::filters :amount-range])]
|
||||
(fn [{:keys [db]} [_ [which] value]]
|
||||
{:dispatch-debounce
|
||||
{:event [::amount-range-settled which value]
|
||||
:time 500
|
||||
:key ::amount-range}
|
||||
:db (assoc-in db [:raw which] value)}))
|
||||
{:db (assoc-in db (into [::filters] which) val)
|
||||
:dispatch-debounce
|
||||
{:event [::filters-settled]
|
||||
:time 800
|
||||
:key ::filters}})))
|
||||
|
||||
(defn side-bar []
|
||||
(let [ap @(re-frame/subscribe [::subs/active-page])
|
||||
@@ -136,8 +144,8 @@
|
||||
[:p.menu-label "Amount"]
|
||||
[:div
|
||||
[number-filter
|
||||
{:on-change-event [::amount-range-changed]
|
||||
:value (:raw @(re-frame/subscribe [::filter :amount-range]))}]]
|
||||
{:on-change-event [::filter-changed :amount-range]
|
||||
:value @(re-frame/subscribe [::filter :amount-range])}]]
|
||||
|
||||
[:p.menu-label "Vendor"]
|
||||
[:div
|
||||
@@ -151,7 +159,6 @@
|
||||
[:div
|
||||
[:div.field
|
||||
[:div.control [:input.input {:placeholder "CHECK 123 ABC"
|
||||
:value (:raw @(re-frame/subscribe [::filter :description]))
|
||||
:on-change (fn [e]
|
||||
(re-frame/dispatch [::description-changed (.. e -target -value) ]))} ]]]]]))
|
||||
:value @(re-frame/subscribe [::filter :description])
|
||||
:on-change (dispatch-value-change [::filter-changed :description])} ]]]]]))
|
||||
|
||||
|
||||
@@ -38,7 +38,13 @@
|
||||
(re-frame/reg-sub
|
||||
::invoice-page
|
||||
(fn [db]
|
||||
(-> db ::invoice-page)))
|
||||
(-> (::invoice-page db)
|
||||
(update :invoices
|
||||
(fn [is]
|
||||
(mapv
|
||||
(fn [i]
|
||||
(assoc i :checkable? (not (:automatically-paid-when-due i))))
|
||||
is))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::invoice
|
||||
@@ -112,8 +118,7 @@
|
||||
(re-frame/reg-event-fx
|
||||
::unmounted
|
||||
(fn [{:keys [db]} _]
|
||||
(println "UNMOUNTING?")
|
||||
{:db (dissoc db ::invoice-page ::table/table-params ::side-bar/filters ::last-params)}))
|
||||
{:db (dissoc db ::invoice-page ::table/table-params ::side-bar/filters ::side-bar/settled-filters ::last-params)}))
|
||||
|
||||
(re-frame/reg-event-db
|
||||
::received
|
||||
|
||||
Reference in New Issue
Block a user