fix(skattekonto): look-alike beslut rows, the list-to-voucher round trip, makulerad rendering, huvudbok discoverability (#1297)
Four fixes from the exit mail Anders Orback (Center Node AB) sent hours after churning. His five points were mostly one job: reconciling skattekontot against banken before årsredovisningen. Skattekonto look-alike rows. Skatteverket splits a retroactive omprövningsbeslut across every month it re-charges and sends one transaction per month, sharing date, text and amount; only ranteberakningsdatum separates them, and we stored it but rendered it nowhere. A real company posted 15 such vouchers (67 785 kr across Feb 2025-Apr 2026) unable to tell them from duplicates of the automatic hämtning. Surface the field when it carries information: its month differs from the Datum column, or another row in the same band is otherwise indistinguishable. The list-to-voucher round trip. The verifikat list collapsed to a skeleton on every refetch and sprang back, moving rows under the pointer; only the first load shows a skeleton now. Filter state is React-only, so leaving the list loses it: add a hover-revealed open-in-new-tab affordance on the voucher list and the skattekonto page, where the link had been behind a hand-rolled opacity-0 that coarse pointers never trigger. Makulerad rendering. A stornoed verifikat now reads as struck out, per data cell rather than on the row, because text-decoration propagates and a child cannot opt out. Vouchers-per-account discoverability. /reports/huvudbok?account=1930 already existed; the palette matcher requires every token and the entry never contained the word "verifikat". Add ReportDescriptor.searchTerms plus a report-library search box. Also fixes a false "Saknar underlag" compliance chip that flashed before attachment counts resolved, and a keyboard-access regression where HOVER_REVEAL_CLASS carried focus-visible only, hiding controls inside a non-focusable wrapper from keyboard users. No migration. No write paths, storno paths or posted entries touched. Follow-ups filed: #1300 #1301 #1302 #1303 #1304 #1305 #1306 #1307 #1308. Open decision: #1305 (Omförd vs Makulerad). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
144cc51458
commit
fa394e3759
@@ -701,3 +701,17 @@ One line per decision: `[YYYY-MM-DD] <decision>: <why>`. Appended by agents and
|
||||
[2026-07-30] InvoiceMatchDialog classifies stale targets as matchable, settled, or not open instead of calling every invalid status fully paid: paid and zero-balance targets need different copy from cancelled, credited, disputed, reversed, draft, or malformed targets, while valid partially paid invoices keep the existing amount-difference flow. Blocked targets do not fetch or show a voucher preview or a confirm-outcome panel because neither match route has a reachable success path for them.
|
||||
|
||||
[2026-07-30] Issue #1289 ruta 05 null-rate fallback is report-local and requires both the 30x1/30x2/30x3 suffix and a matching 25/12/6 % moms account label; explicit configured values win. Declined historical backfill, account-creation derivation, and a DB NOT NULL guard: 3011 is custom rather than BAS 2026, NULL is valid across class 3, and history or mixed vouchers cannot safely set future defaults.
|
||||
|
||||
[2026-07-30] Skattekonto look-alike rows show ränteberäkningsdatum inline as muted text rather than as a fourth column: a retroactive omprövningsbeslut arrives as one transaction per re-charged month sharing date, text and amount, and only that field separates them. Kept it an exception marker per design convention 5 (12 % of prod rows qualify) instead of a column that is empty on the rest, and paired the month-differs rule with a same-band twin check so no two rows can ever render identically.
|
||||
|
||||
[2026-07-30] Amends design convention 11: `.stagger-enter` no longer re-runs on client-fetch completion for a list that is already rendered. The verifikat list now keeps its rows mounted and dims them during a refetch instead of collapsing to a skeleton and springing back, because the height change under the pointer was causing real mis-clicks on filter/sort/page changes. Stagger still runs on server render and on first client load. Chose dim-in-place over row-count-matched skeletons: matching heights only equalises the two states, it does not remove the transition.
|
||||
|
||||
[2026-07-30] Voucher rows get a hover-revealed "öppna i ny flik" affordance (`components/ui/open-in-new-tab.tsx`) next to the existing link rather than flipping the link itself to target="_blank". Working a filtered list means leaving and returning, and filter/scroll state is React-only, so a second tab is the only way to keep the list; cmd-click already worked on most rows but nothing advertised it. Kept the primary click navigating in place so existing habits are unaffected, and used HOVER_REVEAL_CLASS so the control is reachable on touch.
|
||||
|
||||
[2026-07-30] A makulerad (reversed) verifikat now renders struck through and dimmed in the verifikatlista, matching what Grundbok already did. Applied per data cell, not on the <tr>: text-decoration propagates to descendants and a child cannot opt out, so striking the row would have drawn a line through its action controls and status chips. Renamed journal_status.status_cancelled "Makulerad" -> "Avbruten" only: 'cancelled' is what the engine sets instead of DELETE for an aborted entry, never for a storno, and "Avbruten" is already the word used for that status in another namespace. Deliberately did NOT rename status_reversed "Omförd" -> "Makulerad" even though Grundbok already renders that state as "Makulerad": the compliance review flagged that in Swedish practice "makulerad" can imply a voided document with no ongoing audit trail, whereas a storno'd verifikation must stay traceable under BFL 5 kap 5 §, so the two states are legally distinct and the wording is a founder call, not a drive-by. The Omförd/Makulerad split between verifikatlistan and Grundbok therefore survives this PR and is still open.
|
||||
|
||||
[2026-07-30] Vouchers-per-account was a naming problem, not a missing report: /reports/huvudbok?account=1930 already lists a single account's verifikat with click-through. The command palette's token-AND matcher dropped the query "verifikat per konto" because the huvudbok entry never carried the word "verifikat", and the report library had no search at all. Added the synonym set (verifikat, kontoanalys, kontokort, stäm av) to both, via a new optional ReportDescriptor.searchTerms so the vocabulary lives with the catalog rather than being duplicated per surface. Kept "Huvudbok" as the visible name; Fortnox's "Kontoanalys" is a searchable synonym only, and "Kontoutdrag" is deliberately NOT one because it already means bank statement here and in Fortnox.
|
||||
|
||||
[2026-07-30] HOVER_REVEAL_CLASS gains focus-within:opacity-100. focus-visible only matches the element itself, so using the constant on a non-focusable wrapper <span> (the skattekonto Matcha/Bokför cluster, which previously hand-rolled focus-within) left those buttons transparent while a keyboard user tabbed through them. Fixed in the shared constant rather than per call site, since the constant is documented as the one true row-control helper and every wrapper use has the same trap.
|
||||
|
||||
[2026-07-30] Report-vocabulary synonyms live in ReportDescriptor.searchTerms, NOT in the command-palette keywords, when they are words another report already owns. "stäm av"/"avstämning" on the huvudbok palette entry hijacked Enter from Bankavstämning, because the palette auto-selects the first hit and huvudbok is listed above it. The library search shows a list and has no such failure mode, so broad task-vocabulary belongs there.
|
||||
|
||||
Reference in New Issue
Block a user