much better sorting.

This commit is contained in:
Bryce Covert
2020-04-25 16:21:36 -07:00
parent a8736f351e
commit d799fc469d
17 changed files with 294 additions and 219 deletions

View File

@@ -779,30 +779,23 @@
(update-in [:query :where] into (get-in query-part-2 [:query :where])) (update-in [:query :where] into (get-in query-part-2 [:query :where]))
(update-in [:args] into (get-in query-part-2 [:args])))) (update-in [:args] into (get-in query-part-2 [:args]))))
(defn add-sorter-fields [q sort-map args]
(reduce
(fn [q {:keys [sort-key asc]}]
(merge-query q
{:query {:find [(symbol (str "?sort-" sort-key))]
:where (sort-map
sort-key
(println "Warning, trying to sort by unsupported field" sort-key))}}))
q
(:sort args)))
(defn apply-sort-3 [args results]
(defn add-sorter-field [q sort-map args] (let [sort-bys (or (:sort args) [])
(merge-query q
{:query {:find ['?sorter]
:where (sort-map
(:sort-by args)
(println "Warning, trying to sort by unsupported field" (:sort-by args)))}}))
(defn apply-sort [args sort-fn results ]
(cond->> results
sort-fn (sort-by sort-fn)
(= (:asc args) false) (reverse)))
(defn apply-sort-2 [args default-sort results ]
(let [sort-bys (if (:sort-by args)
(conj (seq default-sort) (if (:asc args)
:asc
:desc))
(seq default-sort))
comparator (fn [xs ys] comparator (fn [xs ys]
(or (->> (map vector sort-bys xs ys) (or (->> (map vector sort-bys xs ys)
(map (fn [[asc x y]] (map (fn [[{:keys [asc]} x y]]
(if (= :asc asc) (if asc
(compare x y) (compare x y)
(compare y x)))) (compare y x))))
(drop-while #(= 0 %)) (drop-while #(= 0 %))

View File

@@ -1,6 +1,6 @@
(ns auto-ap.datomic.checks (ns auto-ap.datomic.checks
(:require [datomic.api :as d] (:require [datomic.api :as d]
[auto-ap.datomic :refer [uri merge-query apply-sort-2 apply-pagination add-sorter-field]] [auto-ap.datomic :refer [uri merge-query apply-sort-3 apply-pagination add-sorter-fields]]
[auto-ap.graphql.utils :refer [limited-clients]] [auto-ap.graphql.utils :refer [limited-clients]]
[auto-ap.utils :refer [dollars=]] [auto-ap.utils :refer [dollars=]]
[clojure.set :refer [rename-keys]] [clojure.set :refer [rename-keys]]
@@ -28,16 +28,16 @@
:in ['$] :in ['$]
:where []} :where []}
:args [db]} :args [db]}
(:sort-by args) (add-sorter-field {"client" ['[?e :payment/client ?c] (:sort args) (add-sorter-fields {"client" ['[?e :payment/client ?c]
'[?c :client/name ?sorter]] '[?c :client/name ?sort-client]]
"vendor" ['[?e :payment/vendor ?v] "vendor" ['[?e :payment/vendor ?v]
'[?v :vendor/name ?sorter]] '[?v :vendor/name ?sort-vendor]]
"bank-account" ['[?e :payment/bank-account ?c] "bank-account" ['[?e :payment/bank-account ?ba]
'[?c :bank-account/name ?sorter]] '[?ba :bank-account/name ?sort-bank-account]]
"check-number" ['[?e :payment/check-number ?sorter]] "check-number" ['[?e :payment/check-number ?sort-check-number]]
"date" ['[?e :payment/date ?sorter]] "date" ['[?e :payment/date ?sort-date]]
"amount" ['[?e :payment/amount ?sorter]] "amount" ['[?e :payment/amount ?sort-amount]]
"status" ['[?e :payment/status ?sorter]]} "status" ['[?e :payment/status ?sort-status]]}
args) args)
(limited-clients (:id args)) (limited-clients (:id args))
@@ -113,7 +113,7 @@
(cond->> query (cond->> query
true (d/query) true (d/query)
true (apply-sort-2 args [:desc :asc]) true (apply-sort-3 args)
true (apply-pagination args)))) true (apply-pagination args))))
(defn graphql-results [ids db args] (defn graphql-results [ids db args]

View File

@@ -1,6 +1,6 @@
(ns auto-ap.datomic.invoices (ns auto-ap.datomic.invoices
(:require [datomic.api :as d] (:require [datomic.api :as d]
[auto-ap.datomic :refer [uri remove-nils merge-query apply-pagination apply-sort-2 add-sorter-field]] [auto-ap.datomic :refer [uri remove-nils merge-query apply-pagination apply-sort-3 add-sorter-fields]]
[auto-ap.graphql.utils :refer [limited-clients]] [auto-ap.graphql.utils :refer [limited-clients]]
[auto-ap.parse :as parse] [auto-ap.parse :as parse]
[clj-time.coerce :as c] [clj-time.coerce :as c]
@@ -28,17 +28,19 @@
:in ['$] :in ['$]
:where ['[?e :invoice/invoice-number]]} :where ['[?e :invoice/invoice-number]]}
:args [(d/db (d/connect uri))]} :args [(d/db (d/connect uri))]}
(:sort-by args) (add-sorter-field {"client" ['[?e :invoice/client ?c] (:sort args) (add-sorter-fields {"client" ['[?e :invoice/client ?c]
'[?c :client/name ?sorter]] '[?c :client/name ?sort-client]]
"vendor" ['[?e :invoice/vendor ?v] "vendor" ['[?e :invoice/vendor ?v]
'[?v :vendor/name ?sorter]] '[?v :vendor/name ?sort-vendor]]
"description-original" ['[?e :transaction/description-original ?sorter]] "description-original" ['[?e :transaction/description-original ?sort-description-original]]
"date" ['[?e :invoice/date ?sorter]] "location" ['[?e :invoice/expense-accounts ?iea]
"due" ['[?e :invoice/due ?sorter]] '[?iea :invoice-expense-account/location ?sort-location]]
"invoice-number" ['[?e :invoice/invoice-number ?sorter]] "date" ['[?e :invoice/date ?sort-date]]
"total" ['[?e :invoice/total ?sorter]] "due" ['[?e :invoice/due ?sort-due]]
"outstanding" ['[?e :invoice/outstanding-balance ?sorter]]} "invoice-number" ['[?e :invoice/invoice-number ?sort-invoice-number]]
args) "total" ['[?e :invoice/total ?sort-total]]
"outstanding-balance" ['[?e :invoice/outstanding-balance ?sort-outstanding-balance]]}
args)
(limited-clients (:id args)) (limited-clients (:id args))
(merge-query {:query {:in ['[?xx ...]] (merge-query {:query {:in ['[?xx ...]]
:where ['[?e :invoice/client ?xx]]} :where ['[?e :invoice/client ?xx]]}
@@ -94,7 +96,7 @@
(merge-query {:query {:find ['?base-date '?e] (merge-query {:query {:find ['?base-date '?e]
:where ['[?e :invoice/date ?base-date]]}}) ) :where ['[?e :invoice/date ?base-date]]}}) )
(d/query) (d/query)
(apply-sort-2 args [:asc :asc]) (apply-sort-3 args)
(apply-pagination args))) (apply-pagination args)))

View File

@@ -1,22 +1,11 @@
(ns auto-ap.datomic.ledger (ns auto-ap.datomic.ledger
(:require [datomic.api :as d] (:require [datomic.api :as d]
[auto-ap.graphql.utils :refer [->graphql limited-clients]] [auto-ap.graphql.utils :refer [->graphql limited-clients]]
[auto-ap.datomic :refer [merge-query apply-sort-2 apply-sort apply-pagination add-sorter-field]] [auto-ap.datomic :refer [merge-query apply-sort-3 apply-pagination add-sorter-fields]]
[auto-ap.datomic :refer [uri]] [auto-ap.datomic :refer [uri]]
[clj-time.coerce :as c] [clj-time.coerce :as c]
[clj-time.core :as time])) [clj-time.core :as time]))
(defn sort-fn [sort-by]
(cond
(= "client" sort-by)
#(-> % :journal-entry/client :client/name)
(= "vendor" sort-by)
#(-> % :journal-entry/vendor :vendor/name)
:else
(keyword "journal-entry" sort-by)))
(defn raw-graphql-ids [db args] (defn raw-graphql-ids [db args]
(let [query (cond-> {:query {:find [] (let [query (cond-> {:query {:find []
@@ -24,12 +13,12 @@
:where []} :where []}
:args [db]} :args [db]}
(:sort-by args) (add-sorter-field {"client" ['[?e :journal-entry/client ?c] (:sort args) (add-sorter-fields {"client" ['[?e :journal-entry/client ?c]
'[?c :client/name ?sorter]] '[?c :client/name ?sort-client]]
"date" ['[?e :journal-entry/date ?sorter]] "date" ['[?e :journal-entry/date ?sort-date]]
"vendor" ['[?e :journal-entry/vendor ?sorter]] "vendor" ['[?e :journal-entry/vendor ?sort-vendor]]
"amount" ['[?e :journal-entry/amount ?sorter]]} "amount" ['[?e :journal-entry/amount ?sort-amount]]}
args) args)
(limited-clients (:id args)) (limited-clients (:id args))
(merge-query {:query {:in ['[?xx ...]] (merge-query {:query {:in ['[?xx ...]]
@@ -85,7 +74,7 @@
(merge-query {:query {:find ['?base-date '?e] :where ['[?e :journal-entry/date ?base-date]]}}))] (merge-query {:query {:find ['?base-date '?e] :where ['[?e :journal-entry/date ?base-date]]}}))]
(->> query (->> query
(d/query) (d/query)
(apply-sort-2 args [:desc :asc]) (apply-sort-3 args)
(apply-pagination args)))) (apply-pagination args))))
(defn graphql-results [ids db args] (defn graphql-results [ids db args]

View File

@@ -1,6 +1,6 @@
(ns auto-ap.datomic.transaction-rules (ns auto-ap.datomic.transaction-rules
(:require [datomic.api :as d] (:require [datomic.api :as d]
[auto-ap.datomic :refer [uri merge-query apply-sort-2 apply-pagination add-sorter-field]] [auto-ap.datomic :refer [uri merge-query apply-sort-3 apply-pagination add-sorter-fields]]
[auto-ap.graphql.utils :refer [limited-clients]] [auto-ap.graphql.utils :refer [limited-clients]]
[clojure.set :refer [rename-keys]] [clojure.set :refer [rename-keys]]
[clj-time.coerce :as c])) [clj-time.coerce :as c]))
@@ -24,18 +24,17 @@
:in ['$] :in ['$]
:where []} :where []}
:args [db]} :args [db]}
(:sort-by args) (add-sorter-field {"client" ['[?e :transaction-rule/client ?c] (:sort args) (add-sorter-fields {"client" ['[?e :transaction-rule/client ?c]
'[?c :client/name ?sorter]] '[?c :client/name ?sort-client]]
"yodlee-merchant" ['[?e :transaction-rule/yodlee-merchant ?c] "yodlee-merchant" ['[?e :transaction-rule/yodlee-merchant ?ym]
'[?c :yodlee-merchant/name ?sorter]] '[?ym :yodlee-merchant/name ?sort-yodlee-merchant]]
"bank-account" ['[?e :transaction-rule/bank-account ?c] "bank-account" ['[?e :transaction-rule/bank-account ?ba]
'[?c :bank-account/name ?sorter]] '[?ba :bank-account/name ?sort-bank-account]]
"description" ['[?e :transaction-rule/description ?sorter]] "description" ['[?e :transaction-rule/description ?sort-description]]
"note" ['[?e :transaction-rule/note ?sorter]] "note" ['[?e :transaction-rule/note ?sort-note]]
"amount-lte" ['[?e :transaction-rule/amount-lte ?sorter]] "amount-lte" ['[?e :transaction-rule/amount-lte ?sort-amount-lte]]
"amount-gte" ['[?e :transaction-rule/amount-gte ?sorter]] "amount-gte" ['[?e :transaction-rule/amount-gte ?sort-amount-gte]]}
}
args) args)
(limited-clients (:id args)) (limited-clients (:id args))
@@ -55,7 +54,7 @@
(cond->> query (cond->> query
true (d/query) true (d/query)
true (apply-sort-2 args [:asc]) true (apply-sort-3 args)
true (apply-pagination args)))) true (apply-pagination args))))
(defn graphql-results [ids db args] (defn graphql-results [ids db args]

View File

@@ -1,6 +1,6 @@
(ns auto-ap.datomic.transactions (ns auto-ap.datomic.transactions
(:require [datomic.api :as d] (:require [datomic.api :as d]
[auto-ap.datomic :refer [uri merge-query apply-sort-2 apply-sort apply-pagination add-sorter-field]] [auto-ap.datomic :refer [uri merge-query apply-sort-3 apply-pagination add-sorter-fields]]
[auto-ap.graphql.utils :refer [limited-clients]] [auto-ap.graphql.utils :refer [limited-clients]]
[clj-time.coerce :as c] [clj-time.coerce :as c]
[clj-time.coerce :as coerce])) [clj-time.coerce :as coerce]))
@@ -25,25 +25,25 @@
:where []} :where []}
:args [db]} :args [db]}
(:sort-by args) (add-sorter-field {"client" ['[?e :transaction/client ?c] (:sort args) (add-sorter-fields {"client" ['[?e :transaction/client ?c]
'[?c :client/name ?sorter]] '[?c :client/name ?sort-client]]
"account" ['[?e :transaction/date] "account" ['[?e :transaction/date]
'(or-join [?e ?sorter] '(or-join [?e ?sort-account]
(and [?e :transaction/account ?c] (and [?e :transaction/account ?c]
[?c :account/name ?sorter]) [?c :account/name ?sort-account])
(and (and
(not [?e :transaction/account]) (not [?e :transaction/account])
[(ground "") ?sorter]))] [(ground "") ?sort-account]))]
"description-original" ['[?e :transaction/description-original ?sorter]] "description-original" ['[?e :transaction/description-original ?sort-description-original]]
"date" ['[?e :transaction/date ?sorter]] "date" ['[?e :transaction/date ?sort-date]]
"vendor" ['(or-join [?e ?sorter] "vendor" ['(or-join [?e ?sort-vendor]
(and [(missing? $ ?e :transaction/vendor)] (and [(missing? $ ?e :transaction/vendor)]
[?e :transaction/description-original ?sorter]) [?e :transaction/description-original ?sort-vendor])
(and [?e :transaction/vendor ?v] (and [?e :transaction/vendor ?v]
[?v :vendor/name ?sorter]))] [?v :vendor/name ?sort-vendor]))]
"amount" ['[?e :transaction/amount ?sorter]] "amount" ['[?e :transaction/amount ?sort-amount]]
"status" ['[?e :transaction/status ?sorter]]} "status" ['[?e :transaction/status ?sort-status]]}
args) args)
(limited-clients (:id args)) (limited-clients (:id args))
(merge-query {:query {:in ['[?xx ...]] (merge-query {:query {:in ['[?xx ...]]
@@ -118,7 +118,7 @@
'[?e :transaction/date ?base-date]]}}))] '[?e :transaction/date ?base-date]]}}))]
(cond->> query (cond->> query
true (d/query) true (d/query)
true (apply-sort-2 args [:desc :asc]) true (apply-sort-3 args)
true (apply-pagination args))))) true (apply-pagination args)))))
(defn graphql-results [ids db args] (defn graphql-results [ids db args]

View File

@@ -283,6 +283,8 @@
:client {:type :client}}} :client {:type :client}}}
:invoice_page {:fields {:invoices {:type '(list :invoice)} :invoice_page {:fields {:invoices {:type '(list :invoice)}
:count {:type 'Int} :count {:type 'Int}
:total {:type 'Int} :total {:type 'Int}
@@ -375,6 +377,8 @@
:to_date {:type :iso_date}} :to_date {:type :iso_date}}
:resolve :get-profit-and-loss} :resolve :get-profit-and-loss}
:invoice_page {:type '(list :invoice_page) :invoice_page {:type '(list :invoice_page)
:args {:import_status {:type 'String} :args {:import_status {:type 'String}
:date_range {:type :date_range} :date_range {:type :date_range}
@@ -383,8 +387,7 @@
:vendor_id {:type :id} :vendor_id {:type :id}
:invoice_number_like {:type 'String} :invoice_number_like {:type 'String}
:start {:type 'Int} :start {:type 'Int}
:sort_by {:type 'String} :sort {:type '(list :sort_item)}}
:asc {:type 'Boolean}}
:resolve :get-invoice-page} :resolve :get-invoice-page}
@@ -419,8 +422,7 @@
:amount_gte {:type :money} :amount_gte {:type :money}
:description {:type 'String} :description {:type 'String}
:start {:type 'Int} :start {:type 'Int}
:sort_by {:type 'String} :sort {:type '(list :sort_item)}
:asc {:type 'Boolean}
:approval_status {:type :transaction_approval_status}} :approval_status {:type :transaction_approval_status}}
:resolve :get-transaction-page} :resolve :get-transaction-page}
@@ -428,7 +430,7 @@
:transaction_rule_page {:type :transaction_rule_page :transaction_rule_page {:type :transaction_rule_page
:args {:client_id {:type :id} :args {:client_id {:type :id}
:start {:type 'Int} :start {:type 'Int}
:sort_by {:type 'String} :sort {:type '(list :sort_item)}
:asc {:type 'Boolean}} :asc {:type 'Boolean}}
:resolve :get-transaction-rule-page} :resolve :get-transaction-rule-page}
@@ -441,8 +443,7 @@
:from_numeric_code {:type 'Int} :from_numeric_code {:type 'Int}
:to_numeric_code {:type 'Int} :to_numeric_code {:type 'Int}
:start {:type 'Int} :start {:type 'Int}
:sort_by {:type 'String} :sort {:type '(list :sort_item)}}
:asc {:type 'Boolean}}
:resolve :get-ledger-page} :resolve :get-ledger-page}
@@ -452,8 +453,7 @@
:date_range {:type :date_range} :date_range {:type :date_range}
:check_number_like {:type 'String} :check_number_like {:type 'String}
:start {:type 'Int} :start {:type 'Int}
:sort_by {:type 'String} :sort {:type '(list :sort_item)}}
:asc {:type 'Boolean}}
:resolve :get-payment-page} :resolve :get-payment-page}
@@ -467,6 +467,10 @@
:input-objects :input-objects
{ {
:sort_item
{:fields {:sort_key {:type 'String}
:sort_name {:type 'String}
:asc {:type 'Boolean}}}
:invoice_payment_amount {:fields {:invoice_id {:type :id} :invoice_payment_amount {:fields {:invoice_id {:type :id}
:amount {:type 'Float}}} :amount {:type 'Float}}}
:edit_location_match {:fields {:location {:type 'String} :edit_location_match {:fields {:location {:type 'String}
@@ -652,8 +656,7 @@
:amount_gte {:type :money} :amount_gte {:type :money}
:description {:type 'String} :description {:type 'String}
:start {:type 'Int} :start {:type 'Int}
:sort_by {:type 'String} :sort {:type '(list :sort_item)}
:asc {:type 'Boolean}
:approval_status {:type :transaction_approval_status}} :approval_status {:type :transaction_approval_status}}
:resolve :mutation/unapprove-transactions} :resolve :mutation/unapprove-transactions}

View File

@@ -134,12 +134,10 @@
retractions (map (fn [[_ e]] [:db/retractEntity [:journal-entry/original-entity e]]) affected-entities)] retractions (map (fn [[_ e]] [:db/retractEntity [:journal-entry/original-entity e]]) affected-entities)]
(when (seq retractions) (when (seq retractions)
(println "Retracting " retractions)
@(d/transact (d/connect uri) retractions)) @(d/transact (d/connect uri) retractions))
(doseq [d-tx d-txs] (doseq [d-tx d-txs]
(clojure.pprint/pprint d-tx)
#_(println "updating general-ledger " d-tx) #_(println "updating general-ledger " d-tx)
@(d/transact (d/connect uri) [d-tx])))) @(d/transact (d/connect uri) [d-tx]))))

View File

@@ -5,7 +5,7 @@
[clj-time.coerce :as c] [clj-time.coerce :as c]
[clj-time.core :as t])) [clj-time.core :as t]))
(defn exclude-until-date [client end] (defn mark-until-date [client end]
(let [conn (d/connect uri)] (let [conn (d/connect uri)]
(doseq [p (->> (doseq [p (->>
(d/query {:query {:find '[?e] (d/query {:query {:find '[?e]
@@ -47,5 +47,22 @@
@(d/transact conn p) @(d/transact conn p)
(println "process 100")))) (println "process 100"))))
(defn unapprove-all []
(let [conn (d/connect uri)]
(doseq [p (->>
(d/query {:query {:find '[?e]
:in '[$ ]
:where ['[?e :transaction/date ?d ]]}
:args [(d/db conn)]})
(mapv first)
(mapv (fn [i]
{:db/id i
:transaction/approval-status :transaction-approval-status/unapproved}))
(partition-all 100))]
@(d/transact conn p)
(println "process 100"))))

View File

@@ -3,6 +3,7 @@
[auto-ap.subs :as subs] [auto-ap.subs :as subs]
[auto-ap.views.utils :refer [date->str dispatch-event delayed-dispatch nf]] [auto-ap.views.utils :refer [date->str dispatch-event delayed-dispatch nf]]
[auto-ap.views.components.paginator :refer [paginator]] [auto-ap.views.components.paginator :refer [paginator]]
[auto-ap.views.components.sort-by-list :refer [sort-by-list]]
[auto-ap.views.components.sorter :refer [sorted-column]] [auto-ap.views.components.sorter :refer [sorted-column]]
[auto-ap.views.components.dropdown :refer [drop-down drop-down-contents]] [auto-ap.views.components.dropdown :refer [drop-down drop-down-contents]]
[auto-ap.events :as events] [auto-ap.events :as events]
@@ -44,8 +45,9 @@
(defn query [params] (defn query [params]
{:venia/queries [[:invoice_page {:venia/queries [[:invoice_page
(assoc params (-> params
:client-id (:id @(re-frame/subscribe [::subs/client]))) (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
[:vendor [:name :id]] [:vendor [:name :id]]
[:expense_accounts [:amount :id :location [:expense_accounts [:amount :id :location
@@ -64,19 +66,22 @@
opc (fn [p] opc (fn [p]
(on-params-change (merge @params p)))] (on-params-change (merge @params p)))]
(fn [{:keys [id invoice-page status on-params-change vendors checked params]}] (fn [{:keys [id invoice-page status on-params-change vendors checked params]}]
(let [{:keys [sort-by asc]} @params (let [{:keys [sort asc]} @params
{:keys [invoices start end count total]} @invoice-page {:keys [invoices start end count total]} @invoice-page
visible-checks @(re-frame/subscribe [::visible-checks]) visible-checks @(re-frame/subscribe [::visible-checks])
visible-expense-accounts @(re-frame/subscribe [::visible-expense-accounts]) visible-expense-accounts @(re-frame/subscribe [::visible-expense-accounts])
selected-client @(re-frame/subscribe [::subs/client]) selected-client @(re-frame/subscribe [::subs/client])
percentage-size (if selected-client "%50%" "33%") percentage-size (if selected-client "%50%" "33%")]
]
[:div [:div
[:div.level
[:div.level-left
[paginator {:start start :end end :count count :total total [:div.level-item
:on-change (fn [p ] [paginator {:start start :end end :count count :total total
(on-params-change (merge @params p) ))}] :on-change (fn [p ]
(on-params-change (merge @params p) ))}]]
[:div.level-item
[sort-by-list {:sort sort
:on-change opc}]]]]
[:table.table.is-fullwidth [:table.table.is-fullwidth
[:thead [:thead
[:tr [:tr
@@ -86,53 +91,61 @@
(when-not selected-client (when-not selected-client
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-name "Client"
:sort-key "client" :sort-key "client"
:sort-by sort-by :sort sort
:asc asc} :asc asc}
"Client"]) "Client"])
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-name "Vendor"
:sort-key "vendor" :sort-key "vendor"
:sort-by sort-by :sort sort
:asc asc} :asc asc}
"Vendor"] "Vendor"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-name "Invoice Number"
:sort-key "invoice-number" :sort-key "invoice-number"
:sort-by sort-by :sort sort
:asc asc} :asc asc}
"Invoice #"] "Invoice #"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-name "Date"
:sort-key "date" :sort-key "date"
:sort-by sort-by :sort sort
:asc asc} :asc asc}
"Date"] "Date"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-name "Due"
:sort-key "due" :sort-key "due"
:sort-by sort-by :sort sort
:asc asc} :asc asc}
"Due"] "Due"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "5em" :cursor "pointer"} :style {:width "5em" :cursor "pointer"}
:sort-name "Location"
:sort-key "location" :sort-key "location"
:sort-by sort-by :sort sort
:asc asc} :asc asc}
"Loc"] "Loc"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-name "Total"
:sort-key "total" :sort-key "total"
:class "has-text-right" :class "has-text-right"
:sort-by sort-by :sort sort
:asc asc} :asc asc}
"Amount"] "Amount"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "10em" :cursor "pointer"} :style {:width "10em" :cursor "pointer"}
:sort-name "Outstanding"
:sort-key "outstanding-balance" :sort-key "outstanding-balance"
:class "has-text-right" :class "has-text-right"
:sort-by sort-by :sort sort
:asc asc} :asc asc}
"Outstanding"] "Outstanding"]

View File

@@ -0,0 +1,21 @@
(ns auto-ap.views.components.sort-by-list
(:require [re-frame.core :as re-frame]
[auto-ap.subs :as subs]
[auto-ap.views.utils :refer [date->str]]
[reagent.core :as reagent]
[clojure.string :as str]
[cljs-time.format :as format]))
(defn sort-by-list [{:keys [sort on-change]}]
[:div.field.is-grouped.is-grouped-multiline
(for [{:keys [sort-key sort-name asc]} sort]
^{:key sort-key}
[:div.control
[:div.tags.has-addons
[:div.tag.is-medium [:span.icon (if asc
[:i.fa.fa-sort-up]
[:i.fa.fa-sort-down])]
[:span sort-name] ]
[:a.tag.is-medium.is-delete {:on-click (fn []
(on-change {:sort (filter #(not= sort-key (:sort-key %)) sort)}))}]]])])

View File

@@ -5,30 +5,45 @@
[reagent.core :as reagent] [reagent.core :as reagent]
[clojure.string :as str] [clojure.string :as str]
[cljs-time.format :as format])) [cljs-time.format :as format]))
(defn toggle-sort-by [params key] (defn toggle-sort-by [params sort-key sort-name asc]
(let [[found? sort] (reduce
(fn [[found? sort] sort-item]
(if (= sort-key (:sort-key sort-item))
[true (conj sort
(update sort-item :asc not))]
[found? (conj sort sort-item)]))
[false []]
(:sort params))
sort (if found?
sort
(conj sort {:sort-key sort-key
:sort-name sort-name
:asc true}))]
(-> params (-> params
(assoc :sort-by key) (assoc :sort sort))))
(update :asc not)))
(defn sort-icon [which sort-by asc] (defn sort-icon [which sort asc]
(cond (let [sort-item (first (filter #(= which (:sort-key %)) sort))]
(and (= sort-by which) asc) (cond
[:span.icon (and sort-item (:asc sort-item))
[:i.fa.fa-sort-up]] [:span.icon
[:i.fa.fa-sort-up]]
(and (= sort-by which) (not asc)) (and sort-item (not (:asc sort-item)))
[:span.icon [:span.icon
[:i.fa.fa-sort-down]] [:i.fa.fa-sort-down]]
:else :else
[:span.icon [:span.icon
[:i.fa.fa-sort]])) [:i.fa.fa-sort]])))
(defn sorted-column [{:keys [on-sort sort-key sort-by asc style class]} & rest]
(defn sorted-column [{:keys [on-sort sort-key sort sort-name asc style class]} & rest]
[:th {:on-click (fn [e] (on-sort (toggle-sort-by {:asc asc} sort-key))) [:th {:on-click (fn [e]
(on-sort
(toggle-sort-by {:sort sort} sort-key sort-name asc)))
:style style :style style
:class class} :class class}
rest rest
(sort-icon sort-key sort-by asc)]) (sort-icon sort-key sort asc)])

View File

@@ -3,6 +3,7 @@
[auto-ap.views.utils :refer [dispatch-event ->$ with-user]] [auto-ap.views.utils :refer [dispatch-event ->$ with-user]]
[auto-ap.views.pages.admin.rules.form :as form] [auto-ap.views.pages.admin.rules.form :as form]
[auto-ap.views.components.paginator :refer [paginator]] [auto-ap.views.components.paginator :refer [paginator]]
[auto-ap.views.components.sort-by-list :refer [sort-by-list]]
[auto-ap.views.pages.admin.rules.results-modal :as results-modal] [auto-ap.views.pages.admin.rules.results-modal :as results-modal]
[auto-ap.views.components.sorter :refer [sorted-column]] [auto-ap.views.components.sorter :refer [sorted-column]]
[re-frame.core :as re-frame])) [re-frame.core :as re-frame]))
@@ -36,58 +37,62 @@
(let [opc (fn [p] (let [opc (fn [p]
(on-params-change (merge @params p )))] (on-params-change (merge @params p )))]
(fn [{:keys [id rule-page on-params-change params status]}] (fn [{:keys [id rule-page on-params-change params status]}]
(let [{:keys [sort-by asc]} @params (let [{:keys [sort asc]} @params
{:keys [transaction-rules start end count total]} @rule-page {:keys [transaction-rules start end count total]} @rule-page
selected-client @(re-frame/subscribe [::subs/client])] selected-client @(re-frame/subscribe [::subs/client])]
[:div [:div
[paginator {:start start :end end :count count :total total [:div.level
:on-change (fn [p ] [:div.level-left
(on-params-change (merge @params p)))}] [:div.level-item
[paginator {:start start :end end :count count :total total
:on-change (fn [p ]
(on-params-change (merge @params p)))}]]
[:div.level-item
[sort-by-list {:sort sort
:on-change opc}]]]]
[:table.table.is-fullwidth.compact [:table.table.is-fullwidth.compact
[:thead [:thead
[:tr [:tr
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"} :style {:width "25%" :cursor "pointer"}
:sort-key "client" :sort-key "client"
:sort-by sort-by :sort-name "Client"
:asc asc} :sort sort}
"Client"] "Client"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"} :style {:width "25%" :cursor "pointer"}
:sort-key "bank-account" :sort-key "bank-account"
:sort-by sort-by :sort-name "Bank Account"
:asc asc} :sort sort}
"Bank Account"] "Bank Account"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"} :style {:width "25%" :cursor "pointer"}
:sort-key "description" :sort-key "description"
:sort-by sort-by :sort-name "Description"
:asc asc} :sort sort}
"Description"] "Description"]
#_[sorted-column {:on-sort opc #_[sorted-column {:on-sort opc
:style {:width "8em" :cukjsor "pointer"} :style {:width "8em" :cukjsor "pointer"}
:class "has-text-right" :class "has-text-right"
:sort-key "amount-gte" :sort-key "amount-gte"
:sort-by sort-by :sort sort}
:asc asc}
"Amount"] "Amount"]
[:th.has-text-right {:style {:width "12em"}} "Amount"] [:th.has-text-right {:style {:width "12em"}} "Amount"]
#_[sorted-column {:on-sort opc #_[sorted-column {:on-sort opc
:class "has-text-right" :class "has-text-right"
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "amount-lte" :sort-key "amount-lte"
:sort-by sort-by :sort sort}
:asc asc}
"<="] "<="]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "25%" :cursor "pointer"} :style {:width "25%" :cursor "pointer"}
:sort-key "note" :sort-key "note"
:sort-by sort-by :sort-name "Note"
:asc asc} :sort sort}
"Note"] "Note"]
[:th {:style {:width "9em"}} [:th {:style {:width "9em"}}
]]] ]]]

View File

@@ -12,6 +12,7 @@
[auto-ap.views.components.layouts :refer [side-bar-layout]] [auto-ap.views.components.layouts :refer [side-bar-layout]]
[auto-ap.views.components.typeahead :refer [typeahead]] [auto-ap.views.components.typeahead :refer [typeahead]]
[auto-ap.views.components.paginator :refer [paginator]] [auto-ap.views.components.paginator :refer [paginator]]
[auto-ap.views.components.sort-by-list :refer [sort-by-list]]
[auto-ap.events :as events] [auto-ap.events :as events]
[auto-ap.views.utils :refer [dispatch-event date->str bind-field nf with-user]] [auto-ap.views.utils :refer [dispatch-event date->str bind-field nf with-user]]
[auto-ap.utils :refer [by]] [auto-ap.utils :refer [by]]
@@ -141,64 +142,70 @@
(on-params-change (merge @params p)))] (on-params-change (merge @params p)))]
(fn [{:keys [id payment-page status on-params-change vendors checked]}] (fn [{:keys [id payment-page status on-params-change vendors checked]}]
(let [{:keys [sort-by asc]} @params (let [{:keys [sort]} @params
{:keys [payments start end count total]} @payment-page {:keys [payments start end count total]} @payment-page
selected-client @(re-frame/subscribe [::subs/client]) selected-client @(re-frame/subscribe [::subs/client])
percentage-size (if selected-client "50%" "33%")] percentage-size (if selected-client "50%" "33%")]
[:div [:div
[paginator {:start start :end end :count count :total total [:div.level
:on-change (fn [p ] [:div.level-left
(on-params-change (merge @params p)))}] [:div.level-item
[paginator {:start start :end end :count count :total total
:on-change (fn [p ]
(on-params-change (merge @params p)))}]]
[:div.level-item
[sort-by-list {:sort sort
:on-change opc}]]]]
[:table.table.is-fullwidth [:table.table.is-fullwidth
[:thead [:thead
[:tr [:tr
(when-not selected-client (when-not selected-client
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-key "client" :sort-key "client"
:sort-by sort-by :sort-name "Client"
:asc asc} :sort sort}
"Client"]) "Client"])
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-key "vendor" :sort-key "vendor"
:sort-by sort-by :sort-name "Vendor"
:asc asc} :sort sort}
"Vendor"] "Vendor"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-key "vendor" :sort-key "bank-account"
:sort-by sort-by :sort-name "Bank Account"
:asc asc} :sort sort}
"Bank Account"] "Bank Account"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-key "check-number" :sort-key "check-number"
:sort-by sort-by :sort-name "Check #"
:asc asc} :sort sort}
"Check #"] "Check #"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "date" :sort-key "date"
:sort-by sort-by :sort-name "Date"
:asc asc} :sort sort}
"Date"] "Date"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:class "has-text-right" :class "has-text-right"
:sort-key "amount" :sort-key "amount"
:sort-by sort-by :sort-name "Amount"
:asc asc} :sort sort}
"Amount"] "Amount"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "status" :sort-key "status"
:sort-by sort-by :sort-name "Status"
:asc asc} :sort sort}
"Status"] "Status"]

View File

@@ -2,6 +2,7 @@
(:require [auto-ap.subs :as subs] (:require [auto-ap.subs :as subs]
[auto-ap.views.components.paginator :refer [paginator]] [auto-ap.views.components.paginator :refer [paginator]]
[auto-ap.views.components.sorter :refer [sorted-column]] [auto-ap.views.components.sorter :refer [sorted-column]]
[auto-ap.views.components.sort-by-list :refer [sort-by-list]]
[auto-ap.views.utils :refer [date->str dispatch-event nf]] [auto-ap.views.utils :refer [date->str dispatch-event nf]]
[goog.string :as gstring] [goog.string :as gstring]
[re-frame.core :as re-frame])) [re-frame.core :as re-frame]))
@@ -11,14 +12,20 @@
(on-params-change (merge @params p )))] (on-params-change (merge @params p )))]
(fn [{:keys [id ledger-page status on-params-change vendors checked status?] (fn [{:keys [id ledger-page status on-params-change vendors checked status?]
:or {status? true}}] :or {status? true}}]
(let [{:keys [sort-by asc]} @params (let [{:keys [sort]} @params
{:keys [journal-entries start end count total]} @ledger-page {:keys [journal-entries start end count total]} @ledger-page
selected-client @(re-frame/subscribe [::subs/client]) selected-client @(re-frame/subscribe [::subs/client])
percentage-size (if selected-client "25%" "33%")] percentage-size (if selected-client "25%" "33%")]
[:div [:div
[paginator {:start start :end end :count count :total total [:div.level
:on-change (fn [p ] [:div.level-left
(on-params-change (merge @params p)))}] [:div.level-item
[paginator {:start start :end end :count count :total total
:on-change (fn [p ]
(on-params-change (merge @params p)))}]]
[:div.level-item
[sort-by-list {:sort sort
:on-change opc}]]]]
[:table.table.is-fullwidth.compact [:table.table.is-fullwidth.compact
@@ -28,25 +35,22 @@
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-key "client" :sort-key "client"
:sort-by sort-by :sort-name "Client"
:asc asc} :sort sort}
"Client"]) "Client"])
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-key "vendor" :sort-key "vendor"
:sort-by sort-by :sort-name "Vendor"
:asc asc} :sort sort}
"Vendor"] "Vendor"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "date" :sort-key "date"
:sort-by sort-by :sort-name "Date"
:asc asc} :sort sort}
"Date"] "Date"]
[:th [:th
{:style {:width percentage-size }} {:style {:width percentage-size }}
@@ -54,17 +58,17 @@
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "amount" :sort-key "amount"
:sort-name "Amount"
:class "has-text-right" :class "has-text-right"
:sort-by sort-by :sort sort}
:asc asc}
"Debit"] "Debit"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "amount" :sort-key "amount"
:sort-name "Amount"
:class "has-text-right" :class "has-text-right"
:sort-by sort-by :sort sort}
:asc asc}
"Credit"] "Credit"]
@@ -73,8 +77,8 @@
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "status" :sort-key "status"
:sort-by sort-by :sort-name "Status"
:asc asc} :sort sort}
"Status"])]] "Status"])]]
[:tbody [:tbody
(if (:loading @status) (if (:loading @status)

View File

@@ -12,6 +12,7 @@
[auto-ap.views.components.layouts :refer [appearing-side-bar side-bar-layout]] [auto-ap.views.components.layouts :refer [appearing-side-bar side-bar-layout]]
[auto-ap.views.components.modal :refer [action-modal]] [auto-ap.views.components.modal :refer [action-modal]]
[auto-ap.views.components.paginator :refer [paginator]] [auto-ap.views.components.paginator :refer [paginator]]
[auto-ap.views.components.sort-by-list :refer [sort-by-list]]
[auto-ap.views.components.sorter :refer [sorted-column]] [auto-ap.views.components.sorter :refer [sorted-column]]
[auto-ap.views.pages.transactions.form :as edit] [auto-ap.views.pages.transactions.form :as edit]
[auto-ap.views.pages.transactions.table :as table] [auto-ap.views.pages.transactions.table :as table]

View File

@@ -1,6 +1,7 @@
(ns auto-ap.views.pages.transactions.table (ns auto-ap.views.pages.transactions.table
(:require [auto-ap.subs :as subs] (:require [auto-ap.subs :as subs]
[auto-ap.views.components.paginator :refer [paginator]] [auto-ap.views.components.paginator :refer [paginator]]
[auto-ap.views.components.sort-by-list :refer [sort-by-list]]
[auto-ap.views.components.sorter :refer [sorted-column]] [auto-ap.views.components.sorter :refer [sorted-column]]
[auto-ap.views.components.dropdown :refer [drop-down drop-down-contents]] [auto-ap.views.components.dropdown :refer [drop-down drop-down-contents]]
[auto-ap.views.pages.transactions.form :as edit] [auto-ap.views.pages.transactions.form :as edit]
@@ -39,14 +40,21 @@
(let [opc (fn [p] (let [opc (fn [p]
(on-params-change (merge @params p )))] (on-params-change (merge @params p )))]
(fn [{:keys [id transaction-page status on-params-change vendors checked]}] (fn [{:keys [id transaction-page status on-params-change vendors checked]}]
(let [{:keys [sort-by asc]} @params (let [{:keys [sort]} @params
{:keys [transactions start end count total]} @transaction-page {:keys [transactions start end count total]} @transaction-page
selected-client @(re-frame/subscribe [::subs/client]) selected-client @(re-frame/subscribe [::subs/client])
percentage-size (if selected-client "25%" "33%")] percentage-size (if selected-client "25%" "33%")]
[:div [:div
[paginator {:start start :end end :count count :total total [:div.level
:on-change (fn [p ] [:div.level-left
(on-params-change (merge @params p)))}] [:div.level-item
[paginator {:start start :end end :count count :total total
:on-change (fn [p ]
(on-params-change (merge @params p)))}]]
[:div.level-item
[sort-by-list {:sort sort
:on-change opc}]]]]
[:table.table.is-fullwidth [:table.table.is-fullwidth
[:thead [:thead
@@ -55,36 +63,36 @@
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-key "client" :sort-key "client"
:sort-by sort-by :sort-name "Client"
:asc asc} :sort sort}
"Client"]) "Client"])
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width percentage-size :cursor "pointer"} :style {:width percentage-size :cursor "pointer"}
:sort-key "vendor" :sort-key "vendor"
:sort-by sort-by :sort-name "Vendor"
:asc asc} :sort sort}
"Vendor"] "Vendor"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "date" :sort-key "date"
:sort-by sort-by :sort-name "Date"
:asc asc} :sort sort}
"Date"] "Date"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "amount" :sort-key "amount"
:sort-name "Amount"
:class "has-text-right" :class "has-text-right"
:sort-by sort-by :sort sort}
:asc asc}
"Amount"] "Amount"]
[sorted-column {:on-sort opc [sorted-column {:on-sort opc
:style {:width "8em" :cursor "pointer"} :style {:width "8em" :cursor "pointer"}
:sort-key "status" :sort-key "status"
:sort-by sort-by :sort-name "Status"
:asc asc} :sort sort}
"Status"] "Status"]
[:th {:width percentage-size} "Bank account"] [:th {:width percentage-size} "Bank account"]
[:th {:style {:width "14em"}} "" ]]] [:th {:style {:width "14em"}} "" ]]]