MLR(旧)からMLS(新)へ:Peppolのメッセージ応答は何が変わるのか

Views: 50

2026年7月1日からすでにMLSへの移行期間が開始されており、MLSの送受信に向けた実装・準備が進められています。[7]

Peppol Message Level Statusの現行仕様はv1.1.0です。[2]

MLS

2024年10月に、次の記事でPeppolのMessage Level Response(MLR)からMessage Level Status(MLS)への移行について紹介していました。

  • Peppolメッセージ応答の進化:MLRからMLSへの移行と追加機能 [17]

その後、MLSは正式仕様となり、2026年7月2日に Peppol Message Level Status v1.1.0、Peppol Network Policy、MLS Phase-in Planが公開され、MLR廃止計画も公開されています。[2][6][7][8]

本稿では、従来のMessage Level Responseを MLR(旧)、新しいMessage Level Statusを MLS(新) と表記します。

Note
MLS(新)はMLR(旧)の単なる名称変更ではありません。MLR(旧)はEnd User間のbusiness documentとしてvalidation結果を通知する仕組みであるのに対し、MLS(新)はC3から、原則としてC2へ送られるService Provider間のmessage processing及びC4へのdelivery statusを通知するeDeliveryの仕組みです。MLS_TOが有効に指定されている場合は、そのfallback chainで決定されたService Providerが実効的な受信者になります。[2][3][9]

Peppol Service Provider Operational Guideline on MLS の現行仕様はv1.0.0です.[3]

SP OP MLS

1. MLR(旧)とMLS(新)の基本的な違い

1.1 MLR(旧)が通知していたもの

MLR(旧)Message Level Response はPeppol Post-Award BISとして定義され、受信したbusiness documentについて、[9]

この文書は、

仕様上、次の処理へ進めることができるか

というvalidation結果を通知するものでした。

代表的なResponse Codeは次の3つです。

表示 状態 意味

MLR(旧)AP

Acceptance

validationをfatal errorなしで通過し、次の処理へ進める。

MLR(旧)AB

Acknowledgement

business messageとして受領・識別したが、conformance validationは実施していない。

MLR(旧)RE

Rejection

conformance ruleに対するerrorがあり、それ以上処理しない。

MLR(旧)の`AP`は、BuyerがInvoiceを業務上承認したという意味ではありません。あくまでmessage levelのvalidation結果です。

1.2 MLR(旧)の論理的な応答とPeppol Network上の通信

MLR(旧)では、論理的なbusiness responseとPeppol Network上の通信経路を区別する必要があります。

通常のbusiness documentは、

C1  ------>  C2  ------>  C3  ------>  C4

と配送されます。

これに対するMLR(旧)は、論理的には元business documentのreceiverからsenderへ返されます。

C4  ------------------------------>  C1

              MLR(旧)

しかしPeppol Network上では逆方向に、

C4  ------>  C3  ------>  C2  ------>  C1

と配送されるため、network上ではC3からC2への通信を経由します。

したがって、

MLR(旧)

論理的な応答主体 : C4 → C1

Network上の通信 : C3 → C2を経由

と整理するのが適切です。

1.3 MLS(新)はC3自身が原則C2へ返す

図1 MLR(旧)とMLS(新)の違い

図1に示すように、MLS(新)Message Level Status は、受信側Service ProviderであるC3自身が送信するstatus messageです。通常の受信先は元business documentを送信したC2ですが、`MLS_TO`が有効に指定されている場合には、そのfallback chainで決定されたService Providerが実効受信者になります。[2][3]

C1  ------>  C2  ------>  C3  ------>  C4

               ^            |

               |            |

               +-- MLS(新)-+

                   C3 → C2(基本形)

つまりMLS(新)は、

論理的な送信者 = C3

論理的な受信者 = C2(基本形)/`MLS_TO`で決定された受信Service Provider

というService Provider間の通信です。

MLR(旧) MLS(新)

位置付け

Post-Award BIS

eDelivery

論理的な送信者

C4 End User

C3 Service Provider

論理的な受信者

C1 End User

C2 Service Provider(又は`MLS_TO`で決定された受信Service Provider)

Network上の逆方向通信

C3 → C2を経由

C3 → C2(又は`MLS_TO`で決定された受信Service Provider)

主目的

business documentのvalidation結果

C3での処理結果及びC4へのdelivery status

2. AP、AB、REとInvoice Responseの違い

2.1 同じコードでも意味が違う

MLR(旧)とMLS(新)はどちらも`AP`、AB、`RE`を使用しますが、その意味は同じではありません。

コード MLR(旧) MLS(新)

AP

validationをfatal errorなしで通過した

C4への配送が成功し、C3が確認可能なacknowledgementを得た

AB

文書は受領したがconformance validationを実施していない

C4へ転送したが、C3には到達を確認する方法がない

RE

validation等に問題があり、それ以上処理しない

conformance violation等でRejectした、又はC4への恒久的な配送に失敗した

特に、

MLR(旧)AP

= validation成功

MLS(新)AP

= C4への配送成功+確認あり

という違いが重要です。[2]

JP PINT Invoiceが公式SchematronをPASSしただけでは、MLS(新)`AP`にはなりません。

2.2 MLS(新)REはvalidation failureだけではない

MLS(新)では、C4への恒久的なdelivery failureも`RE`として扱います。[2]

代表的なStatus Reason Codeには次があります。

Reason Code 意味

SV

XML Schema validation error

BV

Standard Compliance violation、fatal Schematron error等

BW

Schematron warning

FD

C4への恒久的なdelivery failure

Schematron warningである`BW`だけを理由としてbusiness documentをRejectすることはできません。

また、MLS(新)のReject理由はclosed listとして整理されており、各Service Providerが任意の独自理由で`RE`を返す仕組みではありません。

2.3 Invoice Responseは業務応答

Invoiceの業務処理状況をSellerへ通知するのはMLS(新)ではなく、*Invoice Response(業務応答)*です。[10]

コード 意味

AB

BuyerがreadableなInvoiceを受領し、処理へ回せる状態

IP

BuyerのシステムでInvoice処理を開始した

UQ

問い合わせ中

CA

条件付きで受け入れた

RE

BuyerがInvoiceをそれ以上処理しない

AP

BuyerがInvoiceを最終承認した

PD

支払処理を開始又は支払済み

同じ`AP`でも、

MLR(旧)AP

= 文書validation成功

MLS(新)AP

= C4への配送成功・確認あり

Invoice Response AP

= BuyerによるInvoiceの業務上の最終承認

と意味が異なります。

したがって、

message / delivery status

        = MLS(新)

business processing status

        = Invoice Response

と分けて考える必要があります。

3. JP PINT InvoiceとSelf Billingでの扱い

図2 JP PINT InvoiceとSelf BillingにおけるMLSの向き

図2は、通常のJP PINT InvoiceとSelf Billing Invoiceで、C1からC4へのbusiness documentの向きと、C3から送信されるMLS(新)の基本的な向きを対比したものです。C1/C4をSeller/Buyerに固定して理解するのではなく、そのbusiness documentにおけるsender/receiverの役割として理解する必要があります。

3.1 通常のJP PINT Invoice

図2上段に示すように、通常のJP PINT Invoiceでは、

Seller C1

    |

    v

Seller側 C2

    |

    v

Buyer側 C3

    |

    v

Buyer C4

となります。

MLS(新)は、

Buyer側 C3

    |

    | MLS(新)

    v

Seller側 C2

へ返されます。

これは`MLS_TO`で別の有効な受信Service Providerを指定していない場合の基本形です。`MLS_TO`が有効な場合には、そのfallback chainで決定されたService Providerが受信者になります。[3]

SellerであるC1へMLS(新)が直接送信されるわけではありません。

したがって、SellerがMLS(新)の結果を知るためには、C2であるService ProviderがUI、API、notification等によってC1へ情報を提供する必要があります。

3.2 Self Billing Invoiceでは方向が逆になる

図2下段に示すように、JP BIS Self Billing Invoice、すなわち仕入明細書ではBuyerがSelf Billing Invoiceを作成し、Sellerへ送ります。

Buyer C1

    |

    v

Buyer側 C2

    |

    v

Seller側 C3

    |

    v

Seller C4

この場合のMLS(新)は、

Seller側 C3

    |

    | MLS(新)

    v

Buyer側 C2

へ返されます。

ここでも`MLS_TO`が有効に指定されていれば、実効受信者はそのfallback chainによって決定されます。[3]

C1を常にSeller、C4を常にBuyerと固定的に考えてはいけません。

3.3 Self Billingの業務上の異議はMLS(新)ではない

Self Billing Invoiceについて、

XML Schemaに違反している

JP PINT Self Billingのfatal ruleに違反している

SellerであるC4へ配送できない

といった問題はMLS(新)の領域です。

一方、

数量が違う

単価が合意内容と違う

取引内容が違う

仕入明細書の内容にSellerが同意しない

といった問題はbusiness levelの問題です。

MLS(新)`RE`を、Sellerによる仕入明細書の業務上の拒否と解釈してはいけません。

4. MLS(新)の導入とMLR(旧)の廃止

4.1 移行スケジュール

図3 MLS導入とMLR廃止のスケジュール

図3に示すように、OpenPeppolの Peppol MLR Deprecation and Phase-out Plan v1.0.0 では、MLR廃止はMLS導入と連動して進められます。[7][8]

Milestone 日付 内容

T1

2026年7月1日

MLSへの移行期間開始。MLS関連仕様が適用され、各SPはMLSの送受信に向けた実装・準備を開始する。この時点ではMLRは引き続き利用可能であり、MLSへの切替えはまだ必須ではない。

T2

2027年3月1日

MLS sending activation window開始。MLS送信を開始したSPは、そのbusiness documentについてMLR送信を停止する。

T3

2027年4月1日

すべてのSPでMLS送信が必須。SLRも適用。MLRは例外的なfallbackのみ。

4.2 同一文書にMLR(旧)とMLS(新)を両方返さない

移行期間中にはMLR(旧)とMLS(新)が共存します。

しかし、同じbusiness documentについて両方を返すことは認められていません。

One business document

MUST only be responded with

either MLR or MLS.

両方を扱える場合にはMLSが優先されます。

4.3 MLS_TYPE、MLS_TO、SLR

SBDH v2.0.2では、MLSのために`MLS_TYPE`と`MLS_TO`が追加されています。`MLS_TYPE`では、C2が応答方法を指定できます。[1][2]

値 意味

FAILURE_ONLY

negative MLSである`RE`の場合だけ返す

ALWAYS_SEND

`RE`に加えて、positive MLSである`AP`又は`AB`も返す

デフォルトは`FAILURE_ONLY`です。[6]

また`MLS_TO`によってMLSの送信先を指定できます。`MLS_TO`がない場合、又は指定値を利用できない場合には、規定されたfallback chainに従って実効受信者が決定されます。[2][3]

Service Provider Identification Scheme(SPIS)と`0242`

図4 MLSのSender/ReceiverとSPIS 0242

図4に示すように、MLS SBDHではC1/C4のEnd Userではなく、MLSを送受信するService ProviderをSender/Receiverとして識別します。その識別に使用するのがService Provider Identification Scheme(SPIS)です。

MLSでは、SBDHのSender及びReceiverにEnd UserのParticipant IDを使用せず、Service Providerを識別するための Service Provider Identification Scheme(SPIS) を使用します。MLS SBDHのparty identifierは`iso6523-actorid-upis`を使用し、そのParticipant Identifier Schemeは`0242`です。SenderはMLSを送信するC3、Receiverは`MLS_TO`のfallback chainによって決定された実効的なMLS受信Service Providerです。End Userの識別子をSender又はReceiverとして使用してはいけません。[3]

0242`は個々のService Providerそのものを表す番号ではなく、OpenPeppol Service Provider Identification Scheme を表すscheme codeです。SPISの識別子本体であるSPID(Service Provider ID)は、必須の6桁`Main ID、任意の`Peppol Use Case ID`、任意の`Service Provider Suffix`から構成されます。`Main ID`はService Providerを一意に識別する6桁番号で、OpenPeppolによって割り当てられます。これは物理的なAPサーバー1台ごとに別番号が発行されるという意味ではなく、OpenPeppol Service Providerを識別するMain IDです。必要に応じてUse Case IDやService Provider Suffixを付加して用途やSP内部の識別を拡張できます。[4][5]

0242:000270

この例では、

0242    = SPISを示すParticipant Identifier Scheme
000270  = OpenPeppolが割り当てた6桁のMain ID

という関係になります。したがって、`0242`だけでは特定のService Providerを識別できません。`0242`と、そのSPに割り当てられたMain IDを組み合わせてService Providerを識別します。

MLSのOperational Guidelineでは、MLS関連のParticipant Identifier Schemeはすべて`0242`とされ、Main IDを使用する基本形は、

0242:<6桁のMain ID>

です。さらにMLS用のUse Case IDを使用する場合には、例えば、

0242:987654-MLS
0242:987654-MLS.svc01

のような形式も使用できます。[3]

これは、例えば日本のEnd Userを識別するParticipant Identifier Schemeの一つである`0188`などとは役割が異なります。

End Userの識別
  0188:...

Service Providerの識別
  0242:000270

つまりMLSでは、C1/C4のEnd Userではなく、C2/C3側のService ProviderをSPISで明示的に識別する設計になっています。[3][5]

さらに、M1、M2、M3という時刻が重要になります。

時刻 意味

M1

元business documentをC2が送信したAS4 timestamp

M2

C3がMLSを送信したAS4 timestamp

M3

C2がMLSを受信した時刻

対象となるメッセージについて、

M2 - M1 <= 20分

M3 - M1 <= 25分

というService Level Requirementが規定され、99.5%の達成率が求められます。[3][6]

したがってMLS対応には、

  • 元business documentとのcorrelation

  • M1、M2、M3の記録

  • retry / queue

  • SMP capability

  • MLS_TO

  • MLS_TYPE

なども含まれます。

5. JP PINTのvalidationとMLS(新)のReject

5.1 BIS本文には計算規則がある

MLS必須化によって、JP PINTでは「何をMLS(新)`RE`にするのか」が重要になります。

例えば、日本の消費税についてはTax category taxable amountである`IBT-116`を、

IBT-116

 =

該当するInvoice line net amount(IBT-131)の合計

 +

該当するDocument level charge amount(IBT-099)の合計

 -

該当するDocument level allowance amount(IBT-092)の合計

としてTax category code及びTax rateごとに計算し、そのうえで、

IBT-117

 =

IBT-116 × IBT-119 / 100

としてTax category tax amountを計算します。[12]

5.2 Schematronとは何を検証するものか

PeppolのInvoice validationでは、XML SchemaとSchematronが異なる役割を担っています。

XML Schemaは主として、

要素が存在するか

要素の並びが正しいか

文字列、数値、日付などのデータ型が正しいか

といったXML文書としての構造を検証します。

一方、SchematronはXPathを使用して、XML Schemaだけでは表現しにくいbusiness ruleを検証します。

例えば、

Invoice total amount

 =

Line amountの合計

 +

Charge

 -

Allowance

のような複数項目間の計算関係や、

Tax category code = S

である場合には

Tax rateが必要

といった条件付きのルールを機械的に検証できます。

検証 主な対象 例

XML Schema

XML構造、要素、属性、データ型

必須要素が存在するか、数値項目に文字列が入っていないか

Schematron

Business Rule、項目間関係、計算規則、条件

合計金額が明細の合計と一致するか、条件に応じた項目が設定されているか

Peppolでは、BISやSemantic Modelで定義したBusiness TermがUBLなどのXML要素へBindingされ、そのXML文書に対してSchematronによるvalidationが行われます。

BIS / Semantic Model

        |

        v

Business Rules

        |

        v

Syntax Binding

        |

        v

UBL XML

        |

        v

Schematron

        |

        v

PASS / warning / fatal

したがってSchematronは、単なるXML文法チェックではありません。

BISで定義されたbusiness ruleについて、実際に交換されるXML documentがそのルールに適合しているかを客観的に判定するためのmachine-readable validation artefactです。

5.3 Schematron ruleはXPathで項目間の関係を検証する

Schematronでは、通常、対象となるXML要素をXPathで選択し、その値や他の要素との関係を`test`として記述します。

概念的には、

<rule context="...">

    <assert test="計算条件">

        Business rule violation

    </assert>

</rule>

のような形になります。

Schematron の <assert> では、test 属性に「正しいデータで成立すべき条件」を XPath で記述します。

test の評価結果が true であれば検証に合格し、false であれば assertion failure としてエラーが報告されます。

Schematron validatorは、XMLに記載された値を読み取り、

条件が true

    -> rule PASS

条件が false

    -> validation error

と判定します。

Peppolではruleごとにseverityが設定され、`fatal`や`warning`などとしてvalidation結果が示されます。

MLS(新)との関係では、特に`fatal`となる共通のconformance ruleが重要です。

C3が受信したbusiness documentについて公式Schematronのfatal errorを検出した場合には、Standard Compliance violationとしてMLS(新)の`RE`につながり得るためです。

5.4 Schematronで検出されない計算規則

この問題について、OpenPeppol Helpdeskへ次のIssueを登録しています。

PEPPOL-23582

JP PINT 2025-Q4 validation defect:

Schematron does not appear to validate calculation rules defined in JP PINT BIS

JP PINT 2025-Q4 の検証不備:

JP PINT BISで規定されている計算規則がSchematronで検証されていない可能性
Note
JP PINT BISでは、課税対象額や税額、合計金額などについて、項目間の計算関係がBusiness Ruleとして規定されています。

しかし、2025-Q4版のSchematronでは、これらの計算規則の一部について対応する検証ルールが実装されておらず、BIS上は不正な値であってもSchematron検証を通過してしまう可能性があります。

BISで計算規則を規定するのであれば、その適合性を機械的かつ客観的に確認できるSchematron ruleも整備する必要があります。

現在のJP PINTでは、

IBT-117

 =

IBT-116 × IBT-119 / 100

についてはSchematronによるvalidationがあります。[13]

しかし、

IBT-116

 =

sum(IBT-131)

 +

sum(IBT-099)

 -

sum(IBT-092)

をTax category code及びTax rateごとに検証するruleなど、BIS本文に規定される一部の計算規則について対応するSchematron validationが確認できないという問題があります。

BIS本文にnormativeな計算規則があっても、その計算を検証するSchematron ruleがvalidation artefactとして実装されていなければ、通常のSchematron validationではその誤りを検出できません。

5.5 課税対象額の例

例えば、10%課税のInvoice line net amount(IBT-131)の合計が100,000円で、該当する文書レベルのcharge及びallowanceがないとします。

Invoice line net amount の合計

= 100,000円

Document level charge

= 0円

Document level allowance

= 0円

したがって、本来のIBT-116

= 100,000円

ところが、Tax breakdownの文書レベルの金額として、意図的に10倍の課税対象額を記載したとします。

IBT-116 = 1,000,000円

IBT-119 =        10%

IBT-117 =   100,000円

この場合でも、最終税額についてだけ確認すれば、

IBT-117

 =

IBT-116 × IBT-119 / 100

100,000

 =

1,000,000 × 10 / 100

となるため、`IBT-117`は報告された`IBT-116`と税率に対して算術的には整合しています。

しかし、本来検証すべき課税対象額は、

IBT-116

 =

100,000 + 0 - 0

 =

100,000円

であり、報告された1,000,000円とは900,000円も異なります。

この例では丸め誤差や端数処理では説明できず、Tax breakdownの課税対象額そのものが明らかに誤っています。

それでも`IBT-117 = IBT-116 × IBT-119 / 100`だけを検証している限り、税額と誤った課税対象額の組合せ自体は整合してしまいます。

したがって重要なのは、最終税額だけでなく、文書レベルのTax breakdownに記載された`IBT-116`が、該当する明細、文書レベルcharge及びallowanceから正しく集計されていることを検証することです。

5.6 明細行金額についても同じ問題がある

同様の問題はInvoice line net amount(IBT-131)にもあります。

明細行金額についてBISが、

Invoice line net amount

 =

Quantity

 × Item net price

 / Item price base quantity

 + Line charge

 - Line allowance

という計算規則を定めているのであれば、報告されたIBT-131がこの式から求めた値と一致することもmachine-readable ruleで確認する必要があります。

例えば、

Quantity = 10

Unit price = 1,000円

Price base quantity = 1

Charge = 0円

Allowance = 0円

なら、

正しいIBT-131

 =

10 × 1,000 / 1

 =

10,000円

です。

ところが、

IBT-131 = 12,000円

と報告し、その誤った金額をそのまま文書レベル合計へ使用すると、

IBT-106

 =

sum(IBT-131)

という集計だけは一致させることができます。

したがって、単価・数量からIBT-131を再計算するruleと、IBT-131からIBT-106を集計するruleは、それぞれ別にvalidationする必要があります。

5.7 `u:slack()`を使った1円の許容差

金額計算のvalidationでは、計算方法や丸め処理の違いによって、ごく小さな差額が生じる場合があります。

Peppol BIS Billingでは、このような差を扱うために`u:slack()`関数が使用されています。[14]

例えば、次のような関数です。

<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="diff" as="xs:decimal"/>

    <sequence select="

        xs:decimal($exp + $diff) >= $val

        and

        xs:decimal($exp - $diff) <= $val"/>

</function>

ここで、

$exp   = documentに記載された金額

$val   = ruleから計算した金額

$diff  = 許容する差額

です。

したがって、

u:slack($reportedAmount, $calculatedAmount, 1)

とすると、

| reportedAmount - calculatedAmount | <= 1

すなわち、円建てのJP PINT Invoiceであれば、計算結果との差を*±1円まで許容*するvalidationとすることができます。

Note
ここでの`1`は、JP PINTの円建て計算向けの提案値です。既存のPeppol BIS Billingで用いられている許容差をそのまま引用するものではありません。

5.8 Schematron追加案:IBT-131

Invoice line net amountについては、数量、単価、価格基準数量、明細行charge及びallowanceから計算した値と、実際に報告されたIBT-131を比較します。

以下のrule IDは提案用であり、公式rule IDではありません。

<rule context="cac:InvoiceLine | cac:CreditNoteLine">

    <let name="lineExtensionAmount"

         value="

           if (cbc:LineExtensionAmount)

           then xs:decimal(cbc:LineExtensionAmount)

           else 0"/>

    <let name="quantity"

         value="

           if (/ubl-invoice:Invoice)

           then

             (if (cbc:InvoicedQuantity)

              then xs:decimal(cbc:InvoicedQuantity)

              else 1)

           else

             (if (cbc:CreditedQuantity)

              then xs:decimal(cbc:CreditedQuantity)

              else 1)"/>

    <let name="priceAmount"

         value="

           if (cac:Price/cbc:PriceAmount)

           then xs:decimal(cac:Price/cbc:PriceAmount)

           else 0"/>

    <let name="baseQuantity"

         value="

           if (cac:Price/cbc:BaseQuantity

               and xs:decimal(cac:Price/cbc:BaseQuantity) != 0)

           then xs:decimal(cac:Price/cbc:BaseQuantity)

           else 1"/>

    <let name="chargesTotal"

         value="

           sum(

             cac:AllowanceCharge[

               normalize-space(cbc:ChargeIndicator) = 'true'

             ]/cbc:Amount/xs:decimal(.)

           )"/>

    <let name="allowancesTotal"

         value="

           sum(

             cac:AllowanceCharge[

               normalize-space(cbc:ChargeIndicator) = 'false'

             ]/cbc:Amount/xs:decimal(.)

           )"/>

    <let name="calculatedLineAmount"

         value="

           ($quantity * ($priceAmount div $baseQuantity))

           + $chargesTotal

           - $allowancesTotal"/>

    <assert id="JP-PINT-PROPOSAL-LINE-AMOUNT"

            flag="fatal"

            test="

              u:slack(

                $lineExtensionAmount,

                $calculatedLineAmount,

                1

              )">

        Invoice line net amount MUST equal the calculated

        line amount within a tolerance of 1 JPY.

    </assert>

</rule>

例えば、計算結果が10,000円の場合、

 9,999円   PASS

10,000円   PASS

10,001円   PASS

 9,998円   FAIL

10,002円   FAIL

となります。

5.9 Schematron追加案:IBT-116

より重要なのが、Tax category taxable amount(IBT-116)のvalidationです。

BIS本文の計算関係は、

IBT-116

 =

同じTax category code及びTax rateの

  sum(IBT-131)

+

  sum(IBT-099)

-

  sum(IBT-092)

です。

これについても、報告されたIBT-116と、明細等から再計算した金額を`u:slack()`で比較できます。

以下も提案用の例です。

<rule context="cac:TaxTotal/cac:TaxSubtotal">

    <let name="taxCategoryCode"

         value="

           normalize-space(cac:TaxCategory/cbc:ID)"/>

    <let name="taxRate"

         value="

           if (cac:TaxCategory/cbc:Percent)

           then xs:decimal(cac:TaxCategory/cbc:Percent)

           else 0"/>

    <let name="reportedTaxableAmount"

         value="

           xs:decimal(cbc:TaxableAmount)"/>

    <let name="lineTotal"

         value="

           sum(

             /ubl-invoice:Invoice/cac:InvoiceLine[

               cac:Item/cac:ClassifiedTaxCategory[

                 normalize-space(cbc:ID) = $taxCategoryCode

                 and

                 (

                   if (cbc:Percent)

                   then xs:decimal(cbc:Percent)

                   else 0

                 ) = $taxRate

               ]

             ]/cbc:LineExtensionAmount/xs:decimal(.)

           )"/>

    <let name="chargeTotal"

         value="

           sum(

             /ubl-invoice:Invoice/cac:AllowanceCharge[

               normalize-space(cbc:ChargeIndicator) = 'true'

               and

               cac:TaxCategory[

                 normalize-space(cbc:ID) = $taxCategoryCode

                 and

                 (

                   if (cbc:Percent)

                   then xs:decimal(cbc:Percent)

                   else 0

                 ) = $taxRate

               ]

             ]/cbc:Amount/xs:decimal(.)

           )"/>

    <let name="allowanceTotal"

         value="

           sum(

             /ubl-invoice:Invoice/cac:AllowanceCharge[

               normalize-space(cbc:ChargeIndicator) = 'false'

               and

               cac:TaxCategory[

                 normalize-space(cbc:ID) = $taxCategoryCode

                 and

                 (

                   if (cbc:Percent)

                   then xs:decimal(cbc:Percent)

                   else 0

                 ) = $taxRate

               ]

             ]/cbc:Amount/xs:decimal(.)

           )"/>

    <let name="calculatedTaxableAmount"

         value="

           $lineTotal

           + $chargeTotal

           - $allowanceTotal"/>

    <assert id="JP-PINT-PROPOSAL-TAXABLE-AMOUNT"

            flag="fatal"

            test="

              u:slack(

                $reportedTaxableAmount,

                $calculatedTaxableAmount,

                1

              )">

        Tax category taxable amount MUST equal

        the sum of line net amounts plus document level

        charges minus document level allowances

        for the same tax category and tax rate,

        within a tolerance of 1 JPY.

    </assert>

</rule>

このruleのポイントは、単にInvoice全体の明細を合計するのではなく、

Tax category code

       +

Tax rate

が同じものだけを選択して集計することです。

例えば、

10%対象 IBT-131 合計       100,000円

10%対象 IBT-099                 0円

10%対象 IBT-092                 0円

計算されたIBT-116          100,000円

の場合、

報告 IBT-116 =  99,999円   PASS

報告 IBT-116 = 100,000円   PASS

報告 IBT-116 = 100,001円   PASS

報告 IBT-116 = 100,002円   FAIL

となります。

先の例のように、

報告 IBT-116 = 1,000,000円

であれば、

計算値 =   100,000円

報告値 = 1,000,000円

差額   =   900,000円

であり、1円のslackを大きく超えるため、明確に`fatal`となります。

5.10 Schematron PASSとBIS適合は同じではない

Schematronで検出されない

        ≠

BIS本文の規則が存在しない

BIS本文にnormativeな計算規則として規定されているのであれば、business documentは本来その規則にも適合する必要があります。

また、

公式Schematron PASS

        ≠

BIS本文のすべてのnormative ruleを

検証済み

です。

Schematronは、それ自身に実装されているruleしか検証できません。

一方で、

Schematronで検出されない

        ≠

各C3が独自validatorを実装する義務がある

とも考える必要があります。

5.11 MLS(新)では相互運用性問題になる

各C3が独自validationを行うと、例えば、

                  同じJP PINT Invoice

                           |

              +------------+------------+

              |                         |

            C3-A                      C3-B

              |                         |

     公式Schematronのみ          独自計算validation

              |                         |

            PASS                      FAIL

              |                         |

         C4へ配送                MLS(新)RE / BV

となり、同じJP PINT Invoiceについて受信側Service Providerごとに結果が異なる可能性があります。

これは単なるvalidator品質の問題ではなく、Peppolネットワークにおけるinteroperabilityの問題です。

5.12 共通validation artefactが重要になる

MLS必須化後は、

BIS / Semantic Model

        |

        v

Business Rules

        |

        v

公式validation artefacts

        |

        v

共通の適合性判定

        |

        v

必要な場合のみ

MLS(新)RE

という関係を明確にする必要があります。

特に、MLSによるRejectの根拠とする計算ruleについては、各Service Providerの独自実装に任せるのではなく、共通のmachine-readable validation ruleとして提供することが望まれます。

また、

  • BIS本文

  • Semantic Model

  • Syntax Binding

  • Business Rules

  • Schematron

に矛盾がある場合には、各Service Providerが独自にどれかを正しいと判断して`RE`を返すのではなく、Japan PA / OpenPeppolへSpecification defectとして報告し、規定又はvalidation artefactを共通ルールとして修正することが重要です。

5.13 提言

JP PINT BIS本文にnormativeな計算ruleとして規定されている金額については、対応するSchematron ruleを整備することを提案します。

特に、

対象 検証すべき関係

IBT-131

数量、単価、基準数量、明細charge及びallowanceから明細行金額を再計算

IBT-106

各IBT-131を合計して文書レベルの明細行合計と照合

IBT-116

Tax category及びTax rateごとにIBT-131、IBT-099及びIBT-092から課税対象額を再計算

IBT-117

IBT-116とIBT-119からTax category tax amountを再計算

という一連の計算チェーンを共通Schematronで検証できるようにすることが望まれます。

Quantity / Price

      |

      v

   IBT-131

      |

      +------------------+

      |                  |

      v                  v

   IBT-106        Tax category別集計

                         |

                         v

                      IBT-116

                         |

                         v

                      IBT-117

円建ての場合には、例えば、

u:slack(

    reported value,

    calculated value,

    1

)

によって±1円の許容差を含めた客観的な適合性判定を行う方法が考えられます。

重要なのは、1円という許容差を設けることによって計算ruleを曖昧にすることではありません。

むしろ、

BISで規定された計算式

        |

        v

Schematronで再計算

        |

        v

u:slack(..., 1)

        |

        +-- 差額 <= 1円 -> PASS

        |

        +-- 差額 >  1円 -> fatal

とすることにより、許容する差額の範囲まで含めて共通ルールとして明確にできます。

BISで計算規則をnormativeに定義するのであれば、その規則に対する客観的な適合性判定を可能とするSchematron ruleも原則として提供するべきです。

これにより、各Service Providerが異なる独自ロジックで計算妥当性を判断することを避け、同じJP PINT Invoiceに対して共通のvalidation結果を得られるようにすることができます。

これは単なるvalidatorの品質改善ではなく、MLS(新)によるRejectを含めたPeppol Network全体のinteroperabilityを確保するための要件と考えます。

5.14 まとめ

MLR(旧)からMLS(新)への移行は、単なる名称変更ではありません。

MLR(旧)

= End User間のbusiness documentとして

  validation結果を通知

  (Peppol Network上ではC3→C2を経由)

MLS(新)

= C3自身がC2(又は`MLS_TO`で決定された受信SP)へ返す

  message / delivery status

Invoice Response

= Invoiceのbusiness processing status

  Buyer → Seller

特に、同じ`AP`、AB、`RE`でも意味が異なる点に注意が必要です。

MLS必須化によって、JP PINTの公式validation artefactの役割もより重要になります。

JP PINT BIS本文にnormativeな計算ruleが存在していても、公式Schematronでその一部が検証されていない場合、各Service Providerによる独自validationが異なるMLS結果を生む可能性があります。

そのため、

  • JP PINT BISのnormative requirements

  • Business Rules

  • 公式Schematronその他のvalidation artefacts

  • MLS(新)`RE`の条件

を整合させることが、これまで以上に重要になると考えます。

参考文献


投稿日

カテゴリー:

,

投稿者:

タグ:

コメント

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です