[PEPPOL] Use Swedish organisation number for EndpointID under scheme 0007#8646
[PEPPOL] Use Swedish organisation number for EndpointID under scheme 0007#8646Franco111000 wants to merge 3 commits into
Conversation
PEPPOL BIS 3.0 scheme 0007 (SE:ORGNR) requires the 10-digit Swedish organisation number, but the EndpointID and PartyLegalEntity CompanyID carried the full 14-char VAT (SE...01), which access points reject (PEPPOL-COMMON-R049). Extract the organisation number for SE parties whose Country/Region VAT Scheme is 0007, leaving the PartyTaxScheme VAT identifier and all other countries unchanged. Add SE coverage to the PEPPOL BIS billing tests.
| var | ||
| DigitsOnly: Text; | ||
| begin | ||
| DigitsOnly := DelChr(VATRegistrationNo, '=', DelChr(VATRegistrationNo, '=', '0123456789')); |
There was a problem hiding this comment.
Nested DelChr digit-extraction is non-obvious
The double-nested DelChr(x, '=', DelChr(x, '=', '0123456789')) pattern — where the inner call extracts the non-digit mask and the outer call removes it — relies on an implicit BC behaviour that is easy to misread, and any future maintainer touching this line may accidentally invert the arguments.
Recommendation:
- Extract the pattern into a clearly named helper, or document it with an inline comment explaining the two-step inversion so its correctness is immediately obvious.
| DigitsOnly := DelChr(VATRegistrationNo, '=', DelChr(VATRegistrationNo, '=', '0123456789')); | |
| // Inner DelChr removes all digits, leaving only non-digit chars as the mask. | |
| // Outer DelChr removes those non-digit chars from the original, leaving only digits. | |
| DigitsOnly := DelChr(VATRegistrationNo, '=', DelChr(VATRegistrationNo, '=', '0123456789')); |
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
There was a problem hiding this comment.
Good call, thanks. Added a comment in b4b5c7604 explaining the two-step DelChr: the inner call builds the non-digit mask, the outer call removes it, leaving only the digits.
| DigitsOnly := DelChr(VATRegistrationNo, '=', DelChr(VATRegistrationNo, '=', '0123456789')); | ||
| if StrLen(DigitsOnly) >= 10 then | ||
| exit(CopyStr(DigitsOnly, 1, 10)); | ||
| exit(VATRegistrationNo); |
There was a problem hiding this comment.
Silent fallback on malformed Swedish org number
When GetSwedishOrgNo cannot extract 10 or more digits from the VAT registration number, it silently returns the raw input unchanged. This could produce an invalid PEPPOL XML document (wrong-length or non-numeric identifier under scheme 0007) with no error surfaced to the user.
Recommendation:
- Raise an error or at minimum log a warning when fewer than 10 digits are found, so the operator is alerted to fix the VAT registration number rather than sending a silently malformed document.
| exit(VATRegistrationNo); | |
| local procedure GetSwedishOrgNo(VATRegistrationNo: Text): Text | |
| var | |
| DigitsOnly: Text; | |
| begin | |
| DigitsOnly := DelChr(VATRegistrationNo, '=', DelChr(VATRegistrationNo, '=', '0123456789')); | |
| if StrLen(DigitsOnly) >= 10 then | |
| exit(CopyStr(DigitsOnly, 1, 10)); | |
| Error('Swedish organisation number could not be derived from VAT Registration No. ''%1'': expected at least 10 digits.', VATRegistrationNo); | |
| end; |
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
There was a problem hiding this comment.
Thanks. This is deliberate. GetSwedishOrgNo is a low-level formatter called for both the supplier and the customer endpoints during export, mirroring the existing FormatVATRegistrationNo helpers, which also format rather than raise. A value with fewer than 10 digits can only occur when a party is configured with scheme 0007 but a malformed VAT, which already produced an invalid document before this change, so returning the input unchanged keeps behaviour no worse than today and lets the receiver's PEPPOL-COMMON-R049 schematron report the precise error. Hard-erroring here would also block a sender from exporting when it is the customer's registration that is malformed, which they may not control. Happy to add an explicit TestField-style guard further upstream (posting/setup) if you would prefer fail-fast.
The new Swedish organisation-number branches used else-if, which AA0018 rejects. Split them so the if starts its own line, and document the keep-only-digits extraction in GetSwedishOrgNo.
|
Pushed
Also replied inline on the silent-fallback point. |
What and why
Swedish PEPPOL BIS 3.0 documents fail at the access point because the supplier/customer electronic address (
cbc:EndpointID) and thecac:PartyLegalEntity/cbc:CompanyIDare emitted as the full 14-character Swedish VAT number (for exampleSE733078715601) underschemeID="0007". Scheme0007is SE:ORGNR, which perPEPPOL-COMMON-R049must be exactly the 10-digit Swedish organisation number (7330787156). Today only Denmark has country-specific endpoint handling (UseVATSchemeID), so Sweden falls through unformatted and the document is rejected.This change extracts the Swedish organisation number for parties whose Country/Region VAT Scheme is
0007, in the four procedures that build the supplier and customerEndpointIDandPartyLegalEntity/CompanyID. Thecac:PartyTaxScheme/cbc:CompanyID(the BT-31/BT-48 VAT identifier) is deliberately left as the full VAT, which is exactly the half that the manual "trim to 10 chars" workaround described in the issue broke.Why gate on the scheme (
0007) rather than the country (ISO = 'SE'): the emittedschemeIDalready comes fromGetVATScheme(country), so gating the value on the same0007keeps the value and the scheme consistent by construction. A Swedish company legitimately registered under EAS9955(SE:VAT) then keeps its full VAT underschemeID="9955", which an ISO-based gate would have stripped incorrectly.The
PartyLegalEntity/cbc:CompanyIDschemeID stays empty for SE, as it already does for every non-DK country.PEPPOL-COMMON-R049only applies whenschemeID="0007"is present, so the bare 10-digit organisation number there is valid and matches the expected output shown in the issue.Note: the fix takes effect when the SE Country/Region VAT Scheme is set to
0007, which is already required for any Swedish tenant sending PEPPOL (the issue's sample XML showsschemeID="0007").Linked work
Fixes #7723
How I validated
EndpointIDandPartyLegalEntity/CompanyIDreturn7330787156under scheme00079955keeps the full VAT (not stripped)PartyTaxScheme/CompanyIDkeeps the full VATRisk and compatibility
0007are behaviourally unchanged: the new branch is only reached for0007, andUseVATSchemeIDstill handles DK in the first branch.EndpointIDandPartyLegalEntitycompany id change; the VAT identifier inPartyTaxSchemeis preserved.