* feat(bookkeeping): show per-account saldo on journal entry form
Adds a "Saldo" column to the journal entry form so bookkeepers can see
the current balance of each account as of the entry date while drafting
a voucher. Useful context for booking bank withdrawals, VAT clearings,
and other balance-sensitive operations.
- New GET /api/bookkeeping/account-balances?accounts=...&as_of=...
returns per-account net (debit - credit) over posted entries up to
and including the requested date. Batched in chunks of 200 entry IDs
to stay under PostgREST IN-list limits.
- JournalEntryForm fetches balances debounced 150ms on changes to the
set of selected account numbers or the entry date; carries forward
previously-known values so the cell doesn't flash to a skeleton on
re-fetch.
- Saldo is reference-only: it reflects "balance before this entry" and
intentionally ignores the draft lines the user is currently editing.
- Renders in both desktop (table column) and mobile (per-line caption)
layouts. Tabular-nums, muted, right-aligned.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(bookkeeping): correct saldo semantics — IB + period-only, BS vs P&L
Address Swedish compliance review on PR #562:
1. P&L accounts (class 3-8) no longer show a since-inception cumulative
sum. They reset each räkenskapsår per BFNAR 2013:2; the saldo now
reflects current-period activity only, matching trial-balance
semantics. BS accounts (class 1-2) continue to include IB.
2. Opening balances are now sourced via the canonical
getOpeningBalances() helper, which reads the explicit
opening_balance_entry_id set by year-end closing or SIE import.
Previously, summing journal_entry_lines from inception returned 0
for SIE-imported companies whose IB lives in a separate entry that
the old query happened to include — and the wrong value once
year-end ran and an OB entry was set without exclusion logic.
3. Relabel "Saldo" -> "Saldo (före)" / "Balance (before)" so the UI
communicates that the figure excludes the draft being edited
(BFNAR 2013:2 kap 8 self-documentation requirement).
4. Stop forwarding raw Supabase error.message to the client; log
server-side via the structured logger and return a generic
'Internal server error' to avoid leaking schema details.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(bookkeeping): reject future as_of dates on account-balances endpoint
Both compliance reviewers on PR #562 flagged this independently: a
future as_of date would include posted entries dated after today in
the activity window, producing a misleading "balance before this
entry" hint that could drive incorrect verifikat entries
(swedish-compliance-review-bot) or be used for future-date probing
(SOC 2 PI1.1, GDPR Art.25(2)).
- AccountBalancesQuerySchema.as_of now refines to <= today.
- JournalEntryForm collapses the loading skeleton to 0 on any non-OK
response so the saldo column doesn't get stuck spinning when a
user enters a future entry_date (which the form's separate period
validation already handles).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(bookkeeping): compare as_of guard against Europe/Stockholm date
swedish-compliance-review-bot caught this on the previous fix: the
future-date guard used new Date().toISOString().slice(0, 10), which is
UTC. Between 00:00–02:00 CET (or 00:00–03:00 CEST), a Swedish
bookkeeper's local "today" is one day ahead of UTC, so entering their
Stockholm-local date would be rejected as a future date.
Compare against Europe/Stockholm-local date via toLocaleDateString
('sv-SE'), which renders YYYY-MM-DD natively, so string comparison
remains correct across DST.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: add language preference for customers to support invoice localization
- Introduced language support for invoices, allowing customers to choose between Swedish and English.
- Updated invoice PDF generation to reflect the selected language for titles, labels, and messages.
- Enhanced email templates to generate content in the customer's preferred language.
- Added migration to include a language column in the customers table with a default value of Swedish.
- Updated tests to verify correct language usage in invoice emails and PDFs.
* fix: debounce API requests in InvoicePreviewCard and update F-skatt terminology in email templates
* Fixed user issues
* feat: add personal_number column to customers for individual identification
* feat: add personal_number field to makeCustomer function for enhanced customer identification
* feat: add personal_number column with constraint check for customer identification
* feat: add user locale preference to user_preferences table
- Introduced a new column 'locale' in the user_preferences table to store per-user UI language preferences.
- Added a CHECK constraint to ensure only supported locales ('sv', 'en') are allowed.
- Triggered a schema reload notification for the changes.
chore: declare CSS module support in TypeScript
- Added a declaration for CSS modules in globals.d.ts to enable TypeScript support for importing CSS files.
* feat: add Swish as an invoice payment method in company settings