b5e908f9ea feat(reconciliation): explain the difference instead of just printing it (#1737)
The bankavstämning card showed three movement sums and a red difference,
leaving the user to work out what the difference consisted of. The page
already knew, exactly: every krona of it is (unmatched bank rows) minus
(unmatched vouchers). Verified on prod for Arcim 1930 over 2025-07-17..
2026-08-20: 403 565,42 bank, 332 680,93 booked, 70 884,49 difference, of
which -277 799,92 sits in 74 unmatched transactions and -348 684,41 in 4
unmatched vouchers, leaving exactly 0,00 unexplained.

Engine: getReconciliationStatus gains unmatched_transaction_total,
unmatched_gl_line_total and unexplained_difference. The residual, not the
raw difference, is the figure that can mean something is wrong: a
difference is expected to be large mid-year and says nothing on its own.
unmatched_gl_line_total is null rather than 0 on a foreign account, whose
candidate lines carry no amount in that currency, and the card falls back
to the flat figures there.

Also fixes the candidate fetch's window: it used the caller's raw dateFrom
while both other sides were clamped to the opening-balance floor, so a
window opening before the account's IB (the v1 endpoint's default, or any
multi-year range) counted vouchers from a period the reconciliation
deliberately drops.

UI: the card becomes a bridge whose two middle rows both explain the
number and navigate to the list that resolves them, above a matched/total
progress rule. Three stacked paragraphs of legal prose collapse into one
line plus a tooltip, keeping the amounts on screen. The permanent
destructive "Ej avstämd" badge is gone: being mid-year and unreconciled is
the normal state, so it marked nothing (convention 5); Avstämd is now what
gets the chip.

The unmatched list becomes one line per transaction (convention 4). It
rendered a ~230px card per row, each with an always-open, always-empty
match field: for a real backlog that is thousands of pixels of empty
search boxes, and it gave the rarest action the only visible affordance
while bokför and ignorera hid behind the row menu. The picker, and its
ranked-candidate fetch, now run for the one row the user opens.

A non-zero residual is stated factually, never in destructive red:
measured over the 206 single-1930-account companies with >=10
transactions, 136 are exactly 0,00 and 63 are >=100 kr out, dominated by
ledger lines the candidate RPC hides (posted/storno on 127 companies)
rather than user error. Surfacing those is follow-up work.

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 12:41:55 +02:00
2026-07-21 23:00:15 +02:00
2026-06-12 16:35:30 +02:00
2026-07-21 23:00:15 +02:00
2026-07-24 15:03:50 +02:00
2026-07-21 23:00:15 +02:00
2026-07-05 03:05:09 +02:00
2026-07-24 15:03:50 +02:00
2026-07-23 16:16:55 +02:00
2026-07-05 03:05:09 +02:00
2026-07-05 03:05:09 +02:00

Accounted

Open-source Swedish accounting software for sole traders (enskild firma) and limited companies (aktiebolag). Double-entry bookkeeping that complies with Swedish accounting law, built to be operated by you or by your AI agent.

License: AGPL-3.0-or-later Core Build pg-real tests Docker

Website · Hosted app · Documentation

Why Accounted?

Compliant by construction. Accounted implements double-entry bookkeeping under Swedish accounting law (Bokföringslagen). Voucher immutability, sequential voucher numbering, period locks, and 7-year document retention are enforced by database triggers, not by convention. Corrections are made the legal way, with reversal entries (storno), never by editing history. See ARCHITECTURE.md for how.

Agent-native. The full bookkeeping engine is exposed as 100+ MCP (Model Context Protocol) tools with scoped API keys, so an AI agent can do the books in Accounted: categorize transactions, draft vouchers, reconcile periods, and prepare declarations. Posting is staged for human approval, so the agent proposes and you decide.

Yours to run. AGPL-3.0 licensed and fully self-hostable with Docker and Supabase. Use the hosted version at app.gnubok.se or run your own.

Features

  • Double-entry bookkeeping -- BAS 2026 chart of accounts, draft/commit workflow, sequential voucher numbering
  • Invoicing -- Create, send, and track invoices with mixed VAT rates and PDF generation
  • Bank reconciliation -- PSD2 bank connection via Enable Banking, 4-pass automatic matching
  • VAT declaration -- SKV 4700 form mapping, per-rate breakdown, EU/export handling
  • Tax reports -- NE-bilaga, INK2, SRU export for Skatteverket
  • Payroll -- Salary runs, payslips, and AGI (arbetsgivardeklaration) employer declarations
  • Supplier invoices -- Registration, payment tracking, input VAT deduction
  • Document archive -- SHA-256 integrity, 7-year retention enforcement, full archive ZIP export
  • SIE import/export -- Standard Swedish accounting interchange format
  • Agent access (MCP) -- 100+ bookkeeping tools over the Model Context Protocol, with scoped API keys and staged approvals
  • Extension system -- Opt-in plugins for AI categorization, receipt OCR, email, calendar, and more

Self-Hosting

git clone https://github.com/erp-mafia/accounted.git
cd accounted
./setup.sh              # Prompts for Supabase credentials, generates .env
docker compose up -d

You need a Supabase project and must apply the database migrations before first use. See docs/SELF-HOSTING.md for the full step-by-step guide, including Supabase setup, auth configuration, optional features (AI, email, push notifications), and troubleshooting.

Development Setup

Prerequisites: Node.js 20+, a Supabase project.

npm install
npm run dev       # Start dev server (auto-generates extension registry)
npm test          # Run tests
npm run build     # Production build
npm run lint      # ESLint

See CONTRIBUTING.md for the full development workflow.

Tech Stack

  • Framework: Next.js 16 (App Router), React 19, TypeScript (strict)
  • Database: Supabase (PostgreSQL + Row Level Security + email/password auth + TOTP MFA)
  • Styling: Tailwind CSS 4 + shadcn/ui
  • Integrations: Enable Banking (PSD2), Anthropic SDK, LangChain, OpenAI, Resend, JSZip

Documentation

Community

Contributing

Contributions are welcome. See CONTRIBUTING.md for the full guide.

All commits require a DCO sign-off (git commit -s).

License

AGPL-3.0-or-later with an extension exception: third-party extensions that interact solely through the documented Extension API may be licensed under any terms, including proprietary. See LICENSE for details and NOTICE for third-party attributions.

S
Description
Accounted — svensk bokföringsmotor (AGPL, BAS 2026, BFL-compliant, 150+ MCP tools). Finance-kapacitet brevet ERPNext. ADR-ENGAGEMENT-001-tillägg.
Readme AGPL-3.0
56 MiB
Languages
TypeScript 93%
PLpgSQL 5.8%
JavaScript 0.4%
HTML 0.3%
MDX 0.2%
Other 0.1%