fix(bookkeeping): remove false 1580 tax-receivable label, let company account names win (#1968)

The hardcoded ACCOUNT_DESCRIPTIONS entry labeled 1580 'Fordran for skatt'
with a Skatteverket explanation. That is wrong on both counts: tax
receivables are 1640 (skattefordringar) / 1650 (momsfordran), and 1580
was traditionally 'Fordringar for kontokort och kuponger', which BAS has
since moved to 1686 (why 1580 is excluded from our BAS 2026 catalog).
Reported by a user who books card/Swish settlements there.

Also flip AccountNumber display precedence to the company's own
account_name over the hardcoded reference name: chart rows are
user-editable data and must not be visually overridden by our copy.
The tooltip keeps showing the BAS reference info.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mattsson
2026-08-26 23:11:05 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent dae0aac26a
commit ff88e3de05
4 changed files with 17 additions and 7 deletions
+1
View File
@@ -1287,3 +1287,4 @@ One line per decision: `[YYYY-MM-DD] <decision>: <why>`. Appended by agents and
[2026-08-26] Dashboard layout diet (responsiveness plan B4): the four nav-visibility probes (WooCommerce/Shopify connections, webshop orders, mileage trips) became one SECURITY INVOKER RPC get_dashboard_nav_flags (20260826120000) rather than a client-side badge hook, because the flags gate whole nav rows and loading them after mount pops rows into the sidebar; RLS still applies inside the function. The layout's getDashboardAuthContext now verifies the JWT locally (lib/auth/claims.ts, shared with requireAuth) with getUser() as the fallback: the proxy already did the per-request revocation check, so the layout's own getUser() was a second Supabase Auth round trip on every hard load. The user-keyed reads (profile, preferences, memberships) moved into the company-resolution wave and the memberships join now supplies the active company row and role, so the layout went from ~20 network calls in 4 waves to ~12 in 2. The memberships-with-embedded-settings single query was NOT attempted: the PostgREST embed shape was unverified and the settings-names query is parallel anyway.
[2026-08-26] OAuth consent pre-checks ALL scopes (one-click, list collapsed in details): founder call after the read-only default dead-ended agent flows; defensible because every write is staged for approval, rows stay untickable, grant revocable.
[2026-08-26] accounting_method optional with form default (AB=accrual, EF=cash) in CompanySetupSchema/planCompanySetup: founder call to cut agent onboarding input to orgnr + moms period; the default is flagged (accounting_method_defaulted) and must be read back in the preview, never silent.
[2026-08-26] Removed the 1580 entry from ACCOUNT_DESCRIPTIONS and flipped AccountNumber name precedence to DB-name-first: the entry falsely labeled 1580 'Fordran for skatt' (tax receivables are 1640/1650; 1580 was traditionally card/coupon receivables, moved by BAS to 1686), and the hardcoded name silently overrode users' own kontoplan names. No replacement entry: 1580 is deliberately off-catalog, so companies with a legacy 1580 now see their own account name.
+4 -1
View File
@@ -46,7 +46,10 @@ export function AccountNumber({
// descriptions for non-hardcoded accounts are available.
useBasReference()
const desc = getAccountDescription(number)
const displayName = desc?.name ?? name
// The company's own account name wins over the BAS reference name: a chart
// row is user-editable data and must never be visually overridden by our
// hardcoded copy. The tooltip still shows the BAS name as reference.
const displayName = name || desc?.name
const numberElement = (
<span
@@ -14,6 +14,13 @@ describe('account-descriptions', () => {
expect(getAccountDescription('9999')).toBeUndefined()
expect(getAccountDescription('')).toBeUndefined()
})
it('has no entry for 1580 (removed from BAS; was mislabeled as tax receivable)', () => {
// Tax receivables are 1640/1650. Card/coupon receivables moved from
// 1580 to 1686. 1580 must stay undefined so a company's own account
// name is what renders.
expect(getAccountDescription('1580')).toBeUndefined()
})
})
describe('data completeness', () => {
+5 -6
View File
@@ -18,12 +18,11 @@ const ACCOUNT_DESCRIPTIONS: Record<string, AccountDescription> = {
type: 'asset',
explanation: 'Pengar som kunder är skyldiga dig för skickade fakturor som inte betalats ännu.',
},
'1580': {
name: 'Fordran för skatt',
classLabel: 'Tillgångar',
type: 'asset',
explanation: 'Pengar du har att fordra från Skatteverket, t.ex. överskjutande moms.',
},
// 1580 is intentionally absent: BAS moved card/coupon acquirer receivables
// from 1580 to 1686, and 1580 is excluded from the BAS 2026 catalog as
// non-standard (see bas-reference.test.ts). A hardcoded entry here once
// mislabeled it as a tax receivable (that is 1640/1650); companies with a
// legacy 1580 see their own account name instead.
'1630': {
name: 'Skattekonto',
classLabel: 'Tillgångar',