Merge branch 'master' of https://github.com/ZUGFeRD/mustangproject into master

This commit is contained in:
Ulrich Zielhofer
2020-11-03 15:42:50 +01:00
9 changed files with 497 additions and 218 deletions

View File

@@ -3,16 +3,17 @@
- support for ZF 2.1.1, i.e. "Reference profile" Xrechnung
- ZF 2.1.1 now default (up to 1.7.8 ZF2 could be set but ZF1 was default)
- integrates validator
- removed jaxb #87
- fluent setter api/pushprovider #40
- new xrechnung profile
- visualization? zugferdvisualizer?
- new xrechnung reference profile
- visualization zugferdvisualizer
- migration feature (XSLT upgrade of ZF1 to ZF2) has been improved and moved from the commandline into the library
- german bank account numbers can no longer be specified (dropped in favor of IBAN and BIC)
- factory for xrechnung #86
- moved to Maven central
- complete or discard read into push provider
- integrates validator
- now TransactionCalculator is a dedicated class and no longer mixed up with pullprovider
- validator now additionally supports xrechnung
- modular project setup
- getSellerTradePartyAddress (PR #157 ) thanks to aberndt-hub

View File

@@ -84,7 +84,10 @@ changes to
```
IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(1).setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel.EN16931).load(SOURCE_PDF)) {
```
```
The old Contact class has been corrected to TradeParty. The TradeParty class
can now refer to a (human) Contact from the new Contact() class.
The importer can still be used like
@@ -92,7 +95,41 @@ The importer can still be used like
ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream);
String amount = zi.getAmount();
```
but we are also working on an importer to import into the new invoice class.
but there is also the new invoiceImporter
```
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
Invoice invoice=null;
try {
invoice=zii.extractInvoice();
} catch (XPathExpressionException | ParseException e) {
// handle Exceptions
}
assertFalse(hasExceptions);
// Reading ZUGFeRD
assertEquals("Bei Spiel GmbH", invoice.getOwnOrganisationName());
assertEquals(3, invoice.getZFItems().length);
assertEquals("400.0000", invoice.getZFItems()[1].getQuantity().toString());
assertEquals("160.0000", invoice.getZFItems()[0].getPrice().toString());
assertEquals("Heiße Luft pro Liter", invoice.getZFItems()[2].getProduct().getName());
assertEquals("LTR", invoice.getZFItems()[2].getProduct().getUnit());
assertEquals("7.00", invoice.getZFItems()[0].getProduct().getVATPercent().toString());
assertEquals("RE-20170509/505", invoice.getNumber());
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
assertEquals("2017-05-09",sdf.format(invoice.getIssueDate()));
assertEquals("Bahnstr. 42", invoice.getRecipient().getStreet());
assertEquals("88802", invoice.getRecipient().getZIP());
assertEquals("DE", invoice.getRecipient().getCountry());
assertEquals("Spielkreis", invoice.getRecipient().getLocation());
TransactionCalculator tc=new TransactionCalculator(invoice);
assertEquals(new BigDecimal("571.040000"),tc.getTotalGross());
```
### Using the library to create e-invoices
From maven central fetch
@@ -143,7 +180,33 @@ zf2p.generateXML(i);
String theXML = new String(zf2p.getXML());
```
or can also be used with setTransaction to generate invoice PDFs straight away.
### Embedding ZF1 to ZF2 migration
The functionality is based on the XSLT file in library/src/main/resources/stylesheets/ZF1ToZF2.xsl,
it can be accessed via
```
XMLUpgrader zmi = new XMLUpgrader();
String xml = zmi.migrateFromV1ToV2(xmlName);
Files.write(Paths.get(outName), xml.getBytes());
```
### Embedding ZF2 visualization
In case you don't want to access this functionality over the
commandline you can use
```
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
xml = zvi.visualize(sourceName);
Files.write(Paths.get("factur-x.xml"), xml.getBytes());
```
for the visualizer. The output requires a CSS and a javascript file which are in the
jar's resources as
(/src/main/resources/)xrechnung-viewer.css
(/src/main/respurces/)xrechnung-viewer.js
### Embedding the validator
The validator library also contains the functionality to
read/write ZUGFeRD-invoices like the (smaller) library module.
```
<dependencies>
<dependency>

View File

@@ -2,7 +2,11 @@ package org.mustangproject.ZUGFeRD;
import java.math.BigDecimal;
public class LineCalc {
/***
* the linecalculator does the math within an item line, and e.g. calculates quantity*price.
* @see TransactionCalculator
*/
public class LineCalculator {
private BigDecimal totalGross;
private BigDecimal price;
private BigDecimal priceGross;
@@ -11,7 +15,7 @@ public class LineCalc {
private BigDecimal allowance = new BigDecimal(0);
private BigDecimal charge = new BigDecimal(0);
public LineCalc(IZUGFeRDExportableItem currentItem) {
public LineCalculator(IZUGFeRDExportableItem currentItem) {
if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) {
for (IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) {

View File

@@ -0,0 +1,134 @@
package org.mustangproject.ZUGFeRD;
import java.math.BigDecimal;
import java.util.HashMap;
/***
* The Transactioncalculator e.g. adds the line totals and applies VAT on whole invoices
* @see LineCalculator
*/
public class TransactionCalculator implements IAbsoluteValueProvider {
protected IExportableTransaction trans;
public TransactionCalculator(IExportableTransaction trans) {
this.trans=trans;
}
protected BigDecimal getTotalPrepaid() {
if (trans.getTotalPrepaidAmount() == null) {
return new BigDecimal(0);
} else {
return trans.getTotalPrepaidAmount();
}
}
protected BigDecimal getTotalGross() {
BigDecimal res = getTaxBasis();
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = getVATPercentAmountMap();
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
res = res.add(amount.getCalculated());
}
return res;
}
protected BigDecimal getCharges() {
BigDecimal res = new BigDecimal(0);
IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges();
if ((charges != null) && (charges.length > 0)) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) {
res = res.add(currentCharge.getTotalAmount(this));
}
}
return res;
}
protected BigDecimal getAllowances() {
BigDecimal res = new BigDecimal(0);
IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances();
if ((allowances != null) && (allowances.length > 0)) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
res = res.add(currentAllowance.getTotalAmount(this));
}
}
return res;
}
protected BigDecimal getTotal() {
BigDecimal res = new BigDecimal(0);
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
LineCalculator lc = new LineCalculator(currentItem);
res = res.add(lc.getItemTotalGrossAmount());
}
return res;
}
protected BigDecimal getTaxBasis() {
BigDecimal res = getTotal().add(getCharges()).subtract(getAllowances());
return res;
}
/**
* which taxes have been used with which amounts in this transaction, empty for
* no taxes, or e.g. 19:190 and 7:14 if 1000 Eur were applicable to 19% VAT
* (=190 EUR VAT) and 200 EUR were applicable to 7% (=14 EUR VAT) 190 Eur
*
* @return which taxes have been used with which amounts in this invoice
*/
protected HashMap<BigDecimal, VATAmount> getVATPercentAmountMap() {
HashMap<BigDecimal, VATAmount> hm = new HashMap<>();
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
BigDecimal percent = currentItem.getProduct().getVATPercent();
LineCalculator lc = new LineCalculator(currentItem);
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(),
trans.getDocumentCode());
VATAmount current = hm.get(percent);
if (current == null) {
hm.put(percent, itemVATAmount);
} else {
hm.put(percent, current.add(itemVATAmount));
}
}
IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges();
if ((charges != null) && (charges.length > 0)) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) {
VATAmount theAmount = hm.get(currentCharge.getTaxPercent());
if (theAmount == null) {
theAmount = new VATAmount(new BigDecimal(0), new BigDecimal(0), "S");
}
theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(this)));
BigDecimal factor = currentCharge.getTaxPercent().divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(currentCharge.getTaxPercent(), theAmount);
}
}
IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances();
if ((allowances != null) && (allowances.length > 0)) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
VATAmount theAmount = hm.get(currentAllowance.getTaxPercent());
if (theAmount == null) {
theAmount = new VATAmount(new BigDecimal(0), new BigDecimal(0), "S");
}
theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this)));
BigDecimal factor = currentAllowance.getTaxPercent().divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(currentAllowance.getTaxPercent(), theAmount);
}
}
return hm;
}
@Override
public BigDecimal getValue() {
return getTotal();
}
}

View File

@@ -104,6 +104,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
@Override
public void generateXML(IExportableTransaction trans) {
this.trans = trans;
this.calc=new TransactionCalculator(trans);
boolean hasDueDate=false;
String taxCategoryCode="";
@@ -288,7 +289,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
}
}
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = getVATPercentAmountMap();
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = calc.getVATPercentAmountMap();
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
if (amount != null) {
@@ -329,23 +330,23 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
}
xml = xml + " <ram:SpecifiedTradeSettlementMonetarySummation>\n"
+ " <ram:LineTotalAmount currencyID=\""+trans.getCurrency()+"\">" + currencyFormat(getTotal()) + "</ram:LineTotalAmount>\n" //$NON-NLS-2$
+ " <ram:LineTotalAmount currencyID=\""+trans.getCurrency()+"\">" + currencyFormat(calc.getTotal()) + "</ram:LineTotalAmount>\n" //$NON-NLS-2$
// currencyID=\"EUR\"
+ " <ram:ChargeTotalAmount currencyID=\"" + trans.getCurrency() + "\">0.00</ram:ChargeTotalAmount>\n" // currencyID=\"EUR\"
+ " <ram:AllowanceTotalAmount currencyID=\"" + trans.getCurrency() + "\">0.00</ram:AllowanceTotalAmount>\n" //
// currencyID=\"EUR\"
// + " <ChargeTotalAmount currencyID=\"EUR\">5.80</ChargeTotalAmount>\n"
// + " <AllowanceTotalAmount currencyID=\"EUR\">14.73</AllowanceTotalAmount>\n"
+ " <ram:TaxBasisTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(getTotal()) + "</ram:TaxBasisTotalAmount>\n" //$NON-NLS-2$
+ " <ram:TaxBasisTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(calc.getTotal()) + "</ram:TaxBasisTotalAmount>\n" //$NON-NLS-2$
// //
// currencyID=\"EUR\"
+ " <ram:TaxTotalAmount currencyID=\"" + trans.getCurrency() + "\">"
+ currencyFormat(getTotalGross().subtract(getTotal())) + "</ram:TaxTotalAmount>\n"
+ " <ram:GrandTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(getTotalGross()) + "</ram:GrandTotalAmount>\n" //$NON-NLS-2$
+ currencyFormat(calc.getTotalGross().subtract(calc.getTotal())) + "</ram:TaxTotalAmount>\n"
+ " <ram:GrandTotalAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(calc.getTotalGross()) + "</ram:GrandTotalAmount>\n" //$NON-NLS-2$
// //
// currencyID=\"EUR\"
+ " <ram:TotalPrepaidAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(getTotalPrepaid()) + "</ram:TotalPrepaidAmount>\n"
+ " <ram:DuePayableAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(getTotalGross().subtract(getTotalPrepaid())) + "</ram:DuePayableAmount>\n" //$NON-NLS-2$
+ " <ram:TotalPrepaidAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(calc.getTotalPrepaid()) + "</ram:TotalPrepaidAmount>\n"
+ " <ram:DuePayableAmount currencyID=\"" + trans.getCurrency() + "\">" + currencyFormat(calc.getTotalGross().subtract(calc.getTotalPrepaid())) + "</ram:DuePayableAmount>\n" //$NON-NLS-2$
// //
// currencyID=\"EUR\"
+ " </ram:SpecifiedTradeSettlementMonetarySummation>\n"
@@ -361,7 +362,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
}
LineCalc lc = new LineCalc(currentItem);
LineCalculator lc = new LineCalculator(currentItem);
xml = xml + " <ram:IncludedSupplyChainTradeLineItem>\n" +
" <ram:AssociatedDocumentLineDocument>\n"
+ " <ram:LineID>" + lineID + "</ram:LineID>\n" //$NON-NLS-2$
@@ -482,7 +483,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
if (discountTerms != null) {
paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>";
String currency = trans.getCurrency();
String basisAmount = currencyFormat(getTotalGross());
String basisAmount = currencyFormat(calc.getTotalGross());
paymentTermsXml += "<ram:BasisAmount currencyID=\"" + currency + "\">" + basisAmount + "</ram:BasisAmount>";
paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString()
+ "</ram:CalculationPercent>";

View File

@@ -29,23 +29,23 @@ import java.util.Date;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Base64;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.mustangproject.FileAttachment;
import org.mustangproject.Invoice;
import org.mustangproject.XMLTools;
public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvider {
public class ZUGFeRD2PullProvider implements IXMLProvider {
//// MAIN CLASS
protected SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd");
protected byte[] zugferdData;
protected IExportableTransaction trans;
protected TransactionCalculator calc;
private String paymentTermsDescription;
protected Profile profile = Profiles.getByName("EN16931");
@@ -99,117 +99,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
}
//move
protected BigDecimal getTotalPrepaid() {
if (trans.getTotalPrepaidAmount() == null) {
return new BigDecimal(0);
} else {
return trans.getTotalPrepaidAmount();
}
}
protected BigDecimal getTotalGross() {
BigDecimal res = getTaxBasis();
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = getVATPercentAmountMap();
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
res = res.add(amount.getCalculated());
}
return res;
}
protected BigDecimal getCharges() {
BigDecimal res = new BigDecimal(0);
IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges();
if ((charges != null) && (charges.length > 0)) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) {
res = res.add(currentCharge.getTotalAmount(this));
}
}
return res;
}
protected BigDecimal getAllowances() {
BigDecimal res = new BigDecimal(0);
IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances();
if ((allowances != null) && (allowances.length > 0)) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
res = res.add(currentAllowance.getTotalAmount(this));
}
}
return res;
}
protected BigDecimal getTotal() {
BigDecimal res = new BigDecimal(0);
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
LineCalc lc = new LineCalc(currentItem);
res = res.add(lc.getItemTotalGrossAmount());
}
return res;
}
protected BigDecimal getTaxBasis() {
BigDecimal res = getTotal().add(getCharges()).subtract(getAllowances());
return res;
}
/**
* which taxes have been used with which amounts in this transaction, empty for
* no taxes, or e.g. 19:190 and 7:14 if 1000 Eur were applicable to 19% VAT
* (=190 EUR VAT) and 200 EUR were applicable to 7% (=14 EUR VAT) 190 Eur
*
* @return which taxes have been used with which amounts in this invoice
*/
protected HashMap<BigDecimal, VATAmount> getVATPercentAmountMap() {
HashMap<BigDecimal, VATAmount> hm = new HashMap<>();
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
BigDecimal percent = currentItem.getProduct().getVATPercent();
LineCalc lc = new LineCalc(currentItem);
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(),
trans.getDocumentCode());
VATAmount current = hm.get(percent);
if (current == null) {
hm.put(percent, itemVATAmount);
} else {
hm.put(percent, current.add(itemVATAmount));
}
}
IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges();
if ((charges != null) && (charges.length > 0)) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) {
VATAmount theAmount = hm.get(currentCharge.getTaxPercent());
if (theAmount == null) {
theAmount = new VATAmount(new BigDecimal(0), new BigDecimal(0), "S");
}
theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(this)));
BigDecimal factor = currentCharge.getTaxPercent().divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(currentCharge.getTaxPercent(), theAmount);
}
}
IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances();
if ((allowances != null) && (allowances.length > 0)) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
VATAmount theAmount = hm.get(currentAllowance.getTaxPercent());
if (theAmount == null) {
theAmount = new VATAmount(new BigDecimal(0), new BigDecimal(0), "S");
}
theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this)));
BigDecimal factor = currentAllowance.getTaxPercent().divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(currentAllowance.getTaxPercent(), theAmount);
}
}
return hm;
}
@Override
public Profile getProfile() {
@@ -304,6 +193,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
@Override
public void generateXML(IExportableTransaction trans) {
this.trans = trans;
this.calc=new TransactionCalculator(trans);
boolean hasDueDate = false;
String taxCategoryCode = "";
@@ -386,7 +276,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
exemptionReason = "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>";
}
LineCalc lc = new LineCalc(currentItem);
LineCalculator lc = new LineCalculator(currentItem);
xml = xml + " <ram:IncludedSupplyChainTradeLineItem>\n" +
" <ram:AssociatedDocumentLineDocument>\n"
+ " <ram:LineID>" + lineID + "</ram:LineID>\n" //$NON-NLS-2$
@@ -498,13 +388,13 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
// Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung)
if (trans.getAdditionalReferencedDocuments() != null) {
for (FileAttachment f : trans.getAdditionalReferencedDocuments()) {
// final String documentContent = Base64.encodeBase64String(f.getData());
final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData()));
xml = xml + " <ram:AdditionalReferencedDocument>\n"
+ " <ram:IssuerAssignedID>" + f.getFilename() + "</ram:IssuerAssignedID>\n"
+ " <ram:TypeCode>916</ram:TypeCode>\n"
+ " <ram:Name>" + f.getDescription() + "</ram:Name>\n"
+ " <ram:AttachmentBinaryObject mimeCode=\"" + f.getMimetype() + "\"\n"
// + " filename=\"" + f.getFilename() + ">" + documentContent + "\n"
+ " filename=\"" + f.getFilename() + ">" + documentContent + "\n"
+ " </ram:AdditionalReferencedDocument>\n";
}
}
@@ -557,7 +447,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
}
}
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = getVATPercentAmountMap();
HashMap<BigDecimal, VATAmount> VATPercentAmountMap = calc.getVATPercentAmountMap();
for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
if (amount != null) {
@@ -591,7 +481,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
" <ram:ChargeIndicator>\n" +
" <udt:Indicator>true</udt:Indicator>\n" +
" </ram:ChargeIndicator>\n" +
" <ram:ActualAmount>" + currencyFormat(getCharges()) + "</ram:ActualAmount>\n" +
" <ram:ActualAmount>" + currencyFormat(calc.getCharges()) + "</ram:ActualAmount>\n" +
" <ram:Reason>Charge</ram:Reason>\n" +
" <ram:CategoryTradeTax>\n" +
" <ram:TypeCode>VAT</ram:TypeCode>\n" +
@@ -608,7 +498,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
" <ram:ChargeIndicator>\n" +
" <udt:Indicator>false</udt:Indicator>\n" +
" </ram:ChargeIndicator>\n" +
" <ram:ActualAmount>" + currencyFormat(getAllowances()) + "</ram:ActualAmount>\n" +
" <ram:ActualAmount>" + currencyFormat(calc.getAllowances()) + "</ram:ActualAmount>\n" +
" <ram:Reason>Allowance</ram:Reason>\n" +
" <ram:CategoryTradeTax>\n" +
" <ram:TypeCode>VAT</ram:TypeCode>\n" +
@@ -644,24 +534,24 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
}
String allowanceTotalLine = "<ram:AllowanceTotalAmount>" + currencyFormat(getAllowances()) + "</ram:AllowanceTotalAmount>";
String allowanceTotalLine = "<ram:AllowanceTotalAmount>" + currencyFormat(calc.getAllowances()) + "</ram:AllowanceTotalAmount>";
String chargesTotalLine = "<ram:ChargeTotalAmount>" + currencyFormat(getCharges()) + "</ram:ChargeTotalAmount>";
String chargesTotalLine = "<ram:ChargeTotalAmount>" + currencyFormat(calc.getCharges()) + "</ram:ChargeTotalAmount>";
xml = xml + " <ram:SpecifiedTradeSettlementHeaderMonetarySummation>\n"
+ " <ram:LineTotalAmount>" + currencyFormat(getTotal()) + "</ram:LineTotalAmount>\n" //$NON-NLS-2$
+ " <ram:LineTotalAmount>" + currencyFormat(calc.getTotal()) + "</ram:LineTotalAmount>\n" //$NON-NLS-2$
+ chargesTotalLine
+ allowanceTotalLine
+ " <ram:TaxBasisTotalAmount>" + currencyFormat(getTaxBasis()) + "</ram:TaxBasisTotalAmount>\n" //$NON-NLS-2$
+ " <ram:TaxBasisTotalAmount>" + currencyFormat(calc.getTaxBasis()) + "</ram:TaxBasisTotalAmount>\n" //$NON-NLS-2$
// //
// currencyID=\"EUR\"
+ " <ram:TaxTotalAmount currencyID=\"" + trans.getCurrency() + "\">"
+ currencyFormat(getTotalGross().subtract(getTaxBasis())) + "</ram:TaxTotalAmount>\n"
+ " <ram:GrandTotalAmount>" + currencyFormat(getTotalGross()) + "</ram:GrandTotalAmount>\n" //$NON-NLS-2$
+ currencyFormat(calc.getTotalGross().subtract(calc.getTaxBasis())) + "</ram:TaxTotalAmount>\n"
+ " <ram:GrandTotalAmount>" + currencyFormat(calc.getTotalGross()) + "</ram:GrandTotalAmount>\n" //$NON-NLS-2$
// //
// currencyID=\"EUR\"
+ " <ram:TotalPrepaidAmount>" + currencyFormat(getTotalPrepaid()) + "</ram:TotalPrepaidAmount>\n"
+ " <ram:DuePayableAmount>" + currencyFormat(getTotalGross().subtract(getTotalPrepaid())) + "</ram:DuePayableAmount>\n" //$NON-NLS-2$
+ " <ram:TotalPrepaidAmount>" + currencyFormat(calc.getTotalPrepaid()) + "</ram:TotalPrepaidAmount>\n"
+ " <ram:DuePayableAmount>" + currencyFormat(calc.getTotalGross().subtract(calc.getTotalPrepaid())) + "</ram:DuePayableAmount>\n" //$NON-NLS-2$
// //
// currencyID=\"EUR\"
+ " </ram:SpecifiedTradeSettlementHeaderMonetarySummation>\n"
@@ -720,7 +610,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
if (discountTerms != null) {
paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>";
String currency = trans.getCurrency();
String basisAmount = currencyFormat(getTotalGross());
String basisAmount = currencyFormat(calc.getTotalGross());
paymentTermsXml += "<ram:BasisAmount currencyID=\"" + currency + "\">" + basisAmount + "</ram:BasisAmount>";
paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString()
+ "</ram:CalculationPercent>";
@@ -742,8 +632,4 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvide
return paymentTermsXml;
}
@Override
public BigDecimal getValue() {
return getTotal();
}
}

View File

@@ -6,6 +6,8 @@ import org.w3c.dom.NodeList;
import javax.xml.xpath.*;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
@@ -13,78 +15,185 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter {
super(filename);
}
public Invoice extractInvoice() {
/***
* This will parse a XML into a invoice object
* @return the parsed invoice object
*/
public Invoice extractInvoice() throws XPathExpressionException, ParseException {
String number = "AB123";
/**
String number = "";
/*
* dummywerte sind derzeit noch setDueDate setIssueDate setDeliveryDate setSender setRecipient setnumber
* bspw. due date //ExchangedDocument//IssueDateTime//DateTimeString : due date optional
*/
XPathFactory xpathFact = XPathFactory.newInstance();
XPath xpath = xpathFact.newXPath();
Invoice zpp = null;
try {
XPathExpression xpr = xpath.compile(
"//SellerTradeParty");
NodeList SellerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile(
"//BuyerTradeParty");
NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
XPathExpression xpr = xpath.compile(
"//*[local-name()=\"SellerTradeParty\"]");
NodeList SellerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
zpp= new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number);
//.addItem(new Item(new Product("Testprodukt","","C62",new BigDecimal(0)),amount,new BigDecimal(1.0)))
zpp.setOwnOrganisationName(extractString("//SellerTradeParty/Name"));
xpr = xpath.compile(
"//*[local-name()=\"BuyerTradeParty\"]");
NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile(
"//*[local-name()=\"ExchangedDocument\"]");
NodeList ExchangedDocumentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile(
"//*[local-name()=\"IncludedSupplyChainTradeLineItem\"]");
NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (nodes.getLength() == 0) {
} else {
for (int i = 0; i < nodes.getLength(); i++) {
//nodes.item(i).getTextContent())) {
Node currentItemNode = nodes.item(i);
NodeList itemChilds = currentItemNode.getChildNodes();
String price = "0";
String quantity = "0";
for (int itemChildIndex = 0; itemChildIndex < itemChilds.getLength(); itemChildIndex++) {
if (itemChilds.item(itemChildIndex).getNodeName().equals("ram:SpecifiedLineTradeAgreement")) {
NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds.getLength(); tradeLineChildIndex++) {
if (tradeLineChilds.item(tradeLineChildIndex).getNodeName().equals("ram:NetPriceProductTradePrice")) {
NodeList netChilds = tradeLineChilds.item(tradeLineChildIndex).getChildNodes();
for (int netIndex = 0; netIndex < netChilds.getLength(); netIndex++) {
if (netChilds.item(netIndex).getNodeName().equals("ram:ChargeAmount")) {
price = netChilds.item(netIndex).getTextContent();//ram:ChargeAmount
Date issueDate = null;
Date dueDate = null;
Date deliveryDate = null;
for (int i = 0; i < ExchangedDocumentNodes.getLength(); i++) {
}
}
}
}
//nodes.item(i).getTextContent())) {
Node exchangedDocumentNode = ExchangedDocumentNodes.item(i);
NodeList exchangedDocumentChilds = exchangedDocumentNode.getChildNodes();
for (int documentChildIndex = 0; documentChildIndex < exchangedDocumentChilds.getLength(); documentChildIndex++) {
if (exchangedDocumentChilds.item(documentChildIndex).getNodeName().equals("ram:ID")) {
number = exchangedDocumentChilds.item(documentChildIndex).getTextContent();
}
if (exchangedDocumentChilds.item(documentChildIndex).getNodeName().equals("ram:IssueDateTime")) {
NodeList issueDateTimeChilds = exchangedDocumentChilds.item(documentChildIndex).getChildNodes();
for (int issueDateChildIndex = 0; issueDateChildIndex < issueDateTimeChilds.getLength(); issueDateChildIndex++) {
if (issueDateTimeChilds.item(issueDateChildIndex).getNodeName().equals("udt:DateTimeString")) {
issueDate = new SimpleDateFormat("yyyyMMdd").parse(issueDateTimeChilds.item(issueDateChildIndex).getTextContent());
}
if (itemChilds.item(itemChildIndex).getNodeName().equals("ram:SpecifiedLineTradeDelivery")) {
NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds.getLength(); tradeLineChildIndex++) {
if (tradeLineChilds.item(tradeLineChildIndex).getNodeName().equals("ram:BilledQuantity")) {
quantity = tradeLineChilds.item(tradeLineChildIndex).getTextContent();
}
}
}
}
xpr = xpath.compile(
"//*[local-name()=\"ApplicableHeaderTradeDelivery\"]");
NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
for (int i = 0; i < headerTradeDeliveryNodes.getLength(); i++) {
//nodes.item(i).getTextContent())) {
Node headerTradeDeliveryNode = headerTradeDeliveryNodes.item(i);
NodeList headerTradeDeliveryChilds = headerTradeDeliveryNode.getChildNodes();
for (int deliveryChildIndex = 0; deliveryChildIndex < headerTradeDeliveryChilds.getLength(); deliveryChildIndex++) {
if (headerTradeDeliveryChilds.item(deliveryChildIndex).getNodeName().equals("ram:ActualDeliverySupplyChainEvent")) {
NodeList actualDeliveryChilds = headerTradeDeliveryChilds.item(deliveryChildIndex).getChildNodes();
for (int actualDeliveryChildIndex = 0; actualDeliveryChildIndex < actualDeliveryChilds.getLength(); actualDeliveryChildIndex++) {
if (actualDeliveryChilds.item(actualDeliveryChildIndex).getNodeName().equals("ram:OccurrenceDateTime")) {
NodeList occurenceChilds = actualDeliveryChilds.item(actualDeliveryChildIndex).getChildNodes();
for (int occurenceChildIndex = 0; occurenceChildIndex < occurenceChilds.getLength(); occurenceChildIndex++) {
if (occurenceChilds.item(occurenceChildIndex).getNodeName().equals("udt:DateTimeString")) {
deliveryDate = new SimpleDateFormat("yyyyMMdd").parse(occurenceChilds.item(occurenceChildIndex).getTextContent());
}
}
}
}
// Logger.getLogger(ZUGFeRDInvoiceImporter.class.getName()).log(Level.INFO, "deb "+price);
// dummywerte sind derzeit noch produkname, beschreibung, unit, VAT percent, menge
zpp.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(0)), new BigDecimal(price), new BigDecimal(quantity)));
}
}
}
xpr = xpath.compile(
"//*[local-name()=\"ApplicableHeaderTradeSettlement\"]");
NodeList headerTradeSettlementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
for (int i = 0; i < headerTradeSettlementNodes.getLength(); i++) {
//nodes.item(i).getTextContent())) {
Node headerTradeSettlementNode = headerTradeSettlementNodes.item(i);
NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes();
for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds.getLength(); settlementChildIndex++) {
if (headerTradeSettlementChilds.item(settlementChildIndex).getNodeName().equals("ram:SpecifiedTradePaymentTerms")) {
NodeList paymentTermChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes();
for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) {
if (paymentTermChilds.item(paymentTermChildIndex).getNodeName().equals("ram:DueDateDateTime")) {
NodeList dueDateChilds = paymentTermChilds.item(paymentTermChildIndex).getChildNodes();
for (int dueDateChildIndex = 0; dueDateChildIndex < dueDateChilds.getLength(); dueDateChildIndex++) {
if (dueDateChilds.item(dueDateChildIndex).getNodeName().equals("udt:DateTimeString")) {
dueDate = new SimpleDateFormat("yyyyMMdd").parse(dueDateChilds.item(dueDateChildIndex).getTextContent());
}
}
}
}
}
}
}
zpp = new Invoice().setDueDate(dueDate).setDeliveryDate(deliveryDate).setIssueDate(issueDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number);
//.addItem(new Item(new Product("Testprodukt","","C62",new BigDecimal(0)),amount,new BigDecimal(1.0)))
zpp.setOwnOrganisationName(extractString("//SellerTradeParty/Name"));
xpr = xpath.compile(
"//*[local-name()=\"IncludedSupplyChainTradeLineItem\"]");
NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (nodes.getLength() == 0) {
} else {
for (int i = 0; i < nodes.getLength(); i++) {
String price = "0";
String name = "";
String description = "";
String quantity = "0";
String vatPercent = "0";
String unitCode = "0";
//nodes.item(i).getTextContent())) {
Node currentItemNode = nodes.item(i);
NodeList itemChilds = currentItemNode.getChildNodes();
for (int itemChildIndex = 0; itemChildIndex < itemChilds.getLength(); itemChildIndex++) {
if (itemChilds.item(itemChildIndex).getNodeName().equals("ram:SpecifiedLineTradeAgreement")) {
NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds.getLength(); tradeLineChildIndex++) {
if (tradeLineChilds.item(tradeLineChildIndex).getNodeName().equals("ram:NetPriceProductTradePrice")) {
NodeList netChilds = tradeLineChilds.item(tradeLineChildIndex).getChildNodes();
for (int netIndex = 0; netIndex < netChilds.getLength(); netIndex++) {
if (netChilds.item(netIndex).getNodeName().equals("ram:ChargeAmount")) {
price = netChilds.item(netIndex).getTextContent();//ram:ChargeAmount
}
}
}
}
}
if (itemChilds.item(itemChildIndex).getNodeName().equals("ram:SpecifiedLineTradeDelivery")) {
NodeList tradeLineChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeLineChildIndex = 0; tradeLineChildIndex < tradeLineChilds.getLength(); tradeLineChildIndex++) {
if (tradeLineChilds.item(tradeLineChildIndex).getNodeName().equals("ram:BilledQuantity")) {
quantity = tradeLineChilds.item(tradeLineChildIndex).getTextContent();
unitCode = tradeLineChilds.item(tradeLineChildIndex).getAttributes().getNamedItem("unitCode").getNodeValue();
}
}
}
if (itemChilds.item(itemChildIndex).getNodeName().equals("ram:SpecifiedTradeProduct")) {
NodeList tradeProductChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeProductChildIndex = 0; tradeProductChildIndex < tradeProductChilds.getLength(); tradeProductChildIndex++) {
if (tradeProductChilds.item(tradeProductChildIndex).getNodeName().equals("ram:Name")) {
name = tradeProductChilds.item(tradeProductChildIndex).getTextContent();
}
}
}
if (itemChilds.item(itemChildIndex).getNodeName().equals("ram:SpecifiedLineTradeSettlement")) {
NodeList tradeSettlementChilds = itemChilds.item(itemChildIndex).getChildNodes();
for (int tradeSettlementChildIndex = 0; tradeSettlementChildIndex < tradeSettlementChilds.getLength(); tradeSettlementChildIndex++) {
if (tradeSettlementChilds.item(tradeSettlementChildIndex).getNodeName().equals("ram:ApplicableTradeTax")) {
NodeList taxChilds = tradeSettlementChilds.item(tradeSettlementChildIndex).getChildNodes();
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
if (taxChilds.item(taxChildIndex).getNodeName().equals("ram:RateApplicablePercent")) {
vatPercent = taxChilds.item(taxChildIndex).getTextContent();
}
}
}
}
}
}
zpp.addItem(new Item(new Product(name, description, unitCode, new BigDecimal(vatPercent)), new BigDecimal(price), new BigDecimal(quantity)));
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return zpp;
}
}

View File

@@ -38,6 +38,7 @@ import junit.framework.TestCase;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ZF2PushTest extends TestCase {
final String TARGET_PDF = "./target/testout-ZF2Push.pdf";
final String TARGET_ALLOWANCESPDF = "./target/testout-ZF2PushAllowances.pdf";
final String TARGET_CORRECTIONPDF = "./target/testout-ZF2PushCorrection.pdf";
final String TARGET_ITEMCHARGESALLOWANCESPDF = "./target/testout-ZF2PushItemChargesAllowances.pdf";
final String TARGET_CHARGESALLOWANCESPDF = "./target/testout-ZF2PushChargesAllowances.pdf";
@@ -49,9 +50,9 @@ public class ZF2PushTest extends TestCase {
// the writing part
String orgname = "Test company";
String number = "123";
String amountStr = "1.00";
BigDecimal amount = new BigDecimal(amountStr);
String number = "RE-20170509/505";
String priceStr = "1.00";
BigDecimal price = new BigDecimal(priceStr);
String occurenceFrom = "20201001";
String occurenceTo = "20201005";
String contractID = "376zreurzu0983";
@@ -63,7 +64,7 @@ public class ZF2PushTest extends TestCase {
.load(SOURCE_PDF)) {
try {
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setContractReferencedDocument(contractID).setOccurrencePeriod(new SimpleDateFormat("yyyyMMdd").parse(occurenceFrom), new SimpleDateFormat("yyyyMMdd").parse(occurenceTo)).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addBankDetails(new BankDetails("777666555", "DE4321"))).setOwnTaxID("4711").setOwnVATID("DE19990815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").setAdditionalAddress("Hinterhaus 3").setContact(new Contact("nameRep", "phoneRep", "emailRep@test.com"))).setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0))));
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setContractReferencedDocument(contractID).setOccurrencePeriod(new SimpleDateFormat("yyyyMMdd").parse(occurenceFrom), new SimpleDateFormat("yyyyMMdd").parse(occurenceTo)).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addBankDetails(new BankDetails("777666555", "DE4321"))).setOwnTaxID("4711").setOwnVATID("DE19990815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").setAdditionalAddress("Hinterhaus 3").setContact(new Contact("nameRep", "phoneRep", "emailRep@test.com"))).setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0))));
} catch (ParseException ex) {
throw new RuntimeException("Parse exception");
}
@@ -102,9 +103,9 @@ public class ZF2PushTest extends TestCase {
String orgname = "Test company";
String number = "123";
String amountStr = "1.00";
String priceStr = "1.00";
String taxID = "9990815";
BigDecimal amount = new BigDecimal(amountStr);
BigDecimal price = new BigDecimal(priceStr);
try (InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
@@ -115,7 +116,7 @@ public class ZF2PushTest extends TestCase {
byte[] b = {12, 13};
ze.attachFile("one.pdf", b, "Application/PDF", "Alternative");
ze.attachFile("two.pdf", b, "Application/PDF", "Alternative");
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID(taxID)).setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)))
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID(taxID)).setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)))
);
String theXML = new String(ze.getProvider().getXML());
@@ -238,14 +239,56 @@ public class ZF2PushTest extends TestCase {
}
}
public void testAllowancesExport() {
String orgname = "Test company";
String number = "123";
BigDecimal qty = new BigDecimal("20");
try (InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1().setProducer("My Application")
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("en16931")).ignorePDFAErrors()
.load(SOURCE_PDF)) {
ze.setTransaction(new Invoice().setDueDate(new Date()).setOccurrenceDate(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", "", "C62", new BigDecimal(19)), new BigDecimal(500.0), qty).addAllowance(new Allowance(new BigDecimal(300)).setTaxPercent(new BigDecimal(19))))
.addAllowance(new Allowance(new BigDecimal(600)).setTaxPercent(new BigDecimal(19)))
);
String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
ze.export(TARGET_ALLOWANCESPDF);
} catch (IOException e) {
fail("IOException should not be raised in testEdgeExport");
}
// now check the contents (like MustangReaderTest)
ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_ALLOWANCESPDF);
assertTrue(zi.getUTF8().contains("EUR"));
// Reading ZUGFeRD
assertEquals("4046.00", zi.getAmount());
assertEquals(zi.getHolder(), orgname);
assertEquals(zi.getForeignReference(), number);
try {
assertEquals(zi.getVersion(), 2);
} catch (Exception e) {
e.printStackTrace();
}
}
public void testRelativeChargesAllowancesExport() {
String orgname = "Test company";
String number = "123";
String amountStr = "3.00";
BigDecimal amount = new BigDecimal(amountStr);
String priceStr = "3.00";
BigDecimal price = new BigDecimal(priceStr);
try (InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
@@ -254,9 +297,9 @@ public class ZF2PushTest extends TestCase {
.load(SOURCE_PDF)) {
ze.setTransaction(new Invoice().setCurrency("CHF").setDueDate(new Date()).setOccurrenceDate(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", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addCharge(new Charge().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19))))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)).addCharge(new Charge().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19))))
.addAllowance(new Allowance().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19)))
);
@@ -292,7 +335,7 @@ public class ZF2PushTest extends TestCase {
String number = "123";
String priceStr = "1.00";
BigDecimal price = new BigDecimal(priceStr);
BigDecimal amount = new BigDecimal(-1.0);
BigDecimal qty = new BigDecimal(-1.0);
try (InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
@@ -301,9 +344,9 @@ public class ZF2PushTest extends TestCase {
.load(SOURCE_PDF)) {
Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setOccurrencePeriod(new Date(), 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").addVATID("DE0815")).setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, amount))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, amount))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, amount)).setCorrection("0815");
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, qty)).setCorrection("0815");
ze.setTransaction(i);
String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));

View File

@@ -27,6 +27,14 @@ import junit.framework.TestCase;
import junit.framework.Test;
import junit.framework.TestSuite;
import javax.xml.xpath.XPathExpressionException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
/***
* Classname ZF2ZInvoiceImporterTest is alphabetical behind the tests which will create the file
@@ -39,17 +47,47 @@ public class ZF2ZInvoiceImporterTest extends TestCase {
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
Invoice invoice=zii.extractInvoice();
boolean hasExceptions=false;
Invoice invoice=null;
try {
invoice=zii.extractInvoice();
} catch (XPathExpressionException | ParseException e) {
hasExceptions=true;
}
assertFalse(hasExceptions);
// Reading ZUGFeRD
assertEquals("Bei Spiel GmbH", invoice.getOwnOrganisationName());
assertEquals(3, invoice.getZFItems().length);
assertEquals("400.0000", invoice.getZFItems()[1].getQuantity().toString());
/* assertEquals("160.0000", invoice.getZFItems()[0].getPrice().toString());
assertEquals("160.0000", invoice.getZFItems()[0].getPrice().toString());
assertEquals("Heiße Luft pro Liter", invoice.getZFItems()[2].getProduct().getName());
assertEquals("7", invoice.getZFItems()[0].getProduct().getVATPercent().toString());
assertEquals("LTR", invoice.getZFItems()[2].getProduct().getUnit());
assertEquals("7.00", invoice.getZFItems()[0].getProduct().getVATPercent().toString());
assertEquals("RE-20170509/505", invoice.getNumber());
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
assertEquals("2017-05-09",sdf.format(invoice.getIssueDate()));
assertEquals("2017-05-07",sdf.format(invoice.getDeliveryDate()));
assertEquals("2017-05-30",sdf.format(invoice.getDueDate()));
assertEquals("Bahnstr. 42", invoice.getRecipient().getStreet());
assertEquals("88802", invoice.getRecipient().getZIP());
assertEquals("DE", invoice.getRecipient().getCountry());
assertEquals("Spielkreis", invoice.getRecipient().getLocation());
assertEquals("Ecke 12", invoice.getSender().getStreet());
assertEquals("12345", invoice.getSender().getZIP());
assertEquals("DE", invoice.getSender().getCountry());
assertEquals("Stadthausen", invoice.getSender().getLocation());
TransactionCalculator tc=new TransactionCalculator(invoice);
assertEquals(new BigDecimal("571.040000"),tc.getTotalGross());
// name street location zip country, contact name phone email, total amount
*/
}