From 722b22972dcbe6940b615da2feb0d589b5f65a25 Mon Sep 17 00:00:00 2001 From: Jakob Wennberg <149234542+jakobwennberg@users.noreply.github.com> Date: Thu, 14 May 2026 16:59:29 +0200 Subject: [PATCH] =?UTF-8?q?feat(enable-banking):=20per-account=20ledger=20?= =?UTF-8?q?mapping=20for=20multicurrency=20setups=20(#443)=20=E2=80=94=20r?= =?UTF-8?q?ebase=20of=20#487=20(#488)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(enable-banking): per-account ledger mapping for multicurrency setups (#443) Today every bank account routes to BAS 1930. Multicurrency setups (Wise, SEB foreign-currency sub-accounts) get pooled into a single SEK ledger account, making year-end FX revaluation a mess. This change lets each bank account under a PSD2 consent map to its own BAS account (SEK→1930, EUR→1932, USD→1933, etc.). The mapping engine already honors IngestOptions.settlementAccount (lib/bookkeeping/mapping-engine.ts:55-57) so the wiring is small: - StoredAccount gains an optional ledger_account field (no migration — bank_connections.accounts_data is already JSONB). - syncAccountTransactions passes account.ledger_account through as settlementAccount so the bank-side leg routes to the right BAS account. - PATCH /accounts accepts account_mappings, validates 4-digit BAS format, and verifies each ledger_account exists in chart_of_accounts before persisting. Selection edits without account_mappings preserve existing values for back-compat. - AccountPickerDialog shows a per-account "Bokför till konto" combobox populated from the company's 19xx accounts, with currency-based defaults (SEK→1930, EUR→1932, USD→1933, GBP→1934) and a non-blocking warning when two enabled accounts route to the same BAS account with different currencies. Reconciliation still scans 1930 only — foreign-currency accounts skip auto-matching until follow-up PR 4 (filed in the plan). Co-Authored-By: Claude Opus 4.7 (1M context) * fix(enable-banking): address review feedback on PR #487 Two real bugs flagged in review: 1. AccountPickerDialog row wrapped a Radix (which renders as its own