From ab4a4263699df9745ea82ece21d64dbd523d9d6b Mon Sep 17 00:00:00 2001 From: Bryce Covert Date: Sun, 13 Mar 2022 12:04:59 -0700 Subject: [PATCH] Starting to add locked until --- src/clj/auto_ap/datomic/clients.clj | 1 + src/clj/auto_ap/datomic/migrate/clients.clj | 8 +- src/clj/auto_ap/graphql.clj | 110 +------------- src/clj/auto_ap/graphql/clients.clj | 138 +++++++++++++++++- src/clj/auto_ap/graphql/invoices.clj | 29 +++- src/clj/auto_ap/graphql/utils.clj | 5 + src/cljs/auto_ap/events.cljs | 2 +- src/cljs/auto_ap/status.cljs | 5 + .../views/components/invoice_table.cljs | 1 - .../views/pages/admin/clients/form.cljs | 12 ++ .../views/pages/admin/clients/table.cljs | 9 +- .../auto_ap/views/pages/unpaid_invoices.cljs | 4 +- 12 files changed, 207 insertions(+), 117 deletions(-) diff --git a/src/clj/auto_ap/datomic/clients.clj b/src/clj/auto_ap/datomic/clients.clj index 018f215c..b892f7d1 100644 --- a/src/clj/auto_ap/datomic/clients.clj +++ b/src/clj/auto_ap/datomic/clients.clj @@ -8,6 +8,7 @@ (-> e (assoc :client/yodlee-provider-accounts (get e :yodlee-provider-account/_client)) (assoc :client/plaid-items (get e :plaid-item/_client)) + (update :client/locked-until #(some-> % coerce/to-date-time)) (update :client/location-matches (fn [lms] (map #(assoc % :location-match/match (first (:location-match/matches %))) lms))) diff --git a/src/clj/auto_ap/datomic/migrate/clients.clj b/src/clj/auto_ap/datomic/migrate/clients.clj index 9137ef2b..1fd18d0f 100644 --- a/src/clj/auto_ap/datomic/migrate/clients.clj +++ b/src/clj/auto_ap/datomic/migrate/clients.clj @@ -52,4 +52,10 @@ ::migrate-bank-account-numeric-codes {:txes-fn `migrate-bank-account-numeric-codes :requires [::add-bank-account-current-balance - ::add-bank-account-numeric-codes]}}) + ::add-bank-account-numeric-codes]} + + ::add-locked-until + {:txes [[{:db/ident :client/locked-until + :db/doc "No new data before this date can be added/changed" + :db/valueType :db.type/instant + :db/cardinality :db.cardinality/one}]]}}) diff --git a/src/clj/auto_ap/graphql.clj b/src/clj/auto_ap/graphql.clj index 9fbcdc7a..2e8b67be 100644 --- a/src/clj/auto_ap/graphql.clj +++ b/src/clj/auto_ap/graphql.clj @@ -96,29 +96,6 @@ { :message {:fields {:message {:type 'String}}} - :location_match - {:fields {:location {:type 'String} - :match {:type 'String} - :id {:type :id}}} - - :client - {:fields {:id {:type :id} - :name {:type 'String} - :code {:type 'String} - :signature_file {:type 'String} - :week_a_debits {:type :money} - :week_a_credits {:type :money} - :week_b_debits {:type :money} - :week_b_credits {:type :money} - :email {:type 'String} - :address {:type :address} - :location_matches {:type '(list :location_match)} - :locations {:type '(list String)} - :matches {:type '(list String)} - :bank_accounts {:type '(list :bank_account)} - :forecasted_transactions {:type '(list :forecasted_transaction)} - :yodlee_provider_accounts {:type '(list :yodlee_provider_account)} - :plaid_items {:type '(list :plaid_item)}}} :yodlee_provider_account {:fields {:id {:type 'Int} @@ -141,32 +118,7 @@ :email {:type 'String} :phone {:type 'String}}} - :bank_account - {:fields {:id {:type :id} - :type {:type :ident} - :start_date {:type :iso_date} - :number {:type 'String} - :numeric_code {:type 'Int} - :sort_order {:type 'Int} - :visible {:type 'Boolean} - :include_in_reports {:type 'Boolean} - :routing {:type 'String} - :code {:type 'String} - :check_number {:type 'Int} - :name {:type 'String} - :bank_code {:type 'String} - :bank_name {:type 'String} - :current_balance {:type :money} - :yodlee_balance_old {:type :money} - :yodlee_account_id {:type 'Int} - :yodlee_account {:type :yodlee_account} - :plaid_account {:type :plaid_account} - :intuit_bank_account {:type :intuit_bank_account} - :locations {:type '(list String)}}} - :forecasted_transaction {:fields {:identifier {:type 'String} - :id {:type :id} - :day_of_month {:type 'Int} - :amount {:type :money}}} + :balance_sheet_account {:fields {:id {:type 'String} :amount {:type 'String} @@ -507,8 +459,7 @@ - :client {:type '(list :client) - :resolve :get-client} + :vendor {:type '(list :vendor) :resolve :get-vendor} :user {:type '(list :user) @@ -538,14 +489,7 @@ :source {:type 'String} :sort {:type '(list :sort_item)}}} - :edit_location_match {:fields {:location {:type 'String} - :match {:type 'String} - :id {:type :id}}} - - :edit_forecasted_transaction {:fields {:identifier {:type 'String} - :id {:type :id} - :day_of_month {:type 'Int} - :amount {:type :money}}} + :date_range {:fields {:start {:type :iso_date} @@ -565,42 +509,7 @@ :cleared_against {:type 'String} :line_items {:type '(list :import_ledger_line_item)}}} - :edit_client {:fields {:id {:type :id} - :name {:type 'String} - :code {:type 'String} - :signature_data {:type 'String} - :email {:type 'String} - :week_a_credits {:type :money} - :week_a_debits {:type :money} - :week_b_credits {:type :money} - :week_b_debits {:type :money} - :address {:type :add_address} - :locations {:type '(list String)} - :matches {:type '(list String)} - :location_matches {:type '(list :edit_location_match)} - :bank_accounts {:type '(list :edit_bank_account)} - :forecasted_transactions {:type '(list :edit_forecasted_transaction)}}} - - :edit_bank_account - {:fields {:id {:type :id} - :code {:type 'String} - :type {:type :bank_account_type} - :start_date {:type :iso_date} - :number {:type 'String} - :check_number {:type 'Int} - :numeric_code {:type 'Int} - :visible {:type 'Boolean} - :include_in_reports {:type 'Boolean} - :sort_order {:type 'Int} - :name {:type 'String} - :bank_code {:type 'String} - :routing {:type 'String} - :bank_name {:type 'String} - :locations {:type '(list String)} - :yodlee_account_id {:type 'Int} - :intuit_bank_account {:type :id} - :plaid_account {:type :id} - :yodlee_account {:type 'Int}}} + :edit_user {:fields {:id {:type :id} :name {:type 'String} @@ -703,9 +612,7 @@ :type_1099 {:values [{:enum-value :none} {:enum-value :misc} {:enum-value :landlord}]} - :bank_account_type {:values [{:enum-value :check} - {:enum-value :credit} - {:enum-value :cash}]} + :applicability {:values [{:enum-value :global} {:enum-value :optional} {:enum-value :customized}]} @@ -737,9 +644,7 @@ :args {:edit_user {:type :edit_user}} :resolve :mutation/edit-user} - :edit_client {:type :client - :args {:edit_client {:type :edit_client}} - :resolve :mutation/edit-client} + :upsert_vendor {:type :vendor :args {:vendor {:type :add_vendor}} @@ -987,7 +892,6 @@ :get-cash-flow get-cash-flow :get-yodlee-merchants ym/get-yodlee-merchants :get-intuit-bank-accounts gq-intuit-bank-accounts/get-intuit-bank-accounts - :get-client gq-clients/get-client :get-user get-user :mutation/delete-transaction-rule gq-transaction-rules/delete-transaction-rule :mutation/edit-user gq-users/edit-user @@ -995,7 +899,6 @@ :mutation/upsert-transaction-rule gq-transaction-rules/upsert-transaction-rule :test-transaction-rule gq-transaction-rules/test-transaction-rule :run-transaction-rule gq-transaction-rules/run-transaction-rule - :mutation/edit-client gq-clients/edit-client :mutation/upsert-vendor gq-vendors/upsert-vendor :mutation/upsert-account gq-accounts/upsert-account :mutation/merge-vendors gq-vendors/merge-vendors @@ -1008,6 +911,7 @@ gq-transactions/attach gq-expected-deposit/attach gq-invoices/attach + gq-clients/attach schema/compile)) diff --git a/src/clj/auto_ap/graphql/clients.clj b/src/clj/auto_ap/graphql/clients.clj index e2b9d703..5ac2c694 100644 --- a/src/clj/auto_ap/graphql/clients.clj +++ b/src/clj/auto_ap/graphql/clients.clj @@ -4,7 +4,7 @@ [auto-ap.graphql.utils :refer [->graphql assert-admin can-see-client? is-admin?]] [auto-ap.utils :refer [by]] [auto-ap.yodlee.core :refer [in-memory-cache]] - + [com.walmartlabs.lacinia.util :refer [attach-resolvers]] [clj-time.coerce :as coerce] [config.core :refer [env]] [clojure.string :as str] @@ -95,6 +95,7 @@ :client/matches (:matches edit_client) :client/signature-file signature-file :client/email (:email edit_client) + :client/locked-until (some-> (:locked_until edit_client) (coerce/to-date)) :client/locations (filter identity (:locations edit_client)) :client/week-a-debits (:week_a_debits edit_client) :client/week-a-credits (:week_a_credits edit_client) @@ -256,3 +257,138 @@ (assoc ba :bank-account/yodlee-balance-old (get-in (by :id (mapcat :accounts @in-memory-cache) ) [(:bank-account/yodlee-account-id ba) :balance :amount]))) bank-accounts)))))))) + + + + +(def objects + {:location_match + {:fields {:location {:type 'String} + :match {:type 'String} + :id {:type :id}}} + + :client + {:fields {:id {:type :id} + :name {:type 'String} + :locked_until {:type :iso_date} + :code {:type 'String} + :signature_file {:type 'String} + :week_a_debits {:type :money} + :week_a_credits {:type :money} + :week_b_debits {:type :money} + :week_b_credits {:type :money} + :email {:type 'String} + :address {:type :address} + :location_matches {:type '(list :location_match)} + :locations {:type '(list String)} + :matches {:type '(list String)} + :bank_accounts {:type '(list :bank_account)} + :forecasted_transactions {:type '(list :forecasted_transaction)} + :yodlee_provider_accounts {:type '(list :yodlee_provider_account)} + :plaid_items {:type '(list :plaid_item)}}} + + :bank_account + {:fields {:id {:type :id} + :type {:type :ident} + :start_date {:type :iso_date} + :number {:type 'String} + :numeric_code {:type 'Int} + :sort_order {:type 'Int} + :visible {:type 'Boolean} + :include_in_reports {:type 'Boolean} + :routing {:type 'String} + :code {:type 'String} + :check_number {:type 'Int} + :name {:type 'String} + :bank_code {:type 'String} + :bank_name {:type 'String} + :current_balance {:type :money} + :yodlee_balance_old {:type :money} + :yodlee_account_id {:type 'Int} + :yodlee_account {:type :yodlee_account} + :plaid_account {:type :plaid_account} + :intuit_bank_account {:type :intuit_bank_account} + :locations {:type '(list String)}}} + + :forecasted_transaction {:fields {:identifier {:type 'String} + :id {:type :id} + :day_of_month {:type 'Int} + :amount {:type :money}}} + +}) + +(def queries + {:client {:type '(list :client) + :resolve :get-client}}) + +(def mutations + {:edit_client {:type :client + :args {:edit_client {:type :edit_client}} + :resolve :mutation/edit-client}}) + +(def input-objects + {:edit_location_match {:fields {:location {:type 'String} + :match {:type 'String} + :id {:type :id}}} + + :edit_forecasted_transaction {:fields {:identifier {:type 'String} + :id {:type :id} + :day_of_month {:type 'Int} + :amount {:type :money}}} + :edit_client {:fields {:id {:type :id} + :name {:type 'String} + :locked_until {:type :iso_date} + :code {:type 'String} + :signature_data {:type 'String} + :email {:type 'String} + :week_a_credits {:type :money} + :week_a_debits {:type :money} + :week_b_credits {:type :money} + :week_b_debits {:type :money} + :address {:type :add_address} + :locations {:type '(list String)} + :matches {:type '(list String)} + :location_matches {:type '(list :edit_location_match)} + :bank_accounts {:type '(list :edit_bank_account)} + :forecasted_transactions {:type '(list :edit_forecasted_transaction)}}} + + :edit_bank_account + {:fields {:id {:type :id} + :code {:type 'String} + :type {:type :bank_account_type} + :start_date {:type :iso_date} + :number {:type 'String} + :check_number {:type 'Int} + :numeric_code {:type 'Int} + :visible {:type 'Boolean} + :include_in_reports {:type 'Boolean} + :sort_order {:type 'Int} + :name {:type 'String} + :bank_code {:type 'String} + :routing {:type 'String} + :bank_name {:type 'String} + :locations {:type '(list String)} + :yodlee_account_id {:type 'Int} + :intuit_bank_account {:type :id} + :plaid_account {:type :id} + :yodlee_account {:type 'Int}}}}) + +(def enums + {:bank_account_type {:values [{:enum-value :check} + {:enum-value :credit} + {:enum-value :cash}]}}) + +(def resolvers + {:get-client get-client + :mutation/edit-client edit-client}) + + +(defn attach [schema] + (-> + (merge-with merge schema + {:objects objects + :queries queries + :mutations mutations + :input-objects input-objects + :enums enums}) + (attach-resolvers resolvers))) diff --git a/src/clj/auto_ap/graphql/invoices.clj b/src/clj/auto_ap/graphql/invoices.clj index 7f36002d..f1d862fc 100644 --- a/src/clj/auto_ap/graphql/invoices.clj +++ b/src/clj/auto_ap/graphql/invoices.clj @@ -6,12 +6,14 @@ [auto-ap.datomic.invoices :as d-invoices] [auto-ap.datomic.vendors :as d-vendors] [auto-ap.graphql.checks :as gq-checks] + [auto-ap.time :as atime] [auto-ap.graphql.utils :as u :refer [<-graphql assert-admin assert-can-see-client assert-power-user + assert-failure enum->keyword]] [auto-ap.utils :refer [dollars=]] [clj-time.coerce :as coerce] @@ -120,7 +122,6 @@ (defn assert-valid-expense-accounts [expense_accounts] (doseq [expense-account expense_accounts :let [account (d/entity (d/db conn) (:account_id expense-account))]] - (log/info "ACCOUNT" (:account/location account)) (when (empty? (:location expense-account)) (throw (ex-info "Expense account is missing location" {:validation-error "Expense account is missing location"}))) @@ -148,10 +149,17 @@ (when-not (dollars= total expense-account-total) (let [error (str "Expense account total (" expense-account-total ") does not equal invoice total (" total ")")] (throw (ex-info error {:validation-error error})))))) +(defn assert-not-locked [client-id date] + (let [{:client/keys [locked-until]} (d/pull (d/db conn) [:client/locked-until] client-id)] + (when (and locked-until + (>= (compare locked-until (coerce/to-date date)) 0)) + (assert-failure (str "Integreat has locked finances prior to " (-> locked-until coerce/to-date-time (atime/unparse-local atime/normal-date)) "."))))) (defn add-invoice [context {{:keys [expense_accounts client_id] :as in} :invoice} _] (assert-no-conflicting in) (assert-can-see-client (:id context) client_id) + + (assert-not-locked client_id (:date in)) (assert-valid-expense-accounts expense_accounts) (assert-invoice-amounts-add-up in) @@ -163,10 +171,13 @@ (when-not ((set (map :db/id (:client/bank-accounts (d-clients/get-by-id client-id)))) bank-account-id) (throw (ex-info (str "Bank account does not belong to client") {:validation-error "Bank account does not belong to client."})))) + + (defn add-and-print-invoice [context {{:keys [total client_id] :as in} :invoice bank-account-id :bank_account_id type :type} _] (assert-no-conflicting in) (assert-can-see-client (:id context) client_id) (assert-bank-account-belongs client_id bank-account-id) + (assert-not-locked client_id (:date in)) (assert-valid-expense-accounts (:expense_accounts in)) (assert-invoice-amounts-add-up in) (let [transaction-result (audit-transact [(add-invoice-transaction in)] (:id context))] @@ -189,6 +200,7 @@ paid-amount (- (:invoice/total invoice) (:invoice/outstanding-balance invoice)) _ (assert-can-see-client (:id context) (:db/id (:invoice/client invoice))) deleted (deleted-expense-accounts invoice expense_accounts) + _ (assert-not-locked (:db/id (:invoice/client invoice)) (:date in)) _ (assert-valid-expense-accounts expense_accounts) _ (assert-invoice-amounts-add-up in) @@ -209,8 +221,9 @@ (->graphql (:id context))))) (defn void-invoice [context {id :invoice_id} _] - (let [invoice (d-invoices/get-by-id id) - _ (assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))] + (let [invoice (d-invoices/get-by-id id)] + (assert-can-see-client (:id context) (:db/id (:invoice/client invoice))) + (assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice)) (audit-transact [{:db/id id :invoice/total 0.0 :invoice/outstanding-balance 0.0 @@ -262,6 +275,7 @@ (defn unvoid-invoice [context {id :invoice_id} _] (let [invoice (d-invoices/get-by-id id) _ (assert-can-see-client (:id context) (:db/id (:invoice/client invoice))) + _ (assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice)) conn (d/connect uri) history (d/history (d/db conn)) txs (d/query {:query {:find ['?tx '?e '?original-status '?original-outstanding '?total '?ea '?ea-amount] @@ -281,7 +295,6 @@ :invoice/total total :invoice/status original-status :invoice/outstanding-balance original-outstanding) - (update :invoice/expense-accounts conj {:db/id expense-account :invoice-expense-account/amount expense-account-amount}))) {}))] (:id context)) @@ -289,9 +302,10 @@ (->graphql (:id context))))) (defn unautopay-invoice [context {id :invoice_id} _] - (let [invoice (d/entity (d/db conn) id) - _ (assert (:invoice/client invoice)) - _ (assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))] + (let [invoice (d/entity (d/db conn) id)] + (assert (:invoice/client invoice)) + (assert-can-see-client (:id context) (:db/id (:invoice/client invoice))) + (assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice)) (audit-transact [[:db/add id :invoice/status :invoice-status/unpaid] [:db/add id :invoice/outstanding-balance (:invoice/total invoice)] [:db/retract id :invoice/scheduled-payment (:invoice/scheduled-payment invoice)]] @@ -304,6 +318,7 @@ (assert-can-see-client (:id context) (:db/id (:invoice/client (d-invoices/get-by-id (:invoice_id args))))) (let [invoice-id (:invoice_id args) invoice (d-invoices/get-by-id invoice-id) + _ (assert-not-locked (:db/id (:invoice/client invoice)) (:invoice/date invoice)) _ (assert-valid-expense-accounts (:expense_accounts args)) deleted (deleted-expense-accounts invoice (:expense_accounts args)) updated {:db/id invoice-id diff --git a/src/clj/auto_ap/graphql/utils.clj b/src/clj/auto_ap/graphql/utils.clj index aae98b24..6a13db01 100644 --- a/src/clj/auto_ap/graphql/utils.clj +++ b/src/clj/auto_ap/graphql/utils.clj @@ -59,6 +59,11 @@ (throw (ex-info (str "Missing field '" name "'.") {:validation-error (str "Missing field '" name "'.")}))))) +(defn assert-failure + ([message] + (throw (ex-info message + {:validation-error message})))) + (defn assert-power-user [id] (when-not (#{"power-user" "admin"} (:user/role id)) (log/warn "user " id " not an power-user!") diff --git a/src/cljs/auto_ap/events.cljs b/src/cljs/auto_ap/events.cljs index 54d63545..7adac694 100644 --- a/src/cljs/auto_ap/events.cljs +++ b/src/cljs/auto_ap/events.cljs @@ -31,7 +31,7 @@ [:address [:street1 :street2 :city :state :zip]]]) (defn client-query [token] - (cond-> [:id :name :signature-file :code :email :matches :week-a-debits :week-a-credits :week-b-debits :week-b-credits :locations + (cond-> [:id :name :signature-file :code :email :matches :week-a-debits :week-a-credits :week-b-debits :week-b-credits :locations :locked-until [:location-matches [:id :location :match]] [:bank-accounts [:id :start-date :numeric-code :code :number :bank-name :bank-code :check-number :name :routing :type :sort-order :visible :yodlee-account-id [:yodlee-account [:name :id :number]] diff --git a/src/cljs/auto_ap/status.cljs b/src/cljs/auto_ap/status.cljs index 7a2a7177..6e1c78ed 100644 --- a/src/cljs/auto_ap/status.cljs +++ b/src/cljs/auto_ap/status.cljs @@ -59,6 +59,11 @@ (fn [db [_ multi]] (get-in db [::status multi]))) +(re-frame/reg-sub + ::last-multi + (fn [db [_ multi]] + (last (vals (get-in db [::status multi]))))) + (re-frame/reg-sub ::single (fn [db [_ single]] diff --git a/src/cljs/auto_ap/views/components/invoice_table.cljs b/src/cljs/auto_ap/views/components/invoice_table.cljs index bd5a3543..6b73ccd8 100644 --- a/src/cljs/auto_ap/views/components/invoice_table.cljs +++ b/src/cljs/auto_ap/views/components/invoice_table.cljs @@ -72,7 +72,6 @@ :which id} :query-obj {:venia/operation {:operation/type :mutation :operation/name "VoidInvoice"} - :venia/queries [{:query/data [:void-invoice {:invoice-id id} invoice-read]}]} diff --git a/src/cljs/auto_ap/views/pages/admin/clients/form.cljs b/src/cljs/auto_ap/views/pages/admin/clients/form.cljs index 176666f0..819c5838 100644 --- a/src/cljs/auto_ap/views/pages/admin/clients/form.cljs +++ b/src/cljs/auto_ap/views/pages/admin/clients/form.cljs @@ -108,6 +108,8 @@ :name (:name new-client-data) :code (:code new-client-data) ;; TODO add validation can't change :email (:email new-client-data) + + :locked-until (some-> new-client-data :locked-until #_(date->str standard)) :locations (mapv :location (:locations new-client-data)) :matches (mapv :match (:matches new-client-data)) :location-matches (:location-matches new-client-data) @@ -516,6 +518,16 @@ [:input.input {:type "code" :field :code :spec ::entity/code}])])] + (field "Locked Until" + [date-picker {:class-name "input" + :class "input" + :format-week-number (fn [] "") + :previous-month-button-label "" + :placeholder "mm/dd/yyyy" + :next-month-button-label "" + :next-month-label "" + :type "date" + :field [:locked-until]}]) (field "Email" diff --git a/src/cljs/auto_ap/views/pages/admin/clients/table.cljs b/src/cljs/auto_ap/views/pages/admin/clients/table.cljs index 228b48db..1f71b1e6 100644 --- a/src/cljs/auto_ap/views/pages/admin/clients/table.cljs +++ b/src/cljs/auto_ap/views/pages/admin/clients/table.cljs @@ -3,7 +3,7 @@ [clojure.string :as str] [re-frame.core :as re-frame] [auto-ap.views.pages.admin.clients.form :as form] - [auto-ap.views.utils :refer [action-cell-width]] + [auto-ap.views.utils :refer [action-cell-width date->str]] [auto-ap.views.components.grid :as grid] [auto-ap.views.components.buttons :as buttons])) @@ -38,16 +38,21 @@ [grid/header-cell {} "Name"] [grid/header-cell {:style {:width "20em"}} "Code"] [grid/header-cell {} "Locations"] + [grid/header-cell {} "Locked Until"] [grid/header-cell {} "Email"] [grid/header-cell {:style {:width (action-cell-width 1)}}]] ] [grid/body - (for [{:keys [id name email code locations] :as c} (:data page)] + (for [{:keys [id name email locked-until code locations] :as c} (:data page)] ^{:key (str name "-" id )} [grid/row {:id id} [grid/cell {} name] [grid/cell {} code] [grid/cell {} (str/join ", " locations)] + [grid/cell {} [:div.tag (or (some-> locked-until date->str) + "Not locked" + + )]] [grid/cell {} email] [grid/cell {} [buttons/fa-icon {:event [::form/editing id] :icon :fa-pencil}]]])]]]) diff --git a/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs b/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs index b2d1eb9b..03b40e9f 100644 --- a/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs +++ b/src/cljs/auto_ap/views/pages/unpaid_invoices.cljs @@ -257,7 +257,9 @@ current-client @(re-frame/subscribe [::subs/client])] [:div [:h1.title (str (str/capitalize (name (or status :all))) " invoices")] - [status/status-notification {:statuses [[::status/single ::print-checks]]}] + [status/status-notification {:statuses [[::status/single ::print-checks] + [::status/last-multi ::table/void] + [::status/last-multi ::table/unvoid]]}] (when (= status :unpaid) [pay-button]) [table/invoice-table {:id (:id page)