fix(ssr): repair New Invoice + Transaction Edit 500s and broken modal sizes
Three regressions from the SSR rendering-modernization migration, all verified live via agent-browser: - BUG A — New Invoice: choosing a client 500'd from /invoice/new/due-date (ClassCastException: DateTime cannot be cast to java.util.Date). `due-date` and `scheduled-payment-date` called `coerce/from-date` on values already decoded to clj-time DateTimes. Drop the coerce; use the decoded dates. - BUG C — Transaction Edit: any whole-form swap (mode toggle, vendor change, add/remove row) 500'd whenever the txn had >=1 autopay-invoice match (ClassCastException at links-body*: PersistentVector cannot be cast to Named). The autopay link-panel's hidden `action` input was missing `:form ""`, so it serialized alongside the main `action` hidden, producing a duplicate param that Ring collapsed to a vector. Add `:form ""` to match the unpaid/rule panels. - Modal sizes: Vendor/Client/Invoice-Pay modals ballooned to full width because resources/public/output.css was missing their arbitrary Tailwind size classes. Root cause: tailwind.config.js `content` never scanned resources/templates/**/*.html (46 Selmer templates the migration introduced), so a rebuild also dropped template-only classes like md:w-[950px]. Add the templates glob and rebuild; all modal size classes now present, no working modal regressed. Docs: add 2026-06-27 QA findings + resumable fix task list; cross-link from the migration plan. Remaining (per the new plan): Vendor/Client inner step-body overflow, wizard step animations, bulk-edit empty-selection 500, footer EDN leak. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -97,7 +97,7 @@
|
||||
[:fn {:error/message "Not an allowed account."}
|
||||
#(check-allowance % :account/invoice-allowance)]]]
|
||||
[:invoice-expense-account/location :string]
|
||||
[:invoice-expense-account/amount :double]]
|
||||
[:invoice-expense-account/amount :double]]
|
||||
[:fn {:error/fn (fn [r x] (:type r))
|
||||
:error/path [:invoice-expense-account/location]}
|
||||
(fn [iea]
|
||||
@@ -113,13 +113,13 @@
|
||||
client-id)))
|
||||
(map :vendor-terms-override/terms)
|
||||
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 (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)
|
||||
|
||||
automatically-paid-when-due (->> automatically-paid-when-due
|
||||
@@ -147,24 +147,24 @@
|
||||
:else
|
||||
[["Shared" "Shared"]]))]
|
||||
(com/select {:options options
|
||||
:name name
|
||||
:name name
|
||||
:value (or value (ffirst options))
|
||||
:class "w-full"})))
|
||||
|
||||
(defn account-typeahead*
|
||||
[{:keys [name value client-id x-model]}]
|
||||
[:div.flex.flex-col
|
||||
(com/typeahead {:name name
|
||||
(com/typeahead {:name name
|
||||
:placeholder "Search..."
|
||||
:url (hu/url (bidi/path-for ssr-routes/only-routes :account-search)
|
||||
{:client-id client-id
|
||||
:purpose "invoice"})
|
||||
:id name
|
||||
:x-model x-model
|
||||
:value value
|
||||
:content-fn (fn [value]
|
||||
(:account/name (d-accounts/clientize (dc/pull (dc/db conn) d-accounts/default-read value)
|
||||
client-id)))})])
|
||||
:url (hu/url (bidi/path-for ssr-routes/only-routes :account-search)
|
||||
{:client-id client-id
|
||||
:purpose "invoice"})
|
||||
:id name
|
||||
:x-model x-model
|
||||
:value value
|
||||
:content-fn (fn [value]
|
||||
(:account/name (d-accounts/clientize (dc/pull (dc/db conn) d-accounts/default-read value)
|
||||
client-id)))})])
|
||||
|
||||
(defn assert-no-conflicting [{:invoice/keys [invoice-number client vendor] :db/keys [id]}]
|
||||
(when (seq (d-invoices/find-conflicting {:invoice/invoice-number invoice-number
|
||||
@@ -184,7 +184,7 @@
|
||||
(let [base-amount (int (/ shared-amount total-locations))
|
||||
remainder (- shared-amount (* base-amount total-locations))]
|
||||
{:base-amount base-amount
|
||||
:remainder remainder}))
|
||||
:remainder remainder}))
|
||||
|
||||
(defn- spread-expense-account
|
||||
"Spreads the expense account amount across the given locations"
|
||||
@@ -600,10 +600,9 @@
|
||||
(defn due-date [request]
|
||||
(let [{:invoice/keys [vendor client date due]} (form-vendor-client request)
|
||||
vendor (clientize-vendor (get-vendor (->db-id vendor)) (->db-id client))
|
||||
date (some-> date coerce/from-date)
|
||||
good-date (or (when (and date (:vendor/terms vendor))
|
||||
(time/plus date (time/days (:vendor/terms vendor))))
|
||||
(some-> due coerce/from-date))]
|
||||
due)]
|
||||
(html-response
|
||||
(com/date-input {:value (some-> good-date (atime/unparse-local atime/normal-date))
|
||||
:name "invoice/due"
|
||||
@@ -616,7 +615,7 @@
|
||||
(let [{:invoice/keys [vendor client due]} (form-vendor-client request)
|
||||
vendor (clientize-vendor (get-vendor (->db-id vendor)) (->db-id client))
|
||||
good-date (when (and due (:vendor/automatically-paid-when-due vendor))
|
||||
(some-> due coerce/from-date))]
|
||||
due)]
|
||||
(html-response
|
||||
(com/date-input {:value (some-> good-date (atime/unparse-local atime/normal-date))
|
||||
:name "invoice/scheduled-payment"
|
||||
|
||||
@@ -658,7 +658,7 @@
|
||||
(panel-wrap
|
||||
(if (seq invoice-matches)
|
||||
(panel-list* {:heading "Available Autopay Invoices"
|
||||
:action-hidden (sc/hidden {:name "action" :value "link-autopay-invoices"})
|
||||
:action-hidden (sc/hidden {:name "action" :value "link-autopay-invoices" :form ""})
|
||||
:prompt "Select an autopay invoice to apply:"
|
||||
:radio (sc/radio-card {:options (for [match-group invoice-matches]
|
||||
{:value (pr-str (map :db/id match-group))
|
||||
|
||||
Reference in New Issue
Block a user