fix(payments): correct pain.001 dialect per Swedbank Validex run (#1507)

* fix(payments): correct pain.001 dialect per Swedbank Validex run

Real MIG validation (eken.validex.net) rejected the first generated file
on four rules: character set (e-acute in names), missing InitgPty OrgId,
BGNR creditors demanding a BGNR debtor, and Strd lacking RfrdDocAmt.
Names and messages now transliterate to the MIG set, the org number is
required at batch creation (settings first, companies fallback), bankgiro
payees debit the company bankgiro in their own PmtInf group when one
exists (IBAN otherwise, with Cdtr PstlAdr/Ctry SE always present), and
structured OCR remittance repeats the amount as RfrdDocAmt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(payments): review quick wins on the MIG pass

NFC-normalize before transliteration (decomposed marks from PDF-pasted
names fold to the precomposed forms the map knows), a dedicated settings
link label for the missing-org state, and coverage for an invalid
company bankgiro being dropped from the debtor snapshot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-08-10 20:53:43 +02:00
committed by GitHub
parent f0bedc14af
commit fea5dfd1f9
9 changed files with 281 additions and 54 deletions
@@ -38,7 +38,7 @@ interface Preview {
excluded: Array<{ id: string; reason: string }>
total: number
debtor_ok: boolean
debtor_missing?: 'iban' | 'bic'
debtor_missing?: 'iban' | 'bic' | 'org_number'
}
interface PaymentFileDialogProps {
@@ -220,10 +220,18 @@ export default function PaymentFileDialog({
) : (
<div className="space-y-4">
{!preview.debtor_ok && (
<AttnLine action={{ label: t('debtor_missing_link'), href: '/settings/invoicing' }}>
<AttnLine
action={
preview.debtor_missing === 'org_number'
? { label: t('debtor_missing_org_link'), href: '/settings/company' }
: { label: t('debtor_missing_link'), href: '/settings/invoicing' }
}
>
{preview.debtor_missing === 'bic'
? t('debtor_missing_bic')
: t('debtor_missing_iban')}
: preview.debtor_missing === 'org_number'
? t('debtor_missing_org')
: t('debtor_missing_iban')}
</AttnLine>
)}