Bug 642555: [master] [NL] SEPA Direct Debit Export (Report 11000015 – pain.008.001.08) exports unstructured address instead of structured#9609
Conversation
| AddElement(XMLNodeCurr, 'PstlAdr', '', '', XMLNewChild); | ||
| XMLNodeCurr := XMLNewChild; | ||
| AddElement(XMLNodeCurr, 'AdrLine', CompanyInfo.Address, '', XMLNewChild); | ||
| StreetName := CopyStr(DelChr(CompanyInfo.Address, '<>') + ' ' + DelChr(CompanyInfo."Address 2", '<>'), 1, MaxStrLen(StreetName)); |
There was a problem hiding this comment.
In the UltmtCdtr (Company Information) and UltmtDbtr (Customer) structured address blocks, StreetName is built as DelChr(Address, '<>') + ' ' + DelChr("Address 2", '<>'). When "Address 2" is blank (the common case), this unconditionally appends a literal space, producing a StrtNm value with a trailing space in the exported SEPA XML (e.g. 'Main Street 1 ' instead of 'Main Street 1'). A knowledgeable reviewer would expect the separator to be added only when Address 2 is non-empty, matching how the codebase already treats optional components elsewhere in this same procedure (e.g. the StreetName/PostalCode/TownName <> '' guards before emitting each element). The new automated test (VerifyStructuredDebtorAddressInDirectDebitExport / the UltmtCdtr and UltmtDbtr assertions in TestExportSEPAISO20022) does not catch this because it recomputes the same concatenation rather than asserting against a fixed expected string.
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.12.4
| AddElement(XMLNodeCurr, 'PstlAdr', '', '', XMLNewChild); | ||
| XMLNodeCurr := XMLNewChild; | ||
|
|
||
| StreetName := CopyStr(PaymentHistoryLine."Account Holder Address", 1, MaxStrLen(StreetName)); |
There was a problem hiding this comment.
In AddTrxInformation, the debtor (Dbtr) structured postal address fields StreetName/PostalCode/TownName are populated directly from PaymentHistoryLine."Account Holder Address"/"Account Holder Post Code"/"Account Holder City" without DelChr(..., '<>') sanitization. Every other structured-address block added in this same change (Cdtr from Bank Account, UltmtCdtr from Company Information, UltmtDbtr from Customer) strips '<' and '>' with DelChr before assigning to the same StrtNm/PstCd/TwnNm elements. This is an inconsistency introduced by the diff: the debtor block is the only one of the four that skips the sanitization step, so literal '<' or '>' characters in the account holder's address/post code/city could reach the exported SEPA XML unsanitized (impact would otherwise be major, but per policy agent findings are capped at minor since no knowledge file backs this rule).
Recommendation:
- sanitize with the same DelChr(field, '<>') pattern used in the other three blocks (or rely on the already-sanitized AddrLine[2]/AddrLine[3] returned by GetAccHolderPostalAddr, which already applies DelChr) for consistency.
Suggested fix (apply manually — could not be anchored as a one-click suggestion):
StreetName := CopyStr(DelChr(PaymentHistoryLine."Account Holder Address", '<>'), 1, MaxStrLen(StreetName));
PostalCode := CopyStr(DelChr(PaymentHistoryLine."Account Holder Post Code", '<>'), 1, MaxStrLen(PostalCode));
TownName := CopyStr(DelChr(PaymentHistoryLine."Account Holder City", '<>'), 1, MaxStrLen(TownName));👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.12.4
ISSUE:
The Dutch SEPA Direct Debit export (report 11000015 "SEPA ISO20022 Pain 008.001.08") wrote postal addresses as a single unstructured element. Banks require the address to be provided in structured form.
SOLUTION:
The debtor, creditor, ultimate creditor and ultimate debtor addresses are now exported as structured elements — (street), (post code), (town) and (country) — instead of a single . Each element is only written when it has a value.
Fixes AB#642555