Merge branch 'master' into fix_compile_20241123

This commit is contained in:
Jochen Staerk
2024-12-03 13:29:07 +01:00
committed by GitHub
42 changed files with 1846 additions and 913 deletions

View File

@@ -1,12 +1,16 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.math.BigDecimal;
/***
* (absolute) allowances on item and document level
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Allowance extends Charge {
/***

View File

@@ -2,11 +2,14 @@ package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.IZUGFeRDTradeSettlementPayment;
/**
* provides e.g. the IBAN to transfer money to :-)
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class BankDetails implements IZUGFeRDTradeSettlementPayment {
/**
* the bank account number
@@ -15,15 +18,17 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment {
/**
* BIC, I believe it's optional
*/
protected String BIC=null;
protected String BIC = null;
/**
* the "name" of the bank account (holder)
*/
protected String accountName=null;
protected String accountName = null;
/***
* bean constructor
*/
public BankDetails() { }
public BankDetails() {
}
/***
* constructor for IBAN only :-)
@@ -32,6 +37,7 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment {
public BankDetails(String IBAN) {
this.IBAN = IBAN;
}
/***
* constructor for normal use :-)
* @param IBAN the IBAN as string
@@ -55,6 +61,7 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment {
* identify the IBAN. Of course you will specify your own IBAN in full length but
* if you deduct from a customer's account you may e.g. leave out the first or last
* digits so that nobody spying on the invoice gets to know the complete number
*
* @param IBAN the "IBAN ID", i.e. the IBAN or parts of it
* @return fluent setter
*/
@@ -81,9 +88,10 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment {
return this;
}
/***
* getOwn... methods will be removed in the future in favor of Tradeparty (e.g. Sender) class
* */
/*
I'd really like to get rid of all those getOwn... methods some time but in this case they are in the interface :-(
*/
@Override
@Deprecated
@JsonIgnore
@@ -101,11 +109,12 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment {
/**
* set Holder
*
* @param name account name (usually account holder if != sender)
* @return fluent setter
*/
public BankDetails setAccountName(String name) {
accountName=name;
accountName = name;
return this;
}
@@ -115,5 +124,4 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment {
}
}

View File

@@ -2,6 +2,8 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.TransactionCalculator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -9,13 +11,21 @@ import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.math.BigDecimal;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class CalculatedInvoice extends Invoice implements Serializable {
protected BigDecimal grandTotal=null;
protected BigDecimal lineTotalAmount=null;
protected BigDecimal duePayable=null;
protected BigDecimal grandTotal=null;
protected BigDecimal taxBasis=null;
public void calculate() {
TransactionCalculator tc=new TransactionCalculator(this);
grandTotal=tc.getGrandTotal();
lineTotalAmount=tc.getValue();
duePayable=tc.getDuePayable();
taxBasis= tc.getTaxBasis();
}
public BigDecimal getGrandTotal() {
if (grandTotal==null) {
@@ -27,4 +37,37 @@ public class CalculatedInvoice extends Invoice implements Serializable {
grandTotal=grand;
return this;
}
public BigDecimal getTaxBasis() {
if (taxBasis==null) {
calculate();
}
return taxBasis;
}
public CalculatedInvoice setTaxBasis(BigDecimal basis) {
taxBasis=basis;
return this;
}
public BigDecimal getDuePayable() {
if (duePayable==null) {
calculate();
}
return duePayable;
}
public CalculatedInvoice setDuePayable(BigDecimal due) {
duePayable=due;
return this;
}
public BigDecimal getLineTotalAmount() {
if (lineTotalAmount==null) {
calculate();
}
return lineTotalAmount;
}
public CalculatedInvoice setLineTotalAmount(BigDecimal total) {
lineTotalAmount=total;
return this;
}
}

View File

@@ -1,5 +1,7 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.IZUGFeRDCashDiscount;
import java.math.BigDecimal;
@@ -7,6 +9,8 @@ import java.math.BigDecimal;
/***
* A class to represent discounts for early payments ("Skonto")
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class CashDiscount implements IZUGFeRDCashDiscount {
/***
@@ -31,6 +35,31 @@ public class CashDiscount implements IZUGFeRDCashDiscount {
this.days = days;
}
/***
* bean contructor
*/
public CashDiscount() {
}
public BigDecimal getPercent() {
return percent;
}
public CashDiscount setPercent(BigDecimal percent) {
this.percent = percent;
return this;
}
public Integer getDays() {
return days;
}
public CashDiscount setDays(Integer days) {
this.days = days;
return this;
}
/***
* @return this particular cash discount as cross industry invoice XML
*/

View File

@@ -1,6 +1,8 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.IAbsoluteValueProvider;
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
@@ -9,6 +11,8 @@ import java.math.BigDecimal;
/***
* Absolute and relative charges for document and item level
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Charge implements IZUGFeRDAllowanceCharge {
/**

View File

@@ -20,12 +20,16 @@
*/
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* A schemed classification for products. The scheme can be anything defined in UNTDID 7143.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ClassCode {
private final String listID;
private final String code;

View File

@@ -1,6 +1,7 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -11,6 +12,7 @@ import org.w3c.dom.NodeList;
* @see TradeParty
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Contact implements IZUGFeRDExportableContact {
/**

View File

@@ -20,12 +20,16 @@
*/
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.IDesignatedProductClassification;
/**
* An implementation of {@link IDesignatedProductClassification} for describing a {@link org.mustangproject.Product}
*
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class DesignatedProductClassification implements IDesignatedProductClassification {
private final ClassCode classCode;
private String className;

View File

@@ -1,10 +1,14 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.IZUGFeRDTradeSettlementDebit;
/**
* provides e.g. the IBAN to transfer money to :-)
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class DirectDebit implements IZUGFeRDTradeSettlementDebit {
/**
* Debited account identifier (BT-91)

View File

@@ -1,5 +1,10 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class FileAttachment {
protected String filename;

View File

@@ -1,10 +1,16 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
/**
* A grouping of business terms to indicate accounting-relevant free texts including a qualification of these.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class IncludedNote {
private String content;
private SubjectCode subjectCode;
private static final String INCLUDE_START = "<ram:IncludedNote>";
@@ -14,7 +20,7 @@ public class IncludedNote {
private static final String SUBJECT_CODE_START = "<ram:SubjectCode>";
private static final String SUBJECT_CODE_END = "</ram:SubjectCode>";
private IncludedNote(String content, SubjectCode subjectCode) {
public IncludedNote(String content, SubjectCode subjectCode) {
this.content = content;
this.subjectCode = subjectCode;
}
@@ -29,24 +35,31 @@ public class IncludedNote {
public static IncludedNote generalNote(String content) {
return new IncludedNote(content, SubjectCode.AAI);
}
public static IncludedNote regulatoryNote(String content) {
return new IncludedNote(content, SubjectCode.REG);
}
public static IncludedNote legalNote(String content) {
return new IncludedNote(content, SubjectCode.ABL);
}
public static IncludedNote customsNote(String content) {
return new IncludedNote(content, SubjectCode.CUS);
}
public static IncludedNote sellerNote(String content) {
return new IncludedNote(content, SubjectCode.SUR);
}
public static IncludedNote taxNote(String content) {
return new IncludedNote(content, SubjectCode.TXD);
}
public static IncludedNote introductionNote(String content) {
return new IncludedNote(content, SubjectCode.ACY);
}
public static IncludedNote discountBonusNote(String content) {
return new IncludedNote(content, SubjectCode.AAK);
}
@@ -68,10 +81,17 @@ public class IncludedNote {
return subjectCode;
}
public IncludedNote setSubjectCode(SubjectCode subjectCode) {
this.subjectCode = subjectCode;
return this;
}
public IncludedNote setSubjectCode(SubjectCode subjectCode) {
this.subjectCode = subjectCode;
return this;
}
public IncludedNote setContent(String content) {
this.content = content;
return this;
}
public String toCiiXml(){
String result = INCLUDE_START + CONTENT_START +

View File

@@ -413,6 +413,11 @@ public class Invoice implements IExportableTransaction {
return includedNotes;
}
public Invoice setNotesWithSubjectCode(List<IncludedNote> theList) {
includedNotes=theList;
return this;
}
@Override
public String getCurrency() {
return currency;

View File

@@ -12,7 +12,11 @@ import org.w3c.dom.NodeList;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
/***
* describes any invoice line
@@ -37,6 +41,8 @@ public class Item implements IZUGFeRDExportableItem {
protected ArrayList<ReferencedDocument> additionalReference = null;
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<>();
protected ArrayList<IZUGFeRDAllowanceCharge> Charges = new ArrayList<>();
protected List<IncludedNote> includedNotes = null;
//protected HashMap<String, String> attributes = new HashMap<>();
/***
* default constructor
@@ -64,11 +70,39 @@ public class Item implements IZUGFeRDExportableItem {
// ubl
//we need: name description unitcode
//and we additionally have vat%
setProduct(new Product());
// Bharti's homework 20241126:Streams https://www.youtube.com/watch?v=Lf01cBzmuXw
// and Lambdas https://www.youtube.com/watch?v=HCyx31NW8xg
setProduct(new Product(itemMap.getNode("Item").get()));
icnm.getAsString("Name").ifPresent(product::setName);
icnm.getAsString("Description").ifPresent(product::setDescription);
icnm.getAsNodeMap("SellersItemIdentification").ifPresent(SellersItemIdentification -> {
SellersItemIdentification.getAsString("ID").ifPresent(product::setSellerAssignedID);
});
icnm.getAsNodeMap("BuyersItemIdentification").ifPresent(BuyersItemIdentification -> {
BuyersItemIdentification.getAsString("ID").ifPresent(product::setBuyerAssignedID);
});
// String name = icnm.getAsStringOrNull("Name");
// String val = icnm.getAsStringOrNull("Value");
// if (name != null && val != null) {
// if (attributes == null) {
// attributes = new HashMap<>();
// }
// product.attributes.put(name, val);
// }
//icnm.getNode("AdditionalItemProperty").flatMap(n ->n.getAttributes()).ifPresent(product::setAttributes);
icnm.getAsNodeMap("ClassifiedTaxCategory").flatMap(m -> m.getAsBigDecimal("Percent"))
.ifPresent(product::setVATPercent);
});
itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(icnm -> {
icnm.getAsString("LineID").ifPresent(this::setId);
});
itemMap.getAsNodeMap("Price").ifPresent(icnm -> {
// ubl
@@ -83,21 +117,37 @@ public class Item implements IZUGFeRDExportableItem {
product.setUnit(icn.getAttributes().getNamedItem("unitCode").getNodeValue());
});
itemMap.getAllNodes("DocumentReference").map(ReferencedDocument::fromNode)
.forEach(this::addAdditionalReference);
// ubl
itemMap.getAsNodeMap("OrderLineReference")
// ubl
.flatMap(bordNodes -> bordNodes.getAsString("LineID"))
.ifPresent(this::addReferencedLineID);
itemMap.getAsNodeMap("SpecifiedLineTradeAgreement", "SpecifiedSupplyChainTradeAgreement").ifPresent(icnm -> {
icnm.getAsNodeMap("BuyerOrderReferencedDocument")
.flatMap(bordNodes -> bordNodes.getAsString("LineID"))
.ifPresent(this::addReferencedLineID);
icnm.getAsNodeMap("NetPriceProductTradePrice").ifPresent(npptpNodes -> {
npptpNodes.getAsBigDecimal("ChargeAmount").ifPresent(this::setPrice);
npptpNodes.getAsBigDecimal("BasisQuantity").ifPresent(this::setBasisQuantity);
});
icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode)
.forEach(this::addReferencedDocument);
icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).
forEach(this::addReferencedDocument);
});
itemMap.getNode("SpecifiedTradeProduct").map(Product::new).ifPresent(this::setProduct);
itemMap.getNode("SpecifiedTradeProduct").map(Product::new).ifPresent(this::setProduct);//CII
itemMap.getNode("SpecifiedTradeProduct").map(Product::new).ifPresent(this::setProduct);//UBL
// RequestedQuantity is for Order-X, BilledQuantity for FX and ZF
itemMap.getAsNodeMap("SpecifiedLineTradeDelivery", "SpecifiedSupplyChainTradeDelivery")
@@ -125,6 +175,38 @@ public class Item implements IZUGFeRDExportableItem {
icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference);
});
itemMap.getAsString("Note").ifPresent(this::addNote);
itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(adld -> {
List<IncludedNote> includedNotes = new ArrayList<>();
adld.getAllNodes("IncludedNote").forEach(item -> {
String subjectCode = "";
String content = null;
NodeList includedNodeChilds = item.getChildNodes();
for (int issueDateChildIndex = 0; issueDateChildIndex < includedNodeChilds.getLength(); issueDateChildIndex++) {
if ((includedNodeChilds.item(issueDateChildIndex).getLocalName() != null)
&& (includedNodeChilds.item(issueDateChildIndex).getLocalName().equals("Content"))) {
content = XMLTools.trimOrNull(includedNodeChilds.item(issueDateChildIndex));
}
if ((includedNodeChilds.item(issueDateChildIndex).getLocalName() != null)
&& (includedNodeChilds.item(issueDateChildIndex).getLocalName().equals("SubjectCode"))) {
subjectCode = XMLTools.trimOrNull(includedNodeChilds.item(issueDateChildIndex));
}
}
boolean foundCode = false;
for (SubjectCode code : SubjectCode.values()) {
if (code.toString().equals(subjectCode)) {
includedNotes.add(new IncludedNote(content, code));
foundCode = true;
break;
}
}
if (!foundCode) {
includedNotes.add(new IncludedNote(content, null));
}
});
addNotes(includedNotes);
});
}
public Item addReferencedLineID(String s) {
@@ -372,4 +454,19 @@ public class Item implements IZUGFeRDExportableItem {
return detailedDeliveryPeriodTo;
}
public IZUGFeRDExportableItem addNotes(Collection<IncludedNote> notes) {
if (notes == null) {
return this;
}
if (includedNotes == null) {
includedNotes = new ArrayList<>();
}
includedNotes.addAll(notes);
return this;
}
@Override
public List<IncludedNote> getNotesWithSubjectCode() {
return includedNotes;
}
}

View File

@@ -1,6 +1,7 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.*;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -9,6 +10,7 @@ import org.w3c.dom.NodeList;
* A organisation, i.e. usually a company
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class LegalOrganisation implements IZUGFeRDLegalOrganisation {
protected SchemedID schemedID = null;

View File

@@ -6,6 +6,7 @@ import org.mustangproject.ZUGFeRD.IDesignatedProductClassification;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct;
import org.mustangproject.util.NodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.math.BigDecimal;
import java.util.ArrayList;
@@ -59,11 +60,15 @@ public class Product implements IZUGFeRDExportableProduct {
}
});
nodeMap.getAsString("SellerAssignedID").ifPresent(this::setSellerAssignedID);
nodeMap.getAsString("BuyerAssignedID").ifPresent(this::setBuyerAssignedID);
nodeMap.getAsString("Name").ifPresent(this::setName);
nodeMap.getAsString("Description").ifPresent(this::setDescription);
nodeMap.getAsNodeMap("ApplicableProductCharacteristic").ifPresent(apcNodes -> {
String key = apcNodes.getAsStringOrNull("Description");
String value = apcNodes.getAsStringOrNull("Value");
@@ -75,6 +80,26 @@ public class Product implements IZUGFeRDExportableProduct {
}
});
//UBL
nodeMap.getAsNodeMap("AdditionalItemProperty").ifPresent(aipNodes -> {
String name = aipNodes.getAsStringOrNull("Name");
String val = aipNodes.getAsStringOrNull("Value");
if (name != null && val != null) {
if (attributes == null) {
attributes = new HashMap<>();
}
attributes.put(name, val);
}
});
nodeMap.getAsNodeMap("CommodityClassification").ifPresent(dpcNodes -> {
String className = dpcNodes.getAsStringOrNull("ClassName");
dpcNodes.getNode("ItemClassificationCode").map(ClassCode::fromNode).ifPresent(classCode ->
classifications.add(new DesignatedProductClassification(classCode, className)));
});
//UBL
nodeMap.getAsNodeMap("DesignatedProductClassification").ifPresent(dpcNodes -> {
String className = dpcNodes.getAsStringOrNull("ClassName");
dpcNodes.getNode("ClassCode").map(ClassCode::fromNode).ifPresent(classCode ->
@@ -115,6 +140,7 @@ public class Product implements IZUGFeRDExportableProduct {
return this;
}
/***
*
* @return e.g. intra-commnunity supply or small business

View File

@@ -1,9 +1,13 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.mustangproject.ZUGFeRD.IReferencedDocument;
import org.mustangproject.util.NodeMap;
import org.w3c.dom.Node;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ReferencedDocument implements IReferencedDocument {
String issuerAssignedID;
@@ -22,7 +26,7 @@ public class ReferencedDocument implements IReferencedDocument {
this.referenceTypeCode = referenceTypeCode;
}
/***
/***
* sets an ID assigned by the sender
* @param issuerAssignedID the ID as a string :-)
*/
@@ -66,8 +70,8 @@ public class ReferencedDocument implements IReferencedDocument {
return null;
}
NodeMap nodes = new NodeMap(node);
return new ReferencedDocument(nodes.getAsStringOrNull("IssuerAssignedID"),
nodes.getAsStringOrNull("TypeCode"),
return new ReferencedDocument(nodes.getAsStringOrNull("IssuerAssignedID", "ID"),
nodes.getAsStringOrNull("TypeCode", "DocumentTypeCode"),
nodes.getAsStringOrNull("ReferenceTypeCode"));
}
}

View File

@@ -1,5 +1,11 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class SchemedID {
protected String scheme;
protected String id;

View File

@@ -36,5 +36,9 @@ public enum SubjectCode {
/**
* Discount and bonus agreements
*/
AAK
AAK,
/**
* Vehicle licence number
*/
ABZ
}

View File

@@ -2,6 +2,7 @@ package org.mustangproject;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -16,6 +17,7 @@ import org.w3c.dom.NodeList;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/***
* A organisation, i.e. usually a company
*/
@@ -62,6 +64,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
}
protected void parseFromUBL(NodeList nodes) {
if (nodes.getLength() > 0) {
@@ -71,8 +74,34 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
if (currentItemNode.getLocalName() != null) {
String currentUBLChild = currentItemNode.getLocalName();
if (currentUBLChild.equals("Party")) {
// if (currentUBLChild.equals("Delivery")) {
// NodeList delivery = currentItemNode.getChildNodes();
// for (int deliveryIndex = 0; deliveryIndex < delivery.getLength(); deliveryIndex++) {
// if (delivery.item(deliveryIndex).getLocalName() != null) {
// Node currentNode = delivery.item(deliveryIndex);
// if (currentNode.getLocalName().equals("DeliveryLocation")) {
// NodeList deliveryLocation = currentNode.getChildNodes();
// for (int deliveryLocationIndex = 0; deliveryLocationIndex < deliveryLocation.getLength(); deliveryLocationIndex++) {
// if (deliveryLocation.item(deliveryLocationIndex).getLocalName() != null) {
// if (deliveryLocation.item(deliveryLocationIndex).getLocalName().equals("ID")) {
// //Node currentNode = partyID.item(partyIDIndex);
// setID(deliveryLocation.item(deliveryLocationIndex).getTextContent());
// if ((deliveryLocation.item(deliveryLocationIndex).getAttributes() != null &&
// (deliveryLocation.item(deliveryLocationIndex).getAttributes().getNamedItem("schemeID") != null))
// ) {
// SchemedID sID = new SchemedID().setScheme(deliveryLocation.item(deliveryLocationIndex).getAttributes().getNamedItem("schemeID").getTextContent());
// addGlobalID(sID);
// }
// }
// }
// }
// }
//
// }
// }
// }
if (currentUBLChild.equals("Party")) {
NodeList party = currentItemNode.getChildNodes();
for (int partyIndex = 0; partyIndex < party.getLength(); partyIndex++) {
if (party.item(partyIndex).getLocalName() != null) {
@@ -90,42 +119,64 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
}
}
}
if (party.item(partyIndex).getLocalName().equals("EndpointID")) {
Node currentNode = party.item(partyIndex);
if ((currentNode.getAttributes() != null &&
(currentNode.getAttributes().getNamedItem("schemeID") != null))
&& (party.item(partyIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("EM"))
) {
setEmail(currentNode.getTextContent());
}
if (currentTopElementName.equals("PartyTaxScheme")) {
NodeList partyTaxScheme = party.item(partyIndex).getChildNodes();
for (int partyTaxSchemeIndex = 0; partyTaxSchemeIndex < partyTaxScheme.getLength(); partyTaxSchemeIndex++) {
if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName() != null) {
if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("CompanyID")) {
setTaxID(partyTaxScheme.item(partyTaxSchemeIndex).getTextContent());
}
if (currentTopElementName.equals("PartyIdentification")) {
NodeList partyID = party.item(partyIndex).getChildNodes();
for (int partyIDIndex = 0; partyIDIndex < partyID.getLength(); partyIDIndex++) {
if (partyID.item(partyIDIndex).getLocalName() != null) {
if (partyID.item(partyIDIndex).getLocalName().equals("ID")) {
Node currentNode = partyID.item(partyIDIndex);
if ((currentNode.getAttributes() != null &&
(currentNode.getAttributes().getNamedItem("schemeID") != null))
) {
SchemedID sID = new SchemedID().setScheme(currentNode.getAttributes().getNamedItem("schemeID").getTextContent()).setId(currentNode.getTextContent());
addGlobalID(sID);
}
else {
setID(currentNode.getTextContent());
}
}
}
}
}
if (currentTopElementName.equals("PartyTaxScheme")) {
NodeList partyTaxScheme = party.item(partyIndex).getChildNodes();
String CompanyId = null;
for (int partyTaxSchemeIndex = 0; partyTaxSchemeIndex < partyTaxScheme.getLength(); partyTaxSchemeIndex++) {
if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName() != null) {
if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("CompanyID")) {
CompanyId = (partyTaxScheme.item(partyTaxSchemeIndex).getTextContent());
}
if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("TaxScheme")) {
NodeList taxSchemechilds = partyTaxScheme.item(partyTaxSchemeIndex).getChildNodes();
for (int taxSchemechildsIndex = 0; taxSchemechildsIndex < taxSchemechilds.getLength(); taxSchemechildsIndex++) {
if (taxSchemechilds.item(taxSchemechildsIndex).getLocalName() != null) {
if (taxSchemechilds.item(taxSchemechildsIndex).getTextContent().equals("FC") || (taxSchemechilds.item(taxSchemechildsIndex).getTextContent().equals("NOVAT"))) {
setTaxID(CompanyId);
} else {
setVATID(CompanyId);
}
}
}
}
}
}
}
// if (currentTopElementName.equals("PartyTaxScheme")) {
// NodeList partyTaxScheme = party.item(partyIndex).getChildNodes();
// for (int partyTaxSchemeIndex = 0; partyTaxSchemeIndex < partyTaxScheme.getLength(); partyTaxSchemeIndex++) {
// if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName() != null) {
// if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("TaxScheme")) {
// NodeList taxScheme = partyTaxScheme.item(partyTaxSchemeIndex).getChildNodes();
// for (int taxSchemeIndex = 0 ; taxSchemeIndex < taxScheme.getLength(); taxSchemeIndex++) {
// if (taxScheme.item(taxSchemeIndex).getLocalName() != null) {
// if(taxScheme.item(taxSchemeIndex).getLocalName().equals("ID")){
// if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("CompanyID")) {
// setTaxID(partyTaxScheme.item(partyTaxSchemeIndex).getTextContent());
// } else {
// setVATID(partyTaxScheme.item(partyTaxSchemeIndex).getTextContent());
// }
// }
// }
// }
// }
//
// }
// }
// }
/*
UBL only: formally it can have a name as well but BT27 party name *should* be stored in
so overwrite if one exists
@@ -133,17 +184,37 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
if (currentTopElementName.equals("PartyLegalEntity")) {
NodeList legal = party.item(partyIndex).getChildNodes();
LegalOrganisation lo = null;
for (int legalChildIndex = 0; legalChildIndex < legal.getLength(); legalChildIndex++) {
if (legal.item(legalChildIndex).getLocalName() != null) {
if (legal.item(legalChildIndex).getLocalName().equals("RegistrationName")) {
setName(legal.item(legalChildIndex).getTextContent());
if (lo == null) {
lo = new LegalOrganisation();
}
lo.setTradingBusinessName(legal.item(legalChildIndex).getTextContent());
}
if (legal.item(legalChildIndex).getLocalName().equals("CompanyLegalForm")) {
setDescription(legal.item(legalChildIndex).getTextContent());
}
if (legal.item(legalChildIndex).getLocalName().equals("CompanyID")) {
if (lo == null) {
lo = new LegalOrganisation();
}
if (legal.item(legalChildIndex).getAttributes().getNamedItem("schemeID")!=null) {
SchemedID sid = new SchemedID(legal.item(legalChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue(), legal.item(legalChildIndex).getTextContent());
lo.setSchemedID(sid);
}
}
// we dont have that attribute yet in the legalorganisation: CompanyLegalForm
if (lo != null) {
setLegalOrganisation(lo);
}
}
}
}
if (currentTopElementName.equals("PostalAddress")) {
NodeList postal = party.item(partyIndex).getChildNodes();
@@ -191,8 +262,6 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
}
}
}
if (postal.item(postalChildIndex).getLocalName().equals("Name")) {
setName(postal.item(postalChildIndex).getTextContent());
@@ -210,7 +279,6 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
}
}
}
if (currentUBLChild.equals("GlobalID")) {
@@ -224,57 +292,6 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
NodeList contact = nodes.item(nodeIndex).getChildNodes();
setContact(new Contact(contact));
}
if (currentUBLChild.equals("PostalTradeAddress")) {
NodeList postal = nodes.item(nodeIndex).getChildNodes();
for (int postalChildIndex = 0; postalChildIndex < postal.getLength(); postalChildIndex++) {
if (postal.item(postalChildIndex).getLocalName() != null) {
if (postal.item(postalChildIndex).getLocalName().equals("LineOne")) {
setStreet(postal.item(postalChildIndex).getTextContent());
}
if (postal.item(postalChildIndex).getLocalName().equals("LineTwo")) {
setAdditionalAddress(postal.item(postalChildIndex).getTextContent());
}
if (postal.item(postalChildIndex).getLocalName().equals("LineThree")) {
setAdditionalAddressExtension(postal.item(postalChildIndex).getTextContent());
}
if (postal.item(postalChildIndex).getLocalName().equals("CityName")) {
setLocation(postal.item(postalChildIndex).getTextContent());
}
if (postal.item(postalChildIndex).getLocalName().equals("PostcodeCode")) {
setZIP(postal.item(postalChildIndex).getTextContent());
}
if (postal.item(postalChildIndex).getLocalName().equals("CountryID")) {
setCountry(postal.item(postalChildIndex).getTextContent());
}
}
}
}
if (currentUBLChild.equals("PartyTaxScheme")) {
NodeList taxChilds = nodes.item(nodeIndex).getChildNodes();
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
if (taxChilds.item(taxChildIndex).getLocalName() != null) {
if ((taxChilds.item(taxChildIndex).getLocalName().equals("TaxScheme"))) {
if (taxChilds.item(taxChildIndex).getLocalName().equals("CompanyID")) {
if (taxChilds.item(taxChildIndex).getLocalName().equals("ID")) {
if (taxChilds.item(taxChildIndex).getLocalName().equals("CompanyID")) {
setVATID(taxChilds.item(taxChildIndex).getTextContent());
}
// setTaxID(partyTaxScheme.item(partyTaxSchemeIndex).getTextContent());
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("ID").getNodeValue().equals("FC")) {
if (taxChilds.item(taxChildIndex).getLocalName().equals("CompanyID")) {
setTaxID(taxChilds.item(taxChildIndex).getTextContent());
}
}
}
}
}
}
}
}
}
}
}
@@ -558,6 +575,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
/**
* primarily for invoiceimporter and JSON
*
* @return the list of sepa mandates
*/
public List<DirectDebit> getDebitDetails() {

View File

@@ -28,7 +28,9 @@ package org.mustangproject.ZUGFeRD;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.mustangproject.IncludedNote;
import org.mustangproject.Item;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@@ -153,4 +155,21 @@ public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
return null;
}
/***
*
* @return the line ID
*/
default String getId() {
return null;
}
/**
* A grouping of business terms to indicate accounting-relevant free texts including a qualification of these.
*
* The information are written to the same xml nodes like {@link #getNotes()} but with explicit subjectCode.
* @return list of the notes
*/
default List<IncludedNote> getNotesWithSubjectCode() {
return null;
}
}

View File

@@ -149,7 +149,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
*
* @return item sum +- charges/allowances
*/
protected BigDecimal getTaxBasis() {
public BigDecimal getTaxBasis() {
return getTotal().add(getChargesForPercent(null).setScale(2, RoundingMode.HALF_UP))
.subtract(getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP))
.setScale(2, RoundingMode.HALF_UP);

View File

@@ -401,6 +401,10 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
int lineID = 0;
for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
lineID++;
String lineIDStr = Integer.toString(lineID);
if (currentItem.getId()!=null) {
lineIDStr=currentItem.getId();
}
if (currentItem.getProduct().getTaxExemptionReason() != null) {
exemptionReason = "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>";
}
@@ -408,7 +412,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) {
xml += "<ram:IncludedSupplyChainTradeLineItem>" +
"<ram:AssociatedDocumentLineDocument>"
+ "<ram:LineID>" + lineID + "</ram:LineID>"
+ "<ram:LineID>" + lineIDStr + "</ram:LineID>"
+ buildItemNotes(currentItem)
+ "</ram:AssociatedDocumentLineDocument>"

View File

@@ -343,6 +343,9 @@ public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
* @return the sender's account IBAN code
*/
public String getIBAN() {
if ((importedInvoice==null)||(importedInvoice.getTradeSettlement()==null)) {
return null;
}
for (IZUGFeRDTradeSettlement settlement : importedInvoice.getTradeSettlement()) {
if (settlement instanceof IZUGFeRDTradeSettlementDebit) {
return ((IZUGFeRDTradeSettlementDebit) settlement).getIBAN();
@@ -356,8 +359,6 @@ public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
public String getHolder() {
return extractString("//*[local-name() = 'SellerTradeParty']/*[local-name() = 'Name']");
}
@@ -366,7 +367,6 @@ public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
* @return the total payable amount
*/
public String getAmount() {
return importedInvoice.getGrandTotal().toPlainString();
}

View File

@@ -11,6 +11,7 @@ import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.mustangproject.*;
import org.mustangproject.Exceptions.ArithmetricException;
import org.mustangproject.Exceptions.StructureException;
import org.mustangproject.util.NodeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
@@ -273,6 +274,10 @@ public class ZUGFeRDInvoiceImporter {
}
}
public void setID(String id) {
String ud = id;
}
/***
* This will parse a XML into the given invoice object
* @param zpp the invoice to be altered
@@ -301,13 +306,129 @@ public class ZUGFeRDInvoiceImporter {
zpp.setDeliveryAddress(new TradeParty(deliveryNodes));
}
List<IncludedNote> includedNotes = new ArrayList<>();
//UBL...
XPathExpression UBLNotesEx = xpath.compile("/*[local-name()=\"Invoice\"]/*[local-name()=\"Note\"]");
NodeList UBLNotesNd = (NodeList) UBLNotesEx.evaluate(getDocument(), XPathConstants.NODESET);
if ((UBLNotesNd != null) && (UBLNotesNd.getLength() > 0)) {
for (int nodeIndex = 0; nodeIndex < UBLNotesNd.getLength(); nodeIndex++) {
includedNotes.add(IncludedNote.generalNote(UBLNotesNd.item(nodeIndex).getTextContent()));
}
zpp.addNotes(includedNotes);
}
XPathExpression shipExUBL = xpath.compile("//*[local-name()=\"Delivery\"]");
Node deliveryNode = (Node) shipExUBL.evaluate(getDocument(), XPathConstants.NODE);
if (deliveryNode != null) {
TradeParty delivery = new TradeParty();
new NodeMap(deliveryNode).getAsNodeMap("DeliveryLocation").ifPresent(
deliveryLocationNodeMap -> {
deliveryLocationNodeMap.getNode("ID").ifPresent(s -> {
if (s.getAttributes().getNamedItem("schemeID") != null) {
SchemedID sID = new SchemedID().setScheme(s.getAttributes().getNamedItem("schemeID").getTextContent()).setId(s.getTextContent());
delivery.addGlobalID(sID);
}
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsString("StreetName").ifPresent(t -> delivery.setStreet(t));
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsString("AdditionalStreetName").ifPresent(t -> delivery.setAdditionalAddress(t));
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsString("CityName").ifPresent(t -> delivery.setLocation(t));
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsString("PostalZone").ifPresent(t -> delivery.setZIP(t));
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsNodeMap("Country").ifPresent(t -> t.getAsString("IdentificationCode").ifPresent(u -> delivery.setCountry(u)));
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsNodeMap("AddressLine").ifPresent(t -> t.getAsString("Line").ifPresent(u -> delivery.setAdditionalAddressExtension(u)));
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsString("AdditionalStreetName").ifPresent(t -> delivery.setAdditionalAddress(t));
});
deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> {
s.getAsString("AdditionalStreetName").ifPresent(t -> delivery.setAdditionalAddress(t));
});
});
new NodeMap(deliveryNode).getAsNodeMap("DeliveryParty").ifPresent(partyMap -> {
partyMap.getAsNodeMap("PartyName").ifPresent(s -> {
s.getAsString("Name").ifPresent(t -> delivery.setName(t));
});
});
String street, name, additionalStreet, city, postal, countrySubentity, line, country = null;
/*
String idx = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"ID\"]");
street = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name()=\"Address\"]/*[local-name()=\"StreetName\"]");
additionalStreet = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]/*[local-name() = \"AdditionalStreetName\"]");
city = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]/*[local-name() = \"CityName\"]");
postal = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]/*[local-name() = \"PostalZone\"]");
countrySubentity = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]/*[local-name() = \"CountrySubentity\"]");
line = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]//*[local-name() = \"AddressLine\"]/*[local-name() = \"Line\"]");
country = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]//*[local-name() = \"Country\"]/*[local-name() = \"IdentificationCode\"]");
name = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"DeliveryParty\"]//*[local-name() = \"PartyName\"]/*[local-name() = \"Name\"]");
*/
zpp.setDeliveryAddress(delivery);
/*
zpp.setDeliveryAddress(new TradeParty()
.setStreet(street)
.setAdditionalAddress(additionalStreet)
.setLocation(city)
.setZIP(postal)
.setAdditionalAddressExtension(line)
.setCountry(country)
.setName(name)
);
*/
}
xpr = xpath.compile("//*[local-name()=\"BuyerTradeParty\"]|//*[local-name()=\"AccountingCustomerParty\"]/*");
NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile("//*[local-name()=\"PayeeTradeParty\"]|//*[local-name()=\"PayeeParty\"]/*");
xpr = xpath.compile("//*[local-name()=\"PayeeTradeParty\"]");
NodeList payeeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
// UBL
XPathExpression shipPayee = xpath.compile("//*[local-name()=\"PayeeParty\"]/*");
NodeList ublPayeeNodes = (NodeList) shipPayee.evaluate(getDocument(), XPathConstants.NODESET);
// if(ublPayeeNodes != null) {
// TradeParty payee = new TradeParty();
// NodeMap nodeMap = new NodeMap(ublPayeeNodes).getAsNodeMap("PayeeParty").get();
// nodeMap.getNode("ID").ifPresent(s -> {
// SchemedID sID = new SchemedID().setScheme(s.getAttributes().getNamedItem("schemeID").getTextContent()).setId(s.getTextContent());
// payee.addGlobalID(sID);
// });
// }
//NodeList UBLpayeeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
zpp.setPayee(new TradeParty(ublPayeeNodes));
// TradeParty payee =new TradeParty();
// NodeMap payeeID = new NodeMap(UBLpayeeNodes).getAsNodeMap("PartyIdentification").get();
// if (payeeID !=null) {
// payeeID.getAsString("Name").ifPresent(t->payee.setName(t));
// }
// if (payeeNodes != null) {
// TradeParty payee =new TradeParty();
// NodeMap nodeMap = new NodeMap(payeeNodes).getAsNodeMap("PartyIdentification").get();
// if (nodeMap != null) {
// nodeMap.getNode("ID").ifPresent(s -> {
// SchemedID sID = new SchemedID().setScheme(s.getAttributes().getNamedItem("schemeID").getTextContent()).setId(s.getTextContent());
// payee.addGlobalID(sID);
// });
// }
// }
xpr = xpath.compile("//*[local-name()=\"ExchangedDocument\"]|//*[local-name()=\"HeaderExchangedDocument\"]");
NodeList ExchangedDocumentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
@@ -324,16 +445,47 @@ public class ZUGFeRDInvoiceImporter {
}
}
xpr = xpath.compile("//*[local-name()=\"PrepaidAmount\"]");
xpr = xpath.compile("//*[local-name()=\"TaxBasisTotalAmount\"]|//*[local-name()=\"TaxExclusiveAmount\"]");
BigDecimal expectedTaxBasis = null;
NodeList basisNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (basisNodes.getLength() > 0) {
expectedTaxBasis = new BigDecimal(XMLTools.trimOrNull(basisNodes.item(0)));
if (zpp instanceof CalculatedInvoice) {
// usually we would re-calculate the invoice to get expectedGrandTotal
// however, for "minimal" invoices or other invoices without lines
// this will not work
((CalculatedInvoice) zpp).setTaxBasis(expectedTaxBasis);
}
}
xpr = xpath.compile("//*[local-name()=\"TotalPrepaidAmount\"]|//*[local-name()=\"PrepaidAmount\"]");
NodeList prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (prepaidNodes.getLength() > 0) {
zpp.setTotalPrepaidAmount(new BigDecimal(XMLTools.trimOrNull(prepaidNodes.item(0))));
}
xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"LineTotalAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"LineExtensionAmount\"]");
NodeList lineTotalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (lineTotalNodes.getLength() > 0) {
if (zpp instanceof CalculatedInvoice) {
((CalculatedInvoice) zpp).setLineTotalAmount(new BigDecimal(XMLTools.trimOrNull(lineTotalNodes.item(0))));
}
}
xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"DuePayableAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"PayableAmount\"]");
NodeList lineDueNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (lineDueNodes.getLength() > 0) {
if (zpp instanceof CalculatedInvoice) {
((CalculatedInvoice) zpp).setDuePayable(new BigDecimal(XMLTools.trimOrNull(lineDueNodes.item(0))));
}
}
Date issueDate = null;
Date dueDate = null;
Date deliveryDate = null;
String despatchAdviceReferencedDocument = null;
for (int i = 0; i < ExchangedDocumentNodes.getLength(); i++) {
Node exchangedDocumentNode = ExchangedDocumentNodes.item(i);
NodeList exchangedDocumentChilds = exchangedDocumentNode.getChildNodes();
@@ -354,7 +506,6 @@ public class ZUGFeRDInvoiceImporter {
}
}
}
List<IncludedNote> includedNotes = new ArrayList<>();
if ((item.getLocalName() != null) && (item.getLocalName().equals("IncludedNote"))) {
String subjectCode = "";
String content = null;
@@ -369,21 +520,39 @@ public class ZUGFeRDInvoiceImporter {
subjectCode = XMLTools.trimOrNull(includedNodeChilds.item(issueDateChildIndex));
}
}
switch (subjectCode){
case "AAI": includedNotes.add(IncludedNote.generalNote(content)); break;
case "REG": includedNotes.add(IncludedNote.regulatoryNote(content)); break;
case "ABL": includedNotes.add(IncludedNote.legalNote(content)); break;
case "CUS": includedNotes.add(IncludedNote.customsNote(content)); break;
case "SUR": includedNotes.add(IncludedNote.sellerNote(content)); break;
case "TXD": includedNotes.add(IncludedNote.taxNote(content)); break;
case "ACY": includedNotes.add(IncludedNote.introductionNote(content)); break;
case "AAK": includedNotes.add(IncludedNote.discountBonusNote(content)); break;
default: includedNotes.add(IncludedNote.unspecifiedNote(content)); break;
switch (subjectCode) {
case "AAI":
includedNotes.add(IncludedNote.generalNote(content));
break;
case "REG":
includedNotes.add(IncludedNote.regulatoryNote(content));
break;
case "ABL":
includedNotes.add(IncludedNote.legalNote(content));
break;
case "CUS":
includedNotes.add(IncludedNote.customsNote(content));
break;
case "SUR":
includedNotes.add(IncludedNote.sellerNote(content));
break;
case "TXD":
includedNotes.add(IncludedNote.taxNote(content));
break;
case "ACY":
includedNotes.add(IncludedNote.introductionNote(content));
break;
case "AAK":
includedNotes.add(IncludedNote.discountBonusNote(content));
break;
default:
includedNotes.add(IncludedNote.unspecifiedNote(content));
break;
}
}
zpp.addNotes(includedNotes);
}
}
zpp.addNotes(includedNotes);
String rootNode = extractString("local-name(/*)");
if (rootNode.equals("Invoice")) {
// UBL...
@@ -399,7 +568,8 @@ public class ZUGFeRDInvoiceImporter {
deliveryDate = new SimpleDateFormat("yyyy-MM-dd").parse(deliveryDt);
}
}
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeDelivery\"]");
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeDelivery\"]|//*[local-name()=\"Delivery\"]");
NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
for (int i = 0; i < headerTradeDeliveryNodes.getLength(); i++) {
@@ -471,7 +641,7 @@ public class ZUGFeRDInvoiceImporter {
}
String currency = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"InvoiceCurrencyCode\"]|//*[local-name()=\"DocumentCurrencyCode\"]") ;
String currency = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"InvoiceCurrencyCode\"]|//*[local-name()=\"DocumentCurrencyCode\"]");
zpp.setCurrency(currency);
xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]|//*[local-name()=\"ApplicableSupplyChainTradeSettlement\"]");
@@ -590,7 +760,21 @@ public class ZUGFeRDInvoiceImporter {
}
}
}
// if ((paymentMeansChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DirectDebitMandateID"))) {
// directDebitMandateID = paymentTermChilds.item(paymentTermChildIndex).getTextContent();
// }
if ((paymentMeansChilds.item(meansChildIndex).getLocalName() != null)
&& (paymentMeansChilds.item(meansChildIndex).getLocalName().equals("PaymentMandate"))) {
NodeList paymentMandateChilds = paymentMeansChilds.item(meansChildIndex).getChildNodes();
for (int paymentMandateChildIndex = 0; paymentMandateChildIndex < paymentMandateChilds.getLength(); paymentMandateChildIndex++) {
if ((paymentMandateChilds.item(paymentMandateChildIndex).getLocalName() != null) && (paymentMandateChilds.item(paymentMandateChildIndex).getLocalName().equals("ID"))) {
directDebitMandateID = paymentMandateChilds.item(paymentMandateChildIndex).getTextContent();
}
}
}
}
}
zpp.setDueDate(dueDate).setDeliveryDate(deliveryDate).setIssueDate(issueDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentCode(typeCode);
@@ -608,29 +792,32 @@ public class ZUGFeRDInvoiceImporter {
if (buyerOrderIssuerAssignedID != null) {
zpp.setBuyerOrderReferencedDocumentID(buyerOrderIssuerAssignedID);
}
else {
} else {
zpp.setBuyerOrderReferencedDocumentID(extractString("//*[local-name()=\"OrderReference\"]/*[local-name()=\"ID\"]"));
}
if (sellerOrderIssuerAssignedID != null) {
zpp.setSellerOrderReferencedDocumentID(sellerOrderIssuerAssignedID);
} else {
zpp.setSellerOrderReferencedDocumentID(extractString("//*[local-name()=\"OrderReference\"]/*[local-name()=\"SalesOrderID\"]"));
}
if (despatchAdviceReferencedDocument != null) {
zpp.setDespatchAdviceReferencedDocumentID(despatchAdviceReferencedDocument);
} else {
zpp.setDespatchAdviceReferencedDocumentID(extractString("//*[local-name()=\"DespatchDocumentReference\"]/*[local-name()=\"ID\"]"));
}
zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]|//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyName\"]").trim());
String rounding=extractString("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"RoundingAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"Party\"]/*[local-name()=\"PayableRoundingAmount\"]");
if ((rounding!=null)&&(!rounding.isEmpty())) {
String rounding = extractString("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"RoundingAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"Party\"]/*[local-name()=\"PayableRoundingAmount\"]");
if ((rounding != null) && (!rounding.isEmpty())) {
zpp.setRoundingAmount(new BigDecimal(rounding.trim()));
}
xpr = xpath.compile("//*[local-name()=\"BuyerReference\"]");
String buyerReference = null;
prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (prepaidNodes.getLength() > 0) {
buyerReference = XMLTools.trimOrNull(prepaidNodes.item(0));
lineTotalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
if (lineTotalNodes.getLength() > 0) {
buyerReference = XMLTools.trimOrNull(lineTotalNodes.item(0));
}
if (buyerReference != null) {
zpp.setReferenceNumber(buyerReference);
@@ -662,7 +849,7 @@ public class ZUGFeRDInvoiceImporter {
// be read,
// so the invoice remains arithmetically correct
// -> parse document level charges+allowances
xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeAllowanceCharge\"]");
xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeAllowanceCharge\"]|//*[local-name()=\"AllowanceCharge\"]");//CII and UBL
NodeList chargeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
for (int i = 0; i < chargeNodes.getLength(); i++) {
NodeList chargeNodeChilds = chargeNodes.item(i).getChildNodes();
@@ -676,24 +863,34 @@ public class ZUGFeRDInvoiceImporter {
if (chargeChildName != null) {
if (chargeChildName.equals("ChargeIndicator")) {
NodeList indicatorChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
for (int indicatorChildIndex = 0; indicatorChildIndex < indicatorChilds.getLength(); indicatorChildIndex++) {
if ((indicatorChilds.item(indicatorChildIndex).getLocalName() != null)
&& (indicatorChilds.item(indicatorChildIndex).getLocalName().equals("Indicator"))) {
isCharge = XMLTools.trimOrNull(indicatorChilds.item(indicatorChildIndex)).equalsIgnoreCase("true");
if (chargeNodeChilds.item(chargeChildIndex).getTextContent().trim().equalsIgnoreCase("false")) {
// UBL
isCharge = false;
} else if (chargeNodeChilds.item(chargeChildIndex).getTextContent().trim().equalsIgnoreCase("true")) {
// still UBL
isCharge = true;
} else {
//CII
NodeList indicatorChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
for (int indicatorChildIndex = 0; indicatorChildIndex < indicatorChilds.getLength(); indicatorChildIndex++) {
if ((indicatorChilds.item(indicatorChildIndex).getLocalName() != null)
&& (indicatorChilds.item(indicatorChildIndex).getLocalName().equals("Indicator"))) {
isCharge = XMLTools.trimOrNull(indicatorChilds.item(indicatorChildIndex)).equalsIgnoreCase("true");
}
}
}
} else if (chargeChildName.equals("ActualAmount")) {
} else if (chargeChildName.equals("ActualAmount") || chargeChildName.equals("Amount")) {
chargeAmount = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex));
} else if (chargeChildName.equals("Reason")) {
} else if (chargeChildName.equals("Reason") || chargeChildName.equals("AllowanceChargeReason")) {
reason = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex));
} else if (chargeChildName.equals("ReasonCode")) {
} else if (chargeChildName.equals("ReasonCode") || chargeChildName.equals("AllowanceChargeReasonCode")) {
reasonCode = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex));
} else if (chargeChildName.equals("CategoryTradeTax")) {
} else if (chargeChildName.equals("CategoryTradeTax") || chargeChildName.equals("TaxCategory")) {
NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes();
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
String taxItemName = taxChilds.item(taxChildIndex).getLocalName();
if ((taxItemName != null) && (taxItemName.equals("RateApplicablePercent") || taxItemName.equals("ApplicablePercent"))) {
if ((taxItemName != null) && (taxItemName.equals("RateApplicablePercent") || taxItemName.equals("ApplicablePercent") || taxItemName.equals("Percent"))) {
taxPercent = XMLTools.trimOrNull(taxChilds.item(taxChildIndex));
}
}