Search Posts

Views: 336

消費税額は整数

オープン・ペポルのスキーマトロンルールの中に日本固有のアラインド・ルール
[aligned-ibr-jp-06]-Tax category tax amount in accounting currency (ibt-190) shall be rounded to integer.
消費税額は、整数に丸めなければならない。
というものがあります。

明細行の請求金額には小数点以下の数値も

それでは、それ以外の金額も当然のように整数でしょうか。
業界によっては、請求書の明細行の金額(ibt-131 Invoice line net amount)に小数点以下の数値を表記しているところもあるそうです。
オープン・ペポルのデジタルインボイスが採用されている日本以外の国では、小数点以下の金額表記がありますので、デジタルインボイスにも当然ですが小数点以下の数値があります。

明細行の金額合計は整数?

請求書の内訳で表記される明細行の金額の合計についてオープン・ペポルのシェアド・ルールでは、次のルールが定義されています。
[ibr-co-10]-Sum of Invoice line net amount (ibt-106) = Σ Invoice line net amount (ibt-131).
請求書に表記される明細行の金額合計は、明細行の金額を足し合わせた値でなければならない。

context cac:LegalMonetaryTotal
test条件
(
  xs:decimal(cbc:LineExtensionAmount) =
  (
    round(
      sum(
        //(cac:InvoiceLine|cac:CreditNoteLine)/xs:decimal(cbc:LineExtensionAmount)
      ) * 10 * 10
    ) div 100
  )
)

例えば、粒コショー 50g 1452円を70g購入したときには、2,032.8円となりますがこの金額が明細行で2032.8と表記された場合どのような表記が可能でしょうか。
上記[ibr-co-10]ルールでは、
round(sum(2032.8)*10*10) = 203280
round(sum(2032.8)*10*10) div 100 = 2032.8
ですから、請求書に表記される明細行の金額合計を、2032.8でなく2039とするとエラーとなり、アクセスポイントのチェックにかかり送信できません。

この場合、丸めるための金額(ibt-114 Rounding amount)を使用してここに0.2などの端数金額を記載し、請求金額(ibt-115 Amount due for payment)を整数に丸めて記載することになります。

明細行の金額を整数とする?

PINT JP 0.9には、次のルールがありました。

[jp-br-09]-Invoice line net amount (ibt-131) = 
  Item net price (ibt-146) X Invoiced quantity (ibt-129) ÷ Item price base quantity (ibt-149) + 
  Invoice line charge amount (ibt-141) – 
  Invoice line allowance amount (ibt-136).

スキーマトロンでは、基準数量(ibt-149 Item price base quantity)があるときは、
明細行金額 = 単価 x 数量 / 基準数量
が正しく計算されているか検証するもので、割り算で割り切れないときには端数が小数点以下の数値として記載されるので、比較対象の明細行金額が整数のときにはエラーとなります。

(exists(cac:Price/cbc:BaseQuantity) and
  (
    (exists(cac:AllowanceCharge[cbc:ChargeIndicator=false()]) and
      exists(cac:AllowanceCharge[cbc:ChargeIndicator=true()]) and
      (cbc:LineExtensionAmount =
        cbc:InvoicedQuantity * (cac:Price/cbc:PriceAmount div cac:Price/cbc:BaseQuantity) +
        cac:AllowanceCharge[cbc:ChargeIndicator=true()]/cbc:Amount -
        cac:AllowanceCharge[cbc:ChargeIndicator=false()]/cbc:Amount))       or
    (
      not(
        exists(cac:AllowanceCharge[cbc:ChargeIndicator=false()])) and
      exists(cac:AllowanceCharge[cbc:ChargeIndicator=true()]) and
      (cbc:LineExtensionAmount =
        cbc:InvoicedQuantity * (cac:Price/cbc:PriceAmount div cac:Price/cbc:BaseQuantity) +
        cac:AllowanceCharge[cbc:ChargeIndicator=true()]/cbc:Amount))       or
    (exists(cac:AllowanceCharge[cbc:ChargeIndicator=false()]) and
      not(exists(cac:AllowanceCharge[cbc:ChargeIndicator=true()])) and
      (cbc:LineExtensionAmount =
        cbc:InvoicedQuantity * (cac:Price/cbc:PriceAmount div cac:Price/cbc:BaseQuantity) -
        cac:AllowanceCharge[cbc:ChargeIndicator=false()]/cbc:Amount))       or
    (
      not(
        exists(cac:AllowanceCharge[cbc:ChargeIndicator=false()])) and
      not(exists(cac:AllowanceCharge[cbc:ChargeIndicator=true()])) and
      (cbc:LineExtensionAmount =
        cbc:InvoicedQuantity * (cac:Price/cbc:PriceAmount div cac:Price/cbc:BaseQuantity)))))     or
(
  not(
    exists(cac:Price/cbc:BaseQuantity)) and
  (
    (exists(cac:AllowanceCharge[cbc:ChargeIndicator=false()]) and
      exists(cac:AllowanceCharge[cbc:ChargeIndicator=true()]) and
      (cbc:LineExtensionAmount =
        cbc:InvoicedQuantity * cac:Price/cbc:PriceAmount +
        cac:AllowanceCharge[cbc:ChargeIndicator=true()]/cbc:Amount -
        cac:AllowanceCharge[cbc:ChargeIndicator=false()]/cbc:Amount))       or
    (
      not(
        exists(cac:AllowanceCharge[cbc:ChargeIndicator=false()])) and
      exists(cac:AllowanceCharge[cbc:ChargeIndicator=true()]) and
      (cbc:LineExtensionAmount =
        cbc:InvoicedQuantity * (cac:Price/cbc:PriceAmount  +
          cac:AllowanceCharge[cbc:ChargeIndicator=true()]/cbc:Amount)))       or
    (exists(cac:AllowanceCharge[cbc:ChargeIndicator=false()]) and
      not(exists(cac:AllowanceCharge[cbc:ChargeIndicator=true()])) and
      (cbc:LineExtensionAmount =
        cbc:InvoicedQuantity * (cac:Price/cbc:PriceAmount  -
          cac:AllowanceCharge[cbc:ChargeIndicator=false()]/cbc:Amount)))       or
    (
      not(
        exists(cac:AllowanceCharge[cbc:ChargeIndicator=false()])) and
      not(exists(cac:AllowanceCharge[cbc:ChargeIndicator=true()])) and
      (cbc:LineExtensionAmount =
        cbc:InvoicedQuantity * (cac:Price/cbc:PriceAmount))
    )
  )
)

小数点以下の桁数が2桁までとされている諸外国の場合にも同様の問題が発生しますので、= の判定にslack()関数を使用しています。
この関数は、次のような内容です。

u:slack( exp(xs:decimal), val(xs:decimal), slack(xs:decimal) ) {
  value-of
    xs:decimal($exp + $slack) >= $val and
    xs:decimal($exp - $slack) <= $val
}

計算結果が、記載された値とslack値の範囲内の違いに収まっているか判定するものです。
諸外国では、slack値として0.02が使用されることが多いようですが、日本では、1か2が妥当な値だと思います。
cbc:LineExtensionAmountのページにDraft improved rulesを記載していますのでご確認ください。

このルール自体を廃止することが計画されていますが、C1のプログラム不良や意図的に請求金額を異なる値で請求しても検出できなくなりますのでいかがかなものかと思います。