diff --git a/library/src/main/java/org/mustangproject/Product.java b/library/src/main/java/org/mustangproject/Product.java
index 8ca3680b..a472ac4a 100644
--- a/library/src/main/java/org/mustangproject/Product.java
+++ b/library/src/main/java/org/mustangproject/Product.java
@@ -233,6 +233,9 @@ public class Product implements IZUGFeRDExportableProduct {
*/
public Product setReverseCharge() {
isReverseCharge = true;
+ if ((getTaxExemptionReason()==null)||(getTaxExemptionReason().isEmpty())) {
+ setTaxExemptionReason("Reverse charge");
+ }
setVATPercent(BigDecimal.ZERO);
return this;
}
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java
index 6ee5f22e..71402d8b 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java
@@ -120,7 +120,7 @@ public interface IZUGFeRDExportableProduct {
return TaxCategoryCodeTypeConstants.INTRACOMMUNITY;// "K"; // within europe
} else if (isReverseCharge()) {
return TaxCategoryCodeTypeConstants.REVERSECHARGE;// "AE"; // to out of europe...
- } else if (getVATPercent().compareTo(BigDecimal.ZERO) == 0) {
+ } else if ((getVATPercent()==null)||(getVATPercent().compareTo(BigDecimal.ZERO) == 0)) {
return TaxCategoryCodeTypeConstants.ZEROTAXPRODUCTS; // "Z"; // zero rated goods
} else {
return TaxCategoryCodeTypeConstants.STANDARDRATE;// "S"; // one of the "standard" rates (not
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java
index cddadf7a..50565ecc 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java
@@ -538,7 +538,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
xml += "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "";
}
xml += "" + currentItem.getProduct().getTaxCategoryCode() + "";
- if (!currentItem.getProduct().getTaxCategoryCode().equals(TaxCategoryCodeTypeConstants.UNTAXEDSERVICE)) {
+ if ((!currentItem.getProduct().getTaxCategoryCode().equals(TaxCategoryCodeTypeConstants.UNTAXEDSERVICE)) && (!currentItem.getProduct().getTaxCategoryCode().equals(TaxCategoryCodeTypeConstants.ZEROTAXPRODUCTS))) {
xml += "" + vatFormat(currentItem.getProduct().getVATPercent()) + "";
}
xml += "";
diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java
index 74fac56a..61cfd66a 100644
--- a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java
+++ b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java
@@ -23,5 +23,6 @@ public class DocumentCodeTypeConstants {
public static final String CREDITNOTE = "381";
public static final String DEBITNOTE = "84";
public static final String CORRECTEDINVOICE = "384";
+ public static final String SELFBILLING = "389";
public static final String PARTIAL_BILLING = "326";
}
diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/VATrelatedTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/VATrelatedTest.java
new file mode 100644
index 00000000..7cd41ead
--- /dev/null
+++ b/library/src/test/java/org/mustangproject/ZUGFeRD/VATrelatedTest.java
@@ -0,0 +1,153 @@
+
+/** **********************************************************************
+ *
+ * Copyright 2019 Jochen Staerk
+ *
+ * Use is subject to license terms.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *********************************************************************** */
+package org.mustangproject.ZUGFeRD;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+import org.mustangproject.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class VATrelatedTest extends ResourceCase {
+ final String TARGET_PDF_REVERSE = "./target/testout-ReverseCharge.pdf";
+ final String TARGET_PDF_Z = "./target/testout-TaxcodeZ.pdf";
+
+ public void testReverseCharge() {
+
+ String orgname = "Test company";
+ String number = "123";
+ String priceStr = "3.00";
+ BigDecimal price = new BigDecimal(priceStr);
+ try {
+ InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
+
+ ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1();
+ ze.ignorePDFAErrors().load(SOURCE_PDF);
+ ze.setProfile(Profiles.getByName("Extended"));
+
+ ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("extended");
+ // ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr", "55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
+ // .addItem(new Item(new Product("Testprodukt", "", "H84", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)))));
+
+ Product p=new Product("Testprodukt", "", "H87", new BigDecimal(19));
+ p.setReverseCharge();
+ Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
+ .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815"))
+ .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")
+ .setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562")).addVATID("DE0915"))
+ .setNumber(number)
+ .addCharge(new Charge(new BigDecimal(1)).setReasonCode("ABK").setReason("AReason").setTaxPercent(new BigDecimal(19)))
+
+ .addItem(new Item(p, price, new BigDecimal(1.0)));
+ ze.setTransaction(i);
+
+
+ String theXML = new String(ze.getProvider().getXML(), StandardCharsets.UTF_8);
+ assertTrue(theXML.contains("