diff --git a/library/src/main/java/org/mustangproject/Charge.java b/library/src/main/java/org/mustangproject/Charge.java index 2e9a2e42..5ddf3009 100644 --- a/library/src/main/java/org/mustangproject/Charge.java +++ b/library/src/main/java/org/mustangproject/Charge.java @@ -82,6 +82,13 @@ public class Charge implements IZUGFeRDAllowanceCharge { return true; } + @Override + public String getCategoryCode() { + if(categoryCode != null){ + return categoryCode; + } + return IZUGFeRDAllowanceCharge.super.getCategoryCode(); + } public Charge setCategoryCode(String categoryCode) { diff --git a/library/src/main/java/org/mustangproject/TradeParty.java b/library/src/main/java/org/mustangproject/TradeParty.java index df1b4a02..5729fb53 100644 --- a/library/src/main/java/org/mustangproject/TradeParty.java +++ b/library/src/main/java/org/mustangproject/TradeParty.java @@ -1,11 +1,17 @@ package org.mustangproject; -import org.mustangproject.ZUGFeRD.*; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact; +import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTradeParty; +import org.mustangproject.ZUGFeRD.IZUGFeRDTradeSettlement; +import org.mustangproject.ZUGFeRD.IZUGFeRDTradeSettlementDebit; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import java.util.ArrayList; - /*** * A organisation, i.e. usually a company */ @@ -15,7 +21,8 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { protected String taxID = null, vatID = null; protected String ID = null; protected String additionalAddress = null; - protected ArrayList bankDetails = new ArrayList(); + protected List bankDetails = new ArrayList<>(); + protected List debitDetails = new ArrayList<>(); protected Contact contact = null; /*** @@ -137,8 +144,17 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { bankDetails.add(s); return this; } + /** + * (optional) + * @param debitDetail + * @return fluent setter + */ + public TradeParty addDebitDetails(IZUGFeRDTradeSettlementDebit debitDetail) { + debitDetails.add(debitDetail); + return this; + } - public ArrayList getBankDetails() { + public List getBankDetails() { return bankDetails; } @@ -262,10 +278,19 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } public IZUGFeRDTradeSettlement[] getAsTradeSettlement() { - if (bankDetails.size() == 0) { + if (bankDetails.isEmpty() && debitDetails.isEmpty()) { return null; } - return bankDetails.toArray(new IZUGFeRDTradeSettlement[0]); + List tradeSettlements = Stream.concat(bankDetails.stream(), debitDetails.stream()) + .map(IZUGFeRDTradeSettlement.class::cast) + .collect(Collectors.toList()); + + IZUGFeRDTradeSettlement[] result = new IZUGFeRDTradeSettlement[tradeSettlements.size()]; + for (int i = 0; i < tradeSettlements.size(); i++) { + IZUGFeRDTradeSettlement izugFeRDTradeSettlement = tradeSettlements.get(i); + result[i]=izugFeRDTradeSettlement; + } + return result; } @Override diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java index efab767d..c0d15e04 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java @@ -22,6 +22,8 @@ package org.mustangproject.ZUGFeRD; import java.math.BigDecimal; +import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants; + /** * Mustangproject's ZUGFeRD implementation * Necessary interface for ZUGFeRD exporter @@ -114,13 +116,15 @@ public interface IZUGFeRDExportableProduct { default String getTaxCategoryCode() { if (isIntraCommunitySupply()) { - return "K"; // within europe + return TaxCategoryCodeTypeConstants.INTRACOMMUNITY;// "K"; // within europe } else if (isReverseCharge()) { - return "AE"; // to out of europe... - } else if (getVATPercent().equals(BigDecimal.ZERO)) { - return "Z"; // zero rated goods + return TaxCategoryCodeTypeConstants.REVERSECHARGE;// "AE"; // to out of europe... + } else if (getVATPercent().compareTo(BigDecimal.ZERO) == 0) { + return TaxCategoryCodeTypeConstants.ZEROTAXPRODUCTS; // "Z"; // zero rated goods } else { - return "S"; // one of the "standard" rates (not neccessarily a default rate, even a deducted VAT is standard calculation) + return TaxCategoryCodeTypeConstants.STANDARDRATE;// "S"; // one of the "standard" rates (not + // neccessarily a default rate, even a deducted VAT + // is standard calculation) } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java b/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java index 7221a333..2496e801 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java @@ -20,8 +20,6 @@ */ package org.mustangproject.ZUGFeRD; -import java.util.ArrayList; -import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -33,7 +31,7 @@ public class Profiles { {"BASIC", new Profile("BASIC", "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")}, {"EN16931", new Profile("EN16931", "urn:cen.eu:en16931:2017")}, {"EXTENDED", new Profile("EXTENDED", "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")}, - {"XRECHNUNG", new Profile("XRECHNUNG", "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_1.2")} + {"XRECHNUNG", new Profile("XRECHNUNG", "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.0")} }).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1])); static Map zf1Map = Stream.of(new Object[][]{ diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 2e229a1a..c66ae41b 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -792,8 +792,7 @@ public class ZUGFeRDImporter { List nodeList = getLineItemNodes(); List lineItemList = new ArrayList<>(); - for (Node n: nodeList - ) { + for (Node n: nodeList) { Item lineItem = new Item(null, null, null); lineItem.setProduct(new Product(null,null,null,null)); @@ -807,13 +806,21 @@ public class ZUGFeRDImporter { node = getNodeByName(nn.getChildNodes(), "ram:NetPriceProductTradePrice"); if (node != null) { - node = getNodeByName(node.getChildNodes(), "ram:ChargeAmount"); - lineItem.setPrice(tryBigDecimal(getNodeValue(node))); + NodeList tradeAgreementChildren = node.getChildNodes(); + node = getNodeByName(tradeAgreementChildren, "ram:ChargeAmount"); + lineItem.setPrice(tryBigDecimal(getNodeValue(node))); + node = getNodeByName(tradeAgreementChildren, "ram:BasisQuantity"); + if(node != null && node.getAttributes()!=null) { + Node unitCodeAttribute = node.getAttributes().getNamedItem("unitCode"); + if(unitCodeAttribute != null) { + lineItem.getProduct().setUnit(unitCodeAttribute.getNodeValue()); + } + } } - + node = getNodeByName(nn.getChildNodes(), "ram:GrossPriceProductTradePrice"); if (node != null) { - node = getNodeByName(node.getChildNodes(), "ram:ChargeAmount"); + node = getNodeByName(node.getChildNodes(), "ram:ChargeAmount"); lineItem.setGrossPrice(tryBigDecimal(getNodeValue(node))); } break; diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index 00a3c35d..172cc6cb 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -6,6 +6,7 @@ import org.w3c.dom.NodeList; import javax.xml.xpath.*; import java.math.BigDecimal; +import java.math.RoundingMode; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;