enforce locked until for payments

This commit is contained in:
Bryce Covert
2022-03-14 10:43:38 -07:00
parent ab4a426369
commit ee6669253f
4 changed files with 42 additions and 12 deletions

View File

@@ -10,7 +10,7 @@
[auto-ap.datomic.transactions :as d-transactions]
[auto-ap.datomic.vendors :as d-vendors]
[auto-ap.graphql.utils
:refer [->graphql <-graphql assert-admin assert-can-see-client enum->keyword]]
:refer [->graphql <-graphql assert-admin assert-can-see-client enum->keyword assert-not-locked assert-none-locked]]
[auto-ap.numeric :refer [num->words]]
[auto-ap.time :refer [iso-date local-now parse]]
[auto-ap.utils :refer [by dollars-0?]]
@@ -376,6 +376,7 @@
(let [message (str "The bank account " (:bank-account/name bank-account) " does not have a starting check number. Please ask the integreat staff to initialize it.")]
(throw (ex-info message
{:validation-error message}))))
_ (assert-none-locked client-id (map (comp c/to-date :invoice/date) invoices))
checks (->> (for [[[vendor-id invoices] index] (map vector invoices-grouped-by-vendor (range))]
(invoices->entities invoices (vendors vendor-id) client bank-account type index invoice-amounts))
(reduce into [])
@@ -431,7 +432,10 @@
bank-account (d-bank-accounts/get-by-id bank-account-id)
_ (doseq [invoice invoices]
(assert-can-see-client (:id context) (:invoice/client invoice)))
client-id (:db/id (:invoice/client (first invoices)))
_ (validate-belonging (:db/id (:client/_bank-accounts bank-account)) invoices bank-account)
_ (assert-none-locked client-id (map (comp c/to-date :invoice/date) invoices))
_ (assert-not-locked client-id (:date args))
invoice-payment-lookup (by :invoice_id :amount (:invoice_payments args))
base-payment (base-payment invoices
(:invoice/vendor (first invoices))
@@ -459,6 +463,7 @@
(assert (or (= :payment-status/pending (:payment/status check))
(#{:payment-type/cash :payment-type/debit} (:payment/type check))))
(assert-can-see-client (:id context) (:db/id (:payment/client check)))
(assert-not-locked (:db/id (:payment/client check)) (:payment/date check))
(let [removing-payments (mapcat (fn [x]
(let [invoice (:invoice-payment/invoice x)
new-balance (+ (:invoice/outstanding-balance invoice)
@@ -501,7 +506,12 @@
:in $ [?p ...]
:where
(not [_ :transaction/payment ?p])
(not [?p :payment/status :payment-status/voided])]
(not [?p :payment/status :payment-status/voided])
[?p :payment/client ?c]
[(get-else $ ?c :client/locked-until #inst "2000-01-01") ?lu]
[?p :payment/date ?d]
[(>= ?d ?lu)]
]
(d/db conn))
(mapcat (fn [{:keys [:db/id]
invoices :invoice-payment/_payment}]

View File

@@ -11,6 +11,7 @@
:as u
:refer [<-graphql
assert-admin
assert-not-locked
assert-can-see-client
assert-power-user
assert-failure
@@ -149,11 +150,8 @@
(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)
@@ -252,11 +250,14 @@
(log/info "Voiding " (count all-ids) args)
(audit-transact
(->> all-ids
(d/q '[:find [(pull ?i [:db/id {:invoice/expense-accounts [:db/id]}]) ...]
(d/q '[:find [(pull ?i [:db/id :invoice/date {:invoice/expense-accounts [:db/id]}]) ...]
:in $ [?i ...]
:where (not [_ :invoice-payment/invoice ?i])]
(d/db conn)
)
:where (not [_ :invoice-payment/invoice ?i])
[?i :invoice/client ?c]
[(get-else $ ?c :client/locked-until #inst "2000-01-01") ?lu]
[?i :invoice/date ?d]
[(>= ?d ?lu)]]
(d/db conn))
(mapcat
(fn [i]
(into

View File

@@ -1,6 +1,10 @@
(ns auto-ap.graphql.utils
(:require [clojure.string :as str]
[auto-ap.datomic :refer [conn]]
[clj-time.coerce :as coerce]
[auto-ap.time :as atime]
[buddy.auth :refer [throw-unauthorized]]
[datomic.api :as d]
[clojure.walk :as walk]
[clojure.tools.logging :as log]))
@@ -106,3 +110,16 @@
(defn enum->keyword [e namespace]
(some->> e name snake->kebab (keyword namespace)))
(defn get-locked-until [client-id]
(:client/locked-until (d/pull (d/db conn) [:client/locked-until] client-id)))
(defn assert-not-locked [client-id date]
(let [locked-until (get-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 assert-none-locked [client-id dates]
(doseq [d dates]
(assert-not-locked client-id d)))

View File

@@ -55,8 +55,9 @@
(re-frame/reg-event-fx
::unmounted
(fn [_ _]
(fn [{:keys [db]} _]
{:dispatch [::data-page/dispose ::page]
:db (-> db (status/reset-multi ::table/void))
::track/dispose {:id ::params}
::forward/dispose {:id ::page}}))
@@ -148,6 +149,7 @@
[:div
[:h1.title "Payments"]
[action-buttons]
[status/status-notification {:statuses [[::status/last-multi ::table/void]]}]
[table/table {:id :payments
:data-page ::page}]])