fix(salary): make pain.001 betalfil generatable (company IBAN + BIC) (#950)
The ISO 20022 pain.001 salary payment file could never be generated: the route required company_settings.iban/bic, but no settings screen wrote those columns, so every request returned 400. The specific reason was also swallowed by getErrorMessage (isSwedishUserMessage did not know "krävs"/"saknar"), surfacing only the generic "Förfrågan innehåller ogiltiga uppgifter" (issue #945). - Add IBAN + BIC inputs to Settings > Fakturering > Bankuppgifter. BIC auto-derives from the clearing number / bank already entered, so in practice only the IBAN is typed. Validated client- and server-side. - Route requires the company IBAN (canonical debtor form every Swedish bank accepts) and derives the BIC, with clear actionable errors. - Employees are unchanged: domestic clearing + account (BBAN), which is what Swedish payroll collects. Only the company (debtor) uses IBAN. - getErrorMessage recognizes "krävs"/"saknar" so payment-file reasons surface instead of the generic 400. Fixes #945 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
bacc5914af
commit
c1ea0d9bf2
@@ -5,6 +5,8 @@ import {
|
||||
isValidAccount,
|
||||
validateEmployeeBankAccount,
|
||||
lookupBankByClearing,
|
||||
lookupBicByClearing,
|
||||
lookupBicByBankName,
|
||||
} from '@/lib/salary/payment/bank-account'
|
||||
|
||||
describe('normalizeBankNumber', () => {
|
||||
@@ -100,3 +102,37 @@ describe('lookupBankByClearing', () => {
|
||||
expect(lookupBankByClearing('')).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('lookupBicByClearing', () => {
|
||||
it('maps clearing numbers to the bank BIC', () => {
|
||||
expect(lookupBicByClearing('5000')).toBe('ESSESESS') // SEB
|
||||
expect(lookupBicByClearing('6789')).toBe('HANDSESS') // Handelsbanken
|
||||
expect(lookupBicByClearing('7123')).toBe('SWEDSESS') // Swedbank
|
||||
expect(lookupBicByClearing('3000')).toBe('NDEASESS') // Nordea
|
||||
expect(lookupBicByClearing('1234')).toBe('DABASESX') // Danske Bank
|
||||
})
|
||||
it('maps a 5-digit Swedbank clearing via its 8xxx prefix', () => {
|
||||
expect(lookupBicByClearing('83279')).toBe('SWEDSESS')
|
||||
})
|
||||
it('returns null for unknown ranges rather than guessing a BIC', () => {
|
||||
expect(lookupBicByClearing('9999')).toBeNull()
|
||||
expect(lookupBicByClearing('123')).toBeNull()
|
||||
expect(lookupBicByClearing('')).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('lookupBicByBankName', () => {
|
||||
it('resolves banks outside the clearing table by name', () => {
|
||||
expect(lookupBicByBankName('Länsförsäkringar')).toBe('ELLFSESS')
|
||||
expect(lookupBicByBankName('Skandiabanken')).toBe('SKIASESS')
|
||||
})
|
||||
it('matches on a normalized substring', () => {
|
||||
expect(lookupBicByBankName('Danske Bank Sverige')).toBe('DABASESX')
|
||||
expect(lookupBicByBankName(' SEB ')).toBe('ESSESESS')
|
||||
})
|
||||
it('returns null for unknown or empty names', () => {
|
||||
expect(lookupBicByBankName('Min Lokala Bank')).toBeNull()
|
||||
expect(lookupBicByBankName('')).toBeNull()
|
||||
expect(lookupBicByBankName(null)).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user