A better way to allow bulk select.
This commit is contained in:
@@ -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-3 apply-pagination add-sorter-fields]]
|
[auto-ap.datomic :refer [uri merge-query apply-sort-3 apply-pagination add-sorter-fields conn]]
|
||||||
[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]))
|
||||||
@@ -149,6 +149,17 @@
|
|||||||
[(->> (graphql-results ids-to-retrieve db args))
|
[(->> (graphql-results ids-to-retrieve db args))
|
||||||
matching-count]))
|
matching-count]))
|
||||||
|
|
||||||
|
(defn filter-ids [ids]
|
||||||
|
(if ids
|
||||||
|
(->> {:query {:find ['?e]
|
||||||
|
:in ['$ '[?e ...]]
|
||||||
|
:where ['[?e :transaction/date]]}
|
||||||
|
:args [(d/db conn) ids]}
|
||||||
|
(d/query)
|
||||||
|
(map first)
|
||||||
|
vec)
|
||||||
|
[]))
|
||||||
|
|
||||||
(defn get-by-id [id]
|
(defn get-by-id [id]
|
||||||
(->
|
(->
|
||||||
(d/pull (d/db (d/connect uri))
|
(d/pull (d/db (d/connect uri))
|
||||||
@@ -168,9 +179,17 @@
|
|||||||
(dissoc :transaction/id)))
|
(dissoc :transaction/id)))
|
||||||
|
|
||||||
(defn unapprove [ids]
|
(defn unapprove [ids]
|
||||||
(doseq [x (partition-all 1000 ids)]
|
(doseq [x (partition-all 100 ids)]
|
||||||
@(d/transact (d/connect uri)
|
@(d/transact (d/connect uri)
|
||||||
(mapv (fn [i]
|
(mapv (fn [i]
|
||||||
{:db/id i
|
{:db/id i
|
||||||
:transaction/approval-status :transaction-approval-status/unapproved})
|
:transaction/approval-status :transaction-approval-status/unapproved})
|
||||||
x))))
|
x))))
|
||||||
|
|
||||||
|
(defn delete [ids]
|
||||||
|
(doseq [x (partition-all 100 ids)]
|
||||||
|
@(d/transact (d/connect uri)
|
||||||
|
(mapcat (fn [i]
|
||||||
|
[[:db/retractEntity i]
|
||||||
|
[:db/retractEntity [:journal-entry/original-entity i]]])
|
||||||
|
x))))
|
||||||
|
|||||||
@@ -64,6 +64,8 @@
|
|||||||
%))}}
|
%))}}
|
||||||
:objects
|
:objects
|
||||||
{
|
{
|
||||||
|
:message
|
||||||
|
{:fields {:message {:type 'String}}}
|
||||||
:location_match
|
:location_match
|
||||||
{:fields {:location {:type 'String}
|
{:fields {:location {:type 'String}
|
||||||
:match {:type 'String}
|
:match {:type 'String}
|
||||||
@@ -554,6 +556,7 @@
|
|||||||
:resolve :get-vendor}
|
:resolve :get-vendor}
|
||||||
:user {:type '(list :user)
|
:user {:type '(list :user)
|
||||||
:resolve :get-user}
|
:resolve :get-user}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:input-objects
|
:input-objects
|
||||||
@@ -781,19 +784,14 @@
|
|||||||
:args {:invoices {:type '(list :id)}}
|
:args {:invoices {:type '(list :id)}}
|
||||||
:resolve :mutation/approve-invoices}
|
:resolve :mutation/approve-invoices}
|
||||||
|
|
||||||
:unapprove_transactions {:type '(list :transaction_page)
|
:unapprove_transactions {:type :message
|
||||||
:args {:client_id {:type :id}
|
:args {:filters {:type :transaction_filters}
|
||||||
:vendor_id {:type :id}
|
:ids {:type '(list :id)}}
|
||||||
:bank_account_id {:type :id}
|
|
||||||
:date_range {:type :date_range}
|
|
||||||
:amount_lte {:type :money}
|
|
||||||
:amount_gte {:type :money}
|
|
||||||
:description {:type 'String}
|
|
||||||
:start {:type 'Int}
|
|
||||||
:sort {:type '(list :sort_item)}
|
|
||||||
:approval_status {:type :transaction_approval_status}}
|
|
||||||
|
|
||||||
:resolve :mutation/unapprove-transactions}
|
:resolve :mutation/unapprove-transactions}
|
||||||
|
:delete_transactions {:type :message
|
||||||
|
:args {:filters {:type :transaction_filters}
|
||||||
|
:ids {:type '(list :id)}}
|
||||||
|
:resolve :mutation/delete-transactions}
|
||||||
:delete_transaction_rule {:type :id
|
:delete_transaction_rule {:type :id
|
||||||
:args {:transaction_rule_id {:type :id}}
|
:args {:transaction_rule_id {:type :id}}
|
||||||
:resolve :mutation/delete-transaction-rule}
|
:resolve :mutation/delete-transaction-rule}
|
||||||
@@ -1129,6 +1127,7 @@
|
|||||||
:mutation/edit-invoice gq-invoices/edit-invoice
|
:mutation/edit-invoice gq-invoices/edit-invoice
|
||||||
:mutation/edit-transaction gq-transactions/edit-transaction
|
:mutation/edit-transaction gq-transactions/edit-transaction
|
||||||
:mutation/unapprove-transactions gq-transactions/unapprove-transactions
|
:mutation/unapprove-transactions gq-transactions/unapprove-transactions
|
||||||
|
:mutation/delete-transactions gq-transactions/delete-transactions
|
||||||
:mutation/upsert-transaction-rule gq-transaction-rules/upsert-transaction-rule
|
:mutation/upsert-transaction-rule gq-transaction-rules/upsert-transaction-rule
|
||||||
:test-transaction-rule gq-transaction-rules/test-transaction-rule
|
:test-transaction-rule gq-transaction-rules/test-transaction-rule
|
||||||
:run-transaction-rule gq-transaction-rules/run-transaction-rule
|
:run-transaction-rule gq-transaction-rules/run-transaction-rule
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
[auto-ap.datomic.accounts :as a]
|
[auto-ap.datomic.accounts :as a]
|
||||||
[auto-ap.datomic.transaction-rules :as tr]
|
[auto-ap.datomic.transaction-rules :as tr]
|
||||||
[auto-ap.rule-matching :as rm]
|
[auto-ap.rule-matching :as rm]
|
||||||
[clj-time.coerce :as coerce]))
|
[clj-time.coerce :as coerce]
|
||||||
|
[clojure.tools.logging :as log]))
|
||||||
|
|
||||||
(def approval-status->graphql (ident->enum-f :transaction/approval-status))
|
(def approval-status->graphql (ident->enum-f :transaction/approval-status))
|
||||||
|
|
||||||
@@ -32,10 +33,37 @@
|
|||||||
:end (+ (:start (:filters args) 0) (count transactions))}))
|
:end (+ (:start (:filters args) 0) (count transactions))}))
|
||||||
|
|
||||||
(defn unapprove-transactions [context args value]
|
(defn unapprove-transactions [context args value]
|
||||||
(let [args (assoc args :id (:id context))
|
(let [_ (assert-admin (:id context))
|
||||||
ids (:ids (d-transactions/raw-graphql-ids (update (<-graphql args) :approval-status enum->keyword "transaction-approval-status")))]
|
args (assoc args :id (:id context))
|
||||||
(d-transactions/unapprove ids)
|
ids (some-> (:filters args)
|
||||||
(get-transaction-page context args value)))
|
(<-graphql)
|
||||||
|
(update :approval-status enum->keyword "transaction-approval-status")
|
||||||
|
(assoc :per-page Integer/MAX_VALUE)
|
||||||
|
(d-transactions/raw-graphql-ids )
|
||||||
|
:ids)
|
||||||
|
specific-ids (d-transactions/filter-ids (:ids args))
|
||||||
|
all-ids (into (set ids) specific-ids)]
|
||||||
|
|
||||||
|
(log/info "Unapproving " (count all-ids) args)
|
||||||
|
(d-transactions/unapprove all-ids)
|
||||||
|
{:message (str "Succesfully unapproved " (count all-ids) " transactions.")}))
|
||||||
|
|
||||||
|
|
||||||
|
(defn delete-transactions [context args value]
|
||||||
|
(let [_ (assert-admin (:id context))
|
||||||
|
args (assoc args :id (:id context))
|
||||||
|
ids (some-> (:filters args)
|
||||||
|
(<-graphql)
|
||||||
|
(update :approval-status enum->keyword "transaction-approval-status")
|
||||||
|
(assoc :per-page Integer/MAX_VALUE)
|
||||||
|
(d-transactions/raw-graphql-ids )
|
||||||
|
:ids)
|
||||||
|
specific-ids (d-transactions/filter-ids (:ids args))
|
||||||
|
all-ids (into (set ids) specific-ids)]
|
||||||
|
|
||||||
|
(log/info "Deleting " (count all-ids) args)
|
||||||
|
(d-transactions/delete all-ids)
|
||||||
|
{:message (str "Succesfully deleted " (count all-ids) " transactions.")}))
|
||||||
|
|
||||||
(defn transaction-account->entity [{:keys [id account_id amount location]}]
|
(defn transaction-account->entity [{:keys [id account_id amount location]}]
|
||||||
(remove-nils #:transaction-account {:amount (Double/parseDouble amount)
|
(remove-nils #:transaction-account {:amount (Double/parseDouble amount)
|
||||||
|
|||||||
@@ -54,29 +54,53 @@
|
|||||||
:query/alias :result}]}
|
:query/alias :result}]}
|
||||||
:on-success (fn [result]
|
:on-success (fn [result]
|
||||||
|
|
||||||
|
|
||||||
[::data-page/received ::page (:result result)])}}))
|
[::data-page/received ::page (:result result)])}}))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::unapprove-all
|
::unapprove-selected
|
||||||
(fn [cofx [_ params]]
|
(fn [cofx [_ params]]
|
||||||
|
(let [checked @(re-frame/subscribe [::data-page/checked ::page])
|
||||||
|
checked-params (get checked "header")
|
||||||
|
specific-transactions (map :id (vals (dissoc checked "header")))]
|
||||||
|
(println checked-params)
|
||||||
{:db (-> (:db cofx)
|
{:db (-> (:db cofx)
|
||||||
(assoc-in [:status :loading] true))
|
(assoc-in [:status :loading] true))
|
||||||
:graphql {:token (-> cofx :db :user)
|
:graphql {:token (-> cofx :db :user)
|
||||||
:owns-state {:single ::unapprove-all}
|
:owns-state {:single ::unapprove-selected}
|
||||||
:query-obj
|
:query-obj
|
||||||
{:venia/operation {:operation/type :mutation
|
{:venia/operation {:operation/type :mutation
|
||||||
:operation/name "UnapproveTransactions"}
|
:operation/name "UnapproveTransactions"}
|
||||||
:venia/queries [{:query/data
|
:venia/queries [{:query/data
|
||||||
[:unapprove-transactions
|
[:unapprove-transactions
|
||||||
(data-params->query-params params)
|
{:filters (some-> checked-params data-params->query-params)
|
||||||
[[:transactions transaction-read]
|
:ids specific-transactions}
|
||||||
:total
|
[:message]]}]}
|
||||||
:start
|
|
||||||
:end]]}]}
|
|
||||||
:on-success (fn [result]
|
:on-success (fn [result]
|
||||||
[::data-page/received ::page (set/rename-keys (first (:unapprove-transactions result))
|
[::params-change params]
|
||||||
{:transactions :data})])}}))
|
#_[::data-page/received ::page (:result result)])}})))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::delete-selected
|
||||||
|
(fn [cofx [_ params]]
|
||||||
|
(let [checked @(re-frame/subscribe [::data-page/checked ::page])
|
||||||
|
checked-params (get checked "header")
|
||||||
|
specific-transactions (map :id (vals (dissoc checked "header")))]
|
||||||
|
(println checked-params)
|
||||||
|
{:db (-> (:db cofx)
|
||||||
|
(assoc-in [:status :loading] true))
|
||||||
|
:graphql {:token (-> cofx :db :user)
|
||||||
|
:owns-state {:single ::delete-selected}
|
||||||
|
:query-obj
|
||||||
|
{:venia/operation {:operation/type :mutation
|
||||||
|
:operation/name "UnapproveTransactions"}
|
||||||
|
:venia/queries [{:query/data
|
||||||
|
[:delete-transactions
|
||||||
|
{:filters (some-> checked-params data-params->query-params)
|
||||||
|
:ids specific-transactions}
|
||||||
|
[:message]]}]}
|
||||||
|
:on-success (fn [result]
|
||||||
|
[::params-change params])}})))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::unmounted
|
::unmounted
|
||||||
@@ -105,22 +129,41 @@
|
|||||||
|
|
||||||
|
|
||||||
(defn content []
|
(defn content []
|
||||||
(let [user @(re-frame/subscribe [::subs/user])
|
(let [is-admin? @(re-frame/subscribe [::subs/is-admin?])
|
||||||
params @(re-frame/subscribe [::data-page/params ::page])]
|
params @(re-frame/subscribe [::data-page/params ::page])
|
||||||
|
checked @(re-frame/subscribe [::data-page/checked ::page])]
|
||||||
[:div
|
[:div
|
||||||
[:h1.title "Transactions"]
|
[:h1.title "Transactions"]
|
||||||
[status/status-notification {:statuses [[::status/single ::unapprove-all]
|
[status/status-notification {:statuses [[::status/single ::unapprove-selected]
|
||||||
|
[::status/single ::delete-selected]
|
||||||
[::status/single ::manual-import]]}]
|
[::status/single ::manual-import]]}]
|
||||||
(when (= "admin" (:user/role user))
|
(when is-admin?
|
||||||
[:div.is-pulled-right
|
[:div.is-pulled-right
|
||||||
[:div.buttons
|
[:div.buttons
|
||||||
|
|
||||||
|
(into [:div.tags ] (map (fn [[z {:keys [id]}]]
|
||||||
|
(if (= "header" z)
|
||||||
|
[:span.tag.is-medium {:on-click
|
||||||
|
(dispatch-event [::data-page/remove-check ::page "header"])}
|
||||||
|
"All visible transactions"]
|
||||||
|
[:span.tag.is-medium id
|
||||||
|
[:button.delete.is-small {:on-click
|
||||||
|
(dispatch-event [::data-page/remove-check ::page id])}]]))
|
||||||
|
checked))
|
||||||
[:button.button.is-outlined.is-primary {:on-click (dispatch-event [::manual/opening])}
|
[:button.button.is-outlined.is-primary {:on-click (dispatch-event [::manual/opening])}
|
||||||
"Manual Yodlee Import"]
|
"Manual Yodlee Import"]
|
||||||
[:button.button.is-warning {:on-click (dispatch-event [::unapprove-all params])
|
[:button.button.is-warning {:on-click (dispatch-event [::unapprove-selected params])
|
||||||
:class (status/class-for @(re-frame/subscribe [::status/single ::unapprove-all]))
|
:class (status/class-for @(re-frame/subscribe [::status/single ::unapprove-selected]))
|
||||||
:disabled (status/disabled-for @(re-frame/subscribe [::status/single ::unapprove-all]))}
|
:disabled (or (status/disabled-for @(re-frame/subscribe [::status/single ::unapprove-selected]))
|
||||||
"Unapprove all"]]])
|
(not (seq checked)))}
|
||||||
|
"Unapprove selected"]
|
||||||
|
[:button.button.is-danger {:on-click (dispatch-event [::delete-selected params])
|
||||||
|
:class (status/class-for @(re-frame/subscribe [::status/single ::delete-selected]))
|
||||||
|
:disabled (or (status/disabled-for @(re-frame/subscribe [::status/single ::delete-selected]))
|
||||||
|
(not (seq checked)))}
|
||||||
|
"Delete selected"]]])
|
||||||
[table/table {:id :transactions
|
[table/table {:id :transactions
|
||||||
|
:check-boxes? is-admin?
|
||||||
:data-page ::page}]]))
|
:data-page ::page}]]))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -55,16 +55,18 @@
|
|||||||
(fn [{table-params :db} [_ params :as z]]
|
(fn [{table-params :db} [_ params :as z]]
|
||||||
{:db (merge table-params params)}))
|
{:db (merge table-params params)}))
|
||||||
|
|
||||||
(defn table [{:keys [id data-page ]}]
|
(defn table [{:keys [id data-page check-boxes?]}]
|
||||||
(let [selected-client @(re-frame/subscribe [::subs/client])
|
(let [selected-client @(re-frame/subscribe [::subs/client])
|
||||||
{:keys [data status]} @(re-frame/subscribe [::data-page/page data-page])
|
{:keys [data status params]} @(re-frame/subscribe [::data-page/page data-page])
|
||||||
states @(re-frame/subscribe [::status/multi ::edits])]
|
states @(re-frame/subscribe [::status/multi ::edits])]
|
||||||
[grid/grid {:data-page data-page
|
[grid/grid {:data-page data-page
|
||||||
:column-count (if selected-client 6 7)}
|
:column-count (if selected-client 6 7)
|
||||||
|
:check-boxes? check-boxes?}
|
||||||
[grid/controls data]
|
[grid/controls data]
|
||||||
[grid/table {:fullwidth true}
|
[grid/table {:fullwidth true}
|
||||||
[grid/header {}
|
[grid/header {}
|
||||||
[grid/row {}
|
[grid/row {:id "header"
|
||||||
|
:entity params}
|
||||||
(when-not selected-client
|
(when-not selected-client
|
||||||
[grid/sortable-header-cell {:sort-key "client" :sort-name "Client"} "Client"])
|
[grid/sortable-header-cell {:sort-key "client" :sort-name "Client"} "Client"])
|
||||||
[grid/sortable-header-cell {:sort-key "account" :sort-name "Bank Account"} "Bank Account"]
|
[grid/sortable-header-cell {:sort-key "account" :sort-name "Bank Account"} "Bank Account"]
|
||||||
@@ -76,7 +78,7 @@
|
|||||||
[grid/body
|
[grid/body
|
||||||
(for [{:keys [client account vendor approval-status payment status bank-account description-original date amount id yodlee-merchant ] :as i} (:data data)]
|
(for [{:keys [client account vendor approval-status payment status bank-account description-original date amount id yodlee-merchant ] :as i} (:data data)]
|
||||||
^{:key id}
|
^{:key id}
|
||||||
[grid/row {:class (:class i) :id id}
|
[grid/row {:class (:class i) :id id :entity i}
|
||||||
(when-not selected-client
|
(when-not selected-client
|
||||||
[grid/cell {} (:name client)])
|
[grid/cell {} (:name client)])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user