Skip to content

Commit

Permalink
POACC-735 SE rule for check digit
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinForsberg-Ecru committed Feb 9, 2024
1 parent f866cf4 commit d92a40b
Show file tree
Hide file tree
Showing 3 changed files with 351 additions and 2 deletions.
27 changes: 26 additions & 1 deletion rules/sch/PEPPOL-EN16931-UBL.sch
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,30 @@ 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"/>

<!-- Check if input is numeric -->
<if test="not(matches($number, '^\d+$'))">
<sequence select="false()"/>
</if>
<!-- 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)"/>
</function>
<!-- Empty elements -->
<pattern>
<rule context="//*[not(*) and not(normalize-space())]">
Expand Down Expand Up @@ -362,7 +386,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 +495,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
15 changes: 14 additions & 1 deletion rules/unit-UBL-PEPPOL/PEPPOL-COMMON-R049.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="0007">5566221100</cbc:EndpointID>
<cbc:EndpointID schemeID="0007">2021005489</cbc:EndpointID>
</cac:Party>
</cac:AccountingCustomerParty>
</Invoice>
Expand Down Expand Up @@ -46,4 +46,17 @@
</Invoice>
</test>

<test>
<assert>
<error>PEPPOL-COMMON-R049</error>
</assert>
<Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="0007">2021005480</cbc:EndpointID>
</cac:Party>
</cac:AccountingCustomerParty>
</Invoice>
</test>

</testSet>
311 changes: 311 additions & 0 deletions rules/unit-UBL-SE/UBL-IN_SE-R-013.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
<?xml version="1.0" encoding="UTF-8"?>
<testSet xmlns="http://difi.no/xsd/vefa/validator/1.0" configuration="peppolbis-en16931-base-3.0-ubl">
<assert>
<description>The last digit of a Swedish organization number must be valid according to the Luhn algorithm.</description>
<scope>SE-R-013</scope>
</assert>
<test>
<assert>
<success>SE-R-013</success>
</assert>

<Invoice
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>2018210</cbc:ID>
<cbc:IssueDate>2018-02-08</cbc:IssueDate>
<cbc:DueDate>2018-03-07</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:Note>Testfil för kontroll av svenska valideringsregler</cbc:Note>
<cbc:DocumentCurrencyCode>SEK</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>BuyerRef 123</cbc:BuyerReference>

<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="0007">2021005489</cbc:EndpointID>
<cac:PostalAddress>
<cbc:StreetName>Storgatan 1</cbc:StreetName>
<cbc:CityName>Stockholm</cbc:CityName>
<cbc:PostalZone>11122</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>SE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>Godkänd för F-skatt</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>TAX</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyTaxScheme>
<cbc:CompanyID>SE123456789001</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Allsälj AB</cbc:RegistrationName>
<cbc:CompanyID>2021005489</cbc:CompanyID>
<cbc:CompanyLegalForm>Säte: Stockholm</cbc:CompanyLegalForm>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingSupplierParty>

<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="0007">2021005489</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Kommunteknisk service</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Lilla gränd 9</cbc:StreetName>
<cbc:CityName>Stockholm</cbc:CityName>
<cbc:PostalZone>10203</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>SE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Kommunens Tekniska Bolag AB</cbc:RegistrationName>
<cbc:CompanyID schemeID="0007">2021005489</cbc:CompanyID>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingCustomerParty>

<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
<cbc:PaymentID>08/00355</cbc:PaymentID>
<cac:PayeeFinancialAccount>
<cbc:ID>1234567</cbc:ID>
<cbc:Name>Account name</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>9999</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>

<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:AllowanceChargeReason>Rabatt</cbc:AllowanceChargeReason>
<cbc:Amount currencyID="SEK">11</cbc:Amount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:AllowanceChargeReason>Förvaring</cbc:AllowanceChargeReason>
<cbc:Amount currencyID="SEK">11</cbc:Amount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>

<cac:TaxTotal>
<cbc:TaxAmount currencyID="SEK">25</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="SEK">100</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="SEK">25</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>

<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="SEK">100</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="SEK">100</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="SEK">125</cbc:TaxInclusiveAmount>

<cbc:AllowanceTotalAmount currencyID="SEK">11</cbc:AllowanceTotalAmount>
<cbc:ChargeTotalAmount currencyID="SEK">11</cbc:ChargeTotalAmount>
<cbc:PayableAmount currencyID="SEK">125</cbc:PayableAmount>
</cac:LegalMonetaryTotal>

<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">5</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="SEK">100</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Utbytesstol</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID schemeID="UNCL5305">S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="SEK">20</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>

</Invoice>


</test>
<test>
<assert>
<warning>SE-R-013</warning>
</assert>
<Invoice
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>2018210</cbc:ID>
<cbc:IssueDate>2018-02-08</cbc:IssueDate>
<cbc:DueDate>2018-03-07</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:Note>Testfil för kontroll av svenska valideringsregler</cbc:Note>
<cbc:DocumentCurrencyCode>SEK</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>BuyerRef 123</cbc:BuyerReference>

<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="0007">2021005489</cbc:EndpointID>
<cac:PostalAddress>
<cbc:StreetName>Storgatan 1</cbc:StreetName>
<cbc:CityName>Stockholm</cbc:CityName>
<cbc:PostalZone>11122</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>SE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>SE123456789001</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Allsälj AB</cbc:RegistrationName>
<cbc:CompanyID>2021005480</cbc:CompanyID>
<cbc:CompanyLegalForm>Säte: Stockholm</cbc:CompanyLegalForm>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingSupplierParty>

<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="0007">2021005489</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Kommunteknisk service</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Lilla gränd 9</cbc:StreetName>
<cbc:CityName>Stockholm</cbc:CityName>
<cbc:PostalZone>10203</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>SE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Kommunens Tekniska Bolag AB</cbc:RegistrationName>
<cbc:CompanyID schemeID="0007">1234512345</cbc:CompanyID>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingCustomerParty>

<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
<cbc:PaymentID>08/00355</cbc:PaymentID>
<cac:PayeeFinancialAccount>
<cbc:ID>1234567</cbc:ID>
<cbc:Name>Account name</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>9999</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>

<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:AllowanceChargeReason>Rabatt</cbc:AllowanceChargeReason>
<cbc:Amount currencyID="SEK">11</cbc:Amount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:AllowanceChargeReason>Förvaring</cbc:AllowanceChargeReason>
<cbc:Amount currencyID="SEK">11</cbc:Amount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>

<cac:TaxTotal>
<cbc:TaxAmount currencyID="SEK">25</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="SEK">100</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="SEK">25</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>

<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="SEK">100</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="SEK">100</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="SEK">125</cbc:TaxInclusiveAmount>

<cbc:AllowanceTotalAmount currencyID="SEK">11</cbc:AllowanceTotalAmount>
<cbc:ChargeTotalAmount currencyID="SEK">11</cbc:ChargeTotalAmount>
<cbc:PayableAmount currencyID="SEK">125</cbc:PayableAmount>
</cac:LegalMonetaryTotal>

<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">5</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="SEK">100</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Utbytesstol</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID schemeID="UNCL5305">S</cbc:ID>
<cbc:Percent>25</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="SEK">20</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>

</Invoice>

</test>
</testSet>

0 comments on commit d92a40b

Please sign in to comment.