Files
accounted/lib/import/__tests__/account-vat-treatment.test.ts
T
MattssonandClaude Fable 5 86f0b70fdd fix(vat): complete account treatment enforcement (#1593)
* fix(vat): complete account treatment enforcement

* docs(api): refresh account endpoint skill

* fix(mcp): preserve ruta 05 compatibility

* test(vat): seed migration constraint fixtures

* docs(vat): clarify treatment precedence

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 23:45:04 +02:00

148 lines
4.4 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import {
applyVatTreatmentReview,
enrichChangedAccountMappingWithVat,
enrichAccountMappingsWithVat,
} from '../account-vat-treatment'
import type { AccountMapping } from '../types'
function mapping(account: string, name: string): AccountMapping {
return {
sourceAccount: account,
sourceName: name,
targetAccount: account,
targetName: name,
confidence: 1,
matchType: 'exact',
isOverride: false,
}
}
describe('enrichAccountMappingsWithVat', () => {
it('marks label suggestions for user review', () => {
const [result] = enrichAccountMappingsWithVat(
[mapping('4056', 'Inköp varor 25% EU')],
[],
)
expect(result).toMatchObject({
defaultVatTreatment: 'reverse_charge_eu_goods',
defaultVatRate: 0.25,
vatTreatmentSuggested: true,
vatTreatmentReviewed: false,
requiresVatTreatmentReview: true,
})
})
it('keeps an existing account treatment without asking again', () => {
const [result] = enrichAccountMappingsWithVat(
[mapping('3041', 'Försäljning tjänst 25% sv')],
[{
account_number: '3041',
default_vat_treatment: 'standard_25',
default_vat_rate: 0.25,
} as never],
)
expect(result).toMatchObject({
defaultVatTreatment: 'standard_25',
vatTreatmentSuggested: false,
vatTreatmentReviewed: true,
requiresVatTreatmentReview: false,
})
})
it('preserves an existing booking rate when suggesting a missing treatment', () => {
const [result] = enrichAccountMappingsWithVat(
[mapping('3041', 'Försäljning tjänst 25% sv')],
[{
account_number: '3041',
default_vat_treatment: null,
default_vat_rate: 0.12,
} as never],
)
expect(result.defaultVatTreatment).toBe('standard_25')
expect(result.defaultVatRate).toBe(0.12)
})
it('requires review for a suggested class 6 service treatment', () => {
const [result] = enrichAccountMappingsWithVat(
[mapping('6545', 'Inköp tjänster utanför EU 25%')],
[],
)
expect(result).toMatchObject({
defaultVatTreatment: 'reverse_charge_non_eu_services',
requiresVatTreatmentReview: true,
vatTreatmentReviewed: false,
})
})
})
describe('applyVatTreatmentReview', () => {
it('persists a suggestion only after an explicit row confirmation', () => {
const mappings = enrichAccountMappingsWithVat([
mapping('4056', 'Inköp varor 25% EU'),
], [])
expect(mappings[0].vatTreatmentReviewed).toBe(false)
const reviewed = applyVatTreatmentReview(
mappings,
'4056',
mappings[0].defaultVatTreatment ?? null,
mappings[0].defaultVatRate ?? null,
)
expect(reviewed[0]).toMatchObject({
defaultVatTreatment: 'reverse_charge_eu_goods',
vatTreatmentReviewed: true,
vatTreatmentSuggested: false,
})
})
it('clears hidden review state on remap and restores it on identity mapping', () => {
const [suggested] = enrichAccountMappingsWithVat([
mapping('4056', 'Inköp varor 25% EU'),
], [])
const [remapped] = enrichAccountMappingsWithVat([{
...suggested,
targetAccount: '4010',
targetName: 'Inköp material',
}], [])
expect(remapped).toMatchObject({
defaultVatTreatment: null,
requiresVatTreatmentReview: false,
vatTreatmentReviewed: true,
})
const [identity] = enrichAccountMappingsWithVat([{
...remapped,
targetAccount: '4056',
targetName: 'Inköp varor 25% EU',
}], [])
expect(identity).toMatchObject({
defaultVatTreatment: 'reverse_charge_eu_goods',
requiresVatTreatmentReview: true,
vatTreatmentReviewed: false,
})
})
it('preserves another row review when one mapping changes', () => {
const initial = enrichAccountMappingsWithVat([
mapping('3041', 'Försäljning tjänst 25% sv'),
mapping('4056', 'Inköp varor 25% EU'),
], [])
const reviewed = applyVatTreatmentReview(initial, '3041', 'exempt', 0)
const remapped = enrichChangedAccountMappingWithVat(
reviewed.map((item) => item.sourceAccount === '4056'
? { ...item, targetAccount: '4010', targetName: 'Inköp material' }
: item),
'4056',
[],
)
expect(remapped[0]).toMatchObject({
defaultVatTreatment: 'exempt',
defaultVatRate: 0,
vatTreatmentReviewed: true,
})
})
})