Starting to add locked until

This commit is contained in:
Bryce Covert
2022-03-13 12:04:59 -07:00
parent 96dd99a74c
commit ab4a426369
12 changed files with 207 additions and 117 deletions

View File

@@ -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)))

View File

@@ -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

View File

@@ -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!")