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,3 +1,18 @@
2.15.1
=======
- #566 Failed to parse PDF - Could not reproduce the invoice
? be able to access ID in error message
- closes #579 prepaidamount is only read in UBL
- #581 parse lineTotalAmount
- also parse TaxBasisAmount
- #576 read lineid, #578 set lineid
- log error ids
- #503 import more ubl
- allow jackson to run over more classes, e.g., DirectDebit, bean contructor for direct debit
- allow json includedNotes
- support importing duePayableAmount
2.15.0
=======
2024-11-18

View File

@@ -116,6 +116,12 @@
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.4</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- CII to UBL conversion -->
<dependency>

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));
}
}

View File

@@ -24,15 +24,25 @@ package org.mustangproject.ZUGFeRD;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import junit.framework.TestCase;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.*;
import org.mustangproject.ZUGFeRD.model.EventTimeCodeTypeConstants;
import javax.xml.xpath.XPathExpressionException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class DeSerializationTest extends TestCase {
public class DeSerializationTest extends ResourceCase {
public void testJackson() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
@@ -50,6 +60,33 @@ public class DeSerializationTest extends TestCase {
}
public void testInvoiceLine() throws JsonProcessingException {
File inputCII = getResourceAsFile("factur-x.xml");
boolean hasExceptions = false;
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
try {
zii.fromXML(new String(Files.readAllBytes(inputCII.toPath()), StandardCharsets.UTF_8));
} catch (IOException e) {
hasExceptions = true;
}
CalculatedInvoice ci = new CalculatedInvoice();
try {
zii.extractInto(ci);
} catch (XPathExpressionException e) {
hasExceptions = true;
} catch (ParseException e) {
hasExceptions = true;
}
ObjectMapper mapper = new ObjectMapper();
String jsonArray = mapper.writeValueAsString(ci);
assertFalse(hasExceptions);
assertTrue(jsonArray.contains("lineTotalAmount"));
}
public void testAllowanceRead() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
@@ -121,14 +158,57 @@ public class DeSerializationTest extends TestCase {
" }\n" +
" ]\n" +
"}", Invoice.class);
TransactionCalculator tc=new TransactionCalculator(fromJSON);
assertEquals(tc.getGrandTotal(),new BigDecimal("234.43"));
TransactionCalculator tc = new TransactionCalculator(fromJSON);
assertEquals(tc.getGrandTotal(), new BigDecimal("234.43"));
assertEquals(fromJSON.getNumber(), fromJSON.getNumber());
assertEquals(fromJSON.getZFItems().length, fromJSON.getZFItems().length);
}
public void testIssuerAssignedIDRoundtrip() {
String occurrenceFrom = "20201001";
String occurrenceTo = "20201005";
String contractID = "376zreurzu0983";
String orgID = "0009845";
String orgname = "Test company";
String number = "123";
String priceStr = "1.00";
String taxID = "9990815";
BigDecimal price = new BigDecimal(priceStr);
Invoice newInvoiceFromJSON = null;
boolean hasExceptions = false;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
SchemedID gtin = new SchemedID("0160", "2001015001325");
SchemedID gln = new SchemedID("0088", "4304171000002");
Invoice i = new Invoice().setCurrency("CHF").addNote("document level 1/2").addNote("document level 2/2").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
.setSellerOrderReferencedDocumentID("9384").setBuyerOrderReferencedDocumentID("28934")
.setDetailedDeliveryPeriod(new SimpleDateFormat("yyyyMMdd").parse(occurrenceFrom), new SimpleDateFormat("yyyyMMdd").parse(occurrenceTo))
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID(taxID).setEmail("sender@test.org").setID(orgID).addVATID("DE0815"))
.setDeliveryAddress(new TradeParty("just the other side of the street", "teststr.12a", "55232", "Entenhausen", "DE").addVATID("DE47110"))
.setContractReferencedDocument(contractID)
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addGlobalID(gln).setEmail("recipient@test.org").addVATID("DE4711")
.setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE").setFax("++49555123456")).setAdditionalAddress("Hinterhaus 3"))
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(16)).addGlobalID(gtin).setSellerAssignedID("4711"), price, new BigDecimal(1.0)).setId("a123").addReferencedLineID("xxx").addNote("item level 1/1").addAllowance(new Allowance(new BigDecimal(0.02)).setReason("item discount").setTaxPercent(new BigDecimal(16))).setDetailedDeliveryPeriod(sdf.parse("2020-01-13"), sdf.parse("2020-01-15")))
.addCharge(new Charge(new BigDecimal(0.5)).setReason("quick delivery charge").setTaxPercent(new BigDecimal(16)))
.addAllowance(new Allowance(new BigDecimal(0.2)).setReason("discount").setTaxPercent(new BigDecimal(16)))
.addCashDiscount(new CashDiscount(new BigDecimal(2), 14))
.setDeliveryDate(sdf.parse("2020-11-02")).setNumber(number).setVATDueDateTypeCode(EventTimeCodeTypeConstants.PAYMENT_DATE);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(i);
newInvoiceFromJSON = mapper.readValue(json, Invoice.class);
} catch (ParseException e) {
hasExceptions = true;
} catch (JsonProcessingException e) {
hasExceptions = true;
}
assertEquals(newInvoiceFromJSON.getBuyerOrderReferencedDocumentID(), "28934");
assertFalse(hasExceptions);
}
public void testDueDateRoundtrip() throws JsonProcessingException {
@@ -186,4 +266,389 @@ public class DeSerializationTest extends TestCase {
}
public void testDirectDebit() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
// [{"stringValue":"a","intValue":1,"booleanValue":true},
// {"stringValue":"bc","intValue":3,"booleanValue":false}]
boolean exceptions = false;
String theXML = "";
try {
Invoice fromJSON = mapper.readValue("\n" +
"\t{\n" +
"\t\t\"documentCode\": \"380\",\n" +
"\t\t\"number\": \"F20220031\",\n" +
"\t\t\"referenceNumber\": \"SERVEXEC\",\n" +
"\t\t\"buyerOrderReferencedDocumentID\": \"PO201925478\",\n" +
"\t\t\"ownOrganisationName\": \"LE FOURNISSEUR\",\n" +
"\t\t\"currency\": \"EUR\",\n" +
"\t\t\"issueDate\": \"2022-01-30T23:00:00.000+00:00\",\n" +
"\t\t\"dueDate\": \"2022-03-01T23:00:00.000+00:00\",\n" +
"\t\t\"deliveryDate\": \"2022-01-27T23:00:00.000+00:00\",\n" +
"\t\t\"sender\": {\n" +
"\t\t\"name\": \"LE FOURNISSEUR\",\n" +
"\t\t\t\"zip\": \"75018\",\n" +
"\t\t\t\"street\": \"35 rue d'ici\",\n" +
"\t\t\t\"location\": \"PARIS\",\n" +
"\t\t\t\"country\": \"FR\",\n" +
"\t\t\t\"vatID\": \"FR11123456782\",\n" +
"\t\t\t\"additionalAddress\": \"Seller line 2\",\n" +
"\t\t\t\"additionalAddressExtension\": \"Seller line 3\",\n" +
"\t\t\t\"bankDetails\": [\n" +
"\t\t{\n" +
"\t\t\t\"accountName\": null,\n" +
"\t\t\t\"iban\": \"FR20 1254 2547 2569 8542 5874 698\",\n" +
"\t\t\t\"bic\": \"BIC_MONCOMPTE\"\n" +
"\t\t}\n" +
" ],\n" +
"\t\t\"debitDetails\": [\n" +
"\t\t{\n" +
"\t\t\t\"mandate\": \"MANDATE PT\",\n" +
"\t\t\t\"iban\": \"FR20 1254 2547 2569 8542 5874 698\"\n" +
"\t\t}\n" +
" ],\n" +
"\t\t\"contact\": {\n" +
"\t\t\t\"name\": \"M. CONTACT\",\n" +
"\t\t\t\t\"phone\": \"01 02 03 54 87\",\n" +
"\t\t\t\t\"email\": \"seller@seller.com\",\n" +
"\t\t\t\t\"zip\": null,\n" +
"\t\t\t\t\"street\": null,\n" +
"\t\t\t\t\"location\": null,\n" +
"\t\t\t\t\"country\": null,\n" +
"\t\t\t\t\"fax\": null,\n" +
"\t\t\t\t\"vatid\": null,\n" +
"\t\t\t\t\"id\": null,\n" +
"\t\t\t\t\"additionalAddress\": null\n" +
"\t\t},\n" +
"\t\t\"email\": \"moi@seller.com\",\n" +
"\t\t\t\"vatid\": \"FR11123456782\",\n" +
"\t\t\t\"id\": \"123\",\n" +
"\t\t\t\"legalOrganisation\": {\n" +
"\t\t\t\"schemedID\": null,\n" +
"\t\t\t\t\"tradingBusinessName\": \"SELLER TRADE NAME\"\n" +
"\t\t},\n" +
"\t\t\"globalID\": \"587451236587\",\n" +
"\t\t\t\"globalIDScheme\": \"0088\"\n" +
"\t},\n" +
"\t\t\"recipient\": {\n" +
"\t\t\"name\": \"LE CLIENT\",\n" +
"\t\t\t\"zip\": \"06000\",\n" +
"\t\t\t\"street\": \"MON ADRESSE LIGNE 1\",\n" +
"\t\t\t\"location\": \"MA VILLE\",\n" +
"\t\t\t\"country\": \"FR\",\n" +
"\t\t\t\"vatID\": \"FR 05 987 654 321\",\n" +
"\t\t\t\"additionalAddress\": \"Buyer line 2\",\n" +
"\t\t\t\"additionalAddressExtension\": \"Buyer line 3\",\n" +
"\t\t\t\"contact\": {\n" +
"\t\t\t\"name\": \"Buyer contact name\",\n" +
"\t\t\t\t\"phone\": \"01 01 25 45 87\",\n" +
"\t\t\t\t\"email\": \"buyer@buyer.com\",\n" +
"\t\t\t\t\"zip\": null,\n" +
"\t\t\t\t\"street\": null,\n" +
"\t\t\t\t\"location\": null,\n" +
"\t\t\t\t\"country\": null,\n" +
"\t\t\t\t\"fax\": null,\n" +
"\t\t\t\t\"vatid\": null,\n" +
"\t\t\t\t\"id\": null,\n" +
"\t\t\t\t\"additionalAddress\": null\n" +
"\t\t},\n" +
"\t\t\"email\": \"me@buyer.com\",\n" +
"\t\t\t\"vatid\": \"FR 05 987 654 321\",\n" +
"\t\t\t\"legalOrganisation\": {\n" +
"\t\t\t\"schemedID\": null,\n" +
"\t\t\t\t\"tradingBusinessName\": null\n" +
"\t\t},\n" +
"\t\t\"globalID\": \"3654789851\",\n" +
"\t\t\t\"globalIDScheme\": \"0088\"\n" +
"\t},\n" +
"\t\t\"deliveryAddress\": {\n" +
"\t\t\"name\": \"DEL Name\",\n" +
"\t\t\t\"zip\": \"06000\",\n" +
"\t\t\t\"street\": \"DEL ADRESSE LIGNE 1\",\n" +
"\t\t\t\"location\": \"NICE\",\n" +
"\t\t\t\"country\": \"FR\",\n" +
"\t\t\t\"additionalAddress\": \"DEL line 2\",\n" +
"\t\t\t\"id\": \"PRIVATE_ID_DEL\"\n" +
"\t},\n" +
"\t\t\"payee\": {\n" +
"\t\t\"name\": \"PAYEE NAME\",\n" +
"\t\t\t\"legalOrganisation\": {\n" +
"\t\t\t\"schemedID\": null,\n" +
"\t\t\t\t\"tradingBusinessName\": null\n" +
"\t\t},\n" +
"\t\t\"globalID\": \"587451236586\",\n" +
"\t\t\t\"globalIDScheme\": \"0088\"\n" +
"\t},\n" +
"\t\t\"sellerOrderReferencedDocumentID\": \"SALES REF 2547\",\n" +
"\t\t\"despatchAdviceReferencedDocumentID\": \"DESPADV002\",\n" +
"\t\t\"grandTotal\": 107.82,\n" +
"\t\t\"detailedDeliveryPeriodFrom\": \"2021-12-31T23:00:00.000+00:00\",\n" +
"\t\t\"detailedDeliveryPeriodTo\": \"2022-12-30T23:00:00.000+00:00\",\n" +
"\t\t\"notesWithSubjectCode\": [\n" +
"\t\t{\n" +
"\t\t\t\"content\": \"FOURNISSEUR F SARL au capital de 50 000 EUR\",\n" +
"\t\t\t\"subjectCode\": \"REG\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"content\": \"RCS MAVILLE 123 456 782\",\n" +
"\t\t\t\"subjectCode\": \"ABL\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"content\": \"35 ma rue a moi, code postal Ville Pays contact@masociete.fr - www.masociete.fr N° TVA : FR32 123 456 789\",\n" +
"\t\t\t\"subjectCode\": \"AAI\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"content\": \"Tout retard de paiement engendre une pénalité exigible à compter de la date d'échéance, calculée sur la base de trois fois le taux d'intérêt légal.\",\n" +
"\t\t\t\"subjectCode\": null\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"content\": \"Indemnité forfaitaire pour frais de recouvrement en cas de retard de paiement : 40 €.\",\n" +
"\t\t\t\"subjectCode\": null\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"content\": \"Les réglements reçus avant la date d'échéance ne donneront pas lieu à escompte.\",\n" +
"\t\t\t\"subjectCode\": null\n" +
"\t\t}\n" +
" ],\n" +
"\t\t\"zfallowances\": [\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"REMISE VOLUME\",\n" +
"\t\t\t\"reasonCode\": \"71\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"REMISE VOLUME\",\n" +
"\t\t\t\"reasonCode\": \"71\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"REMISE VOLUME\",\n" +
"\t\t\t\"reasonCode\": \"71\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": null,\n" +
"\t\t\t\"reasonCode\": \"100\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 2,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"REMISE VOLUME\",\n" +
"\t\t\t\"reasonCode\": \"71\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"REMISE VOLUME\",\n" +
"\t\t\t\"reasonCode\": \"71\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"REMISE VOLUME\",\n" +
"\t\t\t\"reasonCode\": \"71\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": null,\n" +
"\t\t\t\"reasonCode\": \"100\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1.4,\n" +
"\t\t\t\"taxPercent\": 20,\n" +
"\t\t\t\"reason\": \"REMISE COMMERCIALE\",\n" +
"\t\t\t\"reasonCode\": \"100\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1.2,\n" +
"\t\t\t\"taxPercent\": 10,\n" +
"\t\t\t\"reason\": \"REMISE COMMERCIALE\",\n" +
"\t\t\t\"reasonCode\": \"100\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t}\n" +
" ],\n" +
"\t\t\"zfcharges\": [\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"FRAIS PALETTE\",\n" +
"\t\t\t\"reasonCode\": null,\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"FRAIS PALETTE\",\n" +
"\t\t\t\"reasonCode\": null,\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"FRAIS PALETTE\",\n" +
"\t\t\t\"reasonCode\": null,\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"FRAIS PALETTE\",\n" +
"\t\t\t\"reasonCode\": null,\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": null,\n" +
"\t\t\t\"reasonCode\": \"ADL\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"FRAIS PALETTE\",\n" +
"\t\t\t\"reasonCode\": null,\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 1,\n" +
"\t\t\t\"taxPercent\": null,\n" +
"\t\t\t\"reason\": \"FRAIS PALETTE\",\n" +
"\t\t\t\"reasonCode\": null,\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 2.8,\n" +
"\t\t\t\"taxPercent\": 20,\n" +
"\t\t\t\"reason\": \"FRAIS DEPLACEMENT\",\n" +
"\t\t\t\"reasonCode\": \"FC\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"percent\": null,\n" +
"\t\t\t\"totalAmount\": 0.6,\n" +
"\t\t\t\"taxPercent\": 10,\n" +
"\t\t\t\"reason\": \"FRAIS DEPLACEMENT\",\n" +
"\t\t\t\"reasonCode\": \"ADR\",\n" +
"\t\t\t\"categoryCode\": \"S\"\n" +
"\t\t}\n" +
" ],\n" +
"\t\t\"tradeSettlement\": [\n" +
"\t\t{\n" +
"\t\t\t\"accountName\": null,\n" +
"\t\t\t\"iban\": \"FR20 1254 2547 2569 8542 5874 698\",\n" +
"\t\t\t\"bic\": \"BIC_MONCOMPTE\"\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"mandate\": \"MANDATE PT\",\n" +
"\t\t\t\"iban\": \"FR20 1254 2547 2569 8542 5874 698\"\n" +
"\t\t}\n" +
" ],\n" +
"\t\t\"zfitems\": [\n" +
"\t\t{\n" +
"\t\t\t\"price\": 60,\n" +
"\t\t\t\"quantity\": 1,\n" +
"\t\t\t\"basisQuantity\": 1,\n" +
"\t\t\t\"product\": {\n" +
"\t\t\t\"unit\": \"C62\",\n" +
"\t\t\t\t\"name\": \"REMBOURSEMENT AFFRANCHISSEMENT\",\n" +
"\t\t\t\t\"description\": \"Description\",\n" +
"\t\t\t\t\"taxCategoryCode\": \"Z\",\n" +
"\t\t\t\t\"vatpercent\": 0,\n" +
"\t\t\t\t\"reverseCharge\": false,\n" +
"\t\t\t\t\"intraCommunitySupply\": false,\n" +
"\t\t\t\t\"globalID\": \"598785412598745\",\n" +
"\t\t\t\t\"globalIDScheme\": \"0160\"\n" +
"\t\t},\n" +
"\t\t\t\"buyerOrderReferencedDocumentLineID\": \"1\",\n" +
"\t\t\t\"value\": 60\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"price\": 30,\n" +
"\t\t\t\"quantity\": 3,\n" +
"\t\t\t\"basisQuantity\": 3,\n" +
"\t\t\t\"product\": {\n" +
"\t\t\t\"unit\": \"C62\",\n" +
"\t\t\t\t\"name\": \"FOURNITURES DIVERSES\",\n" +
"\t\t\t\t\"description\": \"Description\",\n" +
"\t\t\t\t\"taxCategoryCode\": \"S\",\n" +
"\t\t\t\t\"vatpercent\": 20,\n" +
"\t\t\t\t\"reverseCharge\": false,\n" +
"\t\t\t\t\"intraCommunitySupply\": false\n" +
"\t\t},\n" +
"\t\t\t\"buyerOrderReferencedDocumentLineID\": \"3\",\n" +
"\t\t\t\"value\": 30\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"price\": 12,\n" +
"\t\t\t\"quantity\": 1,\n" +
"\t\t\t\"basisQuantity\": 1,\n" +
"\t\t\t\"product\": {\n" +
"\t\t\t\"unit\": \"C62\",\n" +
"\t\t\t\t\"name\": \"APPEL\",\n" +
"\t\t\t\t\"description\": \"Description\",\n" +
"\t\t\t\t\"taxCategoryCode\": \"S\",\n" +
"\t\t\t\t\"vatpercent\": 10,\n" +
"\t\t\t\t\"reverseCharge\": false,\n" +
"\t\t\t\t\"intraCommunitySupply\": false\n" +
"\t\t},\n" +
"\t\t\t\"buyerOrderReferencedDocumentLineID\": \"2\",\n" +
"\t\t\t\"value\": 12\n" +
"\t\t}\n" +
" ],\n" +
"\t\t\"ownStreet\": \"35 rue d'ici\",\n" +
"\t\t\"ownCountry\": \"FR\",\n" +
"\t\t\"ownZIP\": \"75018\",\n" +
"\t\t\"ownLocation\": \"PARIS\",\n" +
"\t\t\"ownVATID\": \"FR11123456782\",\n" +
"\t\t\"valid\": false\n" +
"\t}\n", Invoice.class);
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
zf2p.setProfile(Profiles.getByName("XRechnung"));
zf2p.generateXML(fromJSON);
theXML = new String(zf2p.getXML());
} catch (Exception e) {
exceptions = true;
}
assertTrue(theXML.contains("pour frais de recouvrement en cas de retard de paiement"));
assertFalse(exceptions);
}
}

View File

@@ -61,9 +61,9 @@ public class ZF2PushTest extends TestCase {
final String TARGET_REVERSECHARGEPDF = "./target/testout-ZF2PushReverseCharge.pdf";
public void testPushExport() {
/***
* This writes to a filename like an official sample, please consider when changing (probably better not?)
*/
/***
* This writes to a filename like an official sample, please consider when changing (probably better not?)
*/
// the writing part
String orgname = "Bei Spiel GmbH";
String number = "RE-20201121/508";
@@ -96,8 +96,8 @@ public class ZF2PushTest extends TestCase {
fail("Exception should not be raised");
}
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
Invoice i=new Invoice();
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF);
Invoice i = new Invoice();
try {
zii.extractInto(i);
} catch (XPathExpressionException e) {
@@ -164,7 +164,7 @@ ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
fail("IOException should not be raised");
}
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_ATTACHMENTSPDF);
Invoice i= null;
Invoice i = null;
try {
i = zii.extractInvoice();
} catch (XPathExpressionException e) {
@@ -172,7 +172,7 @@ ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
} catch (ParseException e) {
throw new RuntimeException(e);
}
assertEquals(senderDescription,i.getSender().getDescription());
assertEquals(senderDescription, i.getSender().getDescription());
// now check the contents (like MustangReaderTest)
ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_ATTACHMENTSPDF);
@@ -302,7 +302,7 @@ ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
// .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)))));
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815").addTaxID ("4711"))
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815").addTaxID("4711"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816")
.setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562")))
.setDeliveryAddress(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816"))
@@ -372,7 +372,7 @@ ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
fail("IOException should not be raised");
}
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_INTRACOMMUNITYSUPPLYMANUALPDF);
Invoice i= null;
Invoice i = null;
try {
i = zii.extractInvoice();
} catch (XPathExpressionException e) {
@@ -530,7 +530,7 @@ ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
.setContractReferencedDocument(contractID)
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addGlobalID(gln).setEmail("recipient@test.org").addVATID("DE4711")
.setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE").setFax("++49555123456")).setAdditionalAddress("Hinterhaus 3"))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(16)).addGlobalID(gtin).setSellerAssignedID("4711"), price, new BigDecimal(1.0)).addReferencedLineID("xxx").addNote("item level 1/1").addAllowance(new Allowance(new BigDecimal(0.02)).setReason("item discount").setTaxPercent(new BigDecimal(16))).setDetailedDeliveryPeriod(sdf.parse("2020-01-13"), sdf.parse("2020-01-15")))
.addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(16)).addGlobalID(gtin).setSellerAssignedID("4711"), price, new BigDecimal(1.0)).setId("a123").addReferencedLineID("xxx").addNote("item level 1/1").addAllowance(new Allowance(new BigDecimal(0.02)).setReason("item discount").setTaxPercent(new BigDecimal(16))).setDetailedDeliveryPeriod(sdf.parse("2020-01-13"), sdf.parse("2020-01-15")))
.addCharge(new Charge(new BigDecimal(0.5)).setReason("quick delivery charge").setTaxPercent(new BigDecimal(16)))
.addAllowance(new Allowance(new BigDecimal(0.2)).setReason("discount").setTaxPercent(new BigDecimal(16)))
.addCashDiscount(new CashDiscount(new BigDecimal(2), 14))
@@ -562,7 +562,7 @@ ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
assertTrue(zi.getUTF8().contains(occurrenceFrom));
assertTrue(zi.getUTF8().contains(occurrenceTo));
assertTrue(zi.getUTF8().contains(contractID));
assertEquals(zi.importedInvoice.getZFItems()[0].getId(), "a123");
assertTrue(zi.getUTF8().contains("20200113")); // to contain item delivery periods
assertTrue(zi.getUTF8().contains("20200115")); // to contain item delivery periods

View File

@@ -22,12 +22,15 @@ package org.mustangproject.ZUGFeRD;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.StringUtils;
import org.junit.jupiter.api.Test;
import org.mustangproject.*;
import javax.xml.xpath.XPathExpressionException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
@@ -278,12 +281,16 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
public void testXRImport() {
boolean hasExceptions = false;
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
ZUGFeRDImporter zii = new ZUGFeRDImporter();
int version=-1;
try {
zii.fromXML(new String(Files.readAllBytes(Paths.get("./target/testout-XR-Edge.xml")), StandardCharsets.UTF_8));
version=zii.getVersion();
} catch (IOException e) {
hasExceptions = true;
} catch (Exception e) {
throw new RuntimeException(e);
}
Invoice invoice = null;
@@ -293,8 +300,17 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
hasExceptions = true;
}
assertFalse(hasExceptions);
TransactionCalculator tc = new TransactionCalculator(invoice);
assertEquals(new BigDecimal("1.00"), tc.getGrandTotal());
assertEquals(version,2);
assertTrue(new BigDecimal("1").compareTo(invoice.getZFItems()[0].getQuantity()) == 0);
LineCalculator lc=new LineCalculator(invoice.getZFItems()[0]);
assertTrue(new BigDecimal("1").compareTo(lc.getItemTotalNetAmount()) == 0);
assertTrue(invoice.getTradeSettlement().length == 1);
assertTrue(invoice.getTradeSettlement()[0] instanceof IZUGFeRDTradeSettlementPayment);
IZUGFeRDTradeSettlementPayment paym = (IZUGFeRDTradeSettlementPayment) invoice.getTradeSettlement()[0];
@@ -377,6 +393,35 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
}
@Test
public void testImportPrepaid() throws XPathExpressionException, ParseException {
InputStream inputStream = this.getClass()
.getResourceAsStream("/EN16931_1_Teilrechnung.pdf");
ZUGFeRDInvoiceImporter importer = new ZUGFeRDInvoiceImporter();
importer.doIgnoreCalculationErrors();
importer.setInputStream(inputStream);
CalculatedInvoice invoice = new CalculatedInvoice();
importer.extractInto(invoice);
boolean isBD=invoice.getTotalPrepaidAmount() instanceof BigDecimal;
assertTrue(isBD);
BigDecimal expectedPrepaid=new BigDecimal(50);
BigDecimal expectedLineTotal=new BigDecimal("180.76");
BigDecimal expectedDue=new BigDecimal("147.65");
if (isBD) {
BigDecimal amread=invoice.getTotalPrepaidAmount();
BigDecimal importedLineTotal=invoice.getLineTotalAmount();
BigDecimal importedDuePayable=invoice.getDuePayable();
assertTrue(amread.compareTo(expectedPrepaid) == 0);
assertTrue(importedLineTotal.compareTo(expectedLineTotal) == 0);
assertTrue(importedDuePayable.compareTo(expectedDue) == 0);
}
}
@Test
public void testImportIncludedNotes() throws XPathExpressionException, ParseException {
InputStream inputStream = this.getClass()
@@ -397,4 +442,25 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
}
@Test
public void testImportPositionIncludedNotes() throws FileNotFoundException, XPathExpressionException, ParseException {
File inputFile = getResourceAsFile("ZTESTZUGFERD_1_INVDSS_012015738820PDF-1.pdf");
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile));
Invoice invoice = zii.extractInvoice();
assertEquals(1, invoice.getZFItems().length);
assertEquals(8, invoice.getZFItems()[0].getNotesWithSubjectCode().size());
assertEquals("FB-LE 9999", invoice.getZFItems()[0].getNotesWithSubjectCode().stream().filter(note -> note.getSubjectCode().equals(SubjectCode.ABZ)).findFirst().get().getContent());
}
@Test
public void testImportXRechnungPositionNote() throws FileNotFoundException, XPathExpressionException, ParseException {
File inputFile = getResourceAsFile("TESTXRECHNUNG_INVDSS_012015776085.XML");
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile));
Invoice invoice = zii.extractInvoice();
assertEquals(1, invoice.getZFItems().length);
assertFalse(invoice.getZFItems()[0].getNotes() == null);
assertEquals(1, invoice.getZFItems()[0].getNotes().length);
}
}

Binary file not shown.

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?><ubl:Invoice xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>2015776085</cbc:ID>
<cbc:IssueDate>2024-11-01</cbc:IssueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:Note>#AAI# Wenn bereits bezahlt, nur zu den Akten legen. Für Verzug und Verzugszinsen gelten die Bestimmungen der §§ 286 - 288 BGB. Der Schuldner einer Entgeltforderung kommt spätestens in Verzug, wenn er nicht innerhalb von 30 Tagen nach Fälligkeit und Zugang einer Rechnung oder gleichwertigen Zahlungsaufstellung leistet. Die Lieferung von Waren und Fahrzeugen erfolgt unter Eigentumsvorbehalt.</cbc:Note>
<cbc:Note>#PAI# Rechnungsbetrag zahlbar ohne Abzug sofort nach Erhalt der Rechnung.</cbc:Note>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>02-ZZ987654-99</cbc:BuyerReference>
<cac:InvoicePeriod>
<cbc:StartDate>2024-11-01</cbc:StartDate>
<cbc:EndDate>2024-11-30</cbc:EndDate>
</cac:InvoicePeriod>
<cac:OrderReference>
<cbc:ID>N/A</cbc:ID>
</cac:OrderReference>
<cac:ContractDocumentReference>
<cbc:ID>63435555</cbc:ID>
</cac:ContractDocumentReference>
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="9930">DE238574172</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Alphabet Fuhrparkmanagement GmbH</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Lilienthalallee 26</cbc:StreetName>
<cbc:CityName>München</cbc:CityName>
<cbc:PostalZone>80786</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE238574172</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Alphabet Fuhrparkmanagement GmbH</cbc:RegistrationName>
<cbc:CompanyID>HRB 181098</cbc:CompanyID>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Yildiz Tolga</cbc:Name>
<cbc:Telephone>+49899--</cbc:Telephone>
<cbc:ElectronicMail>Tolga.Yildiz@alphabet.de</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="9930">N/A</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID>00987654</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Muster GmbH</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Musterweg 1</cbc:StreetName>
<cbc:CityName>Kiel</cbc:CityName>
<cbc:PostalZone>24105</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Muster GmbH</cbc:RegistrationName>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Mustermann Max</cbc:Name>
</cac:Contact>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:Delivery>
<cbc:ActualDeliveryDate>2024-11-30</cbc:ActualDeliveryDate>
<cac:DeliveryLocation>
<cbc:ID>00987654</cbc:ID>
<cac:Address>
<cbc:StreetName>Musterweg 1</cbc:StreetName>
<cbc:CityName>Kiel</cbc:CityName>
<cbc:PostalZone>24105</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:Address>
</cac:DeliveryLocation>
<cac:DeliveryParty>
<cac:PartyName>
<cbc:Name>Muster GmbH</cbc:Name>
</cac:PartyName>
</cac:DeliveryParty>
</cac:Delivery>
<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
<cac:PayeeFinancialAccount>
<cbc:ID>DE34700700100156919301</cbc:ID>
<cbc:Name>Alphabet Fuhrparkmanagement GmbH</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>DEUTDEMMXXX</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>
<cac:PaymentTerms>
<cbc:Note>Rechnungsbetrag zahlbar ohne Abzug sofort nach Erhalt der Rechnung.</cbc:Note>
</cac:PaymentTerms>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">161.69</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">851.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">161.69</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">851.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">851.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">1012.69</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">1012.69</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:Note>#AAI# Finanzrate vom 01.11.2024 bis 30.11.2024 #ABZ/Kennzeichen#SH-9 18E #AKG/Fahrgestellnummer#WBY51EJ080CR55555 #BA/Kilometerstand#0 #AKV/LeasingNr#63435555</cbc:Note>
<cbc:InvoicedQuantity unitCode="C62">1.00</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">851.00</cbc:LineExtensionAmount>
<cac:InvoicePeriod>
<cbc:StartDate>2024-11-01</cbc:StartDate>
<cbc:EndDate>2024-11-30</cbc:EndDate>
</cac:InvoicePeriod>
<cac:Item>
<cbc:Description>FL-Rate</cbc:Description>
<cbc:Name>FL-Rate</cbc:Name>
<cac:SellersItemIdentification>
<cbc:ID>90101</cbc:ID>
</cac:SellersItemIdentification>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">851.00</cbc:PriceAmount>
<cbc:BaseQuantity>1.00</cbc:BaseQuantity>
</cac:Price>
</cac:InvoiceLine>
</ubl:Invoice>

View File

@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<rsm:ExchangedDocumentContext>
<ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:ID>BT-23 Business Process Type</ram:ID>
@@ -19,11 +16,11 @@
</ram:IssueDateTime>
<ram:IncludedNote>
<ram:Content>invoice note text</ram:Content>
<ram:SubjectCode>AAA</ram:SubjectCode>
<ram:SubjectCode>#AAA#</ram:SubjectCode>
</ram:IncludedNote>
<ram:IncludedNote>
<ram:Content>invoice note text 2</ram:Content>
<ram:SubjectCode>AAA</ram:SubjectCode>
<ram:SubjectCode>#AAA#</ram:SubjectCode>
</ram:IncludedNote>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
@@ -35,9 +32,7 @@
</ram:IncludedNote>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:GlobalID schemeID="0060">Item standar identifier
</ram:GlobalID>
<ram:GlobalID>Item standar identifier</ram:GlobalID>
<ram:SellerAssignedID>Item seller's identifier</ram:SellerAssignedID>
<ram:BuyerAssignedID>Item buyer's identifier</ram:BuyerAssignedID>
<ram:Name>Item name</ram:Name>
@@ -98,9 +93,9 @@
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:CalculationPercent>1.00</ram:CalculationPercent>
<ram:BasisAmount>100.00</ram:BasisAmount>
<ram:BasisAmount>1000.00</ram:BasisAmount>
<ram:ActualAmount>10.00</ram:ActualAmount>
<ram:ReasonCode>95</ram:ReasonCode>
<ram:ReasonCode>55</ram:ReasonCode>
<ram:Reason>Invoice line allowance reason</ram:Reason>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedTradeAllowanceCharge>
@@ -108,17 +103,18 @@
<udt:Indicator>true</udt:Indicator>
</ram:ChargeIndicator>
<ram:CalculationPercent>1.00</ram:CalculationPercent>
<ram:BasisAmount>100.00</ram:BasisAmount>
<ram:BasisAmount>1000.00</ram:BasisAmount>
<ram:ActualAmount>10.00</ram:ActualAmount>
<ram:ReasonCode>AAA</ram:ReasonCode>
<ram:Reason>Invoice line charge reason</ram:Reason>
</ram:SpecifiedTradeAllowanceCharge>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>100.00</ram:LineTotalAmount>
<ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:AdditionalReferencedDocument>
<ram:IssuerAssignedID>Line object identifier</ram:IssuerAssignedID>
<ram:TypeCode>130</ram:TypeCode>
<ram:ReferenceTypeCode />
</ram:AdditionalReferencedDocument>
<ram:ReceivableSpecifiedTradeAccountingAccount>
<ram:ID>6789</ram:ID>
@@ -147,7 +143,7 @@
<ram:RateApplicablePercent>0.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>100.00</ram:LineTotalAmount>
<ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
@@ -159,7 +155,7 @@
<ram:Name>Seller name</ram:Name>
<ram:Description>Seller additional legal information</ram:Description>
<ram:SpecifiedLegalOrganization>
<!-- <ram:ID schemeID="0310">Seller legal identifier</ram:ID> -->
<ram:ID schemeID="0310">Seller legal identifier</ram:ID>
<ram:TradingBusinessName>Seller trading name</ram:TradingBusinessName>
</ram:SpecifiedLegalOrganization>
<ram:DefinedTradeContact>
@@ -181,7 +177,7 @@
<ram:CountrySubDivisionName>Seller country subdivision</ram:CountrySubDivisionName>
</ram:PostalTradeAddress>
<ram:URIUniversalCommunication>
<ram:URIID schemeID="EM">Seller electronic address</ram:URIID>
<ram:URIID schemeID="SMTP">Seller electronic address</ram:URIID>
</ram:URIUniversalCommunication>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE12345677</ram:ID>
@@ -216,7 +212,7 @@
<ram:CountrySubDivisionName>Buyer country subdivision</ram:CountrySubDivisionName>
</ram:PostalTradeAddress>
<ram:URIUniversalCommunication>
<ram:URIID schemeID="EM">Buyer electronic address</ram:URIID>
<ram:URIID schemeID="DE:SMTP">Buyer electronic address</ram:URIID>
</ram:URIUniversalCommunication>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">IE394838894</ram:ID>
@@ -256,7 +252,7 @@
<ram:AdditionalReferencedDocument>
<ram:IssuerAssignedID>rst</ram:IssuerAssignedID>
<ram:TypeCode>130</ram:TypeCode>
<ram:ReferenceTypeCode>AAA</ram:ReferenceTypeCode>
<ram:ReferenceTypeCode>0090</ram:ReferenceTypeCode>
</ram:AdditionalReferencedDocument>
<ram:SpecifiedProcuringProject>
<ram:ID>456</ram:ID>
@@ -315,32 +311,32 @@
<ram:IBANID>IT1212341234123412</ram:IBANID>
<ram:AccountName>Payment account name</ram:AccountName>
</ram:PayeePartyCreditorFinancialAccount>
<!-- <ram:BICID>BSCTCH22</ram:BICID> -->
<!-- <ram:PayerSpecifiedDebtorFinancialInstitution>
</ram:PayerSpecifiedDebtorFinancialInstitution> -->
<!-- <ram:PayeePartyCreditorFinancialAccount>
<ram:IBANID>IT1212341234123413</ram:IBANID>
<ram:AccountName>Payment account name 2</ram:AccountName>
<ram:PayerSpecifiedDebtorFinancialInstitution>
<ram:BICID>BSCTCH22</ram:BICID>
</ram:PayerSpecifiedDebtorFinancialInstitution>
<ram:PayeePartyCreditorFinancialAccount>
<ram:IBANID>IT1212341234123413</ram:IBANID>
<ram:AccountName>Payment account name 2</ram:AccountName>
</ram:PayeePartyCreditorFinancialAccount>
<ram:PayerSpecifiedDebtorFinancialInstitution>
<ram:BICID>BSCTCH22</ram:BICID>
</ram:PayerSpecifiedDebtorFinancialInstitution> -->
<ram:BICID>BSCTCH22</ram:BICID>
</ram:PayerSpecifiedDebtorFinancialInstitution>
</ram:SpecifiedTradeSettlementPaymentMeans>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>5.00</ram:CalculatedAmount>
<ram:CalculatedAmount>50.00</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>100.00</ram:BasisAmount>
<ram:BasisAmount>1000.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<!-- <ram:DueDateTypeCode>29</ram:DueDateTypeCode> -->
<ram:DueDateTypeCode>29</ram:DueDateTypeCode>
<ram:RateApplicablePercent>5.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>0.00</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:ExemptionReason>Exemtion reason text</ram:ExemptionReason>
<ram:BasisAmount>100.00</ram:BasisAmount>
<ram:BasisAmount>1000.00</ram:BasisAmount>
<ram:CategoryCode>E</ram:CategoryCode>
<ram:ExemptionReasonCode>VATEX-EU-O</ram:ExemptionReasonCode>
<ram:ExemptionReasonCode>Exemption reason code</ram:ExemptionReasonCode>
<ram:DueDateTypeCode>29</ram:DueDateTypeCode>
<ram:RateApplicablePercent>0.00</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
@@ -357,9 +353,9 @@
<udt:Indicator>false</udt:Indicator>
</ram:ChargeIndicator>
<ram:CalculationPercent>1.00</ram:CalculationPercent>
<ram:BasisAmount>100.00</ram:BasisAmount>
<ram:BasisAmount>1000.00</ram:BasisAmount>
<ram:ActualAmount>10.00</ram:ActualAmount>
<ram:ReasonCode>95</ram:ReasonCode>
<ram:ReasonCode>55</ram:ReasonCode>
<ram:Reason>Doc allowance reason text</ram:Reason>
<ram:CategoryTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
@@ -372,7 +368,7 @@
<udt:Indicator>true</udt:Indicator>
</ram:ChargeIndicator>
<ram:CalculationPercent>1.00</ram:CalculationPercent>
<ram:BasisAmount>100.00</ram:BasisAmount>
<ram:BasisAmount>1000.00</ram:BasisAmount>
<ram:ActualAmount>10.00</ram:ActualAmount>
<ram:ReasonCode>AAA</ram:ReasonCode>
<ram:Reason>Doc charge reason text</ram:Reason>
@@ -390,16 +386,16 @@
<ram:DirectDebitMandateID>Mandate reference identifier</ram:DirectDebitMandateID>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>200.00</ram:LineTotalAmount>
<ram:LineTotalAmount>2000.00</ram:LineTotalAmount>
<ram:ChargeTotalAmount>10.00</ram:ChargeTotalAmount>
<ram:AllowanceTotalAmount>10.00</ram:AllowanceTotalAmount>
<ram:TaxBasisTotalAmount>200.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">5.00</ram:TaxTotalAmount>
<ram:TaxTotalAmount currencyID="NOK">4.60</ram:TaxTotalAmount>
<ram:TaxBasisTotalAmount>2000.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">50.00</ram:TaxTotalAmount>
<ram:TaxTotalAmount currencyID="NOK">46.00</ram:TaxTotalAmount>
<ram:RoundingAmount>0.00</ram:RoundingAmount>
<ram:GrandTotalAmount>205.00</ram:GrandTotalAmount>
<ram:GrandTotalAmount>2050.00</ram:GrandTotalAmount>
<ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>
<ram:DuePayableAmount>205.00</ram:DuePayableAmount>
<ram:DuePayableAmount>2050.00</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:InvoiceReferencedDocument>
<ram:IssuerAssignedID>abc123</ram:IssuerAssignedID>

View File

@@ -1,365 +1,401 @@
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cec="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ccts="urn:un:unece:uncefact:documentation:2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDataTypes-2" xmlns:udt="urn:oasis:names:specification:ubl:schema:xsd:UnqualifiedDataTypes-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
<cbc:ProfileID>BT-23 Business Process Type</cbc:ProfileID>
<cbc:ID>Test_EeISI_100</cbc:ID>
<cbc:IssueDate>2018-11-12</cbc:IssueDate>
<cbc:DueDate>2018-11-30</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:Note>#AAA#invoice note text</cbc:Note>
<cbc:Note>#AAA#invoice note text 2</cbc:Note>
<cbc:Note>##AAA##invoice note text</cbc:Note>
<cbc:Note>##AAA##invoice note text 2</cbc:Note>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cbc:TaxCurrencyCode>NOK</cbc:TaxCurrencyCode>
<cbc:AccountingCost>uvz</cbc:AccountingCost>
<cbc:BuyerReference>123</cbc:BuyerReference>
<cac:InvoicePeriod>
<cbc:StartDate>2018-11-12</cbc:StartDate>
<cbc:EndDate>2018-11-30</cbc:EndDate>
</cac:InvoicePeriod>
<cac:OrderReference>
<cbc:ID>abc</cbc:ID>
<cbc:SalesOrderID>def</cbc:SalesOrderID>
</cac:OrderReference>
<cac:BillingReference>
<cac:InvoiceDocumentReference>
<cbc:ID>abc123</cbc:ID>
<cbc:IssueDate>2018-10-04</cbc:IssueDate>
</cac:InvoiceDocumentReference>
</cac:BillingReference>
<cac:DespatchDocumentReference>
<cbc:ID>lmn</cbc:ID>
</cac:DespatchDocumentReference>
<cac:ReceiptDocumentReference>
<cbc:ID>ghi</cbc:ID>
</cac:ReceiptDocumentReference>
<cac:ContractDocumentReference>
<cbc:ID>789</cbc:ID>
</cac:ContractDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID>Supporting document ref</cbc:ID>
<cbc:DocumentDescription>Supporting document descr</cbc:DocumentDescription>
<cac:Attachment>
<cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="filename0">ZGVmYXVsdA==</cbc:EmbeddedDocumentBinaryObject>
<cac:ExternalReference>
<cbc:URI>External document location</cbc:URI>
</cac:ExternalReference>
</cac:Attachment>
</cac:AdditionalDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID schemeID="AAA">rst</cbc:ID>
<cbc:DocumentTypeCode>130</cbc:DocumentTypeCode>
</cac:AdditionalDocumentReference>
<cac:ProjectReference>
<cbc:ID>456</cbc:ID>
</cac:ProjectReference>
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="EM">Seller electronic address</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID schemeID="0100">Seller identifier 1</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="0110">Seller identifier 2</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Seller trading name</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Seller address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Seller address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Seller city</cbc:CityName>
<cbc:PostalZone>12345</cbc:PostalZone>
<cbc:CountrySubentity>Seller country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Seller address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE12345677</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE49294093</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>FC</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Seller name</cbc:RegistrationName>
<cbc:CompanyLegalForm>Seller additional legal information</cbc:CompanyLegalForm>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Seller contact point</cbc:Name>
<cbc:Telephone>+41 345 654455</cbc:Telephone>
<cbc:ElectronicMail>seller@contact.de</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="EM">Buyer electronic address</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID schemeID="0190">Buyer identifier</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Buyer trading name</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Buyer address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Buyer address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Buyer city</cbc:CityName>
<cbc:PostalZone>34562</cbc:PostalZone>
<cbc:CountrySubentity>Buyer country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Buyer address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>IE394838894</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Buyer name</cbc:RegistrationName>
<cbc:CompanyID schemeID="0089">Buyer legal registration identifier</cbc:CompanyID>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Buyer contact point</cbc:Name>
<cbc:Telephone>+353 2948584</cbc:Telephone>
<cbc:ElectronicMail>buyer@contact.ie</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:PayeeParty>
<cac:PartyIdentification>
<cbc:ID schemeID="0098">Payee identifier</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Payee name</cbc:Name>
</cac:PartyName>
</cac:PayeeParty>
<cac:TaxRepresentativeParty>
<cac:PartyName>
<cbc:Name>Tax representative name</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Tax representative address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Tax representative address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Tax representative city</cbc:CityName>
<cbc:PostalZone>23455</cbc:PostalZone>
<cbc:CountrySubentity>Tax representative country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Tax representative address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE3949053</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
</cac:TaxRepresentativeParty>
<cac:Delivery>
<cbc:ActualDeliveryDate>2018-12-04</cbc:ActualDeliveryDate>
<cac:DeliveryLocation>
<cbc:ID schemeID="0045">deliver location identifier</cbc:ID>
<cac:Address>
<cbc:StreetName>Deliver to address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Deliver to address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Deliver to city</cbc:CityName>
<cbc:PostalZone>98765</cbc:PostalZone>
<cbc:CountrySubentity>Deliver to country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Deliver to address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
</cac:Country>
</cac:Address>
</cac:DeliveryLocation>
<cac:DeliveryParty>
<cac:PartyName>
<cbc:Name>Deliver to party name</cbc:Name>
</cac:PartyName>
</cac:DeliveryParty>
</cac:Delivery>
<cac:PaymentTerms>
<cbc:Note>total amount</cbc:Note>
</cac:PaymentTerms>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Doc allowance reason text</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>1.00</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="EUR">10</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>AAA</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Doc charge reason text</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>1.00</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="EUR">10</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">50</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">1000</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">50</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">1000</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">0</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>E</cbc:ID>
<cbc:Percent>0</cbc:Percent>
<cbc:TaxExemptionReasonCode>VATEX-EU-O</cbc:TaxExemptionReasonCode>
<cbc:TaxExemptionReason>Exemtion reason text</cbc:TaxExemptionReason>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="NOK">46</cbc:TaxAmount>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">200</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">200</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">205</cbc:TaxInclusiveAmount>
<cbc:AllowanceTotalAmount currencyID="EUR">10</cbc:AllowanceTotalAmount>
<cbc:ChargeTotalAmount currencyID="EUR">10</cbc:ChargeTotalAmount>
<cbc:PrepaidAmount currencyID="EUR">0</cbc:PrepaidAmount>
<cbc:PayableAmount currencyID="EUR">205</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1a</cbc:ID>
<cbc:Note>Invoice line note</cbc:Note>
<cbc:InvoicedQuantity unitCode="EA">10</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">1000</cbc:LineExtensionAmount>
<cbc:AccountingCost>6789</cbc:AccountingCost>
<cac:InvoicePeriod>
<cbc:StartDate>2018-11-12</cbc:StartDate>
<cbc:EndDate>2018-11-30</cbc:EndDate>
</cac:InvoicePeriod>
<cac:OrderLineReference>
<cbc:LineID>12345</cbc:LineID>
</cac:OrderLineReference>
<cac:DocumentReference>
<cbc:ID>Line object identifier</cbc:ID>
<cbc:DescriptionCode>35</cbc:DescriptionCode>
</cac:InvoicePeriod>
<cac:OrderReference>
<cbc:ID>abc</cbc:ID>
<cbc:SalesOrderID>def</cbc:SalesOrderID>
</cac:OrderReference>
<cac:BillingReference>
<cac:InvoiceDocumentReference>
<cbc:ID>abc123</cbc:ID>
<cbc:IssueDate>2018-10-04</cbc:IssueDate>
</cac:InvoiceDocumentReference>
</cac:BillingReference>
<cac:DespatchDocumentReference>
<cbc:ID>lmn</cbc:ID>
</cac:DespatchDocumentReference>
<cac:ReceiptDocumentReference>
<cbc:ID>ghi</cbc:ID>
</cac:ReceiptDocumentReference>
<cac:OriginatorDocumentReference>
<cbc:ID>opq</cbc:ID>
</cac:OriginatorDocumentReference>
<cac:ContractDocumentReference>
<cbc:ID>789</cbc:ID>
</cac:ContractDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID schemeID="0090">rst</cbc:ID>
<cbc:DocumentTypeCode>130</cbc:DocumentTypeCode>
</cac:DocumentReference>
<cac:AllowanceCharge>
</cac:AdditionalDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID>Supporting document ref</cbc:ID>
<cbc:DocumentDescription>Supporting document descr</cbc:DocumentDescription>
<cac:Attachment>
<cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="filename0">ZGVmYXVsdA==</cbc:EmbeddedDocumentBinaryObject>
<cac:ExternalReference>
<cbc:URI>External document location</cbc:URI>
</cac:ExternalReference>
</cac:Attachment>
</cac:AdditionalDocumentReference>
<cac:ProjectReference>
<cbc:ID>456</cbc:ID>
</cac:ProjectReference>
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="SMTP">Seller electronic address</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID schemeID="0100">Seller identifier 1</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="0110">Seller identifier 2</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Seller trading name</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Seller address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Seller address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Seller city</cbc:CityName>
<cbc:PostalZone>12345</cbc:PostalZone>
<cbc:CountrySubentity>Seller country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Seller address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE12345677</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE49294093</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>NOVAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Seller name</cbc:RegistrationName>
<cbc:CompanyID schemeID="0310">Seller legal identifier</cbc:CompanyID>
<cbc:CompanyLegalForm>Seller additional legal information</cbc:CompanyLegalForm>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Seller contact point</cbc:Name>
<cbc:Telephone>+41 345 654455</cbc:Telephone>
<cbc:ElectronicMail>seller@contact.de</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="DE:SMTP">Buyer electronic address</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID>0190:Buyer identifier</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Buyer trading name</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Buyer address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Buyer address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Buyer city</cbc:CityName>
<cbc:PostalZone>34562</cbc:PostalZone>
<cbc:CountrySubentity>Buyer country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Buyer address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>IE394838894</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Buyer name</cbc:RegistrationName>
<cbc:CompanyID>Buyer legal registration identifier</cbc:CompanyID>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Buyer contact point</cbc:Name>
<cbc:Telephone>+353 2948584</cbc:Telephone>
<cbc:ElectronicMail>buyer@contact.ie</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:PayeeParty>
<cac:PartyIdentification>
<cbc:ID schemeID="0098">Payee identifier</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Payee name</cbc:Name>
</cac:PartyName>
<cac:PartyLegalEntity>
<cbc:CompanyID schemeID="0099">Payee legal registration identifier</cbc:CompanyID>
</cac:PartyLegalEntity>
</cac:PayeeParty>
<cac:TaxRepresentativeParty>
<cac:PartyName>
<cbc:Name>Tax representative name</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Tax representative address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Tax representative address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Tax representative city</cbc:CityName>
<cbc:PostalZone>23455</cbc:PostalZone>
<cbc:CountrySubentity>Tax representative country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Tax representative address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE3949053</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
</cac:TaxRepresentativeParty>
<cac:Delivery>
<cbc:ActualDeliveryDate>2018-12-04</cbc:ActualDeliveryDate>
<cac:DeliveryLocation>
<cbc:ID schemeID="0045">deliver location identifier</cbc:ID>
<cac:Address>
<cbc:StreetName>Deliver to address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Deliver to address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Deliver to city</cbc:CityName>
<cbc:PostalZone>98765</cbc:PostalZone>
<cbc:CountrySubentity>Deliver to country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Deliver to address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
</cac:Country>
</cac:Address>
</cac:DeliveryLocation>
<cac:DeliveryParty>
<cac:PartyName>
<cbc:Name>Deliver to party name</cbc:Name>
</cac:PartyName>
</cac:DeliveryParty>
</cac:Delivery>
<cac:PaymentMeans>
<cbc:PaymentMeansCode name="SEPA">4</cbc:PaymentMeansCode>
<cbc:PaymentID>Remittance information</cbc:PaymentID>
<cac:CardAccount>
<cbc:PrimaryAccountNumberID>1234</cbc:PrimaryAccountNumberID>
<cbc:NetworkID>mandatory network id</cbc:NetworkID>
<cbc:HolderName>Payment card holder name</cbc:HolderName>
</cac:CardAccount>
<cac:PayeeFinancialAccount>
<cbc:ID>IT1212341234123412</cbc:ID>
<cbc:Name>Payment account name</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>BSCTCH22</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
<cac:PayeeFinancialAccount>
<cbc:ID>IT1212341234123413</cbc:ID>
<cbc:Name>Payment account name 2</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>BSCTCH22</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
<cac:PaymentMandate>
<cbc:ID>Mandate reference identifier</cbc:ID>
<cac:PayerFinancialAccount>
<cbc:ID>Debited account identifier</cbc:ID>
</cac:PayerFinancialAccount>
</cac:PaymentMandate>
</cac:PaymentMeans>
<cac:PaymentTerms>
<cbc:Note>total amount</cbc:Note>
</cac:PaymentTerms>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Invoice line allowance reason</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>1.00</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="EUR">10</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
</cac:AllowanceCharge>
<cac:AllowanceCharge>
<cbc:AllowanceChargeReasonCode>55</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Doc allowance reason text</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>1.0000</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="EUR">10.00</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1000.00</cbc:BaseAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>AAA</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Invoice line charge reason</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>1.00</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="EUR">10</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
</cac:AllowanceCharge>
<cac:Item>
<cbc:Description>Item description</cbc:Description>
<cbc:Name>Item name</cbc:Name>
<cac:BuyersItemIdentification>
<cbc:ID>Item buyer's identifier</cbc:ID>
</cac:BuyersItemIdentification>
<cac:SellersItemIdentification>
<cbc:ID>Item seller's identifier</cbc:ID>
</cac:SellersItemIdentification>
<cac:StandardItemIdentification>
<cbc:ID schemeID="0060">Item standar identifier</cbc:ID>
</cac:StandardItemIdentification>
<cac:OriginCountry>
<cbc:IdentificationCode>IT</cbc:IdentificationCode>
</cac:OriginCountry>
<cac:CommodityClassification>
<cbc:ItemClassificationCode listID="ZZZ" listVersionID="version0">Item classification identifier0</cbc:ItemClassificationCode>
</cac:CommodityClassification>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
<cac:AdditionalItemProperty>
<cbc:Name>Color</cbc:Name>
<cbc:Value>Red</cbc:Value>
</cac:AdditionalItemProperty>
<cac:AdditionalItemProperty>
<cbc:Name>Size</cbc:Name>
<cbc:Value>L</cbc:Value>
</cac:AdditionalItemProperty>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="EA">1</cbc:BaseQuantity>
<cbc:AllowanceChargeReason>Doc charge reason text</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>1.0000</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="EUR">10.00</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1000.00</cbc:BaseAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="NOK">46.00</cbc:TaxAmount>
</cac:TaxTotal>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">50.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">50.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">0.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>E</cbc:ID>
<cbc:Percent>0.00</cbc:Percent>
<cbc:TaxExemptionReasonCode>Exemption reason code</cbc:TaxExemptionReasonCode>
<cbc:TaxExemptionReason>Exemtion reason text</cbc:TaxExemptionReason>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">2000.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">2000.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">2050.00</cbc:TaxInclusiveAmount>
<cbc:AllowanceTotalAmount currencyID="EUR">10.00</cbc:AllowanceTotalAmount>
<cbc:ChargeTotalAmount currencyID="EUR">10.00</cbc:ChargeTotalAmount>
<cbc:PayableAmount currencyID="EUR">2050.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1a</cbc:ID>
<cbc:Note>Invoice line note</cbc:Note>
<cbc:InvoicedQuantity unitCode="EA">10.00000000</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
<cbc:AccountingCost>6789</cbc:AccountingCost>
<cac:InvoicePeriod>
<cbc:StartDate>2018-11-12</cbc:StartDate>
<cbc:EndDate>2018-11-30</cbc:EndDate>
</cac:InvoicePeriod>
<cac:OrderLineReference>
<cbc:LineID>12345</cbc:LineID>
</cac:OrderLineReference>
<cac:DocumentReference>
<cbc:ID schemeID="ZZZ">Line object identifier</cbc:ID>
<cbc:DocumentTypeCode>130</cbc:DocumentTypeCode>
</cac:DocumentReference>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">1</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">11</cbc:BaseAmount>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>55</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Invoice line allowance reason</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>1</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="EUR">10</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>AAA</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Invoice line charge reason</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>1</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="EUR">10</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">1000</cbc:BaseAmount>
</cac:AllowanceCharge>
<cac:Item>
<cbc:Description>Item description</cbc:Description>
<cbc:Name>Item name</cbc:Name>
<cac:BuyersItemIdentification>
<cbc:ID>Item buyer's identifier</cbc:ID>
</cac:BuyersItemIdentification>
<cac:SellersItemIdentification>
<cbc:ID>Item seller's identifier</cbc:ID>
</cac:SellersItemIdentification>
<cac:StandardItemIdentification>
<cbc:ID>Item standar identifier</cbc:ID>
</cac:StandardItemIdentification>
<cac:OriginCountry>
<cbc:IdentificationCode>IT</cbc:IdentificationCode>
</cac:OriginCountry>
<cac:CommodityClassification>
<cbc:ItemClassificationCode listID="ZZZ" listVersionID="version0">Item classification identifier0</cbc:ItemClassificationCode>
</cac:CommodityClassification>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
<cac:AdditionalItemProperty>
<cbc:Name>Color</cbc:Name>
<cbc:Value>Red</cbc:Value>
</cac:AdditionalItemProperty>
<cac:AdditionalItemProperty>
<cbc:Name>Size</cbc:Name>
<cbc:Value>L</cbc:Value>
</cac:AdditionalItemProperty>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10.00</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="EA">1.00</cbc:BaseQuantity>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">1</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">11</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price>
</cac:InvoiceLine>
<cac:InvoiceLine>
<cbc:ID>1b</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">10</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">1000</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Item name 2</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>E</cbc:ID>
<cbc:Percent>0</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10</cbc:PriceAmount>
</cac:Price>
<cbc:ID>1b</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">10.00000000</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Item name 2</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>E</cbc:ID>
<cbc:Percent>0.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</Invoice>
</Invoice>

View File

@@ -1,349 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ccts="urn:un:unece:uncefact:documentation:2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDataTypes-2" xmlns:udt="urn:oasis:names:specification:ubl:schema:xsd:UnqualifiedDataTypes-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
<cbc:ProfileID>BT-23 Business Process Type</cbc:ProfileID>
<cbc:ID>Test_EeISI_100</cbc:ID>
<cbc:IssueDate>2018-11-12</cbc:IssueDate>
<cbc:DueDate>2018-11-30</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:Note>##AAA##invoice note text</cbc:Note>
<cbc:Note>##AAA##invoice note text 2</cbc:Note>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cbc:TaxCurrencyCode>NOK</cbc:TaxCurrencyCode>
<cbc:AccountingCost>uvz</cbc:AccountingCost>
<cbc:BuyerReference>123</cbc:BuyerReference>
<cac:InvoicePeriod>
<cbc:StartDate>2018-11-12</cbc:StartDate>
<cbc:EndDate>2018-11-30</cbc:EndDate>
<cbc:DescriptionCode>35</cbc:DescriptionCode>
</cac:InvoicePeriod>
<cac:OrderReference>
<cbc:ID>abc</cbc:ID>
<cbc:SalesOrderID>def</cbc:SalesOrderID>
</cac:OrderReference>
<cac:BillingReference>
<cac:InvoiceDocumentReference>
<cbc:ID>abc123</cbc:ID>
<cbc:IssueDate>2018-10-04</cbc:IssueDate>
</cac:InvoiceDocumentReference>
</cac:BillingReference>
<cac:DespatchDocumentReference>
<cbc:ID>lmn</cbc:ID>
</cac:DespatchDocumentReference>
<cac:ReceiptDocumentReference>
<cbc:ID>ghi</cbc:ID>
</cac:ReceiptDocumentReference>
<cac:OriginatorDocumentReference>
<cbc:ID>opq</cbc:ID>
</cac:OriginatorDocumentReference>
<cac:ContractDocumentReference>
<cbc:ID>789</cbc:ID>
</cac:ContractDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID schemeID="0090">rst</cbc:ID>
<cbc:DocumentTypeCode>130</cbc:DocumentTypeCode>
</cac:AdditionalDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID>Supporting document ref</cbc:ID>
<cbc:DocumentDescription>Supporting document descr</cbc:DocumentDescription>
<cac:Attachment>
<cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="filename0">ZGVmYXVsdA==</cbc:EmbeddedDocumentBinaryObject>
<cac:ExternalReference>
<cbc:URI>External document location</cbc:URI>
</cac:ExternalReference>
</cac:Attachment>
</cac:AdditionalDocumentReference>
<cac:ProjectReference>
<cbc:ID>456</cbc:ID>
</cac:ProjectReference>
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="SMTP">Seller electronic address</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID schemeID="0100">Seller identifier 1</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="0110">Seller identifier 2</cbc:ID>
</cac:PartyIdentification>
<cac:PartyIdentification>
<cbc:ID schemeID="SEPA">Bank assigned creditor identifier</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Seller trading name</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Seller address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Seller address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Seller city</cbc:CityName>
<cbc:PostalZone>12345</cbc:PostalZone>
<cbc:CountrySubentity>Seller country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Seller address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE12345677</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE49294093</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>NOVAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Seller name</cbc:RegistrationName>
<cbc:CompanyID schemeID="0310">Seller legal identifier</cbc:CompanyID>
<cbc:CompanyLegalForm>Seller additional legal information</cbc:CompanyLegalForm>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Seller contact point</cbc:Name>
<cbc:Telephone>+41 345 654455</cbc:Telephone>
<cbc:ElectronicMail>seller@contact.de</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="DE:SMTP">Buyer electronic address</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID>0190:Buyer identifier</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Buyer trading name</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Buyer address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Buyer address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Buyer city</cbc:CityName>
<cbc:PostalZone>34562</cbc:PostalZone>
<cbc:CountrySubentity>Buyer country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Buyer address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>IE394838894</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Buyer name</cbc:RegistrationName>
<cbc:CompanyID>Buyer legal registration identifier</cbc:CompanyID>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:Name>Buyer contact point</cbc:Name>
<cbc:Telephone>+353 2948584</cbc:Telephone>
<cbc:ElectronicMail>buyer@contact.ie</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:PayeeParty>
<cac:PartyIdentification>
<cbc:ID schemeID="0098">Payee identifier</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Payee name</cbc:Name>
</cac:PartyName>
<cac:PartyLegalEntity>
<cbc:CompanyID schemeID="0099">Payee legal registration identifier</cbc:CompanyID>
</cac:PartyLegalEntity>
</cac:PayeeParty>
<cac:TaxRepresentativeParty>
<cac:PartyName>
<cbc:Name>Tax representative name</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Tax representative address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Tax representative address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Tax representative city</cbc:CityName>
<cbc:PostalZone>23455</cbc:PostalZone>
<cbc:CountrySubentity>Tax representative country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Tax representative address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>DE</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>DE3949053</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
</cac:TaxRepresentativeParty>
<cac:Delivery>
<cbc:ActualDeliveryDate>2018-12-04</cbc:ActualDeliveryDate>
<cac:DeliveryLocation>
<cbc:ID schemeID="0045">deliver location identifier</cbc:ID>
<cac:Address>
<cbc:StreetName>Deliver to address line 1</cbc:StreetName>
<cbc:AdditionalStreetName>Deliver to address line 2</cbc:AdditionalStreetName>
<cbc:CityName>Deliver to city</cbc:CityName>
<cbc:PostalZone>98765</cbc:PostalZone>
<cbc:CountrySubentity>Deliver to country subdivision</cbc:CountrySubentity>
<cac:AddressLine>
<cbc:Line>Deliver to address line 3</cbc:Line>
</cac:AddressLine>
<cac:Country>
<cbc:IdentificationCode>IE</cbc:IdentificationCode>
</cac:Country>
</cac:Address>
</cac:DeliveryLocation>
<cac:DeliveryParty>
<cac:PartyName>
<cbc:Name>Deliver to party name</cbc:Name>
</cac:PartyName>
</cac:DeliveryParty>
</cac:Delivery>
<cac:PaymentMeans>
<cbc:PaymentMeansCode name="SEPA">4</cbc:PaymentMeansCode>
<cbc:PaymentID>Remittance information</cbc:PaymentID>
<cac:CardAccount>
<cbc:PrimaryAccountNumberID>1234</cbc:PrimaryAccountNumberID>
<cbc:NetworkID>mandatory network id</cbc:NetworkID>
<cbc:HolderName>Payment card holder name</cbc:HolderName>
</cac:CardAccount>
<cac:PayeeFinancialAccount>
<cbc:ID>IT1212341234123412</cbc:ID>
<cbc:Name>Payment account name</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>BSCTCH22</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
<cac:PayeeFinancialAccount>
<cbc:ID>IT1212341234123413</cbc:ID>
<cbc:Name>Payment account name 2</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>BSCTCH22</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
<cac:PaymentMandate>
<cbc:ID>Mandate reference identifier</cbc:ID>
<cac:PayerFinancialAccount>
<cbc:ID>Debited account identifier</cbc:ID>
</cac:PayerFinancialAccount>
</cac:PaymentMandate>
</cac:PaymentMeans>
<cac:PaymentTerms>
<cbc:Note>total amount</cbc:Note>
</cac:PaymentTerms>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">50.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">50.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">0.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>E</cbc:ID>
<cbc:Percent>0.00</cbc:Percent>
<cbc:TaxExemptionReasonCode>Exemption reason code</cbc:TaxExemptionReasonCode>
<cbc:TaxExemptionReason>Exemtion reason text</cbc:TaxExemptionReason>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">200.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">200.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">205.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">205.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1a</cbc:ID>
<cbc:Note>Invoice line note</cbc:Note>
<cbc:InvoicedQuantity unitCode="EA">10.00000000</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
<cbc:AccountingCost>6789</cbc:AccountingCost>
<cac:InvoicePeriod>
<cbc:StartDate>2018-11-12</cbc:StartDate>
<cbc:EndDate>2018-11-30</cbc:EndDate>
</cac:InvoicePeriod>
<cac:OrderLineReference>
<cbc:LineID>12345</cbc:LineID>
</cac:OrderLineReference>
<cac:DocumentReference>
<cbc:ID schemeID="ZZZ">Line object identifier</cbc:ID>
<cbc:DocumentTypeCode>130</cbc:DocumentTypeCode>
</cac:DocumentReference>
<cac:Item>
<cbc:Description>Item description</cbc:Description>
<cbc:Name>Item name</cbc:Name>
<cac:BuyersItemIdentification>
<cbc:ID>Item buyer's identifier</cbc:ID>
</cac:BuyersItemIdentification>
<cac:SellersItemIdentification>
<cbc:ID>Item seller's identifier</cbc:ID>
</cac:SellersItemIdentification>
<cac:StandardItemIdentification>
<cbc:ID>Item standar identifier</cbc:ID>
</cac:StandardItemIdentification>
<cac:OriginCountry>
<cbc:IdentificationCode>IT</cbc:IdentificationCode>
</cac:OriginCountry>
<cac:CommodityClassification>
<cbc:ItemClassificationCode listID="ZZZ" listVersionID="version0">Item classification identifier0</cbc:ItemClassificationCode>
</cac:CommodityClassification>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>5.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
<cac:AdditionalItemProperty>
<cbc:Name>Color</cbc:Name>
<cbc:Value>Red</cbc:Value>
</cac:AdditionalItemProperty>
<cac:AdditionalItemProperty>
<cbc:Name>Size</cbc:Name>
<cbc:Value>L</cbc:Value>
</cac:AdditionalItemProperty>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10.00</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="EA">1.00</cbc:BaseQuantity>
</cac:Price>
</cac:InvoiceLine>
<cac:InvoiceLine>
<cbc:ID>1b</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">10.00000000</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">100.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Item name 2</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>E</cbc:ID>
<cbc:Percent>0.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</Invoice>

View File

@@ -44,6 +44,12 @@
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.4</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-io</groupId>

View File

@@ -122,7 +122,9 @@ public class PDFValidator extends Validator {
}
// step 2 validate XMP
final ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream);
final ZUGFeRDImporter zi = new ZUGFeRDImporter();
zi.doIgnoreCalculationErrors();//of course the calculation will still be schematron checked
zi.setInputStream(inputStream);
final String xmp = zi.getXMP();
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

View File

@@ -135,6 +135,22 @@ public class ValidationContext {
return String.join(",", errorcodes);
}
/***
*
* @return the unique error IDs as comma separated string
*/
public String getCSVIDResult() {
final ArrayList<String> errorIDs = new ArrayList<>();
for (final ValidationResultItem validationResultItem : results) {
if (!validationResultItem.getID().isEmpty()) {
final String errorID=validationResultItem.getID();
errorIDs.add(errorID);
}
}
return String.join(",", errorIDs);
}
public void setInvalid() {
isValid = false;
}

View File

@@ -12,6 +12,7 @@ public class ValidationResultItem {
protected String message, location=null;
protected int section =-1;
protected String id =""; // e.g. "FX-SCH-A-000026"
private ESeverity severity=ESeverity.error;
@@ -103,6 +104,15 @@ public class ValidationResultItem {
return severity;
}
public ValidationResultItem setID(String id) {
this.id=id;
return this;
}
public String getID() {
return id;
}
public int getSection() {
return section;
}

View File

@@ -424,11 +424,6 @@ public class XMLValidator extends Validator {
*/
public void validateSchematron(String xml, String xsltFilename, int section, ESeverity defaultSeverity) throws IrrecoverableValidationError {
ISchematronResource aResSCH = null;
ESeverity severity=defaultSeverity;
if (defaultSeverity!=ESeverity.notice) {
severity=ESeverity.error;
}
aResSCH = SchematronResourceXSLT.fromClassPath(xsltFilename);
if (aResSCH != null) {
@@ -453,6 +448,7 @@ public class XMLValidator extends Validator {
String thisFailText = "";
String thisFailID = "";
String thisFailIDStr = "";
String thisFailTest = "";
String thisFailLocation = "";
if (failedAsserts.getLength() > 0) {
@@ -461,7 +457,8 @@ public class XMLValidator extends Validator {
//nodes.item(i).getTextContent())) {
Node currentFailNode = failedAsserts.item(nodeIndex);
if (currentFailNode.getAttributes().getNamedItem("id") != null) {
thisFailID = " [ID " + currentFailNode.getAttributes().getNamedItem("id").getNodeValue() + "]";
thisFailID = currentFailNode.getAttributes().getNamedItem("id").getNodeValue();
thisFailIDStr = " [ID " + thisFailID + "]";
}
if (currentFailNode.getAttributes().getNamedItem("test") != null) {
thisFailTest = currentFailNode.getAttributes().getNamedItem("test").getNodeValue();
@@ -470,14 +467,15 @@ public class XMLValidator extends Validator {
thisFailLocation = currentFailNode.getAttributes().getNamedItem("location").getNodeValue();
}
if (currentFailNode.getAttributes().getNamedItem("flag") != null) {
ESeverity severity;
if (defaultSeverity == ESeverity.notice) {
severity = defaultSeverity;
} else if (currentFailNode.getAttributes().getNamedItem("flag") != null
&& currentFailNode.getAttributes().getNamedItem("flag").getNodeValue().equals("warning")) {
// the XR issues warnings with flag=warning
if (currentFailNode.getAttributes().getNamedItem("flag").getNodeValue().equals("warning")) {
if (defaultSeverity!=ESeverity.notice) {
severity=ESeverity.warning;
}
}
severity = ESeverity.warning;
} else {
severity = ESeverity.error;
}
NodeList failChilds = currentFailNode.getChildNodes();
@@ -494,8 +492,8 @@ public class XMLValidator extends Validator {
LOGGER.info("FailedAssert ", thisFailText);
context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailID + " from " + xsltFilename + ")")
.setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section)
context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailIDStr + " from " + xsltFilename + ")")
.setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section).setID(thisFailID)
.setPart(EPart.fx));
failedRules++;

View File

@@ -318,7 +318,7 @@ public class ZUGFeRDValidator {
LOGGER.info("Parsed PDF:" + pdfResult + " XML:" + (xmlValidity ? "valid" : "invalid")
+ " Signature:" + Signature + " Checksum:" + sha1Checksum + " Profile:" + context.getProfile()
+ " Version:" + context.getGeneration() + " Took:" + duration + "ms Errors:[" + context.getCSVResult()
+ "] " + toBeAppended);
+ "] ErrorIDs: [" + context.getCSVIDResult() + "]" + toBeAppended);
wasCompletelyValid = ((pdfValidity) && (xmlValidity));
return sw.toString();
}

View File

@@ -216,10 +216,10 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
assertThat(res).valueByXPath("count(//error)")
.asInt()
.isEqualTo(1);
.isEqualTo(2);
assertThat(res).valueByXPath("count(//warning)")
.asInt()
.isEqualTo(3);
.isEqualTo(2);
assertThat(res).valueByXPath("count(//notice)")
.asInt()