Skip to content

Commit

Permalink
Merge pull request #146 from OpenPEPPOL/POACC-735
Browse files Browse the repository at this point in the history
Poacc 735
  • Loading branch information
MartinForsberg-Ecru authored Feb 12, 2024
2 parents f866cf4 + 539fc62 commit 3a2040a
Show file tree
Hide file tree
Showing 8 changed files with 908 additions and 5 deletions.
1 change: 1 addition & 0 deletions guide/release-notes/v3.0.17.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ Release date:: May 2024

== Changes to code lists and validation artefacts

* Added new Swedish rule (SE-R-013) for validation of the check number of a Swedish Organization number. The rule is introduced as severity warning. All rules which verifies the format of Organization numbers (SE-R-003, SE-R-004 and SE-R-013) will be changed to severity fatal in next release.

== EN 16931 schematrons updated
31 changes: 30 additions & 1 deletion rules/sch/PEPPOL-EN16931-CII.sch
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,34 @@ Last update: 2022 May release 3.0.13.
((string-to-codepoints(substring($val,11,1)) - 48) * 19)) mod 89 = 0
"/>
</function>

<!-- Function for Swedish organisation numbers (0007) -->
<function xmlns="http://www.w3.org/1999/XSL/Transform" name="u:checkSEOrgnr" as="xs:boolean">
<param name="number" as="xs:string"/>
<choose>
<!-- Check if input is numeric -->
<when test="not(matches($number, '^\d+$'))">
<sequence select="false()"/>
</when>
<otherwise>
<!-- verify the check number of the provided identifier according to the Luhn algorithm-->
<variable name="mainPart" select="substring($number, 1, 9)"/>
<variable name="checkDigit" select="substring($number, 10, 1)"/>
<variable name="sum" as="xs:integer">
<value-of select="sum(
for $pos in 1 to string-length($mainPart) return
if ($pos mod 2 = 1)
then (number(substring($mainPart, string-length($mainPart) - $pos + 1, 1)) * 2) mod 10 +
(number(substring($mainPart, string-length($mainPart) - $pos + 1, 1)) * 2) idiv 10
else number(substring($mainPart, string-length($mainPart) - $pos + 1, 1))
)"/>
</variable>
<variable name="calculatedCheckDigit" select="(10 - $sum mod 10) mod 10"/>
<sequence select="$calculatedCheckDigit = number($checkDigit)"/>
</otherwise>
</choose>
</function>

<pattern>
<rule context="rsm:ExchangedDocumentContext">
<assert id="PEPPOL-EN16931-R001" test="ram:BusinessProcessSpecifiedDocumentContextParameter/ram:ID" flag="fatal">Business process MUST be provided.</assert>
Expand Down Expand Up @@ -304,7 +332,7 @@ Last update: 2022 May release 3.0.13.
<assert id="PEPPOL-COMMON-R048" test="u:checkPIVAseIT(normalize-space())" flag="warning">Italian VAT Code (Partita Iva) must be stated in the correct format</assert>
</rule>
<rule context="ram:URIID[@schemeID = '0007'] | ram:ID[@schemeID = '0007'] | ram:GlobalID[@schemeID = '0007']">
<assert id="PEPPOL-COMMON-R049" test="string-length(normalize-space()) = 10 and string(number(normalize-space())) != 'NaN'" flag="fatal">Swedish organization number MUST be stated in the correct format.</assert>
<assert id="PEPPOL-COMMON-R049" test="string-length(normalize-space()) = 10 and string(number(normalize-space())) != 'NaN' and u:checkSEOrgnr(normalize-space())" flag="fatal">Swedish organization number MUST be stated in the correct format.</assert>
</rule>
<rule context="ram:URIID[@schemeID = '0151'] | ram:ID[@schemeID = '0151'] | ram:GlobalID[@schemeID = '0151']">
<assert id="PEPPOL-COMMON-R050" test="u:abn(normalize-space())" flag="fatal">Australian Business Number (ABN) MUST be stated in the correct format.</assert>
Expand Down Expand Up @@ -417,6 +445,7 @@ Last update: 2022 May release 3.0.13.
<rule context="rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:SellerTradeParty/ram:SpecifiedLegalOrganization[../ram:PostalTradeAddress/ram:CountryID = 'SE' and ram:ID]">
<assert id="SE-R-003" test="string(number(ram:ID)) != 'NaN'" flag="warning">Swedish organisation numbers should be numeric.</assert>
<assert id="SE-R-004" test="string-length(normalize-space(ram:ID)) = 10" flag="warning">Swedish organisation numbers consist of 10 characters.</assert>
<assert id="SE-R-013" test="u:checkSEOrgnr(normalize-space(ram:ID))" flag="warning">The last digit of a Swedish organization number must be valid according to the Luhn algorithm.</assert>
</rule>
<rule context="rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:SellerTradeParty[ram:PostalTradeAddress/ram:CountryID = 'SE' and ram:SpecifiedLegalOrganization/ram:ID]/ram:SpecifiedTaxRegistration/ram:ID[@schemeID = 'FC']">
<assert id="SE-R-005" test="normalize-space(upper-case(.)) = 'GODKÄND FÖR F-SKATT'" flag="fatal">For Swedish suppliers, when using Seller tax registration identifier, 'Godkänd för F-skatt' must be stated</assert>
Expand Down
30 changes: 29 additions & 1 deletion rules/sch/PEPPOL-EN16931-UBL.sch
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,33 @@ Last update: 2023 May release 3.0.15.
(number($digits[1])*256) "/>
<value-of select="($checksum mod 11) mod 10 = number($digits[9])"/>
</function>

<!-- Function for Swedish organisation numbers (0007) -->
<function xmlns="http://www.w3.org/1999/XSL/Transform" name="u:checkSEOrgnr" as="xs:boolean">
<param name="number" as="xs:string"/>
<choose>
<!-- Check if input is numeric -->
<when test="not(matches($number, '^\d+$'))">
<sequence select="false()"/>
</when>
<otherwise>
<!-- verify the check number of the provided identifier according to the Luhn algorithm-->
<variable name="mainPart" select="substring($number, 1, 9)"/>
<variable name="checkDigit" select="substring($number, 10, 1)"/>
<variable name="sum" as="xs:integer">
<value-of select="sum(
for $pos in 1 to string-length($mainPart) return
if ($pos mod 2 = 1)
then (number(substring($mainPart, string-length($mainPart) - $pos + 1, 1)) * 2) mod 10 +
(number(substring($mainPart, string-length($mainPart) - $pos + 1, 1)) * 2) idiv 10
else number(substring($mainPart, string-length($mainPart) - $pos + 1, 1))
)"/>
</variable>
<variable name="calculatedCheckDigit" select="(10 - $sum mod 10) mod 10"/>
<sequence select="$calculatedCheckDigit = number($checkDigit)"/>
</otherwise>
</choose>
</function>
<!-- Empty elements -->
<pattern>
<rule context="//*[not(*) and not(normalize-space())]">
Expand Down Expand Up @@ -362,7 +389,7 @@ Last update: 2023 May release 3.0.15.
<assert id="PEPPOL-COMMON-R048" test="u:checkPIVAseIT(normalize-space())" flag="warning">Italian VAT Code (Partita Iva) must be stated in the correct format</assert>
</rule> -->
<rule context="cbc:EndpointID[@schemeID = '0007'] | cac:PartyIdentification/cbc:ID[@schemeID = '0007'] | cbc:CompanyID[@schemeID = '0007']">
<assert id="PEPPOL-COMMON-R049" test="string-length(normalize-space()) = 10 and string(number(normalize-space())) != 'NaN'" flag="fatal">Swedish organization number MUST be stated in the correct format.</assert>
<assert id="PEPPOL-COMMON-R049" test="string-length(normalize-space()) = 10 and string(number(normalize-space())) != 'NaN' and u:checkSEOrgnr(normalize-space())" flag="fatal">Swedish organization number MUST be stated in the correct format.</assert>
</rule>
<rule context="cbc:EndpointID[@schemeID = '0151'] | cac:PartyIdentification/cbc:ID[@schemeID = '0151'] | cbc:CompanyID[@schemeID = '0151']">
<assert id="PEPPOL-COMMON-R050" test="matches(normalize-space(), '^[0-9]{11}$') and u:abn(normalize-space())" flag="fatal">Australian Business Number (ABN) MUST be stated in the correct format.</assert>
Expand Down Expand Up @@ -471,6 +498,7 @@ Last update: 2023 May release 3.0.15.
<rule context="//cac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity[../cac:PostalAddress/cac:Country/cbc:IdentificationCode = 'SE' and cbc:CompanyID]">
<assert id="SE-R-003" test="string(number(cbc:CompanyID)) != 'NaN'" flag="warning">Swedish organisation numbers should be numeric.</assert>
<assert id="SE-R-004" test="string-length(normalize-space(cbc:CompanyID)) = 10" flag="warning">Swedish organisation numbers consist of 10 characters.</assert>
<assert id="SE-R-013" test="u:checkSEOrgnr(normalize-space(cbc:CompanyID))" flag="warning">The last digit of a Swedish organization number must be valid according to the Luhn algorithm.</assert>
</rule>
<rule context="//cac:AccountingSupplierParty/cac:Party[cac:PostalAddress/cac:Country/cbc:IdentificationCode = 'SE' and exists(cac:PartyLegalEntity/cbc:CompanyID)]/cac:PartyTaxScheme[normalize-space(upper-case(cac:TaxScheme/cbc:ID)) != 'VAT']/cbc:CompanyID">
<assert id="SE-R-005" test="normalize-space(upper-case(.)) = 'GODKÄND FÖR F-SKATT'" flag="fatal">For Swedish suppliers, when using Seller tax registration identifier, 'Godkänd för F-skatt' must be stated</assert>
Expand Down
30 changes: 28 additions & 2 deletions rules/unit-CII-PEPPOL/PEPPOL-COMMON-R049.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
<ram:ApplicableHeaderTradeAgreement>
<ram:SellerTradeParty>
<ram:URIUniversalCommunication>
<ram:URIID schemeID="0007">5544332211</ram:URIID>
<ram:URIID schemeID="0007">2021005489</ram:URIID>
</ram:URIUniversalCommunication>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:URIUniversalCommunication>
<ram:URIID schemeID="0007">5544332211</ram:URIID>
<ram:URIID schemeID="0007">2021005489</ram:URIID>
</ram:URIUniversalCommunication>
</ram:BuyerTradeParty>
</ram:ApplicableHeaderTradeAgreement>
Expand Down Expand Up @@ -91,6 +91,32 @@
</rsm:CrossIndustryInvoice>
</test>

<test>
<assert>
<error>PEPPOL-COMMON-R049</error>
</assert>


<rsm:CrossIndustryInvoice
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rsm:ExchangedDocument>
<ram:TypeCode>380</ram:TypeCode>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:ApplicableHeaderTradeAgreement>
<ram:SellerTradeParty>
<ram:URIUniversalCommunication>
<ram:URIID schemeID="0007">2021005480</ram:URIID>
</ram:URIUniversalCommunication>
</ram:SellerTradeParty>
</ram:ApplicableHeaderTradeAgreement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
</test>




Expand Down
Loading

0 comments on commit 3a2040a

Please sign in to comment.