feat(settings): standard verifikationsserier for new companies, opt-in action for existing (#2358)
* feat(settings): standard verifikationsserier for new companies, opt-in action for existing (#2184) A new company_settings row now defaults to the standard series set (A manual/bank, B kundfakturor, C inbetalningar, D leverantörsfakturor, E utbetalningar, H periodisering, I bokslut, K lön, L kontantfaktura, M moms) instead of everything on A. The set lives once, as the exhaustive STANDARD_VOUCHER_SERIES_MAP in the resolver; a pg-real test holds the column default equal to it and to the source_type CHECK. Existing rows are not remapped: the per-type settings form gets an "Använd standarduppsättningen" action that fills the set for review and save through the existing PUT, so the switch is a deliberate, audited act rather than a mid-year numbering change nobody decided. Payment rows bound to the other bokföringsmetod are dimmed, not hidden. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvMaHcTnwAfxzgYD1fGYX1 * test(bookkeeping): fresh company_settings row asserts the standard series set, not all-A voucher-series-defaults.pg.test.ts codified the pre-#2184 column default (every source type on A). Migration 20260906210500 replaces that default with the standard set, so the "freshly inserted row" case now asserts the representative letters and full equality with STANDARD_VOUCHER_SERIES_MAP. The explicit-override case keeps proving a company's own layout replaces the default wholesale. No other pg or tool test asserted on the old map. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvMaHcTnwAfxzgYD1fGYX1 --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
Jakob Wennberg
parent
4fce2d7b94
commit
bf7773d74b
@@ -42,6 +42,7 @@ vi.mock('@/lib/tax/deadline-generator', async (importOriginal) => {
|
||||
|
||||
import { PUT } from '../route'
|
||||
import { regenerateTaxDeadlinesForUser } from '@/lib/tax/deadline-generator'
|
||||
import { STANDARD_VOUCHER_SERIES_MAP } from '@/lib/bookkeeping/voucher-series-resolver'
|
||||
|
||||
describe('PUT /api/settings', () => {
|
||||
beforeEach(() => {
|
||||
@@ -123,6 +124,31 @@ describe('PUT /api/settings', () => {
|
||||
expect(findCall('company_settings', 'update')?.[0]).toEqual({ voucher_series_labels: { L: 'Lön' } })
|
||||
})
|
||||
|
||||
it('stores the standard voucher series set as sent (Använd standarduppsättningen)', async () => {
|
||||
const standard = { ...STANDARD_VOUCHER_SERIES_MAP }
|
||||
enqueueMany([
|
||||
{ data: { entity_type: 'aktiebolag', onboarding_complete: true } }, // fetch oldSettings
|
||||
{ data: { id: 's1', default_voucher_series_per_source_type: standard } }, // update ... returning
|
||||
{ data: null, count: 5 }, // deadlines count
|
||||
])
|
||||
|
||||
const request = createMockRequest('/api/settings', {
|
||||
method: 'PUT',
|
||||
body: { default_voucher_series_per_source_type: standard },
|
||||
})
|
||||
const response = await PUT(request, { params: Promise.resolve({}) })
|
||||
const { status, body } = await parseJsonResponse<{
|
||||
data: { default_voucher_series_per_source_type: Record<string, string> }
|
||||
}>(response)
|
||||
|
||||
expect(status).toBe(200)
|
||||
expect(body.data.default_voucher_series_per_source_type).toEqual(standard)
|
||||
// Every source type, storno and correction included, reaches the row unchanged.
|
||||
expect(findCall('company_settings', 'update')?.[0]).toEqual({
|
||||
default_voucher_series_per_source_type: standard,
|
||||
})
|
||||
})
|
||||
|
||||
it('rejects a voucher_series_labels key that is not a single uppercase letter', async () => {
|
||||
const request = createMockRequest('/api/settings', {
|
||||
method: 'PUT',
|
||||
|
||||
Reference in New Issue
Block a user