ConnectingEurope / eInvoicing-EN16931

Validation artefacts for the European eInvoicing standard EN 16931
Other
138 stars 54 forks source link

BR-CO-16 triggered on UBL for 1.3.3 #242

Closed phax closed 3 years ago

phax commented 4 years ago

Hi guys, since the latest 1.3.3 update, the following UBL block is invalid:

 <cac:LegalMonetaryTotal>
    <cbc:LineExtensionAmount currencyID="EUR">10781.25</cbc:LineExtensionAmount>
      <cbc:TaxExclusiveAmount currencyID="EUR">10781.25</cbc:TaxExclusiveAmount>
      <cbc:TaxInclusiveAmount currencyID="EUR">12829.69</cbc:TaxInclusiveAmount>
      <cbc:AllowanceTotalAmount currencyID="EUR">0</cbc:AllowanceTotalAmount>
      <cbc:ChargeTotalAmount currencyID="EUR">0</cbc:ChargeTotalAmount>
      <cbc:PrepaidAmount currencyID="EUR">12829.69</cbc:PrepaidAmount>
      <cbc:PayableRoundingAmount currencyID="EUR">0</cbc:PayableRoundingAmount>
      <cbc:PayableAmount currencyID="EUR">0</cbc:PayableAmount>
  </cac:LegalMonetaryTotal>

I think the calculation model would now require TaxInclusiveAmount to be 0???

[BR-CO-16]-Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) -Paid amount (BT-113) +Rounding amount (BT-114).]]; 

(exists(cbc:PrepaidAmount) and not(exists(cbc:PayableRoundingAmount)) and (xs:decimal(cbc:PayableAmount) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) * 10 * 10) div 100))) or (not(xs:decimal(cbc:PrepaidAmount)) and not(xs:decimal(cbc:PayableRoundingAmount)) and xs:decimal(cbc:PayableAmount) = xs:decimal(cbc:TaxInclusiveAmount)) or (xs:decimal(cbc:PrepaidAmount) and xs:decimal(cbc:PayableRoundingAmount) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) * 10 * 10) div 100) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) * 10 * 10) div 100))) or (not(xs:decimal(cbc:PrepaidAmount)) and xs:decimal(cbc:PayableRoundingAmount) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) * 10 * 10) div 100) = xs:decimal(cbc:TaxInclusiveAmount)))
oriol commented 4 years ago

No, the problem is the expression. Should be

(exists(cbc:PrepaidAmount) and not(exists(cbc:PayableRoundingAmount)) and (xs:decimal(cbc:PayableAmount) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) 10 10) div 100))) or (not(exists(xs:decimal(cbc:PrepaidAmount))) and not(exists(xs:decimal(cbc:PayableRoundingAmount))) and xs:decimal(cbc:PayableAmount) = xs:decimal(cbc:TaxInclusiveAmount)) or (exists(xs:decimal(cbc:PrepaidAmount)) and exists(xs:decimal(cbc:PayableRoundingAmount)) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) 10 10) div 100) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) 10 10) div 100))) or (not(exists(xs:decimal(cbc:PrepaidAmount))) and exists(xs:decimal(cbc:PayableRoundingAmount)) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) 10 10) div 100) = xs:decimal(cbc:TaxInclusiveAmount)))

phax commented 4 years ago

Okay thanks. Meaning there will be a 1.3.4 release soon?

oriol commented 4 years ago

spring 2021 release

phax commented 4 years ago

Ah okay. That renders the 1.3.3 release quite useless if such a showstopper bug is in it. Can you eventually consider releasing a 1.3.3.1 bugfix release?

oriol commented 4 years ago

This is an old bug. The error has not been noticed because it only appears when there is a PayableRoundingAmount with value 0.

I would then suggest waiting to the next release to fix the bug.

phax commented 4 years ago

The issue poped up when converting CII documents to UBL and that was not changed. The output validated with 1.3.2 validation artefacts but fails with 1.3.3 - so something in this regard was changed.

phax commented 4 years ago

The problem was caused by commit https://github.com/ConnectingEurope/eInvoicing-EN16931/commit/d925641ab610079574dfad6425d54de1591ac40f which was meant to resolve #222

phax commented 4 years ago

I guess your proposal can be simplified to:

(exists(cbc:PrepaidAmount) and not(exists(cbc:PayableRoundingAmount)) and (xs:decimal(cbc:PayableAmount) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) * 10 * 10) div 100))) or 
(not(exists(cbc:PrepaidAmount)) and not(exists(cbc:PayableRoundingAmount)) and xs:decimal(cbc:PayableAmount) = xs:decimal(cbc:TaxInclusiveAmount)) or 
(exists(cbc:PrepaidAmount) and exists(cbc:PayableRoundingAmount) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) * 10 * 10) div 100) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) * 10 * 10) div 100))) or 
(not(exists(cbc:PrepaidAmount)) and exists(cbc:PayableRoundingAmount) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) * 10 * 10) div 100) = xs:decimal(cbc:TaxInclusiveAmount)))
phax commented 4 years ago

Not emitting PayableRoundingAmount if the value is 0 is a suitable work around

oriol commented 4 years ago

Ok @phax, I have added a test on this and will fix it for the next release.

juskoljo commented 4 years ago

Should this introduced bug be communicated somehow? At least mentioned in "News and noteworthy" section ✌️

oriol commented 4 years ago

Should this introduced bug be communicated somehow? At least mentioned in "News and noteworthy" section ✌️

Added a Note in the Release explaining the error.

senikk commented 3 years ago

@oriol where is this note added? Can't see it commited to README.

phax commented 3 years ago

It is referenced at https://github.com/ConnectingEurope/eInvoicing-EN16931/releases/tag/validation-1.3.3