Makes it possible to bulk change invoices

This commit is contained in:
Bryce Covert
2022-12-13 07:45:55 -08:00
parent 545d5c2529
commit d40ff90e85
10 changed files with 255 additions and 23 deletions

View File

@@ -28,6 +28,11 @@
[:span.icon [:i.fa.fa-plus]]
[:span name]])
(defn event-button [{:keys [event name class ]}]
[:a.button.is-outlined {:class class
:on-click (dispatch-event event)}
[:span name]])
(defn dropdown [{:keys [event on-click] :as params}]
[:a.button (cond-> params
true (dissoc :event :icon)

View File

@@ -96,7 +96,7 @@
(on-change (into [] updated-expense-accounts))))}
[:div
[:div.tags
(when max-value
(when (and max-value (not percentage-only?))
[:div.tag "To Allocate: " (->$ max-value)])
(when-not percentage-only?

View File

@@ -29,6 +29,7 @@
:per-page (:per-page params)
:vendor-id (:id (:vendor params))
:account-id (:id (:account params))
:date-range (:date-range params)
:due-range (:due-range params)
:amount-gte (:amount-gte (:amount-range params))

View File

@@ -21,7 +21,8 @@
(defn invoices-side-bar [{:keys [data-page] :as params}]
(let [ap @(re-frame/subscribe [::subs/active-page])
user @(re-frame/subscribe [::subs/user])]
user @(re-frame/subscribe [::subs/user])
client @(re-frame/subscribe [::subs/client])]
[:div
[:div [:p.menu-label "Type"]
[:ul.menu-list
@@ -111,6 +112,18 @@
[:div
[invoice-number-filter params]]
[:p.menu-label "Financial Account"]
[:div
[search-backed-typeahead {:search-query (fn [i]
[:search_account
{:query i
:client-id (:id client)}
[:name :id]])
:entity->text (fn [x ] (:name x))
:type "typeahead-v3"
:on-change #(re-frame/dispatch [::data-page/filter-changed data-page :account (some-> % (select-keys [:name :id :numeric-code]))])
:value @(re-frame/subscribe [::data-page/filter data-page :account])}]]
(when-let [exact-match-id @(re-frame/subscribe [::data-page/filter data-page :exact-match-id])]
[:div
[:p.menu-label "Specific Invoice"]

View File

@@ -0,0 +1,97 @@
(ns auto-ap.views.pages.invoices.bulk-change
(:require
[auto-ap.forms :as forms]
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components.expense-accounts-field
:as expense-accounts-field
:refer [expense-accounts-field-v2]]
[auto-ap.views.components.modal :as modal]
[auto-ap.views.pages.data-page :as data-page]
[auto-ap.views.components.invoice-table
:refer [data-params->query-params]]
[auto-ap.views.utils :refer [dispatch-event with-user]]
[clojure.string :as str]
[re-frame.core :as re-frame]
[reagent.core :as r]
[vimsical.re-frame.fx.track :as track]
[auto-ap.events :as events]
[vimsical.re-frame.cofx.inject :as inject]
[auto-ap.forms.builder :as form-builder]
[auto-ap.views.components :as com]))
(re-frame/reg-event-fx
::coded
(fn [_ [_ _ _]]
{:dispatch-n [[::modal/modal-closed]
[:auto-ap.views.pages.unpaid-invoices/params-change
@(re-frame/subscribe [::data-page/params :auto-ap.views.pages.unpaid-invoices/invoices])]]}))
(re-frame/reg-event-fx
::code-selected
[with-user (forms/in-form ::form) (re-frame/inject-cofx ::inject/sub [::subs/client])]
(fn [{:keys [user db] ::subs/keys [client]} [_ checked]]
(let [checked-params (get checked "header")
specific-invoices (map :id (vals (dissoc checked "header")))
data (:data db)]
{:graphql
{:token user
:owns-state {:single ::form}
:query-obj {:venia/operation {:operation/type :mutation
:operation/name "BulkChangeInvoices"}
:venia/queries [[:bulk-change-invoices
{:filters (some-> checked-params data-params->query-params)
:client_id (:id client)
:ids specific-invoices
:accounts (map
#(-> %
(update :id (fn [i] (if (some-> i (str/starts-with? "new-"))
nil
i)))
(assoc :percentage (/ (get-in % [:amount-percentage]) 100 ))
(assoc :account-id (get-in % [:account :id]))
(select-keys [:percentage :id :location :account-id]))
(:accounts data))}
[:message]
]]}
:on-success (fn [result]
[::coded
(:message result)
checked-params
])}})))
(defn form-content [_]
(let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])]
[form-builder/builder {:submit-event [::code-selected]
:id ::form}
[form-builder/raw-field-v2 {:field :accounts}
[expense-accounts-field-v2 {:descriptor "account asssignment"
:percentage-only? true
:client (:client data)
:locations (into ["Shared"] @(re-frame/subscribe [::subs/locations-for-client (:id (:client data))]))
:max 100}]]]))
(defn form [_]
(r/create-class
{:display-name "invoice-bulk-change-form"
:reagent-render (fn [p]
[form-content p])}))
(re-frame/reg-event-fx
::bulk-change-requested
(fn [{:keys [db]} [_ checked params total-visible]]
(let [to-change (if (get checked "header")
[:b.strong.has-text-danger "all " total-visible " visible invoices"]
(str (count checked) " invoices"))]
{:dispatch [::modal/modal-requested {:title "Confirmation"
:body [:div "Please fill in the details on how to code " to-change ":"
[form ]]
:cancel? true
:confirm {:value "Code"
:class "is-danger"
:status-from [::status/single ::form]
:on-click (dispatch-event [::code-selected checked] )}
:close-event [::status/completed ::code-selected]}]
:db (-> db
(forms/start-form ::form {:accounts []
:client @(re-frame/subscribe [::subs/client (:client-id params)])}))})))

View File

@@ -132,7 +132,8 @@
(defn action-buttons []
(let [is-admin? @(re-frame/subscribe [::subs/is-admin?])
params @(re-frame/subscribe [::data-page/params ::page])
checked @(re-frame/subscribe [::data-page/checked ::page])]
checked @(re-frame/subscribe [::data-page/checked ::page])
{:keys [total]} @(re-frame/subscribe [::data-page/data ::page])]
(when is-admin?
[:<>
[:div.level-item
@@ -154,7 +155,7 @@
[:button.button.is-outlined.is-primary {:on-click (dispatch-event [::manual/opening])}
"Manual Yodlee Import"]
(when (:client-id params)
[:button.button.is-warning {:on-click (dispatch-event [::bulk/code-requested checked params])
[:button.button.is-warning {:on-click (dispatch-event [::bulk/code-requested checked params total])
:disabled (not (seq checked))}
"Code"])
[:button.button.is-danger {:on-click (dispatch-event [::delete-selected-requested params false])

View File

@@ -138,9 +138,9 @@
(re-frame/reg-event-fx
::code-requested
(fn [{:keys [db]} [_ checked params]]
(fn [{:keys [db]} [_ checked params total-visible]]
(let [to-delete (if (get checked "header")
[:b.strong.has-text-danger "all visible transactions"]
[:b.strong.has-text-danger "all " total-visible " visible transactions"]
(str (count checked) " transactions"))]
{:dispatch [::modal/modal-requested {:title "Confirmation"
:body [:div "Please fill in the details on how to code " to-delete ":"

View File

@@ -6,6 +6,7 @@
[auto-ap.status :as status]
[auto-ap.subs :as subs]
[auto-ap.views.components.buttons :as buttons]
[auto-ap.views.pages.invoices.bulk-change :as bulk-change]
[auto-ap.views.components.dropdown :refer [drop-down]]
[auto-ap.views.components.expense-accounts-dialog
:as expense-accounts-dialog]
@@ -208,18 +209,32 @@
"Void"])))
(defn pay-button []
(defn pay-button [status]
(let [current-client @(re-frame/subscribe [::subs/client])
checked-invoices @(re-frame/subscribe [::data-page/checked :invoices])
print-checks-status @(re-frame/subscribe [::status/single ::print-checks])]
is-admin? @(re-frame/subscribe [::subs/is-admin?])
print-checks-status @(re-frame/subscribe [::status/single ::print-checks])
params @(re-frame/subscribe [::data-page/params :invoices])
{:keys [total]} @(re-frame/subscribe [::data-page/data :invoices])
]
[:div.buttons
[void-selected-button]
(when (and (= :unpaid status)
is-admin?)
[void-selected-button])
[buttons/new-button {:event [::new-invoice-clicked]
:name "Invoice"
:class "is-primary"}]
(when current-client
(when (and is-admin?
current-client)
[buttons/event-button {:event [::bulk-change/bulk-change-requested checked-invoices params total]
:name "Bulk Edit"
:class "is-secondary"
:disabled (not (seq checked-invoices))}])
(when (and current-client
(= :unpaid status))
(let [balance (->> checked-invoices
vals
(map (comp js/parseFloat :outstanding-balance))
@@ -284,11 +299,10 @@
[table/invoice-table {:id (:id page)
:data-page :invoices
:check-boxes (= status :unpaid)
:check-boxes true
:checkable-fn (fn [i] (not (:scheduled-payment i)))
:actions #{:edit :void :expense-accounts}
:action-buttons (when (= status :unpaid)
[pay-button])}]]))
:action-buttons [pay-button status]}]]))
(defn layout [params]
(let [{invoice-bar-active? :active?} @(re-frame/subscribe [::forms/form ::form/form])]