closes #172, fixes zero rated products, added some lines to the test of the XRechnung, have the XRechnung test actually wriote to file and have the XR test file validated automatically
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
|
|
||||||
### 2.0.1 todo
|
### 2.0.1 todo
|
||||||
|
- confirm that VAT category code switches from S to Z on 0%VAT
|
||||||
|
- 2.1 support kleinunternehmer, reverse charge?
|
||||||
- dont show empty tax number field
|
- dont show empty tax number field
|
||||||
- fail when no bankverbindung?
|
- fail when no bankverbindung?
|
||||||
- fail when xr attrs missing?
|
- fail when xr attrs missing?
|
||||||
- build xr skonto???
|
- build xr skonto???
|
||||||
- *validator not to XR error on ZF files (only notices)
|
- *validator not to XR error on ZF files (only notices)
|
||||||
- xmp errors may not show correctly in log
|
- xmp errors may not show correctly in log
|
||||||
|
- XR test now includes guideline ID #172
|
||||||
|
- support zero-rated goods
|
||||||
2.0.0
|
2.0.0
|
||||||
=====
|
=====
|
||||||
2020-11-12
|
2020-11-12
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ public class Main {
|
|||||||
private static String getUsage() {
|
private static String getUsage() {
|
||||||
return "Usage: --action metrics|combine|extract|a3only|validate|visualize [-d,--directory] [-l,--listfromstdin] [-i,--ignore fileextension, PDF/A errors] | [-h,--help] \r\n"
|
return "Usage: --action metrics|combine|extract|a3only|validate|visualize [-d,--directory] [-l,--listfromstdin] [-i,--ignore fileextension, PDF/A errors] | [-h,--help] \r\n"
|
||||||
+ " --action=metrics\n"
|
+ " --action=metrics\n"
|
||||||
+
|
|
||||||
+ " -d, --directory count ZUGFeRD files in directory to be scanned\n"
|
+ " -d, --directory count ZUGFeRD files in directory to be scanned\n"
|
||||||
+ " If it is a directory, it will recurse.\n"
|
+ " If it is a directory, it will recurse.\n"
|
||||||
+ " -l, --listfromstdin count ZUGFeRD files from a list of linefeed separated files on runtime.\n"
|
+ " -l, --listfromstdin count ZUGFeRD files from a list of linefeed separated files on runtime.\n"
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ package org.mustangproject.ZUGFeRD;
|
|||||||
* @author jstaerk
|
* @author jstaerk
|
||||||
* */
|
* */
|
||||||
|
|
||||||
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
|
public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
|
||||||
@@ -74,10 +72,6 @@ public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
|
|||||||
return BigDecimal.ONE.setScale(4);
|
return BigDecimal.ONE.setScale(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
default String getCategoryCode() {
|
|
||||||
return TaxCategoryCodeTypeConstants.STANDARDRATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* the ID of an additionally referenced document for this item
|
* the ID of an additionally referenced document for this item
|
||||||
* @return the id as string
|
* @return the id as string
|
||||||
|
|||||||
@@ -106,11 +106,12 @@ public interface IZUGFeRDExportableProduct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default String getTaxCategoryCode() {
|
default String getTaxCategoryCode() {
|
||||||
if (isIntraCommunitySupply()) {
|
if (getVATPercent().equals(new BigDecimal(0))) {
|
||||||
|
return "Z"; // zero rated goods
|
||||||
|
} else if (isIntraCommunitySupply()) {
|
||||||
return "K";
|
return "K";
|
||||||
} else {
|
} else {
|
||||||
return "S";
|
return "S"; // one of the "standard" rates (not neccessarily a default rate, even a deducted VAT is standard calculation)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
|
|||||||
BigDecimal percent = currentItem.getProduct().getVATPercent();
|
BigDecimal percent = currentItem.getProduct().getVATPercent();
|
||||||
LineCalculator lc = new LineCalculator(currentItem);
|
LineCalculator lc = new LineCalculator(currentItem);
|
||||||
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(),
|
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(),
|
||||||
currentItem.getCategoryCode());
|
currentItem.getProduct().getTaxCategoryCode());
|
||||||
VATAmount current = hm.get(percent);
|
VATAmount current = hm.get(percent);
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
hm.put(percent, itemVATAmount);
|
hm.put(percent, itemVATAmount);
|
||||||
|
|||||||
@@ -25,9 +25,11 @@ import junit.framework.TestCase;
|
|||||||
import org.mustangproject.*;
|
import org.mustangproject.*;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.mustangproject.ZUGFeRD.ZUGFeRD2PullProvider;
|
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@@ -36,8 +38,8 @@ import static org.xmlunit.assertj.XmlAssert.assertThat;
|
|||||||
|
|
||||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
public class XRTest extends TestCase {
|
public class XRTest extends TestCase {
|
||||||
|
final String TARGET_XML = "./target/testout-XR.xml";
|
||||||
public void testPushExport() {
|
public void testXRExport() {
|
||||||
|
|
||||||
// the writing part
|
// the writing part
|
||||||
|
|
||||||
@@ -45,10 +47,15 @@ public class XRTest extends TestCase {
|
|||||||
String number = "123";
|
String number = "123";
|
||||||
String amountStr = "1.00";
|
String amountStr = "1.00";
|
||||||
BigDecimal amount = new BigDecimal(amountStr);
|
BigDecimal amount = new BigDecimal(amountStr);
|
||||||
|
Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
|
||||||
Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr","55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(0)), amount, new BigDecimal(1.0)));
|
.setSender(new TradeParty(orgname,"teststr","55232","teststadt","DE").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test","+49123456789","test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890","COBADEFXXX")))
|
||||||
|
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"))
|
||||||
|
.setReferenceNumber("991-01484-64")//leitweg-id
|
||||||
|
// not using any VAT, this is also a test of zero-rated goods:
|
||||||
|
.setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(0)), amount, new BigDecimal(1.0)));
|
||||||
|
|
||||||
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
|
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
|
||||||
|
zf2p.setProfile(Profiles.getByName("XRechnung"));
|
||||||
zf2p.generateXML(i);
|
zf2p.generateXML(i);
|
||||||
String theXML = new String(zf2p.getXML());
|
String theXML = new String(zf2p.getXML());
|
||||||
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
||||||
@@ -60,7 +67,13 @@ public class XRTest extends TestCase {
|
|||||||
assertThat(theXML).valueByXPath("//*[local-name()='DuePayableAmount']")
|
assertThat(theXML).valueByXPath("//*[local-name()='DuePayableAmount']")
|
||||||
.asDouble()
|
.asDouble()
|
||||||
.isEqualTo(1);
|
.isEqualTo(1);
|
||||||
|
try {
|
||||||
|
BufferedWriter writer = new BufferedWriter(new FileWriter(TARGET_XML));
|
||||||
|
writer.write(theXML);
|
||||||
|
writer.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,4 +135,28 @@ public class LibraryTest extends ResourceCase {
|
|||||||
assertThat(res).valueByXPath("/validation/summary/@status")
|
assertThat(res).valueByXPath("/validation/summary/@status")
|
||||||
.isEqualTo("valid");
|
.isEqualTo("valid");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* automatically test the xrechnung
|
||||||
|
*/
|
||||||
|
public void testXRValidation() {
|
||||||
|
File tempFile = new File("../library/target/testout-XR.xml");
|
||||||
|
ZUGFeRDValidator zfv = new ZUGFeRDValidator();
|
||||||
|
|
||||||
|
String res = zfv.validate(tempFile.getAbsolutePath());
|
||||||
|
|
||||||
|
assertThat(res).valueByXPath("count(//error)")
|
||||||
|
.asInt()
|
||||||
|
.isEqualTo(0);
|
||||||
|
|
||||||
|
assertThat(res).valueByXPath("count(//notice)")
|
||||||
|
.asInt()
|
||||||
|
.isEqualTo(0);
|
||||||
|
assertThat(res).valueByXPath("/validation/summary/@status")
|
||||||
|
.asString()
|
||||||
|
.isEqualTo("valid");// expect to be valid because XR notices are, well, only notices
|
||||||
|
assertThat(res).valueByXPath("/validation/xml/summary/@status")
|
||||||
|
.asString()
|
||||||
|
.isEqualTo("valid");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user