Makes print checks basically work.

This commit is contained in:
Bryce
2024-03-16 19:50:04 -07:00
parent 5b9c4b7aef
commit a972df1d43
12 changed files with 2134 additions and 1503 deletions

View File

@@ -6,6 +6,7 @@
pull-many]]
[auto-ap.graphql.checks :as gq-checks :refer [print-checks-internal]]
[auto-ap.graphql.utils :refer [assert-can-see-client
exception->4xx
exception->notification
extract-client-ids notify-if-locked]]
[auto-ap.logging :as alog]
@@ -593,15 +594,37 @@
updated-count
(count ids))})})))
(defn does-amount-exceed-outstanding? [amount outstanding-balance]
(or (and (> outstanding-balance 0)
(> amount outstanding-balance))
(and (> outstanding-balance 0)
(<= amount 0))
(and (< outstanding-balance 0)
(< amount outstanding-balance))
(and (< outstanding-balance 0)
(>= amount 0))))
(def payment-form-schema
(mc/schema [:map
[:client entity-id]
[:invoices [:vector {:coerce? true}
[:map
[:invoice-id entity-id]
[:amount money]]]]
[:invoices [:and
[:vector {:coerce? true}
[:map
[:invoice-id entity-id]
[:amount money]]]
[:fn {:error/message "All payments must not exceed their outstanding balance."}
(fn [invoices]
(let [outstanding-balances (->> (dc/q '[:find ?i ?ob
:in $ [?i ...]
:where [?i :invoice/outstanding-balance ?ob]]
(dc/db conn)
(map :invoice-id invoices))
(into {}))]
(every? #(not (does-amount-exceed-outstanding? (:amount %) (outstanding-balances (:invoice-id %))))
invoices)))]]]
[:bank-account entity-id]
[:method :string]]))
[:mode [:enum :simple :advanced]]
[:method [:enum :debit :print-check :cash :handwrite-check]]]))
(defn bank-account-card-base [{:keys [bg-color text-color icon bank-account]}]
[:div {:class "w-[30em] cursor-move"}
@@ -631,20 +654,45 @@
:data-key "vis"
:class "bg-gray-100 dark:bg-gray-600 rounded-lg shadow-2xl w-max z-50 p-4"
"@click.outside" "chosen=false"})
(com/button {:color :primary
:x-show "chosen"
"@click.prevent.capture" "chosen=true"
:hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account)})
:hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate)
{:from (mm/encode-step-key :choose-method)
:to (mm/encode-step-key :payment-details)})}
"Print check")
(com/button {:x-show "chosen"
"@click.prevent.capture" "chosen=true"}
"Debit")
(com/button {:x-show "chosen"
"@click.prevent.capture" "chosen=true"}
"Handwrite check")]]])])
(when (= :bank-account-type/check
(:bank-account/type bank-account))
(com/button {:color :primary
:minimal-loading? true
:hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account)
"step-params[method]" "print-check"})
:hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate)
{:from (mm/encode-step-key :choose-method)
:to (mm/encode-step-key :payment-details)})}
"Print check"))
(when (= :bank-account-type/cash
(:bank-account/type bank-account))
(com/button {:minimal-loading? true
:hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account)
"step-params[method]" "cash"})
:hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate)
{:from (mm/encode-step-key :choose-method)
:to (mm/encode-step-key :payment-details)})}
"With cash"))
(when (not= :bank-account-type/cash
(:bank-account/type bank-account))
(com/button {:color (when (= :bank-account-type/credit
(:bank-account/type bank-account))
:primary)
:minimal-loading? true
:hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account)
"step-params[method]" "debit"})
:hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate)
{:from (mm/encode-step-key :choose-method)
:to (mm/encode-step-key :payment-details)})}
"Debit"))
(when (= :bank-account-type/check (:bank-account/type bank-account))
(com/button {:minimal-loading? true
:hx-vals (hx/json {"step-params[bank-account]" (:db/id bank-account)
"step-params[method]" "handwrite-check"})
:hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/pay-wizard-navigate)
{:from (mm/encode-step-key :choose-method)
:to (mm/encode-step-key :payment-details)})}
"Handwrite check"))]]])])
(defmulti bank-account-card (comp :bank-account/type))
@@ -682,12 +730,12 @@
[])
(step-schema [_]
(mut/select-keys (mm/form-schema linear-wizard) #{:bank-account}))
(mut/select-keys (mm/form-schema linear-wizard) #{:bank-account :method}))
(render-step [this request]
(mm/default-render-step
linear-wizard this
:head [:div "Pay " (count (:invoices (:snapshot (:multi-form-state request))))]
:head [:div.p-2 "Pay " (count (:invoices (:snapshot (:multi-form-state request)))) " invoices"]
:body (mm/default-step-body
{}
(let [bank-accounts (->> (dc/q '[:find (pull ?ba [:bank-account/name :bank-account/sort-order :bank-account/visible
@@ -704,8 +752,9 @@
(for [ba bank-accounts]
(bank-account-card ba))]))
:footer
(mm/default-step-footer linear-wizard this :validation-route ::route/navigate)
:validation-route ::route/navigate)))
nil
#_(mm/default-step-footer linear-wizard this :validation-route ::route/navigate)
:validation-route ::route/pay-wizard-navigate)))
(defrecord PaymentDetailsStep [linear-wizard]
mm/ModalWizardStep
@@ -723,51 +772,52 @@
(render-step [this request]
(mm/default-render-step
linear-wizard this
:head [:div "HI"]
:head [:div.p-2 "Pay " (count (:invoices (:snapshot (:multi-form-state request)))) " invoices"]
:body (mm/default-step-body
{}
[:div {}
(com/radio-list {:x-model "mode"
:name "mode"
:name "step-params[mode]"
:options [{:value "simple"
:content "Pay in full"}
{:value "advanced"
:content "Customize payments"}]})
[:div.space-y-4 (hx/alpine-appear {:x-show "mode==\"advanced\""})
(fc/with-field :invoices
(com/data-grid
{:headers [(com/data-grid-header {} "Vendor")
(com/data-grid-header {} "Invoice Number")
(com/data-grid-header {:class "text-right"} "Total")
(com/data-grid-header {:class "text-right"} "Pay")]}
(fc/cursor-map
(fn [i]
(println fc/*current*)
(com/data-grid-row
{}
(com/data-grid-cell
(com/validated-field
{:errors (fc/field-errors)}
(com/data-grid
{:headers [(com/data-grid-header {} "Vendor")
(com/data-grid-header {} "Invoice Number")
(com/data-grid-header {:class "text-right"} "Total")
(com/data-grid-header {:class "text-right"} "Pay")]}
(fc/cursor-map
(fn [i]
(com/data-grid-row
{}
(com/data-grid-cell
{}
(-> (fc/field-value) :invoice :invoice/vendor :vendor/name))
(com/data-grid-cell
{}
(fc/with-field :invoice-id
(com/hidden {:name (fc/field-name)
:value (fc/field-value)}))
(-> (fc/field-value) :invoice :invoice/invoice-number))
(com/data-grid-cell
{:class "text-right"}
(format "$%,.2f" (-> (fc/field-value) :invoice :invoice/outstanding-balance)))
(com/data-grid-cell
{:class "w-20"}
(fc/with-field :amount
(com/validated-field {:errors (fc/field-errors)}
(com/money-input {:value (format "%.2f" (fc/field-value)) :class "w-20"
:name (fc/field-name)
:error? (fc/error?)})))))))))]])
(-> (fc/field-value) :invoice :invoice/vendor :vendor/name))
(com/data-grid-cell
{}
(fc/with-field :invoice-id
(com/hidden {:name (fc/field-name)
:value (fc/field-value)}))
(-> (fc/field-value) :invoice :invoice/invoice-number))
(com/data-grid-cell
{:class "text-right"}
(format "$%,.2f" (-> (fc/field-value) :invoice :invoice/outstanding-balance)))
(com/data-grid-cell
{:class "w-20"}
(fc/with-field :amount
(com/validated-field {:errors (fc/field-errors)}
(com/money-input {:value (format "%.2f" (fc/field-value)) :class "w-20"
:name (fc/field-name)
:error? (fc/error?)}))))))))))]])
:footer
(mm/default-step-footer linear-wizard this :validation-route ::route/pay-wizard-navigate)
:validation-route ::route/navigate)))
:validation-route ::route/pay-wizard-navigate)))
@@ -786,29 +836,32 @@
(render-wizard [this {:keys [multi-form-state] :as request}]
;; TODO should this be customized based off the selections they make?
(let [invoices (->> (dc/q '[:find (pull ?i [{:invoice/vendor [:vendor/name :db/id]
:invoice/client [:db/id]}
:invoice/outstanding-balance
:invoice/invoice-number
:db/id])
:in $ [?i ...]]
(dc/db conn)
(map :invoice-id (get-in request [:multi-form-state :step-params :invoices])))
(map first)
(sort-by (juxt (comp :invoice/vendor :vendor/name)
:invoice/invoice-number)))
request (update-in request [:multi-form-state :step-params :invoices]
(fn [form-invoices]
(mapv (fn [form-invoice i]
(assoc form-invoice :invoice i)) form-invoices invoices)))]
(clojure.pprint/pprint (:step-params (:multi-form-state request)))
(mm/default-render-wizard
this request
:form-params
(-> mm/default-form-props
(assoc :hx-post
(str (bidi/path-for ssr-routes/only-routes ::route/pay-submit)))
(assoc :x-data (hx/json {:mode "simple"}))))))
(let [invoices (->> (dc/q '[:find (pull ?i [{:invoice/vendor [:vendor/name :db/id]
:invoice/client [:db/id]}
:invoice/outstanding-balance
:invoice/invoice-number
:db/id])
:in $ [?i ...]]
(dc/db conn)
(map :invoice-id (get-in request [:multi-form-state :step-params :invoices])))
(map first)
(sort-by (juxt (comp :invoice/vendor :vendor/name)
:invoice/invoice-number)))
request (update-in request [:multi-form-state :step-params :invoices]
(fn [form-invoices]
(mapv (fn [form-invoice i]
(assoc form-invoice :invoice i)) form-invoices invoices)))]
(mm/default-render-wizard
this request
:form-params
(-> mm/default-form-props
(assoc :hx-post
(str (bidi/path-for ssr-routes/only-routes ::route/pay-submit)))
(assoc :x-data (hx/json {:mode (some-> multi-form-state
:step-params
:mode
name)}))))))
(steps [_]
[:choose-method
:payment-details])
@@ -829,15 +882,21 @@
payment-form-schema
(:snapshot multi-form-state)
mt/strip-extra-keys-transformer)
result (print-checks-internal (map (fn [i] {:invoice-id (:invoice-id i)
:amount (:amount i)})
(:invoices snapshot))
(:client snapshot)
(:bank-account snapshot)
:payment-type/check
identity)]
result (exception->4xx
#(print-checks-internal (map (fn [i] {:invoice-id (:invoice-id i)
:amount (:amount i)})
(:invoices snapshot))
(:client snapshot)
(:bank-account snapshot)
(cond (= :print-check (:method snapshot))
:payment-type/check
(= :debit (:method snapshot))
:payment-type/debit
(= :cash (:method snapshot))
:payment-type/cash
:else :payment-type/debit)
identity))]
(alog/info ::printed :result result)
(modal-response
(com/modal {}
(com/modal-card-advanced
@@ -846,16 +905,10 @@
(com/modal-body {}
[:div.flex.flex-col.mt-4.space-y-4.items-center
[:div.w-24.h-24.bg-green-50.rounded-full.p-4.text-green-300.animate-gg
svg/thumbs-up]
[:div "Your checks are ready. Click "
(com/link {:href (:pdf-url result)} "here")
" to download."]]))))
#_(html-response
[:div]
:headers {"hx-trigger" (hx/json {:notification (str "Printed!")})}))))
" to download."]])))))))
(def pay-wizard
(->PayWizard nil nil nil))
@@ -892,14 +945,14 @@
(sort-by (juxt (comp :invoice/vendor :vendor/name)
:invoice/invoice-number)))]
(mm/->MultiStepFormState {:invoices (mapv (fn [i] {:invoice-id (:db/id i)
:amount (:invoice/outstanding-balance i) })
:amount (:invoice/outstanding-balance i)})
invoices)
:mode :simple
:client (-> invoices first :invoice/client :db/id)}
[]
{}))))
#_(wrap-entity [:route-params :db/id] default-read)
#_(wrap-schema-enforce :route-schema [:map [:db/id entity-id]]))
{:mode :simple})))))
::route/pay-submit (-> mm/submit-handler
(mm/wrap-wizard pay-wizard)
(mm/wrap-decode-multi-form-state))
::route/pay-wizard-navigate
@@ -914,7 +967,4 @@
(wrap-merge-prior-hx)
(wrap-schema-enforce :query-schema query-schema)
(wrap-schema-enforce :hx-schema query-schema)
(wrap-client-redirect-unauthenticated)))))
(wrap-client-redirect-unauthenticated)))))