diff --git a/src/clj/auto_ap/ssr/components/multi_modal.clj b/src/clj/auto_ap/ssr/components/multi_modal.clj index 83cc72a7..6b1c4181 100644 --- a/src/clj/auto_ap/ssr/components/multi_modal.clj +++ b/src/clj/auto_ap/ssr/components/multi_modal.clj @@ -33,6 +33,9 @@ (defprotocol Initializable (init-step-params [this multi-form-state request])) +(defprotocol CustomNext + (custom-next-handler [this request])) + (defprotocol Discardable (can-discard? [this step-params]) (discard-changes [this request])) @@ -70,6 +73,11 @@ :edit-path [] :step-params @cursor))) +(defn get-mfs-field [mfs k] + (or (get (:step-params mfs) k) + (get-in (:snapshot mfs) (conj (or (:edit-path mfs) []) + k)))) + (def step-key-schema (mc/schema [:orn {:decode/arbitrary clojure.edn/read-string :encode/arbitrary pr-str} [:sub-step [:cat :keyword [:or :int :string]]] @@ -228,7 +236,7 @@ :else "forward"))) -(defn render-navigate [{ {:keys [wizard] :as request } :request to-step :to-step oob :oob}] +(defn navigate-handler [{{:keys [wizard] :as request} :request to-step :to-step oob :oob}] (let [current-step (get-current-step wizard) wizard (navigate wizard to-step) new-step (get-current-step wizard) @@ -249,12 +257,15 @@ (def next-handler (-> (fn [{:keys [wizard] :as request}] - (render-navigate {:request request - :to-step (:to (:query-params request))})) + (let [current-step (get-current-step wizard)] + (if (satisfies? CustomNext current-step) + (custom-next-handler current-step request) + (navigate-handler {:request request + :to-step (:to (:query-params request))})))) (wrap-ensure-step) (wrap-schema-enforce :query-schema [:map - [:to step-key-schema]]))) + [:to {:optional true} [:maybe step-key-schema]]]))) (def discard-handler (-> @@ -326,7 +337,7 @@ (assoc request :wizard (hydrate-from-request linear-wizard request)))))) (defn open-wizard-handler [{:keys [wizard current-step query-params] :as request}] - (cond-> + (cond-> (modal-response [:div#transitioner.flex-1 {:x-data (hx/json {"transitionType" "none"}) :x-ref "transitioner" diff --git a/src/clj/auto_ap/ssr/invoice/common.clj b/src/clj/auto_ap/ssr/invoice/common.clj index cbef98ea..382b3808 100644 --- a/src/clj/auto_ap/ssr/invoice/common.clj +++ b/src/clj/auto_ap/ssr/invoice/common.clj @@ -8,6 +8,8 @@ [:invoice/date :xform clj-time.coerce/from-date] + [:invoice/due :xform clj-time.coerce/from-date] + [:invoice/scheduled-payment :xform clj-time.coerce/from-date] {:invoice/client [:client/code :db/id :client/name] :invoice/expense-accounts [* {:invoice-expense-account/account [:account/name :db/id :account/location diff --git a/src/clj/auto_ap/ssr/invoice/new_invoice_wizard.clj b/src/clj/auto_ap/ssr/invoice/new_invoice_wizard.clj index 3fd87a04..383200b6 100644 --- a/src/clj/auto_ap/ssr/invoice/new_invoice_wizard.clj +++ b/src/clj/auto_ap/ssr/invoice/new_invoice_wizard.clj @@ -2,7 +2,6 @@ (:require [auto-ap.datomic :refer [audit-transact conn pull-attr]] [auto-ap.datomic.accounts :as d-accounts] - [auto-ap.ssr.invoice.common :refer [default-read]] [auto-ap.datomic.invoices :as d-invoices] [auto-ap.graphql.utils :refer [assert-can-see-client assert-not-locked exception->4xx]] @@ -17,6 +16,7 @@ [auto-ap.ssr.components.multi-modal :as mm] [auto-ap.ssr.form-cursor :as fc] [auto-ap.ssr.hx :as hx] + [auto-ap.ssr.invoice.common :refer [default-read]] [auto-ap.ssr.nested-form-params :refer [wrap-nested-form-params]] [auto-ap.ssr.svg :as svg] [auto-ap.ssr.utils @@ -70,10 +70,6 @@ (some? (:vendor/default-account (get-vendor vendor-id)))) ;; TODO negative expense accounts for negative invoices? -;; TODO make changing expense accounts work for editing invoices -;; TODO make a change of total automatically change the expense accounts when editing -;; TODO just close when editing, don't go to print screen - (def new-form-schema [:map @@ -81,7 +77,9 @@ [:customize-due-and-scheduled? {:optional true :default false :decode/arbitrary (fn [x] (if (= "" x) false x))} [:maybe :boolean]] - [:invoice/client entity-id] + [:customize-accounts {:optional true :default :default} [:enum :default :customize]] + + [:invoice/client {:optional true} [:maybe entity-id]] [:invoice/date clj-date-schema] [:invoice/due {:optional true} [:maybe clj-date-schema]] [:invoice/scheduled-payment {:optional true} [:maybe clj-date-schema]] @@ -105,41 +103,57 @@ (defn wrap-schema [s] [:and s - [:fn (fn [{:keys [:db/id :invoice/invoice-number :invoice/vendor] :as z}] - (println "HERE" id invoice-number vendor z) + [:fn (fn [{:keys [:db/id :invoice/invoice-number :invoice/vendor :invoice/client] :as z}] (if id true - (and invoice-number vendor)))]]) + (and invoice-number vendor client)))]]) (defn clientize-vendor [{:vendor/keys [terms-overrides automatically-paid-when-due default-account account-overrides] :as vendor} client-id] - (let [terms-override (->> terms-overrides + (if (nil? vendor) + nil + (let [terms-override (->> terms-overrides + (filter (fn [to] + (= (->db-id (:vendor-terms-override/client to)) + client-id))) + (map :vendor-terms-override/terms) + first) + account (or (->> account-overrides (filter (fn [to] - (= (->db-id (:vendor-terms-override/client to)) + (= (->db-id (:vendor-account-override/client to)) client-id))) - (map :vendor-terms-override/terms) + (map :vendor-account-override/account) first) - account (or (->> account-overrides - (filter (fn [to] - (= (->db-id (:vendor-account-override/client to)) - client-id))) - (map :vendor-account-override/account) - first) - default-account) - account (d-accounts/clientize account client-id) + default-account) + account (d-accounts/clientize account client-id) - automatically-paid-when-due (->> automatically-paid-when-due - (filter (fn [to] - (= (->db-id to) - client-id))) - seq - boolean) - vendor (cond-> vendor - terms-override (assoc :vendor/terms terms-override) - true (assoc :vendor/automatically-paid-when-due automatically-paid-when-due - :vendor/default-account account) - true (dissoc :vendor/account-overrides :vendor/terms-overrides))] - vendor)) + automatically-paid-when-due (->> automatically-paid-when-due + (filter (fn [to] + (= (->db-id to) + client-id))) + seq + boolean) + vendor (cond-> vendor + terms-override (assoc :vendor/terms terms-override) + true (assoc :vendor/automatically-paid-when-due automatically-paid-when-due + :vendor/default-account account) + true (dissoc :vendor/account-overrides :vendor/terms-overrides))] + vendor))) + +(defn account-prediction* [{:keys [multi-form-state]}] + (let [vendor (clientize-vendor (get-vendor (:invoice/vendor (:step-params multi-form-state))) + (->db-id (:invoice/client (:step-params multi-form-state)))) + account-name (:account/name (:vendor/default-account vendor)) + value (mm/get-mfs-field multi-form-state :customize-accounts)] + (when vendor + (com/radio-list {:name "step-params[customize-accounts]" + + :value (name value) + :options (filter identity + [(when account-name {:value (name :default) + :content (com/pill {:color :primary} account-name)}) + {:value (name :customize) + :content [:div "Customize accounts"]}])})))) (defrecord BasicDetailsStep [linear-wizard] @@ -153,155 +167,178 @@ []) (step-schema [_] - (wrap-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 :db/id :customize-due-and-scheduled?}))) + (wrap-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 :db/id :customize-due-and-scheduled? :customize-accounts}))) - (render-step [this request] - (mm/default-render-step - linear-wizard this - :head [:div.p-2 "New invoice"] - :body (mm/default-step-body - {} - [:div {:x-data (hx/json {:clientId (or (:db/id (:client request)) - (fc/field-value (:invoice/client fc/*current*))) - :vendorId (fc/field-value (:invoice/vendor fc/*current*)) - :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)) - :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 :db/id - (when (fc/field-value) + (render-step + [this {:keys [multi-form-state] :as request}] + (let [extant? (mm/get-mfs-field multi-form-state :db/id)] + (mm/default-render-step + linear-wizard this + :head [:div.p-2 (if extant? + "Edit invoice" + "New invoice")] + :body (mm/default-step-body + {} + [:div {:x-data (hx/json {:clientId (or (fc/field-value (:invoice/client fc/*current*)) + (:db/id (:client request))) + :vendorId (fc/field-value (:invoice/vendor fc/*current*)) + :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)) + :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 :db/id + (when extant? + (com/hidden {:name (fc/field-name) + :value (fc/field-value)}))) + + + (fc/with-field :customize-due-and-scheduled? (com/hidden {:name (fc/field-name) - :value (fc/field-value)}))) - - - (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) - :value (:db/id (:client request))}) + :value (fc/field-value) + :x-model "customizeDueAndScheduled"})) + (fc/with-field :invoice/client + (if (or (:client request) extant?) + (com/hidden {:name (fc/field-name) + :value (or (mm/get-mfs-field multi-form-state :invoice/client) + (:db/id (:client request)))}) + (com/validated-field + {:label "Client" + :errors (fc/field-errors)} + [:div.w-96 + (com/typeahead {:name (fc/field-name) + :error? (fc/error?) + :class "w-96" + :placeholder "Search..." + :url (bidi/path-for ssr-routes/only-routes :company-search) + :value (fc/field-value) + :content-fn (fn [c] (pull-attr (dc/db conn) :client/name c)) + :x-model "clientId"})]))) + (fc/with-field :invoice/vendor (com/validated-field - {:label "Client" + {:label "Vendor" :errors (fc/field-errors)} [:div.w-96 (com/typeahead {:name (fc/field-name) :error? (fc/error?) + :disabled (boolean (-> request :multi-form-state :snapshot :db/id)) :class "w-96" :placeholder "Search..." - :url (bidi/path-for ssr-routes/only-routes :company-search) + :url (bidi/path-for ssr-routes/only-routes :vendor-search) :value (fc/field-value) - :content-fn (fn [c] (pull-attr (dc/db conn) :client/name c)) - :x-model "clientId"})]))) - (fc/with-field :invoice/vendor - (com/validated-field - {:label "Vendor" - :errors (fc/field-errors)} - [:div.w-96 - (com/typeahead {:name (fc/field-name) - :error? (fc/error?) - :disabled (boolean (-> request :multi-form-state :snapshot :db/id)) - :class "w-96" - :placeholder "Search..." - :url (bidi/path-for ssr-routes/only-routes :vendor-search) - :value (fc/field-value) - :content-fn (fn [c] (pull-attr (dc/db conn) :vendor/name c)) - :x-model "vendorId"})])) + :content-fn (fn [c] (pull-attr (dc/db conn) :vendor/name c)) + :x-model "vendorId"})])) - [:div.flex.items-center.gap-2 - (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"})])) - [: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-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" + [:div.flex.items-center.gap-2 + (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"})])) + [: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-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" + :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/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"})]])) + :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"})]])) - (fc/with-field :invoice/invoice-number - (com/validated-field - {:label "Invoice Number" - :errors (fc/field-errors)} - [:div {:class "w-24"} - (com/text-input {:value (-> (fc/field-value)) - :disabled (boolean (-> request :multi-form-state :snapshot :db/id)) - :name (fc/field-name) - :error? (fc/field-errors) - :placeholder "HA-123"})])) - (fc/with-field :invoice/total - (com/validated-field - {:label "Total" - :errors (fc/field-errors)} - [:div {:class "w-16"} - (com/money-input {:value (-> (fc/field-value)) - :name (fc/field-name) - :class "w-24" - :error? (fc/field-errors) - :placeholder "212.44"})])) + (fc/with-field :invoice/invoice-number + (com/validated-field + {:label "Invoice Number" + :errors (fc/field-errors)} + [:div {:class "w-24"} + (com/text-input {:value (-> (fc/field-value)) + :disabled (boolean (-> request :multi-form-state :snapshot :db/id)) + :name (fc/field-name) + :error? (fc/field-errors) + :placeholder "HA-123"})])) + (fc/with-field :invoice/total + (com/validated-field + {:label "Total" + :errors (fc/field-errors)} + [:div {:class "w-16"} + (com/money-input {:value (-> (fc/field-value)) + :name (fc/field-name) + :class "w-24" + :error? (fc/field-errors) + :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"})]]) + [:div#expense-account-prediction + (hx/alpine-appear + {:x-dispatch:bryce "[vendorId]" + :hx-trigger "bryce" + :hx-put (bidi.bidi/path-for ssr-routes/only-routes ::route/account-prediction) + :hx-target "this" + :hx-swap "innerHTML"}) + (account-prediction* request)]]) + + :footer + (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" + :hx-put (bidi.bidi/path-for ssr-routes/only-routes + ::route/new-wizard-navigate)} "Save")) + :validation-route ::route/new-wizard-navigate))) + + mm/CustomNext + (custom-next-handler + [_ request] + (if (= (get-in request [:multi-form-state :step-params :customize-accounts]) + :customize) + (mm/navigate-handler {:request request + :to-step :accounts}) + + (html-response [:div] + :headers {"location" (bidi.bidi/path-for ssr-routes/only-routes ::route/new-invoice-submit)} + :status 308) + #_(mm/navigate-handler {:request request + :to-step :next-steps})))) - :footer - (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* [{:keys [name account-location client-locations value]}] @@ -467,8 +504,6 @@ :invoice-expense-account/amount (:invoice/total (:step-params current))}]) (:step-params current)))) -;; TODO closing should render the final row - (defrecord NextSteps [linear-wizard] mm/ModalWizardStep (step-name [_] @@ -587,45 +622,61 @@ new-form-schema) (submit [this {:keys [multi-form-state request-method identity] :as request}] (let [invoice (:snapshot multi-form-state) + extant? (:db/id invoice) client-id (->db-id (:invoice/client invoice)) vendor-id (->db-id (:invoice/vendor invoice)) transaction [:upsert-invoice (-> multi-form-state :snapshot (assoc :db/id (or (:db/id invoice) "invoice")) - (dissoc :customize-due-and-scheduled? :invoice/journal-entry :invoice/payments) - (assoc :invoice/expense-accounts (if-let [ieas (seq (-> multi-form-state :snapshot :invoice/expense-accounts))] - ieas + (dissoc :customize-due-and-scheduled? :invoice/journal-entry :invoice/payments :customize-accounts) + (assoc :invoice/expense-accounts (if (= :customize (:customize-accounts invoice)) + (-> multi-form-state :step-params :invoice/expense-accounts) [{: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))}])) + :invoice-expense-account/amount (or (:invoice/total (:step-params multi-form-state)) + (:invoice/total (:snapshot multi-form-state)))}])) (assoc - :invoice/outstanding-balance (:invoice/total (:snapshot multi-form-state)) + :invoice/outstanding-balance (or + (:invoice/total (:step-params multi-form-state)) + (:invoice/total (:snapshot multi-form-state))) :invoice/import-status :import-status/imported :invoice/status :invoice-status/unpaid) (maybe-spread-locations) (update :invoice/date coerce/to-date) - (update :invoice/due coerce/to-date))]] + (update :invoice/due coerce/to-date) + (update :invoice/scheduled-payment coerce/to-date))]] (assert-invoice-amounts-add-up (second transaction)) - (when-not (:db/id invoice) + (when-not extant? (assert-no-conflicting invoice)) (exception->4xx #(assert-can-see-client (:identity request) client-id)) (exception->4xx #(assert-not-locked client-id (:invoice/date invoice))) (let [transaction-result (audit-transact [transaction] (:identity request))] (solr/touch-with-ledger (get-in transaction-result [:tempids "invoice"])) - (assoc-in (mm/render-navigate {:request (assoc-in request [:multi-form-state :snapshot :db/id] (get-in transaction-result [:tempids "invoice"])) - :to-step :next-steps}) - [:headers "hx-trigger"] "invalidated"))))) + (if extant? + + (html-response + (@(resolve 'auto-ap.ssr.invoices/row*) identity (dc/pull (dc/db conn) default-read (:db/id invoice)) {:flash? true + :request request}) + :headers (cond-> {"hx-trigger" "modalclose" + "hx-retarget" (format "#entity-table tr[data-id=\"%d\"]" (:db/id invoice)) + "hx-reswap" "outerHTML"})) + + (assoc-in (mm/navigate-handler {:request (assoc-in request [:multi-form-state :snapshot :db/id] (get-in transaction-result [:tempids "invoice"])) + :to-step :next-steps}) + [:headers "hx-trigger"] "invalidated")))))) (def new-wizard (->NewWizard2 nil nil)) (defn initial-new-wizard-state [request] - (mm/->MultiStepFormState {:invoice/date (time/now)} + (mm/->MultiStepFormState {:invoice/date (time/now) + :customize-accounts :default} [] - {:invoice/date (time/now)})) + {:invoice/date (time/now) + :customize-accounts :default})) @@ -634,9 +685,11 @@ (let [entity (dc/pull (dc/db conn) default-read (:db/id (:route-params request))) entity (select-keys entity (mut/keys new-form-schema))] - (mm/->MultiStepFormState entity + (mm/->MultiStepFormState (assoc entity + :customize-accounts :customize) [] - entity))) + (assoc entity + :customize-accounts :customize)))) (defn location-select [{{:keys [name account-id client-id value] :as qp} :query-params}] (html-response (location-select* {:name name @@ -683,27 +736,10 @@ :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 - :color :secondary - ;;: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])))) +(defn account-prediction [{:keys [multi-form-state form-errors] :as request}] + (html-response + (account-prediction* request))) (def key->handler (apply-middleware-to-all-handlers diff --git a/src/cljc/auto_ap/routes/invoice.cljc b/src/cljc/auto_ap/routes/invoice.cljc index 0aef9eed..12d9d3d7 100644 --- a/src/cljc/auto_ap/routes/invoice.cljc +++ b/src/cljc/auto_ap/routes/invoice.cljc @@ -5,6 +5,7 @@ "/voided" ::voided-page} "/new" {:get ::new-wizard :post ::new-invoice-submit + :put ::new-invoice-submit "/due-date" ::due-date "/scheduled-payment-date" ::scheduled-payment-date "/navigate" ::new-wizard-navigate