Makes invoice reject accounts that cannot be used.
This commit is contained in:
@@ -23,7 +23,8 @@
|
|||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[clojure.tools.logging :as log]
|
[clojure.tools.logging :as log]
|
||||||
[datomic.api :as d]))
|
[datomic.api :as d]
|
||||||
|
[manifold.deferred :as de]))
|
||||||
|
|
||||||
(defn ->graphql [invoice user ]
|
(defn ->graphql [invoice user ]
|
||||||
(if (= "admin" (:user/role user))
|
(if (= "admin" (:user/role user))
|
||||||
@@ -127,7 +128,7 @@
|
|||||||
set)]
|
set)]
|
||||||
(set/difference existing-ids specified-ids)))
|
(set/difference existing-ids specified-ids)))
|
||||||
|
|
||||||
(defn assert-valid-expense-accounts [expense_accounts]
|
(defn assert-valid-expense-accounts [expense_accounts vendor_id]
|
||||||
(doseq [expense-account expense_accounts
|
(doseq [expense-account expense_accounts
|
||||||
:let [account (d/entity (d/db conn) (:account_id expense-account))]]
|
:let [account (d/entity (d/db conn) (:account_id expense-account))]]
|
||||||
(when (empty? (:location expense-account))
|
(when (empty? (:location expense-account))
|
||||||
@@ -140,6 +141,14 @@
|
|||||||
(throw (ex-info err
|
(throw (ex-info err
|
||||||
{:validation-error err}))))
|
{:validation-error err}))))
|
||||||
|
|
||||||
|
(when (and (= :allowance/denied
|
||||||
|
(:account/invoice-allowance account))
|
||||||
|
(not= (:db/id (:vendor/default-account (d/entity (d/db conn) vendor_id)))
|
||||||
|
(:db/id account)))
|
||||||
|
(let [err (str "Account isn't allowed for invoice use.")]
|
||||||
|
(throw (ex-info err
|
||||||
|
{:validation-error err}))))
|
||||||
|
|
||||||
(when (and (empty? (:account/location account))
|
(when (and (empty? (:account/location account))
|
||||||
(= "A" (:location expense-account)))
|
(= "A" (:location expense-account)))
|
||||||
(let [err (str "Account uses location '" (:location expense-account) "', which is reserved for liabilities, equities, and assets.")]
|
(let [err (str "Account uses location '" (:location expense-account) "', which is reserved for liabilities, equities, and assets.")]
|
||||||
@@ -160,12 +169,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn add-invoice [context {{:keys [expense_accounts client_id] :as in} :invoice} _]
|
(defn add-invoice [context {{:keys [expense_accounts client_id vendor_id] :as in} :invoice} _]
|
||||||
(assert-no-conflicting in)
|
(assert-no-conflicting in)
|
||||||
(assert-can-see-client (:id context) client_id)
|
(assert-can-see-client (:id context) client_id)
|
||||||
|
|
||||||
(assert-not-locked client_id (:date in))
|
(assert-not-locked client_id (:date in))
|
||||||
(assert-valid-expense-accounts expense_accounts)
|
(assert-valid-expense-accounts expense_accounts vendor_id)
|
||||||
(assert-invoice-amounts-add-up in)
|
(assert-invoice-amounts-add-up in)
|
||||||
|
|
||||||
(let [transaction-result (transact-with-ledger [(add-invoice-transaction in)] (:id context))]
|
(let [transaction-result (transact-with-ledger [(add-invoice-transaction in)] (:id context))]
|
||||||
@@ -178,12 +187,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defn add-and-print-invoice [context {{:keys [total client_id] :as in} :invoice bank-account-id :bank_account_id type :type} _]
|
(defn add-and-print-invoice [context {{:keys [total client_id vendor_id] :as in} :invoice bank-account-id :bank_account_id type :type} _]
|
||||||
(assert-no-conflicting in)
|
(assert-no-conflicting in)
|
||||||
(assert-can-see-client (:id context) client_id)
|
(assert-can-see-client (:id context) client_id)
|
||||||
(assert-bank-account-belongs client_id bank-account-id)
|
(assert-bank-account-belongs client_id bank-account-id)
|
||||||
(assert-not-locked client_id (:date in))
|
(assert-not-locked client_id (:date in))
|
||||||
(assert-valid-expense-accounts (:expense_accounts in))
|
(assert-valid-expense-accounts (:expense_accounts in) vendor_id)
|
||||||
(assert-invoice-amounts-add-up in)
|
(assert-invoice-amounts-add-up in)
|
||||||
(let [transaction-result (transact-with-ledger [(add-invoice-transaction in)] (:id context))]
|
(let [transaction-result (transact-with-ledger [(add-invoice-transaction in)] (:id context))]
|
||||||
(-> (gq-checks/print-checks-internal [{:invoice-id (get-in transaction-result [:tempids "invoice"])
|
(-> (gq-checks/print-checks-internal [{:invoice-id (get-in transaction-result [:tempids "invoice"])
|
||||||
@@ -194,7 +203,7 @@
|
|||||||
(:id context))
|
(:id context))
|
||||||
u/->graphql)))
|
u/->graphql)))
|
||||||
|
|
||||||
(defn edit-invoice [context {{:keys [id due invoice_number total date expense_accounts scheduled_payment] :as in} :invoice} _]
|
(defn edit-invoice [context {{:keys [id due invoice_number vendor_id total date expense_accounts scheduled_payment] :as in} :invoice} _]
|
||||||
(let [invoice (d-invoices/get-by-id id)
|
(let [invoice (d-invoices/get-by-id id)
|
||||||
_ (when (seq (d-invoices/find-conflicting {:db/id id
|
_ (when (seq (d-invoices/find-conflicting {:db/id id
|
||||||
:invoice/invoice-number invoice_number
|
:invoice/invoice-number invoice_number
|
||||||
@@ -206,7 +215,7 @@
|
|||||||
_ (assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))
|
_ (assert-can-see-client (:id context) (:db/id (:invoice/client invoice)))
|
||||||
deleted (deleted-expense-accounts invoice expense_accounts)
|
deleted (deleted-expense-accounts invoice expense_accounts)
|
||||||
_ (assert-not-locked (:db/id (:invoice/client invoice)) (:date in))
|
_ (assert-not-locked (:db/id (:invoice/client invoice)) (:date in))
|
||||||
_ (assert-valid-expense-accounts expense_accounts)
|
_ (assert-valid-expense-accounts expense_accounts vendor_id)
|
||||||
_ (assert-invoice-amounts-add-up in)
|
_ (assert-invoice-amounts-add-up in)
|
||||||
|
|
||||||
updated-invoice (cond-> {:db/id id
|
updated-invoice (cond-> {:db/id id
|
||||||
|
|||||||
101
test/clj/auto_ap/integration/graphql/invoices.clj
Normal file
101
test/clj/auto_ap/integration/graphql/invoices.clj
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
(ns auto-ap.integration.graphql.invoices
|
||||||
|
(:require
|
||||||
|
[auto-ap.datomic :refer [conn uri]]
|
||||||
|
[auto-ap.datomic.migrate :as m]
|
||||||
|
[auto-ap.time-reader]
|
||||||
|
[auto-ap.graphql.invoices :as sut]
|
||||||
|
[clj-time.core :as time]
|
||||||
|
[clojure.test :as t :refer [deftest is testing use-fixtures]]
|
||||||
|
[datomic.api :as d]))
|
||||||
|
|
||||||
|
(defn wrap-setup
|
||||||
|
[f]
|
||||||
|
(with-redefs [auto-ap.datomic/uri "datomic:mem://datomic-transactor:4334/invoice"]
|
||||||
|
(d/create-database uri)
|
||||||
|
(with-redefs [auto-ap.datomic/conn (d/connect uri)]
|
||||||
|
(m/migrate conn)
|
||||||
|
|
||||||
|
(f)
|
||||||
|
(d/release conn)
|
||||||
|
(d/delete-database uri))))
|
||||||
|
|
||||||
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
|
(defn admin-token []
|
||||||
|
{:user "TEST ADMIN"
|
||||||
|
:exp (time/plus (time/now) (time/days 1))
|
||||||
|
:user/role "admin"
|
||||||
|
:user/name "TEST ADMIN"})
|
||||||
|
|
||||||
|
#_{:clj-kondo/ignore [:clojure-lsp/unused-public-var]}
|
||||||
|
(defn user-token [client-id]
|
||||||
|
{:user "TEST USER"
|
||||||
|
:exp (time/plus (time/now) (time/days 1))
|
||||||
|
:user/role "user"
|
||||||
|
:user/name "TEST USER"
|
||||||
|
:user/clients [{:db/id client-id}]})
|
||||||
|
|
||||||
|
|
||||||
|
(use-fixtures :each wrap-setup)
|
||||||
|
|
||||||
|
(deftest test-add-invoice
|
||||||
|
(testing "It should Add an invoice"
|
||||||
|
(let [{:strs [vendor-id client-id account-id]}
|
||||||
|
(:tempids @(d/transact conn [{:client/code "ABC"
|
||||||
|
:db/id "client-id"
|
||||||
|
:client/locations ["DT"]}
|
||||||
|
{:vendor/name "Vendy"
|
||||||
|
:db/id "vendor-id"
|
||||||
|
:vendor/default-account "account-id"}
|
||||||
|
{:account/name "Account"
|
||||||
|
:account/numeric-code 123
|
||||||
|
:account/invoice-allowance :allowance/allowed
|
||||||
|
:db/id "account-id"}]))]
|
||||||
|
(is (some? (sut/add-invoice {:id (admin-token)}
|
||||||
|
{:invoice {:client_id client-id
|
||||||
|
:vendor_id vendor-id
|
||||||
|
:invoice_number "123"
|
||||||
|
:date #clj-time/date-time "2022-01-01"
|
||||||
|
:total 10.00
|
||||||
|
:expense_accounts [{:amount 10.0
|
||||||
|
:location "DT"
|
||||||
|
:account_id account-id}]}}
|
||||||
|
nil)))
|
||||||
|
(testing "It should prevent an expense account that isn't allowed"
|
||||||
|
(let [{:strs [denied-account-id]}
|
||||||
|
(:tempids @(d/transact conn [
|
||||||
|
{:account/name "Account"
|
||||||
|
:account/numeric-code 123
|
||||||
|
:account/invoice-allowance :allowance/denied
|
||||||
|
:db/id "denied-account-id"}]))]
|
||||||
|
(is (thrown? Exception (sut/add-invoice {:id (admin-token)}
|
||||||
|
{:invoice {:client_id client-id
|
||||||
|
:vendor_id vendor-id
|
||||||
|
:invoice_number "789"
|
||||||
|
:date #clj-time/date-time "2022-01-01"
|
||||||
|
:total 10.00
|
||||||
|
:expense_accounts [{:amount 10.0
|
||||||
|
:location "DT"
|
||||||
|
:account_id denied-account-id}]}}
|
||||||
|
nil)))))
|
||||||
|
|
||||||
|
(testing "It should allow an expense account that is valid for the vendor"
|
||||||
|
(let [{:strs [vendor-account-id vendor-2]}
|
||||||
|
(:tempids @(d/transact conn [
|
||||||
|
{:account/name "Account"
|
||||||
|
:account/numeric-code 123
|
||||||
|
:account/invoice-allowance :allowance/denied
|
||||||
|
:account/vendor-allowance :allowance/allowed
|
||||||
|
:db/id "vendor-account-id"}
|
||||||
|
{:vendor/name "Testy"
|
||||||
|
:vendor/default-account "vendor-account-id"
|
||||||
|
:db/id "vendor-2"}]))]
|
||||||
|
(is (some? (sut/add-invoice {:id (admin-token)}
|
||||||
|
{:invoice {:client_id client-id
|
||||||
|
:vendor_id vendor-2
|
||||||
|
:invoice_number "456"
|
||||||
|
:date #clj-time/date-time "2022-01-01"
|
||||||
|
:total 10.00
|
||||||
|
:expense_accounts [{:amount 10.0
|
||||||
|
:location "DT"
|
||||||
|
:account_id vendor-account-id}]}}
|
||||||
|
nil))))))))
|
||||||
Reference in New Issue
Block a user