enforce locked until for payments
This commit is contained in:
@@ -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}]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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}]])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user