ZUGFeRD / mustangproject

Open Source Java e-Invoicing library, validator and tool (Factur-X/ZUGFeRD, UNCEFACT/CII XRechnung)
http://www.mustangproject.org
Apache License 2.0
234 stars 132 forks source link

Missing Field for Support Separate VAT Exemption Reason Text (BT-120) and VAT Exemption Reason Code (BT-121) in XML Generation for XRechnung #541

Open fktrdui opened 2 weeks ago

fktrdui commented 2 weeks ago

Based on the cii-xr.xsl and the official XRechnung specification, fields VAT exemption reason text (BT-120) and VAT exemption reason code (BT-121) should be provided as distinct tags within the XML structure whenever the CategoryCode is set to non-standard values like AE.

<xsl:variable name="bg-contents" as="item()*">
<!-- Der Pfad /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:ApplicableTradeTax der Instanz in konkreter Syntax wird auf 6 Objekte der EN 16931 abgebildet.  -->
<xsl:apply-templates mode="BT-116" select="./ram:BasisAmount"/>
<xsl:apply-templates mode="BT-117" select="./ram:CalculatedAmount"/>
<xsl:apply-templates mode="BT-118" select="./ram:CategoryCode"/>
<xsl:apply-templates mode="BT-119" select="./ram:RateApplicablePercent"/>
<xsl:apply-templates mode="BT-120" select="./ram:ExemptionReason"/>
<xsl:apply-templates mode="BT-121" select="./ram:ExemptionReasonCode"/>
</xsl:variable>

Problem Details: Currently, Product.java lacks a dedicated field or method to set a VATExemptionReasonCode, making it impossible to represent BT-121 (the exemption reason code) within the XRechnung XML output. ZUGFeRD2PullProvider currently fills calling getTaxExemptionReason() which returns values "Intra-community supply" or "Reverse Charge" as BT-120, however, there is currently no provision to output the required BT-121. Expected XML Structure Example:

<ram:ApplicableTradeTax>
    <ram:TypeCode>VAT</ram:TypeCode>
    <ram:ExemptionReason>Reverse Charge</ram:ExemptionReason>
    <ram:ExemptionReasonCode>VATEX-EU-AE</ram:ExemptionReasonCode>
    <ram:CategoryCode>AE</ram:CategoryCode>
    <ram:RateApplicablePercent>0.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>

Proposed Solution:

  1. Introduce a field for VAT exemption reason code (BT-121) in Product.java or IZUGFeRDExportableProduct, allowing for flexible capture and configuration of this information.
  2. Modify ZUGFeRD2PullProvider to populate both (BT-120) and (BT-121) fields when CategoryCode is set to a non-standard code like AE.
JohnHuynh commented 1 day ago

I have the same issue. I tried to set the ram:ExemptionReason (BT-120) via setTaxExemptionReason(). And somehow the validation error still occurs, even though the error states that it is an or condition, i.e., only one of both (BT-120 or BT-121) has to be true.

JohnHuynh commented 1 day ago

Proposed Solution:

Introduce a field for VAT exemption reason code (BT-121) in Product.java or IZUGFeRDExportableProduct, allowing for flexible capture and configuration of this information. Modify ZUGFeRD2PullProvider to populate both ram:ExemptionReason (BT-120) and ram:ExemptionReasonCode (BT-121) fields when CategoryCode is set to a non-standard code like AE.

I'm not sure but the problem might be that the validation is incorrect instead of the xml being incorrect. I got this suspicion because I downloaded an official example from here and validated the "EN16931_Innergemeinschaftliche_Lieferungen.pdf" against the mustang validator:

ZUGFeRDValidator validator = new ZUGFeRDValidator();
validator.validate("./EN16931_Innergemeinschaftliche_Lieferungen.pdf");

And the validation still fails. Is there maybe a bug in validation?