Merge branch 'master' of https://github.com/ZUGFeRD/mustangproject into master
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()) {
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>";
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user