From f6dba46835e4aeb766be03f8a79eb3ce43828a5a Mon Sep 17 00:00:00 2001 From: Bryce Date: Mon, 29 Apr 2024 23:05:33 -0700 Subject: [PATCH] home stretch --- src/clj/auto_ap/jobs/sales_summaries.clj | 2 + src/clj/auto_ap/ssr/admin/sales_summaries.clj | 167 +++++++++++++++++- .../auto_ap/routes/admin/sales_summaries.cljc | 5 +- 3 files changed, 169 insertions(+), 5 deletions(-) diff --git a/src/clj/auto_ap/jobs/sales_summaries.clj b/src/clj/auto_ap/jobs/sales_summaries.clj index cbf6a1fa..1fd88ab8 100644 --- a/src/clj/auto_ap/jobs/sales_summaries.clj +++ b/src/clj/auto_ap/jobs/sales_summaries.clj @@ -535,6 +535,8 @@ @(dc/transact conn [{:db/id :sales-summary/total-tax :db/ident :sales-summary/total-tax-legacy} {:db/id :sales-summary/total-tip :db/ident :sales-summary/total-tip-legacy}]) +(auto-ap.datomic/transact-schema conn) + ) diff --git a/src/clj/auto_ap/ssr/admin/sales_summaries.clj b/src/clj/auto_ap/ssr/admin/sales_summaries.clj index b4188c6a..a326efca 100644 --- a/src/clj/auto_ap/ssr/admin/sales_summaries.clj +++ b/src/clj/auto_ap/ssr/admin/sales_summaries.clj @@ -8,14 +8,20 @@ :refer [wrap-admin wrap-client-redirect-unauthenticated]] [auto-ap.ssr-routes :as ssr-routes] [auto-ap.ssr.components :as com] + [auto-ap.ssr.components.multi-modal :as mm] + [auto-ap.ssr.form-cursor :as fc] [auto-ap.ssr.grid-page-helper :as helper] + [auto-ap.ssr.svg :as svg] [auto-ap.ssr.utils - :refer [apply-middleware-to-all-handlers]] + :refer [apply-middleware-to-all-handlers entity-id + wrap-schema-enforce]] [auto-ap.time :as atime] [bidi.bidi :as bidi] [clj-time.coerce :as c] [datomic.api :as dc] - [iol-ion.query :refer [dollars=]])) + [iol-ion.query :refer [dollars=]] + [malli.core :as mc] + [malli.util :as mut])) (defn filters [request] [:form {"hx-trigger" "change delay:500ms, keyup changed from:.hot-filter delay:1000ms" @@ -140,7 +146,10 @@ :fetch-page fetch-page :page-specific-nav filters :row-buttons (fn [_ entity] - []) + [(com/icon-button {:hx-put (bidi/path-for ssr-routes/only-routes + ::route/edit-wizard + :db/id (:db/id entity))} + svg/pencil)]) :oob-render (fn [request] [#_(assoc-in (date-range-field {:value {:start (:start-date (:parsed-query-params request)) @@ -232,11 +241,161 @@ (def row* (partial helper/row* grid-page)) (def table* (partial helper/table* grid-page)) + +(def edit-schema + [:map + [:db/id entity-id] + [:sales-summary/sales-items + [:vector {:coerce? true} + [:map [:db/id entity-id]]]] ]) + +(defrecord MainStep [linear-wizard] + mm/ModalWizardStep + (step-name [_] + "Main") + (step-key [_] + :main) + + (edit-path [_ _] + []) + + (step-schema [_] + (mut/select-keys (mm/form-schema linear-wizard) #{:db/id})) + + (render-step + [this {:keys [multi-form-state] :as request}] + (mm/default-render-step + linear-wizard this + :head [:div.p-2 "New invoice"] + :body (mm/default-step-body + {} + [:div + (fc/with-field :db/id + (com/hidden {:name (fc/field-name) + :value (fc/field-value)})) + + + (pr-str multi-form-state) ]) + + :footer + (mm/default-step-footer linear-wizard this :validation-route ::route/edit-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/edit-wizard-navigate)} "Save")) + :validation-route ::route/edit-wizard-navigate))) + +(defrecord EditWizard [_ current-step] + mm/LinearModalWizard + (hydrate-from-request + [this request] + this) + (navigate [this step-key] + (assoc this :current-step step-key)) + (get-current-step + [this] + (mm/get-step this :main)) + (render-wizard [this {:keys [multi-form-state] :as 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/edit-submit)))) + :render-timeline? false)) + (steps [_] + [:main]) + (get-step [this step-key] + (let [step-key-result (mc/parse mm/step-key-schema step-key) + [step-key-type step-key] step-key-result] + (->MainStep this))) + (form-schema [_] + edit-schema) + (submit [this {:keys [multi-form-state request-method identity] :as request}] + #_(let [invoice (:snapshot multi-form-state) + + _ (alog/peek invoice) + extant? (:db/id invoice) + client-id (->db-id (:invoice/client invoice)) + vendor-id (->db-id (:invoice/vendor invoice)) + paid-amount (if-let [outstanding-balance + (and extant? + (- + (pull-attr (dc/db conn) + :invoice/total + (:db/id invoice)) + (pull-attr (dc/db conn) + :invoice/outstanding-balance + (:db/id invoice))))] + outstanding-balance + 0.0) + outstanding-balance (- (or + (:invoice/total (:step-params multi-form-state)) + (:invoice/total (:snapshot multi-form-state))) + paid-amount) + + 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 :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 (or (:invoice/total (:step-params multi-form-state)) + (:invoice/total (:snapshot multi-form-state)))}])) + (assoc + :invoice/outstanding-balance outstanding-balance + :invoice/import-status :import-status/imported + :invoice/status (if (dollars= 0.0 outstanding-balance) + :invoice-status/paid + :invoice-status/unpaid)) + (maybe-spread-locations) + (update :invoice/date 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 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"])) + (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 edit-wizard (->EditWizard nil nil)) + +(defn initial-edit-wizard-state [request] + (let [entity (dc/pull (dc/db conn) default-read (:db/id (:route-params request))) + entity (select-keys entity (mut/keys edit-schema))] + + (mm/->MultiStepFormState entity [] entity))) + (def key->handler (apply-middleware-to-all-handlers (->> {::route/page (helper/page-route grid-page) - ::route/table (helper/table-route grid-page)}) + ::route/table (helper/table-route grid-page) + ::route/edit-wizard (-> mm/open-wizard-handler + (mm/wrap-wizard edit-wizard) + (mm/wrap-init-multi-form-state initial-edit-wizard-state) + (wrap-schema-enforce :route-schema [:map [:db/id entity-id]])) + ::route/edit-wizard-navigate (-> mm/next-handler + (mm/wrap-wizard edit-wizard) + (mm/wrap-decode-multi-form-state))}) (fn [h] (-> h (wrap-admin) diff --git a/src/cljc/auto_ap/routes/admin/sales_summaries.cljc b/src/cljc/auto_ap/routes/admin/sales_summaries.cljc index e5144e71..a2fd9b6d 100644 --- a/src/cljc/auto_ap/routes/admin/sales_summaries.cljc +++ b/src/cljc/auto_ap/routes/admin/sales_summaries.cljc @@ -1,3 +1,6 @@ (ns auto-ap.routes.admin.sales-summaries) (def routes {"" {:get ::page} - "/table" ::table}) \ No newline at end of file + "/table" ::table + + ["/" [#"\d+" :db/id]] {:put ::edit-wizard} + "/edit/navigate" ::edit-wizard-navigate }) \ No newline at end of file