Add vendor pre-population for bulk code and individual edit forms

- Add vendor-changed HTMX handlers for both bulk code and individual edit
- Pre-populate default account at 100% when vendor is selected and no accounts exist
- Fix render-accounts-section to render from step-params correctly
- Change bulk code vendor-changed from hx-get to hx-post to include form data
- Add routes for vendor-changed endpoints
- Update e2e tests to cover vendor pre-population
- Run lein cljfmt fix across codebase
This commit is contained in:
2026-05-21 14:45:19 -07:00
parent 8bd0cee1b1
commit ba87805d4c
210 changed files with 8694 additions and 9627 deletions

View File

@@ -1,9 +1,9 @@
(ns auto-ap.ssr.payments
(:require
[auto-ap.datomic
:refer [add-sorter-fields apply-pagination apply-sort-3
audit-transact conn merge-query observable-query
pull-many]]
:refer [add-sorter-fields apply-pagination apply-sort-3
audit-transact conn merge-query observable-query
pull-many]]
[auto-ap.graphql.utils :refer [assert-can-see-client
exception->notification extract-client-ids
notify-if-locked]]
@@ -14,7 +14,7 @@
[auto-ap.routes.payments :as route]
[auto-ap.routes.transactions :as transaction-routes]
[auto-ap.routes.utils
:refer [wrap-admin wrap-client-redirect-unauthenticated]]
:refer [wrap-admin wrap-client-redirect-unauthenticated]]
[auto-ap.ssr-routes :as ssr-routes]
[auto-ap.ssr.components :as com]
[auto-ap.ssr.components.bank-account-icon :as bank-account-icon]
@@ -24,11 +24,11 @@
[auto-ap.ssr.pos.common :refer [date-range-field*]]
[auto-ap.ssr.svg :as svg]
[auto-ap.ssr.utils
:refer [apply-middleware-to-all-handlers clj-date-schema
dissoc-nil-transformer entity-id html-response
main-transformer modal-response ref->enum-schema strip
wrap-entity wrap-implied-route-param wrap-merge-prior-hx
wrap-schema-enforce]]
:refer [apply-middleware-to-all-handlers clj-date-schema
dissoc-nil-transformer entity-id html-response
main-transformer modal-response ref->enum-schema strip
wrap-entity wrap-implied-route-param wrap-merge-prior-hx
wrap-schema-enforce]]
[auto-ap.time :as atime]
[bidi.bidi :as bidi]
[clj-time.coerce :as coerce]
@@ -105,19 +105,18 @@
:size :small})])
(com/field {:label "Payment Type"}
(com/radio-card {:size :small
:name "payment-type"
:value (:payment-type (:query-params request))
:options [{:value ""
:content "All"}
{:value "cash"
:content "Cash"}
{:value "check"
:content "Check"}
{:value "debit"
:content "Debit"}]}))
:name "payment-type"
:value (:payment-type (:query-params request))
:options [{:value ""
:content "All"}
{:value "cash"
:content "Cash"}
{:value "check"
:content "Check"}
{:value "debit"
:content "Debit"}]}))
(exact-match-id* request)]])
(def default-read '[*
[:payment/date :xform clj-time.coerce/from-date]
{:invoice-payment/_payment [* {:invoice-payment/invoice [*]}]}
@@ -213,7 +212,6 @@
'[(iol-ion.query/dollars= ?transaction-amount ?amount)]]}
:args [(:amount query-params)]})
(:status route-params)
(merge-query {:query {:in ['?status]
:where ['[?e :payment/status ?status]]}
@@ -244,30 +242,30 @@
refunds))
(defn sum-visible-pending [ids]
(->>
(dc/q {:find ['?id '?o]
:in ['$ '[?id ...]]
:where ['[?id :payment/amount ?o]
'[?id :payment/status :payment-status/pending]]}
(dc/db conn)
ids)
(->>
(dc/q {:find ['?id '?o]
:in ['$ '[?id ...]]
:where ['[?id :payment/amount ?o]
'[?id :payment/status :payment-status/pending]]}
(dc/db conn)
ids)
(map last)
(reduce
+
0.0)))
(defn sum-client-pending [clients]
(->>
(dc/q {:find '[?e ?a]
:in '[$ [?clients ?start ?end]]
:where '[[(iol-ion.query/scan-payments $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]
[?e :payment/status :payment-status/pending]
[?e :payment/amount ?a]]}
(dc/db conn)
[clients
nil
nil])
(->>
(dc/q {:find '[?e ?a]
:in '[$ [?clients ?start ?end]]
:where '[[(iol-ion.query/scan-payments $ ?clients ?start ?end) [[?e _ ?sort-default] ...]]
[?e :payment/status :payment-status/pending]
[?e :payment/amount ?a]]}
(dc/db conn)
[clients
nil
nil])
(map last)
(reduce
+
@@ -278,16 +276,14 @@
{ids-to-retrieve :ids matching-count :count
all-ids :all-ids} (fetch-ids db request)]
[(->> (hydrate-results ids-to-retrieve db request))
matching-count
(sum-visible-pending all-ids)
(sum-client-pending (extract-client-ids (:clients request)
(:client request)
(:client-id (:query-params request))
(when (:client-code (:query-params request))
[:client/code (:client-code (:query-params request))])))
]))
(:client request)
(:client-id (:query-params request))
(when (:client-code (:query-params request))
[:client/code (:client-code (:query-params request))])))]))
(def query-schema (mc/schema
[:maybe [:map {:date-range [:date-range :start-date :end-date]}
@@ -328,7 +324,7 @@
(assoc-in (exact-match-id* request) [1 :hx-swap-oob] true)])
:query-schema query-schema
:action-buttons (fn [request]
(let [[_ _ visible-in-float total-in-float ] (:page-results request)]
(let [[_ _ visible-in-float total-in-float] (:page-results request)]
[(com/pill {:color :primary} " Visible in float "
(format "$%,.2f" visible-in-float))
(com/pill {:color :secondary} " Total in float "
@@ -355,7 +351,7 @@
(= (-> request :query-params :sort first :name) "Bank account")
(-> entity :payment/bank-account :bank-account/name)
:else nil))
:title (fn [r]
(str
@@ -410,7 +406,7 @@
:render (fn [{:payment/keys [date]}]
(some-> date (atime/unparse-local atime/normal-date)))}
{:key "amount"
:sort-key "amount"
:sort-key "amount"
:name "Amount"
:render (fn [{:payment/keys [amount]}]
(some->> amount (format "$%.2f")))}
@@ -422,10 +418,10 @@
(map :invoice-payment/invoice)
(filter identity)
(map (fn [invoice]
{:link (hu/url (bidi/path-for ssr-routes/only-routes
::invoice-route/all-page)
{:exact-match-id (:db/id invoice)})
:content (str "Inv. " (:invoice/invoice-number invoice))})))
{:link (hu/url (bidi/path-for ssr-routes/only-routes
::invoice-route/all-page)
{:exact-match-id (:db/id invoice)})
:content (str "Inv. " (:invoice/invoice-number invoice))})))
(some-> p :transaction/_payment ((fn [t]
[{:link (hu/url (bidi/path-for ssr-routes/only-routes ::transaction-routes/all-page)
{:exact-match-id (:db/id (first t))})
@@ -434,8 +430,6 @@
(def row* (partial helper/row* grid-page))
(comment
(mc/decode query-schema {"exact-match-id" "123"} (mt/transformer main-transformer mt/strip-extra-keys-transformer))
(mc/decode query-schema {} (mt/transformer main-transformer mt/strip-extra-keys-transformer))
@@ -445,7 +439,6 @@
(mc/decode query-schema {"payment-type" "food"} (mt/transformer main-transformer mt/strip-extra-keys-transformer))
(mc/decode query-schema {"vendor" "87"} (mt/transformer main-transformer mt/strip-extra-keys-transformer))
(mc/decode query-schema {"start-date" #inst "2023-12-21T08:00:00.000-00:00"} (mt/transformer main-transformer mt/strip-extra-keys-transformer)))
(defn delete [{check :entity :as request identity :identity}]
@@ -459,7 +452,7 @@
#(assert-can-see-client identity (:db/id (:payment/client check))))
(notify-if-locked (:db/id (:payment/client check))
(:payment/date check))
(let [ removing-payments (mapcat (fn [x]
(let [removing-payments (mapcat (fn [x]
(let [invoice (:invoice-payment/invoice x)
new-balance (+ (:invoice/outstanding-balance invoice)
(:invoice-payment/amount x))]
@@ -475,9 +468,9 @@
:payment/status :payment-status/voided}]
(audit-transact (cond-> removing-payments
true (conj updated-payment)
(:transaction/_payment check) (conj [:db/retract (:db/id (first (:transaction/_payment check)))
(:transaction/_payment check) (conj [:db/retract (:db/id (first (:transaction/_payment check)))
:transaction/payment
(:db/id check)]))
(:db/id check)]))
identity)
(html-response (row* (:identity request) updated-payment {:delete-after-settle? true :class "live-removed"
@@ -578,7 +571,6 @@
(assoc-in [:query-params :start] 0)
(assoc-in [:query-params :per-page] 250))))
:else
selected)
updated-count (void-payments-internal ids (:identity request))]
@@ -591,7 +583,7 @@
(defn wrap-status-from-source [handler]
(fn [{:keys [matched-current-page-route] :as request}]
(let [ request (cond-> request
(let [request (cond-> request
(= ::route/cleared-page matched-current-page-route) (assoc-in [:route-params :status] :payment-status/cleared)
(= ::route/pending-page matched-current-page-route) (assoc-in [:route-params :status] :payment-status/pending)
(= ::route/voided-page matched-current-page-route) (assoc-in [:route-params :status] :payment-status/voided)
@@ -605,7 +597,7 @@
::route/pending-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status :payment-status/pending))
::route/voided-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status :payment-status/voided))
(wrap-implied-route-param :status :payment-status/voided))
::route/all-page (-> (helper/page-route grid-page)
(wrap-implied-route-param :status nil))
@@ -618,7 +610,6 @@
::route/bulk-delete (-> bulk-delete-dialog
(wrap-admin))
::route/table (helper/table-route grid-page)}
(fn [h]
(-> h