Peppol BIS Billing · ubl · rule diff

What 3.0.10 changed

52 rules changed between 3.0.2 and 3.0.10 — added, removed, or rewritten. This is computed from the two rule sets directly, not from a changelog.

What changed

PEPPOL-EN16931-CL007Behaviour changed without the rule changing
$ISO4217: tokenize('AFN EUR ALL DZD USD AOA XCD XCD ARS AMD AWG AUD AZN BSD BHD BDT BBD BYN BZD XOF BMD INR BTN BOB BOV USD BAM BWP NOK BRL USD BND BGN XOF BIF CVE KHR XAF CAD KYD XAF XAF CLP CLF CNY AUD AUD COP COU KMF CDF XAF NZD CRC XOF HRK CUP CUC ANG CZK DKK DJF XCD DOP USD EGP SVC USD XAF ERN ETB FKP DKK FJD XPF XAF GMD GEL GHS GIP DKK XCD USD GTQ GBP GNF XOF GYD HTG USD AUD HNL HKD HUF ISK INR IDR XDR IRR IQD GBP ILS JMD JPY GBP JOD KZT KES AUD KPW KRW KWD KGS LAK LBP LSL ZAR LRD LYD CHF MOP MKD MGA MWK MYR MVR XOF USD MRO MUR XUA MXN MXV USD MDL MNT XCD MAD MZN MMK NAD ZAR AUD NPR XPF NZD NIO XOF NGN NZD AUD USD NOK OMR PKR USD PAB USD PGK PYG PEN PHP NZD PLN USD QAR RON RUB RWF SHP XCD XCD XCD WST STD SAR XOF RSD SCR SLL SGD ANG XSU SBD SOS ZAR SSP LKR SDG SRD NOK SZL SEK CHF CHE CHW SYP TWD TJS TZS THB USD XOF NZD TOP TTD TND TRY TMT USD AUD UGX UAH AED GBP USD USD USN UYU UYI UZS VUV VEF VND USD USD XPF MAD YER ZMW ZWL XBA XBB XBC XBD XTS XXX XAU XPD XPT XAG', '\s') → tokenize('AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND BOB BOV BRL BSD BTN BWP BYN BZD CAD CDF CHE CHF CHW CLF CLP CNY COP COU CRC CUC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HRK HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRO MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLL SOS SRD SSP STN SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD USN UYI UYU UZS VEF VND VUV WST XAF XAG XAU XBA XBB XBC XBD XCD XDR XOF XPD XPF XPT XSU XTS XUA XXX YER ZAR ZMW ZWL', '\s')

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-CL003Behaviour changed without the rule changing
$UNCL7161: tokenize('AA AAA AAC AAD AAE AAF AAH AAI AAS AAT AAV AAY AAZ ABA ABB ABC ABD ABF ABK ABL ABN ABR ABS ABT ABU ACF ACG ACH ACI ACJ ACK ACL ACM ACS ADC ADE ADJ ADK ADL ADM ADN ADO ADP ADQ ADR ADT ADW ADY ADZ AEA AEB AEC AED AEF AEH AEI AEJ AEK AEL AEM AEN AEO AEP AES AET AEU AEV AEW AEX AEY AEZ AJ AU CA CAB CAD CAE CAF CAI CAJ CAK CAL CAM CAN CAO CAP CAQ CAR CAS CAT CAU CAV CAW CD CG CS CT DAB DAD DL EG EP ER FAA FAB FAC FC FH FI GAA HAA HD HH IAA IAB ID IF IR IS KO L1 LA LAA LAB LF MAE MI ML NAA OA PA PAA PC PL RAB RAC RAD RAF RE RF RH RV SA SAA SAD SAE SAI SG SH SM SU TAB TAC TT TV V1 V2 WH XAA YY ZZZ', '\s') → tokenize('AA AAA AAC AAD AAE AAF AAH AAI AAS AAT AAV AAY AAZ ABA ABB ABC ABD ABF ABK ABL ABN ABR ABS ABT ABU ACF ACG ACH ACI ACJ ACK ACL ACM ACS ADC ADE ADJ ADK ADL ADM ADN ADO ADP ADQ ADR ADT ADW ADY ADZ AEA AEB AEC AED AEF AEH AEI AEJ AEK AEL AEM AEN AEO AEP AES AET AEU AEV AEW AEX AEY AEZ AJ AU CA CAB CAD CAE CAF CAI CAJ CAK CAL CAM CAN CAO CAP CAQ CAR CAS CAT CAU CAV CAW CAX CAY CAZ CD CG CS CT DAB DAC DAD DAF DAG DAH DAI DAJ DAK DAL DAM DAN DAO DAP DAQ DL EG EP ER FAA FAB FAC FC FH FI GAA HAA HD HH IAA IAB ID IF IR IS KO L1 LA LAA LAB LF MAE MI ML NAA OA PA PAA PC PL RAB RAC RAD RAF RE RF RH RV SA SAA SAD SAE SAI SG SH SM SU TAB TAC TT TV V1 V2 WH XAA YY ZZZ', '\s')

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-CL008Behaviour changed without the rule changing
$eaid: tokenize('0002 0007 0009 0037 0060 0088 0096 0097 0106 0135 0142 0184 0190 0191 0192 0193 0195 0196 0198 0199 0200 9901 9902 9904 9905 9906 9907 9910 9913 9914 9915 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9955 9956 9957 9958', '\s') → tokenize('0002 0007 0009 0037 0060 0088 0096 0097 0106 0130 0135 0142 0151 0183 0184 0190 0191 0192 0193 0195 0196 0198 0199 0200 0201 0202 0204 0208 0209 0210 0211 0212 0213 9901 9906 9907 9910 9913 9914 9915 9918 9919 9920 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9955 9957', '\s')

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-COMMON-R040Severity raised
severity: warning → fatal

The change is shown above; an explanation appears once one has been reviewed.

DK-R-003Test expression rewritten
not((cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode/@listID = 'MP') and not((cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode/@listVersionID = '19.05.01') or (cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode/@listVersionID = '19.0501') ) )
not((cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode/@listID = 'TST') and not((cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode/@listVersionID = '19.05.01') or (cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode/@listVersionID = '19.0501') ) )

The change is shown above; an explanation appears once one has been reviewed.

DK-R-016Test expression rewritten
not((boolean(/ubl-creditnote:CreditNote)) and (number(cac:LegalMonetaryTotal/cbc:PayableAmount/text()) < 0) )
not((boolean(/ubl-creditnote:CreditNote) and ($DKCustomerCountry = 'DK')) and (number(cac:LegalMonetaryTotal/cbc:PayableAmount/text()) < 0) )

The change is shown above; an explanation appears once one has been reviewed.

DK-R-015Test expression rewritten
not((normalize-space(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[1]/cac:TaxScheme/cbc:ID/text()) = 'VAT') and not ((string-length(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[1]/cbc:CompanyID/text()) = 10) and (substring(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[1]/cbc:CompanyID/text(), 1, 2) = 'DK') and (string(number(substring(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[1]/cbc:CompanyID/text(), 3, 8))) != 'NaN')) or (normalize-space(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[2]/cac:TaxScheme/cbc:ID/text()) = 'VAT') and not ((string-length(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[2]/cbc:CompanyID/text()) = 10) and (substring(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[2]/cbc:CompanyID/text(), 1, 2) = 'DK') and (string(number(substring(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[2]/cbc:CompanyID/text(), 3, 8))) != 'NaN')) )
not((normalize-space(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[1]/cac:TaxScheme/cbc:ID/text()) = 'VAT') and not ((string-length(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[1]/cbc:CompanyID/text()) = 10) and (substring(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[1]/cbc:CompanyID/text(), 1, 2) = 'DK') and (string-length(translate(substring(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[1]/cbc:CompanyID/text(), 3, 8), '1234567890', '')) = 0)) or (normalize-space(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[2]/cac:TaxScheme/cbc:ID/text()) = 'VAT') and not ((string-length(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[2]/cbc:CompanyID/text()) = 10) and (substring(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[2]/cbc:CompanyID/text(), 1, 2) = 'DK') and (string-length(translate(substring(cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[2]/cbc:CompanyID/text(), 3, 8), '1234567890', '')) = 0)) )

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-R008Test expression rewritten
. != ''
false()

The change is shown above; an explanation appears once one has been reviewed.

GR-R-001-5New rule
asserts: string-length(normalize-space($IdSegments[4]))>0 and (some $c in $greekDocumentType satisfies $IdSegments[4] = $c)

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-P0106New rule
asserts: normalize-space(cbc:ID)='K'

The change is shown above; an explanation appears once one has been reviewed.

GR-R-004-2New rule
asserts: matches(.,'^[1-9]([0-9]*)')

The change is shown above; an explanation appears once one has been reviewed.

GR-R-001-1New rule
asserts: count($IdSegments) = 6

The change is shown above; an explanation appears once one has been reviewed.

IS-R-001New rule
asserts: ( ( not(contains(normalize-space(cbc:InvoiceTypeCode),' ')) and contains( ' 380 381 ',concat(' ',normalize-space(cbc:InvoiceTypeCode),' ') ) ) ) or ( ( not(contains(normalize-space(cbc:CreditNoteTypeCode),' ')) and contains( ' 380 381 ',concat(' ',normalize-space(cbc:CreditNoteTypeCode),' ') ) ) )

The change is shown above; an explanation appears once one has been reviewed.

GR-R-003New rule
asserts: substring(.,1,2) = 'EL' and u:TinVerification(substring(.,3))

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-P0108New rule
asserts: normalize-space(cbc:ID)='E'

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-COMMON-R042New rule
asserts: (string-length(text()) = 10) and (substring(text(), 1, 2) = 'DK') and (string-length(translate(substring(text(), 3, 8), '1234567890', '')) = 0)

The change is shown above; an explanation appears once one has been reviewed.

IS-R-007New rule
asserts: exists(cac:PaymentMeans[cbc:PaymentMeansCode = '42']/cac:PayeeFinancialAccount/cbc:ID) and string-length(normalize-space(cac:PaymentMeans[cbc:PaymentMeansCode = '42']/cac:PayeeFinancialAccount/cbc:ID)) = 12 or not(exists(cac:PaymentMeans[cbc:PaymentMeansCode = '42']))

The change is shown above; an explanation appears once one has been reviewed.

GR-R-001-4New rule
asserts: string-length(normalize-space($IdSegments[3]))>0 and string(number($IdSegments[3])) != 'NaN' and xs:integer($IdSegments[3]) >= 0

The change is shown above; an explanation appears once one has been reviewed.

IS-R-005New rule
asserts: exists(cac:Party/cac:PostalAddress/cbc:StreetName) and exists(cac:Party/cac:PostalAddress/cbc:PostalZone)

The change is shown above; an explanation appears once one has been reviewed.

IS-R-006New rule
asserts: exists(cac:PaymentMeans[cbc:PaymentMeansCode = '9']/cac:PayeeFinancialAccount/cbc:ID) and string-length(normalize-space(cac:PaymentMeans[cbc:PaymentMeansCode = '9']/cac:PayeeFinancialAccount/cbc:ID)) = 12 or not(exists(cac:PaymentMeans[cbc:PaymentMeansCode = '9']))

The change is shown above; an explanation appears once one has been reviewed.

GR-S-008-1New rule
asserts: count(cac:AdditionalDocumentReference[cbc:DocumentDescription = '##INVOICE-URL##'])=1

The change is shown above; an explanation appears once one has been reviewed.

GR-R-007-3New rule
asserts: count(cac:PartyTaxScheme[normalize-space(cac:TaxScheme/cbc:ID) = 'VAT']/cbc:CompanyID)=1 and substring(cac:PartyTaxScheme[normalize-space(cac:TaxScheme/cbc:ID) = 'VAT']/cbc:CompanyID,1,2) = 'EL' and u:TinVerification(substring(cac:PartyTaxScheme[normalize-space(cac:TaxScheme/cbc:ID) = 'VAT']/cbc:CompanyID,3))

The change is shown above; an explanation appears once one has been reviewed.

GR-R-007-1New rule
asserts: count(cac:PartyTaxScheme[normalize-space(cac:TaxScheme/cbc:ID) = 'VAT']/cbc:CompanyID) = 1 or count(/ubl-invoice:Invoice/cac:TaxRepresentativeParty) = 1

The change is shown above; an explanation appears once one has been reviewed.

GR-R-008-2New rule
asserts: (count(cac:AdditionalDocumentReference[cbc:DocumentDescription = '##INVOICE-URL##']) = 0 ) or (count(cac:AdditionalDocumentReference[cbc:DocumentDescription = '##INVOICE-URL##']) = 1 )

The change is shown above; an explanation appears once one has been reviewed.

GR-R-001-7New rule
asserts: string-length($IdSegments[6]) > 0

The change is shown above; an explanation appears once one has been reviewed.

GR-R-007-2New rule
asserts: string-length(normalize-space(cac:PartyName/cbc:Name))>0

The change is shown above; an explanation appears once one has been reviewed.

IS-R-010New rule
asserts: (exists(cac:AdditionalDocumentReference[cbc:DocumentDescription = 'EINDAGI']) and (cbc:DueDate) <= (cac:AdditionalDocumentReference[cbc:DocumentDescription = 'EINDAGI']/cbc:ID)) or not(exists(cac:AdditionalDocumentReference[cbc:DocumentDescription = 'EINDAGI']))

The change is shown above; an explanation appears once one has been reviewed.

GR-R-001-2New rule
asserts: string-length(normalize-space($IdSegments[1])) = 9 and u:TinVerification($IdSegments[1]) and ($IdSegments[1] = /*/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme[cac:TaxScheme/cbc:ID = 'VAT']/substring(cbc:CompanyID, 3, 9) or $IdSegments[1] = /*/cac:TaxRepresentativeParty/cac:PartyTaxScheme[cac:TaxScheme/cbc:ID = 'VAT']/substring(cbc:CompanyID, 3, 9) )

The change is shown above; an explanation appears once one has been reviewed.

GR-R-009New rule
asserts: ./@schemeID='9933' and u:TinVerification(.)

The change is shown above; an explanation appears once one has been reviewed.

GR-R-001-3New rule
asserts: string-length(normalize-space($IdSegments[2]))>0 and matches($IdSegments[2],$dateRegExp) and ($tokenizedIdDate[1] = $tokenizedUblIssueDate[3] and $tokenizedIdDate[2] = $tokenizedUblIssueDate[2] and $tokenizedIdDate[3] = $tokenizedUblIssueDate[1])

The change is shown above; an explanation appears once one has been reviewed.

GR-R-004-1New rule
asserts: count(cac:AdditionalDocumentReference[cbc:DocumentDescription = '##M.AR.K##'])=1

The change is shown above; an explanation appears once one has been reviewed.

IS-R-002New rule
asserts: exists(cac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity/cbc:CompanyID) and cac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity/cbc:CompanyID/@schemeID = '0196'

The change is shown above; an explanation appears once one has been reviewed.

GR-R-005New rule
asserts: string-length(./cac:PartyName/cbc:Name)>0

The change is shown above; an explanation appears once one has been reviewed.

GR-R-010New rule
asserts: ./@schemeID='9933' and u:TinVerification(.)

The change is shown above; an explanation appears once one has been reviewed.

GR-R-001-6New rule
asserts: string-length($IdSegments[5]) > 0

The change is shown above; an explanation appears once one has been reviewed.

IS-R-003New rule
asserts: exists(cac:AccountingSupplierParty/cac:Party/cac:PostalAddress/cbc:StreetName) and exists(cac:AccountingSupplierParty/cac:Party/cac:PostalAddress/cbc:PostalZone)

The change is shown above; an explanation appears once one has been reviewed.

IS-R-008New rule
asserts: (exists(cac:AdditionalDocumentReference[cbc:DocumentDescription = 'EINDAGI']) and string-length(cac:AdditionalDocumentReference[cbc:DocumentDescription = 'EINDAGI']/cbc:ID) = 10 and (string(cac:AdditionalDocumentReference[cbc:DocumentDescription = 'EINDAGI']/cbc:ID) castable as xs:date)) or not(exists(cac:AdditionalDocumentReference[cbc:DocumentDescription = 'EINDAGI']))

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-P0111New rule
asserts: normalize-space(cbc:ID)='E'

The change is shown above; an explanation appears once one has been reviewed.

GR-R-006New rule
asserts: count(cac:PartyTaxScheme[normalize-space(cac:TaxScheme/cbc:ID) = 'VAT']/cbc:CompanyID)=1 and substring(cac:PartyTaxScheme[normalize-space(cac:TaxScheme/cbc:ID) = 'VAT']/cbc:CompanyID,1,2) = 'EL' and u:TinVerification(substring(cac:PartyTaxScheme[normalize-space(cac:TaxScheme/cbc:ID) = 'VAT']/cbc:CompanyID,3))

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-P0107New rule
asserts: normalize-space(cbc:ID)='AE'

The change is shown above; an explanation appears once one has been reviewed.

IS-R-009New rule
asserts: (exists(cac:AdditionalDocumentReference[cbc:DocumentDescription = 'EINDAGI']) and exists(cbc:DueDate)) or not(exists(cac:AdditionalDocumentReference[cbc:DocumentDescription = 'EINDAGI']))

The change is shown above; an explanation appears once one has been reviewed.

SE-R-012New rule
asserts: false()

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-P0104New rule
asserts: normalize-space(cbc:ID)='G'

The change is shown above; an explanation appears once one has been reviewed.

IS-R-004New rule
asserts: exists(cac:Party/cac:PartyLegalEntity/cbc:CompanyID) and cac:Party/cac:PartyLegalEntity/cbc:CompanyID/@schemeID = '0196'

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-P0109New rule
asserts: normalize-space(cbc:ID)='E'

The change is shown above; an explanation appears once one has been reviewed.

GR-R-002New rule
asserts: string-length(./cac:PartyName/cbc:Name)>0

The change is shown above; an explanation appears once one has been reviewed.

GR-R-008-3New rule
asserts: string-length(normalize-space(cac:Attachment/cac:ExternalReference/cbc:URI))>0

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-P0105New rule
asserts: normalize-space(cbc:ID)='O'

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-P0110New rule
asserts: normalize-space(cbc:ID)='E'

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-R009Rule removed
was asserting: count(*) != 0

The change is shown above; an explanation appears once one has been reviewed.

DK-R-001Rule removed
was asserting: not(normalize-space(cbc:AccountingCost/text()) = '')

The change is shown above; an explanation appears once one has been reviewed.

PEPPOL-EN16931-CL005Rule removed
was asserting: some $code in $ISO3166 satisfies text() = $code

The change is shown above; an explanation appears once one has been reviewed.

Which of these catch you depends on your invoices.

The rule diff is the same for everyone — what breaks is not. Upload a corpus once and every subsequent release gets replayed against your own invoices, so you see what breaks for you.

RRevalidate

Corpus regression testing for Peppol e-invoices. Rule sets are pulled from docs.peppol.eu, compiled through the ISO Schematron skeleton, and executed with Saxon.

Scope

  • Peppol BIS Billing
  • UBL and CII
  • CEN and Peppol layers

Peppol is a registered trademark of OpenPeppol AISBL. Revalidate is an independent tool and is not affiliated with or endorsed by OpenPeppol. Privacy & data