Applying feedback
This commit is contained in:
@@ -73,6 +73,9 @@
|
||||
|
||||
(def new-form-schema
|
||||
[:map
|
||||
[:customize-due-and-scheduled? {:optional true :default false :decode/arbitrary (fn [x] (if (= "" x)
|
||||
false
|
||||
x))} [:maybe :boolean]]
|
||||
[:invoice/client entity-id]
|
||||
[:invoice/date clj-date-schema]
|
||||
[:invoice/due {:optional true} [:maybe clj-date-schema]]
|
||||
@@ -138,7 +141,7 @@
|
||||
[])
|
||||
|
||||
(step-schema [_]
|
||||
(mut/select-keys (mm/form-schema linear-wizard) #{:invoice/client :invoice/vendor :invoice/date :invoice/due :invoice/scheduled-payment :invoice/total :invoice/invoice-number}))
|
||||
(mut/select-keys (mm/form-schema linear-wizard) #{:invoice/client :invoice/vendor :invoice/date :invoice/due :invoice/scheduled-payment :invoice/total :invoice/invoice-number :customize-due-and-scheduled?}))
|
||||
|
||||
(render-step [this request]
|
||||
(alog/peek ::check (:multi-form-state request))
|
||||
@@ -153,7 +156,14 @@
|
||||
:date (-> (fc/field-value (:invoice/date fc/*current*))
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:due (some-> (fc/field-value (:invoice/due fc/*current*))
|
||||
(atime/unparse-local atime/normal-date))})}
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:scheduledPayment (some-> (fc/field-value (:invoice/scheduled-payment fc/*current*))
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:customizeDueAndScheduled (fc/field-value (:customize-due-and-scheduled? fc/*current*))})}
|
||||
(fc/with-field :customize-due-and-scheduled?
|
||||
(com/hidden {:name (fc/field-name)
|
||||
:value (fc/field-value)
|
||||
:x-model "customizeDueAndScheduled"}))
|
||||
(fc/with-field :invoice/client
|
||||
(if (:client request)
|
||||
(com/hidden {:name (fc/field-name)
|
||||
@@ -184,55 +194,65 @@
|
||||
:content-fn (fn [c] (pull-attr (dc/db conn) :vendor/name c))
|
||||
:x-model "vendorId"})]))
|
||||
|
||||
[:div.flex.gap-x-8.md:flex-row.flex-col
|
||||
(fc/with-field :invoice/date
|
||||
(com/validated-field
|
||||
{:label "Date"
|
||||
:errors (fc/field-errors)}
|
||||
[:div {:class "w-24"}
|
||||
(com/date-input {:value (some-> (fc/field-value)
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:name (fc/field-name)
|
||||
:error? (fc/field-errors)
|
||||
:x-model "date"
|
||||
:placeholder "1/1/2024"})]))
|
||||
(fc/with-field :invoice/due
|
||||
(com/validated-field
|
||||
{:label "Due (optional)"
|
||||
:errors (fc/field-errors)}
|
||||
|
||||
(fc/with-field :invoice/date
|
||||
(com/validated-field
|
||||
{:label "Date"
|
||||
:errors (fc/field-errors)}
|
||||
[:div {:class "w-24"}
|
||||
(com/date-input {:value (some-> (fc/field-value)
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:name (fc/field-name)
|
||||
:error? (fc/field-errors)
|
||||
:x-model "date"
|
||||
:placeholder "1/1/2024"})]))
|
||||
(com/validated-field {}
|
||||
[:div {:x-show "!customizeDueAndScheduled"}
|
||||
(com/link {"@click" "customizeDueAndScheduled=true"
|
||||
:x-show "!due && !scheduledPayment"}
|
||||
"Add due / scheduled payment date")
|
||||
(com/link {"@click" "customizeDueAndScheduled=true"
|
||||
:x-show "due || scheduledPayment"}
|
||||
"Change due / scheduled payment date")])
|
||||
(fc/with-field :invoice/due
|
||||
(com/validated-field
|
||||
(hx/alpine-appear {:label "Due (optional)"
|
||||
:errors (fc/field-errors)
|
||||
:x-show "customizeDueAndScheduled"})
|
||||
[:div {:class "w-24"
|
||||
:hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/due-date)
|
||||
:x-hx-val:client-id "clientId" ;; TODO maybe just use the whole form
|
||||
:x-hx-val:vendor-id "vendorId"
|
||||
:x-hx-val:date "date"
|
||||
:x-dispatch:changed "[clientId, vendorId, date]"
|
||||
:hx-trigger "changed"
|
||||
:hx-target "this"
|
||||
:hx-swap "innerHTML"}
|
||||
(com/date-input {:value (some-> (fc/field-value)
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:name (fc/field-name)
|
||||
:x-model "due"
|
||||
|
||||
:error? (fc/field-errors)
|
||||
:placeholder "1/1/2024"})]))
|
||||
(fc/with-field :invoice/scheduled-payment
|
||||
(com/validated-field
|
||||
(hx/alpine-appear {:label "Scheduled payment (optional)"
|
||||
:errors (fc/field-errors)
|
||||
:x-show "customizeDueAndScheduled"})
|
||||
[:div {:class "w-24"}
|
||||
[:div {:class "w-24"
|
||||
:hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/due-date)
|
||||
:x-hx-val:client-id "clientId" ;; TODO maybe just use the whole form
|
||||
:x-hx-val:vendor-id "vendorId"
|
||||
:x-hx-val:date "date"
|
||||
:x-dispatch:changed "[clientId, vendorId, date]"
|
||||
|
||||
:hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/scheduled-payment-date)
|
||||
:x-dispatch:changed "[clientId, vendorId, due]"
|
||||
:hx-trigger "changed"
|
||||
:hx-target "this"
|
||||
:hx-swap "innerHTML"}
|
||||
(com/date-input {:value (some-> (fc/field-value)
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:name (fc/field-name)
|
||||
:x-model "due"
|
||||
|
||||
:error? (fc/field-errors)
|
||||
:placeholder "1/1/2024"})]))
|
||||
(fc/with-field :invoice/scheduled-payment
|
||||
(com/validated-field
|
||||
{:label "Scheduled payment (optional)"
|
||||
:errors (fc/field-errors)}
|
||||
[:div {:class "w-24"}
|
||||
[:div {:class "w-24"
|
||||
|
||||
:hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/scheduled-payment-date)
|
||||
:x-dispatch:changed "[clientId, vendorId, due]"
|
||||
:hx-trigger "changed"
|
||||
:hx-target "this"
|
||||
:hx-swap "innerHTML"}
|
||||
(com/date-input {:value (some-> (fc/field-value)
|
||||
(atime/unparse-local atime/normal-date))
|
||||
:name (fc/field-name)
|
||||
:error? (fc/field-errors)
|
||||
:placeholder "1/1/2024"})]]))]
|
||||
:placeholder "1/1/2024"})]]))
|
||||
|
||||
(fc/with-field :invoice/invoice-number
|
||||
(com/validated-field
|
||||
@@ -252,10 +272,19 @@
|
||||
:name (fc/field-name)
|
||||
:class "w-24"
|
||||
:error? (fc/field-errors)
|
||||
:placeholder "212.44"})]))])
|
||||
:placeholder "212.44"})]))
|
||||
|
||||
[:div#expense-account-prediction
|
||||
(hx/alpine-appear
|
||||
{:x-dispatch:bryce "[vendorId]"
|
||||
:hx-trigger "load, bryce"
|
||||
:hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/account-prediction)
|
||||
:hx-target "this"
|
||||
:hx-swap "innerHTML"})]])
|
||||
|
||||
:footer
|
||||
(mm/default-step-footer linear-wizard this :validation-route ::route/new-wizard-navigate)
|
||||
(mm/default-step-footer linear-wizard this :validation-route ::route/new-wizard-navigate
|
||||
:next-button (com/button {:color :primary :x-ref "next" :class "w-32"} "Save"))
|
||||
:validation-route ::route/new-wizard-navigate)))
|
||||
|
||||
(defn- location-select*
|
||||
@@ -544,6 +573,14 @@
|
||||
transaction [:upsert-invoice (-> multi-form-state
|
||||
:snapshot
|
||||
(assoc :db/id "invoice")
|
||||
(dissoc :customize-due-and-scheduled?)
|
||||
(assoc :invoice/expense-accounts (if-let [ieas (seq (-> multi-form-state :snapshot :invoice/expense-accounts))]
|
||||
ieas
|
||||
[{:db/id "123"
|
||||
:invoice-expense-account/location "Shared"
|
||||
:invoice-expense-account/account (:db/id (:vendor/default-account (clientize-vendor (get-vendor vendor-id)
|
||||
client-id)))
|
||||
:invoice-expense-account/amount (:invoice/total (:snapshot multi-form-state))}]))
|
||||
(assoc
|
||||
:invoice/outstanding-balance (:invoice/total (:snapshot multi-form-state))
|
||||
:invoice/import-status :import-status/imported
|
||||
@@ -551,8 +588,9 @@
|
||||
(maybe-spread-locations)
|
||||
(update :invoice/date coerce/to-date)
|
||||
(update :invoice/due coerce/to-date))]]
|
||||
(alog/peek ::test transaction)
|
||||
|
||||
(assert-invoice-amounts-add-up invoice)
|
||||
(assert-invoice-amounts-add-up (second transaction))
|
||||
(assert-no-conflicting invoice)
|
||||
(exception->4xx #(assert-can-see-client (:identity request) client-id))
|
||||
|
||||
@@ -631,6 +669,27 @@
|
||||
:error? false
|
||||
:placeholder "1/1/2024"}))))
|
||||
|
||||
(defn account-prediction [{:keys [multi-form-state form-errors]}]
|
||||
(let [vendor (clientize-vendor (get-vendor (:invoice/vendor (:step-params multi-form-state)))
|
||||
(->db-id (:invoice/client (:step-params multi-form-state)))) ]
|
||||
|
||||
(html-response
|
||||
(if-let [account-name (:account/name (:vendor/default-account vendor))]
|
||||
[:div {:class "transition duration-300 ease-in-out htmx-added:opacity-0 opacity-100"}
|
||||
[:label {:class "block mb-2 text-sm font-medium text-gray-900 dark:text-white"} "Default expense account"]
|
||||
[:div.flex.gap-2.items-center (com/pill {:color :primary} account-name)
|
||||
(com/validated-save-button (cond-> {:errors form-errors
|
||||
;;:x-data (hx/json {})
|
||||
:class "w-24"
|
||||
:hx-put (hu/url (bidi/path-for ssr-routes/only-routes ::route/new-wizard-navigate)
|
||||
{:from (mm/encode-step-key :basic-details)
|
||||
:to (mm/encode-step-key :accounts)})
|
||||
:hx-target "closest form"})
|
||||
|
||||
"Change"
|
||||
[:div.w-5.h-5 svg/arrow-right])]]
|
||||
[:div]))))
|
||||
|
||||
(def key->handler
|
||||
(apply-middleware-to-all-handlers
|
||||
{::route/new-wizard (-> mm/open-wizard-handler
|
||||
@@ -640,6 +699,10 @@
|
||||
(mm/wrap-wizard new-wizard)
|
||||
(mm/wrap-decode-multi-form-state)
|
||||
(wrap-nested-form-params))
|
||||
::route/account-prediction (-> account-prediction
|
||||
(mm/wrap-wizard new-wizard)
|
||||
(mm/wrap-decode-multi-form-state)
|
||||
(wrap-nested-form-params))
|
||||
::route/scheduled-payment-date (-> scheduled-payment-date
|
||||
(mm/wrap-wizard new-wizard)
|
||||
(mm/wrap-decode-multi-form-state)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"/navigate" ::new-wizard-navigate
|
||||
"/account/new" ::new-wizard-new-account
|
||||
"/account/location-select" ::location-select
|
||||
"/account/prediction" ::account-prediction
|
||||
"/total" ::expense-account-total}
|
||||
"/pay-button" ::pay-button
|
||||
"/pay" {:get ::pay-wizard
|
||||
|
||||
Reference in New Issue
Block a user