adds support for bulk voids.

This commit is contained in:
2022-02-18 07:53:34 -08:00
parent ea490c5859
commit 0f8dcd43e1
6 changed files with 325 additions and 193 deletions

View File

@@ -27,128 +27,130 @@
{:payment/type [:db/ident]}
{:transaction/_payment [:db/id :transaction/date]}])
(defn raw-graphql-ids [db args]
(let [check-number-like (try (Long/parseLong (:check-number-like args)) (catch Exception _ nil))
query (cond-> {:query {:find []
:in ['$]
:where []}
:args [db]}
(:sort args) (add-sorter-fields {"client" ['[?e :payment/client ?c]
'[?c :client/name ?sort-client]]
"vendor" ['[?e :payment/vendor ?v]
'[?v :vendor/name ?sort-vendor]]
"bank-account" ['[?e :payment/bank-account ?ba]
'[?ba :bank-account/name ?sort-bank-account]]
"check-number" ['[(get-else $ ?e :payment/check-number 0) ?sort-check-number]]
"date" ['[?e :payment/date ?sort-date]]
"amount" ['[?e :payment/amount ?sort-amount]]
"status" ['[?e :payment/status ?sort-status]]}
args)
(:exact-match-id args)
(merge-query {:query {:in ['?e]
:where []}
:args [(:exact-match-id args)]})
(defn raw-graphql-ids
([args] (raw-graphql-ids (d/db conn) args))
([db args]
(let [check-number-like (try (Long/parseLong (:check-number-like args)) (catch Exception _ nil))
query (cond-> {:query {:find []
:in ['$]
:where []}
:args [db]}
(:sort args) (add-sorter-fields {"client" ['[?e :payment/client ?c]
'[?c :client/name ?sort-client]]
"vendor" ['[?e :payment/vendor ?v]
'[?v :vendor/name ?sort-vendor]]
"bank-account" ['[?e :payment/bank-account ?ba]
'[?ba :bank-account/name ?sort-bank-account]]
"check-number" ['[(get-else $ ?e :payment/check-number 0) ?sort-check-number]]
"date" ['[?e :payment/date ?sort-date]]
"amount" ['[?e :payment/amount ?sort-amount]]
"status" ['[?e :payment/status ?sort-status]]}
args)
(:exact-match-id args)
(merge-query {:query {:in ['?e]
:where []}
:args [(:exact-match-id args)]})
(limited-clients (:id args))
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :payment/client ?xx]]}
:args [(set (map :db/id (limited-clients (:id args))))]})
(limited-clients (:id args))
(merge-query {:query {:in ['[?xx ...]]
:where ['[?e :payment/client ?xx]]}
:args [(set (map :db/id (limited-clients (:id args))))]})
(:client-id args)
(merge-query {:query {:in ['?client-id]
:where ['[?e :payment/client ?client-id]]}
:args [(:client-id args)]})
(:client-code args)
(merge-query {:query {:in ['?client-code]
:where ['[?e :payment/client ?client-id]
'[?client-id :client/code ?client-code]]}
:args [(:client-code args)]})
(:client-id args)
(merge-query {:query {:in ['?client-id]
:where ['[?e :payment/client ?client-id]]}
:args [(:client-id args)]})
(:client-code args)
(merge-query {:query {:in ['?client-code]
:where ['[?e :payment/client ?client-id]
'[?client-id :client/code ?client-code]]}
:args [(:client-code args)]})
(:vendor-id args)
(merge-query {:query {:in ['?vendor-id]
:where ['[?e :payment/vendor ?vendor-id]]}
:args [(:vendor-id args)]})
(:vendor-id args)
(merge-query {:query {:in ['?vendor-id]
:where ['[?e :payment/vendor ?vendor-id]]}
:args [(:vendor-id args)]})
(:original-id args)
(merge-query {:query {:in ['?original-id]
:where ['[?e :payment/client ?c]
'[?c :client/original-id ?original-id]]}
:args [(:original-id args)]})
(:original-id args)
(merge-query {:query {:in ['?original-id]
:where ['[?e :payment/client ?c]
'[?c :client/original-id ?original-id]]}
:args [(:original-id args)]})
(:check-number args)
(merge-query {:query {:in ['?check-number]
:where ['[?e :payment/check-number ?check-number]]}
:args [(:check-number args)]})
(:check-number args)
(merge-query {:query {:in ['?check-number]
:where ['[?e :payment/check-number ?check-number]]}
:args [(:check-number args)]})
(not-empty (:invoice-number args))
(merge-query {:query {:in ['?invoice-number]
:where ['[?e :payment/invoices ?i]
'[?i :invoice/invoice-number ?invoice-number]]}
:args [(:invoice-number args)]})
(not-empty (:invoice-number args))
(merge-query {:query {:in ['?invoice-number]
:where ['[?e :payment/invoices ?i]
'[?i :invoice/invoice-number ?invoice-number]]}
:args [(:invoice-number args)]})
(:bank-account-id args)
(merge-query {:query {:in ['?bank-account-id]
:where ['[?e :payment/bank-account ?bank-account-id]]}
:args [(:bank-account-id args)]})
(:bank-account-id args)
(merge-query {:query {:in ['?bank-account-id]
:where ['[?e :payment/bank-account ?bank-account-id]]}
:args [(:bank-account-id args)]})
(:amount-gte args)
(merge-query {:query {:in ['?amount-gte]
:where ['[?e :payment/amount ?a]
'[(>= ?a ?amount-gte)]]}
:args [(:amount-gte args)]})
(:amount-gte args)
(merge-query {:query {:in ['?amount-gte]
:where ['[?e :payment/amount ?a]
'[(>= ?a ?amount-gte)]]}
:args [(:amount-gte args)]})
(:amount-lte args)
(merge-query {:query {:in ['?amount-lte]
:where ['[?e :payment/amount ?a]
'[(<= ?a ?amount-lte)]]}
:args [(:amount-lte args)]})
(:amount-lte args)
(merge-query {:query {:in ['?amount-lte]
:where ['[?e :payment/amount ?a]
'[(<= ?a ?amount-lte)]]}
:args [(:amount-lte args)]})
(:amount args)
(merge-query {:query {:in ['?amount]
:where ['[?e :payment/amount ?transaction-amount]
'[(auto-ap.utils/dollars= ?transaction-amount ?amount)]]}
:args [(:amount args)]})
(:amount args)
(merge-query {:query {:in ['?amount]
:where ['[?e :payment/amount ?transaction-amount]
'[(auto-ap.utils/dollars= ?transaction-amount ?amount)]]}
:args [(:amount args)]})
(:status args)
(merge-query {:query {:in ['?status]
:where ['[?e :payment/status ?status]]}
:args [(:status args)]})
(:start (:date-range args))
(merge-query {:query {:in '[?start-date]
:where ['[?e :payment/date ?date]
'[(>= ?date ?start-date)]]}
:args [(c/to-date (:start (:date-range args)))]})
(:status args)
(merge-query {:query {:in ['?status]
:where ['[?e :payment/status ?status]]}
:args [(:status args)]})
(:start (:date-range args))
(merge-query {:query {:in '[?start-date]
:where ['[?e :payment/date ?date]
'[(>= ?date ?start-date)]]}
:args [(c/to-date (:start (:date-range args)))]})
(:end (:date-range args))
(merge-query {:query {:in '[?end-date]
:where ['[?e :payment/date ?date]
'[(<= ?date ?end-date)]]}
:args [(c/to-date (:end (:date-range args)))]})
(:end (:date-range args))
(merge-query {:query {:in '[?end-date]
:where ['[?e :payment/date ?date]
'[(<= ?date ?end-date)]]}
:args [(c/to-date (:end (:date-range args)))]})
(:payment-type args)
(merge-query {:query {:in '[?payment-type]
:where ['[?e :payment/type ?payment-type]]}
:args [(:payment-type args)]})
(:payment-type args)
(merge-query {:query {:in '[?payment-type]
:where ['[?e :payment/type ?payment-type]]}
:args [(:payment-type args)]})
check-number-like
(merge-query {:query {:in '[?check-number-like]
:where ['[?e :payment/check-number ?check-number-like]]}
:args [check-number-like]})
check-number-like
(merge-query {:query {:in '[?check-number-like]
:where ['[?e :payment/check-number ?check-number-like]]}
:args [check-number-like]})
true
(merge-query {:query {:find ['?sort-default '?e]
:where ['[?e :payment/date ?sort-default]]}}))]
true
(merge-query {:query {:find ['?sort-default '?e]
:where ['[?e :payment/date ?sort-default]]}}))]
(log/info query)
(cond->> query
true (d/query)
true (apply-sort-3 args)
true (apply-pagination args))))
(log/info query)
(cond->> query
true (d/query)
true (apply-sort-3 args)
true (apply-pagination args)))))
(defn graphql-results [ids db _]
(let [results (->> (d/pull-many db default-read ids)
@@ -166,6 +168,17 @@
[(->> (graphql-results ids-to-retrieve db args))
matching-count]))
(defn filter-ids [ids]
(if ids
(->> {:query {:find ['?e]
:in ['$ '[?e ...]]
:where ['[?e :payment/date]]}
:args [(d/db conn) ids]}
(d/query)
(map first)
vec)
[]))
(defn get-by-id [id]
(->>
(d/pull (d/db conn) default-read id)

View File

@@ -1,7 +1,7 @@
(ns auto-ap.graphql.checks
(:require
[amazonica.aws.s3 :as s3]
[auto-ap.datomic :refer [audit-transact remove-nils]]
[auto-ap.datomic :refer [audit-transact remove-nils conn]]
[auto-ap.datomic.accounts :as a]
[auto-ap.datomic.bank-accounts :as d-bank-accounts]
[auto-ap.datomic.checks :as d-checks]
@@ -22,8 +22,10 @@
[clojure.java.io :as io]
[clojure.set :as set]
[clojure.string :as str]
[clojure.tools.logging :as log]
[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
[config.core :refer [env]]
[datomic.api :as d]
[digest])
(:import
(java.io ByteArrayOutputStream)
@@ -396,6 +398,7 @@
(defn get-payment-page [context args _]
(let [args (assoc args :id (:id context))
[payments checks-count] (d-checks/get-graphql (-> args
:filters
(<-graphql)
(update :payment-type enum->keyword "payment-type")
(update :status enum->keyword "payment-status")))]
@@ -451,7 +454,7 @@
:invoices (d-invoices/get-multi (map :invoice_id (:invoice_payments args)))})))
(defn void-check [context {id :payment_id} _]
(defn void-payment [context {id :payment_id} _]
(let [check (d-checks/get-by-id id)]
(assert (or (= :payment-status/pending (:payment/status check))
(#{:payment-type/cash :payment-type/debit} (:payment/type check))))
@@ -470,13 +473,55 @@
updated-payment {:db/id id
:payment/amount 0.0
:payment/status :payment-status/voided}]
(audit-transact (conj removing-payments updated-payment)
(:id context)))
(-> (d-checks/get-by-id id)
(->graphql))))
(defn void-payments [context args _]
(assert-admin (:id context))
(let [args (assoc args :id (:id context))
ids (some-> args
:filters
(assoc :id (:id context))
(<-graphql)
(update :payment-type enum->keyword "payment-type")
(update :status enum->keyword "payment-status")
(assoc :per-page Integer/MAX_VALUE)
d-checks/raw-graphql-ids
:ids)
specific-ids (d-checks/filter-ids (:ids args))
all-ids (into (set ids) specific-ids)]
(log/info "Voiding " (count all-ids) args)
(audit-transact (->> all-ids
(d/q '[:find [(pull ?p [:db/id
{:invoice-payment/_payment [:invoice-payment/amount
:db/id
{:invoice-payment/invoice [:db/id :invoice/outstanding-balance]}]}]) ...]
:in $ [?p ...]
:where
(not [_ :transaction/payment ?p])
(not [?p :payment/status :payment-status/voided])]
(d/db conn))
(mapcat (fn [{:keys [:db/id]
invoices :invoice-payment/_payment}]
(into
[{:db/id id
:payment/amount 0.0
:payment/status :payment-status/voided}]
(->> invoices
(mapcat (fn [{:keys [:invoice-payment/invoice :db/id :invoice-payment/amount]}]
(let [new-balance (+ (:invoice/outstanding-balance invoice)
amount)]
[[:db.fn/retractEntity id]
{:db/id (:db/id invoice)
:invoice/outstanding-balance new-balance
:invoice/status (if (dollars-0? new-balance)
(:invoice/status invoice)
:invoice-status/unpaid)}]))))))))
(:id context))
{:message (str "Succesfully voided " (count all-ids))}))
(defn get-all-payments [context args _]
(assert-admin (:id context))
(map
@@ -484,7 +529,6 @@
(first (d-checks/get-graphql (assoc (<-graphql args) :count Integer/MAX_VALUE)))))
(defn print-checks [context args _]
(assert-can-see-client (:id context) (:client_id args))
(->graphql
(print-checks-internal (map (fn [i] {:invoice-id (:invoice_id i)
@@ -531,19 +575,7 @@
:statuses {:type '(list String)}}
:resolve :get-all-payments}
:payment_page {:type '(list :payment_page)
:args {:client_id {:type :id}
:vendor_id {:type :id}
:payment_type {:type :payment_type}
:status {:type :payment_status}
:exact_match_id {:type :id}
:date_range {:type :date_range}
:amount_lte {:type :money}
:amount_gte {:type :money}
:check_number_like {:type 'String}
:invoice_number {:type 'String}
:start {:type 'Int}
:per_page {:type 'Int}
:sort {:type '(list :sort_item)}}
:args {:filters {:type :payment_filters}}
:resolve :get-payment-page}
:potential_payment_matches {:type '(list :payment)
:args {:transaction_id {:type :id}}
@@ -564,11 +596,29 @@
:resolve :mutation/add-handwritten-check}
:void_payment {:type :payment
:args {:payment_id {:type :id}}
:resolve :mutation/void-payment}})
:resolve :mutation/void-payment}
:void_payments {:type :message
:args {:filters {:type :payment_filters}
:ids {:type '(list :id)}}
:resolve :mutation/void-payments}})
(def input-objects
{:invoice_payment_amount {:fields {:invoice_id {:type :id}
:amount {:type :money}}}})
:amount {:type :money}}}
:payment_filters {:fields {:client_id {:type :id}
:vendor_id {:type :id}
:payment_type {:type :payment_type}
:status {:type :payment_status}
:exact_match_id {:type :id}
:date_range {:type :date_range}
:amount_lte {:type :money}
:amount_gte {:type :money}
:check_number_like {:type 'String}
:invoice_number {:type 'String}
:start {:type 'Int}
:per_page {:type 'Int}
:sort {:type '(list :sort_item)}}}})
(def enums
{:payment_type {:values [{:enum-value :check}
@@ -584,7 +634,8 @@
{:get-potential-payments get-potential-payments
:get-payment-page get-payment-page
:get-all-payments get-all-payments
:mutation/void-payment void-check
:mutation/void-payment void-payment
:mutation/void-payments void-payments
:mutation/print-checks print-checks
:mutation/add-handwritten-check add-handwritten-check
})