diff --git a/DECISIONS.md b/DECISIONS.md index 479a17d8..ee20fe31 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -741,4 +741,5 @@ One line per decision: `[YYYY-MM-DD] : `. Appended by agents and [2026-08-01] Out-of-order SIE IB activity is bounded by the target fiscal-period end, not its start: this excludes later-first imports while preserving same-period continuation suppression; successor IB resync checks the current error state plus a real target-period entry because result.success is finalized later, keeping replacement on a new engine voucher plus storno without letting a no-op import succeed through resync alone. [2026-08-01] Successor SIE IB replacement uses a specialized engine RPC instead of loosening the owner-only generic relink RPC: non-viewer members and scoped service-role imports are supported, while one period-row lock and expected-pointer CAS make the replacement voucher, storno, reversal status, pointer swap, and voucher sequence increments commit or roll back together. [2026-08-02] Out-of-order SIE IB resync requires exact date adjacency: the nearest later fiscal period can sit beyond a missing middle year, and replacing its authoritative IB with a non-adjacent UB would make that later period temporarily wrong until the gap was imported. +[2026-08-03] Issue #1360 keeps EUR annual reports fail-closed at general eligibility rather than only digital filing: the ledger and annual-report model are SEK-denominated, so allowing a EUR profile to lock a paper version would mislabel SEK amounts; full EUR support requires a company accounting-currency model across the ledger, report builders, and iXBRL. [2026-08-03] Issue #1267 localizes the latest-posted-voucher label in the web views while PDF and spreadsheet exports remain Swedish: translating one export label would create mixed-language files, so full export localization stays a separate surface-wide change. diff --git a/lib/bokslut/arsredovisning/__tests__/completeness.test.ts b/lib/bokslut/arsredovisning/__tests__/completeness.test.ts index 1826671a..329bd945 100644 --- a/lib/bokslut/arsredovisning/__tests__/completeness.test.ts +++ b/lib/bokslut/arsredovisning/__tests__/completeness.test.ts @@ -104,6 +104,28 @@ describe('validateAnnualReportCompleteness', () => { expect(result.error_count).toBe(0) }) + it('keeps an unsupported reporting currency blocking at signing stage', () => { + const value = input('signing') + const currencyIssue = { + code: 'AR-SCOPE-CURRENCY', + severity: 'error' as const, + section: 'scope' as const, + message: 'Accounteds årsredovisningsflöde stöder ännu endast SEK som redovisningsvaluta.', + } + value.eligibility = { + ...eligibility, + k2_eligible: false, + digital_filing_eligible: false, + issues: [currencyIssue], + digital_issues: [currencyIssue], + } + + const result = validateAnnualReportCompleteness(value) + + expect(result.ok).toBe(false) + expect(result.issues).toEqual(expect.arrayContaining([currencyIssue])) + }) + it('does not infer an unanswered disclosure confirmation', () => { const value = input('draft') value.disclosures.securities_pledged_confirmed = false diff --git a/lib/bokslut/arsredovisning/__tests__/eligibility.test.ts b/lib/bokslut/arsredovisning/__tests__/eligibility.test.ts index 02974127..037b1434 100644 --- a/lib/bokslut/arsredovisning/__tests__/eligibility.test.ts +++ b/lib/bokslut/arsredovisning/__tests__/eligibility.test.ts @@ -39,6 +39,33 @@ describe('evaluateAnnualReportEligibility', () => { expect(result.issues).toEqual([]) }) + it('blocks EUR reports before they can be finalized or filed digitally', () => { + const profile = completeProfile() + profile.reporting_currency = 'EUR' + const result = evaluateAnnualReportEligibility({ + entityType: 'aktiebolag', + framework: 'k2', + periodStart: '2026-01-01', + periodEnd: '2026-12-31', + profile, + metrics, + }) + + expect(result.k2_eligible).toBe(false) + expect(result.digital_filing_eligible).toBe(false) + expect(result.issues).toEqual( + expect.arrayContaining([ + expect.objectContaining({ code: 'AR-SCOPE-CURRENCY', severity: 'error' }), + ]), + ) + expect(result.digital_issues.filter((item) => item.code === 'AR-SCOPE-CURRENCY')).toHaveLength( + 1, + ) + expect( + result.digital_issues.filter((item) => item.code === 'AR-DIGITAL-CURRENCY'), + ).toHaveLength(0) + }) + it('does not treat unanswered legal facts as false', () => { const result = evaluateAnnualReportEligibility({ entityType: 'aktiebolag', diff --git a/lib/bokslut/arsredovisning/eligibility.ts b/lib/bokslut/arsredovisning/eligibility.ts index 0255067e..e29fd9d1 100644 --- a/lib/bokslut/arsredovisning/eligibility.ts +++ b/lib/bokslut/arsredovisning/eligibility.ts @@ -279,6 +279,16 @@ export function evaluateAnnualReportEligibility( } } + if (profile.reporting_currency !== 'SEK') { + issues.push( + issue( + 'AR-SCOPE-CURRENCY', + 'Accounteds årsredovisningsflöde stöder ännu endast SEK som redovisningsvaluta.', + 'Upprätta årsredovisningen i ett system som stöder euro som redovisningsvaluta.', + ), + ) + } + const k2Eligible = input.framework === 'k2' && issues.every((item) => item.severity !== 'error') const digitalIssues = [...issues] if (input.framework !== 'k2') { @@ -290,14 +300,6 @@ export function evaluateAnnualReportEligibility( ), ) } - if (profile.reporting_currency !== 'SEK') { - digitalIssues.push( - issue( - 'AR-DIGITAL-CURRENCY', - 'Digital inlämning stöds ännu endast för årsredovisningar i SEK.', - ), - ) - } if (profile.auditor_report_required === null) { digitalIssues.push( issue(