Commit Graph

2063 Commits

Author SHA1 Message Date
8a676718a7 feat(ssr): reset transaction selection after bulk code
Bulk coding left the checked items selected after the table refreshed.
Add a dedicated reset-selection event that the grid's Alpine state
listens for, and fire it alongside refreshTable on bulk-code submit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 22:06:37 -07:00
3ffb661da3 fix(ssr): stop unresolved filter flipping to true on transactions navigation
The unresolved/potential-duplicates query-param decoders fell through to
(boolean %) for unrecognized strings. A round-tripped "false" (pushed into the
URL, re-read via HX-Current-URL) decoded to true since any non-nil string is
truthy, so navigating pages silently turned on the "Unresolved only" filter.

Handle "false" and already-boolean values symmetrically.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 21:40:31 -07:00
f9438ba983 fix(ssr): only require account coding for manual transaction edits
Account coding lived in the always-applied base map of edit-form-schema, so
every action (including the link/apply-rule/unlink actions) required a valid
transaction-account/account. The edit modal always submits the Manual tab's
(usually blank) account row, so link submits failed validation before reaching
their save-handler and silently no-op'd. Move account validation into the
:manual branch of the action :multi so link actions validate without it.

Also surface whole-form validation errors in the wizard footer error bar:
default-step-footer only handled top-level/sequential error shapes, so nested
field-error maps (e.g. a hidden tab's account error) produced an empty bar and
a silent failure. Add flatten-form-errors to flatten the humanized error tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 21:30:29 -07:00
7d34b8a5f6 money 2026-06-18 20:26:07 -07:00
c09d85ede6 fix(ssr): fix Client Review (requires-feedback) status in bulk-code dialog
The bulk-code "Requires Feedback" option submitted "requires_feedback"
(underscore), which decoded to an enum keyword not present in the
schema (idents use a hyphen), so selecting it failed validation. Use
the hyphenated value and relabel the option, the reconciliation report
header to "Client Review" to unify with the sidebar terminology.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 10:38:00 -07:00
ec4f88b7fc fix(ssr): hide P&L warning box when there is no warning
The profit-and-loss report always passed :warning as a [:div ...] hiccup
vector, which is truthy even when empty. The shared report table renders
its red warning box with (when warning ...), so a clean report with no
warning and no unresolved entries still showed an empty red error box.

Only build the warning div when there is actual warning text or sample
links, matching how the balance-sheet and cash-flows reports pass nil.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 15:56:43 -07:00
8ca5e75c4d fix(ssr): hide client column in edited transaction row for single client
The save-handler re-rendered the edited row via row* without passing
:request, so the Client column's :hide? predicate received a nil request
and never hid the column. Pass :request request like table* does.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 13:40:50 -07:00
4aed27b204 feat(ssr): add bank account column to transactions table
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 13:36:08 -07:00
d0028f403c fix(ssr): allow picking bank account when editing a transaction rule
The bank-account filter rendered "Please select a client" even when a
client was set on the rule. Two causes:

- Inside (fc/with-field :transaction-rule/bank-account ...) the cursor is
  rebound to the bank-account field, so (:transaction-rule/client
  (fc/field-value)) read the nil bank-account value and the server
  rendered the placeholder. The clientId watcher only fires on change, so
  when editing (client preset, unchanged) the htmx swap never corrected
  it. Read the client from the form root before entering the field.
- The clientId-change swap used innerHTML, nesting a fresh typeahead
  inside the stale one and breaking its Alpine refs. Use outerHTML so the
  typeahead is replaced in place.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 13:32:30 -07:00
6b4392b74b fix(ssr): keep top bar to a fixed-height single row
The top bar grew vertically on narrower viewports when the environment
badge and company-selector labels wrapped, pushing content under the
fixed navbar (which the layout offsets with a fixed pt-16).

Rework the navbar into a fixed h-16 row with a priority-based responsive
layout:
- search fills the middle (flex-1) and shrinks first when space is tight
- company selector holds its size and truncates long names
- environment badge degrades full pill -> compact letter badge -> hidden
- harmonize control heights (40px controls, 32px badge/avatar accents) so
  the search no longer renders as a cramped thin strip

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 09:01:32 -07:00
cdc87d3710 fix 2026-06-16 20:36:00 -07:00
1e3952a7fb fix(auth): login error-details pre escaping Alpine scope
The error-details <pre> lived inside a <span x-data="{e:false}"> that was
itself inside a <p>. Since <pre> is block content, the HTML parser closed
the <p> and reparented the <pre> out of the span, so Alpine evaluated
x-show="e" with e no longer in scope ("e is not defined"). Use a <div>
wrapper instead of <p> so the pre stays within the e scope.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 20:05:43 -07:00
e099714af1 fix(ssr): transaction edit dropdown duplication and advanced->simple toggle
- Location field hx-target "find *" resolved to the <label> (first child),
  so changing an account swapped the reloaded <select> over the label and
  left a duplicate dropdown. Target "find select" instead (simple + advanced).
- edit-wizard-toggle-mode-handler read mode only from step-params, but the
  hidden "mode" field is a top-level form param, so current-mode always
  defaulted to "simple" and the toggle could never return from advanced.
  Read it from form-params too, matching edit-vendor-changed-handler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 20:02:41 -07:00
11024b7b89 fix(ssr): transaction rule wizard drops fields on Next
The EditModal step body wrapped all rule fields in a nested
<form id="my-form"> inside the wizard's own #wizard-form. By HTML
form-ownership rules those fields belonged to the inner form, so when
htmx serialized #wizard-form on Next, none of the step-params fields
were sent. The server saw an empty rule, reported "required" for
description/accounts, and re-rendered a blank wizard (losing input).

Replace the nested <form> with a plain <div>; the wizard form already
owns submission, so the inner form and its htmx attributes were
redundant.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 14:58:36 -07:00
de2a1ab850 fixes pnl file name 2026-06-16 14:37:13 -07:00
85aaf7b759 mcp repl fixes 2026-06-02 23:40:05 -07:00
3759258ebe fix(ssr): require Apply for all date-range filters
Most grid pages auto-submitted their date-range filter on every change
event, which fired mid-typing and re-rendered the date inputs, breaking
manual date entry. Invoices and ledgers already gated date submission
behind an explicit Apply button; this brings the other ten pages in line.

- date-range component: stop `change` from the date inputs bubbling to
  the form (@change.stop) and always render the Apply button, so typed or
  picked dates submit only via the Apply button's `datesApplied` event.
  The All/Week/Month/Year presets and all other filters are unaffected.
- payments, invoice import, transactions, import batches, sales
  summaries, expected deposits, cash drawer shifts, refunds, tenders,
  sales orders: add `datesApplied` to the form hx-trigger.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 22:42:17 -07:00
19186097d5 fix(ssr): stop content-card forcing always-on scrollbars; add tmp/ scratch dir
content-card used `overflow-scroll`, which renders scrollbar tracks even
when the content fits — visible as superfluous bars around the admin chart
cards. Switch to `overflow-auto` so scrollbars only appear when content
genuinely overflows (e.g. wide data tables still scroll).

Also add a gitignored ./tmp/ scratch directory (tracked via .gitkeep) and
document in AGENTS.md that temp files belong there.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 09:16:16 -07:00
1f6395382d refactor(charts): unify on Chart.js, remove Chartist
The admin page was the only consumer of Chartist while the dashboard and
expense report already use Chart.js. Convert the admin "Growth in clients"
(bar) and "Changes by hour" (line) charts to Chart.js using the same
Alpine x-data/x-init canvas pattern as the dashboard, and drop the global
Chartist CSS/JS includes from the base page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 07:55:47 -07:00
901d9eb508 date-choosing 2026-06-02 07:13:29 -07:00
9cc3418b1b fix(review): apply autofix feedback
- Alphabetize the import.clj :require block (AGENTS.md Import Formatting).
- Remove unused imports (digest, strip) flagged by clj-kondo.
- Make the client-not-found classify-table test independent: it previously
  reused the bank-account-not-found input and added zero marginal coverage;
  now seeds an orphan bank account so only the client error fires.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 11:34:31 -07:00
a1098b28f8 feat(transactions): port manual bank-transaction import to SSR
Implement the SSR/alpine/htmx manual transaction import, wiring the
already-declared but unhandled ::external-import-page/parse/import routes.
Mirrors the SSR ledger import: paste the exact master-branch Yodlee
positional-column TSV, review parsed rows in an editable grid with per-row
error/warning badges, and import. Every master validation is preserved and
the existing import.transactions engine is reused unchanged
(via import.manual/import-batch), so core components are untouched.

- New ns auto-ap.ssr.transaction.import (page, paste/parse, editable grid,
  two-tier validation, import handler) + admin-only transactions Import nav.
- Two-tier validation: fixable problems (bad date/amount, unknown client or
  bank-account code, missing fields) are hard errors that block the whole
  batch; inherent skip-conditions (non-POSTED, before start-date/locked,
  already-imported) are warnings computed from the engine's own
  categorize-transaction so the grid preview matches the import result.
- Tests: failing-first Playwright e2e (e2e/transaction-import.spec.ts) plus
  unit/integration coverage (ssr/transaction/import_test.clj, 10 tests).
- Deterministic bank-account code in the e2e seed.

Plan: docs/plans/2026-06-01-001-feat-manual-transaction-import-ssr-plan.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 11:18:28 -07:00
b6649a3d1d fixes 2026-05-31 08:37:44 -07:00
38ae6f460f Cleanup of simple/advanced mode 2026-05-31 08:30:11 -07:00
e156d8bfd8 fixes vendor selection bug 2026-05-30 09:21:39 -07:00
6814cf1b15 better login page 2026-05-29 10:55:14 -07:00
3441ae63b4 fix: normalize account ref map to db/id in simple mode rendering
When a transaction is pre-coded, the snapshot stores :transaction-account/account
as a Datomic ref map {:db/id N} rather than a bare integer. simple-mode-fields*
and the simpleAccountId Alpine initializer both need the integer id, not the map,
to correctly populate the account typeahead value and the x-hx-val binding.
2026-05-28 00:10:15 -07:00
79ddda624a fix: change toggle-mode links from hx-get to hx-post so form data is submitted 2026-05-27 23:53:43 -07:00
cbb9bc750d fix: prefer step-params over snapshot for row-count and existing-row 2026-05-27 23:49:59 -07:00
9997d60de1 fix: handle absent :transaction/accounts in simple-mode-fields* (ValCursor crash) 2026-05-27 23:07:52 -07:00
06fb0ea067 feat: update edit-vendor-changed-handler to support simple/advanced mode 2026-05-27 22:03:13 -07:00
9a7d0b8b18 feat: add edit-wizard-toggle-mode-handler 2026-05-27 21:59:33 -07:00
70a3db9a64 fix: repair vendor-changed swap target and remove unused declare 2026-05-27 21:57:11 -07:00
4e22fb1d82 feat: extract manual-coding-section* with simple/advanced mode selection 2026-05-27 21:52:09 -07:00
a88dcf4122 fix: safe cursor indexing in simple-mode-fields* 2026-05-27 21:44:54 -07:00
00b5303c28 feat: add simple-mode-fields* for transaction edit modal 2026-05-27 21:40:04 -07:00
17eebe5628 Add http-port override, login UI improvements, and dev tooling 2026-05-27 14:13:43 -07:00
e5a2d0bbba Simplify sysco line item allocation: use actual amounts, default unmatched to food cost (50000) 2026-05-27 13:22:29 -07:00
7db1e07512 new glimpse test. 2026-05-27 10:14:54 -07:00
de933699aa Merge branch 'integreat-assorted' into staging 2026-05-26 23:20:45 -07:00
4fca49bff0 fixes a number of issues 2026-05-26 23:20:31 -07:00
2f9da3cdd9 general improvements 2026-05-26 22:25:47 -07:00
78bd1d92e0 Merge branch 'integreat-invoices-for-ntg' into staging 2026-05-26 22:04:37 -07:00
99dd88329e uses percent 2026-05-26 22:04:21 -07:00
de73233a08 transaction dialog now uses sidebar. 2026-05-26 21:58:24 -07:00
11cc887671 unique locations 2026-05-26 21:56:58 -07:00
a4d7ac5982 Allows upload of CSV of sysco with line item parsing 2026-05-26 21:53:04 -07:00
f42d937691 fix: replace broken hx-vals JS with hx-include for transaction nav links
The hx-vals attribute with a JavaScript IIFE was causing a SyntaxError
when navigating to the transactions page from any other page. Replaced
with hx-include="#transaction-filters" which correctly preserves
filter state across transaction sub-pages.
2026-05-26 21:16:37 -07:00
200056098f feat: add memo filter and enhance description filter with regex matching
- Add new memo filter to transaction page (searches :transaction/memo)
- Enhance existing description filter to use case-insensitive regex
- Both filters support wildcard matching via .* pattern
- Add e2e tests for filter functionality
- Update test data with memo fields
2026-05-26 16:34:56 -07:00
712b2c0cb8 fix: use cleansed-query for Solr client name search
Fixes substring search in company dropdown. The search query was
using raw user input instead of the cleansed version that adds a
wildcard suffix (e.g. 'dough' -> 'dough*'). Without the wildcard,
Solr performs exact token matching, so searching 'dough' would not
match 'Doughballs'.
2026-05-26 13:21:53 -07:00