Search Posts

Visits: 209

Peppol authority of Japan announced new releaseJP PINT 0.9.2 .

PINT Complience states;

Senders compliance to PINT based BIS

A sending party may claim compliance to the Peppol International model if they send invoices that comply with the rules of the Peppol International Invoice when applied without any specialized rules even if that document may at the same time comply with any set of specialized rules.

Processing of rules

A sender SHALL NOT send messages that are not compliant to the BIS specification identified by the customization.
A sender shall validate an outgoing message that are in line with the customsation identifier.

I would like to compare this version with BIS Billing 3.0 to see which range of the validation defined in clause 5.
Clause 5 Rules defines the validation rules for monetary amounts caliculation. These caliculation rules were fully supported by BIS Billing 3.0.
The BIS Billing 3.0 rules defined in the following two pages.

EN16931 model bound to UBL
Rules for Peppol BIS 3.0 Billing

ID BT 5.1 Calculations JP PINT 0.9.2
ibt-092 Document level allowance amount
請求書レベルの返金金額
ibt-092 = ibt-093 * (ibt-094 / 100) none
ibt-099 Document level charge amount
請求書レベルの追加請求金額
ibt-099 = ibt-100 * (ibt-101 / 100) none
ibt-106 Sum of Invoice line net amount
値引後請求書明細行金額の合計
ibt-106 = Σ ibt-131 Shared
ibt-107 Sum of allowances on document level
請求書レベルの返金の合計
ibt-107 = Σ ibt-092 Shared
ibt-108 Sum of charges on document level
請求書レベルの追加請求の合計
ibt-108 = Σ ibt-099 Shared
ibt-109 Invoice total amount without TAX
請求書合計金額(税抜き)
ibt-109 = ibt-106 – ibt-107 + ibt-108 Shared
ibt-110 Invoice total TAX amount
請求書消費税合計金額
ibt-110 = Σ ibt-117 Shared
ibt-112 Invoice total amount with TAX
請求書合計金額(税込み)
ibt-112 = ibt-109 + ibt-110 Shared
ibt-115 Amount due for payment
差引請求金額
ibt-115 = ibt-112 – ibt-113 + ibt-114 Shared
ibt-116 TAX category taxable amount
課税分類毎の課税基準額
ibt-116 = Σ ibt-131 – ibt-092 + ibt-099 none
ibt-117 TAX category tax amount
課税分類毎の消費税額
ibt-117 = ibt-116 * (ibt-119 / 100)
rounded result amount shall be between the floor and the ceiling
Specific
ibt-131 Invoice line net amount
値引後請求書明細行金額(税抜き)
ibt-131 = (ibt-146 / ibt-149) * ibt-129 – ibt-136 + ibt-141 none
ibt-136 Invoice line allowance amount
請求書明細行の返金金額(税抜き)
ibt-136 = ibt-137 * (ibt-138 / 100) none
ibt-141 Invoice line charge amount,br>請求書明細行の追加請求金額(税抜き) ibt-141 = ibt-142 * (ibt-143 / 100) none
ibt-146 Item net price
品目単価(値引後)(税抜き)
ibt-146 = ibt-148 – ibt-147 none

The following table shows the message for each rule.

ID BT rule
ibt-106 Sum of Invoice line net amount
値引後請求書明細行金額の合計
[ibr-co-10]
Sum of Invoice line net amount (ibt-106) = Σ Invoice line net amount (ibt-131).
ibt-107 Sum of allowances on document level
請求書レベルの返金の合計
[ibr-co-11]
Sum of allowances on document level (ibt-107) = Σ Document level allowance amount (ibt-092).
ibt-108 Sum of charges on document level
請求書レベルの追加請求の合計
[ibr-co-12]
Sum of charges on document level (ibt-108) = Σ Document level charge amount (ibt-099).
ibt-109 Invoice total amount without TAX
請求書合計金額(税抜き)
[ibr-co-13]
Invoice total amount without Tax (ibt-109) = Σ Invoice line net amount (ibt-131) – Sum of allowances on document level (ibt-107) + Sum of charges on document level (ibt-108).
ibt-110 Invoice total TAX amount
請求書消費税合計金額
[ibr-co-14]
Invoice total Tax amount (ibt-110) = Σ Tax category tax amount (ibt-117).
ibt-112 Invoice total amount with TAX
請求書合計金額(税込み)
[ibr-co-15]
Invoice total amount with Tax (ibt-112) = Invoice total amount without Tax (ibt-109) + Invoice total Tax amount (ibt-110).
ibt-115 Amount due for payment
請求書合計金額(税込み)
[ibr-co-16]
Amount due for payment (ibt-115) = Invoice total amount with Tax (ibt-112) – Paid amount (ibt-113) + Rounding amount (ibt-114).
ibt-117 TAX category tax amount
課税分類毎の消費税額
[aligned-ibrp-051-jp]
Tax category tax amount (ibt-117) = tax category taxable amount (ibt-116) x (tax category rate (ibt-119) / 100), rounded to integer. The rounded result amount shall be between the floor and the ceiling.
[aligned-ibrp-e-09]
The tax category tax amount (ibt-117) In a tax breakdown (ibg-23) where the tax category code (ibt-118) equals “”Exempt from tax”” MUST equal 0 (zero).
[aligned-ibrp-g-09]
The tax category tax amount (ibt-117) in a tax breakdown (ibg-23) where the tax category code (ibt-118) is “Export” MUST be 0 (zero).
[aligned-ibrp-o-09]
The tax category tax amount (ibt-117) in a tax breakdown (ibg-23) where the tax category code (ibt-118) is “Not subject to tax” MUST be 0 (zero).

Since the coding of the [aligned-ibrp-051-jp] listed on the page is difficult to read, you can check the following by indenting the lines separately (though I don’t think it is necessary to apply the round () function to the tax rate).

In the last part, this rule added the rules when the tax rate is 0 (zero) and when the Tax category code is ‘O’, when there is no tax rate.

In addition, cbc: TaxAmount/@currencyID = /ubl: Invoice/cbc: DocumentCurrencyCode/text () is coded in the select condition of cac:taxSubtotal to which the rule is applied, but this rule is only applicable when the currency is Japanese JPY. I think cbc:TaxAmount/@currencyID=’JPY’ is better. Since Invoices denominated in foreign currencies are not always rounded down or rounded up.

Context
  cac:TaxSubtotal[cbc:TaxAmount/@currencyID=/ubl:Invoice/cbc:DocumentCurrencyCode/text()]
Test
  (
    (cac:TaxCategory/normalize-space(upper-case(cbc:ID)) != 'O') and 
    (
      (
        round(cac:TaxCategory/xs:decimal(cbc:Percent)) != 0 and 
        (
          xs:decimal(cbc:TaxAmount) >= 
          floor(
            xs:decimal(cbc:TaxableAmount) * (cac:TaxCategory/xs:decimal(cbc:Percent) div 100)
          )
        ) and 
        (
          xs:decimal(cbc:TaxAmount) <= 
          ceiling(
            xs:decimal(cbc:TaxableAmount) * (cac:TaxCategory/xs:decimal(cbc:Percent) div 100)
          )
        )
      ) or 
      (
        round(cac:TaxCategory/xs:decimal(cbc:Percent)) = 0 and 
        (xs:decimal(cbc:TaxAmount) = 0)
      )
    )
  ) or 
  (
    not(cac:TaxCategory/cbc:Percent) and 
    (
      cac:TaxCategory/normalize-space(upper-case(cbc:ID)) = 'O'
    ) and 
    (xs:decimal(cbc:TaxAmount) = 0)
  )

Compared to JP JPINT 0.9.2, the following BIS Billing 3.0 table shows that all validation rules are provided for all monetary calculations.

A rounding rule for the tax amount calculation for each tax category code is provided, but no following underlying amounts rule is provided.

Validation rules for ibt-116 TAX category taxable amount, ibt-131 Invoice line net amount, and ibt-146 Item net price were provided with BIS Billing 3.0. Without these fundamental validation rule, even if a sender validate an outgoing message with provided schematron files that are in line with the customsation identifier, a sender CAN NOT claim that he never sends messages that are not compliant to the BIS specification identified by the customization.

If each service provider (C2 / C3) or end user (C1 / C4) are asked to achieve this compliance requirement with their own additional validation functionality with their own software. This additional requirement not only deviates from the standardization intent, but this also may require them unintentionally investmants in compliance. These monetary amounts validation rules were provided completely free of charge in BIS Billing 3.0.

I hope that it will be improved in the next revision.

ID BT BIS Billing 3.0
ibt-092 Document level allowance amount PEPPOL-EN16931-R040
Allowance/charge amount must equal base amount * percentage/100 if base amount and percentage exists
ibt-099 Document level charge amount PEPPOL-EN16931-R040
Allowance/charge amount must equal base amount * percentage/100 if base amount and percentage exists
ibt-106 Sum of Invoice line net amount BR-CO-10
Sum of Invoice line net amount (BT-106) = Σ Invoice line net amount (BT-131).
ibt-107 Sum of allowances on document level BR-CO-11
Sum of allowances on document level (BT-107) = Σ Document level allowance amount (BT-92).
ibt-108 Sum of charges on document level BBR-CO-12
Sum of charges on document level (BT-108) = Σ Document level charge amount (BT-99).
ibt-109 Invoice total amount without TAX BR-CO-13
Invoice total amount without VAT (BT-109) = Σ Invoice line net amount (BT-131) – Sum of allowances on document level (BT-107) + Sum of charges on document level (BT-108).
ibt-110 Invoice total TAX amount BR-CO-14
Invoice total VAT amount (BT-110) = Σ VAT category tax amount (BT-117).
ibt-112 Invoice total amount with TAX BR-CO-15
Invoice total amount with VAT (BT-112) = Invoice total amount without VAT (BT-109) + Invoice total VAT amount (BT-110).
ibt-115 Amount due for payment BR-CO-16
Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) -Paid amount (BT-113) +Rounding amount (BT-114).
ibt-116 TAX category taxable amount BR-S-08
For each different value of VAT category rate (BT-119) where the VAT category code (BT-118) is “Standard rated”, the VAT category taxable amount (BT-116) in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts (BT-131) plus the sum of document level charge amounts (BT-99) minus the sum of document level allowance amounts (BT-92) where the VAT category code (BT-151, BT-102, BT-95) is “Standard rated” and the VAT rate (BT-152, BT-103, BT-96) equals the VAT category rate (BT-119).
ibt-117 TAX category tax amount BR-CO-17
VAT category tax amount (BT-117) = VAT category taxable amount (BT-116) x (VAT category rate (BT-119) / 100), rounded to two decimals.
BR-S-09
The VAT category tax amount (BT-117) in a VAT breakdown (BG-23) where VAT category code (BT-118) is “Standard rated” shall equal the VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119).
ibt-131 Invoice line net amount PEPPOL-EN16931-R120
Invoice line net amount MUST equal (Invoiced quantity * (Item net price/item price base quantity) + Sum of invoice line charge amount – sum of invoice line allowance amount
ibt-136 Invoice line allowance amount PEPPOL-EN16931-R040
Allowance/charge amount must equal base amount * percentage/100 if base amount and percentage exists
ibt-141 Invoice line charge amount PEPPOL-EN16931-R040PEPPOL-EN16931-R040
Allowance/charge amount must equal base amount * percentage/100 if base amount and percentage exists
ibt-146 Item net price PEPPOL-EN16931-R046
Item net price MUST equal (Gross price – Allowance amount) when gross price is provided.

BIS Billing 3.0 defines validation of ibt-116 TAX category taxable amount as follows;
BR-S-08 (fatal)
For each different value of VAT category rate (BT-119) where the VAT category code (BT-118) is “Standard rated”, the VAT category taxable amount (BT-116) in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts (BT-131) plus the sum of document level charge amounts (BT-99) minus the sum of document level allowance amounts (BT-92) where the VAT category code (BT-151, BT-102, BT-95) is “Standard rated” and the VAT rate (BT-152, BT-103, BT-96) equals the VAT category rate (BT-119).

where context targets cac:TaxSubtotal/cac:TaxCategory and defines test as folllows.
/*/cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory[normalize-space(cbc:ID)=’S’][cac:TaxScheme/normalize-space(upper-case(cbc:ID))=’VAT’]

every $rate in xs:decimal(cbc:Percent) satisfies (
  (
    (
      exists(//cac:InvoiceLine[cac:Item/cac:ClassifiedTaxCategory/normalize-space(cbc:ID)='S'][cac:Item/cac:ClassifiedTaxCategory/xs:decimal(cbc:Percent=$rate]) or
      exists(//cac:AllowanceCharge[cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate])
    ) and
    (
      (
        ../xs:decimal(cbc:TaxableAmount - 1) < 
        (
          sum(../../../cac:InvoiceLine[cac:Item/cac:ClassifiedTaxCategory/normalize-space(cbc:ID)='S'][cac:Item/cac:ClassifiedTaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:LineExtensionAmount)) +
          sum(../../../cac:AllowanceCharge[cbc:ChargeIndicator=true()][cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:Amount)) -
          sum(../../../cac:AllowanceCharge[cbc:ChargeIndicator=false()][cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:Amount))
        )
      ) and
      (
        ../xs:decimal(cbc:TaxableAmount + 1) > 
        (
          sum(../../../cac:InvoiceLine[cac:Item/cac:ClassifiedTaxCategory/normalize-space(cbc:ID)='S'][cac:Item/cac:ClassifiedTaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:LineExtensionAmount)) +
          sum(../../../cac:AllowanceCharge[cbc:ChargeIndicator=true()][cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:Amount)) -
          sum(../../../cac:AllowanceCharge[cbc:ChargeIndicator=false()][cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:Amount))
        )
      )
    )
  ) or
  (
    exists(//cac:CreditNoteLine[cac:Item/cac:ClassifiedTaxCategory/normalize-space(cbc:ID)='S'][cac:Item/cac:ClassifiedTaxCategory/xs:decimal(cbc:Percent)=$rate]) or
    exists(//cac:AllowanceCharge[cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate])
  ) and
  (
    (
      ../xs:decimal(cbc:TaxableAmount - 1) < 
      (
        sum(../../../cac:CreditNoteLine[cac:Item/cac:ClassifiedTaxCategory/normalize-space(cbc:ID)='S'][cac:Item/cac:ClassifiedTaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:LineExtensionAmount)) +
        sum(../../../cac:AllowanceCharge[cbc:ChargeIndicator=true()][cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:Amount)) -
        sum(../../../cac:AllowanceCharge[cbc:ChargeIndicator=false()][cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:Amount))
      )
    ) and
    (
      ../xs:decimal(cbc:TaxableAmount + 1) > 
      (
        sum(../../../cac:CreditNoteLine[cac:Item/cac:ClassifiedTaxCategory/normalize-space(cbc:ID)='S'][cac:Item/cac:ClassifiedTaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:LineExtensionAmount)) +
        sum(../../../cac:AllowanceCharge[cbc:ChargeIndicator=true()][cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:Amount)) -
        sum(../../../cac:AllowanceCharge[cbc:ChargeIndicator=false()][cac:TaxCategory/normalize-space(cbc:ID)='S'][cac:TaxCategory/xs:decimal(cbc:Percent)=$rate]/xs:decimal(cbc:Amount))
      )
    )
  )
)

For ibt-131 net invoice line amount, the slack () function is used in the invoice line amount (excluding tax) validation rule as follows:

Context
  cac:InvoiceLine | cac:CreditNoteLine
Test
  u:slack($lineExtensionAmount, 
  (
    $quantity * ($priceAmount div $baseQuantity)) + 
    $chargesTotal - 
    $allowancesTotal,
    0.02
  )

The slack() function is following XSL function.

<function xmlns="http://www.w3.org/1999/XSL/Transform" name="u:slack" as="xs:boolean">
    <param name="exp" as="xs:decimal"/>
    <param name="val" as="xs:decimal"/>
    <param name="slack" as="xs:decimal"/>
    <value-of select="
        xs:decimal($exp + $slack) &gt;= $val and 
        xs:decimal($exp - $slack) &lt;= $val
    "/>
</function>

It is determined whether the amount to be compared and the amount of the check result are within the range of ± slack value. In the case of foreign currency, the slack value declared is usually 0.02 because there are two digits after the decimal point. If the difference between the check result and the comparison target amount is within this range, it is judged to be a correct calculation. In Japanese yen, the slack value may be 2 because the normal monetary amount is expressed as an integer.

This article is based on the following sources:
Downloaded files from Japan PINT Invoice Version 0.9.2 Download resources button.

and Peppol BIS Billing 3.0 Home page.

I listed the result of tree command for unzipped directory. The schematron file listed above is the Shared rule and the below is the Specific(Aligned).
├── schematron
│   ├── PINT-UBL-validation-preprocessed.sch
│   └── PINT-jurisdiction-aligned-rules.sch
├── semantic-model.yaml
└── syntax-binding.yaml

Files included in the downloaded directory contains yaml files corresponding to the code list, the Semantic model page, and the Syntax binding page. Unfotunately XSLT file contained in the previous download is not included in this directory. Please make sure to update customizationId in XSLT file, if you want to use previous file.

pint-jp-resources-dev pontsoleil$ tree .
.
├── common
│   └── docs
│   ├── bis.pdf
│   ├── compliance.pdf
│   └── release-notes.pdf
└── trn-invoice
├── codelist
│   ├── Aligned-TaxCategoryCodes.gc
│   ├── Aligned-TaxCategoryCodes.yaml
│   ├── Aligned-TaxExemptionCodes.gc
│   ├── Aligned-TaxExemptionCodes.yaml
│   ├── ICD.gc
│   ├── ICD.yaml
│   ├── ISO3166.gc
│   ├── ISO3166.yaml
│   ├── ISO4217.gc
│   ├── ISO4217.yaml
│   ├── MimeCode.gc
│   ├── MimeCode.yaml
│   ├── SEPA.gc
│   ├── SEPA.yaml
│   ├── UNCL1001-inv.gc
│   ├── UNCL1001-inv.yaml
│   ├── UNCL1153.gc
│   ├── UNCL1153.yaml
│   ├── UNCL2005.gc
│   ├── UNCL2005.yaml
│   ├── UNCL4461.gc
│   ├── UNCL4461.yaml
│   ├── UNCL5189.gc
│   ├── UNCL5189.yaml
│   ├── UNCL7143.gc
│   ├── UNCL7143.yaml
│   ├── UNCL7161.gc
│   ├── UNCL7161.yaml
│   ├── UNECERec20.gc
│   ├── UNECERec20.yaml
│   ├── eas.gc
│   └── eas.yaml
├── schematron
│   ├── PINT-UBL-validation-preprocessed.sch
│   └── PINT-jurisdiction-aligned-rules.sch
├── semantic-model.yaml
└── syntax-binding.yaml