You can now pay invoices with credits from the same vendor.
This commit is contained in:
@@ -508,6 +508,9 @@
|
||||
:db/cardinality :db.cardinality/one}]]}
|
||||
:auto-ap/add-payment-type-credit {:txes [[{:db/ident :payment-type/credit
|
||||
:db/doc "Credit for negative invoices"}]]}
|
||||
|
||||
:auto-ap/add-payment-type-balance-credit {:txes [[{:db/ident :payment-type/balance-credit
|
||||
:db/doc "Used for paying invoices from statement credits."}]]}
|
||||
:auto-ap/fulltext-accounts {:txes [[{:db/ident :account/search-terms
|
||||
:db/valueType :db.type/string
|
||||
:db/cardinality :db.cardinality/one
|
||||
|
||||
@@ -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 assert-not-locked assert-none-locked]]
|
||||
:refer [->graphql <-graphql assert-admin assert-failure 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?]]
|
||||
@@ -212,7 +212,8 @@
|
||||
type))
|
||||
(defn invoice-payments [invoices invoice-amounts]
|
||||
(->> (for [invoice invoices
|
||||
:let [invoice-amount (invoice-amounts (:db/id invoice))]]
|
||||
:let [invoice-amount (invoice-amounts (:db/id invoice))]
|
||||
:when invoice-amount]
|
||||
[{:invoice-payment/payment (-> invoice :invoice/vendor :db/id str)
|
||||
:invoice-payment/amount invoice-amount
|
||||
:invoice-payment/invoice (:db/id invoice)}
|
||||
@@ -292,6 +293,16 @@
|
||||
(conj payment)
|
||||
(into (invoice-payments invoices invoice-amounts)))))
|
||||
|
||||
|
||||
(defmethod invoices->entities :payment-type/balance-credit [invoices vendor client bank-account type index invoice-amounts]
|
||||
(when (<= (->> invoices
|
||||
(map (comp invoice-amounts :db/id))
|
||||
(reduce + 0.0))
|
||||
0.001)
|
||||
(throw (ex-info "The selected invoices do not have an outstanding balance."
|
||||
{:validation-error "The selected invoices do not have an outstanding balance."})))
|
||||
)
|
||||
|
||||
(defmethod invoices->entities :payment-type/credit [invoices vendor client bank-account type index invoice-amounts]
|
||||
(when (>= (->> invoices
|
||||
(map (comp invoice-amounts :db/id))
|
||||
@@ -552,6 +563,76 @@
|
||||
(:type args)
|
||||
(:id context))))
|
||||
|
||||
(defn pay-invoices-from-balance [context {invoices :invoices
|
||||
client-id :client_id} _]
|
||||
(assert-can-see-client (:id context) client-id)
|
||||
(let [invoices (d-invoices/get-multi invoices)
|
||||
client (d-clients/get-by-id client-id)
|
||||
_ (when (> (count (set (map :invoice/vendor invoices))) 1)
|
||||
(assert-failure "Balance payments can only be done on one vendor at a time."))
|
||||
_ (when (> (reduce + 0 (map :invoice/outstanding-balance invoices)) 0.001)
|
||||
(assert-failure "There isn't a positive balance to pay from."))
|
||||
invoices-to-be-paid (filter
|
||||
(fn [i]
|
||||
(> (:invoice/outstanding-balance i)
|
||||
0.001))
|
||||
invoices)
|
||||
credit-invoices (filter
|
||||
(fn [i]
|
||||
(< (:invoice/outstanding-balance i)
|
||||
0.001))
|
||||
invoices)
|
||||
|
||||
|
||||
total-to-pay (reduce + 0 (map :invoice/outstanding-balance invoices-to-be-paid))
|
||||
_ (when (<= total-to-pay 0.001)
|
||||
(assert-failure "You must select invoices that need to be paid."))
|
||||
|
||||
invoice-amounts (->> invoices-to-be-paid
|
||||
(map (fn [i]
|
||||
[(:db/id i)
|
||||
(:invoice/outstanding-balance i)]))
|
||||
(concat (->> credit-invoices
|
||||
(reduce
|
||||
(fn [[remaining-to-pay invoice-amounts] invoice]
|
||||
|
||||
(cond (dollars-0? (+ remaining-to-pay (:invoice/outstanding-balance invoice)))
|
||||
(reduced (conj invoice-amounts
|
||||
[(:db/id invoice)
|
||||
(:invoice/outstanding-balance invoice)]))
|
||||
|
||||
(< (+ remaining-to-pay (:invoice/outstanding-balance invoice)) 0.0)
|
||||
(reduced (conj invoice-amounts
|
||||
[(:db/id invoice)
|
||||
(- remaining-to-pay)]))
|
||||
|
||||
:else
|
||||
[(+ remaining-to-pay (:invoice/outstanding-balance invoice))
|
||||
(conj invoice-amounts [(:db/id invoice)
|
||||
(:invoice/outstanding-balance invoice)])]))
|
||||
[total-to-pay []])))
|
||||
(into {}))
|
||||
|
||||
|
||||
|
||||
vendor-id (:db/id (:invoice/vendor (first invoices)))
|
||||
payment {:db/id (str vendor-id)
|
||||
:payment/amount total-to-pay
|
||||
:payment/vendor vendor-id
|
||||
:payment/client (:db/id client)
|
||||
:payment/date (c/to-date (time/now))
|
||||
:payment/invoices (map :db/id invoices)
|
||||
:payment/type :payment-type/balance-credit
|
||||
:payment/status :payment-status/cleared}]
|
||||
|
||||
|
||||
|
||||
|
||||
(audit-transact (-> []
|
||||
(conj payment)
|
||||
(into (invoice-payments invoices invoice-amounts))) (:id context))
|
||||
(->graphql {:invoices (d-invoices/get-multi (map :db/id invoices))})))
|
||||
|
||||
(def objects
|
||||
{:payment {:fields {:id {:type :id}
|
||||
:type {:type :payment_type}
|
||||
@@ -601,6 +682,11 @@
|
||||
:type {:type :payment_type}
|
||||
:client_id {:type :id}}
|
||||
:resolve :mutation/print-checks}
|
||||
:pay_invoices_from_balance {:type :check_result
|
||||
:args {:invoices {:type '(list :id)}
|
||||
:client_id {:type :id}}
|
||||
:resolve :mutation/pay-invoices-from-balance}
|
||||
|
||||
:add_handwritten_check {:type :check_result
|
||||
:args {:invoice_payments {:type '(list :invoice_payment_amount)}
|
||||
:date {:type 'String}
|
||||
@@ -637,7 +723,8 @@
|
||||
{:payment_type {:values [{:enum-value :check}
|
||||
{:enum-value :cash}
|
||||
{:enum-value :debit}
|
||||
{:enum-value :credit}]}
|
||||
{:enum-value :credit}
|
||||
{:enum-value :balance_credit}]}
|
||||
:payment_status {:values [{:enum-value :voided}
|
||||
{:enum-value :pending}
|
||||
{:enum-value :cleared}]}})
|
||||
@@ -650,6 +737,7 @@
|
||||
:mutation/void-payment void-payment
|
||||
:mutation/void-payments void-payments
|
||||
:mutation/print-checks print-checks
|
||||
:mutation/pay-invoices-from-balance pay-invoices-from-balance
|
||||
:mutation/add-handwritten-check add-handwritten-check
|
||||
})
|
||||
|
||||
|
||||
@@ -689,13 +689,7 @@
|
||||
})
|
||||
|
||||
(def enums
|
||||
{:payment_type {:values [{:enum-value :check}
|
||||
{:enum-value :cash}
|
||||
{:enum-value :debit}
|
||||
{:enum-value :credit}]}
|
||||
:payment_status {:values [{:enum-value :voided}
|
||||
{:enum-value :pending}
|
||||
{:enum-value :cleared}]}})
|
||||
{})
|
||||
|
||||
|
||||
(def resolvers
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
[goog.string :as gstring]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as r]
|
||||
[vimsical.re-frame.fx.track :as track]))
|
||||
[vimsical.re-frame.fx.track :as track]
|
||||
[vimsical.re-frame.cofx.inject :as inject]))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::params-change
|
||||
@@ -105,6 +106,30 @@
|
||||
(:invoices (:print-checks result))
|
||||
(:pdf-url (:print-checks result))])}}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::pay-invoices-from-balance
|
||||
[with-user (re-frame/inject-cofx ::inject/sub [::data-page/checked :invoices])]
|
||||
(fn [{:keys [db user] ::data-page/keys [checked] :as cofx} _]
|
||||
{:graphql
|
||||
{:token user
|
||||
:owns-state {:single ::print-checks}
|
||||
|
||||
:query-obj {:venia/operation {:operation/type :mutation
|
||||
:operation/name "PayInvoicesFromBalance"}
|
||||
:venia/queries [[:pay-invoices-from-balance
|
||||
{:invoices (->> checked
|
||||
(vals )
|
||||
(filter (fn [{:keys [id outstanding-balance] }]
|
||||
(and id outstanding-balance)))
|
||||
(map :id))
|
||||
:client_id (:client db)}
|
||||
[[:invoices invoice-read]
|
||||
:pdf_url]]]}
|
||||
:on-success (fn [result]
|
||||
[::checks-printed
|
||||
(:invoices (:pay-invoices-from-balance result))
|
||||
nil])}}))
|
||||
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::checks-printed
|
||||
@@ -229,9 +254,16 @@
|
||||
:disabled (status/disabled-for print-checks-status)} "Debit from " name])
|
||||
(list
|
||||
^{:key (str id "-credit")} [:a.dropdown-item {:on-click (dispatch-event-with-propagation [::print-checks id :credit])
|
||||
:disabled (status/disabled-for print-checks-status)} "Credit from " name]))))
|
||||
(when (> balance 0.001)
|
||||
^{:key "advanced-divider"} [:hr.dropdown-divider])
|
||||
:disabled (status/disabled-for print-checks-status)} "Credit from " name]
|
||||
))))
|
||||
|
||||
^{:key "advanced-divider"} [:hr.dropdown-divider]
|
||||
|
||||
(when (and (> (count checked-invoices) 1)
|
||||
(= 1 (count (set (map (comp :id :vendor) (vals checked-invoices)))))
|
||||
(< balance 0.001))
|
||||
^{:key (str "balance-credit")} [:a.dropdown-item {:on-click (dispatch-event-with-propagation [::pay-invoices-from-balance])
|
||||
:disabled (status/disabled-for print-checks-status)} "Pay invoices using balance "])
|
||||
|
||||
(when (and (= 1 (count (set (map (comp :id :vendor) (vals checked-invoices)))))
|
||||
(> balance 0.001))
|
||||
|
||||
Reference in New Issue
Block a user