Fix/invoice delivery and payment accounts (#1116)
* fix: reconcile annual reports with final closing entries * test: cover annual report depreciation and VAT balances * Merge remote-tracking branch 'origin/main' into fix/usr-fdbck-ch * fix: show exact invoice delivery details * fix: use currency account in invoice emails * fix: address invoice delivery review feedback * fix: harden invoice delivery and payment accounts * test: assert RLS-denied zero-row updates * fix: close remaining invoice compliance gaps * fix: harden invoice archive authorization * fix: close invoice delivery review findings * fix: verify delivery finalization results * fix: cap combined invoice email recipients * fix: close final invoice compliance findings * fix: prevent stale payment account saves * test: prove invoice delivery isolation * fix: close invoice privacy review findings * test: normalize delivery retention dates
This commit is contained in:
+37
@@ -22,12 +22,14 @@ vi.mock('@/lib/bokslut/arsredovisning/model', () => ({
|
||||
}))
|
||||
vi.mock('@/lib/bokslut/arsredovisning/version-service', () => ({
|
||||
createAnnualReportVersion: vi.fn(),
|
||||
hasStatementIntegrityErrors: vi.fn(),
|
||||
listAnnualReportVersions: vi.fn(),
|
||||
}))
|
||||
|
||||
import { buildCanonicalAnnualReport } from '@/lib/bokslut/arsredovisning/model'
|
||||
import {
|
||||
createAnnualReportVersion,
|
||||
hasStatementIntegrityErrors,
|
||||
listAnnualReportVersions,
|
||||
} from '@/lib/bokslut/arsredovisning/version-service'
|
||||
import { GET, POST } from '../route'
|
||||
@@ -57,6 +59,7 @@ function setup() {
|
||||
vi.mocked(buildCanonicalAnnualReport).mockResolvedValue({
|
||||
validation: { ok: true },
|
||||
} as never)
|
||||
vi.mocked(hasStatementIntegrityErrors).mockReturnValue(false)
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -134,6 +137,40 @@ describe('annual report versions route', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it.each(['snapshot', 'finalize'] as const)(
|
||||
'rejects an inconsistent report before creating a %s version',
|
||||
async (action) => {
|
||||
const { enqueue } = setup()
|
||||
enqueue({ data: { id: 'period-1' } })
|
||||
vi.mocked(hasStatementIntegrityErrors).mockReturnValue(true)
|
||||
vi.mocked(buildCanonicalAnnualReport).mockResolvedValue({
|
||||
validation: {
|
||||
ok: false,
|
||||
issues: [{ code: 'AR-RESULT-MISMATCH', severity: 'error' }],
|
||||
},
|
||||
} as never)
|
||||
|
||||
const { status, body } = await parseJsonResponse<{
|
||||
error: { code: string; message: string; message_en: string }
|
||||
}>(
|
||||
await POST(
|
||||
createMockRequest('/x', { method: 'POST', body: { action } }),
|
||||
params,
|
||||
),
|
||||
)
|
||||
|
||||
expect(status).toBe(409)
|
||||
expect(body.error).toEqual(
|
||||
expect.objectContaining({
|
||||
code: 'ARSREDOVISNING_INCOMPLETE',
|
||||
message: expect.any(String),
|
||||
message_en: expect.any(String),
|
||||
}),
|
||||
)
|
||||
expect(createAnnualReportVersion).not.toHaveBeenCalled()
|
||||
},
|
||||
)
|
||||
|
||||
it('accepts a VD as the fastställelseintyg signer', async () => {
|
||||
const { enqueue } = setup()
|
||||
enqueue({ data: { id: 'period-1' } })
|
||||
|
||||
@@ -8,6 +8,7 @@ import { createServiceClient } from '@/lib/supabase/server'
|
||||
import { buildCanonicalAnnualReport } from '@/lib/bokslut/arsredovisning/model'
|
||||
import {
|
||||
createAnnualReportVersion,
|
||||
hasStatementIntegrityErrors,
|
||||
listAnnualReportVersions,
|
||||
} from '@/lib/bokslut/arsredovisning/version-service'
|
||||
|
||||
@@ -83,16 +84,17 @@ export const POST = withRouteContext(
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
if (hasStatementIntegrityErrors(model)) {
|
||||
return errorResponseFromCode('ARSREDOVISNING_INCOMPLETE', log, {
|
||||
requestId,
|
||||
details: model.validation,
|
||||
})
|
||||
}
|
||||
if (validation.data.action === 'finalize' && !model.validation.ok) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: {
|
||||
code: 'ARSREDOVISNING_INCOMPLETE',
|
||||
details: model.validation,
|
||||
},
|
||||
},
|
||||
{ status: 409 },
|
||||
)
|
||||
return errorResponseFromCode('ARSREDOVISNING_INCOMPLETE', log, {
|
||||
requestId,
|
||||
details: model.validation,
|
||||
})
|
||||
}
|
||||
const data = await createAnnualReportVersion(
|
||||
validation.data.action === 'finalize' ? createServiceClient() : supabase,
|
||||
|
||||
Reference in New Issue
Block a user