diff --git a/doc/MustangWriter.java b/doc/MustangWriter.java index 6cf8670..700ca96 100755 --- a/doc/MustangWriter.java +++ b/doc/MustangWriter.java @@ -1,277 +1,271 @@ org.openrewrite.config.CompositeRecipe package mustangtest; +import org.mustangproject.ZUGFeRD.*; + import java.io.IOException; import java.math.BigDecimal; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; -import org.mustangproject.ZUGFeRD.IExportableTransaction; -import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge; -import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem; -import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct; -import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTradeParty; -import org.mustangproject.ZUGFeRD.IZUGFeRDExporter; -import org.mustangproject.ZUGFeRD.ZUGFeRDExporterFromA1; - class Contact implements IZUGFeRDExportableTradeParty { - public String getCountry() { - return "DE"; - } + public String getCountry() { + return "DE"; + } - public String getLocation() { - return "Spielkreis"; - } + public String getLocation() { + return "Spielkreis"; + } - public String getName() { - return "Theodor Est"; - } + public String getName() { + return "Theodor Est"; + } - public String getStreet() { - return "Bahnstr. 42"; - } + public String getStreet() { + return "Bahnstr. 42"; + } - public String getVATID() { - return "DE999999999"; - } + public String getVATID() { + return "DE999999999"; + } - public String getZIP() { - return "88802"; - } + public String getZIP() { + return "88802"; + } } class Item implements IZUGFeRDExportableItem { - public Item(BigDecimal price, BigDecimal quantity, Product product) { - super(); - this.price = price; - this.quantity = quantity; - this.product = product; - } + public Item(BigDecimal price, BigDecimal quantity, Product product) { + super(); + this.price = price; + this.quantity = quantity; + this.product = product; + } - private BigDecimal price, quantity; - private Product product; + private BigDecimal price, quantity; + private Product product; - public BigDecimal getPrice() { - return price; - } + public BigDecimal getPrice() { + return price; + } - public void setPrice(BigDecimal price) { - this.price = price; - } + public void setPrice(BigDecimal price) { + this.price = price; + } - public BigDecimal getQuantity() { - return quantity; - } + public BigDecimal getQuantity() { + return quantity; + } - public void setQuantity(BigDecimal quantity) { - this.quantity = quantity; - } + public void setQuantity(BigDecimal quantity) { + this.quantity = quantity; + } - public Product getProduct() { - return product; - } + public Product getProduct() { + return product; + } - public void setProduct(Product product) { - this.product = product; - } + public void setProduct(Product product) { + this.product = product; + } - public IZUGFeRDAllowanceCharge[] getItemAllowances() { - // TODO Auto-generated method stub - return null; - } + public IZUGFeRDAllowanceCharge[] getItemAllowances() { + // TODO Auto-generated method stub + return null; + } - public IZUGFeRDAllowanceCharge[] getItemCharges() { - // TODO Auto-generated method stub - return null; - } + public IZUGFeRDAllowanceCharge[] getItemCharges() { + // TODO Auto-generated method stub + return null; + } } class Product implements IZUGFeRDExportableProduct { - public Product(String description, String name, String unit, BigDecimal vATPercent) { - super(); - this.description = description; - this.name = name; - this.unit = unit; - VATPercent = vATPercent; - } + public Product(String description, String name, String unit, BigDecimal vATPercent) { + super(); + this.description = description; + this.name = name; + this.unit = unit; + VATPercent = vATPercent; + } - private String description, name, unit; - private BigDecimal VATPercent; + private String description, name, unit; + private BigDecimal VATPercent; - public String getDescription() { - return description; - } + public String getDescription() { + return description; + } - public void setDescription(String description) { - this.description = description; - } + public void setDescription(String description) { + this.description = description; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public String getUnit() { - return unit; - } + public String getUnit() { + return unit; + } - public void setUnit(String unit) { - this.unit = unit; - } + public void setUnit(String unit) { + this.unit = unit; + } - public BigDecimal getVATPercent() { - return VATPercent; - } + public BigDecimal getVATPercent() { + return VATPercent; + } - public void setVATPercent(BigDecimal vATPercent) { - VATPercent = vATPercent; - } + public void setVATPercent(BigDecimal vATPercent) { + VATPercent = vATPercent; + } } public class MustangWriter implements IExportableTransaction { - private void apply() { - try { - System.out.println("Reading Blanko-PDF"); - IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setProducer("My Application") - .setCreator(System.getProperty("user.name")) - .load("./MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); - System.out.println("Generating and attaching ZUGFeRD-Data"); - ze.setTransaction(this); - System.out.println("Writing ZUGFeRD-PDF"); - ze.export("./MustangGnuaccountingBeispielRE-20170509_505new.pdf"); - System.out.println("Done."); - } catch (IOException e) { - e.printStackTrace(); - } + private void apply() { + try { + System.out.println("Reading Blanko-PDF"); + IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setProducer("My Application") + .setCreator(System.getProperty("user.name")) + .load("./MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); + System.out.println("Generating and attaching ZUGFeRD-Data"); + ze.setTransaction(this); + System.out.println("Writing ZUGFeRD-PDF"); + ze.export("./MustangGnuaccountingBeispielRE-20170509_505new.pdf"); + System.out.println("Done."); + } catch (IOException e) { + e.printStackTrace(); + } - } + } - public static void main(String[] args) { - MustangWriter mw=new MustangWriter(); - mw.apply(); - } + public static void main(String[] args) { + MustangWriter mw = new MustangWriter(); + mw.apply(); + } - public String getCurrency() { - return "EUR"; - } + public String getCurrency() { + return "EUR"; + } - public Date getDeliveryDate() { - return new GregorianCalendar(2017, Calendar.NOVEMBER, 17).getTime(); - } + public Date getDeliveryDate() { + return new GregorianCalendar(2017, Calendar.NOVEMBER, 17).getTime(); + } - public Date getDueDate() { - return new GregorianCalendar(2017, Calendar.DECEMBER, 9).getTime(); - } + public Date getDueDate() { + return new GregorianCalendar(2017, Calendar.DECEMBER, 9).getTime(); + } - public Date getIssueDate() { - return new GregorianCalendar(2017, Calendar.NOVEMBER, 18).getTime(); - } + public Date getIssueDate() { + return new GregorianCalendar(2017, Calendar.NOVEMBER, 18).getTime(); + } - public String getNumber() { - // TODO Auto-generated method stub - return "RE-20171118/506"; - } + public String getNumber() { + // TODO Auto-generated method stub + return "RE-20171118/506"; + } - public String getOwnBIC() { - // TODO Auto-generated method stub - return "COBADEFFXXX"; - } + public String getOwnBIC() { + // TODO Auto-generated method stub + return "COBADEFFXXX"; + } - public String getOwnBankName() { - // TODO Auto-generated method stub - return "Commerzbank"; - } + public String getOwnBankName() { + // TODO Auto-generated method stub + return "Commerzbank"; + } - public String getOwnCountry() { - // TODO Auto-generated method stub - return "DE"; - } + public String getOwnCountry() { + // TODO Auto-generated method stub + return "DE"; + } - public String getOwnIBAN() { - // TODO Auto-generated method stub - return "DE88 2008 0000 0970 3757 00"; - } + public String getOwnIBAN() { + // TODO Auto-generated method stub + return "DE88 2008 0000 0970 3757 00"; + } - public String getOwnLocation() { - // TODO Auto-generated method stub - return "Stadthausen"; - } + public String getOwnLocation() { + // TODO Auto-generated method stub + return "Stadthausen"; + } - public String getOwnOrganisationFullPlaintextInfo() { - // TODO Auto-generated method stub - return "Bei Spiel GmbH\n" + "Ecke 12\n" + "12345 Stadthausen\n" + "Geschäftsführer: Max Mustermann"; - } + public String getOwnOrganisationFullPlaintextInfo() { + // TODO Auto-generated method stub + return "Bei Spiel GmbH\n" + "Ecke 12\n" + "12345 Stadthausen\n" + "Geschäftsführer: Max Mustermann"; + } - public String getOwnOrganisationName() { - // TODO Auto-generated method stub - return "Bei Spiel GmbH"; - } + public String getOwnOrganisationName() { + // TODO Auto-generated method stub + return "Bei Spiel GmbH"; + } - public String getOwnPaymentInfoText() { - // TODO Auto-generated method stub - return null; - } + public String getOwnPaymentInfoText() { + // TODO Auto-generated method stub + return null; + } - public String getOwnStreet() { - return "Ecke 12"; - } + public String getOwnStreet() { + return "Ecke 12"; + } - public String getOwnTaxID() { - return "22/815/0815/4"; - } + public String getOwnTaxID() { + return "22/815/0815/4"; + } - public String getOwnVATID() { - return "DE136695976"; - } + public String getOwnVATID() { + return "DE136695976"; + } - public String getOwnZIP() { - return "12345"; - } + public String getOwnZIP() { + return "12345"; + } - public String getPaymentTermDescription() { - // TODO Auto-generated method stub - return null; - } + public String getPaymentTermDescription() { + // TODO Auto-generated method stub + return null; + } - public IZUGFeRDExportableTradeParty getRecipient() { - return new Contact(); - } + public IZUGFeRDExportableTradeParty getRecipient() { + return new Contact(); + } - public String getReferenceNumber() { - // TODO Auto-generated method stub - return null; - } + public String getReferenceNumber() { + // TODO Auto-generated method stub + return null; + } - public IZUGFeRDAllowanceCharge[] getZFAllowances() { - // TODO Auto-generated method stub - return null; - } + public IZUGFeRDAllowanceCharge[] getZFAllowances() { + // TODO Auto-generated method stub + return null; + } - public IZUGFeRDAllowanceCharge[] getZFCharges() { - // TODO Auto-generated method stub - return null; - } + public IZUGFeRDAllowanceCharge[] getZFCharges() { + // TODO Auto-generated method stub + return null; + } - public IZUGFeRDExportableItem[] getZFItems() { - Item[] allItems = new Item[3]; - Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", - new BigDecimal("7.000000")); - Product balloonProduct = new Product("", "Luftballon: Bunt, ca. 500ml", "C62", new BigDecimal("19.000000")); - Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000")); - allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); - allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); - allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); - return allItems; - } + public IZUGFeRDExportableItem[] getZFItems() { + Item[] allItems = new Item[3]; + Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", + new BigDecimal("7.000000")); + Product balloonProduct = new Product("", "Luftballon: Bunt, ca. 500ml", "C62", new BigDecimal("19.000000")); + Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000")); + allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); + allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); + allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); + return allItems; + } - public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - // TODO Auto-generated method stub - return null; - } + public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { + // TODO Auto-generated method stub + return null; + } } diff --git a/library/src/main/java/org/mustangproject/Allowance.java b/library/src/main/java/org/mustangproject/Allowance.java index e378f76..34a4a5f 100755 --- a/library/src/main/java/org/mustangproject/Allowance.java +++ b/library/src/main/java/org/mustangproject/Allowance.java @@ -13,29 +13,29 @@ org.openrewrite.config.CompositeRecipe @JsonInclude(JsonInclude.Include.NON_EMPTY) public class Allowance extends Charge { - /*** - * bean constructor - */ - public Allowance() { + /*** + * bean constructor + */ + public Allowance() { - } + } - /*** - * create a allowance with the following amount - * @param totalAmount the money amount as bigdecimal (prob max 2 decimals) - */ - public Allowance(BigDecimal totalAmount) { - super(totalAmount); + /*** + * create a allowance with the following amount + * @param totalAmount the money amount as bigdecimal (prob max 2 decimals) + */ + public Allowance(BigDecimal totalAmount) { + super(totalAmount); - } + } - /*** - * Always to return false for IZUGFeRDAllowanceCharge - * @return false since its not supposed to be calculated negatively - */ - @Override - @JsonIgnore - public boolean isCharge() { - return false; - } + /*** + * Always to return false for IZUGFeRDAllowanceCharge + * @return false since its not supposed to be calculated negatively + */ + @Override + @JsonIgnore + public boolean isCharge() { + return false; + } } diff --git a/library/src/main/java/org/mustangproject/BankDetails.java b/library/src/main/java/org/mustangproject/BankDetails.java index a16976f..64b0736 100755 --- a/library/src/main/java/org/mustangproject/BankDetails.java +++ b/library/src/main/java/org/mustangproject/BankDetails.java @@ -11,117 +11,117 @@ org.openrewrite.config.CompositeRecipe @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) public class BankDetails implements IZUGFeRDTradeSettlementPayment { - /** - * the bank account number - */ - protected String IBAN; - /** - * BIC, I believe it's optional - */ - protected String BIC = null; - /** - * the "name" of the bank account (holder) - */ - protected String accountName = null; + /** + * the bank account number + */ + protected String IBAN; + /** + * BIC, I believe it's optional + */ + protected String BIC = null; + /** + * the "name" of the bank account (holder) + */ + protected String accountName = null; - /*** - * bean constructor - */ - public BankDetails() { - } + /*** + * bean constructor + */ + public BankDetails() { + } - /*** - * constructor for IBAN only :-) - * @param IBAN the IBAN as string - */ - public BankDetails(String IBAN) { - this.IBAN = IBAN; - } + /*** + * constructor for IBAN only :-) + * @param IBAN the IBAN as string + */ + public BankDetails(String IBAN) { + this.IBAN = IBAN; + } - /*** - * constructor for normal use :-) - * @param IBAN the IBAN as string - * @param BIC the BIC code as string - */ - public BankDetails(String IBAN, String BIC) { - this.IBAN = IBAN; - this.BIC = BIC; - } + /*** + * constructor for normal use :-) + * @param IBAN the IBAN as string + * @param BIC the BIC code as string + */ + public BankDetails(String IBAN, String BIC) { + this.IBAN = IBAN; + this.BIC = BIC; + } - /*** - * getter for the IBAN - * @return IBAN - */ - public String getIBAN() { - return IBAN; - } + /*** + * getter for the IBAN + * @return IBAN + */ + public String getIBAN() { + return IBAN; + } - /** - * Sets the IBAN "ID", which means that it only needs to be a way to uniquely - * 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 - */ - public BankDetails setIBAN(String IBAN) { - this.IBAN = IBAN; - return this; - } + /** + * Sets the IBAN "ID", which means that it only needs to be a way to uniquely + * 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 + */ + public BankDetails setIBAN(String IBAN) { + this.IBAN = IBAN; + return this; + } - /*** - * getter for the BIC - * @return the BIC - */ - public String getBIC() { - return BIC; - } + /*** + * getter for the BIC + * @return the BIC + */ + public String getBIC() { + return BIC; + } - /*** - * The bank identifier. Bank name is no longer neccessary in SEPA. - * @param BIC the bic code - * @return fluent setter - */ - public BankDetails setBIC(String BIC) { - this.BIC = BIC; - return this; - } + /*** + * The bank identifier. Bank name is no longer neccessary in SEPA. + * @param BIC the bic code + * @return fluent setter + */ + public BankDetails setBIC(String BIC) { + this.BIC = BIC; + return this; + } - /* - 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 - public String getOwnBIC() { - return getBIC(); - } + /* + 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 + public String getOwnBIC() { + return getBIC(); + } - @Override - @Deprecated - @JsonIgnore - public String getOwnIBAN() { - return getIBAN(); - } + @Override + @Deprecated + @JsonIgnore + public String getOwnIBAN() { + return getIBAN(); + } - /** - * set Holder - * - * @param name account name (usually account holder if != sender) - * @return fluent setter - */ - public BankDetails setAccountName(String name) { - accountName = name; - return this; - } + /** + * set Holder + * + * @param name account name (usually account holder if != sender) + * @return fluent setter + */ + public BankDetails setAccountName(String name) { + accountName = name; + return this; + } - @Override - public String getAccountName() { - return accountName; - } + @Override + public String getAccountName() { + return accountName; + } } diff --git a/library/src/main/java/org/mustangproject/CalculatedInvoice.java b/library/src/main/java/org/mustangproject/CalculatedInvoice.java index 194441b..3f8c2e3 100755 --- a/library/src/main/java/org/mustangproject/CalculatedInvoice.java +++ b/library/src/main/java/org/mustangproject/CalculatedInvoice.java @@ -5,8 +5,6 @@ org.openrewrite.config.CompositeRecipe 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; import java.io.Serializable; import java.math.BigDecimal; @@ -15,59 +13,65 @@ @JsonInclude(JsonInclude.Include.NON_EMPTY) public class CalculatedInvoice extends Invoice implements Serializable { - protected BigDecimal lineTotalAmount=null; - protected BigDecimal duePayable=null; - protected BigDecimal grandTotal=null; - protected BigDecimal taxBasis=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(); + TransactionCalculator tc = new TransactionCalculator(this); + grandTotal = tc.getGrandTotal(); + lineTotalAmount = tc.getValue(); + duePayable = tc.getDuePayable(); + taxBasis = tc.getTaxBasis(); } - public BigDecimal getGrandTotal() { - if (grandTotal==null) { - calculate(); - } - return grandTotal; - } - public CalculatedInvoice setGrandTotal(BigDecimal grand) { - 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 getGrandTotal() { + if (grandTotal == null) { + calculate(); + } + return grandTotal; + } - public BigDecimal getLineTotalAmount() { - if (lineTotalAmount==null) { - calculate(); - } - return lineTotalAmount; - } - public CalculatedInvoice setLineTotalAmount(BigDecimal total) { - lineTotalAmount=total; - return this; - } + public CalculatedInvoice setGrandTotal(BigDecimal grand) { + 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; + } } diff --git a/library/src/main/java/org/mustangproject/CashDiscount.java b/library/src/main/java/org/mustangproject/CashDiscount.java index 2151489..d1b82e4 100755 --- a/library/src/main/java/org/mustangproject/CashDiscount.java +++ b/library/src/main/java/org/mustangproject/CashDiscount.java @@ -13,76 +13,74 @@ org.openrewrite.config.CompositeRecipe @JsonInclude(JsonInclude.Include.NON_EMPTY) public class CashDiscount implements IZUGFeRDCashDiscount { - /*** - * the reduction percent allowed in the period - */ - protected BigDecimal percent; - /*** - * the period (usually days) count how long the percent apply - */ - protected Integer days=null; + /*** + * the reduction percent allowed in the period + */ + protected BigDecimal percent; + /*** + * the period (usually days) count how long the percent apply + */ + protected Integer days = null; - /*** - * Create a cash discount (skonto) with the specified height in the specified period. - * Should someone add more period types than just "days" there - * is be space for a (optional) third parameter - * - * @param percent max 3 decimals "behind the dot", more precision is currently ignored - * @param days the count of the periods (usually days) the percentage applies - */ - public CashDiscount(BigDecimal percent, int days) { - this.percent = percent; - this.days = days; - } + /*** + * Create a cash discount (skonto) with the specified height in the specified period. + * Should someone add more period types than just "days" there + * is be space for a (optional) third parameter + * + * @param percent max 3 decimals "behind the dot", more precision is currently ignored + * @param days the count of the periods (usually days) the percentage applies + */ + public CashDiscount(BigDecimal percent, int days) { + this.percent = percent; + this.days = days; + } - /*** - * bean contructor - */ - public CashDiscount() { + /*** + * bean contructor + */ + public CashDiscount() { - } + } - public BigDecimal getPercent() { - return percent; - } + public BigDecimal getPercent() { + return percent; + } - public CashDiscount setPercent(BigDecimal percent) { - this.percent = percent; - return this; - } + public CashDiscount setPercent(BigDecimal percent) { + this.percent = percent; + return this; + } - public Integer getDays() { - return days; - } + public Integer getDays() { + return days; + } - public CashDiscount setDays(Integer days) { - this.days = days; - return this; - } + public CashDiscount setDays(Integer days) { + this.days = days; + return this; + } - /*** - * @return this particular cash discount as cross industry invoice XML - */ - public String getAsCII() { - return ""+ - "Cash Discount"+ - " "+ - " "+days+""+ - " "+XMLTools.nDigitFormat(percent,3)+""+ - " "+ - ""; - } + /*** + * @return this particular cash discount as cross industry invoice XML + */ + public String getAsCII() { + return "" + + "Cash Discount" + + " " + + " " + days + "" + + " " + XMLTools.nDigitFormat(percent, 3) + "" + + " " + + ""; + } - /*** - * since EN16931 voted not to have (or even allow) cash discounts in their core invoice the german - * XRechnung CIUS defined it's own proprietary format for a freetext field - * @return this particular cash discount in proprietary xrechnung format - */ - public String getAsXRechnung() { - return "#SKONTO#TAGE="+days+"#PROZENT="+XMLTools.nDigitFormat(percent,2)+"#\n"; - } - - + /*** + * since EN16931 voted not to have (or even allow) cash discounts in their core invoice the german + * XRechnung CIUS defined it's own proprietary format for a freetext field + * @return this particular cash discount in proprietary xrechnung format + */ + public String getAsXRechnung() { + return "#SKONTO#TAGE=" + days + "#PROZENT=" + XMLTools.nDigitFormat(percent, 2) + "#\n"; + } } diff --git a/library/src/main/java/org/mustangproject/Charge.java b/library/src/main/java/org/mustangproject/Charge.java index 6232611..c9a32c1 100755 --- a/library/src/main/java/org/mustangproject/Charge.java +++ b/library/src/main/java/org/mustangproject/Charge.java @@ -15,168 +15,167 @@ org.openrewrite.config.CompositeRecipe @JsonInclude(JsonInclude.Include.NON_EMPTY) public class Charge implements IZUGFeRDAllowanceCharge { - /** - * the percentage, null if not relative at all - */ - protected BigDecimal percent = null; - /** - * the absolute value if not percentage - */ - protected BigDecimal totalAmount; - /** - * the tax rate the charge belongs to - */ - protected BigDecimal taxPercent; - /** - * a simple human readable description - */ - protected String reason; - /** - * Code from list UNTDID 5189 - */ - protected String reasonCode; - /** - * the category ID why this charge has been applied - */ - protected String categoryCode; + /** + * the percentage, null if not relative at all + */ + protected BigDecimal percent = null; + /** + * the absolute value if not percentage + */ + protected BigDecimal totalAmount; + /** + * the tax rate the charge belongs to + */ + protected BigDecimal taxPercent; + /** + * a simple human readable description + */ + protected String reason; + /** + * Code from list UNTDID 5189 + */ + protected String reasonCode; + /** + * the category ID why this charge has been applied + */ + protected String categoryCode; - /*** - * Bean connstructor - */ - public Charge() { - taxPercent=BigDecimal.ZERO; - } + /*** + * Bean connstructor + */ + public Charge() { + taxPercent = BigDecimal.ZERO; + } - /*** - * creates a item level or invoice level charge - * @param totalAmount (the absolute amount) - */ - public Charge(BigDecimal totalAmount) { - this.totalAmount = totalAmount; - } + /*** + * creates a item level or invoice level charge + * @param totalAmount (the absolute amount) + */ + public Charge(BigDecimal totalAmount) { + this.totalAmount = totalAmount; + } - /*** - * sets the total amount to be changed to, e.g. if not specified via constructor - * @param totalAmount 2 decimal money amount - * @return fluid setter - */ - public Charge setTotalAmount(BigDecimal totalAmount) { - this.totalAmount = totalAmount; - return this; - } + /*** + * sets the total amount to be changed to, e.g. if not specified via constructor + * @param totalAmount 2 decimal money amount + * @return fluid setter + */ + public Charge setTotalAmount(BigDecimal totalAmount) { + this.totalAmount = totalAmount; + return this; + } - /*** - * if relative charge: percent to increase the item - * @param percent as bigdecimal - * @return fluid setter - */ - public Charge setPercent(BigDecimal percent) { - this.percent = percent; - return this; - } + /*** + * if relative charge: percent to increase the item + * @param percent as bigdecimal + * @return fluid setter + */ + public Charge setPercent(BigDecimal percent) { + this.percent = percent; + return this; + } - /*** - * charges can be applied to VAT items, in which case they take the same VAT rate - * @param taxPercent the tax percentage on the charge - * @return fluid setter - */ - public Charge setTaxPercent(BigDecimal taxPercent) { - this.taxPercent = taxPercent; - return this; - } + /*** + * charges can be applied to VAT items, in which case they take the same VAT rate + * @param taxPercent the tax percentage on the charge + * @return fluid setter + */ + public Charge setTaxPercent(BigDecimal taxPercent) { + this.taxPercent = taxPercent; + return this; + } - @Override - public String getReason() { - return reason; - } + @Override + public String getReason() { + return reason; + } - /*** - * Freetext (?) reason for the charge - * @param reason freetext - * @return fluid setter - */ - public Charge setReason(String reason) { - this.reason = reason; - return this; - } + /*** + * Freetext (?) reason for the charge + * @param reason freetext + * @return fluid setter + */ + public Charge setReason(String reason) { + this.reason = reason; + return this; + } - @Override - public String getReasonCode() { - return reasonCode; - } + @Override + public String getReasonCode() { + return reasonCode; + } - /*** - * Reason code for the charge - * @param reasonCode from list UNTDID 5189 - * @return fluid setter - */ - public Charge setReasonCode(String reasonCode) { - this.reasonCode = reasonCode; - return this; - } - - - @Override - public BigDecimal getTotalAmount(IAbsoluteValueProvider currentItem) { - if (percent!=null) { - return currentItem.getValue().multiply(getPercent().divide(new BigDecimal(100))); - } else if(totalAmount != null) { - return totalAmount; - } else { - throw new RuntimeException("percent must be set"); - } - } - - public BigDecimal getTotalAmount() { - if (totalAmount!=null) { - return totalAmount; - } else { - throw new RuntimeException("totalAmount must be set"); - } - } + /*** + * Reason code for the charge + * @param reasonCode from list UNTDID 5189 + * @return fluid setter + */ + public Charge setReasonCode(String reasonCode) { + this.reasonCode = reasonCode; + return this; + } - @Override - public BigDecimal getPercent() { - return percent; - } + @Override + public BigDecimal getTotalAmount(IAbsoluteValueProvider currentItem) { + if (percent != null) { + return currentItem.getValue().multiply(getPercent().divide(new BigDecimal(100))); + } else if (totalAmount != null) { + return totalAmount; + } else { + throw new RuntimeException("percent must be set"); + } + } - @Override - public BigDecimal getTaxPercent() { - return taxPercent; - } + public BigDecimal getTotalAmount() { + if (totalAmount != null) { + return totalAmount; + } else { + throw new RuntimeException("totalAmount must be set"); + } + } + @Override + public BigDecimal getPercent() { + return percent; + } - /*** - * Always to return true for IZUGFeRDAllowanceCharge - * @return true since it is supposed to be calculated negatively - */ - @Override - @JsonIgnore - public boolean isCharge() { - return true; - } - - @Override - public String getCategoryCode() { - if(categoryCode != null){ - return categoryCode; - } - return IZUGFeRDAllowanceCharge.super.getCategoryCode(); - } + @Override + public BigDecimal getTaxPercent() { + return taxPercent; + } - /*** - * the category ID why this has been applied - * @param categoryCode usually S - * @return fluid setter - */ - public Charge setCategoryCode(String categoryCode) { - this.categoryCode = categoryCode; - return this; - } + /*** + * Always to return true for IZUGFeRDAllowanceCharge + * @return true since it is supposed to be calculated negatively + */ + @Override + @JsonIgnore + public boolean isCharge() { + return true; + } + + @Override + public String getCategoryCode() { + if (categoryCode != null) { + return categoryCode; + } + return IZUGFeRDAllowanceCharge.super.getCategoryCode(); + } + + + /*** + * the category ID why this has been applied + * @param categoryCode usually S + * @return fluid setter + */ + public Charge setCategoryCode(String categoryCode) { + this.categoryCode = categoryCode; + return this; + } } diff --git a/library/src/main/java/org/mustangproject/CII/CIIToUBL.java b/library/src/main/java/org/mustangproject/CII/CIIToUBL.java index 816f699..1e7ace0 100755 --- a/library/src/main/java/org/mustangproject/CII/CIIToUBL.java +++ b/library/src/main/java/org/mustangproject/CII/CIIToUBL.java @@ -1,38 +1,39 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.CII; -import java.io.File; -import java.io.Serializable; - import com.helger.commons.error.list.ErrorList; import com.helger.en16931.cii2ubl.CIIToUBL23Converter; import com.helger.ubl23.UBL23Marshaller; +import oasis.names.specification.ubl.schema.xsd.creditnote_23.CreditNoteType; +import oasis.names.specification.ubl.schema.xsd.invoice_23.InvoiceType; + +import java.io.File; +import java.io.Serializable; /*** * converts a Cross Industry Invoice XML file to a UBL XML file * thanks to Philip Helger for his library */ public class CIIToUBL { - /*** - * performs the actual conversion - * @param input the CII file to convert - * @param output the UBL file to write to - */ + /*** + * performs the actual conversion + * @param input the CII file to convert + * @param output the UBL file to write to + */ public void convert(File input, File output) { - final ErrorList occurred=new ErrorList(); - final CIIToUBL23Converter cc=new CIIToUBL23Converter(); - final Serializable aUBL = cc.convertCIItoUBL(input, occurred); - if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.invoice_23.InvoiceType) - { - UBL23Marshaller.invoice () - .setFormattedOutput (true) - .write ((oasis.names.specification.ubl.schema.xsd.invoice_23.InvoiceType) aUBL, output); - } - else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.creditnote_23.CreditNoteType) - { - UBL23Marshaller.creditNote () - .setFormattedOutput (true) - .write ((oasis.names.specification.ubl.schema.xsd.creditnote_23.CreditNoteType) aUBL, output); - } - } + final ErrorList occurred = new ErrorList(); + final CIIToUBL23Converter cc = new CIIToUBL23Converter(); + final Serializable aUBL = cc.convertCIItoUBL(input, occurred); + if (aUBL instanceof InvoiceType) + { + UBL23Marshaller.invoice() + .setFormattedOutput(true) + .write((InvoiceType) aUBL, output); + } else if (aUBL instanceof CreditNoteType) + { + UBL23Marshaller.creditNote() + .setFormattedOutput(true) + .write((CreditNoteType) aUBL, output); + } + } } diff --git a/library/src/main/java/org/mustangproject/ClassCode.java b/library/src/main/java/org/mustangproject/ClassCode.java index 61fdd20..29d147e 100755 --- a/library/src/main/java/org/mustangproject/ClassCode.java +++ b/library/src/main/java/org/mustangproject/ClassCode.java @@ -31,85 +31,85 @@ org.openrewrite.config.CompositeRecipe @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) public class ClassCode { - private String listID; - private String code; - private String listVersionID; + private String listID; + private String code; + private String listVersionID; - /** - * A UNTDID 7143 schemed classification code - * - * @param listID the scheme from UNTDID 7143 - * @param code the classification code - * @param listVersionID an (optional) version of the scheme - */ - public ClassCode(String listID, String code, String listVersionID) { - this.listID = listID; - this.code = code; - this.listVersionID = listVersionID; - } + /** + * A UNTDID 7143 schemed classification code + * + * @param listID the scheme from UNTDID 7143 + * @param code the classification code + * @param listVersionID an (optional) version of the scheme + */ + public ClassCode(String listID, String code, String listVersionID) { + this.listID = listID; + this.code = code; + this.listVersionID = listVersionID; + } - /** - * A UNTDID 7143 schemed classification code - * - * @param listID the scheme from UNTDID 7143 - * @param code the classification code - */ - public ClassCode(String listID, String code) { - this(listID, code, null); - } + /** + * A UNTDID 7143 schemed classification code + * + * @param listID the scheme from UNTDID 7143 + * @param code the classification code + */ + public ClassCode(String listID, String code) { + this(listID, code, null); + } - /*** - * bean constructor - */ - public ClassCode() { - } + /*** + * bean constructor + */ + public ClassCode() { + } - /*** - * Set the version for the scheme returned by {@link #getListID()} - * @param listVersionID the scheme version - */ - public void setListVersionID(String listVersionID) { - this.listVersionID = listVersionID; - } + /*** + * Set the version for the scheme returned by {@link #getListID()} + * @param listVersionID the scheme version + */ + public void setListVersionID(String listVersionID) { + this.listVersionID = listVersionID; + } - /** - * Get the scheme (according to UNTDID 7143) that describes the value returned by {@link #getCode()}, - * potentially versioned by {@link #getListVersionID()} - * - * @return the scheme - */ - public String getListID() { - return listID; - } + /** + * Get the scheme (according to UNTDID 7143) that describes the value returned by {@link #getCode()}, + * potentially versioned by {@link #getListVersionID()} + * + * @return the scheme + */ + public String getListID() { + return listID; + } - /** - * Get the code that (following the scheme returned by {@link #getListID()}) describes the product - * - * @return the classification code itself - */ - public String getCode() { - return code; - } + /** + * Get the code that (following the scheme returned by {@link #getListID()}) describes the product + * + * @return the classification code itself + */ + public String getCode() { + return code; + } - /** - * Get the (optional) version for the scheme returned by {@link #getListID()} - * - * @return the version or {@code null} if not set - */ - public String getListVersionID() { - return listVersionID; - } + /** + * Get the (optional) version for the scheme returned by {@link #getListID()} + * + * @return the version or {@code null} if not set + */ + public String getListVersionID() { + return listVersionID; + } - public static ClassCode fromNode(Node node) { - NamedNodeMap attrs = node.getAttributes(); - if (attrs != null && attrs.getNamedItem("listID") != null) { - ClassCode classCode = new ClassCode(attrs.getNamedItem("listID").getNodeValue(), node.getTextContent()); - if (attrs.getNamedItem("listVersionID") != null) { - classCode.setListVersionID(attrs.getNamedItem("listVersionID").getNodeValue()); - } - return classCode; - } - return null; - } + public static ClassCode fromNode(Node node) { + NamedNodeMap attrs = node.getAttributes(); + if (attrs != null && attrs.getNamedItem("listID") != null) { + ClassCode classCode = new ClassCode(attrs.getNamedItem("listID").getNodeValue(), node.getTextContent()); + if (attrs.getNamedItem("listVersionID") != null) { + classCode.setListVersionID(attrs.getNamedItem("listVersionID").getNodeValue()); + } + return classCode; + } + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ClasspathResolverURIAdapter.java b/library/src/main/java/org/mustangproject/ClasspathResolverURIAdapter.java index f5076eb..e4f2d1e 100755 --- a/library/src/main/java/org/mustangproject/ClasspathResolverURIAdapter.java +++ b/library/src/main/java/org/mustangproject/ClasspathResolverURIAdapter.java @@ -1,8 +1,4 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject; -import java.io.IOException; -import java.io.OutputStream; -import java.net.URI; -import java.net.URL; import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.xmlgraphics.io.Resource; @@ -10,32 +6,37 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URI; +import java.net.URL; + public class ClasspathResolverURIAdapter implements ResourceResolver { - private static final Logger LOGGER = LoggerFactory.getLogger(ClasspathResolverURIAdapter.class); - private final ResourceResolver wrapped; + private static final Logger LOGGER = LoggerFactory.getLogger(ClasspathResolverURIAdapter.class); + private final ResourceResolver wrapped; - public ClasspathResolverURIAdapter() { - this.wrapped = ResourceResolverFactory.createDefaultResourceResolver(); - } + public ClasspathResolverURIAdapter() { + this.wrapped = ResourceResolverFactory.createDefaultResourceResolver(); + } - @Override - public Resource getResource(URI uri) throws IOException { - LOGGER.debug("public Resource getResource(URI uri='{}')", uri); - if (uri.getScheme().equals("classpath")) { - URL url = getClass().getClassLoader().getResource(uri.getSchemeSpecificPart()); + @Override + public Resource getResource(URI uri) throws IOException { + LOGGER.debug("public Resource getResource(URI uri='{}')", uri); + if (uri.getScheme().equals("classpath")) { + URL url = getClass().getClassLoader().getResource(uri.getSchemeSpecificPart()); - return new Resource(url.openStream()); - } else { - return wrapped.getResource(uri); - } - } + return new Resource(url.openStream()); + } else { + return wrapped.getResource(uri); + } + } - @Override - public OutputStream getOutputStream(URI uri) throws IOException { - return wrapped.getOutputStream(uri); - } + @Override + public OutputStream getOutputStream(URI uri) throws IOException { + return wrapped.getOutputStream(uri); + } } diff --git a/library/src/main/java/org/mustangproject/Contact.java b/library/src/main/java/org/mustangproject/Contact.java index cead6f8..9831a4e 100755 --- a/library/src/main/java/org/mustangproject/Contact.java +++ b/library/src/main/java/org/mustangproject/Contact.java @@ -15,255 +15,255 @@ org.openrewrite.config.CompositeRecipe @JsonInclude(JsonInclude.Include.NON_EMPTY) public class Contact implements IZUGFeRDExportableContact { - /** - * name of the contact person - */ - protected String name; - /** - * phone of the contact - */ - protected String phone; - /** - * email address - */ - protected String email; - /** - * postcode of the contact - */ - protected String zip; - /** - * street address (=name+number) - */ - protected String street; - /** - * city - */ - protected String location; - /** - * 2 character ISO code of a country - */ - protected String country; - /** - * the fax number of the contact person - */ - protected String fax = null; + /** + * name of the contact person + */ + protected String name; + /** + * phone of the contact + */ + protected String phone; + /** + * email address + */ + protected String email; + /** + * postcode of the contact + */ + protected String zip; + /** + * street address (=name+number) + */ + protected String street; + /** + * city + */ + protected String location; + /** + * 2 character ISO code of a country + */ + protected String country; + /** + * the fax number of the contact person + */ + protected String fax = null; - /*** - * default constructor. - * Name, phone and email of sender contact person are e.g. required by XRechnung - * @param name full name of the contact - * @param phone full phone number - * @param email email address of the contact - */ - public Contact(String name, String phone, String email) { - this.name = name; - this.phone = phone; - this.email = email; - } + /*** + * default constructor. + * Name, phone and email of sender contact person are e.g. required by XRechnung + * @param name full name of the contact + * @param phone full phone number + * @param email email address of the contact + */ + public Contact(String name, String phone, String email) { + this.name = name; + this.phone = phone; + this.email = email; + } - /*** - * empty constructor. - * as always, not recommended, for jackson... - */ - public Contact() { - } + /*** + * empty constructor. + * as always, not recommended, for jackson... + */ + public Contact() { + } - /*** - * complete specification of a named contact with a different address - * @param name full name - * @param phone full phone number - * @param email full email - * @param street street+number - * @param zip postcode - * @param location city - * @param country two-letter iso code - */ - public Contact(String name, String phone, String email, String street, String zip, String location, String country) { - this.name = name; - this.phone = phone; - this.email = email; - this.street = street; - this.zip = zip; - this.location = location; - this.country = country; + /*** + * complete specification of a named contact with a different address + * @param name full name + * @param phone full phone number + * @param email full email + * @param street street+number + * @param zip postcode + * @param location city + * @param country two-letter iso code + */ + public Contact(String name, String phone, String email, String street, String zip, String location, String country) { + this.name = name; + this.phone = phone; + this.email = email; + this.street = street; + this.zip = zip; + this.location = location; + this.country = country; - } + } - /*** - * XML parsing constructor - * @param nodes the nodelist returned e.g. from xpath - */ - public Contact(NodeList nodes) { - if (nodes.getLength() > 0) { + /*** + * XML parsing constructor + * @param nodes the nodelist returned e.g. from xpath + */ + public Contact(NodeList nodes) { + if (nodes.getLength() > 0) { - /* - will parse sth like - - Name - - 069 100-0 - - - test@example.com - - - */ - for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { - //nodes.item(i).getTextContent())) { - Node currentItemNode = nodes.item(nodeIndex); - if (currentItemNode.getLocalName() != null) { + /* + will parse sth like + + Name + + 069 100-0 + + + test@example.com + + + */ + for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { + // nodes.item(i).getTextContent())) { + Node currentItemNode = nodes.item(nodeIndex); + if (currentItemNode.getLocalName() != null) { - if (currentItemNode.getLocalName().equals("PersonName")/*CII*/||currentItemNode.getLocalName().equals("Name")/*UBL*/) { - setName(currentItemNode.getFirstChild().getNodeValue()); - } - if (currentItemNode.getLocalName().equals("TelephoneUniversalCommunication")) { /*CII*/ - NodeList tel = currentItemNode.getChildNodes(); - for (int telChildIndex = 0; telChildIndex < tel.getLength(); telChildIndex++) { - if (tel.item(telChildIndex).getLocalName() != null) { - if (tel.item(telChildIndex).getLocalName().equals("CompleteNumber")) { - setPhone(tel.item(telChildIndex).getTextContent()); - } - } - } - } else if (currentItemNode.getLocalName().equals("Telephone")) { /* UBL */ - setPhone(currentItemNode.getTextContent()); - } - if (currentItemNode.getLocalName().equals("EmailURIUniversalCommunication")) { /* CII */ - NodeList email = currentItemNode.getChildNodes(); - for (int emailChildIndex = 0; emailChildIndex < email.getLength(); emailChildIndex++) { - if (email.item(emailChildIndex).getLocalName() != null) { - if (email.item(emailChildIndex).getLocalName().equals("URIID")) { - setEMail(email.item(emailChildIndex).getTextContent()); - } - } - } - } else if (currentItemNode.getLocalName().equals("ElectronicMail")) { /* UBL */ - setEMail(currentItemNode.getTextContent()); - } - } - } - } - } + if (currentItemNode.getLocalName().equals("PersonName")/*CII*/|| currentItemNode.getLocalName().equals("Name")/*UBL*/) { + setName(currentItemNode.getFirstChild().getNodeValue()); + } + if (currentItemNode.getLocalName().equals("TelephoneUniversalCommunication")) { /*CII*/ +NodeList tel = currentItemNode.getChildNodes(); + for (int telChildIndex = 0; telChildIndex < tel.getLength(); telChildIndex++) { + if (tel.item(telChildIndex).getLocalName() != null) { + if (tel.item(telChildIndex).getLocalName().equals("CompleteNumber")) { + setPhone(tel.item(telChildIndex).getTextContent()); + } + } + } + } else if (currentItemNode.getLocalName().equals("Telephone")) { /* UBL */ +setPhone(currentItemNode.getTextContent()); + } + if (currentItemNode.getLocalName().equals("EmailURIUniversalCommunication")) { /* CII */ +NodeList email = currentItemNode.getChildNodes(); + for (int emailChildIndex = 0; emailChildIndex < email.getLength(); emailChildIndex++) { + if (email.item(emailChildIndex).getLocalName() != null) { + if (email.item(emailChildIndex).getLocalName().equals("URIID")) { + setEMail(email.item(emailChildIndex).getTextContent()); + } + } + } + } else if (currentItemNode.getLocalName().equals("ElectronicMail")) { /* UBL */ +setEMail(currentItemNode.getTextContent()); + } + } + } + } + } - @Override - public String getName() { - return name; - } + @Override + public String getName() { + return name; + } - /** - * the first and last name of the contact - * - * @param name first and last name - * @return fluent setter - */ - public Contact setName(String name) { - this.name = name; - return this; - } + /** + * the first and last name of the contact + * + * @param name first and last name + * @return fluent setter + */ + public Contact setName(String name) { + this.name = name; + return this; + } - @Override - public String getPhone() { - return phone; - } + @Override + public String getPhone() { + return phone; + } - /*** - * complete phone number of the contact - * @param phone the complete phone number - * @return fluent setter - */ - public Contact setPhone(String phone) { - this.phone = phone; - return this; - } + /*** + * complete phone number of the contact + * @param phone the complete phone number + * @return fluent setter + */ + public Contact setPhone(String phone) { + this.phone = phone; + return this; + } - @Override - public String getFax() { - return fax; - } + @Override + public String getFax() { + return fax; + } - /*** - * (optional) complete fax number - * @param fax complete fax number of the contact - * @return fluent setter - */ - public Contact setFax(String fax) { - this.fax = fax; - return this; - } + /*** + * (optional) complete fax number + * @param fax complete fax number of the contact + * @return fluent setter + */ + public Contact setFax(String fax) { + this.fax = fax; + return this; + } - public String getEMail() { - return email; - } + public String getEMail() { + return email; + } - /*** - * personal email address of the contact person - * @param email the email address of the contact - * @return fluent setter - */ - public Contact setEMail(String email) { - this.email = email; - return this; - } + /*** + * personal email address of the contact person + * @param email the email address of the contact + * @return fluent setter + */ + public Contact setEMail(String email) { + this.email = email; + return this; + } - public String getZIP() { - return zip; - } + public String getZIP() { + return zip; + } - /*** - * the postcode, if the address is different to the organisation - * @param zip the postcode of the contact - * @return fluent setter - */ - public Contact setZIP(String zip) { - this.zip = zip; - return this; - } + /*** + * the postcode, if the address is different to the organisation + * @param zip the postcode of the contact + * @return fluent setter + */ + public Contact setZIP(String zip) { + this.zip = zip; + return this; + } - @Override - public String getStreet() { - return street; - } + @Override + public String getStreet() { + return street; + } - /** - * street and number, if the address is different to the organisation - * - * @param street street and number of the contact - * @return fluent setter - */ - public Contact setStreet(String street) { - this.street = street; - return this; - } + /** + * street and number, if the address is different to the organisation + * + * @param street street and number of the contact + * @return fluent setter + */ + public Contact setStreet(String street) { + this.street = street; + return this; + } - @Override - public String getLocation() { - return location; - } + @Override + public String getLocation() { + return location; + } - /*** - * city of the contact person, if different from organisation - * @param location city - * @return fluent setter - */ - public Contact setLocation(String location) { - this.location = location; - return this; - } + /*** + * city of the contact person, if different from organisation + * @param location city + * @return fluent setter + */ + public Contact setLocation(String location) { + this.location = location; + return this; + } - @Override - public String getCountry() { - return country; - } + @Override + public String getCountry() { + return country; + } - /*** - * two-letter ISO country code of the contact, if different from organisation - * @param country two-letter iso code - * @return fluent setter - */ - public Contact setCountry(String country) { - this.country = country; - return this; - } + /*** + * two-letter ISO country code of the contact, if different from organisation + * @param country two-letter iso code + * @return fluent setter + */ + public Contact setCountry(String country) { + this.country = country; + return this; + } } diff --git a/library/src/main/java/org/mustangproject/DesignatedProductClassification.java b/library/src/main/java/org/mustangproject/DesignatedProductClassification.java index ffa35c1..d42d9a2 100755 --- a/library/src/main/java/org/mustangproject/DesignatedProductClassification.java +++ b/library/src/main/java/org/mustangproject/DesignatedProductClassification.java @@ -31,52 +31,52 @@ org.openrewrite.config.CompositeRecipe @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) public class DesignatedProductClassification implements IDesignatedProductClassification { - private ClassCode classCode; - private String className; + private ClassCode classCode; + private String className; - /** - * A schemed product descriptor - * - * @param classCode an UNTDID 7143 schemed class code - * @param className a verbal description of the class code - */ - public DesignatedProductClassification(ClassCode classCode, String className) { - this.classCode = classCode; - this.className = className; - } + /** + * A schemed product descriptor + * + * @param classCode an UNTDID 7143 schemed class code + * @param className a verbal description of the class code + */ + public DesignatedProductClassification(ClassCode classCode, String className) { + this.classCode = classCode; + this.className = className; + } - /** - * A schemed product descriptor - * - * @param classCode an UNTDID 7143 schemed class code - */ - public DesignatedProductClassification(ClassCode classCode) { - this(classCode, null); - } + /** + * A schemed product descriptor + * + * @param classCode an UNTDID 7143 schemed class code + */ + public DesignatedProductClassification(ClassCode classCode) { + this(classCode, null); + } - /** - * Bean constructor for schemed product descriptor - */ - public DesignatedProductClassification() { - classCode = null;// we need this constructor for jackson, i.e. to be able to JSON - } + /** + * Bean constructor for schemed product descriptor + */ + public DesignatedProductClassification() { + classCode = null;// we need this constructor for jackson, i.e. to be able to JSON + } - @Override - public ClassCode getClassCode() { - return classCode; - } + @Override + public ClassCode getClassCode() { + return classCode; + } - @Override - public String getClassName() { - return className; - } + @Override + public String getClassName() { + return className; + } - /** - * Set the human-readable name of the class code - * - * @param className the name of the class code (can be {@code null}) - */ - public void setClassName(String className) { - this.className = className; - } + /** + * Set the human-readable name of the class code + * + * @param className the name of the class code (can be {@code null}) + */ + public void setClassName(String className) { + this.className = className; + } } diff --git a/library/src/main/java/org/mustangproject/DirectDebit.java b/library/src/main/java/org/mustangproject/DirectDebit.java index 86937a0..7f58784 100755 --- a/library/src/main/java/org/mustangproject/DirectDebit.java +++ b/library/src/main/java/org/mustangproject/DirectDebit.java @@ -10,55 +10,55 @@ org.openrewrite.config.CompositeRecipe @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) public class DirectDebit implements IZUGFeRDTradeSettlementDebit { - /** - * Debited account identifier (BT-91) - */ - protected String IBAN; + /** + * Debited account identifier (BT-91) + */ + protected String IBAN; - /** - * Mandate reference identifier (BT-89) - */ - protected String mandate; + /** + * Mandate reference identifier (BT-89) + */ + protected String mandate; - /** - * bean constructor - */ - public DirectDebit() { - this.IBAN = ""; - this.mandate = ""; - } + /** + * bean constructor + */ + public DirectDebit() { + this.IBAN = ""; + this.mandate = ""; + } - /*** - * constructor for normal use :-) - * @param IBAN the IBAN as string - * @param mandate the mandate as string - */ - public DirectDebit(String IBAN, String mandate) { - this.IBAN = IBAN; - this.mandate = mandate; - } + /*** + * constructor for normal use :-) + * @param IBAN the IBAN as string + * @param mandate the mandate as string + */ + public DirectDebit(String IBAN, String mandate) { + this.IBAN = IBAN; + this.mandate = mandate; + } - /*** - * getter for the IBAN - * @return IBAN - */ - @Override - public String getIBAN() { - return this.IBAN; - } + /*** + * getter for the IBAN + * @return IBAN + */ + @Override + public String getIBAN() { + return this.IBAN; + } - public DirectDebit setIBAN(String iBAN) { - this.IBAN = iBAN; - return this; - } + public DirectDebit setIBAN(String iBAN) { + this.IBAN = iBAN; + return this; + } - @Override - public String getMandate() { - return this.mandate; - } + @Override + public String getMandate() { + return this.mandate; + } - public DirectDebit setMandate(String mandate) { - this.mandate = mandate; - return this; - } + public DirectDebit setMandate(String mandate) { + this.mandate = mandate; + return this; + } } diff --git a/library/src/main/java/org/mustangproject/EStandard.java b/library/src/main/java/org/mustangproject/EStandard.java index 966e1a2..d3c600b 100755 --- a/library/src/main/java/org/mustangproject/EStandard.java +++ b/library/src/main/java/org/mustangproject/EStandard.java @@ -1,6 +1,6 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject; public enum EStandard { - facturx, orderx, despatchadvice, ubldespatchadvice, zugferd, cii, ubl, ubl_creditnote + facturx, orderx, despatchadvice, ubldespatchadvice, zugferd, cii, ubl, ubl_creditnote } diff --git a/library/src/main/java/org/mustangproject/Exceptions/ArithmeticException.java b/library/src/main/java/org/mustangproject/Exceptions/ArithmeticException.java index f64b46e..61b7a54 100755 --- a/library/src/main/java/org/mustangproject/Exceptions/ArithmeticException.java +++ b/library/src/main/java/org/mustangproject/Exceptions/ArithmeticException.java @@ -6,11 +6,12 @@ org.openrewrite.config.CompositeRecipe * will be thrown if an invoice cannot be reproduced numerically */ public class ArithmeticException extends ParseException { - @SuppressWarnings("unused") - public ArithmeticException() { - this(""); - } - public ArithmeticException(final String msg) { - super("Could not reproduce the invoice. " + msg, 0); - } + @SuppressWarnings("unused") + public ArithmeticException() { + this(""); + } + + public ArithmeticException(final String msg) { + super("Could not reproduce the invoice. " + msg, 0); + } } diff --git a/library/src/main/java/org/mustangproject/Exceptions/StructureException.java b/library/src/main/java/org/mustangproject/Exceptions/StructureException.java index e34e671..99f3b85 100755 --- a/library/src/main/java/org/mustangproject/Exceptions/StructureException.java +++ b/library/src/main/java/org/mustangproject/Exceptions/StructureException.java @@ -6,7 +6,7 @@ org.openrewrite.config.CompositeRecipe * will be thrown if an invoice cannot be read */ public class StructureException extends ParseException { - public StructureException(String message, int line) { - super(message, line); - } + public StructureException(String message, int line) { + super(message, line); + } } diff --git a/library/src/main/java/org/mustangproject/FileAttachment.java b/library/src/main/java/org/mustangproject/FileAttachment.java index ed1fe39..235c775 100755 --- a/library/src/main/java/org/mustangproject/FileAttachment.java +++ b/library/src/main/java/org/mustangproject/FileAttachment.java @@ -7,70 +7,70 @@ org.openrewrite.config.CompositeRecipe @JsonInclude(JsonInclude.Include.NON_EMPTY) public class FileAttachment { - protected String filename; - protected String mimetype; - protected String relation; - protected String description; - protected byte[] data; + protected String filename; + protected String mimetype; + protected String relation; + protected String description; + protected byte[] data; - /*** - * bean contructor - */ - public FileAttachment() { + /*** + * bean contructor + */ + public FileAttachment() { - } + } - public FileAttachment(String filename, String mimetype, String relation, byte[] data) { - this.filename = filename; - this.mimetype = mimetype; - this.relation = relation; - this.data = data; - this.description = "Additional file attachment"; - } + public FileAttachment(String filename, String mimetype, String relation, byte[] data) { + this.filename = filename; + this.mimetype = mimetype; + this.relation = relation; + this.data = data; + this.description = "Additional file attachment"; + } - public String getDescription() { - return description; - } + public String getDescription() { + return description; + } - public FileAttachment setDescription(String description) { - this.description = description; - return this; - } + public FileAttachment setDescription(String description) { + this.description = description; + return this; + } - public String getFilename() { - return filename; - } + public String getFilename() { + return filename; + } - public FileAttachment setFilename(String filename) { - this.filename = filename; - return this; - } + public FileAttachment setFilename(String filename) { + this.filename = filename; + return this; + } - public String getMimetype() { - return mimetype; - } + public String getMimetype() { + return mimetype; + } - public FileAttachment setMimetype(String mimetype) { - this.mimetype = mimetype; - return this; - } + public FileAttachment setMimetype(String mimetype) { + this.mimetype = mimetype; + return this; + } - public String getRelation() { - return relation; - } + public String getRelation() { + return relation; + } - public FileAttachment setRelation(String relation) { - this.relation = relation; - return this; - } + public FileAttachment setRelation(String relation) { + this.relation = relation; + return this; + } - public byte[] getData() { - return data; - } + public byte[] getData() { + return data; + } - public FileAttachment setData(byte[] data) { - this.data = data; - return this; - } + public FileAttachment setData(byte[] data) { + this.data = data; + return this; + } } diff --git a/library/src/main/java/org/mustangproject/IncludedNote.java b/library/src/main/java/org/mustangproject/IncludedNote.java index 0bcf313..c64d26d 100755 --- a/library/src/main/java/org/mustangproject/IncludedNote.java +++ b/library/src/main/java/org/mustangproject/IncludedNote.java @@ -9,92 +9,92 @@ org.openrewrite.config.CompositeRecipe @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) public class IncludedNote { - private String content; + private String content; - private SubjectCode subjectCode; + private SubjectCode subjectCode; - private static final String INCLUDE_START = ""; - private static final String INCLUDE_END = ""; - private static final String CONTENT_START = ""; - private static final String CONTENT_END = ""; - private static final String SUBJECT_CODE_START = ""; - private static final String SUBJECT_CODE_END = ""; + private static final String INCLUDE_START = ""; + private static final String INCLUDE_END = ""; + private static final String CONTENT_START = ""; + private static final String CONTENT_END = ""; + private static final String SUBJECT_CODE_START = ""; + private static final String SUBJECT_CODE_END = ""; - public IncludedNote(String content, SubjectCode subjectCode) { - this.content = content; - this.subjectCode = subjectCode; - } + public IncludedNote(String content, SubjectCode subjectCode) { + this.content = content; + this.subjectCode = subjectCode; + } - /** - * bean constructor - */ - public IncludedNote() { + /** + * bean constructor + */ + public IncludedNote() { - } + } - public static IncludedNote generalNote(String content) { - return new IncludedNote(content, SubjectCode.AAI); - } + 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 regulatoryNote(String content) { + return new IncludedNote(content, SubjectCode.REG); + } - public static IncludedNote legalNote(String content) { - return new IncludedNote(content, SubjectCode.ABL); - } + 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 customsNote(String content) { + return new IncludedNote(content, SubjectCode.CUS); + } - public static IncludedNote sellerNote(String content) { - return new IncludedNote(content, SubjectCode.SUR); - } + 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 taxNote(String content) { + return new IncludedNote(content, SubjectCode.TXD); + } - public static IncludedNote introductionNote(String content) { - return new IncludedNote(content, SubjectCode.ACY); - } + public static IncludedNote introductionNote(String content) { + return new IncludedNote(content, SubjectCode.ACY); + } - public static IncludedNote discountBonusNote(String content) { - return new IncludedNote(content, SubjectCode.AAK); - } + public static IncludedNote discountBonusNote(String content) { + return new IncludedNote(content, SubjectCode.AAK); + } - public static IncludedNote unspecifiedNote(String content) { - return new IncludedNote(content, null); - } + public static IncludedNote unspecifiedNote(String content) { + return new IncludedNote(content, null); + } - public String getContent() { - return content; - } + public String getContent() { + return content; + } - public SubjectCode getSubjectCode() { - return subjectCode; - } + public SubjectCode getSubjectCode() { + 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 IncludedNote setContent(String content) { + this.content = content; + return this; + } - public String toCiiXml() { - String result = INCLUDE_START + CONTENT_START + - XMLTools.encodeXML(getContent()) + CONTENT_END; - if (getSubjectCode() != null) { - result += SUBJECT_CODE_START + getSubjectCode() + SUBJECT_CODE_END; - } - return result + INCLUDE_END; - } + public String toCiiXml() { + String result = INCLUDE_START + CONTENT_START + + XMLTools.encodeXML(getContent()) + CONTENT_END; + if (getSubjectCode() != null) { + result += SUBJECT_CODE_START + getSubjectCode() + SUBJECT_CODE_END; + } + return result + INCLUDE_END; + } } diff --git a/library/src/main/java/org/mustangproject/Invoice.java b/library/src/main/java/org/mustangproject/Invoice.java index 648ba71..f81c65f 100755 --- a/library/src/main/java/org/mustangproject/Invoice.java +++ b/library/src/main/java/org/mustangproject/Invoice.java @@ -20,16 +20,14 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.mustangproject.ZUGFeRD.*; + import java.math.BigDecimal; import java.util.*; -import com.fasterxml.jackson.annotation.JsonInclude; -import org.mustangproject.ZUGFeRD.*; -import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - /*** * An invoice, with fluent setters * @see IExportableTransaction if you want to implement an interface instead @@ -38,931 +36,931 @@ @JsonInclude(JsonInclude.Include.NON_EMPTY) public class Invoice implements IExportableTransaction { - protected String documentName = null, documentCode = null, number = null, ownOrganisationFullPlaintextInfo = null, referenceNumber = null, shipToOrganisationID = null, shipToOrganisationName = null, shipToStreet = null, shipToZIP = null, shipToLocation = null, shipToCountry = null, buyerOrderReferencedDocumentID = null, invoiceReferencedDocumentID = null, buyerOrderReferencedDocumentIssueDateTime = null, ownForeignOrganisationID = null, ownOrganisationName = null, currency = null, paymentTermDescription = null; - protected Date issueDate = null, dueDate = null, deliveryDate = null; - protected TradeParty sender = null, recipient = null, deliveryAddress = null, payee = null; - protected ArrayList cashDiscounts = null; - @JsonDeserialize(contentAs = Item.class) - protected ArrayList ZFItems = null; - protected ArrayList notes = null; - private List includedNotes = null; - protected String sellerOrderReferencedDocumentID; - protected String contractReferencedDocument = null; - protected ArrayList xmlEmbeddedFiles = null; + protected String documentName = null, documentCode = null, number = null, ownOrganisationFullPlaintextInfo = null, referenceNumber = null, shipToOrganisationID = null, shipToOrganisationName = null, shipToStreet = null, shipToZIP = null, shipToLocation = null, shipToCountry = null, buyerOrderReferencedDocumentID = null, invoiceReferencedDocumentID = null, buyerOrderReferencedDocumentIssueDateTime = null, ownForeignOrganisationID = null, ownOrganisationName = null, currency = null, paymentTermDescription = null; + protected Date issueDate = null, dueDate = null, deliveryDate = null; + protected TradeParty sender = null, recipient = null, deliveryAddress = null, payee = null; + protected ArrayList cashDiscounts = null; + @JsonDeserialize(contentAs = Item.class) + protected ArrayList ZFItems = null; + protected ArrayList notes = null; + private List includedNotes = null; + protected String sellerOrderReferencedDocumentID; + protected String contractReferencedDocument = null; + protected ArrayList xmlEmbeddedFiles = null; - protected BigDecimal totalPrepaidAmount = null; - protected Date detailedDeliveryDateStart = null; - protected Date detailedDeliveryPeriodEnd = null; + protected BigDecimal totalPrepaidAmount = null; + protected Date detailedDeliveryDateStart = null; + protected Date detailedDeliveryPeriodEnd = null; - protected ArrayList Allowances = new ArrayList<>(), - Charges = new ArrayList<>(), LogisticsServiceCharges = new ArrayList<>(); - protected IZUGFeRDPaymentTerms paymentTerms = null; - protected Date invoiceReferencedIssueDate; - protected String specifiedProcuringProjectID = null; - protected String specifiedProcuringProjectName = null; - protected String despatchAdviceReferencedDocumentID = null; - protected String vatDueDateTypeCode = null; - protected String creditorReferenceID; // required when direct debit is used. - private BigDecimal roundingAmount=null; + protected ArrayList Allowances = new ArrayList<>(), + Charges = new ArrayList<>(), LogisticsServiceCharges = new ArrayList<>(); + protected IZUGFeRDPaymentTerms paymentTerms = null; + protected Date invoiceReferencedIssueDate; + protected String specifiedProcuringProjectID = null; + protected String specifiedProcuringProjectName = null; + protected String despatchAdviceReferencedDocumentID = null; + protected String vatDueDateTypeCode = null; + protected String creditorReferenceID; // required when direct debit is used. + private BigDecimal roundingAmount = null; - public Invoice() { - ZFItems = new ArrayList<>(); - cashDiscounts = new ArrayList<>(); - setCurrency("EUR"); - } + public Invoice() { + ZFItems = new ArrayList<>(); + cashDiscounts = new ArrayList<>(); + setCurrency("EUR"); + } - @Override - public String getDocumentName() { - return documentName; - } + @Override + public String getDocumentName() { + return documentName; + } - @Override - public String getContractReferencedDocument() { - return contractReferencedDocument; - } + @Override + public String getContractReferencedDocument() { + return contractReferencedDocument; + } - public Invoice setDocumentName(String documentName) { - this.documentName = documentName; - return this; - } + public Invoice setDocumentName(String documentName) { + this.documentName = documentName; + return this; + } - @Override - public String getDocumentCode() { - return documentCode; - } + @Override + public String getDocumentCode() { + return documentCode; + } - public Invoice setDocumentCode(String documentCode) { - this.documentCode = documentCode; - return this; - } + public Invoice setDocumentCode(String documentCode) { + this.documentCode = documentCode; + return this; + } - public Invoice embedFileInXML(FileAttachment fa) { - if (xmlEmbeddedFiles == null) { - xmlEmbeddedFiles = new ArrayList<>(); - } - xmlEmbeddedFiles.add(fa); - return this; - } + public Invoice embedFileInXML(FileAttachment fa) { + if (xmlEmbeddedFiles == null) { + xmlEmbeddedFiles = new ArrayList<>(); + } + xmlEmbeddedFiles.add(fa); + return this; + } - @Override - public FileAttachment[] getAdditionalReferencedDocuments() { - if (xmlEmbeddedFiles == null) { - return null; - } - return xmlEmbeddedFiles.toArray(new FileAttachment[0]); + @Override + public FileAttachment[] getAdditionalReferencedDocuments() { + if (xmlEmbeddedFiles == null) { + return null; + } + return xmlEmbeddedFiles.toArray(new FileAttachment[0]); - } + } - /*** - * setter in case e.g. jackson tries to map attachments (normal use embedFileInXML) - * @param fileArr Array of FileAttachments - * @return fluent setter - */ - public Invoice setAdditionalReferencedDocuments(FileAttachment[] fileArr) { - xmlEmbeddedFiles = new ArrayList<>(Arrays.asList(fileArr)); - return this; - } + /*** + * setter in case e.g. jackson tries to map attachments (normal use embedFileInXML) + * @param fileArr Array of FileAttachments + * @return fluent setter + */ + public Invoice setAdditionalReferencedDocuments(FileAttachment[] fileArr) { + xmlEmbeddedFiles = new ArrayList<>(Arrays.asList(fileArr)); + return this; + } - @Override - public IZUGFeRDCashDiscount[] getCashDiscounts() { - return cashDiscounts.toArray(new IZUGFeRDCashDiscount[0]); - } + @Override + public IZUGFeRDCashDiscount[] getCashDiscounts() { + return cashDiscounts.toArray(new IZUGFeRDCashDiscount[0]); + } - @Override - public String getNumber() { - return number; - } + @Override + public String getNumber() { + return number; + } - public Invoice setNumber(String number) { - this.number = number; - return this; - } + public Invoice setNumber(String number) { + this.number = number; + return this; + } - /*** - * switch type to invoice correction and refer to document number. - * Please note that the quantities need to be negative, if you - * e.g. delivered 100 and take 50 back the quantity should be -50 in the - * corrected invoice, which will result in negative VAT and a negative payment amount - * @param number the invoice number to be corrected - * @return this object (fluent setter) - */ - public Invoice setCorrection(String number) { - setInvoiceReferencedDocumentID(number); - documentCode = DocumentCodeTypeConstants.CORRECTEDINVOICE; - return this; - } + /*** + * switch type to invoice correction and refer to document number. + * Please note that the quantities need to be negative, if you + * e.g. delivered 100 and take 50 back the quantity should be -50 in the + * corrected invoice, which will result in negative VAT and a negative payment amount + * @param number the invoice number to be corrected + * @return this object (fluent setter) + */ + public Invoice setCorrection(String number) { + setInvoiceReferencedDocumentID(number); + documentCode = DocumentCodeTypeConstants.CORRECTEDINVOICE; + return this; + } - public Invoice setCreditNote() { - documentCode = DocumentCodeTypeConstants.CREDITNOTE; - return this; - } + public Invoice setCreditNote() { + documentCode = DocumentCodeTypeConstants.CREDITNOTE; + return this; + } - @Override - public String getOwnOrganisationFullPlaintextInfo() { - return ownOrganisationFullPlaintextInfo; - } + @Override + public String getOwnOrganisationFullPlaintextInfo() { + return ownOrganisationFullPlaintextInfo; + } - public Invoice setOwnOrganisationFullPlaintextInfo(String ownOrganisationFullPlaintextInfo) { - this.ownOrganisationFullPlaintextInfo = ownOrganisationFullPlaintextInfo; - return this; - } + public Invoice setOwnOrganisationFullPlaintextInfo(String ownOrganisationFullPlaintextInfo) { + this.ownOrganisationFullPlaintextInfo = ownOrganisationFullPlaintextInfo; + return this; + } - @Override - public String getReferenceNumber() { - return referenceNumber; - } + @Override + public String getReferenceNumber() { + return referenceNumber; + } - public Invoice setReferenceNumber(String referenceNumber) { - this.referenceNumber = referenceNumber; - return this; - } + public Invoice setReferenceNumber(String referenceNumber) { + this.referenceNumber = referenceNumber; + return this; + } - @Override - public String getShipToOrganisationID() { - return shipToOrganisationID; - } + @Override + public String getShipToOrganisationID() { + return shipToOrganisationID; + } - public Invoice setShipToOrganisationID(String shipToOrganisationID) { - this.shipToOrganisationID = shipToOrganisationID; - return this; - } + public Invoice setShipToOrganisationID(String shipToOrganisationID) { + this.shipToOrganisationID = shipToOrganisationID; + return this; + } - @Override - public String getShipToOrganisationName() { - return shipToOrganisationName; - } + @Override + public String getShipToOrganisationName() { + return shipToOrganisationName; + } - public Invoice setShipToOrganisationName(String shipToOrganisationName) { - this.shipToOrganisationName = shipToOrganisationName; - return this; - } + public Invoice setShipToOrganisationName(String shipToOrganisationName) { + this.shipToOrganisationName = shipToOrganisationName; + return this; + } - @Override - public String getShipToStreet() { - return shipToStreet; - } + @Override + public String getShipToStreet() { + return shipToStreet; + } - public Invoice setShipToStreet(String shipToStreet) { - this.shipToStreet = shipToStreet; - return this; - } + public Invoice setShipToStreet(String shipToStreet) { + this.shipToStreet = shipToStreet; + return this; + } - @Override - public String getShipToZIP() { - return shipToZIP; - } + @Override + public String getShipToZIP() { + return shipToZIP; + } - public Invoice setShipToZIP(String shipToZIP) { - this.shipToZIP = shipToZIP; - return this; - } + public Invoice setShipToZIP(String shipToZIP) { + this.shipToZIP = shipToZIP; + return this; + } - @Override - public String getShipToLocation() { - return shipToLocation; - } + @Override + public String getShipToLocation() { + return shipToLocation; + } - public Invoice setShipToLocation(String shipToLocation) { - this.shipToLocation = shipToLocation; - return this; - } + public Invoice setShipToLocation(String shipToLocation) { + this.shipToLocation = shipToLocation; + return this; + } - @Override - public String getShipToCountry() { - return shipToCountry; - } + @Override + public String getShipToCountry() { + return shipToCountry; + } - public Invoice setShipToCountry(String shipToCountry) { - this.shipToCountry = shipToCountry; - return this; - } + public Invoice setShipToCountry(String shipToCountry) { + this.shipToCountry = shipToCountry; + return this; + } - @Override - public String getBuyerOrderReferencedDocumentID() { - return buyerOrderReferencedDocumentID; - } + @Override + public String getBuyerOrderReferencedDocumentID() { + return buyerOrderReferencedDocumentID; + } - @Override - public String getSellerOrderReferencedDocumentID() { - return sellerOrderReferencedDocumentID; - } + @Override + public String getSellerOrderReferencedDocumentID() { + return sellerOrderReferencedDocumentID; + } - public Invoice setSellerOrderReferencedDocumentID(String sellerOrderReferencedDocumentID) { - this.sellerOrderReferencedDocumentID = sellerOrderReferencedDocumentID; - return this; - } + public Invoice setSellerOrderReferencedDocumentID(String sellerOrderReferencedDocumentID) { + this.sellerOrderReferencedDocumentID = sellerOrderReferencedDocumentID; + return this; + } - /*** - * usually the order number - * @param buyerOrderReferencedDocumentID string with number - * @return fluent setter - */ - public Invoice setBuyerOrderReferencedDocumentID(String buyerOrderReferencedDocumentID) { - this.buyerOrderReferencedDocumentID = buyerOrderReferencedDocumentID; - return this; - } + /*** + * usually the order number + * @param buyerOrderReferencedDocumentID string with number + * @return fluent setter + */ + public Invoice setBuyerOrderReferencedDocumentID(String buyerOrderReferencedDocumentID) { + this.buyerOrderReferencedDocumentID = buyerOrderReferencedDocumentID; + return this; + } - /*** - * usually in case of a correction the original invoice number - * @param invoiceReferencedDocumentID string with number - * @return fluent setter - */ - public Invoice setInvoiceReferencedDocumentID(String invoiceReferencedDocumentID) { - this.invoiceReferencedDocumentID = invoiceReferencedDocumentID; - return this; - } + /*** + * usually in case of a correction the original invoice number + * @param invoiceReferencedDocumentID string with number + * @return fluent setter + */ + public Invoice setInvoiceReferencedDocumentID(String invoiceReferencedDocumentID) { + this.invoiceReferencedDocumentID = invoiceReferencedDocumentID; + return this; + } - @Override - public String getInvoiceReferencedDocumentID() { - return invoiceReferencedDocumentID; - } + @Override + public String getInvoiceReferencedDocumentID() { + return invoiceReferencedDocumentID; + } - @Override - public Date getInvoiceReferencedIssueDate() { - return invoiceReferencedIssueDate; - } + @Override + public Date getInvoiceReferencedIssueDate() { + return invoiceReferencedIssueDate; + } - public Invoice setInvoiceReferencedIssueDate(Date issueDate) { - this.invoiceReferencedIssueDate = issueDate; - return this; - } + public Invoice setInvoiceReferencedIssueDate(Date issueDate) { + this.invoiceReferencedIssueDate = issueDate; + return this; + } - @Override - public String getBuyerOrderReferencedDocumentIssueDateTime() { - return buyerOrderReferencedDocumentIssueDateTime; - } + @Override + public String getBuyerOrderReferencedDocumentIssueDateTime() { + return buyerOrderReferencedDocumentIssueDateTime; + } - /*** - * allow to set a amount which has already been paid - * @param prepaid null is possible to omit - * @return fluent setter - */ - public Invoice setTotalPrepaidAmount(BigDecimal prepaid) { - totalPrepaidAmount = prepaid; - return this; - } + /*** + * allow to set a amount which has already been paid + * @param prepaid null is possible to omit + * @return fluent setter + */ + public Invoice setTotalPrepaidAmount(BigDecimal prepaid) { + totalPrepaidAmount = prepaid; + return this; + } - @Override - public BigDecimal getTotalPrepaidAmount() { - return totalPrepaidAmount; - } + @Override + public BigDecimal getTotalPrepaidAmount() { + return totalPrepaidAmount; + } - /*** - * when the order (or whatever reference in BuyerOrderReferencedDocumentID) was issued (@todo switch to date?) - * @param buyerOrderReferencedDocumentIssueDateTime IssueDateTime in format CCYY-MM-DDTHH:MM:SS - * @return fluent setter - */ - public Invoice setBuyerOrderReferencedDocumentIssueDateTime(String buyerOrderReferencedDocumentIssueDateTime) { - this.buyerOrderReferencedDocumentIssueDateTime = buyerOrderReferencedDocumentIssueDateTime; - return this; - } + /*** + * when the order (or whatever reference in BuyerOrderReferencedDocumentID) was issued (@todo switch to date?) + * @param buyerOrderReferencedDocumentIssueDateTime IssueDateTime in format CCYY-MM-DDTHH:MM:SS + * @return fluent setter + */ + public Invoice setBuyerOrderReferencedDocumentIssueDateTime(String buyerOrderReferencedDocumentIssueDateTime) { + this.buyerOrderReferencedDocumentIssueDateTime = buyerOrderReferencedDocumentIssueDateTime; + return this; + } - @Override - public String getOwnTaxID() { - return getSender().getTaxID(); - } + @Override + public String getOwnTaxID() { + return getSender().getTaxID(); + } - @Deprecated - /*** - * @deprecated use TradeParty::addTaxID instead - * @see TradeParty - */ - public Invoice setOwnTaxID(String ownTaxID) { - sender.addTaxID(ownTaxID); - return this; - } + @Deprecated + /*** + * @deprecated use TradeParty::addTaxID instead + * @see TradeParty + */ + public Invoice setOwnTaxID(String ownTaxID) { + sender.addTaxID(ownTaxID); + return this; + } - @Override - public String getOwnVATID() { - return getSender().getVATID(); - } + @Override + public String getOwnVATID() { + return getSender().getVATID(); + } - @Deprecated - /*** - * @deprecated use TradeParty::addVATID instead - * @see TradeParty - */ - public Invoice setOwnVATID(String ownVATID) { - sender.addVATID(ownVATID); - return this; - } + @Deprecated + /*** + * @deprecated use TradeParty::addVATID instead + * @see TradeParty + */ + public Invoice setOwnVATID(String ownVATID) { + sender.addVATID(ownVATID); + return this; + } - @Override - public String getOwnForeignOrganisationID() { - return ownForeignOrganisationID; - } + @Override + public String getOwnForeignOrganisationID() { + return ownForeignOrganisationID; + } - @Deprecated - /*** - * @deprecated use TradeParty instead - * @see TradeParty - */ - public Invoice setOwnForeignOrganisationID(String ownForeignOrganisationID) { - this.ownForeignOrganisationID = ownForeignOrganisationID; - return this; - } + @Deprecated + /*** + * @deprecated use TradeParty instead + * @see TradeParty + */ + public Invoice setOwnForeignOrganisationID(String ownForeignOrganisationID) { + this.ownForeignOrganisationID = ownForeignOrganisationID; + return this; + } - @Override - public String getOwnOrganisationName() { - return ownOrganisationName; - } + @Override + public String getOwnOrganisationName() { + return ownOrganisationName; + } - @Deprecated - /*** - * @deprecated use senders' TradeParty's name instead - * @see TradeParty - */ - public Invoice setOwnOrganisationName(String ownOrganisationName) { - this.ownOrganisationName = ownOrganisationName; - return this; - } + @Deprecated + /*** + * @deprecated use senders' TradeParty's name instead + * @see TradeParty + */ + public Invoice setOwnOrganisationName(String ownOrganisationName) { + this.ownOrganisationName = ownOrganisationName; + return this; + } - @Override - public String getOwnStreet() { - return sender.getStreet(); - } + @Override + public String getOwnStreet() { + return sender.getStreet(); + } - @Override - public String getOwnZIP() { - return sender.getZIP(); - } + @Override + public String getOwnZIP() { + return sender.getZIP(); + } - @Override - public String getOwnLocation() { - return sender.getLocation(); - } + @Override + public String getOwnLocation() { + return sender.getLocation(); + } - @Override - public String getOwnCountry() { - return sender.getCountry(); - } + @Override + public String getOwnCountry() { + return sender.getCountry(); + } - @Override - public String[] getNotes() { - if (notes == null) { - return null; - } - return notes.toArray(new String[0]); - } + @Override + public String[] getNotes() { + if (notes == null) { + return null; + } + return notes.toArray(new String[0]); + } - @Override - public List getNotesWithSubjectCode() { - return includedNotes; - } + @Override + public List getNotesWithSubjectCode() { + return includedNotes; + } - public Invoice setNotesWithSubjectCode(List theList) { - includedNotes=theList; - return this; - } + public Invoice setNotesWithSubjectCode(List theList) { + includedNotes = theList; + return this; + } - @Override - public String getCurrency() { - return currency; - } + @Override + public String getCurrency() { + return currency; + } - public Invoice setCurrency(String currency) { - this.currency = currency; - return this; - } + public Invoice setCurrency(String currency) { + this.currency = currency; + return this; + } - @Override - public String getPaymentTermDescription() { - return paymentTermDescription; - } + @Override + public String getPaymentTermDescription() { + return paymentTermDescription; + } - public Invoice setPaymentTermDescription(String paymentTermDescription) { - this.paymentTermDescription = paymentTermDescription; - return this; - } + public Invoice setPaymentTermDescription(String paymentTermDescription) { + this.paymentTermDescription = paymentTermDescription; + return this; + } - @Override - public Date getIssueDate() { - return issueDate; - } + @Override + public Date getIssueDate() { + return issueDate; + } - public Invoice setIssueDate(Date issueDate) { - this.issueDate = issueDate; - return this; - } + public Invoice setIssueDate(Date issueDate) { + this.issueDate = issueDate; + return this; + } - @Override - public Date getDueDate() { - return dueDate; - } + @Override + public Date getDueDate() { + return dueDate; + } - public Invoice setDueDate(Date dueDate) { - this.dueDate = dueDate; - return this; - } + public Invoice setDueDate(Date dueDate) { + this.dueDate = dueDate; + return this; + } - @Override - public Date getDeliveryDate() { - return deliveryDate; - } + @Override + public Date getDeliveryDate() { + return deliveryDate; + } - public Invoice setDeliveryDate(Date deliveryDate) { - this.deliveryDate = deliveryDate; - return this; - } + public Invoice setDeliveryDate(Date deliveryDate) { + this.deliveryDate = deliveryDate; + return this; + } - @Override - public TradeParty getSender() { - return sender; - } + @Override + public TradeParty getSender() { + return sender; + } - /*** - * for currency rounding differences to 5ct e.g. in Netherlands ("Rappenrundung") - * @return null if not set, otherwise BigDecimal of Euros - */ - @Override - public BigDecimal getRoundingAmount() { - return roundingAmount; - } + /*** + * for currency rounding differences to 5ct e.g. in Netherlands ("Rappenrundung") + * @return null if not set, otherwise BigDecimal of Euros + */ + @Override + public BigDecimal getRoundingAmount() { + return roundingAmount; + } - /*** - * set the cent e.g. to reach the next 5ct mark for currencies in certain countries - * e.g. in the Netherlands ("Rappenrundung") - * @param amount - * @return fluent setter - */ - public Invoice setRoundingAmount(BigDecimal amount) { - roundingAmount=amount; - return this; - } + /*** + * set the cent e.g. to reach the next 5ct mark for currencies in certain countries + * e.g. in the Netherlands ("Rappenrundung") + * @param amount + * @return fluent setter + */ + public Invoice setRoundingAmount(BigDecimal amount) { + roundingAmount = amount; + return this; + } - /*** - * sets a named sender contact - * @deprecated use setSender - * @see Contact - * @param ownContact the sender contact - * @return fluent setter - */ - @Deprecated - public Invoice setOwnContact(Contact ownContact) { - this.sender.setContact(ownContact); - return this; - } + /*** + * sets a named sender contact + * @deprecated use setSender + * @see Contact + * @param ownContact the sender contact + * @return fluent setter + */ + @Deprecated + public Invoice setOwnContact(Contact ownContact) { + this.sender.setContact(ownContact); + return this; + } - @Override - public TradeParty getRecipient() { - return recipient; - } + @Override + public TradeParty getRecipient() { + return recipient; + } - /** - * required. - * sets the invoice receiving institution = invoicee - * - * @param recipient the invoicee organisation - * @return fluent setter - */ - public Invoice setRecipient(TradeParty recipient) { - this.recipient = recipient; - return this; - } + /** + * required. + * sets the invoice receiving institution = invoicee + * + * @param recipient the invoicee organisation + * @return fluent setter + */ + public Invoice setRecipient(TradeParty recipient) { + this.recipient = recipient; + return this; + } - /** - * required. - * sets the invoicing institution = invoicer - * - * @param sender the invoicer - * @return fluent setter - */ - public Invoice setSender(TradeParty sender) { - this.sender = sender; - if ((sender.getBankDetails() != null) && (sender.getBankDetails().size() > 0)) { - // convert bankdetails + /** + * required. + * sets the invoicing institution = invoicer + * + * @param sender the invoicer + * @return fluent setter + */ + public Invoice setSender(TradeParty sender) { + this.sender = sender; + if ((sender.getBankDetails() != null) && (sender.getBankDetails().size() > 0)) { + // convert bankdetails - } - return this; - } + } + return this; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFAllowances() { - if (Allowances.isEmpty()) { - return null; - } else { - return Allowances.toArray(new IZUGFeRDAllowanceCharge[0]); - } - } + @Override + public IZUGFeRDAllowanceCharge[] getZFAllowances() { + if (Allowances.isEmpty()) { + return null; + } else { + return Allowances.toArray(new IZUGFeRDAllowanceCharge[0]); + } + } - /*** - * this is wrong and only used from jackson - * @param iza the Array of allowances/charges - * @return fluent setter - */ - public Invoice setZFAllowances(Allowance[] iza) { - Allowances=new ArrayList<>(); + /*** + * this is wrong and only used from jackson + * @param iza the Array of allowances/charges + * @return fluent setter + */ + public Invoice setZFAllowances(Allowance[] iza) { + Allowances = new ArrayList<>(); - for (IZUGFeRDAllowanceCharge cz:iza) { - Allowances.add(cz); - } - return this; - } + for (IZUGFeRDAllowanceCharge cz :iza) { + Allowances.add(cz); + } + return this; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFCharges() { - if (Charges.isEmpty()) { - return null; - } else { - return Charges.toArray(new IZUGFeRDAllowanceCharge[0]); - } - } + @Override + public IZUGFeRDAllowanceCharge[] getZFCharges() { + if (Charges.isEmpty()) { + return null; + } else { + return Charges.toArray(new IZUGFeRDAllowanceCharge[0]); + } + } - /*** - * this is wrong and only used from jackson - * @param iza the array of charges - * @return fluent setter - */ - public Invoice setZFCharges(Charge[] iza) { - Charges=new ArrayList<>(); - for (IZUGFeRDAllowanceCharge cz:iza) { - Charges.add(cz); - } - return this; - } + /*** + * this is wrong and only used from jackson + * @param iza the array of charges + * @return fluent setter + */ + public Invoice setZFCharges(Charge[] iza) { + Charges = new ArrayList<>(); + for (IZUGFeRDAllowanceCharge cz :iza) { + Charges.add(cz); + } + return this; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - if (LogisticsServiceCharges.isEmpty()) { - return null; - } else { - return LogisticsServiceCharges.toArray(new IZUGFeRDAllowanceCharge[0]); - } - } + @Override + public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { + if (LogisticsServiceCharges.isEmpty()) { + return null; + } else { + return LogisticsServiceCharges.toArray(new IZUGFeRDAllowanceCharge[0]); + } + } - @Override - public IZUGFeRDTradeSettlement[] getTradeSettlement() { + @Override + public IZUGFeRDTradeSettlement[] getTradeSettlement() { - if (getSender() == null) { - return null; - } + if (getSender() == null) { + return null; + } - return getSender().getAsTradeSettlement(); + return getSender().getAsTradeSettlement(); - } + } - @Override - public IZUGFeRDPaymentTerms getPaymentTerms() { - return paymentTerms; - } + @Override + public IZUGFeRDPaymentTerms getPaymentTerms() { + return paymentTerms; + } - public Invoice setPaymentTerms(IZUGFeRDPaymentTerms paymentTerms) { - this.paymentTerms = paymentTerms; - return this; - } + public Invoice setPaymentTerms(IZUGFeRDPaymentTerms paymentTerms) { + this.paymentTerms = paymentTerms; + return this; + } - @Override - public TradeParty getDeliveryAddress() { - return deliveryAddress; - } + @Override + public TradeParty getDeliveryAddress() { + return deliveryAddress; + } - /*** - * if the delivery address is not the recipient address, it can be specified here - * @param deliveryAddress the goods receiving organisation - * @return fluent setter - */ - public Invoice setDeliveryAddress(TradeParty deliveryAddress) { - this.deliveryAddress = deliveryAddress; - return this; - } + /*** + * if the delivery address is not the recipient address, it can be specified here + * @param deliveryAddress the goods receiving organisation + * @return fluent setter + */ + public Invoice setDeliveryAddress(TradeParty deliveryAddress) { + this.deliveryAddress = deliveryAddress; + return this; + } - @Override - public TradeParty getPayee() { - return this.payee; - } + @Override + public TradeParty getPayee() { + return this.payee; + } - /*** - * if the payee is not the seller, it can be specified here - * @param payee the payment receiving organisation - * @return fluent setter - */ - public Invoice setPayee(TradeParty payee) { - this.payee = payee; - return this; - } + /*** + * if the payee is not the seller, it can be specified here + * @param payee the payment receiving organisation + * @return fluent setter + */ + public Invoice setPayee(TradeParty payee) { + this.payee = payee; + return this; + } - /*** - * Adds a cash discount (skonto) - * @param c the CashDiscount percent/period combination - * @return fluent setter - */ - public Invoice addCashDiscount(CashDiscount c) { - this.cashDiscounts.add(c); - return this; - } + /*** + * Adds a cash discount (skonto) + * @param c the CashDiscount percent/period combination + * @return fluent setter + */ + public Invoice addCashDiscount(CashDiscount c) { + this.cashDiscounts.add(c); + return this; + } - @Override - public IZUGFeRDExportableItem[] getZFItems() { - return ZFItems.toArray(new IZUGFeRDExportableItem[0]); - } + @Override + public IZUGFeRDExportableItem[] getZFItems() { + return ZFItems.toArray(new IZUGFeRDExportableItem[0]); + } - public void setZFItems(ArrayList ims) { - ZFItems = ims; - } + public void setZFItems(ArrayList ims) { + ZFItems = ims; + } - /** - * required - * adds invoice "lines" :-) - * - * @param item the invoice line - * @return fluent setter - * @see Item - */ - public Invoice addItem(IZUGFeRDExportableItem item) { - ZFItems.add(item); - return this; - } + /** + * required + * adds invoice "lines" :-) + * + * @param item the invoice line + * @return fluent setter + * @see Item + */ + public Invoice addItem(IZUGFeRDExportableItem item) { + ZFItems.add(item); + return this; + } - /*** - * checks if all required items are set in order to be able to export it - * @return true if all required items are set - */ - public boolean isValid() { - return (dueDate != null) && (sender != null) && (sender.getTaxID() != null) && (sender.getVATID() != null) && (recipient != null); - //contact - // this.phone = phone; - // this.email = email; - // this.street = street; - // this.zip = zip; - // this.location = location; - // this.country = country; - } + /*** + * checks if all required items are set in order to be able to export it + * @return true if all required items are set + */ + public boolean isValid() { + return (dueDate != null) && (sender != null) && (sender.getTaxID() != null) && (sender.getVATID() != null) && (recipient != null); + // contact + // this.phone = phone; + // this.email = email; + // this.street = street; + // this.zip = zip; + // this.location = location; + // this.country = country; + } - /*** - * adds a document level addition to the price - * @see Charge - * @param izac the charge to be applied - * @return fluent setter - */ - public Invoice addCharge(IZUGFeRDAllowanceCharge izac) { - Charges.add(izac); - return this; - } + /*** + * adds a document level addition to the price + * @see Charge + * @param izac the charge to be applied + * @return fluent setter + */ + public Invoice addCharge(IZUGFeRDAllowanceCharge izac) { + Charges.add(izac); + return this; + } - /*** - * adds a document level rebate - * @see Allowance - * @param izac the allowance to be applied - * @return fluent setter - */ - public Invoice addAllowance(IZUGFeRDAllowanceCharge izac) { - Allowances.add(izac); - return this; - } + /*** + * adds a document level rebate + * @see Allowance + * @param izac the allowance to be applied + * @return fluent setter + */ + public Invoice addAllowance(IZUGFeRDAllowanceCharge izac) { + Allowances.add(izac); + return this; + } - /*** - * adds the ID of a contract referenced in the invoice - * @param s the contract number - * @return fluent setter - */ - public Invoice setContractReferencedDocument(String s) { - contractReferencedDocument = s; - return this; - } + /*** + * adds the ID of a contract referenced in the invoice + * @param s the contract number + * @return fluent setter + */ + public Invoice setContractReferencedDocument(String s) { + contractReferencedDocument = s; + return this; + } - /*** - * sets a document level delivery period, - * which is optional additional to the mandatory deliverydate - * and which will become a BillingSpecifiedPeriod-Element - * @param start the date of first delivery - * @param end the date of last delivery - * @return fluent setter - */ - public Invoice setDetailedDeliveryPeriod(Date start, Date end) { - detailedDeliveryDateStart = start; - detailedDeliveryPeriodEnd = end; + /*** + * sets a document level delivery period, + * which is optional additional to the mandatory deliverydate + * and which will become a BillingSpecifiedPeriod-Element + * @param start the date of first delivery + * @param end the date of last delivery + * @return fluent setter + */ + public Invoice setDetailedDeliveryPeriod(Date start, Date end) { + detailedDeliveryDateStart = start; + detailedDeliveryPeriodEnd = end; - return this; - } + return this; + } - @Override - public Date getDetailedDeliveryPeriodFrom() { - return detailedDeliveryDateStart; - } + @Override + public Date getDetailedDeliveryPeriodFrom() { + return detailedDeliveryDateStart; + } - @Override - public Date getDetailedDeliveryPeriodTo() { - return detailedDeliveryPeriodEnd; - } + @Override + public Date getDetailedDeliveryPeriodTo() { + return detailedDeliveryPeriodEnd; + } - /** - * adds a free text paragraph, which will become an includedNote element - * - * @param text freeform UTF8 plain text - * @return fluent setter - */ - public Invoice addNote(String text) { - if (notes == null) { - notes = new ArrayList<>(); - } - notes.add(text); - return this; - } + /** + * adds a free text paragraph, which will become an includedNote element + * + * @param text freeform UTF8 plain text + * @return fluent setter + */ + public Invoice addNote(String text) { + if (notes == null) { + notes = new ArrayList<>(); + } + notes.add(text); + return this; + } - public Invoice addNotes(Collection notes) { - if (notes == null) { - return this; - } - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.addAll(notes); - return this; - } + public Invoice addNotes(Collection notes) { + if (notes == null) { + return this; + } + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.addAll(notes); + return this; + } - /** - * adds a free text paragraph, which will become an includedNote element with explicit - * subjectCode {@link SubjectCode#AAI} - * - * @param content freeform UTF8 plain text - * @return fluent setter - */ - public Invoice addGeneralNote(String content) { - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.add(IncludedNote.generalNote(content)); - return this; - } + /** + * adds a free text paragraph, which will become an includedNote element with explicit + * subjectCode {@link SubjectCode#AAI} + * + * @param content freeform UTF8 plain text + * @return fluent setter + */ + public Invoice addGeneralNote(String content) { + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(IncludedNote.generalNote(content)); + return this; + } - /** - * adds a free text paragraph, which will become an includedNote element with explicit - * subjectCode {@link SubjectCode#REG} - * - * @param content freeform UTF8 plain text - * @return fluent setter - */ - public Invoice addRegulatoryNote(String content) { - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.add(IncludedNote.regulatoryNote(content)); - return this; - } + /** + * adds a free text paragraph, which will become an includedNote element with explicit + * subjectCode {@link SubjectCode#REG} + * + * @param content freeform UTF8 plain text + * @return fluent setter + */ + public Invoice addRegulatoryNote(String content) { + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(IncludedNote.regulatoryNote(content)); + return this; + } - /** - * adds a free text paragraph, which will become an includedNote element with explicit - * subjectCode {@link SubjectCode#ABL} - * - * @param content freeform UTF8 plain text - * @return fluent setter - */ - public Invoice addLegalNote(String content) { - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.add(IncludedNote.legalNote(content)); - return this; - } + /** + * adds a free text paragraph, which will become an includedNote element with explicit + * subjectCode {@link SubjectCode#ABL} + * + * @param content freeform UTF8 plain text + * @return fluent setter + */ + public Invoice addLegalNote(String content) { + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(IncludedNote.legalNote(content)); + return this; + } - /** - * adds a free text paragraph, which will become an includedNote element with explicit - * subjectCode {@link SubjectCode#CUS} - * - * @param content freeform UTF8 plain text - * @return fluent setter - */ - public Invoice addCustomsNote(String content) { - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.add(IncludedNote.customsNote(content)); - return this; - } + /** + * adds a free text paragraph, which will become an includedNote element with explicit + * subjectCode {@link SubjectCode#CUS} + * + * @param content freeform UTF8 plain text + * @return fluent setter + */ + public Invoice addCustomsNote(String content) { + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(IncludedNote.customsNote(content)); + return this; + } - /** - * adds a free text paragraph, which will become an includedNote element with explicit - * subjectCode {@link SubjectCode#SUR} - * - * @param content freeform UTF8 plain text - * @return fluent setter - */ - public Invoice addSellerNote(String content) { - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.add(IncludedNote.sellerNote(content)); - return this; - } + /** + * adds a free text paragraph, which will become an includedNote element with explicit + * subjectCode {@link SubjectCode#SUR} + * + * @param content freeform UTF8 plain text + * @return fluent setter + */ + public Invoice addSellerNote(String content) { + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(IncludedNote.sellerNote(content)); + return this; + } - /** - * adds a free text paragraph, which will become an includedNote element with explicit - * subjectCode {@link SubjectCode#TXD} - * - * @param content freeform UTF8 plain text - * @return fluent setter - */ - public Invoice addTaxNote(String content) { - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.add(IncludedNote.taxNote(content)); - return this; - } + /** + * adds a free text paragraph, which will become an includedNote element with explicit + * subjectCode {@link SubjectCode#TXD} + * + * @param content freeform UTF8 plain text + * @return fluent setter + */ + public Invoice addTaxNote(String content) { + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(IncludedNote.taxNote(content)); + return this; + } - /** - * adds a free text paragraph, which will become an includedNote element with explicit - * subjectCode {@link SubjectCode#ACY} - * - * @param content freeform UTF8 plain text - * @return fluent setter - */ - public Invoice addIntroductionNote(String content) { - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.add(IncludedNote.introductionNote(content)); - return this; - } + /** + * adds a free text paragraph, which will become an includedNote element with explicit + * subjectCode {@link SubjectCode#ACY} + * + * @param content freeform UTF8 plain text + * @return fluent setter + */ + public Invoice addIntroductionNote(String content) { + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(IncludedNote.introductionNote(content)); + return this; + } - /** - * adds a free text paragraph, which will become an includedNote element with explicit - * subjectCode {@link SubjectCode#AAK} - * - * @param content freeform UTF8 plain text - * @return fluent setter - */ - public Invoice addDiscountBonusNote(String content) { - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.add(IncludedNote.discountBonusNote(content)); - return this; - } + /** + * adds a free text paragraph, which will become an includedNote element with explicit + * subjectCode {@link SubjectCode#AAK} + * + * @param content freeform UTF8 plain text + * @return fluent setter + */ + public Invoice addDiscountBonusNote(String content) { + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(IncludedNote.discountBonusNote(content)); + return this; + } - @Override - public String getSpecifiedProcuringProjectID() { - return specifiedProcuringProjectID; - } + @Override + public String getSpecifiedProcuringProjectID() { + return specifiedProcuringProjectID; + } - public Invoice setSpecifiedProcuringProjectID(String specifiedProcuringProjectID) { - this.specifiedProcuringProjectID = specifiedProcuringProjectID; - return this; - } + public Invoice setSpecifiedProcuringProjectID(String specifiedProcuringProjectID) { + this.specifiedProcuringProjectID = specifiedProcuringProjectID; + return this; + } - @Override - public String getDespatchAdviceReferencedDocumentID() { - return despatchAdviceReferencedDocumentID; - } + @Override + public String getDespatchAdviceReferencedDocumentID() { + return despatchAdviceReferencedDocumentID; + } - public Invoice setDespatchAdviceReferencedDocumentID(String despatchAdviceReferencedDocumentID) { - this.despatchAdviceReferencedDocumentID = despatchAdviceReferencedDocumentID; - return this; - } + public Invoice setDespatchAdviceReferencedDocumentID(String despatchAdviceReferencedDocumentID) { + this.despatchAdviceReferencedDocumentID = despatchAdviceReferencedDocumentID; + return this; + } - @Override - public String getSpecifiedProcuringProjectName() { - return specifiedProcuringProjectName; - } + @Override + public String getSpecifiedProcuringProjectName() { + return specifiedProcuringProjectName; + } - public Invoice setSpecifiedProcuringProjectName(String specifiedProcuringProjectName) { - this.specifiedProcuringProjectName = specifiedProcuringProjectName; - return this; - } + public Invoice setSpecifiedProcuringProjectName(String specifiedProcuringProjectName) { + this.specifiedProcuringProjectName = specifiedProcuringProjectName; + return this; + } - @Override - public String getVATDueDateTypeCode() { - return vatDueDateTypeCode; - } + @Override + public String getVATDueDateTypeCode() { + return vatDueDateTypeCode; + } - /** - * Decide when the VAT should be collected. - * - * @param vatDueDateTypeCode use EventTimeCodeTypeConstants - * @return fluent setter - */ - public Invoice setVATDueDateTypeCode(String vatDueDateTypeCode) { - this.vatDueDateTypeCode = vatDueDateTypeCode; - return this; - } + /** + * Decide when the VAT should be collected. + * + * @param vatDueDateTypeCode use EventTimeCodeTypeConstants + * @return fluent setter + */ + public Invoice setVATDueDateTypeCode(String vatDueDateTypeCode) { + this.vatDueDateTypeCode = vatDueDateTypeCode; + return this; + } - public String getCreditorReferenceID() { - return creditorReferenceID; - } + public String getCreditorReferenceID() { + return creditorReferenceID; + } - public Invoice setCreditorReferenceID(String creditorReferenceID) { - this.creditorReferenceID = creditorReferenceID; - return this; - } + public Invoice setCreditorReferenceID(String creditorReferenceID) { + this.creditorReferenceID = creditorReferenceID; + return this; + } } diff --git a/library/src/main/java/org/mustangproject/Item.java b/library/src/main/java/org/mustangproject/Item.java index 249d506..5a304ed 100755 --- a/library/src/main/java/org/mustangproject/Item.java +++ b/library/src/main/java/org/mustangproject/Item.java @@ -15,8 +15,6 @@ org.openrewrite.config.CompositeRecipe import java.util.Collection; import java.util.Date; import java.util.List; -import java.util.HashMap; -import java.util.Map; /*** * describes any invoice line @@ -25,465 +23,464 @@ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) public class Item implements IZUGFeRDExportableItem { - protected BigDecimal price = BigDecimal.ZERO; - protected BigDecimal quantity; - protected BigDecimal tax; - protected BigDecimal grossPrice; - protected BigDecimal lineTotalAmount; - protected BigDecimal basisQuantity = BigDecimal.ONE; - protected Date detailedDeliveryPeriodFrom = null; - protected Date detailedDeliveryPeriodTo = null; - protected String id; - protected String referencedLineID = null; - protected Product product; - protected ArrayList notes = null; - protected ArrayList referencedDocuments = null; - protected ArrayList additionalReference = null; - protected ArrayList Allowances = new ArrayList<>(); - protected ArrayList Charges = new ArrayList<>(); - protected List includedNotes = null; - //protected HashMap attributes = new HashMap<>(); + protected BigDecimal price = BigDecimal.ZERO; + protected BigDecimal quantity; + protected BigDecimal tax; + protected BigDecimal grossPrice; + protected BigDecimal lineTotalAmount; + protected BigDecimal basisQuantity = BigDecimal.ONE; + protected Date detailedDeliveryPeriodFrom = null; + protected Date detailedDeliveryPeriodTo = null; + protected String id; + protected String referencedLineID = null; + protected Product product; + protected ArrayList notes = null; + protected ArrayList referencedDocuments = null; + protected ArrayList additionalReference = null; + protected ArrayList Allowances = new ArrayList<>(); + protected ArrayList Charges = new ArrayList<>(); + protected List includedNotes = null; - /*** - * default constructor - * @param product contains the products name, tax rate, and unit - * @param price the base price of one item the product - * @param quantity the number, dimensions or the weight of the delivered product or good in this context - */ - public Item(Product product, BigDecimal price, BigDecimal quantity) { - this.price = price; - this.quantity = quantity; - this.product = product; - } + // protected HashMap attributes = new HashMap<>(); - /*** - * empty constructor - * do not use, but might be used e.g. by jackson - * */ - public Item() { - } + /*** + * default constructor + * @param product contains the products name, tax rate, and unit + * @param price the base price of one item the product + * @param quantity the number, dimensions or the weight of the delivered product or good in this context + */ + public Item(Product product, BigDecimal price, BigDecimal quantity) { + this.price = price; + this.quantity = quantity; + this.product = product; + } - public Item(NodeList itemChilds, boolean recalcPrice) { - NodeMap itemMap = new NodeMap(itemChilds); + /*** + * empty constructor + * do not use, but might be used e.g. by jackson + * */ + public Item() { + } - itemMap.getAsNodeMap("Item").ifPresent(icnm -> { - // ubl - //we need: name description unitcode - //and we additionally have vat% + public Item(NodeList itemChilds, boolean recalcPrice) { + NodeMap itemMap = new NodeMap(itemChilds); - // 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); + itemMap.getAsNodeMap("Item").ifPresent(icnm -> { + // ubl + // we need: name description unitcode + // and we additionally have vat% - icnm.getAsNodeMap("SellersItemIdentification").ifPresent(SellersItemIdentification -> { - SellersItemIdentification.getAsString("ID").ifPresent(product::setSellerAssignedID); - }); + // 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("BuyersItemIdentification").ifPresent(BuyersItemIdentification -> { - BuyersItemIdentification.getAsString("ID").ifPresent(product::setBuyerAssignedID); - }); + icnm.getAsNodeMap("SellersItemIdentification").ifPresent(SellersItemIdentification -> { + SellersItemIdentification.getAsString("ID").ifPresent(product::setSellerAssignedID); + }); -// 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("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 - // PriceAmount with currencyID and BaseQuantity with unitCode - icnm.getAsBigDecimal("PriceAmount").ifPresent(this::setPrice); - icnm.getAsBigDecimal("BaseQuantity").ifPresent(this::setBasisQuantity); - }); + icnm.getAsNodeMap("ClassifiedTaxCategory").flatMap(m -> m.getAsBigDecimal("Percent")) + .ifPresent(product::setVATPercent); + }); + itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(icnm -> { + icnm.getAsString("LineID").ifPresent(this::setId); + }); - itemMap.getNode("InvoicedQuantity").ifPresent(icn -> { - // ubl - setQuantity(new BigDecimal(icn.getTextContent().trim())); - product.setUnit(icn.getAttributes().getNamedItem("unitCode").getNodeValue()); - }); + itemMap.getAsNodeMap("Price").ifPresent(icnm -> { + // ubl + // PriceAmount with currencyID and BaseQuantity with unitCode + icnm.getAsBigDecimal("PriceAmount").ifPresent(this::setPrice); + icnm.getAsBigDecimal("BaseQuantity").ifPresent(this::setBasisQuantity); + }); - itemMap.getAllNodes("DocumentReference").map(ReferencedDocument::fromNode) - .forEach(this::addAdditionalReference); + itemMap.getNode("InvoicedQuantity").ifPresent(icn -> { + // ubl + setQuantity(new BigDecimal(icn.getTextContent().trim())); + product.setUnit(icn.getAttributes().getNamedItem("unitCode").getNodeValue()); + }); - // ubl + itemMap.getAllNodes("DocumentReference").map(ReferencedDocument::fromNode) + .forEach(this::addAdditionalReference); - itemMap.getAsNodeMap("OrderLineReference") - // ubl - .flatMap(bordNodes -> bordNodes.getAsString("LineID")) - .ifPresent(this::addReferencedLineID); + // ubl - itemMap.getAsString("ID") - .ifPresent(this::setId); + itemMap.getAsNodeMap("OrderLineReference") + // ubl + .flatMap(bordNodes -> bordNodes.getAsString("LineID")) + .ifPresent(this::addReferencedLineID); + itemMap.getAsString("ID") + .ifPresent(this::setId); - itemMap.getAsString("Note") - .ifPresent(this::addNote); + itemMap.getAsString("Note") + .ifPresent(this::addNote); + itemMap.getAsNodeMap("SpecifiedLineTradeAgreement", "SpecifiedSupplyChainTradeAgreement").ifPresent(icnm -> { + icnm.getAsNodeMap("BuyerOrderReferencedDocument") + .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.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);// CII + itemMap.getNode("SpecifiedTradeProduct").map(Product::new).ifPresent(this::setProduct);// UBL - 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") + .flatMap(icnm -> icnm.getNode("BilledQuantity", "RequestedQuantity", "DespatchedQuantity")) + .ifPresent(bq -> { + setQuantity(new BigDecimal(bq.getTextContent().trim())); + if (bq.hasAttributes()) { + Node unitAttr = bq.getAttributes().getNamedItem("unitCode"); + if (unitAttr != null) { + product.setUnit(unitAttr.getNodeValue()); + } + } + }); - // RequestedQuantity is for Order-X, BilledQuantity for FX and ZF - itemMap.getAsNodeMap("SpecifiedLineTradeDelivery", "SpecifiedSupplyChainTradeDelivery") - .flatMap(icnm -> icnm.getNode("BilledQuantity", "RequestedQuantity", "DespatchedQuantity")) - .ifPresent(bq -> { - setQuantity(new BigDecimal(bq.getTextContent().trim())); - if (bq.hasAttributes()) { - Node unitAttr = bq.getAttributes().getNamedItem("unitCode"); - if (unitAttr != null) { - product.setUnit(unitAttr.getNodeValue()); - } - } - }); + itemMap.getAsNodeMap("SpecifiedLineTradeSettlement", "SpecifiedSupplyChainTradeSettlement").ifPresent(icnm -> { + icnm.getAsNodeMap("ApplicableTradeTax") + .flatMap(cnm -> cnm.getAsBigDecimal("RateApplicablePercent", "ApplicablePercent")) + .ifPresent(product::setVATPercent); - itemMap.getAsNodeMap("SpecifiedLineTradeSettlement", "SpecifiedSupplyChainTradeSettlement").ifPresent(icnm -> { - icnm.getAsNodeMap("ApplicableTradeTax") - .flatMap(cnm -> cnm.getAsBigDecimal("RateApplicablePercent", "ApplicablePercent")) - .ifPresent(product::setVATPercent); + if (recalcPrice && !BigDecimal.ZERO.equals(quantity)) { + icnm.getAsNodeMap("SpecifiedTradeSettlementLineMonetarySummation") + .flatMap(cnm -> cnm.getAsBigDecimal("LineTotalAmount")) + .ifPresent(lineTotal -> setPrice(lineTotal.divide(quantity, 4, RoundingMode.HALF_UP))); + } - if (recalcPrice && !BigDecimal.ZERO.equals(quantity)) { - icnm.getAsNodeMap("SpecifiedTradeSettlementLineMonetarySummation") - .flatMap(cnm -> cnm.getAsBigDecimal("LineTotalAmount")) - .ifPresent(lineTotal -> setPrice(lineTotal.divide(quantity, 4, RoundingMode.HALF_UP))); - } + icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference); + }); - icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference); - }); + itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(adld -> { + List 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); + }); + } - itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(adld -> { - List 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) { + referencedLineID = s; + return this; + } - public Item addReferencedLineID(String s) { - referencedLineID = s; - return this; - } + /*** + * BT 132 (issue https://github.com/ZUGFeRD/mustangproject/issues/247) + * @return the line ID of the order (BT132) + */ + @Override + public String getBuyerOrderReferencedDocumentLineID() { + return referencedLineID; + } - /*** - * BT 132 (issue https://github.com/ZUGFeRD/mustangproject/issues/247) - * @return the line ID of the order (BT132) - */ - @Override - public String getBuyerOrderReferencedDocumentLineID() { - return referencedLineID; - } + public BigDecimal getLineTotalAmount() { + return lineTotalAmount; + } - public BigDecimal getLineTotalAmount() { - return lineTotalAmount; - } + public Item setNotesWithSubjectCode(List theList) { + includedNotes = theList; + return this; + } - public Item setNotesWithSubjectCode(List theList) { - includedNotes=theList; - return this; - } + /** + * should only be set by calculator classes or maybe when reading from XML + * + * @param lineTotalAmount price*quantity of this line + * @return fluent setter + */ + public Item setLineTotalAmount(BigDecimal lineTotalAmount) { + this.lineTotalAmount = lineTotalAmount; + return this; + } - /** - * should only be set by calculator classes or maybe when reading from XML - * - * @param lineTotalAmount price*quantity of this line - * @return fluent setter - */ - public Item setLineTotalAmount(BigDecimal lineTotalAmount) { - this.lineTotalAmount = lineTotalAmount; - return this; - } + public BigDecimal getGrossPrice() { + return grossPrice; + } - public BigDecimal getGrossPrice() { - return grossPrice; - } - - /*** - * the list price without VAT (sic!), refer to EN16931-1 for definition - * @param grossPrice the list price without VAT - * @return fluent setter - */ - public Item setGrossPrice(BigDecimal grossPrice) { - this.grossPrice = grossPrice; - return this; - } + /*** + * the list price without VAT (sic!), refer to EN16931-1 for definition + * @param grossPrice the list price without VAT + * @return fluent setter + */ + public Item setGrossPrice(BigDecimal grossPrice) { + this.grossPrice = grossPrice; + return this; + } - public BigDecimal getTax() { - return tax; - } + public BigDecimal getTax() { + return tax; + } - public Item setTax(BigDecimal tax) { - this.tax = tax; - return this; - } + public Item setTax(BigDecimal tax) { + this.tax = tax; + return this; + } - public Item setId(String id) { - this.id = id; - return this; - } + public Item setId(String id) { + this.id = id; + return this; + } - public String getId() { - return id; - } + public String getId() { + return id; + } - @Override - public BigDecimal getPrice() { - return price; - } + @Override + public BigDecimal getPrice() { + return price; + } - public Item setPrice(BigDecimal price) { - this.price = price; - return this; - } + public Item setPrice(BigDecimal price) { + this.price = price; + return this; + } - @Override - public BigDecimal getBasisQuantity() { - return basisQuantity; - } + @Override + public BigDecimal getBasisQuantity() { + return basisQuantity; + } - public Item setBasisQuantity(BigDecimal basis) { - this.basisQuantity = basis; - return this; - } + public Item setBasisQuantity(BigDecimal basis) { + this.basisQuantity = basis; + return this; + } - @Override - public BigDecimal getQuantity() { - return quantity; - } + @Override + public BigDecimal getQuantity() { + return quantity; + } - public Item setQuantity(BigDecimal quantity) { - this.quantity = quantity; - return this; - } + public Item setQuantity(BigDecimal quantity) { + this.quantity = quantity; + return this; + } - @Override - public Product getProduct() { - return product; - } + @Override + public Product getProduct() { + return product; + } - @Override - public IZUGFeRDAllowanceCharge[] getItemAllowances() { - if (Allowances.isEmpty()) { - return null; - } else - return Allowances.toArray(new IZUGFeRDAllowanceCharge[0]); - } + @Override + public IZUGFeRDAllowanceCharge[] getItemAllowances() { + if (Allowances.isEmpty()) { + return null; + } else + return Allowances.toArray(new IZUGFeRDAllowanceCharge[0]); + } - @Override - public IZUGFeRDAllowanceCharge[] getItemCharges() { - if (Charges.isEmpty()) { - return null; - } else - return Charges.toArray(new IZUGFeRDAllowanceCharge[0]); - } + @Override + public IZUGFeRDAllowanceCharge[] getItemCharges() { + if (Charges.isEmpty()) { + return null; + } else + return Charges.toArray(new IZUGFeRDAllowanceCharge[0]); + } - @Override - public String[] getNotes() { - if (notes == null) { - return null; - } - return notes.toArray(new String[0]); - } + @Override + public String[] getNotes() { + if (notes == null) { + return null; + } + return notes.toArray(new String[0]); + } - public Item setProduct(Product product) { - this.product = product; - return this; - } + public Item setProduct(Product product) { + this.product = product; + return this; + } - /*** - * Adds a item level addition to the price (will be multiplied by quantity) - * @see org.mustangproject.Charge - * @param izac a relative or absolute charge - * @return fluent setter - */ - public Item addCharge(IZUGFeRDAllowanceCharge izac) { - Charges.add(izac); - return this; - } + /*** + * Adds a item level addition to the price (will be multiplied by quantity) + * @see org.mustangproject.Charge + * @param izac a relative or absolute charge + * @return fluent setter + */ + public Item addCharge(IZUGFeRDAllowanceCharge izac) { + Charges.add(izac); + return this; + } - /*** - * Adds a item level reduction the price (will be multiplied by quantity) - * @see org.mustangproject.Allowance - * @param izac a relative or absolute allowance - * @return fluent setter - */ - public Item addAllowance(IZUGFeRDAllowanceCharge izac) { - Allowances.add(izac); - return this; - } + /*** + * Adds a item level reduction the price (will be multiplied by quantity) + * @see org.mustangproject.Allowance + * @param izac a relative or absolute allowance + * @return fluent setter + */ + public Item addAllowance(IZUGFeRDAllowanceCharge izac) { + Allowances.add(izac); + return this; + } - /*** - * adds item level freetext fields (includednote) - * @param text UTF8 plain text - * @return fluent setter - */ - public Item addNote(String text) { - if (notes == null) { - notes = new ArrayList<>(); - } - notes.add(text); + /*** + * adds item level freetext fields (includednote) + * @param text UTF8 plain text + * @return fluent setter + */ + public Item addNote(String text) { + if (notes == null) { + notes = new ArrayList<>(); + } + notes.add(text); - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.add(IncludedNote.unspecifiedNote(text)); + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(IncludedNote.unspecifiedNote(text)); - return this; - } + return this; + } - /*** - * adds item level Referenced documents along with their typecodes and issuerassignedIDs - * @param doc the ReferencedDocument to add - * @return fluent setter - */ - public Item addReferencedDocument(ReferencedDocument doc) { - if (referencedDocuments == null) { - referencedDocuments = new ArrayList<>(); - } - referencedDocuments.add(doc); - return this; - } + /*** + * adds item level Referenced documents along with their typecodes and issuerassignedIDs + * @param doc the ReferencedDocument to add + * @return fluent setter + */ + public Item addReferencedDocument(ReferencedDocument doc) { + if (referencedDocuments == null) { + referencedDocuments = new ArrayList<>(); + } + referencedDocuments.add(doc); + return this; + } - @Override - public IReferencedDocument[] getReferencedDocuments() { - if (referencedDocuments == null) { - return null; - } - return referencedDocuments.toArray(new IReferencedDocument[0]); - } + @Override + public IReferencedDocument[] getReferencedDocuments() { + if (referencedDocuments == null) { + return null; + } + return referencedDocuments.toArray(new IReferencedDocument[0]); + } - /*** - * adds item level references along with their typecodes and issuerassignedIDs (contract ID, cost centre, ...) - * @param doc the ReferencedDocument to add - * @return fluent setter - */ - public Item addAdditionalReference(ReferencedDocument doc) { - if (additionalReference == null) { - additionalReference = new ArrayList<>(); - } - additionalReference.add(doc); - return this; - } + /*** + * adds item level references along with their typecodes and issuerassignedIDs (contract ID, cost centre, ...) + * @param doc the ReferencedDocument to add + * @return fluent setter + */ + public Item addAdditionalReference(ReferencedDocument doc) { + if (additionalReference == null) { + additionalReference = new ArrayList<>(); + } + additionalReference.add(doc); + return this; + } - @Override - public IReferencedDocument[] getAdditionalReferences() { - if (additionalReference == null) { - return null; - } - return additionalReference.toArray(new IReferencedDocument[0]); - } + @Override + public IReferencedDocument[] getAdditionalReferences() { + if (additionalReference == null) { + return null; + } + return additionalReference.toArray(new IReferencedDocument[0]); + } - /*** - * specify a item level delivery period - * (apart from the document level delivery period, and the document level - * delivery day, which is probably anyway required) - * - * @param from start date - * @param to end date - * @return fluent setter - */ - public Item setDetailedDeliveryPeriod(Date from, Date to) { - detailedDeliveryPeriodFrom = from; - detailedDeliveryPeriodTo = to; - return this; - } + /*** + * specify a item level delivery period + * (apart from the document level delivery period, and the document level + * delivery day, which is probably anyway required) + * + * @param from start date + * @param to end date + * @return fluent setter + */ + public Item setDetailedDeliveryPeriod(Date from, Date to) { + detailedDeliveryPeriodFrom = from; + detailedDeliveryPeriodTo = to; + return this; + } - /*** - * specifies the item level delivery period (there is also one on document level), - * this will be included in a BillingSpecifiedPeriod element - * @return the beginning of the delivery period - */ - @Override - public Date getDetailedDeliveryPeriodFrom() { - return detailedDeliveryPeriodFrom; - } + /*** + * specifies the item level delivery period (there is also one on document level), + * this will be included in a BillingSpecifiedPeriod element + * @return the beginning of the delivery period + */ + @Override + public Date getDetailedDeliveryPeriodFrom() { + return detailedDeliveryPeriodFrom; + } - /*** - * specifies the item level delivery period (there is also one on document level), - * this will be included in a BillingSpecifiedPeriod element - * @return the end of the delivery period - */ - @Override - public Date getDetailedDeliveryPeriodTo() { - return detailedDeliveryPeriodTo; - } + /*** + * specifies the item level delivery period (there is also one on document level), + * this will be included in a BillingSpecifiedPeriod element + * @return the end of the delivery period + */ + @Override + public Date getDetailedDeliveryPeriodTo() { + return detailedDeliveryPeriodTo; + } - public IZUGFeRDExportableItem addNotes(Collection notes) { - if (notes == null) { - return this; - } - if (includedNotes == null) { - includedNotes = new ArrayList<>(); - } - includedNotes.addAll(notes); - return this; - } + public IZUGFeRDExportableItem addNotes(Collection notes) { + if (notes == null) { + return this; + } + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.addAll(notes); + return this; + } - @Override - public List getNotesWithSubjectCode() { - return includedNotes; - } + @Override + public List getNotesWithSubjectCode() { + return includedNotes; + } } diff --git a/library/src/main/java/org/mustangproject/LegalOrganisation.java b/library/src/main/java/org/mustangproject/LegalOrganisation.java index 705420c..05e4bd1 100755 --- a/library/src/main/java/org/mustangproject/LegalOrganisation.java +++ b/library/src/main/java/org/mustangproject/LegalOrganisation.java @@ -2,7 +2,7 @@ org.openrewrite.config.CompositeRecipe import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; -import org.mustangproject.ZUGFeRD.*; +import org.mustangproject.ZUGFeRD.IZUGFeRDLegalOrganisation; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -13,68 +13,68 @@ @JsonInclude(JsonInclude.Include.NON_EMPTY) public class LegalOrganisation implements IZUGFeRDLegalOrganisation { - protected SchemedID schemedID = null; - protected String tradingBusinessName = null; + protected SchemedID schemedID = null; + protected String tradingBusinessName = null; - public LegalOrganisation() { - } + public LegalOrganisation() { + } - public LegalOrganisation(String ID, String scheme) { - this.schemedID = new SchemedID(scheme, ID); - } + public LegalOrganisation(String ID, String scheme) { + this.schemedID = new SchemedID(scheme, ID); + } - public LegalOrganisation(SchemedID schemedID, String tradingBusinessName) { - this.schemedID = schemedID; - this.tradingBusinessName=tradingBusinessName; - } + public LegalOrganisation(SchemedID schemedID, String tradingBusinessName) { + this.schemedID = schemedID; + this.tradingBusinessName = tradingBusinessName; + } - /*** - * XML parsing constructor - * @param nodes the nodelist returned e.g. from xpath - */ - public LegalOrganisation(NodeList nodes) { - if (nodes.getLength() > 0) { - /* - will parse sth like - - 4711 - Test GmbH & Co.KG - - */ - for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { - Node currentItemNode = nodes.item(nodeIndex); - if (currentItemNode.getLocalName() != null) { - if (currentItemNode.getLocalName().equals("GlobalID")) { - if (currentItemNode.getAttributes().getNamedItem("schemeID") != null) { - SchemedID gid = new SchemedID().setScheme(currentItemNode.getAttributes().getNamedItem("schemeID").getNodeValue()).setId(currentItemNode.getTextContent()); - this.setSchemedID(gid); - } - } - if (currentItemNode.getLocalName().equals("TradingBusinessName")) { - setTradingBusinessName(currentItemNode.getFirstChild().getNodeValue()); - } - } - } - } - } + /*** + * XML parsing constructor + * @param nodes the nodelist returned e.g. from xpath + */ + public LegalOrganisation(NodeList nodes) { + if (nodes.getLength() > 0) { + /* + will parse sth like + + 4711 + Test GmbH & Co.KG + + */ + for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { + Node currentItemNode = nodes.item(nodeIndex); + if (currentItemNode.getLocalName() != null) { + if (currentItemNode.getLocalName().equals("GlobalID")) { + if (currentItemNode.getAttributes().getNamedItem("schemeID") != null) { + SchemedID gid = new SchemedID().setScheme(currentItemNode.getAttributes().getNamedItem("schemeID").getNodeValue()).setId(currentItemNode.getTextContent()); + this.setSchemedID(gid); + } + } + if (currentItemNode.getLocalName().equals("TradingBusinessName")) { + setTradingBusinessName(currentItemNode.getFirstChild().getNodeValue()); + } + } + } + } + } - @Override - public SchemedID getSchemedID() { - return this.schemedID; - } + @Override + public SchemedID getSchemedID() { + return this.schemedID; + } - @Override - public String getTradingBusinessName() { - return this.tradingBusinessName; - } + @Override + public String getTradingBusinessName() { + return this.tradingBusinessName; + } - public LegalOrganisation setSchemedID(SchemedID schemedID) { - this.schemedID = schemedID; - return this; - } + public LegalOrganisation setSchemedID(SchemedID schemedID) { + this.schemedID = schemedID; + return this; + } - public LegalOrganisation setTradingBusinessName(String tradingBusinessName) { - this.tradingBusinessName = tradingBusinessName; - return this; - } + public LegalOrganisation setTradingBusinessName(String tradingBusinessName) { + this.tradingBusinessName = tradingBusinessName; + return this; + } } diff --git a/library/src/main/java/org/mustangproject/Product.java b/library/src/main/java/org/mustangproject/Product.java index 4bbde40..bd168b4 100755 --- a/library/src/main/java/org/mustangproject/Product.java +++ b/library/src/main/java/org/mustangproject/Product.java @@ -7,14 +7,9 @@ org.openrewrite.config.CompositeRecipe 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; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /*** * describes a product, good or service used in an invoice item line @@ -23,375 +18,375 @@ @JsonInclude(JsonInclude.Include.NON_EMPTY) public class Product implements IZUGFeRDExportableProduct { - protected String unit, name, sellerAssignedID, buyerAssignedID; - protected String description = ""; - protected String taxExemptionReason = null; - protected String taxCategoryCode = null; - protected BigDecimal VATPercent; - protected boolean isReverseCharge = false; - protected boolean isIntraCommunitySupply = false; - protected SchemedID globalId = null; - protected String countryOfOrigin = null; - protected HashMap attributes = new HashMap<>(); + protected String unit, name, sellerAssignedID, buyerAssignedID; + protected String description = ""; + protected String taxExemptionReason = null; + protected String taxCategoryCode = null; + protected BigDecimal VATPercent; + protected boolean isReverseCharge = false; + protected boolean isIntraCommunitySupply = false; + protected SchemedID globalId = null; + protected String countryOfOrigin = null; + protected HashMap attributes = new HashMap<>(); - protected List classifications = new ArrayList<>(); + protected List classifications = new ArrayList<>(); - /*** - * default constructor - * @param name product short name - * @param description product long name - * @param unit a two/three letter UN/ECE rec 20 unit code, e.g. "C62" for piece - * @param VATPercent product vat rate - */ - public Product(String name, String description, String unit, BigDecimal VATPercent) { - this.unit = unit; - this.name = name; - this.description = description; - this.VATPercent = VATPercent; - } + /*** + * default constructor + * @param name product short name + * @param description product long name + * @param unit a two/three letter UN/ECE rec 20 unit code, e.g. "C62" for piece + * @param VATPercent product vat rate + */ + public Product(String name, String description, String unit, BigDecimal VATPercent) { + this.unit = unit; + this.name = name; + this.description = description; + this.VATPercent = VATPercent; + } - public Product(Node node) { - NodeMap nodeMap = new NodeMap(node); + public Product(Node node) { + NodeMap nodeMap = new NodeMap(node); - nodeMap.getNode("GlobalID").ifPresent(idNode -> { - if (idNode.hasAttributes() - && idNode.getAttributes().getNamedItem("schemeID") != null) { - globalId = new SchemedID() - .setScheme(idNode.getAttributes().getNamedItem("schemeID").getNodeValue()) - .setId(idNode.getTextContent()); - } - }); + nodeMap.getNode("GlobalID").ifPresent(idNode -> { + if (idNode.hasAttributes() + && idNode.getAttributes().getNamedItem("schemeID") != null) { + globalId = new SchemedID() + .setScheme(idNode.getAttributes().getNamedItem("schemeID").getNodeValue()) + .setId(idNode.getTextContent()); + } + }); - 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.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"); - if (key != null && value != null) { - if (attributes == null) { - attributes = new HashMap<>(); - } - attributes.put(key, value); - } - }); + nodeMap.getAsNodeMap("ApplicableProductCharacteristic").ifPresent(apcNodes -> { + String key = apcNodes.getAsStringOrNull("Description"); + String value = apcNodes.getAsStringOrNull("Value"); + if (key != null && value != null) { + if (attributes == null) { + attributes = new HashMap<>(); + } + attributes.put(key, value); + } + }); - //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); - } - }); + // 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))); - }); + 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 -> - 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 -> + classifications.add(new DesignatedProductClassification(classCode, className))); + }); - nodeMap.getAsString("OriginTradeCounty").ifPresent(this::setCountryOfOrigin); - } + nodeMap.getAsString("OriginTradeCounty").ifPresent(this::setCountryOfOrigin); + } - /*** - * empty constructor - * just for jackson etc - */ - public Product() { + /*** + * empty constructor + * just for jackson etc + */ + public Product() { - } + } - @Override - public String getGlobalID() { - if (globalId == null) { - return null; - } else { - return globalId.getID(); - } - } + @Override + public String getGlobalID() { + if (globalId == null) { + return null; + } else { + return globalId.getID(); + } + } - @Override - public String getGlobalIDScheme() { - if (globalId == null) { - return null; - } else { - return globalId.getScheme(); - } - } + @Override + public String getGlobalIDScheme() { + if (globalId == null) { + return null; + } else { + return globalId.getScheme(); + } + } - public Product addGlobalID(SchemedID schemedID) { - globalId = schemedID; - return this; - } + public Product addGlobalID(SchemedID schemedID) { + globalId = schemedID; + return this; + } - /*** - * - * @return e.g. intra-commnunity supply or small business - */ - @Override - public String getTaxExemptionReason() { - return taxExemptionReason; - } + /*** + * + * @return e.g. intra-commnunity supply or small business + */ + @Override + public String getTaxExemptionReason() { + return taxExemptionReason; + } - /*** - * - * @param taxExemptionReasonText String e.g. Kleinunternehmer gemäß §19 UStG https://github.com/ZUGFeRD/mustangproject/issues/463 - * @return fluent setter - */ - public Product setTaxExemptionReason(String taxExemptionReasonText) { - taxExemptionReason = taxExemptionReasonText; - return this; - } + /*** + * + * @param taxExemptionReasonText String e.g. Kleinunternehmer gemäß §19 UStG https://github.com/ZUGFeRD/mustangproject/issues/463 + * @return fluent setter + */ + public Product setTaxExemptionReason(String taxExemptionReasonText) { + taxExemptionReason = taxExemptionReasonText; + return this; + } - /*** - * - * @return e.g. S (normal tax), Z=zero rated, E (e.g. small business) or K (intrra community supply) - */ - @Override - public String getTaxCategoryCode() { - if (taxCategoryCode == null) { - return IZUGFeRDExportableProduct.super.getTaxCategoryCode(); - } - return taxCategoryCode; - } + /*** + * + * @return e.g. S (normal tax), Z=zero rated, E (e.g. small business) or K (intrra community supply) + */ + @Override + public String getTaxCategoryCode() { + if (taxCategoryCode == null) { + return IZUGFeRDExportableProduct.super.getTaxCategoryCode(); + } + return taxCategoryCode; + } - /*** - * - * @param code e.g. S (normal tax), Z=zero rated, E (e.g. small business) or K (intrra community supply) see also https://github.com/ZUGFeRD/mustangproject/issues/463 - * @return fluent setter - */ - public Product setTaxCategoryCode(String code) { - taxCategoryCode = code; - return this; - } + /*** + * + * @param code e.g. S (normal tax), Z=zero rated, E (e.g. small business) or K (intrra community supply) see also https://github.com/ZUGFeRD/mustangproject/issues/463 + * @return fluent setter + */ + public Product setTaxCategoryCode(String code) { + taxCategoryCode = code; + return this; + } - @Override - public String getSellerAssignedID() { - return sellerAssignedID; - } + @Override + public String getSellerAssignedID() { + return sellerAssignedID; + } - /*** - * how the seller identifies this type of product - * @param sellerAssignedID a unique String - * @return fluent setter - */ - public Product setSellerAssignedID(String sellerAssignedID) { - this.sellerAssignedID = sellerAssignedID; - return this; - } + /*** + * how the seller identifies this type of product + * @param sellerAssignedID a unique String + * @return fluent setter + */ + public Product setSellerAssignedID(String sellerAssignedID) { + this.sellerAssignedID = sellerAssignedID; + return this; + } - @Override - public String getBuyerAssignedID() { - return buyerAssignedID; - } + @Override + public String getBuyerAssignedID() { + return buyerAssignedID; + } - /*** - * if the buyer provided an ID how he refers to this product - * @param buyerAssignedID a string the buyer provided - * @return fluent setter - */ - public Product setBuyerAssignedID(String buyerAssignedID) { - this.buyerAssignedID = buyerAssignedID; - return this; - } + /*** + * if the buyer provided an ID how he refers to this product + * @param buyerAssignedID a string the buyer provided + * @return fluent setter + */ + public Product setBuyerAssignedID(String buyerAssignedID) { + this.buyerAssignedID = buyerAssignedID; + return this; + } - @Override - public boolean isReverseCharge() { - return isReverseCharge; - } + @Override + public boolean isReverseCharge() { + return isReverseCharge; + } - @Override - public boolean isIntraCommunitySupply() { - return isIntraCommunitySupply; - } + @Override + public boolean isIntraCommunitySupply() { + return isIntraCommunitySupply; + } - /*** - * sets reverse charge(=delivery to outside EU) - * @return fluent setter - */ - public Product setReverseCharge() { - isReverseCharge = true; - setVATPercent(BigDecimal.ZERO); - return this; - } + /*** + * sets reverse charge(=delivery to outside EU) + * @return fluent setter + */ + public Product setReverseCharge() { + isReverseCharge = true; + setVATPercent(BigDecimal.ZERO); + return this; + } - /*** - * sets intra community supply(=delivery outside the country inside the EU) - * @return fluent setter - */ - public Product setIntraCommunitySupply() { - isIntraCommunitySupply = true; - setVATPercent(BigDecimal.ZERO); - setTaxExemptionReason("Intra-community supply"); - setTaxCategoryCode("K"); - return this; - } + /*** + * sets intra community supply(=delivery outside the country inside the EU) + * @return fluent setter + */ + public Product setIntraCommunitySupply() { + isIntraCommunitySupply = true; + setVATPercent(BigDecimal.ZERO); + setTaxExemptionReason("Intra-community supply"); + setTaxCategoryCode("K"); + return this; + } - @Override - public String getUnit() { - return unit; - } + @Override + public String getUnit() { + return unit; + } - /*** - * sets a UN/ECE rec 20 or 21 code which unit the product ships in, e.g. C62=piece - * @param unit 2-3 letter UN/ECE rec 20 or 21 - * @return fluent setter - */ - public Product setUnit(String unit) { - this.unit = unit; - return this; - } + /*** + * sets a UN/ECE rec 20 or 21 code which unit the product ships in, e.g. C62=piece + * @param unit 2-3 letter UN/ECE rec 20 or 21 + * @return fluent setter + */ + public Product setUnit(String unit) { + this.unit = unit; + return this; + } - @Override - public String getName() { - return name; - } + @Override + public String getName() { + return name; + } - /** - * name of the product - * - * @param name short name - * @return fluent setter - */ - public Product setName(String name) { - this.name = name; - return this; - } + /** + * name of the product + * + * @param name short name + * @return fluent setter + */ + public Product setName(String name) { + this.name = name; + return this; + } - @Override - public String getDescription() { - return description; - } + @Override + public String getDescription() { + return description; + } - /** - * description of the product (required) - * - * @param description long name - * @return fluent setter - */ - public Product setDescription(String description) { - this.description = description; - return this; - } + /** + * description of the product (required) + * + * @param description long name + * @return fluent setter + */ + public Product setDescription(String description) { + this.description = description; + return this; + } - @Override - public BigDecimal getVATPercent() { - return VATPercent; - } + @Override + public BigDecimal getVATPercent() { + return VATPercent; + } - /**** - * VAT rate of the product - * @param VATPercent vat rate of the product - * @return fluent setter - */ - public Product setVATPercent(BigDecimal VATPercent) { - if (VATPercent == null) { - this.VATPercent = BigDecimal.ZERO; - } else { - this.VATPercent = VATPercent; - } - return this; - } + /**** + * VAT rate of the product + * @param VATPercent vat rate of the product + * @return fluent setter + */ + public Product setVATPercent(BigDecimal VATPercent) { + if (VATPercent == null) { + this.VATPercent = BigDecimal.ZERO; + } else { + this.VATPercent = VATPercent; + } + return this; + } - @Override - public String getCountryOfOrigin() { - return this.countryOfOrigin; - } + @Override + public String getCountryOfOrigin() { + return this.countryOfOrigin; + } - public Product setCountryOfOrigin(String countryOfOrigin) { - this.countryOfOrigin = countryOfOrigin; - return this; - } + public Product setCountryOfOrigin(String countryOfOrigin) { + this.countryOfOrigin = countryOfOrigin; + return this; + } - @Override - public HashMap getAttributes() { - if (attributes.isEmpty()) { - return null; - } else { - return this.attributes; - } - } + @Override + public HashMap getAttributes() { + if (attributes.isEmpty()) { + return null; + } else { + return this.attributes; + } + } - public Product setAttributes(Map attributes) { - this.attributes.clear(); - if (attributes != null) { - this.attributes.putAll(attributes); - } - return this; - } + public Product setAttributes(Map attributes) { + this.attributes.clear(); + if (attributes != null) { + this.attributes.putAll(attributes); + } + return this; + } - public Product addAttribute(String name, String value) { - this.attributes.put(name, value); - return this; - } + public Product addAttribute(String name, String value) { + this.attributes.put(name, value); + return this; + } - @Override - public IDesignatedProductClassification[] getClassifications() { - if (classifications.isEmpty()) { - return null; - } else { - return classifications.toArray(new IDesignatedProductClassification[0]); - } - } + @Override + public IDesignatedProductClassification[] getClassifications() { + if (classifications.isEmpty()) { + return null; + } else { + return classifications.toArray(new IDesignatedProductClassification[0]); + } + } - /** - * Replace the current set of {@link IDesignatedProductClassification}s with a new set - * - * @param classifications the new set of classifications - * @return the modified object - */ - public Product setClassifications(IDesignatedProductClassification[] classifications) { - this.classifications.clear(); - if (classifications != null) { - this.classifications.addAll(Arrays.asList(classifications)); - } - return this; - } + /** + * Replace the current set of {@link IDesignatedProductClassification}s with a new set + * + * @param classifications the new set of classifications + * @return the modified object + */ + public Product setClassifications(IDesignatedProductClassification[] classifications) { + this.classifications.clear(); + if (classifications != null) { + this.classifications.addAll(Arrays.asList(classifications)); + } + return this; + } - /** - * Provide Jackson a hint as to use DesignatedProductClassification for the - * IDesignatedProductClassification product classifications - * - * @param classifications the new set of classifications - * @return fluent setter - */ - @JsonSetter("classifications") - public Product setClassificationsClass(DesignatedProductClassification[] classifications) { - this.classifications.clear(); - if (classifications != null) { - this.classifications.addAll(Arrays.asList(classifications)); - } - return this; - } + /** + * Provide Jackson a hint as to use DesignatedProductClassification for the + * IDesignatedProductClassification product classifications + * + * @param classifications the new set of classifications + * @return fluent setter + */ + @JsonSetter("classifications") + public Product setClassificationsClass(DesignatedProductClassification[] classifications) { + this.classifications.clear(); + if (classifications != null) { + this.classifications.addAll(Arrays.asList(classifications)); + } + return this; + } - /** - * Add a {@link IDesignatedProductClassification} classification - * - * @param classification the classification - * @return the modified object - */ - public Product addClassification(IDesignatedProductClassification classification) { - this.classifications.add(classification); - return this; - } + /** + * Add a {@link IDesignatedProductClassification} classification + * + * @param classification the classification + * @return the modified object + */ + public Product addClassification(IDesignatedProductClassification classification) { + this.classifications.add(classification); + return this; + } } diff --git a/library/src/main/java/org/mustangproject/ReferencedDocument.java b/library/src/main/java/org/mustangproject/ReferencedDocument.java index 9255017..0b8ca40 100755 --- a/library/src/main/java/org/mustangproject/ReferencedDocument.java +++ b/library/src/main/java/org/mustangproject/ReferencedDocument.java @@ -10,68 +10,68 @@ org.openrewrite.config.CompositeRecipe @JsonInclude(JsonInclude.Include.NON_EMPTY) public class ReferencedDocument implements IReferencedDocument { - String issuerAssignedID; - String typeCode; - String referenceTypeCode; + String issuerAssignedID; + String typeCode; + String referenceTypeCode; - public ReferencedDocument(String issuerAssignedID, String typeCode, String referenceTypeCode) { - this.issuerAssignedID = issuerAssignedID; - this.typeCode = typeCode; - this.referenceTypeCode = referenceTypeCode; - } + public ReferencedDocument(String issuerAssignedID, String typeCode, String referenceTypeCode) { + this.issuerAssignedID = issuerAssignedID; + this.typeCode = typeCode; + this.referenceTypeCode = referenceTypeCode; + } - public ReferencedDocument(String issuerAssignedID, String referenceTypeCode) { - this.issuerAssignedID = issuerAssignedID; - this.typeCode = "916"; // additional invoice related document - this.referenceTypeCode = referenceTypeCode; - } + public ReferencedDocument(String issuerAssignedID, String referenceTypeCode) { + this.issuerAssignedID = issuerAssignedID; + this.typeCode = "916"; // additional invoice related document + this.referenceTypeCode = referenceTypeCode; + } /*** - * sets an ID assigned by the sender - * @param issuerAssignedID the ID as a string :-) - */ - public void setIssuerAssignedID(String issuerAssignedID) { - this.issuerAssignedID = issuerAssignedID; - } + * sets an ID assigned by the sender + * @param issuerAssignedID the ID as a string :-) + */ + public void setIssuerAssignedID(String issuerAssignedID) { + this.issuerAssignedID = issuerAssignedID; + } - /** - * which type is the document? e.g. "916" for additional invoice related - * @param typeCode as String, e.g. 916 - */ - public void setTypeCode(String typeCode) { - this.typeCode = typeCode; - } + /** + * which type is the document? e.g. "916" for additional invoice related + * @param typeCode as String, e.g. 916 + */ + public void setTypeCode(String typeCode) { + this.typeCode = typeCode; + } - /** - * type of the reference of this line, a UNTDID 1153 code - * @param referenceTypeCode three uppercase character reference type code as string - */ - public void setReferenceTypeCode(String referenceTypeCode) { - this.referenceTypeCode = referenceTypeCode; - } + /** + * type of the reference of this line, a UNTDID 1153 code + * @param referenceTypeCode three uppercase character reference type code as string + */ + public void setReferenceTypeCode(String referenceTypeCode) { + this.referenceTypeCode = referenceTypeCode; + } - @Override - public String getIssuerAssignedID() { - return issuerAssignedID; - } + @Override + public String getIssuerAssignedID() { + return issuerAssignedID; + } - @Override - public String getTypeCode() { - return typeCode; - } + @Override + public String getTypeCode() { + return typeCode; + } - @Override - public String getReferenceTypeCode() { - return referenceTypeCode; - } + @Override + public String getReferenceTypeCode() { + return referenceTypeCode; + } - public static ReferencedDocument fromNode(Node node) { - if (!node.hasChildNodes()) { - return null; - } - NodeMap nodes = new NodeMap(node); - return new ReferencedDocument(nodes.getAsStringOrNull("IssuerAssignedID", "ID"), - nodes.getAsStringOrNull("TypeCode", "DocumentTypeCode"), - nodes.getAsStringOrNull("ReferenceTypeCode")); - } + public static ReferencedDocument fromNode(Node node) { + if (!node.hasChildNodes()) { + return null; + } + NodeMap nodes = new NodeMap(node); + return new ReferencedDocument(nodes.getAsStringOrNull("IssuerAssignedID", "ID"), + nodes.getAsStringOrNull("TypeCode", "DocumentTypeCode"), + nodes.getAsStringOrNull("ReferenceTypeCode")); + } } diff --git a/library/src/main/java/org/mustangproject/SchemedID.java b/library/src/main/java/org/mustangproject/SchemedID.java index 6cbac0e..7cb6d57 100755 --- a/library/src/main/java/org/mustangproject/SchemedID.java +++ b/library/src/main/java/org/mustangproject/SchemedID.java @@ -7,39 +7,39 @@ org.openrewrite.config.CompositeRecipe @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_EMPTY) public class SchemedID { - protected String scheme; - protected String id; + protected String scheme; + protected String id; - public String getScheme() { - return scheme; - } + public String getScheme() { + return scheme; + } - public SchemedID setScheme(String scheme) { - this.scheme = scheme; - return this; - } + public SchemedID setScheme(String scheme) { + this.scheme = scheme; + return this; + } - public String getID() { - return id; - } + public String getID() { + return id; + } - public SchemedID setId(String id) { - this.id = id; - return this; - } + public SchemedID setId(String id) { + this.id = id; + return this; + } - public SchemedID() { + public SchemedID() { - } + } - public SchemedID(String scheme, String id) { - setScheme(scheme); - setId(id); - } + public SchemedID(String scheme, String id) { + setScheme(scheme); + setId(id); + } - @Override - public String toString() { - return "SchemedID{scheme='" + scheme + "', id='" + id + "'}"; - } + @Override + public String toString() { + return "SchemedID{scheme='" + scheme + "', id='" + id + "'}"; + } } diff --git a/library/src/main/java/org/mustangproject/SubjectCode.java b/library/src/main/java/org/mustangproject/SubjectCode.java index 808c09d..8c61e13 100755 --- a/library/src/main/java/org/mustangproject/SubjectCode.java +++ b/library/src/main/java/org/mustangproject/SubjectCode.java @@ -5,40 +5,40 @@ org.openrewrite.config.CompositeRecipe * In the first step only the recommended codes are implemented. */ public enum SubjectCode { - /** - * general information - */ - AAI, - /** - * seller notes - */ - SUR, - /** - * regulatory information - */ - REG, - /** - * legal information - */ - ABL, - /** - * tax information - */ - TXD, - /** - * Customs information - */ - CUS, - /** - * introduction - */ - ACY, - /** - * Discount and bonus agreements - */ - AAK, - /** - * Vehicle licence number - */ - ABZ + /** + * general information + */ + AAI, + /** + * seller notes + */ + SUR, + /** + * regulatory information + */ + REG, + /** + * legal information + */ + ABL, + /** + * tax information + */ + TXD, + /** + * Customs information + */ + CUS, + /** + * introduction + */ + ACY, + /** + * Discount and bonus agreements + */ + AAK, + /** + * Vehicle licence number + */ + ABZ } diff --git a/library/src/main/java/org/mustangproject/TradeParty.java b/library/src/main/java/org/mustangproject/TradeParty.java index 73b1ae8..940a739 100755 --- a/library/src/main/java/org/mustangproject/TradeParty.java +++ b/library/src/main/java/org/mustangproject/TradeParty.java @@ -1,11 +1,7 @@ org.openrewrite.config.CompositeRecipe 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; - +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTradeParty; @@ -14,8 +10,10 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; /*** @@ -25,790 +23,789 @@ @JsonInclude(JsonInclude.Include.NON_EMPTY) public class TradeParty implements IZUGFeRDExportableTradeParty { - protected String name, zip, street, location, country, taxScheme; - protected String taxID = null, vatID = null; - protected String ID = null; - protected String description = null; - protected String additionalAddress = null; - protected String additionalAddressExtension = null; - protected List bankDetails = new ArrayList<>(); - protected List debitDetails = new ArrayList<>(); - protected Contact contact = null; - protected LegalOrganisation legalOrg = null; - protected SchemedID globalId = null; - protected SchemedID uriUniversalCommunicationId = null; //e.g. the email address of the organization + protected String name, zip, street, location, country, taxScheme; + protected String taxID = null, vatID = null; + protected String ID = null; + protected String description = null; + protected String additionalAddress = null; + protected String additionalAddressExtension = null; + protected List bankDetails = new ArrayList<>(); + protected List debitDetails = new ArrayList<>(); + protected Contact contact = null; + protected LegalOrganisation legalOrg = null; + protected SchemedID globalId = null; + protected SchemedID uriUniversalCommunicationId = null; // e.g. the email address of the organization - /** - * Default constructor. - * Probably a bad idea but might be needed by jackson or similar - */ - public TradeParty() { + /** + * Default constructor. + * Probably a bad idea but might be needed by jackson or similar + */ +public TradeParty() { - } + } - /*** - * - * @param name of the company - * @param street street and number (use setAdditionalAddress for more parts) - * @param zip postcode of the company - * @param location city of the company - * @param country two letter ISO code - */ - public TradeParty(String name, String street, String zip, String location, String country) { - this.name = name; - this.street = street; - this.zip = zip; - this.location = location; - this.country = country; + /*** + * + * @param name of the company + * @param street street and number (use setAdditionalAddress for more parts) + * @param zip postcode of the company + * @param location city of the company + * @param country two letter ISO code + */ + public TradeParty(String name, String street, String zip, String location, String country) { + this.name = name; + this.street = street; + this.zip = zip; + this.location = location; + this.country = country; - } + } - protected void parseFromUBL(NodeList nodes) { - if (nodes.getLength() > 0) { + protected void parseFromUBL(NodeList nodes) { + if (nodes.getLength() > 0) { - for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { - //nodes.item(i).getTextContent())) { - Node currentItemNode = nodes.item(nodeIndex); + for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { + // nodes.item(i).getTextContent())) { + Node currentItemNode = nodes.item(nodeIndex); - if (currentItemNode.getLocalName() != null) { - String currentUBLChild = currentItemNode.getLocalName(); -// 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 (currentItemNode.getLocalName() != null) { + String currentUBLChild = currentItemNode.getLocalName(); +// 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) { - String currentTopElementName = party.item(partyIndex).getLocalName(); - if (currentTopElementName.equals("PartyName")) { + if (currentUBLChild.equals("Party")) { + NodeList party = currentItemNode.getChildNodes(); + for (int partyIndex = 0; partyIndex < party.getLength(); partyIndex++) { + if (party.item(partyIndex).getLocalName() != null) { + String currentTopElementName = party.item(partyIndex).getLocalName(); + if (currentTopElementName.equals("PartyName")) { - NodeList partyName = party.item(partyIndex).getChildNodes(); - for (int partyNameIndex = 0; partyNameIndex < partyName.getLength(); partyNameIndex++) { - if (partyName.item(partyNameIndex).getLocalName() != null) { + NodeList partyName = party.item(partyIndex).getChildNodes(); + for (int partyNameIndex = 0; partyNameIndex < partyName.getLength(); partyNameIndex++) { + if (partyName.item(partyNameIndex).getLocalName() != null) { - if (partyName.item(partyNameIndex).getLocalName().equals("Name")) { - setName(partyName.item(partyNameIndex).getTextContent()); - } + if (partyName.item(partyNameIndex).getLocalName().equals("Name")) { + setName(partyName.item(partyNameIndex).getTextContent()); + } - } - } - } - 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 (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("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); + } + 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()); - } + } 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(); + 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); + } + } + } + } + } - } - } + } + } - /* - UBL only: formally it can have a name as well but BT27 party name *should* be stored in - so overwrite if one exists - */ + /* + UBL only: formally it can have a name as well but BT27 party name *should* be stored in + so overwrite if one exists + */ - 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 (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")) { - 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 (legal.item(legalChildIndex).getLocalName().equals("RegistrationName")) { + 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")) { + if (currentTopElementName.equals("PostalAddress")) { - NodeList postal = party.item(partyIndex).getChildNodes(); - for (int postalChildIndex = 0; postalChildIndex < postal.getLength(); postalChildIndex++) { - if (postal.item(postalChildIndex).getLocalName() != null) { + NodeList postal = party.item(partyIndex).getChildNodes(); + for (int postalChildIndex = 0; postalChildIndex < postal.getLength(); postalChildIndex++) { + if (postal.item(postalChildIndex).getLocalName() != null) { - if (postal.item(postalChildIndex).getLocalName().equals("StreetName")) { - setStreet(postal.item(postalChildIndex).getTextContent()); - } - if (postal.item(postalChildIndex).getLocalName().equals("AdditionalStreetName")) { - setAdditionalAddress(postal.item(postalChildIndex).getTextContent()); - } - //unknow correspondence if (postal.item(postalChildIndex).getLocalName().equals("LineThree")) { + if (postal.item(postalChildIndex).getLocalName().equals("StreetName")) { + setStreet(postal.item(postalChildIndex).getTextContent()); + } + if (postal.item(postalChildIndex).getLocalName().equals("AdditionalStreetName")) { + setAdditionalAddress(postal.item(postalChildIndex).getTextContent()); + } + // unknow correspondence if (postal.item(postalChildIndex).getLocalName().equals("LineThree")) { - if (postal.item(postalChildIndex).getLocalName().equals("CityName")) { - setLocation(postal.item(postalChildIndex).getTextContent()); - } - if (postal.item(postalChildIndex).getLocalName().equals("PostalZone")) { - setZIP(postal.item(postalChildIndex).getTextContent()); - } - if (postal.item(postalChildIndex).getLocalName().equals("Country")) { - NodeList country = postal.item(postalChildIndex).getChildNodes(); - for (int countryIndex = 0; countryIndex < country.getLength(); countryIndex++) { - if (country.item(countryIndex).getLocalName() != null) { + if (postal.item(postalChildIndex).getLocalName().equals("CityName")) { + setLocation(postal.item(postalChildIndex).getTextContent()); + } + if (postal.item(postalChildIndex).getLocalName().equals("PostalZone")) { + setZIP(postal.item(postalChildIndex).getTextContent()); + } + if (postal.item(postalChildIndex).getLocalName().equals("Country")) { + NodeList country = postal.item(postalChildIndex).getChildNodes(); + for (int countryIndex = 0; countryIndex < country.getLength(); countryIndex++) { + if (country.item(countryIndex).getLocalName() != null) { - if (country.item(countryIndex).getLocalName().equals("IdentificationCode")) { - setCountry(country.item(countryIndex).getTextContent()); - } + if (country.item(countryIndex).getLocalName().equals("IdentificationCode")) { + setCountry(country.item(countryIndex).getTextContent()); + } - } - } + } + } - } + } - if (postal.item(postalChildIndex).getLocalName().equals("AddressLine")) { - NodeList AddressLine = postal.item(postalChildIndex).getChildNodes(); - for (int lineIndex = 0; lineIndex < AddressLine.getLength(); lineIndex++) { - if (AddressLine.item(lineIndex).getLocalName() != null) { + if (postal.item(postalChildIndex).getLocalName().equals("AddressLine")) { + NodeList AddressLine = postal.item(postalChildIndex).getChildNodes(); + for (int lineIndex = 0; lineIndex < AddressLine.getLength(); lineIndex++) { + if (AddressLine.item(lineIndex).getLocalName() != null) { - if (AddressLine.item(lineIndex).getLocalName().equals("Line")) { - setAdditionalAddressExtension(AddressLine.item(lineIndex).getTextContent()); - } + if (AddressLine.item(lineIndex).getLocalName().equals("Line")) { + setAdditionalAddressExtension(AddressLine.item(lineIndex).getTextContent()); + } - } - } - } - if (postal.item(postalChildIndex).getLocalName().equals("Name")) { - setName(postal.item(postalChildIndex).getTextContent()); - } + } + } + } + if (postal.item(postalChildIndex).getLocalName().equals("Name")) { + setName(postal.item(postalChildIndex).getTextContent()); + } - } - } - } + } + } + } - if (currentTopElementName.equals("Contact")) { - NodeList contact = party.item(partyIndex).getChildNodes(); - setContact(new Contact(contact)); + if (currentTopElementName.equals("Contact")) { + NodeList contact = party.item(partyIndex).getChildNodes(); + setContact(new Contact(contact)); - } - } - } + } + } + } - } + } - if (currentUBLChild.equals("GlobalID")) { - if (nodes.item(nodeIndex).getAttributes().getNamedItem("schemeID") != null) { - SchemedID gid = new SchemedID().setScheme(nodes.item(nodeIndex).getAttributes().getNamedItem("schemeID").getNodeValue()).setId(nodes.item(nodeIndex).getTextContent()); - addGlobalID(gid); - } + if (currentUBLChild.equals("GlobalID")) { + if (nodes.item(nodeIndex).getAttributes().getNamedItem("schemeID") != null) { + SchemedID gid = new SchemedID().setScheme(nodes.item(nodeIndex).getAttributes().getNamedItem("schemeID").getNodeValue()).setId(nodes.item(nodeIndex).getTextContent()); + addGlobalID(gid); + } - } - if (currentUBLChild.equals("DefinedTradeContact")) { - NodeList contact = nodes.item(nodeIndex).getChildNodes(); - setContact(new Contact(contact)); - } - } - } - } + } + if (currentUBLChild.equals("DefinedTradeContact")) { + NodeList contact = nodes.item(nodeIndex).getChildNodes(); + setContact(new Contact(contact)); + } + } + } + } - } + } - /*** - * XML parsing constructor - * @param nodes the nodelist returned e.g. from xpath - */ - public TradeParty(NodeList nodes) { -/** - * CII would be sth like - * - * LIEF-987654321 - * Max Mustermann IT GmbH - * - * Herr Treudiener - * - * +49 1234-98765-12 - * - * - * treudiener@max-mustermann-it.de - * - * - * - * 12345 - * Musterstraße 1 - * Musterstadt - * DE - * - * - * DE123456789 - * - * - * while UBL may be - * - * - * - * Theodor Est - * - * - * Bahnstr. 42 - * Hinterhaus - * Spielkreis - * 88802 - * - * Zweiter Stock - * - * - * DE - * - * - * - * DE999999999 - * - * VAT - * - * - * - * Theodor Est - * - * - * - * - * */ - if (nodes.getLength() > 0) { + /*** + * XML parsing constructor + * @param nodes the nodelist returned e.g. from xpath + */ + public TradeParty(NodeList nodes) { + /** + * CII would be sth like + * + * LIEF-987654321 + * Max Mustermann IT GmbH + * + * Herr Treudiener + * + * +49 1234-98765-12 + * + * + * treudiener@max-mustermann-it.de + * + * + * + * 12345 + * Musterstraße 1 + * Musterstadt + * DE + * + * + * DE123456789 + * + * + * while UBL may be + * + * + * + * Theodor Est + * + * + * Bahnstr. 42 + * Hinterhaus + * Spielkreis + * 88802 + * + * Zweiter Stock + * + * + * DE + * + * + * + * DE999999999 + * + * VAT + * + * + * + * Theodor Est + * + * + * + * + * */ + if (nodes.getLength() > 0) { - for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { - //nodes.item(i).getTextContent())) { - String topElementName = nodes.item(nodeIndex).getLocalName(); - if (topElementName.equals("Party")) { - // take one step back and parse from top - parseFromUBL(nodes); - return; - } - Node currentItemNode = nodes.item(nodeIndex); - NodeList itemChilds = currentItemNode.getChildNodes(); - for (int itemChildIndex = 0; itemChildIndex < itemChilds.getLength(); itemChildIndex++) { - if (itemChilds.item(itemChildIndex).getLocalName() != null) { - if (itemChilds.item(itemChildIndex).getLocalName().equals("ID")) { - setID(itemChilds.item(itemChildIndex).getTextContent()); - } - if (itemChilds.item(itemChildIndex).getLocalName().equals("Name")) { - setName(itemChilds.item(itemChildIndex).getTextContent()); - } + for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) { + // nodes.item(i).getTextContent())) { + String topElementName = nodes.item(nodeIndex).getLocalName(); + if (topElementName.equals("Party")) { + // take one step back and parse from top + parseFromUBL(nodes); + return; + } + Node currentItemNode = nodes.item(nodeIndex); + NodeList itemChilds = currentItemNode.getChildNodes(); + for (int itemChildIndex = 0; itemChildIndex < itemChilds.getLength(); itemChildIndex++) { + if (itemChilds.item(itemChildIndex).getLocalName() != null) { + if (itemChilds.item(itemChildIndex).getLocalName().equals("ID")) { + setID(itemChilds.item(itemChildIndex).getTextContent()); + } + if (itemChilds.item(itemChildIndex).getLocalName().equals("Name")) { + setName(itemChilds.item(itemChildIndex).getTextContent()); + } - if (itemChilds.item(itemChildIndex).getLocalName().equals("Description")) { - setDescription(itemChilds.item(itemChildIndex).getTextContent()); - } - if (itemChilds.item(itemChildIndex).getLocalName().equals("GlobalID")) { - if (itemChilds.item(itemChildIndex).getAttributes().getNamedItem("schemeID") != null) { - SchemedID gid = new SchemedID().setScheme(itemChilds.item(itemChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue()).setId(itemChilds.item(itemChildIndex).getTextContent()); - addGlobalID(gid); - } - } - if (itemChilds.item(itemChildIndex).getLocalName().equals("SpecifiedLegalOrganization")) { - NodeList organization = itemChilds.item(itemChildIndex).getChildNodes(); - setLegalOrganisation(new LegalOrganisation(organization)); - } - if (itemChilds.item(itemChildIndex).getLocalName().equals("DefinedTradeContact")) { - NodeList contact = itemChilds.item(itemChildIndex).getChildNodes(); - setContact(new Contact(contact)); - } - if (itemChilds.item(itemChildIndex).getLocalName().equals("PostalTradeAddress")) { - NodeList postal = itemChilds.item(itemChildIndex).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 (itemChilds.item(itemChildIndex).getLocalName().equals("URIUniversalCommunication")) { - NodeList URIchilds = itemChilds.item(itemChildIndex).getChildNodes(); - for (int URIChildIndex = 0; URIChildIndex < URIchilds.getLength(); URIChildIndex++) { - Node currentNode = URIchilds.item(URIChildIndex); - if ((currentNode.getLocalName() != null) && (currentNode.getLocalName().equals("URIID") - && - (currentNode.getAttributes().getNamedItem("schemeID") != null)) - && (URIchilds.item(URIChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("EM")) - ) { - setEmail(currentNode.getTextContent()); - } - } - } + if (itemChilds.item(itemChildIndex).getLocalName().equals("Description")) { + setDescription(itemChilds.item(itemChildIndex).getTextContent()); + } + if (itemChilds.item(itemChildIndex).getLocalName().equals("GlobalID")) { + if (itemChilds.item(itemChildIndex).getAttributes().getNamedItem("schemeID") != null) { + SchemedID gid = new SchemedID().setScheme(itemChilds.item(itemChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue()).setId(itemChilds.item(itemChildIndex).getTextContent()); + addGlobalID(gid); + } + } + if (itemChilds.item(itemChildIndex).getLocalName().equals("SpecifiedLegalOrganization")) { + NodeList organization = itemChilds.item(itemChildIndex).getChildNodes(); + setLegalOrganisation(new LegalOrganisation(organization)); + } + if (itemChilds.item(itemChildIndex).getLocalName().equals("DefinedTradeContact")) { + NodeList contact = itemChilds.item(itemChildIndex).getChildNodes(); + setContact(new Contact(contact)); + } + if (itemChilds.item(itemChildIndex).getLocalName().equals("PostalTradeAddress")) { + NodeList postal = itemChilds.item(itemChildIndex).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 (itemChilds.item(itemChildIndex).getLocalName().equals("URIUniversalCommunication")) { + NodeList URIchilds = itemChilds.item(itemChildIndex).getChildNodes(); + for (int URIChildIndex = 0; URIChildIndex < URIchilds.getLength(); URIChildIndex++) { + Node currentNode = URIchilds.item(URIChildIndex); + if ((currentNode.getLocalName() != null) && (currentNode.getLocalName().equals("URIID") + && + (currentNode.getAttributes().getNamedItem("schemeID") != null)) + && (URIchilds.item(URIChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("EM")) + ) { + setEmail(currentNode.getTextContent()); + } + } + } - if (itemChilds.item(itemChildIndex).getLocalName().equals("SpecifiedTaxRegistration")) { - NodeList taxChilds = itemChilds.item(itemChildIndex).getChildNodes(); - for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) { - if (taxChilds.item(taxChildIndex).getLocalName() != null) { - if ((taxChilds.item(taxChildIndex).getLocalName().equals("ID"))) { - if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID") != null) { - Node firstChild = taxChilds.item(taxChildIndex).getFirstChild(); - if (firstChild != null) { - if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("VA")) { - setVATID(firstChild.getNodeValue()); - } - if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("FC")) { - setTaxID(firstChild.getNodeValue()); - } - } - } - } - } - } - } - } - } - } - } - } + if (itemChilds.item(itemChildIndex).getLocalName().equals("SpecifiedTaxRegistration")) { + NodeList taxChilds = itemChilds.item(itemChildIndex).getChildNodes(); + for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) { + if (taxChilds.item(taxChildIndex).getLocalName() != null) { + if (taxChilds.item(taxChildIndex).getLocalName().equals("ID")) { + if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID") != null) { + Node firstChild = taxChilds.item(taxChildIndex).getFirstChild(); + if (firstChild != null) { + if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("VA")) { + setVATID(firstChild.getNodeValue()); + } + if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("FC")) { + setTaxID(firstChild.getNodeValue()); + } + } + } + } + } + } + } + } + } + } + } + } - @Override - public String getID() { - return ID; - } + @Override + public String getID() { + return ID; + } - @Override - public String getGlobalID() { - if (globalId != null) { - return globalId.getID(); - } - return null; - } + @Override + public String getGlobalID() { + if (globalId != null) { + return globalId.getID(); + } + return null; + } - @Override - public String getGlobalIDScheme() { - if (globalId != null) { - return globalId.getScheme(); - } - return null; + @Override + public String getGlobalIDScheme() { + if (globalId != null) { + return globalId.getScheme(); + } + return null; - } + } - @Override - @JsonIgnore - public String getUriUniversalCommunicationID() { - if (uriUniversalCommunicationId != null) { - return uriUniversalCommunicationId.getID(); - } - return null; - } + @Override + @JsonIgnore + public String getUriUniversalCommunicationID() { + if (uriUniversalCommunicationId != null) { + return uriUniversalCommunicationId.getID(); + } + return null; + } - @Override - @JsonIgnore - public String getUriUniversalCommunicationIDScheme() { - if (uriUniversalCommunicationId != null) { - return uriUniversalCommunicationId.getScheme(); - } - return null; + @Override + @JsonIgnore + public String getUriUniversalCommunicationIDScheme() { + if (uriUniversalCommunicationId != null) { + return uriUniversalCommunicationId.getScheme(); + } + return null; - } + } - /*** - * sets the email of the organization (not the one of the contact person) - * (while setEmail has to be defined here getEmail comes from IZUGFeRDExportableTradeParty) - * @param eMail address of institution (not contact) - * @return fluent setter - */ - public TradeParty setEmail(String eMail) { - SchemedID theSchemedID = new SchemedID("EM", eMail); - addUriUniversalCommunicationID(theSchemedID); - return this; - } + /*** + * sets the email of the organization (not the one of the contact person) + * (while setEmail has to be defined here getEmail comes from IZUGFeRDExportableTradeParty) + * @param eMail address of institution (not contact) + * @return fluent setter + */ + public TradeParty setEmail(String eMail) { + SchemedID theSchemedID = new SchemedID("EM", eMail); + addUriUniversalCommunicationID(theSchemedID); + return this; + } - /** - * if it's a customer, this can e.g. be the customer ID - * - * @param ID customer/seller number - * @return fluent setter - */ - public TradeParty setID(String ID) { - this.ID = ID; - return this; - } + /** + * if it's a customer, this can e.g. be the customer ID + * + * @param ID customer/seller number + * @return fluent setter + */ + public TradeParty setID(String ID) { + this.ID = ID; + return this; + } - /*** - * (optional) a named contact person - * @see Contact - * @param c the named contact person - * @return fluent setter - */ - public TradeParty setContact(Contact c) { - this.contact = c; - return this; - } + /*** + * (optional) a named contact person + * @see Contact + * @param c the named contact person + * @return fluent setter + */ + public TradeParty setContact(Contact c) { + this.contact = c; + return this; + } - public TradeParty addGlobalID(SchemedID schemedID) { - globalId = schemedID; - return this; - } + public TradeParty addGlobalID(SchemedID schemedID) { + globalId = schemedID; + return this; + } - public TradeParty addUriUniversalCommunicationID(SchemedID schemedID) { - uriUniversalCommunicationId = schemedID; - return this; - } + public TradeParty addUriUniversalCommunicationID(SchemedID schemedID) { + uriUniversalCommunicationId = schemedID; + return this; + } - /*** - * required (for senders, if payment is not debit): the BIC and IBAN - * @param s bank credentials - * @return fluent setter - */ - public TradeParty addBankDetails(BankDetails s) { - bankDetails.add(s); - return this; - } + /*** + * required (for senders, if payment is not debit): the BIC and IBAN + * @param s bank credentials + * @return fluent setter + */ + public TradeParty addBankDetails(BankDetails s) { + bankDetails.add(s); + return this; + } - /** - * (optional) - * - * @param debitDetail e.g. containing IBAN and mandate - * @return fluent setter - */ - public TradeParty addDebitDetails(DirectDebit debitDetail) { - debitDetails.add(debitDetail); - return this; - } + /** + * (optional) + * + * @param debitDetail e.g. containing IBAN and mandate + * @return fluent setter + */ + public TradeParty addDebitDetails(DirectDebit debitDetail) { + debitDetails.add(debitDetail); + return this; + } - /** - * primarily for invoiceimporter and JSON - * - * @return the list of sepa mandates - */ - public List getDebitDetails() { - return debitDetails; - } + /** + * primarily for invoiceimporter and JSON + * + * @return the list of sepa mandates + */ + public List getDebitDetails() { + return debitDetails; + } - @Override - public IZUGFeRDLegalOrganisation getLegalOrganisation() { - return legalOrg; - } + @Override + public IZUGFeRDLegalOrganisation getLegalOrganisation() { + return legalOrg; + } - public TradeParty setLegalOrganisation(LegalOrganisation legalOrganisation) { - legalOrg = legalOrganisation; - return this; - } + public TradeParty setLegalOrganisation(LegalOrganisation legalOrganisation) { + legalOrg = legalOrganisation; + return this; + } - public List getBankDetails() { - return bankDetails; - } + public List getBankDetails() { + return bankDetails; + } - /*** - * a general tax ID - * @param taxID tax number of the organisation - * @return fluent setter - */ - public TradeParty addTaxID(String taxID) { - this.taxID = taxID; - return this; - } + /*** + * a general tax ID + * @param taxID tax number of the organisation + * @return fluent setter + */ + public TradeParty addTaxID(String taxID) { + this.taxID = taxID; + return this; + } - /*** - * the USt-ID - * @param vatID Ust-ID - * @return fluent setter - */ - public TradeParty addVATID(String vatID) { - this.vatID = vatID; - return this; - } + /*** + * the USt-ID + * @param vatID Ust-ID + * @return fluent setter + */ + public TradeParty addVATID(String vatID) { + this.vatID = vatID; + return this; + } - @Override - public String getVATID() { - return vatID; - } + @Override + public String getVATID() { + return vatID; + } - public TradeParty setVATID(String VATid) { - this.vatID = VATid; - return this; - } + public TradeParty setVATID(String VATid) { + this.vatID = VATid; + return this; + } - @Override - public String getTaxID() { - return taxID; - } + @Override + public String getTaxID() { + return taxID; + } - public TradeParty setTaxID(String tax) { - this.taxID = tax; - return this; - } + public TradeParty setTaxID(String tax) { + this.taxID = tax; + return this; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - /*** - * required, usually done in the constructor: the complete name of the organisation - * @param name complete legal name - * @return fluent setter - */ - public TradeParty setName(String name) { - this.name = name; - return this; - } + /*** + * required, usually done in the constructor: the complete name of the organisation + * @param name complete legal name + * @return fluent setter + */ + public TradeParty setName(String name) { + this.name = name; + return this; + } - /*** - * - * @return String the description, e.g. if it's a vat exempt company - */ - public String getDescription() { - return description; - } + /*** + * + * @return String the description, e.g. if it's a vat exempt company + */ + public String getDescription() { + return description; + } - /*** - * required, usually done in the constructor: the complete name of the organisation - * @param description human readable description - * @return fluent setter - */ - public TradeParty setDescription(String description) { - this.description = description; - return this; - } + /*** + * required, usually done in the constructor: the complete name of the organisation + * @param description human readable description + * @return fluent setter + */ + public TradeParty setDescription(String description) { + this.description = description; + return this; + } - public String getZIP() { - return zip; - } + public String getZIP() { + return zip; + } - /*** - * usually set in the constructor, required for recipients in german invoices: postcode - * @param zip postcode - * @return fluent setter - */ - public TradeParty setZIP(String zip) { - this.zip = zip; - return this; - } + /*** + * usually set in the constructor, required for recipients in german invoices: postcode + * @param zip postcode + * @return fluent setter + */ + public TradeParty setZIP(String zip) { + this.zip = zip; + return this; + } - @Override - public String getStreet() { - return street; - } + @Override + public String getStreet() { + return street; + } - /*** - * usually set in constructor, required in germany, street and house number - * @param street street name and number - * @return fluent setter - */ - public TradeParty setStreet(String street) { - this.street = street; - return this; - } + /*** + * usually set in constructor, required in germany, street and house number + * @param street street name and number + * @return fluent setter + */ + public TradeParty setStreet(String street) { + this.street = street; + return this; + } - @Override - public String getLocation() { - return location; - } + @Override + public String getLocation() { + return location; + } - /*** - * usually set in constructor, usually required in germany, the city of the organisation - * @param location city - * @return fluent setter - */ - public TradeParty setLocation(String location) { - this.location = location; - return this; - } + /*** + * usually set in constructor, usually required in germany, the city of the organisation + * @param location city + * @return fluent setter + */ + public TradeParty setLocation(String location) { + this.location = location; + return this; + } - @Override - public String getCountry() { - return country; - } + @Override + public String getCountry() { + return country; + } - /*** - * two-letter ISO code of the country - * @param country two-letter-code - * @return fluent setter - */ - public TradeParty setCountry(String country) { - this.country = country; - return this; - } + /*** + * two-letter ISO code of the country + * @param country two-letter-code + * @return fluent setter + */ + public TradeParty setCountry(String country) { + this.country = country; + return this; + } - public String getVatID() { - return vatID; - } + public String getVatID() { + return vatID; + } - @Override - public IZUGFeRDExportableContact getContact() { - return contact; - } + @Override + public IZUGFeRDExportableContact getContact() { + return contact; + } - @JsonIgnore - public IZUGFeRDTradeSettlement[] getAsTradeSettlement() { - if (bankDetails.isEmpty() && debitDetails.isEmpty()) { - return null; - } - List tradeSettlements = Stream.concat(bankDetails.stream(), debitDetails.stream()).map(IZUGFeRDTradeSettlement.class::cast).collect(Collectors.toList()); + @JsonIgnore + public IZUGFeRDTradeSettlement[] getAsTradeSettlement() { + if (bankDetails.isEmpty() && debitDetails.isEmpty()) { + return null; + } + List tradeSettlements = Stream.concat(bankDetails.stream(), debitDetails.stream()).map(IZUGFeRDTradeSettlement.class::cast).collect(Collectors.toList()); - IZUGFeRDTradeSettlement[] result = new IZUGFeRDTradeSettlement[tradeSettlements.size()]; - for (int i = 0; i < tradeSettlements.size(); i++) { - IZUGFeRDTradeSettlement izugFeRDTradeSettlement = tradeSettlements.get(i); - result[i] = izugFeRDTradeSettlement; - } - return result; - } + IZUGFeRDTradeSettlement[] result = new IZUGFeRDTradeSettlement[tradeSettlements.size()]; + for (int i = 0; i < tradeSettlements.size(); i++) { + IZUGFeRDTradeSettlement izugFeRDTradeSettlement = tradeSettlements.get(i); + result[i] = izugFeRDTradeSettlement; + } + return result; + } - @Override - public String getAdditionalAddress() { - return additionalAddress; - } + @Override + public String getAdditionalAddress() { + return additionalAddress; + } - /*** - * additional info of the address, e.g. which building or which floor. - * Street address will become "lineOne", this will become "lineTwo". - * (see setAdditionalAddressExtension for "lineThree") - * @param additionalAddress additional address description - * @return fluent setter - */ - public TradeParty setAdditionalAddress(String additionalAddress) { - this.additionalAddress = additionalAddress; - return this; - } + /*** + * additional info of the address, e.g. which building or which floor. + * Street address will become "lineOne", this will become "lineTwo". + * (see setAdditionalAddressExtension for "lineThree") + * @param additionalAddress additional address description + * @return fluent setter + */ + public TradeParty setAdditionalAddress(String additionalAddress) { + this.additionalAddress = additionalAddress; + return this; + } - /*** - * Sets two parts of additional address at once, e.g. which building and which floor - * (if building is not in question which floor can also be set with the first part only :-)) - * - * @param additionalAddress1 first part of additional info, e.g. "Rear building" - * @param additionalAddress2 second part of additional address info, e.g. "2nd floor" - * @return fluent setter - */ - public TradeParty setAdditionalAddress(String additionalAddress1, String additionalAddress2) { - this.additionalAddress = additionalAddress1; - this.additionalAddressExtension = additionalAddress2; - return this; - } + /*** + * Sets two parts of additional address at once, e.g. which building and which floor + * (if building is not in question which floor can also be set with the first part only :-)) + * + * @param additionalAddress1 first part of additional info, e.g. "Rear building" + * @param additionalAddress2 second part of additional address info, e.g. "2nd floor" + * @return fluent setter + */ + public TradeParty setAdditionalAddress(String additionalAddress1, String additionalAddress2) { + this.additionalAddress = additionalAddress1; + this.additionalAddressExtension = additionalAddress2; + return this; + } - /*** - * Sets even advanced additional address information, - * e.g. which floor (if LineTwo has already been used e.g. for which building) - * This could sometimes be BT-165? - * - * @param additionalAddress2 e.g. which floor, as String - * @return fluent setter - */ - public TradeParty setAdditionalAddressExtension(String additionalAddress2) { - this.additionalAddressExtension = additionalAddress2; - return this; - } + /*** + * Sets even advanced additional address information, + * e.g. which floor (if LineTwo has already been used e.g. for which building) + * This could sometimes be BT-165? + * + * @param additionalAddress2 e.g. which floor, as String + * @return fluent setter + */ + public TradeParty setAdditionalAddressExtension(String additionalAddress2) { + this.additionalAddressExtension = additionalAddress2; + return this; + } - /*** - * Returns even advanced additional address information, - * e.g. which floor (if LineTwo=setAdditionalAddress has already been used e.g. for which building) - * @return lineThree - */ - public String getAdditionalAddressExtension() { - return this.additionalAddressExtension; - } + /*** + * Returns even advanced additional address information, + * e.g. which floor (if LineTwo=setAdditionalAddress has already been used e.g. for which building) + * @return lineThree + */ + public String getAdditionalAddressExtension() { + return this.additionalAddressExtension; + } } diff --git a/library/src/main/java/org/mustangproject/util/ByteArraySearcher.java b/library/src/main/java/org/mustangproject/util/ByteArraySearcher.java index 9fb83a6..02bce47 100755 --- a/library/src/main/java/org/mustangproject/util/ByteArraySearcher.java +++ b/library/src/main/java/org/mustangproject/util/ByteArraySearcher.java @@ -2,55 +2,55 @@ org.openrewrite.config.CompositeRecipe public final class ByteArraySearcher { - private ByteArraySearcher() { - } + private ByteArraySearcher() { + } - public static int indexOf(byte[] haystack, byte[] needle) { - if (needle.length > haystack.length) { - return -1; - } + public static int indexOf(byte[] haystack, byte[] needle) { + if (needle.length > haystack.length) { + return -1; + } - // Any needle to search? - if (needle.length == 0) { - return -1; - } + // Any needle to search? + if (needle.length == 0) { + return -1; + } - for (int i = 0; i <= haystack.length - needle.length; i++) { - boolean found = true; - for (int j = 0; j < needle.length; j++) { - if (haystack[i + j] != needle[j]) { - found = false; - break; - } - } - if (found) { - return i; - } - } + for (int i = 0; i <= haystack.length - needle.length; i++) { + boolean found = true; + for (int j = 0; j < needle.length; j++) { + if (haystack[i + j] != needle[j]) { + found = false; + break; + } + } + if (found) { + return i; + } + } - return -1; - } + return -1; + } - public static boolean contains(byte[] haystack, byte[] needle) { - return indexOf(haystack, needle) >= 0; - } + public static boolean contains(byte[] haystack, byte[] needle) { + return indexOf(haystack, needle) >= 0; + } - public static boolean startsWith(byte[] haystack, byte[] needle) { - if (needle.length > haystack.length) { - return false; - } + public static boolean startsWith(byte[] haystack, byte[] needle) { + if (needle.length > haystack.length) { + return false; + } - // Any needle to search? - if (needle.length == 0) { - return false; - } + // Any needle to search? + if (needle.length == 0) { + return false; + } - for (int j = 0; j < needle.length; j++) { - if (haystack[j] != needle[j]) { - return false; - } - } + for (int j = 0; j < needle.length; j++) { + if (haystack[j] != needle[j]) { + return false; + } + } - return true; - } + return true; + } } diff --git a/library/src/main/java/org/mustangproject/util/NodeMap.java b/library/src/main/java/org/mustangproject/util/NodeMap.java index 77064d0..7c2c99c 100755 --- a/library/src/main/java/org/mustangproject/util/NodeMap.java +++ b/library/src/main/java/org/mustangproject/util/NodeMap.java @@ -30,7 +30,6 @@ org.openrewrite.config.CompositeRecipe import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -39,113 +38,113 @@ * It can be constructed either from the children of a single {@link Node} or a {@link NodeList}. */ public class NodeMap { - private final Map> map = new HashMap<>(); + private final Map> map = new HashMap<>(); - /** - * Create a new {@link NodeMap} - * The {@link Node} that is passed to the constructor must not be null. - * The {@link NodeMap} will be empty when no child nodes are present. - * - * @param node the node that shall be represented by this {@link NodeMap} - * @throws IllegalArgumentException when argument is null - */ - public NodeMap(Node node) { - if (node == null) { - throw new IllegalArgumentException("node cannot be null"); - } - if (node.hasChildNodes()) { - mapNodeList(node.getChildNodes()); - } - } + /** + * Create a new {@link NodeMap} + * The {@link Node} that is passed to the constructor must not be null. + * The {@link NodeMap} will be empty when no child nodes are present. + * + * @param node the node that shall be represented by this {@link NodeMap} + * @throws IllegalArgumentException when argument is null + */ + public NodeMap(Node node) { + if (node == null) { + throw new IllegalArgumentException("node cannot be null"); + } + if (node.hasChildNodes()) { + mapNodeList(node.getChildNodes()); + } + } - public NodeMap(NodeList nodeList) { - if (nodeList == null) { - throw new IllegalArgumentException("nodeList cannot be null"); - } - mapNodeList(nodeList); - } + public NodeMap(NodeList nodeList) { + if (nodeList == null) { + throw new IllegalArgumentException("nodeList cannot be null"); + } + mapNodeList(nodeList); + } - /** - * Get matching node by {@code LocalName} - * In case more than one node matches, it is not guaranteed that the first match is selected - * - * @param localNames one or more {@code LocalName}s - * @return the matching node - */ - public Optional getNode(String... localNames) { - return getAllNodes(localNames).findAny(); - } + /** + * Get matching node by {@code LocalName} + * In case more than one node matches, it is not guaranteed that the first match is selected + * + * @param localNames one or more {@code LocalName}s + * @return the matching node + */ + public Optional getNode(String... localNames) { + return getAllNodes(localNames).findAny(); + } - /** - * Get a {@link NodeMap} of the child of a matching node by {@code LocalName} - * In case more than one node matches, it is not guaranteed that the first match is selected - * - * @param localNames one or more {@code LocalName}s - * @return the {@link NodeMap} representation of the matching node - */ - public Optional getAsNodeMap(String... localNames) { - return getNode(localNames).filter(Node::hasChildNodes).map(NodeMap::new); - } + /** + * Get a {@link NodeMap} of the child of a matching node by {@code LocalName} + * In case more than one node matches, it is not guaranteed that the first match is selected + * + * @param localNames one or more {@code LocalName}s + * @return the {@link NodeMap} representation of the matching node + */ + public Optional getAsNodeMap(String... localNames) { + return getNode(localNames).filter(Node::hasChildNodes).map(NodeMap::new); + } - /** - * Get the text content of a matching node - * In case more than one node matches, it is not guaranteed that the first match is selected - * - * @param localNames one or more {@code LocalName}s - * @return the text content of the matching node - */ - public Optional getAsString(String... localNames) { - return getNode(localNames).map(Node::getTextContent); - } + /** + * Get the text content of a matching node + * In case more than one node matches, it is not guaranteed that the first match is selected + * + * @param localNames one or more {@code LocalName}s + * @return the text content of the matching node + */ + public Optional getAsString(String... localNames) { + return getNode(localNames).map(Node::getTextContent); + } - /** - * Get the text content of a matching node - * In case more than one node matches, it is not guaranteed that the first match is selected - * - * @param localNames one or more {@code LocalName}s - * @return the text content of the matching node, converted to BigDecimal - */ - public Optional getAsBigDecimal(String... localNames) { - return getNode(localNames).map(Node::getTextContent).map(s->{ - try { - return new BigDecimal(s.trim()); - } catch (NumberFormatException e) { - return null; - } + /** + * Get the text content of a matching node + * In case more than one node matches, it is not guaranteed that the first match is selected + * + * @param localNames one or more {@code LocalName}s + * @return the text content of the matching node, converted to BigDecimal + */ + public Optional getAsBigDecimal(String... localNames) { + return getNode(localNames).map(Node::getTextContent).map(s -> { + try { + return new BigDecimal(s.trim()); + } catch (NumberFormatException e) { + return null; + } - }); - } + }); + } - /** - * Get the text content of a matching node - * In case more than one node matches, it is not guaranteed that the first match is selected - * - * @param localNames one or more {@code LocalName}s - * @return the text content of the matching node or {@code null} when no matching node could be found - */ - public String getAsStringOrNull(String... localNames) { - return getAsString(localNames).orElse(null); - } + /** + * Get the text content of a matching node + * In case more than one node matches, it is not guaranteed that the first match is selected + * + * @param localNames one or more {@code LocalName}s + * @return the text content of the matching node or {@code null} when no matching node could be found + */ + public String getAsStringOrNull(String... localNames) { + return getAsString(localNames).orElse(null); + } - /** - * Get all matching nodes - * - * @param localNames one or more {@code LocalName}s - * @return a {@code Stream} that contains all matching nodes (can be empty if nothing matches) - */ - public Stream getAllNodes(String... localNames) { - List localNamesList = Arrays.asList(localNames); - return map.entrySet().stream().filter(e -> localNamesList.contains(e.getKey())).flatMap(e -> e.getValue().stream()); - } + /** + * Get all matching nodes + * + * @param localNames one or more {@code LocalName}s + * @return a {@code Stream} that contains all matching nodes (can be empty if nothing matches) + */ + public Stream getAllNodes(String... localNames) { + List localNamesList = Arrays.asList(localNames); + return map.entrySet().stream().filter(e -> localNamesList.contains(e.getKey())).flatMap(e -> e.getValue().stream()); + } - private void mapNodeList(NodeList nodeList) { - IntStream.range(0, nodeList.getLength()).mapToObj(nodeList::item) - .filter(node -> node != null && node.getLocalName() != null) - .forEach(node -> map.computeIfAbsent(node.getLocalName(), k -> new ArrayList<>()).add(node)); - } + private void mapNodeList(NodeList nodeList) { + IntStream.range(0, nodeList.getLength()).mapToObj(nodeList::item) + .filter(node -> node != null && node.getLocalName() != null) + .forEach(node -> map.computeIfAbsent(node.getLocalName(), k -> new ArrayList<>()).add(node)); + } - @Override - public String toString() { - return map.toString(); - } + @Override + public String toString() { + return map.toString(); + } } diff --git a/library/src/main/java/org/mustangproject/XMLTools.java b/library/src/main/java/org/mustangproject/XMLTools.java index d890c3d..4402555 100755 --- a/library/src/main/java/org/mustangproject/XMLTools.java +++ b/library/src/main/java/org/mustangproject/XMLTools.java @@ -1,5 +1,10 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject; +import org.apache.commons.io.IOUtils; +import org.dom4j.io.XMLWriter; +import org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat; +import org.w3c.dom.Node; + import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; @@ -7,223 +12,219 @@ import java.text.SimpleDateFormat; import java.util.Date; -import org.apache.commons.io.IOUtils; -import org.dom4j.io.XMLWriter; -import org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat; -import org.w3c.dom.Node; - public class XMLTools extends XMLWriter { - @Override - public String escapeAttributeEntities(String s) { - return super.escapeAttributeEntities(s); - } + @Override + public String escapeAttributeEntities(String s) { + return super.escapeAttributeEntities(s); + } - @Override - public String escapeElementEntities(String s) { - return super.escapeElementEntities(s); - } + @Override + public String escapeElementEntities(String s) { + return super.escapeElementEntities(s); + } - public static String nDigitFormat(BigDecimal value, int scale) { - /* - * I needed 123.45, locale independent.I tried - * NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is locale - * specific.I also tried DecimalFormat df = new DecimalFormat( "0,00" ); - * df.setDecimalSeparatorAlwaysShown(true); df.setGroupingUsed(false); - * DecimalFormatSymbols symbols = new DecimalFormatSymbols(); - * symbols.setDecimalSeparator(','); symbols.setGroupingSeparator(' '); - * df.setDecimalFormatSymbols(symbols); - * - * but that would not switch off grouping. Although I liked very much the - * (incomplete) "BNF diagram" in - * http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html in the - * end I decided to calculate myself and take eur+sparator+cents - * - */ - return value.setScale(scale, RoundingMode.HALF_UP).toPlainString(); + public static String nDigitFormat(BigDecimal value, int scale) { + /* + * I needed 123.45, locale independent.I tried + * NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is locale + * specific.I also tried DecimalFormat df = new DecimalFormat( "0,00" ); + * df.setDecimalSeparatorAlwaysShown(true); df.setGroupingUsed(false); + * DecimalFormatSymbols symbols = new DecimalFormatSymbols(); + * symbols.setDecimalSeparator(','); symbols.setGroupingSeparator(' '); + * df.setDecimalFormatSymbols(symbols); + * + * but that would not switch off grouping. Although I liked very much the + * (incomplete) "BNF diagram" in + * http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html in the + * end I decided to calculate myself and take eur+sparator+cents + * + */ + return value.setScale(scale, RoundingMode.HALF_UP).toPlainString(); - } + } - /** - * returns the value of an node - * - * @param node the Node to get the value from - * @return A String or empty String, if no value was found - */ - public static String getNodeValue(Node node) { - if (node != null && node.getFirstChild() != null) { - return node.getFirstChild().getNodeValue(); - } - return ""; - } + /** + * returns the value of an node + * + * @param node the Node to get the value from + * @return A String or empty String, if no value was found + */ + public static String getNodeValue(Node node) { + if (node != null && node.getFirstChild() != null) { + return node.getFirstChild().getNodeValue(); + } + return ""; + } - /** - * tries to convert a String to BigDecimal. - * - * @param nodeValue The value as String - * @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs - */ - public static BigDecimal tryBigDecimal(String nodeValue) { - try { - return new BigDecimal(nodeValue); - } catch (final Exception e) { - try { - return BigDecimal.valueOf(Float.valueOf(nodeValue)); - } catch (final Exception ex) { - return new BigDecimal("0.00"); - } - } - } + /** + * tries to convert a String to BigDecimal. + * + * @param nodeValue The value as String + * @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs + */ + public static BigDecimal tryBigDecimal(String nodeValue) { + try { + return new BigDecimal(nodeValue); + } catch (final Exception e) { + try { + return BigDecimal.valueOf(Float.valueOf(nodeValue)); + } catch (final Exception ex) { + return new BigDecimal("0.00"); + } + } + } - /** - * tries to convert a Node to a BigDecimal. - * - * @param node The value as String - * @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs - */ - public static BigDecimal tryBigDecimal(Node node) { - final String nodeValue = XMLTools.getNodeValue(node); - if (nodeValue.isEmpty()) { - return null; - } - return XMLTools.tryBigDecimal(nodeValue); - } - /*** - * formats a number so that at least minDecimals are displayed but at the maximum maxDecimals are there, i.e. - * cuts potential 0s off the end until minDecimals - * @param value the value to be formatted - * @param maxDecimals number of maximal scale - * @param minDecimals number of minimal scale - * @return value as String with decimals in the specified range - */ - public static String nDigitFormatDecimalRange(BigDecimal value, int maxDecimals, int minDecimals) { - if ((maxDecimalsminDecimals) && (value.setScale(curDecimals, RoundingMode.HALF_UP).compareTo(value.setScale(curDecimals-1, RoundingMode.HALF_UP))==0)) { - curDecimals--; - } - return value.setScale(curDecimals, RoundingMode.HALF_UP).toPlainString(); + /** + * tries to convert a Node to a BigDecimal. + * + * @param node The value as String + * @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs + */ + public static BigDecimal tryBigDecimal(Node node) { + final String nodeValue = XMLTools.getNodeValue(node); + if (nodeValue.isEmpty()) { + return null; + } + return XMLTools.tryBigDecimal(nodeValue); + } - } + /*** + * formats a number so that at least minDecimals are displayed but at the maximum maxDecimals are there, i.e. + * cuts potential 0s off the end until minDecimals + * @param value the value to be formatted + * @param maxDecimals number of maximal scale + * @param minDecimals number of minimal scale + * @return value as String with decimals in the specified range + */ + public static String nDigitFormatDecimalRange(BigDecimal value, int maxDecimals, int minDecimals) { + if ((maxDecimals < minDecimals) || (maxDecimals < 0) || (minDecimals < 0)) { + throw new IllegalArgumentException("Invalid scale range provided"); + } + int curDecimals = maxDecimals; + while ((curDecimals > minDecimals) && (value.setScale(curDecimals, RoundingMode.HALF_UP).compareTo(value.setScale(curDecimals - 1, RoundingMode.HALF_UP)) == 0)) { + curDecimals--; + } + return value.setScale(curDecimals, RoundingMode.HALF_UP).toPlainString(); + + } - /*** - * returns a util.Date from a 102 String yyyymmdd in a node - * @param node the node - * @return a util.Date, or null, if not parseable - */ - public static Date tryDate(Node node) { - final String nodeValue = XMLTools.getNodeValue(node); - if (nodeValue.isEmpty()) { - return null; - } - return tryDate(nodeValue); - } + /*** + * returns a util.Date from a 102 String yyyymmdd in a node + * @param node the node + * @return a util.Date, or null, if not parseable + */ + public static Date tryDate(Node node) { + final String nodeValue = XMLTools.getNodeValue(node); + if (nodeValue.isEmpty()) { + return null; + } + return tryDate(nodeValue); + } - /*** - * returns a util.Date from a 102 String yyyymmdd - * @param toParse the string - * @return a util.Date, or null, if not parseable - */ - public static Date tryDate(String toParse) { - final SimpleDateFormat formatter = ZUGFeRDDateFormat.DATE.getFormatter(); - try { - return formatter.parse(toParse); - } catch (final Exception e) { - return null; - } - } + /*** + * returns a util.Date from a 102 String yyyymmdd + * @param toParse the string + * @return a util.Date, or null, if not parseable + */ + public static Date tryDate(String toParse) { + final SimpleDateFormat formatter = ZUGFeRDDateFormat.DATE.getFormatter(); + try { + return formatter.parse(toParse); + } catch (final Exception e) { + return null; + } + } - /*** - * relplaces some entities like < , > and & with their escaped pendant like &lt; - * @param s the string - * @return the "safe" string - */ - public static String encodeXML(CharSequence s) { - if (s == null) { - return ""; - } - final StringBuilder sb = new StringBuilder(); - final int len = s.length(); - for (int i = 0; i < len; i++) { - int c = s.charAt(i); - if (c >= 0xd800 && c <= 0xdbff && i + 1 < len) { - c = ((c - 0xd7c0) << 10) | (s.charAt(++i) & 0x3ff); // UTF16 decode - } - if (c < 0x80) { // ASCII range: test most common case first - if (c < 0x20 && (c != '\t' && c != '\r' && c != '\n')) { - // Illegal XML character, even encoded. Skip or substitute - sb.append("�"); // Unicode replacement character - } else { - switch (c) { - case '&': - sb.append("&"); - break; - case '>': - sb.append(">"); - break; - case '<': - sb.append("<"); - break; - // Uncomment next two if encoding for an XML attribute -// case '\'' sb.append("'"); break; -// case '\"' sb.append("""); break; - // Uncomment next three if you prefer, but not required -// case '\n' sb.append(" "); break; -// case '\r' sb.append(" "); break; -// case '\t' sb.append(" "); break; + /*** + * relplaces some entities like < , > and & with their escaped pendant like &lt; + * @param s the string + * @return the "safe" string + */ + public static String encodeXML(CharSequence s) { + if (s == null) { + return ""; + } + final StringBuilder sb = new StringBuilder(); + final int len = s.length(); + for (int i = 0; i < len; i++) { + int c = s.charAt(i); + if (c >= 0xd800 && c <= 0xdbff && i + 1 < len) { + c = ((c - 0xd7c0) << 10) | (s.charAt(++i) & 0x3ff); // UTF16 decode + } + if (c < 0x80) { // ASCII range: test most common case first + if (c < 0x20 && (c != '\t' && c != '\r' && c != '\n')) { + // Illegal XML character, even encoded. Skip or substitute + sb.append("�"); // Unicode replacement character + } else { + switch (c) { + case '&': + sb.append("&"); + break; + case '>': + sb.append(">"); + break; + case '<': + sb.append("<"); + break; + // Uncomment next two if encoding for an XML attribute +// case '\'' sb.append("'"); break; +// case '\"' sb.append("""); break; + // Uncomment next three if you prefer, but not required +// case '\n' sb.append(" "); break; +// case '\r' sb.append(" "); break; +// case '\t' sb.append(" "); break; - default: - sb.append((char) c); - } - } - } else if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) { - // Illegal XML character, even encoded. Skip or substitute - sb.append("�"); // Unicode replacement character - } else { - sb.append("&#x"); - sb.append(Integer.toHexString(c)); - sb.append(';'); - } - } - return sb.toString(); - } + default: + sb.append((char) c); + } + } + } else if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) { + // Illegal XML character, even encoded. Skip or substitute + sb.append("�"); // Unicode replacement character + } else { + sb.append("&#x"); + sb.append(Integer.toHexString(c)); + sb.append(';'); + } + } + return sb.toString(); + } - /*** - * removes utf8 byte order marks from byte arrays, in case one is there - * @param zugferdRaw the CII XML - * @return the byte array without bom - */ - public static byte[] removeBOM(byte[] zugferdRaw) { - final byte[] zugferdData; - // This handles the UTF-8 BOM - if ((zugferdRaw[0] == (byte) 0xEF) && (zugferdRaw[1] == (byte) 0xBB) && (zugferdRaw[2] == (byte) 0xBF)) { - // I don't like BOMs, lets remove it - zugferdData = new byte[zugferdRaw.length - 3]; - System.arraycopy(zugferdRaw, 3, zugferdData, 0, zugferdRaw.length - 3); - } else { - zugferdData = zugferdRaw; - } - return zugferdData; - } + /*** + * removes utf8 byte order marks from byte arrays, in case one is there + * @param zugferdRaw the CII XML + * @return the byte array without bom + */ + public static byte[] removeBOM(byte[] zugferdRaw) { + final byte[] zugferdData; + // This handles the UTF-8 BOM + if ((zugferdRaw[0] == (byte) 0xEF) && (zugferdRaw[1] == (byte) 0xBB) && (zugferdRaw[2] == (byte) 0xBF)) { + // I don't like BOMs, lets remove it + zugferdData = new byte[zugferdRaw.length - 3]; + System.arraycopy(zugferdRaw, 3, zugferdData, 0, zugferdRaw.length - 3); + } else { + zugferdData = zugferdRaw; + } + return zugferdData; + } - public static byte[] getBytesFromStream(InputStream fileinput) throws IOException { - return IOUtils.toByteArray (fileinput); - } + public static byte[] getBytesFromStream(InputStream fileinput) throws IOException { + return IOUtils.toByteArray(fileinput); + } - public static String trimOrNull(Node node) { - if (node != null) { - String textContent = node.getTextContent(); - if (textContent != null) { - return textContent.trim(); - } - } - return null; - } + public static String trimOrNull(Node node) { + if (node != null) { + String textContent = node.getTextContent(); + if (textContent != null) { + return textContent.trim(); + } + } + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java index 45f79f2..08a0606 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java @@ -22,45 +22,45 @@ org.openrewrite.config.CompositeRecipe public class CustomXMLProvider implements IXMLProvider { - protected byte[] zugferdData; - protected Profile profile=Profiles.getByName("EN16931"); + protected byte[] zugferdData; + protected Profile profile = Profiles.getByName("EN16931"); - @Override - public byte[] getXML() { - return zugferdData; - } + @Override + public byte[] getXML() { + return zugferdData; + } - public void setXML(byte[] newData) { - String zf = new String(newData, StandardCharsets.UTF_8); - /** - * rsm:CrossIndustry is ZF/FX/XR (CII 2016b),rsm:SCRDMCCBDACIOMessageStructure is Order-X (CIO 2021) and - * SCRDMCCBDACIDAMessageStructure is Despatch Advice - */ - if ((!zf.contains("rsm:CrossIndustry")) && (!zf.contains("rsm:SCRDMCCBDACIOMessageStructure")) && (!zf.contains("SCRDMCCBDACIDAMessageStructure"))) { - throw new RuntimeException("ZUGFeRD XML does not contain \n" - // + " - // xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100 - // ../Schema/ZUGFeRD1p0.xsd\"" - + "" - // + " - +" "+testBooleanStr+"\n" - // - + "" - + "" + getProfile().getID() + "" - + "" - + "" - + "" - + "" + XMLTools.encodeXML(trans.getNumber()) + "" - // + " RECHNUNG" - // + "380" - + "" + typecode + "" - + "" - + DATE.udtFormat(trans.getIssueDate()) + "" // date - + buildNotes(trans) + String testBooleanStr = "true"; + String xml = "\n" + // + " + // xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100 + // ../Schema/ZUGFeRD1p0.xsd\"" + + "" + // + " + + " " + testBooleanStr + "\n" + // + + "" + + "" + getProfile().getID() + "" + + "" + + "" + + "" + + "" + XMLTools.encodeXML(trans.getNumber()) + "" + // + " RECHNUNG" + // + "380" + + "" + typecode + "" + + "" + + DATE.udtFormat(trans.getIssueDate()) + "" // date + + buildNotes(trans) - + "" - + ""; - int lineID = 0; - for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) { - lineID++; - if (currentItem.getProduct().getTaxExemptionReason() != null) { - // exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; - } - final LineCalculator lc = new LineCalculator(currentItem); - xml += "" + - "" - + "" + lineID + "" - + buildItemNotes(currentItem) - + "" + + "" + + ""; + int lineID = 0; + for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) { + lineID++; + if (currentItem.getProduct().getTaxExemptionReason() != null) { + // exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; + } + final LineCalculator lc = new LineCalculator(currentItem); + xml += "" + + "" + + "" + lineID + "" + + buildItemNotes(currentItem) + + "" - + ""; - // + " 4012345001235" - if (currentItem.getProduct().getSellerAssignedID() != null) { - xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; - } - if (currentItem.getProduct().getBuyerAssignedID() != null) { - xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; - } - String allowanceChargeStr = ""; - if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { - for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { - allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem); - } - } - if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { - for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { - allowanceChargeStr += getAllowanceChargeStr(charge, currentItem); + + ""; + // + " 4012345001235" + if (currentItem.getProduct().getSellerAssignedID() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; + } + if (currentItem.getProduct().getBuyerAssignedID() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; + } + String allowanceChargeStr = ""; + if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { + for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { + allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem); + } + } + if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { + for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { + allowanceChargeStr += getAllowanceChargeStr(charge, currentItem); - } - } + } + } - xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "" - + "" + XMLTools.encodeXML(currentItem.getProduct().getDescription()) - + "" - + "" + xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "" + + "" + XMLTools.encodeXML(currentItem.getProduct().getDescription()) + + "" + + "" - + "" - + "" - + quantityFormat(currentItem.getQuantity()) + "" - + "" - + ""; - if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) { - xml += ""; - if (currentItem.getDetailedDeliveryPeriodFrom() != null) { - xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodFrom()) + ""; - } - if (currentItem.getDetailedDeliveryPeriodTo() != null) { - xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodTo()) + ""; - } - xml += ""; + + "" + + "" + + quantityFormat(currentItem.getQuantity()) + "" + + "" + + ""; + if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) { + xml += ""; + if (currentItem.getDetailedDeliveryPeriodFrom() != null) { + xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodFrom()) + ""; + } + if (currentItem.getDetailedDeliveryPeriodTo() != null) { + xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodTo()) + ""; + } + xml += ""; - } + } - xml += "" - + "" + currencyFormat(lc.getItemTotalNetAmount()) - + "" // currencyID=\"EUR\" - + ""; - /* if (currentItem.getAdditionalReferencedDocumentID() != null) { - xml += "" + currentItem.getAdditionalReferencedDocumentID() + "130"; + xml += "" + + "" + currencyFormat(lc.getItemTotalNetAmount()) + + "" // currencyID=\"EUR\" + + ""; + /* if (currentItem.getAdditionalReferencedDocumentID() != null) { + xml += "" + currentItem.getAdditionalReferencedDocumentID() + "130"; + }*/ + xml += "" + + ""; - }*/ - xml += "" - + ""; + } - } + xml += ""; + if (trans.getReferenceNumber() != null) { + xml += "" + XMLTools.encodeXML(trans.getReferenceNumber()) + ""; - xml += ""; - if (trans.getReferenceNumber() != null) { - xml += "" + XMLTools.encodeXML(trans.getReferenceNumber()) + ""; + } + xml += "" + + getTradePartyAsXML(trans.getSender(), true, false) + + "" + + ""; + // + " GE2020211" + // + " 4000001987658" - } - xml += "" - + getTradePartyAsXML(trans.getSender(), true, false) - + "" - + ""; - // + " GE2020211" - // + " 4000001987658" + xml += getTradePartyAsXML(trans.getRecipient(), false, false); + xml += ""; - xml += getTradePartyAsXML(trans.getRecipient(), false, false); - xml += ""; + if (trans.getSellerOrderReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" + + ""; + } + if (trans.getBuyerOrderReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" + + ""; + } + if (trans.getContractReferencedDocument() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "" + + ""; + } - if (trans.getSellerOrderReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" - + ""; - } - if (trans.getBuyerOrderReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" - + ""; - } - if (trans.getContractReferencedDocument() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "" - + ""; - } + // Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung) + if (trans.getAdditionalReferencedDocuments() != null) { + for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) { + final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData())); + xml += "" + + "" + f.getFilename() + "" + + "916" + + "" + f.getDescription() + "" + + "" + documentContent + "" + + ""; + } + } - // Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung) - if (trans.getAdditionalReferencedDocuments() != null) { - for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) { - final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData())); - xml += "" - + "" + f.getFilename() + "" - + "916" - + "" + f.getDescription() + "" - + "" + documentContent + "" - + ""; - } - } + if (trans.getSpecifiedProcuringProjectID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + ""; + if (trans.getSpecifiedProcuringProjectName() != null) { + xml += "" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + ""; + } + xml += ""; + } + xml += "" + + ""; + if (this.trans.getDeliveryAddress() != null) { + xml += "" + + getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) + + ""; + } + xml += " \n" + + " \n" + + " " + DATE.udtFormat(trans.getDeliveryDate()) + "\n" + + " \n" + + " "; - if (trans.getSpecifiedProcuringProjectID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + ""; - if (trans.getSpecifiedProcuringProjectName() != null) { - xml += "" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + ""; - } - xml += ""; - } - xml += "" - + ""; - if (this.trans.getDeliveryAddress() != null) { - xml += "" + - getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) + - ""; - } - xml += " \n" + - " \n" + - " "+ DATE.udtFormat(trans.getDeliveryDate() )+"\n" + - " \n" + - " "; + /* + xml += "" + + ""; + + if (trans.getDeliveryDate() != null) { + xml += DATE.udtFormat(trans.getDeliveryDate()); + } else { + throw new IllegalStateException("No delivery date provided"); + } + xml += "\n"; + xml += "\n" + + */ + /* + * + "\n" + + * "20130603\n" + + * "2013-51112\n" + + * "\n" + */ + xml += "\n"; + // + " " + // + " " + // + " " + // + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. + // 2013-51112 in Rechnung zu stellen:\n" + // + " \n" + // + " \n" + // + " \n"; -/* - xml += "" - + ""; + xml += "" + + ""; - if (trans.getDeliveryDate() != null) { - xml += DATE.udtFormat(trans.getDeliveryDate()); - } else { - throw new IllegalStateException("No delivery date provided"); - } - xml += "\n"; - xml += "\n" + final byte[] zugferdRaw; + zugferdRaw = xml.getBytes(StandardCharsets.UTF_8); - */ - /* - * + "\n" + - * "20130603\n" + - * "2013-51112\n" + - * "\n" - */ - xml+= "\n"; - // + " " - // + " " - // + " " - // + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. - // 2013-51112 in Rechnung zu stellen:\n" - // + " \n" - // + " \n" - // + " \n"; - - xml += "" - + ""; - - final byte[] zugferdRaw; - zugferdRaw = xml.getBytes(StandardCharsets.UTF_8); - - zugferdData = XMLTools.removeBOM(zugferdRaw); - } - - - @Override - public void setProfile(Profile p) { - profile = p; - } - - @Override - public Profile getProfile() { - return profile; - } - - @Override - protected String buildNotes(IExportableTransaction exportableTransaction) { - Invoice copyWithoutRebateInfo = new Invoice() - .setOwnOrganisationFullPlaintextInfo(exportableTransaction.getOwnOrganisationFullPlaintextInfo()) - .addNotes(exportableTransaction.getNotesWithSubjectCode()); - if(exportableTransaction.getNotes() != null) { - for (String note : exportableTransaction.getNotes()) { - copyWithoutRebateInfo.addNote(note); - } + zugferdData = XMLTools.removeBOM(zugferdRaw); } - Optional.ofNullable(exportableTransaction.getSubjectNote()).ifPresent(copyWithoutRebateInfo::addNote); - return super.buildNotes(copyWithoutRebateInfo); - } + + + @Override + public void setProfile(Profile p) { + profile = p; + } + + @Override + public Profile getProfile() { + return profile; + } + + @Override + protected String buildNotes(IExportableTransaction exportableTransaction) { + Invoice copyWithoutRebateInfo = new Invoice() + .setOwnOrganisationFullPlaintextInfo(exportableTransaction.getOwnOrganisationFullPlaintextInfo()) + .addNotes(exportableTransaction.getNotesWithSubjectCode()); + if (exportableTransaction.getNotes() != null) { + for (String note : exportableTransaction.getNotes()) { + copyWithoutRebateInfo.addNote(note); + } + } + Optional.ofNullable(exportableTransaction.getSubjectNote()).ifPresent(copyWithoutRebateInfo::addNote); + return super.buildNotes(copyWithoutRebateInfo); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA1.java b/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA1.java index f22d76c..878ef44 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA1.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA1.java @@ -19,143 +19,153 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; -import java.io.IOException; -import java.io.InputStream; - +import jakarta.activation.DataSource; import org.apache.pdfbox.preflight.PreflightDocument; import org.apache.pdfbox.preflight.ValidationResult; import org.apache.pdfbox.preflight.exception.ValidationException; import org.apache.pdfbox.preflight.parser.PreflightParser; -import jakarta.activation.DataSource; +import java.io.IOException; +import java.io.InputStream; public class DXExporterFromA1 extends DXExporterFromA3 { - protected boolean ignorePDFAErrors = false; + protected boolean ignorePDFAErrors = false; - @Override - public DXExporterFromA1 ignorePDFAErrors() { - this.ignorePDFAErrors = true; - return this; - } + @Override + public DXExporterFromA1 ignorePDFAErrors() { + this.ignorePDFAErrors = true; + return this; + } - private static boolean isValidA1(DataSource dataSource) throws IOException { - return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser (dataSource)); - } - /*** - * internal helper function: get namespace for order-x - * @param ver the delivery-x version - * @return the URN of the namespace - */ - @Override - public String getNamespaceForVersion(int ver) { - // As of late 2022 the Delivery-X standard is not yet published. See specification: - // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022 - // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3 - // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html - return "urn:factur-x:pdfa:CrossIndustryDocument:despatchadvice:1p0#"; - } - /*** - * internal helper: returns the namespace prefix for the given order-x version number - * @param ver the ox version - * @return the namespace prefix as string, without colon - */ - @Override - public String getPrefixForVersion(int ver) { - return "fx"; - } + private static boolean isValidA1(DataSource dataSource) throws IOException { + return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource)); + } - private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException { - /* - * Parse the PDF file with PreflightParser that inherits from the - * NonSequentialParser. Some additional controls are present to check a set of - * PDF/A requirements. (Stream length consistency, EOL after some Keyword...) - */ - // might add a Format.PDF_A1A as parameter and iterate through A1 and A3 - - try (PreflightDocument document = (PreflightDocument) parser.parse()) { - /* - * Once the syntax validation is done, the parser can provide a - * PreflightDocument (that inherits from PDDocument) This document process the - * end of PDF/A validation. - */ + /*** + * internal helper function: get namespace for order-x + * @param ver the delivery-x version + * @return the URN of the namespace + */ + @Override + public String getNamespaceForVersion(int ver) { + // As of late 2022 the Delivery-X standard is not yet published. See specification: + // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022 + // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3 + // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html + return "urn:factur-x:pdfa:CrossIndustryDocument:despatchadvice:1p0#"; + } - ValidationResult res = document.validate(); + /*** + * internal helper: returns the namespace prefix for the given order-x version number + * @param ver the ox version + * @return the namespace prefix as string, without colon + */ + @Override + public String getPrefixForVersion(int ver) { + return "fx"; + } - // Get validation result - return res.isValid(); - } catch (ValidationException e) { - /* - * the parse method can throw a SyntaxValidationException if the PDF file can't - * be parsed. In this case, the exception contains an instance of - * ValidationResult - */ - return false; - } - } + private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException { + /* + * Parse the PDF file with PreflightParser that inherits from the + * NonSequentialParser. Some additional controls are present to check a set of + * PDF/A requirements. (Stream length consistency, EOL after some Keyword...) + */ + // might add a Format.PDF_A1A as parameter and iterate through A1 and A3 + + try (PreflightDocument document = (PreflightDocument) parser.parse()) { + /* + * Once the syntax validation is done, the parser can provide a + * PreflightDocument (that inherits from PDDocument) This document process the + * end of PDF/A validation. + */ + + ValidationResult res = document.validate(); + + // Get validation result + return res.isValid(); + } catch (ValidationException e) { + /* + * the parse method can throw a SyntaxValidationException if the PDF file can't + * be parsed. In this case, the exception contains an instance of + * ValidationResult + */ + return false; + } + } - @Override - public DXExporterFromA1 setProfile(Profile p) { - return (DXExporterFromA1)super.setProfile(p); - } - @Override - public DXExporterFromA1 setProfile(String profileName) { - return (DXExporterFromA1)super.setProfile(profileName); - } + @Override + public DXExporterFromA1 setProfile(Profile p) { + return (DXExporterFromA1) super.setProfile(p); + } - @Override - public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { - if (!ignorePDFAErrors && !isValidA1(dataSource)) { - throw new IOException("File is not a valid PDF/A input file"); - } - return true; - } + @Override + public DXExporterFromA1 setProfile(String profileName) { + return (DXExporterFromA1) super.setProfile(profileName); + } - public DXExporterFromA1() { - setZUGFeRDVersion(ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion); + @Override + public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { + if (!ignorePDFAErrors && !isValidA1(dataSource)) { + throw new IOException("File is not a valid PDF/A input file"); + } + return true; + } - } + public DXExporterFromA1() { + setZUGFeRDVersion(ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion); - @Override - public DXExporterFromA1 load(String pdfFilename) throws IOException { - return (DXExporterFromA1) super.load(pdfFilename); - } - @Override - public DXExporterFromA1 load(byte[] pdfBinary) throws IOException { - return (DXExporterFromA1) super.load(pdfBinary); - } - @Override - public DXExporterFromA1 load(InputStream pdfSource) throws IOException{ - return (DXExporterFromA1) super.load(pdfSource); - } - @Override - public DXExporterFromA1 setCreator(String creator) { - return (DXExporterFromA1) super.setCreator(creator); - } - @Override - public DXExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) { - return (DXExporterFromA1) super.setConformanceLevel(newLevel); - } - @Override - public DXExporterFromA1 setProducer(String producer){ - return (DXExporterFromA1) super.setProducer(producer); - } - @Override - public DXExporterFromA1 setZUGFeRDVersion(int version){ - return (DXExporterFromA1) super.setZUGFeRDVersion(version); - } - @Override - public DXExporterFromA1 setXML(byte[] zugferdData) throws IOException{ - return (DXExporterFromA1) super.setXML(zugferdData); - } + } - @Override - public DXExporterFromA1 disableAutoClose(boolean disableAutoClose){ - return (DXExporterFromA1) super.disableAutoClose(disableAutoClose); - } - public DXExporterFromA1 convertOnly() { - setAttachZUGFeRDHeaders(false); - return this; - } + @Override + public DXExporterFromA1 load(String pdfFilename) throws IOException { + return (DXExporterFromA1) super.load(pdfFilename); + } + + @Override + public DXExporterFromA1 load(byte[] pdfBinary) throws IOException { + return (DXExporterFromA1) super.load(pdfBinary); + } + + @Override + public DXExporterFromA1 load(InputStream pdfSource) throws IOException { + return (DXExporterFromA1) super.load(pdfSource); + } + + @Override + public DXExporterFromA1 setCreator(String creator) { + return (DXExporterFromA1) super.setCreator(creator); + } + + @Override + public DXExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) { + return (DXExporterFromA1) super.setConformanceLevel(newLevel); + } + + @Override + public DXExporterFromA1 setProducer(String producer) { + return (DXExporterFromA1) super.setProducer(producer); + } + + @Override + public DXExporterFromA1 setZUGFeRDVersion(int version) { + return (DXExporterFromA1) super.setZUGFeRDVersion(version); + } + + @Override + public DXExporterFromA1 setXML(byte[] zugferdData) throws IOException { + return (DXExporterFromA1) super.setXML(zugferdData); + } + + @Override + public DXExporterFromA1 disableAutoClose(boolean disableAutoClose) { + return (DXExporterFromA1) super.disableAutoClose(disableAutoClose); + } + + public DXExporterFromA1 convertOnly() { + setAttachZUGFeRDHeaders(false); + return this; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA3.java b/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA3.java index 7a6e128..7c3a54d 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA3.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/DXExporterFromA3.java @@ -20,26 +20,10 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.transform.TransformerException; - +import jakarta.activation.DataSource; +import jakarta.activation.FileDataSource; import org.apache.pdfbox.Loader; -import org.apache.pdfbox.cos.COSArray; -import org.apache.pdfbox.cos.COSBase; -import org.apache.pdfbox.cos.COSDictionary; -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.cos.COSObject; +import org.apache.pdfbox.cos.*; import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentCatalog; @@ -65,698 +49,702 @@ import org.mustangproject.EStandard; import org.mustangproject.FileAttachment; -import jakarta.activation.DataSource; -import jakarta.activation.FileDataSource; +import javax.xml.transform.TransformerException; +import java.io.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 { - protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE; - protected ArrayList fileAttachments = new ArrayList<>(); + protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE; + protected ArrayList fileAttachments = new ArrayList<>(); - /** - * This flag controls whether or not the metadata is overwritten, or kind of merged. - * The merging probably needs to be overhauled, but for my purpose it was good enough. - */ - protected boolean overwrite = true; + /** + * This flag controls whether or not the metadata is overwritten, or kind of merged. + * The merging probably needs to be overhauled, but for my purpose it was good enough. + */ + protected boolean overwrite = true; - private boolean disableAutoClose; - private boolean fileAttached = false; - private Profile profile = null; - private boolean documentPrepared = false; + private boolean disableAutoClose; + private boolean fileAttached = false; + private Profile profile = null; + private boolean documentPrepared = false; - /** - * Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set, - * in which case passing a IZUGFeRDExportableTransaction is not necessary. By - * default it is null meaning the caller needs to pass a - * IZUGFeRDExportableTransaction for the XML to be populated. - */ - protected PDMetadata metadata = null; - /** - * Producer attribute for PDF - */ - protected String producer = "mustangproject"; - /** - * Author/Creator attribute for PDF - */ - protected String creator = "mustangproject"; - /** - * CreatorTool - */ - protected String creatorTool = "mustangproject"; + /** + * Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set, + * in which case passing a IZUGFeRDExportableTransaction is not necessary. By + * default it is null meaning the caller needs to pass a + * IZUGFeRDExportableTransaction for the XML to be populated. + */ + protected PDMetadata metadata = null; + /** + * Producer attribute for PDF + */ + protected String producer = "mustangproject"; + /** + * Author/Creator attribute for PDF + */ + protected String creator = "mustangproject"; + /** + * CreatorTool + */ + protected String creatorTool = "mustangproject"; - /** - * @deprecated author is never set yet - */ - @Deprecated - protected String author; - /** - * @deprecated title is never set yet - */ - @Deprecated - protected String title; - /** - * @deprecated subject is never set yet - */ - @Deprecated - protected String subject; + /** + * @deprecated author is never set yet + */ + @Deprecated + protected String author; + /** + * @deprecated title is never set yet + */ + @Deprecated + protected String title; + /** + * @deprecated subject is never set yet + */ + @Deprecated + protected String subject; - /** - * OrderX document type. As of version 1.0 it may be - * ORDER, ORDER_RESPONSE, or ORDER_CHANGE - */ - protected String despatchAdviceDocumentType = "DESPATCHADVICE"; + /** + * OrderX document type. As of version 1.0 it may be + * ORDER, ORDER_RESPONSE, or ORDER_CHANGE + */ + protected String despatchAdviceDocumentType = "DESPATCHADVICE"; - private boolean attachZUGFeRDHeaders = true; + private boolean attachZUGFeRDHeaders = true; - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfFilename filename of an PDF/A1 compliant document - */ - @Override - public DXExporterFromA3 load(String pdfFilename) throws IOException { + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfFilename filename of an PDF/A1 compliant document + */ + @Override + public DXExporterFromA3 load(String pdfFilename) throws IOException { - ensurePDFIsValid(new FileDataSource(pdfFilename)); - try (FileInputStream pdf = new FileInputStream(pdfFilename)) { - return load(readAllBytes(pdf)); - } - } + ensurePDFIsValid(new FileDataSource(pdfFilename)); + try (FileInputStream pdf = new FileInputStream(pdfFilename)) { + return load(readAllBytes(pdf)); + } + } - @Override - public IXMLProvider getProvider() { - return xmlProvider; - } + @Override + public IXMLProvider getProvider() { + return xmlProvider; + } - @Override - public DXExporterFromA3 setProfile(Profile p) { - this.profile = p; - if (xmlProvider != null) { - xmlProvider.setProfile(p); - } - return this; - } + @Override + public DXExporterFromA3 setProfile(Profile p) { + this.profile = p; + if (xmlProvider != null) { + xmlProvider.setProfile(p); + } + return this; + } - @Override - public DXExporterFromA3 setProfile(String profilename) { - this.profile = Profiles.getByName(profilename); + @Override + public DXExporterFromA3 setProfile(String profilename) { + this.profile = Profiles.getByName(profilename); - if (xmlProvider != null) { - xmlProvider.setProfile(this.profile); - } - return this; - } + if (xmlProvider != null) { + xmlProvider.setProfile(this.profile); + } + return this; + } - @Override - public DXExporterFromA3 addAdditionalFile(String name, byte[] content) { - fileAttachments.add(new FileAttachment(name, "text/xml", "Supplement", content).setDescription("ZUGFeRD extension/additional data")); - return this; - } + @Override + public DXExporterFromA3 addAdditionalFile(String name, byte[] content) { + fileAttachments.add(new FileAttachment(name, "text/xml", "Supplement", content).setDescription("ZUGFeRD extension/additional data")); + return this; + } + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfBinary binary of a PDF/A1 compliant document + */ + @Override + public DXExporterFromA3 load(byte[] pdfBinary) throws IOException { + ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); + doc = Loader.loadPDF(pdfBinary); + return this; + } - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfBinary binary of a PDF/A1 compliant document - */ - @Override - public DXExporterFromA3 load(byte[] pdfBinary) throws IOException { - ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); - doc = Loader.loadPDF(pdfBinary); - return this; - } + public DXExporterFromA3() { + super(); + } - public DXExporterFromA3() { - super(); - } + @Override + public void attachFile(FileAttachment file) { + fileAttachments.add(file); + } - @Override - public void attachFile(FileAttachment file) { - fileAttachments.add(file); - } + @Override + public void attachFile(String filename, byte[] data, String mimetype, String relation) { + FileAttachment fa = new FileAttachment(filename, mimetype, relation, data); + fileAttachments.add(fa); + } - @Override - public void attachFile(String filename, byte[] data, String mimetype, String relation) { - FileAttachment fa = new FileAttachment(filename, mimetype, relation, data); - fileAttachments.add(fa); - } + /*** + * Perform the final export to a now ZUGFeRD-enriched PDF file + * @param ZUGFeRDfilename the pdf file name + * @throws IOException if anything is wrong in the target location + */ + @Override + public void export(String ZUGFeRDfilename) throws IOException { + if (!documentPrepared) { + prepareDocument(); + } + if ((!fileAttached) && attachZUGFeRDHeaders) { + throw new IOException( + "File must be attached (usually with setTransaction) before perfoming this operation"); + } + doc.save(ZUGFeRDfilename); + if (!disableAutoClose) { + close(); + } + } - /*** - * Perform the final export to a now ZUGFeRD-enriched PDF file - * @param ZUGFeRDfilename the pdf file name - * @throws IOException if anything is wrong in the target location - */ - @Override - public void export(String ZUGFeRDfilename) throws IOException { - if (!documentPrepared) { - prepareDocument(); - } - if ((!fileAttached) && (attachZUGFeRDHeaders)) { - throw new IOException( - "File must be attached (usually with setTransaction) before perfoming this operation"); - } - doc.save(ZUGFeRDfilename); - if (!disableAutoClose) { - close(); - } - } + @Override + public void close() throws IOException { + if (doc != null) { + doc.close(); + } + } - @Override - public void close() throws IOException { - if (doc != null) { - doc.close(); - } - } + /*** + * Perform the final export to a now ZUGFeRD-enriched PDF file as OutputStream + * @param output the OutputStream + * @throws IOException if anything is wrong in the OutputStream + */ + @Override + public void export(OutputStream output) throws IOException { + if (!documentPrepared) { + prepareDocument(); + } + if ((!fileAttached) && attachZUGFeRDHeaders) { + throw new IOException( + "File must be attached (usually with setTransaction) before perfoming this operation"); + } + doc.save(output); + if (!disableAutoClose) { + close(); + } + } - /*** - * Perform the final export to a now ZUGFeRD-enriched PDF file as OutputStream - * @param output the OutputStream - * @throws IOException if anything is wrong in the OutputStream - */ - @Override - public void export(OutputStream output) throws IOException { - if (!documentPrepared) { - prepareDocument(); - } - if ((!fileAttached) && (attachZUGFeRDHeaders)) { - throw new IOException( - "File must be attached (usually with setTransaction) before perfoming this operation"); - } - doc.save(output); - if (!disableAutoClose) { - close(); - } - } + /** + * Embeds an external file (generic - any type allowed) in the PDF. + * The embedding is done in the default PDF document. + * + * @param filename name of the file that will become attachment name in the PDF + * @param relationship how the file relates to the content, e.g. "Alternative" + * @param description Human-readable description of the file content + * @param subType type of the data e.g. could be "text/xml" - mime like + * @param data the binary data of the file/attachment + * @throws IOException if anything is wrong with filename + */ + @Override + public void PDFAttachGenericFile(String filename, String relationship, String description, + String subType, byte[] data) throws IOException { + PDFAttachGenericFile(this.doc, filename, relationship, description, subType, data); + } - /** - * Embeds an external file (generic - any type allowed) in the PDF. - * The embedding is done in the default PDF document. - * - * @param filename name of the file that will become attachment name in the PDF - * @param relationship how the file relates to the content, e.g. "Alternative" - * @param description Human-readable description of the file content - * @param subType type of the data e.g. could be "text/xml" - mime like - * @param data the binary data of the file/attachment - * @throws IOException if anything is wrong with filename - */ - @Override - public void PDFAttachGenericFile(String filename, String relationship, String description, - String subType, byte[] data) throws IOException { - PDFAttachGenericFile(this.doc, filename, relationship, description, subType, data); - } + /** + * Embeds an external file (generic - any type allowed) in the PDF. + * + * @param doc PDDocument to attach the file to. + * @param filename name of the file that will become attachment name in the PDF + * @param relationship how the file relates to the content, e.g. "Alternative" + * @param description Human-readable description of the file content + * @param subType type of the data e.g. could be "text/xml" - mime like + * @param data the binary data of the file/attachment + * @throws IOException if anything is wrong with filename + */ + @Override + public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description, + String subType, byte[] data) throws IOException { + fileAttached = true; - /** - * Embeds an external file (generic - any type allowed) in the PDF. - * - * @param doc PDDocument to attach the file to. - * @param filename name of the file that will become attachment name in the PDF - * @param relationship how the file relates to the content, e.g. "Alternative" - * @param description Human-readable description of the file content - * @param subType type of the data e.g. could be "text/xml" - mime like - * @param data the binary data of the file/attachment - * @throws IOException if anything is wrong with filename - */ - @Override - public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description, - String subType, byte[] data) throws IOException { - fileAttached = true; + PDComplexFileSpecification fs = new PDComplexFileSpecification(); + fs.setFile(filename); - PDComplexFileSpecification fs = new PDComplexFileSpecification(); - fs.setFile(filename); + COSDictionary dict = fs.getCOSObject(); + dict.setName("AFRelationship", relationship); + dict.setString("UF", filename); + dict.setString("Desc", description); - COSDictionary dict = fs.getCOSObject(); - dict.setName("AFRelationship", relationship); - dict.setString("UF", filename); - dict.setString("Desc", description); + ByteArrayInputStream fakeFile = new ByteArrayInputStream(data); + PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile); +// ef.addCompression(); + ef.setSubtype(subType); + ef.setSize(data.length); + ef.setCreationDate(new GregorianCalendar()); - ByteArrayInputStream fakeFile = new ByteArrayInputStream(data); - PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile); -// ef.addCompression(); - ef.setSubtype(subType); - ef.setSize(data.length); - ef.setCreationDate(new GregorianCalendar()); + ef.setModDate(Calendar.getInstance()); - ef.setModDate(Calendar.getInstance()); + fs.setEmbeddedFile(ef); - fs.setEmbeddedFile(ef); + // In addition make sure the embedded file is set under /UF + dict = fs.getCOSObject(); + COSDictionary efDict = (COSDictionary) dict.getDictionaryObject(COSName.EF); + COSBase lowerLevelFile = efDict.getItem(COSName.F); + efDict.setItem(COSName.UF, lowerLevelFile); - // In addition make sure the embedded file is set under /UF - dict = fs.getCOSObject(); - COSDictionary efDict = (COSDictionary) dict.getDictionaryObject(COSName.EF); - COSBase lowerLevelFile = efDict.getItem(COSName.F); - efDict.setItem(COSName.UF, lowerLevelFile); + // now add the entry to the embedded file tree and set in the document. + PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); + PDEmbeddedFilesNameTreeNode efTree = names.getEmbeddedFiles(); + if (efTree == null) { + efTree = new PDEmbeddedFilesNameTreeNode(); + } - // now add the entry to the embedded file tree and set in the document. - PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); - PDEmbeddedFilesNameTreeNode efTree = names.getEmbeddedFiles(); - if (efTree == null) { - efTree = new PDEmbeddedFilesNameTreeNode(); - } + Map namesMap = new HashMap<>(); - Map namesMap = new HashMap<>(); + Map oldNamesMap = efTree.getNames(); + if (oldNamesMap != null) { + for (String key : oldNamesMap.keySet()) { + namesMap.put(key, oldNamesMap.get(key)); + } + } + namesMap.put(filename, fs); + efTree.setNames(namesMap); - Map oldNamesMap = efTree.getNames(); - if (oldNamesMap != null) { - for (String key : oldNamesMap.keySet()) { - namesMap.put(key, oldNamesMap.get(key)); - } - } - namesMap.put(filename, fs); - efTree.setNames(namesMap); + names.setEmbeddedFiles(efTree); + doc.getDocumentCatalog().setNames(names); - names.setEmbeddedFiles(efTree); - doc.getDocumentCatalog().setNames(names); + // AF entry (Array) in catalog with the FileSpec + COSBase AFEntry = doc.getDocumentCatalog().getCOSObject().getItem("AF"); + if (AFEntry == null) { + COSArray cosArray = new COSArray(); + cosArray.add(fs); + doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); + } else if (AFEntry instanceof COSArray) { + COSArray cosArray = (COSArray) AFEntry; + cosArray.add(fs); + doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); + } else if ((AFEntry instanceof COSObject) && + ((COSObject) AFEntry).getObject() instanceof COSArray) { + COSArray cosArray = (COSArray) ((COSObject) AFEntry).getObject(); + cosArray.add(fs); + } else { + throw new IOException("Unexpected object type for PDFDocument/Catalog/COSDictionary/Item(AF)"); + } + } - // AF entry (Array) in catalog with the FileSpec - COSBase AFEntry = doc.getDocumentCatalog().getCOSObject().getItem("AF"); - if ((AFEntry == null)) { - COSArray cosArray = new COSArray(); - cosArray.add(fs); - doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); - } else if (AFEntry instanceof COSArray) { - COSArray cosArray = (COSArray) AFEntry; - cosArray.add(fs); - doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); - } else if ((AFEntry instanceof COSObject) && - ((COSObject) AFEntry).getObject() instanceof COSArray) { - COSArray cosArray = (COSArray) ((COSObject) AFEntry).getObject(); - cosArray.add(fs); - } else { - throw new IOException("Unexpected object type for PDFDocument/Catalog/COSDictionary/Item(AF)"); - } - } + /** + * Sets the ZUGFeRD XML data to be attached as a single byte array. This is + * useful for use-cases where the XML has already been produced by some external + * API or component. + * + * @param zugferdData XML data to be set as a byte array (XML file in raw form). + * @throws IOException (should not happen) + */ + @Override + public DXExporterFromA3 setXML(byte[] zugferdData) throws IOException { + CustomXMLProvider cus = new CustomXMLProvider(); + // As of late 2022 the Delivery-X standard is not yet published. See specification: + // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022 + // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3 + // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html + cus.setProfile(Profiles.getByName(EStandard.despatchadvice, "PILOT", 1)); - /** - * Sets the ZUGFeRD XML data to be attached as a single byte array. This is - * useful for use-cases where the XML has already been produced by some external - * API or component. - * - * @param zugferdData XML data to be set as a byte array (XML file in raw form). - * @throws IOException (should not happen) - */ - @Override - public DXExporterFromA3 setXML(byte[] zugferdData) throws IOException { - CustomXMLProvider cus = new CustomXMLProvider(); - // As of late 2022 the Delivery-X standard is not yet published. See specification: - // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022 - // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3 - // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html - cus.setProfile(Profiles.getByName(EStandard.despatchadvice, "PILOT", 1)); + cus.setXML(zugferdData); + this.setXMLProvider(cus); + prepare(); + return this; + } - cus.setXML(zugferdData); - this.setXMLProvider(cus); - prepare(); - return this; - } + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfSource source to read a PDF/A1 compliant document from + */ + @Override + public DXExporterFromA3 load(InputStream pdfSource) throws IOException { + return load(readAllBytes(pdfSource)); + } - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfSource source to read a PDF/A1 compliant document from - */ - @Override - public DXExporterFromA3 load(InputStream pdfSource) throws IOException { - return load(readAllBytes(pdfSource)); - } + @Override + public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { + return true; + } - @Override - public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { - return true; - } + private static byte[] readAllBytes(InputStream in) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + IOUtils.copy(in, buffer); + return buffer.toByteArray(); + } - private static byte[] readAllBytes(InputStream in) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - IOUtils.copy(in, buffer); - return buffer.toByteArray(); - } + /** + * All files are PDF/A-3, setConformance refers to the level conformance. + *

+ * PDF/A-3 has three coformance levels, called "A", "U" and "B". + *

+ * PDF/A-3-B where B means only visually preservable, U -standard for Mustang- + * means visually and unicode preservable and A means full compliance, i.e. + * visually, unicode and structurally preservable and tagged PDF, i.e. useful + * metainformation for blind people. + *

+ * Feel free to pass "A" as new level if you know what you are doing :-) + */ + @Override + public DXExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) { + conformanceLevel = newLevel; + return this; + } - /** - * All files are PDF/A-3, setConformance refers to the level conformance. - *

- * PDF/A-3 has three coformance levels, called "A", "U" and "B". - *

- * PDF/A-3-B where B means only visually preservable, U -standard for Mustang- - * means visually and unicode preservable and A means full compliance, i.e. - * visually, unicode and structurally preservable and tagged PDF, i.e. useful - * metainformation for blind people. - *

- * Feel free to pass "A" as new level if you know what you are doing :-) - */ - @Override - public DXExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) { - conformanceLevel = newLevel; - return this; - } + @Override + public DXExporterFromA3 setCreator(String creator) { + this.creator = creator; + return this; + } - @Override - public DXExporterFromA3 setCreator(String creator) { - this.creator = creator; - return this; - } - - @Override - public DXExporterFromA3 setCreatorTool(String creatorTool) { - this.creatorTool = creatorTool; - return this; - } + @Override + public DXExporterFromA3 setCreatorTool(String creatorTool) { + this.creatorTool = creatorTool; + return this; + } - @Override - public DXExporterFromA3 setProducer(String producer) { - this.producer = producer; - return this; - } + @Override + public DXExporterFromA3 setProducer(String producer) { + this.producer = producer; + return this; + } - /** - * Sets the property for DocumentType. - * - * @param DocumentType String, usually DESPATCHADVICE - * - * @return this exporter - */ - public DXExporterFromA3 setDocumentType(String DocumentType) - { - this.despatchAdviceDocumentType = DocumentType; + /** + * Sets the property for DocumentType. + * + * @param DocumentType String, usually DESPATCHADVICE + * + * @return this exporter + */ + public DXExporterFromA3 setDocumentType(String DocumentType) + { + this.despatchAdviceDocumentType = DocumentType; - return this; - } + return this; + } - @Override - protected DXExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) { - this.attachZUGFeRDHeaders = attachHeaders; - return this; - } + @Override + protected DXExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) { + this.attachZUGFeRDHeaders = attachHeaders; + return this; + } - /** - * This will add both the RDF-indication which embedded file is Zugferd and the - * neccessary PDF/A schema extension description to be able to add this - * information to RDF - * - * @param metadata the PDFbox XMPMetadata object - */ - @Override - protected void addXMP(XMPMetadata metadata) { + /** + * This will add both the RDF-indication which embedded file is Zugferd and the + * neccessary PDF/A schema extension description to be able to add this + * information to RDF + * + * @param metadata the PDFbox XMPMetadata object + */ + @Override + protected void addXMP(XMPMetadata metadata) { - if (attachZUGFeRDHeaders) { - // As of late 2022 the Delivery-X standard is not yet published. See specification: - // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022 - // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3 - // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html - XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, 1, true, xmlProvider.getProfile(), - "urn:factur-x:pdfa:CrossIndustryDocument:despatchadvice:1p0#", "fx", - "cida.xml", "1.0"); - zf.setType(this.despatchAdviceDocumentType); + if (attachZUGFeRDHeaders) { + // As of late 2022 the Delivery-X standard is not yet published. See specification: + // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022 + // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3 + // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html + XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, 1, true, xmlProvider.getProfile(), + "urn:factur-x:pdfa:CrossIndustryDocument:despatchadvice:1p0#", "fx", + "cida.xml", "1.0"); + zf.setType(this.despatchAdviceDocumentType); - metadata.addSchema(zf); - // also add the schema extensions... - XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(this, metadata, 1, attachZUGFeRDHeaders, EStandard.despatchadvice); - pdfaex.setZUGFeRDVersion(1); - metadata.addSchema(pdfaex); - } + metadata.addSchema(zf); + // also add the schema extensions... + XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(this, metadata, 1, attachZUGFeRDHeaders, EStandard.despatchadvice); + pdfaex.setZUGFeRDVersion(1); + metadata.addSchema(pdfaex); + } - } + } - /** - * Embeds the Zugferd XML structure in a file named ZUGFeRD-invoice.xml. - * - * @param trans a IZUGFeRDExportableTransaction that provides the data-model to - * populate the XML. This parameter may be null, if so the XML data - * should hav ebeen set via - * setZUGFeRDXMLData(byte[] zugferdData) - * @throws IOException if anything is wrong with already loaded PDF - */ - @Override - public IExporter setTransaction(IExportableTransaction trans) throws IOException { - this.trans = trans; - return prepare(); - } + /** + * Embeds the Zugferd XML structure in a file named ZUGFeRD-invoice.xml. + * + * @param trans a IZUGFeRDExportableTransaction that provides the data-model to + * populate the XML. This parameter may be null, if so the XML data + * should hav ebeen set via + * setZUGFeRDXMLData(byte[] zugferdData) + * @throws IOException if anything is wrong with already loaded PDF + */ + @Override + public IExporter setTransaction(IExportableTransaction trans) throws IOException { + this.trans = trans; + return prepare(); + } - @Override - public IExporter prepare() throws IOException { - prepareDocument(); - xmlProvider.generateXML(trans); - String filename = "cida.xml"; - PDFAttachGenericFile(doc, filename, "Alternative", - "Delivery metadata", - "text/xml", xmlProvider.getXML()); + @Override + public IExporter prepare() throws IOException { + prepareDocument(); + xmlProvider.generateXML(trans); + String filename = "cida.xml"; + PDFAttachGenericFile(doc, filename, "Alternative", + "Delivery metadata", + "text/xml", xmlProvider.getXML()); - for (FileAttachment attachment : fileAttachments) { - PDFAttachGenericFile(doc, attachment.getFilename(), attachment.getRelation(), attachment.getDescription(), attachment.getMimetype(), attachment.getData()); - } + for (FileAttachment attachment : fileAttachments) { + PDFAttachGenericFile(doc, attachment.getFilename(), attachment.getRelation(), attachment.getDescription(), attachment.getMimetype(), attachment.getData()); + } - return this; - } + return this; + } - /** - * Reads the XMPMetadata from the PDDocument, if it exists. - * Otherwise creates XMPMetadata. - */ - @Override - protected XMPMetadata getXmpMetadata() throws IOException { - PDMetadata meta = doc.getDocumentCatalog().getMetadata(); - if ((meta != null) && (meta.getLength() > 0)) { - try { - DomXmpParser xmpParser = new DomXmpParser(); - return xmpParser.parse(meta.toByteArray()); - } catch (XmpParsingException | IOException e) { - throw new IOException(e); - } - } - return XMPMetadata.createXMPMetadata(); - } + /** + * Reads the XMPMetadata from the PDDocument, if it exists. + * Otherwise creates XMPMetadata. + */ + @Override + protected XMPMetadata getXmpMetadata() throws IOException { + PDMetadata meta = doc.getDocumentCatalog().getMetadata(); + if ((meta != null) && (meta.getLength() > 0)) { + try { + DomXmpParser xmpParser = new DomXmpParser(); + return xmpParser.parse(meta.toByteArray()); + } catch (XmpParsingException | IOException e) { + throw new IOException(e); + } + } + return XMPMetadata.createXMPMetadata(); + } - @Override - protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - new XmpSerializer().serialize(xmpMetadata, buffer, true); // see https://github.com/ZUGFeRD/mustangproject/issues/44 - return buffer.toByteArray(); - } + @Override + protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + new XmpSerializer().serialize(xmpMetadata, buffer, true); // see https://github.com/ZUGFeRD/mustangproject/issues/44 + return buffer.toByteArray(); + } - /** - * Sets the producer if the overwrite flag is set or the producer is not already set. - * Sets the PDFVersion to 1.4 if the field is empty. - */ - @Override - protected void writeAdobePDFSchema(XMPMetadata xmp) { - AdobePDFSchema pdf = getAdobePDFSchema(xmp); - if (overwrite || isEmpty(pdf.getProducer())) - pdf.setProducer(producer); - } + /** + * Sets the producer if the overwrite flag is set or the producer is not already set. + * Sets the PDFVersion to 1.4 if the field is empty. + */ + @Override + protected void writeAdobePDFSchema(XMPMetadata xmp) { + AdobePDFSchema pdf = getAdobePDFSchema(xmp); + if (overwrite || isEmpty(pdf.getProducer())) + pdf.setProducer(producer); + } - /** - * Returns the AdobePDFSchema from the XMPMetadata if it exists. - * If the overwrite flag is set or no AdobePDFSchema exists in the XMPMetadata, it is created, added and returned. - */ - @Override - protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) { - AdobePDFSchema pdf = xmp.getAdobePDFSchema(); - if (pdf != null) - if (overwrite) - xmp.removeSchema(pdf); - else - return pdf; - return xmp.createAndAddAdobePDFSchema(); - } + /** + * Returns the AdobePDFSchema from the XMPMetadata if it exists. + * If the overwrite flag is set or no AdobePDFSchema exists in the XMPMetadata, it is created, added and returned. + */ + @Override + protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) { + AdobePDFSchema pdf = xmp.getAdobePDFSchema(); + if (pdf != null) + if (overwrite) + xmp.removeSchema(pdf); + else + return pdf; + return xmp.createAndAddAdobePDFSchema(); + } - @Override - protected void writePDFAIdentificationSchema(XMPMetadata xmp) { - PDFAIdentificationSchema pdfaid = getPDFAIdentificationSchema(xmp); - if (overwrite || isEmpty(pdfaid.getConformance())) { - try { - pdfaid.setConformance(conformanceLevel.getLetter()); - } catch (BadFieldValueException ex) { - // This should be impossible, because it would occur only if an illegal - // conformance level is supplied, - // however the enum enforces that the conformance level is valid. - throw new RuntimeException(ex); - } - } - pdfaid.setPart(3); - } + @Override + protected void writePDFAIdentificationSchema(XMPMetadata xmp) { + PDFAIdentificationSchema pdfaid = getPDFAIdentificationSchema(xmp); + if (overwrite || isEmpty(pdfaid.getConformance())) { + try { + pdfaid.setConformance(conformanceLevel.getLetter()); + } catch (BadFieldValueException ex) { + // This should be impossible, because it would occur only if an illegal + // conformance level is supplied, + // however the enum enforces that the conformance level is valid. + throw new RuntimeException(ex); + } + } + pdfaid.setPart(3); + } - @Override - protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { - PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema(); - if (pdfaid != null) - if (overwrite) - xmp.removeSchema(pdfaid); - else - return pdfaid; - return xmp.createAndAddPDFAIdentificationSchema(); - } + @Override + protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { + PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema(); + if (pdfaid != null) + if (overwrite) + xmp.removeSchema(pdfaid); + else + return pdfaid; + return xmp.createAndAddPDFAIdentificationSchema(); + } - @Override - protected void writeDublinCoreSchema(XMPMetadata xmp) { - DublinCoreSchema dc = getDublinCoreSchema(xmp); - if (dc.getFormat() == null) - dc.setFormat("application/pdf"); - if ((overwrite || dc.getCreators() == null || dc.getCreators().isEmpty()) && creator != null) - dc.addCreator(creator); - if ((overwrite || dc.getDates() == null || dc.getDates().isEmpty()) && creator != null) - dc.addDate(Calendar.getInstance()); + @Override + protected void writeDublinCoreSchema(XMPMetadata xmp) { + DublinCoreSchema dc = getDublinCoreSchema(xmp); + if (dc.getFormat() == null) + dc.setFormat("application/pdf"); + if ((overwrite || dc.getCreators() == null || dc.getCreators().isEmpty()) && creator != null) + dc.addCreator(creator); + if ((overwrite || dc.getDates() == null || dc.getDates().isEmpty()) && creator != null) + dc.addDate(Calendar.getInstance()); - ArrayProperty titleProperty = dc.getTitleProperty(); - if (titleProperty != null) { - if (overwrite && !isEmpty(title)) { - dc.removeProperty(titleProperty); - dc.setTitle(title); - } else if (titleProperty.getElementsAsString().stream().anyMatch("Untitled"::equalsIgnoreCase)) { - // remove unfitting ghostscript default - dc.removeProperty(titleProperty); - } - } else if (!isEmpty(title)) { - dc.setTitle(title); - } - } + ArrayProperty titleProperty = dc.getTitleProperty(); + if (titleProperty != null) { + if (overwrite && !isEmpty(title)) { + dc.removeProperty(titleProperty); + dc.setTitle(title); + } else if (titleProperty.getElementsAsString().stream().anyMatch("Untitled"::equalsIgnoreCase)) { + // remove unfitting ghostscript default + dc.removeProperty(titleProperty); + } + } else if (!isEmpty(title)) { + dc.setTitle(title); + } + } - @Override - protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) { - DublinCoreSchema dc = xmp.getDublinCoreSchema(); - if (dc != null) - if (overwrite) - xmp.removeSchema(dc); - else - return dc; - return xmp.createAndAddDublinCoreSchema(); - } + @Override + protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) { + DublinCoreSchema dc = xmp.getDublinCoreSchema(); + if (dc != null) + if (overwrite) + xmp.removeSchema(dc); + else + return dc; + return xmp.createAndAddDublinCoreSchema(); + } - @Override - protected void writeXMLBasicSchema(XMPMetadata xmp) { - XMPBasicSchema xsb = getXmpBasicSchema(xmp); - if (overwrite || isEmpty(xsb.getCreatorTool()) || "UnknownApplication".equals(xsb.getCreatorTool())) - xsb.setCreatorTool(creatorTool); - if (overwrite || xsb.getCreateDate() == null) - xsb.setCreateDate(Calendar.getInstance()); - } + @Override + protected void writeXMLBasicSchema(XMPMetadata xmp) { + XMPBasicSchema xsb = getXmpBasicSchema(xmp); + if (overwrite || isEmpty(xsb.getCreatorTool()) || "UnknownApplication".equals(xsb.getCreatorTool())) + xsb.setCreatorTool(creatorTool); + if (overwrite || xsb.getCreateDate() == null) + xsb.setCreateDate(Calendar.getInstance()); + } - @Override - protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) { - XMPBasicSchema xsb = xmp.getXMPBasicSchema(); - if (xsb != null) - if (overwrite) - xmp.removeSchema(xsb); - else - return xsb; - return xmp.createAndAddXMPBasicSchema(); - } + @Override + protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) { + XMPBasicSchema xsb = xmp.getXMPBasicSchema(); + if (xsb != null) + if (overwrite) + xmp.removeSchema(xsb); + else + return xsb; + return xmp.createAndAddXMPBasicSchema(); + } - @Override - protected void writeDocumentInformation() { - String fullProducer = producer + " (via mustangproject.org " + Version.VERSION + ")"; - PDDocumentInformation info = doc.getDocumentInformation(); - if (overwrite || info.getCreationDate() == null) - info.setCreationDate(Calendar.getInstance()); - if (overwrite || info.getModificationDate() == null) - info.setModificationDate(Calendar.getInstance()); - if (overwrite || (isEmpty(info.getAuthor()) && !isEmpty(author))) - info.setAuthor(author); - if (overwrite || (isEmpty(info.getProducer()) && !isEmpty(fullProducer))) - info.setProducer(fullProducer); - if (overwrite || (isEmpty(info.getCreator()) && !isEmpty(creator))) - info.setCreator(creator); - if (overwrite || (isEmpty(info.getTitle()) && !isEmpty(title))) - info.setTitle(title); - if (overwrite || (isEmpty(info.getSubject()) && !isEmpty(subject))) - info.setSubject(subject); - } + @Override + protected void writeDocumentInformation() { + String fullProducer = producer + " (via mustangproject.org " + Version.VERSION + ")"; + PDDocumentInformation info = doc.getDocumentInformation(); + if (overwrite || info.getCreationDate() == null) + info.setCreationDate(Calendar.getInstance()); + if (overwrite || info.getModificationDate() == null) + info.setModificationDate(Calendar.getInstance()); + if (overwrite || (isEmpty(info.getAuthor()) && !isEmpty(author))) + info.setAuthor(author); + if (overwrite || (isEmpty(info.getProducer()) && !isEmpty(fullProducer))) + info.setProducer(fullProducer); + if (overwrite || (isEmpty(info.getCreator()) && !isEmpty(creator))) + info.setCreator(creator); + if (overwrite || (isEmpty(info.getTitle()) && !isEmpty(title))) + info.setTitle(title); + if (overwrite || (isEmpty(info.getSubject()) && !isEmpty(subject))) + info.setSubject(subject); + } - /** - * Adds an OutputIntent and the sRGB color profile if no OutputIntent exist - */ - @Override - protected void addSRGBOutputIntend() throws IOException { - if (!doc.getDocumentCatalog().getOutputIntents().isEmpty()) { - return; - } + /** + * Adds an OutputIntent and the sRGB color profile if no OutputIntent exist + */ + @Override + protected void addSRGBOutputIntend() throws IOException { + if (!doc.getDocumentCatalog().getOutputIntents().isEmpty()) { + return; + } - try { - InputStream colorProfile = Thread.currentThread().getContextClassLoader().getResourceAsStream("sRGB.icc"); - if (colorProfile != null) { - PDOutputIntent intent = new PDOutputIntent(doc, colorProfile); - intent.setInfo("sRGB IEC61966-2.1"); - intent.setOutputCondition("sRGB IEC61966-2.1"); - intent.setOutputConditionIdentifier("sRGB IEC61966-2.1"); - intent.setRegistryName("http://www.color.org"); - doc.getDocumentCatalog().addOutputIntent(intent); - } - } catch (IOException e) { - throw e; - } - } + try { + InputStream colorProfile = Thread.currentThread().getContextClassLoader().getResourceAsStream("sRGB.icc"); + if (colorProfile != null) { + PDOutputIntent intent = new PDOutputIntent(doc, colorProfile); + intent.setInfo("sRGB IEC61966-2.1"); + intent.setOutputCondition("sRGB IEC61966-2.1"); + intent.setOutputConditionIdentifier("sRGB IEC61966-2.1"); + intent.setRegistryName("http://www.color.org"); + doc.getDocumentCatalog().addOutputIntent(intent); + } + } catch (IOException e) { + throw e; + } + } - /** - * Adds a MarkInfo element to the PDF if it doesn't already exist and sets it as marked. - */ - @Override - protected void setMarked() { - PDDocumentCatalog catalog = doc.getDocumentCatalog(); - if (catalog.getMarkInfo() == null) { - catalog.setMarkInfo(new PDMarkInfo(doc.getPages().getCOSObject())); - } - catalog.getMarkInfo().setMarked(true); - } + /** + * Adds a MarkInfo element to the PDF if it doesn't already exist and sets it as marked. + */ + @Override + protected void setMarked() { + PDDocumentCatalog catalog = doc.getDocumentCatalog(); + if (catalog.getMarkInfo() == null) { + catalog.setMarkInfo(new PDMarkInfo(doc.getPages().getCOSObject())); + } + catalog.getMarkInfo().setMarked(true); + } - /** - * Adds a StructureTreeRoot element to the PDF if it doesn't already exist. - */ - @Override - protected void addStructureTreeRoot() { - if (doc.getDocumentCatalog().getStructureTreeRoot() == null) { - doc.getDocumentCatalog().setStructureTreeRoot(new PDStructureTreeRoot()); - } - } + /** + * Adds a StructureTreeRoot element to the PDF if it doesn't already exist. + */ + @Override + protected void addStructureTreeRoot() { + if (doc.getDocumentCatalog().getStructureTreeRoot() == null) { + doc.getDocumentCatalog().setStructureTreeRoot(new PDStructureTreeRoot()); + } + } - /** - * @return if pdf file will be automatically closed after adding ZF - */ - @Override - public boolean isAutoCloseDisabled() { - return disableAutoClose; - } + /** + * @return if pdf file will be automatically closed after adding ZF + */ + @Override + public boolean isAutoCloseDisabled() { + return disableAutoClose; + } - /** - * @param disableAutoClose prevent PDF file from being closed after adding ZF - */ - @Override - public DXExporterFromA3 disableAutoClose(boolean disableAutoClose) { - this.disableAutoClose = disableAutoClose; - return this; - } + /** + * @param disableAutoClose prevent PDF file from being closed after adding ZF + */ + @Override + public DXExporterFromA3 disableAutoClose(boolean disableAutoClose) { + this.disableAutoClose = disableAutoClose; + return this; + } - @Override - protected void setXMLProvider(IXMLProvider p) { - this.xmlProvider = p; - if (profile != null) { - xmlProvider.setProfile(profile); - } - } + @Override + protected void setXMLProvider(IXMLProvider p) { + this.xmlProvider = p; + if (profile != null) { + xmlProvider.setProfile(profile); + } + } - @Override - public DXExporterFromA3 setZUGFeRDVersion(int version) { - DAPullProvider z2p = new DAPullProvider(); - setXMLProvider(z2p); - return this; - } + @Override + public DXExporterFromA3 setZUGFeRDVersion(int version) { + DAPullProvider z2p = new DAPullProvider(); + setXMLProvider(z2p); + return this; + } - /** - * Utility method inspired by apache commons-lang3 StringUtils. - * - * @param string the string to test - * @return true if the string is null or empty - */ - private boolean isEmpty(String string) { - return string == null || string.isEmpty(); - } + /** + * Utility method inspired by apache commons-lang3 StringUtils. + * + * @param string the string to test + * @return true if the string is null or empty + */ + private boolean isEmpty(String string) { + return string == null || string.isEmpty(); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/EinLieferscheinExporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/EinLieferscheinExporter.java index b2e166e..b6ac406 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/EinLieferscheinExporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/EinLieferscheinExporter.java @@ -25,31 +25,31 @@ org.openrewrite.config.CompositeRecipe import java.io.IOException; import java.io.OutputStream; -public class EinLieferscheinExporter implements IExporter { - IXMLProvider xmlProvider; - IExportableTransaction trans; +public class EinLieferscheinExporter implements IExporter { + IXMLProvider xmlProvider; + IExportableTransaction trans; - public EinLieferscheinExporter() { - xmlProvider=new UBLDAPullProvider(); - } + public EinLieferscheinExporter() { + xmlProvider = new UBLDAPullProvider(); + } - @Override - public IExporter setTransaction(IExportableTransaction trans) throws IOException { - this.trans=trans; - return this; - } + @Override + public IExporter setTransaction(IExportableTransaction trans) throws IOException { + this.trans = trans; + return this; + } - @Override - public void export(String ZUGFeRDfilename) throws IOException { - export(new FileOutputStream(new File(ZUGFeRDfilename))); + @Override + public void export(String ZUGFeRDfilename) throws IOException { + export(new FileOutputStream(new File(ZUGFeRDfilename))); - } + } - @Override - public void export(OutputStream output) throws IOException { - xmlProvider.generateXML(trans); - byte[] bytes=xmlProvider.getXML(); - output.write(bytes, 0, bytes.length); - } + @Override + public void export(OutputStream output) throws IOException { + xmlProvider.generateXML(trans); + byte[] bytes = xmlProvider.getXML(); + output.write(bytes, 0, bytes.length); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IAbsoluteValueProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IAbsoluteValueProvider.java index 3c4be8b..296408d 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IAbsoluteValueProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IAbsoluteValueProvider.java @@ -22,6 +22,6 @@ org.openrewrite.config.CompositeRecipe public interface IAbsoluteValueProvider { - public BigDecimal getValue(); + public BigDecimal getValue(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IDesignatedProductClassification.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IDesignatedProductClassification.java index 327fb08..ccff25d 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IDesignatedProductClassification.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IDesignatedProductClassification.java @@ -26,17 +26,19 @@ org.openrewrite.config.CompositeRecipe * A product classification that allows to describe a product. Classification codes are schemed by the available systems in UNTDID 7143. */ public interface IDesignatedProductClassification { - /** - * Classification code - * - * @return the classification code - */ - ClassCode getClassCode(); + /** + * Classification code + * + * @return the classification code + */ + ClassCode getClassCode(); - /** - * an optional, human-readable description of the classifcation code - * - * @return the name or {@code null} if not set - */ - default String getClassName() { return null; } + /** + * an optional, human-readable description of the classifcation code + * + * @return the name or {@code null} if not set + */ + default String getClassName() { + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java index 0a67a6b..aba1dbb 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java @@ -29,14 +29,23 @@ org.openrewrite.config.CompositeRecipe * @author jstaerk * */ -import java.math.BigDecimal; -import java.util.Date; -import java.util.List; - import org.mustangproject.FileAttachment; import org.mustangproject.IncludedNote; import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; +/** + * Mustangproject's ZUGFeRD implementation + * Neccessary interface for ZUGFeRD exporter + * Licensed under the APLv2 + * @date 2014-05-10 to 2020-11-12 + * @version 2.0.0 + * @author jstaerk + * */ + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + /*** * the interface of an transaction, e.g. an invoice, you want to create xml * (potentially to be added to a PDF) for @@ -45,501 +54,503 @@ */ public interface IExportableTransaction { - /** - * appears in /rsm:CrossIndustryDocument/rsm:HeaderExchangedDocument/ram:Name - * - * @return Name of document - */ - default String getDocumentName() { - return "RECHNUNG"; - } + /** + * appears in /rsm:CrossIndustryDocument/rsm:HeaderExchangedDocument/ram:Name + * + * @return Name of document + */ + default String getDocumentName() { + return "RECHNUNG"; + } - /** - * - * - * @return Code number of Document type, e.g. "380" for invoiceF - */ - default String getDocumentCode() { - return DocumentCodeTypeConstants.INVOICE; - } + /** + * + * + * @return Code number of Document type, e.g. "380" for invoiceF + */ + default String getDocumentCode() { + return DocumentCodeTypeConstants.INVOICE; + } - /** - * Number, typically invoice number of the invoice - * - * @return invoice number - */ - default String getNumber() { - return null; - } + /** + * Number, typically invoice number of the invoice + * + * @return invoice number + */ + default String getNumber() { + return null; + } - /** - * the date when the invoice was created - * - * @return when the invoice was created - */ - default Date getIssueDate() { - return null; - } + /** + * the date when the invoice was created + * + * @return when the invoice was created + */ + default Date getIssueDate() { + return null; + } - /** - * this should be the full sender institution name, details, manager and tax - * registration. It is one of the few functions which may return null. e.g. - * - * Lieferant GmbH Lieferantenstraße 20 80333 München Deutschland - * Geschäftsführer: Hans Muster Handelsregisternummer: H A 123 - * - * It is written as an includedNode with subjectCode {@link org.mustangproject.SubjectCode#REG}. See also - * {@link #getNotesWithSubjectCode()} - * @return null or full sender institution name, details, manager and tax - * registration - */ - default String getOwnOrganisationFullPlaintextInfo() { - return null; - } + /** + * this should be the full sender institution name, details, manager and tax + * registration. It is one of the few functions which may return null. e.g. + * + * Lieferant GmbH Lieferantenstraße 20 80333 München Deutschland + * Geschäftsführer: Hans Muster Handelsregisternummer: H A 123 + * + * It is written as an includedNode with subjectCode {@link org.mustangproject.SubjectCode#REG}. See also + * {@link #getNotesWithSubjectCode()} + * @return null or full sender institution name, details, manager and tax + * registration + */ + default String getOwnOrganisationFullPlaintextInfo() { + return null; + } - /** - * when the invoice is to be paid - * - * @return when the invoice is to be paid - */ - default Date getDueDate() { - return null; - } + /** + * when the invoice is to be paid + * + * @return when the invoice is to be paid + */ + default Date getDueDate() { + return null; + } - default String getContractReferencedDocument() { - return null; - } + default String getContractReferencedDocument() { + return null; + } - /** - * the sender of the invoice - * - * @return the contact person at the supplier side - */ - default IZUGFeRDExportableTradeParty getSender() { - return null; - } + /** + * the sender of the invoice + * + * @return the contact person at the supplier side + */ + default IZUGFeRDExportableTradeParty getSender() { + return null; + } - /** - * subject of the document e.g. invoice and order number as human readable text - * - * @return string with document subject - */ - default String getSubjectNote() { - return null; - } + /** + * subject of the document e.g. invoice and order number as human readable text + * + * @return string with document subject + */ + default String getSubjectNote() { + return null; + } - default IZUGFeRDAllowanceCharge[] getZFAllowances() { - return null; - } + default IZUGFeRDAllowanceCharge[] getZFAllowances() { + return null; + } - default IZUGFeRDAllowanceCharge[] getZFCharges() { - return null; - } + default IZUGFeRDAllowanceCharge[] getZFCharges() { + return null; + } - default IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - return null; - } + default IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { + return null; + } - default IZUGFeRDCashDiscount[] getCashDiscounts() { return null; } + default IZUGFeRDCashDiscount[] getCashDiscounts() { + return null; + } - /*** - * @return the invoice line items with the positions - */ - IZUGFeRDExportableItem[] getZFItems(); + /*** + * @return the invoice line items with the positions + */ + IZUGFeRDExportableItem[] getZFItems(); - /** - * the recipient - * - * @return the recipient of the invoice - */ - IZUGFeRDExportableTradeParty getRecipient(); + /** + * the recipient + * + * @return the recipient of the invoice + */ + IZUGFeRDExportableTradeParty getRecipient(); - /** - * the creditors payment informations - * - * @deprecated use getTradeSettlement - * @return an array of IZUGFeRDTradeSettlementPayment - */ - @Deprecated - default IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment() { - return null; - } + /** + * the creditors payment informations + * + * @deprecated use getTradeSettlement + * @return an array of IZUGFeRDTradeSettlementPayment + */ + @Deprecated + default IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment() { + return null; + } - /** - * the payment information for any payment means - * - * @return an array of IZUGFeRDTradeSettlement - */ - default IZUGFeRDTradeSettlement[] getTradeSettlement() { - return null; - } + /** + * the payment information for any payment means + * + * @return an array of IZUGFeRDTradeSettlement + */ + default IZUGFeRDTradeSettlement[] getTradeSettlement() { + return null; + } - /** - * Tax ID (not VAT ID) of the sender - * - * @return Tax ID (not VAT ID) of the sender - */ - default String getOwnTaxID() { - if (getSender() != null) { - return getSender().getTaxID(); - } else { - return null; - } - } + /** + * Tax ID (not VAT ID) of the sender + * + * @return Tax ID (not VAT ID) of the sender + */ + default String getOwnTaxID() { + if (getSender() != null) { + return getSender().getTaxID(); + } else { + return null; + } + } - /** - * VAT ID (Umsatzsteueridentifikationsnummer) of the sender - * - * @return VAT ID (Umsatzsteueridentifikationsnummer) of the sender - */ - default String getOwnVATID() { - if (getSender() != null) { - return getSender().getVATID(); - } else { - return null; - } - } + /** + * VAT ID (Umsatzsteueridentifikationsnummer) of the sender + * + * @return VAT ID (Umsatzsteueridentifikationsnummer) of the sender + */ + default String getOwnVATID() { + if (getSender() != null) { + return getSender().getVATID(); + } else { + return null; + } + } - /** - * supplier identification assigned by the costumer - * - * @return the sender's identification - */ - default String getOwnForeignOrganisationID() { - return null; - } + /** + * supplier identification assigned by the costumer + * + * @return the sender's identification + */ + default String getOwnForeignOrganisationID() { + return null; + } - /** - * own name - * - * @return the sender's organisation name - */ - default String getOwnOrganisationName() { - if (getSender() != null) { - return getSender().getName(); - } else { - return null; - } - } + /** + * own name + * + * @return the sender's organisation name + */ + default String getOwnOrganisationName() { + if (getSender() != null) { + return getSender().getName(); + } else { + return null; + } + } - /** - * own street address - * - * @return sender street address - */ - default String getOwnStreet() { - if (getSender() != null) { - return getSender().getStreet(); - } else { - return null; - } - } + /** + * own street address + * + * @return sender street address + */ + default String getOwnStreet() { + if (getSender() != null) { + return getSender().getStreet(); + } else { + return null; + } + } - /** - * own street postal code - * - * @return sender postal code - */ - default String getOwnZIP() { - if (getSender() != null) { - return getSender().getZIP(); - } else { - return null; - } + /** + * own street postal code + * + * @return sender postal code + */ + default String getOwnZIP() { + if (getSender() != null) { + return getSender().getZIP(); + } else { + return null; + } - } + } - /** - * own city - * - * @return the invoice sender's city - */ - default String getOwnLocation() { - if (getSender() != null) { - return getSender().getLocation(); - } else { - return null; - } + /** + * own city + * + * @return the invoice sender's city + */ + default String getOwnLocation() { + if (getSender() != null) { + return getSender().getLocation(); + } else { + return null; + } - } + } - /** - * own two digit country code - * - * @return the invoice senders two character country iso code - */ - default String getOwnCountry() { - if (getSender() != null) { - return getSender().getCountry(); - } else { - return null; - } + /** + * own two digit country code + * + * @return the invoice senders two character country iso code + */ + default String getOwnCountry() { + if (getSender() != null) { + return getSender().getCountry(); + } else { + return null; + } - } + } - /** - * get delivery date - * - * @return the day the goods have been delivered - */ - Date getDeliveryDate(); + /** + * get delivery date + * + * @return the day the goods have been delivered + */ + Date getDeliveryDate(); - /** - * get main invoice currency used on the invoice - * - * @return three character currency of this invoice - */ - default String getCurrency() { - return "EUR"; - } + /** + * get main invoice currency used on the invoice + * + * @return three character currency of this invoice + */ + default String getCurrency() { + return "EUR"; + } - /** - * get payment term descriptional text e.g. Bis zum 22.10.2015 ohne Abzug - * - * @return get payment terms - */ - default String getPaymentTermDescription() { - return null; - } + /** + * get payment term descriptional text e.g. Bis zum 22.10.2015 ohne Abzug + * + * @return get payment terms + */ + default String getPaymentTermDescription() { + return null; + } - /** - * get payment terms. if set, getPaymentTermDescription() and getDueDate() are - * ignored - * - * @return the IZUGFeRDPaymentTerms of the invoice - */ - default IZUGFeRDPaymentTerms getPaymentTerms() { - return null; - } + /** + * get payment terms. if set, getPaymentTermDescription() and getDueDate() are + * ignored + * + * @return the IZUGFeRDPaymentTerms of the invoice + */ + default IZUGFeRDPaymentTerms getPaymentTerms() { + return null; + } - /** - * returns if a rebate agreements exists - * - * @return true if a agreement exists - */ - default boolean rebateAgreementExists() { - return false; - } + /** + * returns if a rebate agreements exists + * + * @return true if a agreement exists + */ + default boolean rebateAgreementExists() { + return false; + } - /** - * supplier identification assigned by the costumer - * - * @return the sender's identification - */ - default BigDecimal getRoundingAmount() { - return null; - } + /** + * supplier identification assigned by the costumer + * + * @return the sender's identification + */ + default BigDecimal getRoundingAmount() { + return null; + } - /** - * get reference document number typically used for Invoice Corrections Will be - * added as IncludedNote in comfort profile - * - * @return the ID of the document this document refers to - */ - default String getReferenceNumber() { - return null; - } + /** + * get reference document number typically used for Invoice Corrections Will be + * added as IncludedNote in comfort profile + * + * @return the ID of the document this document refers to + */ + default String getReferenceNumber() { + return null; + } - /** - * consignee identification (identification of the organisation the goods are - * shipped to [assigned by the costumer]) - * - * @return the sender's identification - */ - default String getShipToOrganisationID() { - return null; - } + /** + * consignee identification (identification of the organisation the goods are + * shipped to [assigned by the costumer]) + * + * @return the sender's identification + */ + default String getShipToOrganisationID() { + return null; + } - /** - * consignee name (name of the organisation the goods are shipped to) - * - * @return the consignee's organisation name - */ - default String getShipToOrganisationName() { - return null; - } + /** + * consignee name (name of the organisation the goods are shipped to) + * + * @return the consignee's organisation name + */ + default String getShipToOrganisationName() { + return null; + } - /** - * consignee street address (street of the organisation the goods are shipped - * to) - * - * @return consignee street address - */ - default String getShipToStreet() { - return null; - } + /** + * consignee street address (street of the organisation the goods are shipped + * to) + * + * @return consignee street address + */ + default String getShipToStreet() { + return null; + } - /** - * consignee street postal code (postal code of the organisation the goods are - * shipped to) - * - * @return consignee postal code - */ - default String getShipToZIP() { - return null; - } + /** + * consignee street postal code (postal code of the organisation the goods are + * shipped to) + * + * @return consignee postal code + */ + default String getShipToZIP() { + return null; + } - /** - * consignee city (city of the organisation the goods are shipped to) - * - * @return the consignee's city - */ - default String getShipToLocation() { - return null; - } + /** + * consignee city (city of the organisation the goods are shipped to) + * + * @return the consignee's city + */ + default String getShipToLocation() { + return null; + } - /** - * consignee two digit country code (country code of the organisation the goods - * are shipped to) - * - * @return the consignee's two character country iso code - */ - default String getShipToCountry() { - return null; - } + /** + * consignee two digit country code (country code of the organisation the goods + * are shipped to) + * + * @return the consignee's two character country iso code + */ + default String getShipToCountry() { + return null; + } - /** - * get the ID of the SellerOrderReferencedDocument, which sits in the - * ApplicableSupplyChainTradeAgreement/ApplicableHeaderTradeAgreement - * - * @return the ID of the document - */ - default String getSellerOrderReferencedDocumentID() { - return null; - } + /** + * get the ID of the SellerOrderReferencedDocument, which sits in the + * ApplicableSupplyChainTradeAgreement/ApplicableHeaderTradeAgreement + * + * @return the ID of the document + */ + default String getSellerOrderReferencedDocumentID() { + return null; + } - /** - * get the ID of the BuyerOrderReferencedDocument, which sits in the - * ApplicableSupplyChainTradeAgreement - * - * @return the ID of the document - */ - default String getBuyerOrderReferencedDocumentID() { - return null; - } + /** + * get the ID of the BuyerOrderReferencedDocument, which sits in the + * ApplicableSupplyChainTradeAgreement + * + * @return the ID of the document + */ + default String getBuyerOrderReferencedDocumentID() { + return null; + } - /** - * get the ID of the preceding invoice, which is e.g. to be corrected if this is - * a correction - * - * @return the ID of the document - */ - default String getInvoiceReferencedDocumentID() { - return null; - } + /** + * get the ID of the preceding invoice, which is e.g. to be corrected if this is + * a correction + * + * @return the ID of the document + */ + default String getInvoiceReferencedDocumentID() { + return null; + } - default Date getInvoiceReferencedIssueDate() { - return null; - } + default Date getInvoiceReferencedIssueDate() { + return null; + } - /** - * get the issue timestamp of the BuyerOrderReferencedDocument, which sits in - * the ApplicableSupplyChainTradeAgreement - * - * @return the IssueDateTime in format CCYY-MM-DDTHH:MM:SS - */ - default String getBuyerOrderReferencedDocumentIssueDateTime() { - return null; - } + /** + * get the issue timestamp of the BuyerOrderReferencedDocument, which sits in + * the ApplicableSupplyChainTradeAgreement + * + * @return the IssueDateTime in format CCYY-MM-DDTHH:MM:SS + */ + default String getBuyerOrderReferencedDocumentIssueDateTime() { + return null; + } - /** - * get the TotalPrepaidAmount located in - * SpecifiedTradeSettlementMonetarySummation (v1) or - * SpecifiedTradeSettlementHeaderMonetarySummation (v2) - * - * @return the total sum (incl. VAT) of prepayments, i.e. the difference between - * GrandTotalAmount and DuePayableAmount - */ - default BigDecimal getTotalPrepaidAmount() { - return BigDecimal.ZERO; - } + /** + * get the TotalPrepaidAmount located in + * SpecifiedTradeSettlementMonetarySummation (v1) or + * SpecifiedTradeSettlementHeaderMonetarySummation (v2) + * + * @return the total sum (incl. VAT) of prepayments, i.e. the difference between + * GrandTotalAmount and DuePayableAmount + */ + default BigDecimal getTotalPrepaidAmount() { + return BigDecimal.ZERO; + } - /*** - * delivery address, i.e. ram:ShipToTradeParty (only supported for zf2) - * - * @return the IZUGFeRDExportableTradeParty delivery address - */ - default IZUGFeRDExportableTradeParty getDeliveryAddress() { - return null; - } + /*** + * delivery address, i.e. ram:ShipToTradeParty (only supported for zf2) + * + * @return the IZUGFeRDExportableTradeParty delivery address + */ + default IZUGFeRDExportableTradeParty getDeliveryAddress() { + return null; + } - /*** - * payee / payment receiver, if different from seller, ram:Payee (only supported for zf2) - * - * @return the IZUGFeRDExportableTradeParty payment receiver, if different from sellver - */ - default IZUGFeRDExportableTradeParty getPayee() { - return null; - } + /*** + * payee / payment receiver, if different from seller, ram:Payee (only supported for zf2) + * + * @return the IZUGFeRDExportableTradeParty payment receiver, if different from sellver + */ + default IZUGFeRDExportableTradeParty getPayee() { + return null; + } - /*** - * specifies the document level delivery period, will be included in a - * BillingSpecifiedPeriod element - * - * @return the beginning of the delivery period - */ - default Date getDetailedDeliveryPeriodFrom() { - return null; - } + /*** + * specifies the document level delivery period, will be included in a + * BillingSpecifiedPeriod element + * + * @return the beginning of the delivery period + */ + default Date getDetailedDeliveryPeriodFrom() { + return null; + } - /*** - * specifies the document level delivery period, will be included in a - * BillingSpecifiedPeriod element - * - * @return the end of the delivery period - */ - default Date getDetailedDeliveryPeriodTo() { - return null; - } + /*** + * specifies the document level delivery period, will be included in a + * BillingSpecifiedPeriod element + * + * @return the end of the delivery period + */ + default Date getDetailedDeliveryPeriodTo() { + return null; + } - /** - * get additional referenced documents acccording to BG-24 XRechnung - * (Rechnungsbegruendende Unterlagen), i.e. - * ram:ApplicableHeaderTradeAgreement/ram:AdditionalReferencedDocument - * - * @return a array of objects from class FileAttachment - */ - default FileAttachment[] getAdditionalReferencedDocuments() { - return null; - } + /** + * get additional referenced documents acccording to BG-24 XRechnung + * (Rechnungsbegruendende Unterlagen), i.e. + * ram:ApplicableHeaderTradeAgreement/ram:AdditionalReferencedDocument + * + * @return a array of objects from class FileAttachment + */ + default FileAttachment[] getAdditionalReferencedDocuments() { + return null; + } - default String getDespatchAdviceReferencedDocumentID() { - return null; - } + default String getDespatchAdviceReferencedDocumentID() { + return null; + } - /*** - * additional text description - * - * @return an array of strings of document wide "includedNotes" (descriptive - * text values) - */ - default String[] getNotes() { - return null; - } + /*** + * additional text description + * + * @return an array of strings of document wide "includedNotes" (descriptive + * text values) + */ + default String[] getNotes() { + 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 getNotesWithSubjectCode() { - 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 getNotesWithSubjectCode() { + return null; + } - default String getSpecifiedProcuringProjectName() { - return null; - } + default String getSpecifiedProcuringProjectName() { + return null; + } - default String getSpecifiedProcuringProjectID() { - return null; - } + default String getSpecifiedProcuringProjectID() { + return null; + } - default String getVATDueDateTypeCode() { - return null; - } + default String getVATDueDateTypeCode() { + return null; + } - default String getCreditorReferenceID() { - return null; - } + default String getCreditorReferenceID() { + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IExporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IExporter.java index 7f30f81..82d9066 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IExporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IExporter.java @@ -23,8 +23,10 @@ org.openrewrite.config.CompositeRecipe public interface IExporter { - public IExporter setTransaction(IExportableTransaction trans) throws IOException; - public void export(String ZUGFeRDfilename) throws IOException; - public void export(OutputStream output) throws IOException; + public IExporter setTransaction(IExportableTransaction trans) throws IOException; + + public void export(String ZUGFeRDfilename) throws IOException; + + public void export(OutputStream output) throws IOException; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IReferencedDocument.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IReferencedDocument.java index 9d46d9b..185c3f4 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IReferencedDocument.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IReferencedDocument.java @@ -2,22 +2,22 @@ org.openrewrite.config.CompositeRecipe public interface IReferencedDocument { - /*** - * sets an ID assigned by the sender - * @return String of an ID - */ - String getIssuerAssignedID(); + /*** + * sets an ID assigned by the sender + * @return String of an ID + */ + String getIssuerAssignedID(); - /*** - * which type is the document? e.g. "916" for additional invoice related - * @return string of a most likely numeric code - */ - String getTypeCode(); + /*** + * which type is the document? e.g. "916" for additional invoice related + * @return string of a most likely numeric code + */ + String getTypeCode(); - /*** - * type of the reference of this line, a UNTDID 1153 code - * @return String of a code - */ - String getReferenceTypeCode(); + /*** + * type of the reference of this line, a UNTDID 1153 code + * @return String of a code + */ + String getReferenceTypeCode(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IXMLProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IXMLProvider.java index b6136f3..0dffd60 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IXMLProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IXMLProvider.java @@ -20,15 +20,15 @@ org.openrewrite.config.CompositeRecipe public interface IXMLProvider { - public byte[] getXML(); + public byte[] getXML(); - public void setTest(); + public void setTest(); - public void generateXML(IExportableTransaction trans); + public void generateXML(IExportableTransaction trans); - public void setProfile(Profile p); + public void setProfile(Profile p); - public Profile getProfile(); + public Profile getProfile(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java index 0c61ba5..c432d24 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDAllowanceCharge.java @@ -15,58 +15,60 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import java.math.BigDecimal; - import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants; +import java.math.BigDecimal; + /** * The interface for allowances or charges, to be used by the pullprovider * @author AlexanderSchmidt */ public interface IZUGFeRDAllowanceCharge { - /*** - * returns the absolute amount, even if it was relative in the first place - * @param trans the class delivering the initial value - * @return the calculated value (e.g. when percentage) - */ - BigDecimal getTotalAmount(IAbsoluteValueProvider trans); + /*** + * returns the absolute amount, even if it was relative in the first place + * @param trans the class delivering the initial value + * @return the calculated value (e.g. when percentage) + */ + BigDecimal getTotalAmount(IAbsoluteValueProvider trans); - /*** - * returns a percentage, if relative abount, or null for absolute amounts - * @return null or Percentage as Bigdecimal - */ - default BigDecimal getPercent() {return null;} + /*** + * returns a percentage, if relative abount, or null for absolute amounts + * @return null or Percentage as Bigdecimal + */ + default BigDecimal getPercent() { + return null; + } - /*** - * get a description for the allowance/charge - * @return the description - */ - String getReason(); + /*** + * get a description for the allowance/charge + * @return the description + */ + String getReason(); - /*** - * get the code for the allowance/charge - * @return the code - */ - String getReasonCode(); + /*** + * get the code for the allowance/charge + * @return the code + */ + String getReasonCode(); - /*** - * get the applicable tax percentage for the allowance/charge - * @return the percentage - */ - BigDecimal getTaxPercent(); + /*** + * get the applicable tax percentage for the allowance/charge + * @return the percentage + */ + BigDecimal getTaxPercent(); - /*** - * the category ID why this has been applied - * @return default value Standard rate=S - */ - default String getCategoryCode() { - return TaxCategoryCodeTypeConstants.STANDARDRATE; - } + /*** + * the category ID why this has been applied + * @return default value Standard rate=S + */ + default String getCategoryCode() { + return TaxCategoryCodeTypeConstants.STANDARDRATE; + } - /*** - * is this in reality a charge and now allowance - * @return true if amnount to be treated negative - */ - public boolean isCharge(); + /*** + * is this in reality a charge and now allowance + * @return true if amnount to be treated negative + */ + public boolean isCharge(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDCashDiscount.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDCashDiscount.java index 5d5fff1..cd91043 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDCashDiscount.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDCashDiscount.java @@ -3,16 +3,16 @@ org.openrewrite.config.CompositeRecipe public interface IZUGFeRDCashDiscount { - /*** - * @return this particular cash discount as cross industry invoice XML - */ - public String getAsCII(); + /*** + * @return this particular cash discount as cross industry invoice XML + */ + public String getAsCII(); - /*** - * since EN16931 voted not to have (or even allow) cash discounts in their core invoice the german - * XRechnung CIUS defined it's own proprietary format for a freetext field - * @return this particular cash discount in proprietary xrechnung format - */ - public String getAsXRechnung(); + /*** + * since EN16931 voted not to have (or even allow) cash discounts in their core invoice the german + * XRechnung CIUS defined it's own proprietary format for a freetext field + * @return this particular cash discount in proprietary xrechnung format + */ + public String getAsXRechnung(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableContact.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableContact.java index c0fa520..90e8bb0 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableContact.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableContact.java @@ -29,94 +29,94 @@ org.openrewrite.config.CompositeRecipe public interface IZUGFeRDExportableContact { - /** - * customer identification assigned by the seller - * - * @return customer identification - */ - default String getID() { - return null; - } + /** + * customer identification assigned by the seller + * + * @return customer identification + */ + default String getID() { + return null; + } - /** - * First and last name of the recipient - * - * @return First and last name of the recipient - */ - default String getName() { - return null; - } + /** + * First and last name of the recipient + * + * @return First and last name of the recipient + */ + default String getName() { + return null; + } - default String getPhone() { - return null; - } + default String getPhone() { + return null; + } - default String getEMail() { - return null; - } + default String getEMail() { + return null; + } - default String getFax() { - return null; - } + default String getFax() { + return null; + } - /** - * Postal code of the recipient - * - * @return Postal code of the recipient - */ - default String getZIP() { - return null; - } + /** + * Postal code of the recipient + * + * @return Postal code of the recipient + */ + default String getZIP() { + return null; + } - /** - * VAT ID (Umsatzsteueridentifikationsnummer) of the contact - * - * @return VAT ID (Umsatzsteueridentifikationsnummer) of the contact - */ - default String getVATID() { - return null; - } + /** + * VAT ID (Umsatzsteueridentifikationsnummer) of the contact + * + * @return VAT ID (Umsatzsteueridentifikationsnummer) of the contact + */ + default String getVATID() { + return null; + } - /** - * two-letter country code of the contact - * - * @return two-letter iso country code of the contact - */ - default String getCountry() { - return null; - } + /** + * two-letter country code of the contact + * + * @return two-letter iso country code of the contact + */ + default String getCountry() { + return null; + } - /** - * Returns the city of the contact - * - * @return Returns the city of the recipient - */ - default String getLocation() { - return null; - } + /** + * Returns the city of the contact + * + * @return Returns the city of the recipient + */ + default String getLocation() { + return null; + } - /** - * Returns the street address (street+number) of the contact - * - * @return street address (street+number) of the contact - */ - default String getStreet() { - return null; - } + /** + * Returns the street address (street+number) of the contact + * + * @return street address (street+number) of the contact + */ + default String getStreet() { + return null; + } - /** - * returns additional address information which is display in xml tag "LineTwo" - * - * @return additional address information - */ - default String getAdditionalAddress() { - return null; - } + /** + * returns additional address information which is display in xml tag "LineTwo" + * + * @return additional address information + */ + default String getAdditionalAddress() { + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java index 45c210e..c0bb46b 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java @@ -17,6 +17,20 @@ org.openrewrite.config.CompositeRecipe * *********************************************************************** */ package org.mustangproject.ZUGFeRD; + +/** + * Mustangproject's ZUGFeRD implementation + * Neccessary interface for ZUGFeRD exporter + * Licensed under the APLv2 + * @date 2014-05-10 + * @version 1.2.0 + * @author jstaerk + * */ + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.mustangproject.IncludedNote; +import org.mustangproject.Item; + /** * Mustangproject's ZUGFeRD implementation * Neccessary interface for ZUGFeRD exporter @@ -30,146 +44,142 @@ import java.util.Date; import java.util.List; -import org.mustangproject.IncludedNote; -import org.mustangproject.Item; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - @JsonDeserialize(as = Item.class) -public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{ - IZUGFeRDExportableProduct getProduct(); +public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider { + IZUGFeRDExportableProduct getProduct(); - /** - * item level discounts - * @return array of the discounts on a single item - */ - default IZUGFeRDAllowanceCharge[] getItemAllowances() { - return null; - } + /** + * item level discounts + * @return array of the discounts on a single item + */ + default IZUGFeRDAllowanceCharge[] getItemAllowances() { + return null; + } - /** - * item level price additions - * @return array of the additional charges on the item - */ - default IZUGFeRDAllowanceCharge[] getItemCharges() { - return null; - } + /** + * item level price additions + * @return array of the additional charges on the item + */ + default IZUGFeRDAllowanceCharge[] getItemCharges() { + return null; + } - /*** - * BT 132 (issue https://github.com/ZUGFeRD/mustangproject/issues/247) - * @return the line ID of the order (BT-132) - */ - default String getBuyerOrderReferencedDocumentLineID() { - return null; - } + /*** + * BT 132 (issue https://github.com/ZUGFeRD/mustangproject/issues/247) + * @return the line ID of the order (BT-132) + */ + default String getBuyerOrderReferencedDocumentLineID() { + return null; + } - /** - * The price of one item excl. taxes - * - * @return The price of one item excl. taxes - */ - BigDecimal getPrice(); + /** + * The price of one item excl. taxes + * + * @return The price of one item excl. taxes + */ + BigDecimal getPrice(); - @Override - default BigDecimal getValue() { - return getPrice(); - } - /** - * how many get billed - * - * @return the quantity of the item - */ - BigDecimal getQuantity(); + @Override + default BigDecimal getValue() { + return getPrice(); + } - /** - * how many items units per price - * - * @return item units per price - */ - default BigDecimal getBasisQuantity() { - return BigDecimal.ONE.setScale(4); - } + /** + * how many get billed + * + * @return the quantity of the item + */ + BigDecimal getQuantity(); - /*** - * the ID of an additionally referenced document for this item - * @deprecated use {@link #getAdditionalReferences()} instead. - * @return the id as string - */ - @Deprecated - default String getAdditionalReferencedDocumentID() { - return null; - } + /** + * how many items units per price + * + * @return item units per price + */ + default BigDecimal getBasisQuantity() { + return BigDecimal.ONE.setScale(4); + } - /*** - * allows to specify multiple references (billing information) - * @return the referenced documents - */ - default IReferencedDocument[] getAdditionalReferences() { - return null; - } + /*** + * the ID of an additionally referenced document for this item + * @deprecated use {@link #getAdditionalReferences()} instead. + * @return the id as string + */ + @Deprecated + default String getAdditionalReferencedDocumentID() { + return null; + } + + /*** + * allows to specify multiple references (billing information) + * @return the referenced documents + */ + default IReferencedDocument[] getAdditionalReferences() { + return null; + } - /*** - * allows to specify multiple(!) referenced documents along with e.g. their typecodes - * @return the referenced documents - */ - default IReferencedDocument[] getReferencedDocuments() { - return null; - } - /*** - * descriptive texts - * @return an array of strings of item specific "includedNotes", text values - */ - default String[] getNotes() { - return null; - } + /*** + * allows to specify multiple(!) referenced documents along with e.g. their typecodes + * @return the referenced documents + */ + default IReferencedDocument[] getReferencedDocuments() { + return null; + } + + /*** + * descriptive texts + * @return an array of strings of item specific "includedNotes", text values + */ + default String[] getNotes() { + return null; + } + /*** + * specifies the item level delivery period (there is also one on document level), + * this will be included in a BillingSpecifiedPeriod element + * @return the beginning of the delivery period + */ + default Date getDetailedDeliveryPeriodFrom() { + return null; + } - /*** - * specifies the item level delivery period (there is also one on document level), - * this will be included in a BillingSpecifiedPeriod element - * @return the beginning of the delivery period - */ - default Date getDetailedDeliveryPeriodFrom() { - return null; - } + /*** + * specifies the item level delivery period (there is also one on document level), + * this will be included in a BillingSpecifiedPeriod element + * @return the end of the delivery period + */ + default Date getDetailedDeliveryPeriodTo() { + return null; + } - /*** - * specifies the item level delivery period (there is also one on document level), - * this will be included in a BillingSpecifiedPeriod element - * @return the end of the delivery period - */ - default Date getDetailedDeliveryPeriodTo() { - return null; - } - - /*** - * specify allowances amount for the line item total - * - * @return the sum of allowances for this item - */ - default IZUGFeRDAllowanceCharge[] getItemTotalAllowances() { - return null; - } + /*** + * specify allowances amount for the line item total + * + * @return the sum of allowances for this item + */ + default IZUGFeRDAllowanceCharge[] getItemTotalAllowances() { + return null; + } - /*** - * - * @return the line ID - */ - default String getId() { - 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 getNotesWithSubjectCode() { - 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 getNotesWithSubjectCode() { + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportablePostalTradeAddress.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportablePostalTradeAddress.java index 05e7b76..890d23f 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportablePostalTradeAddress.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportablePostalTradeAddress.java @@ -1,11 +1,31 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; public interface IZUGFeRDExportablePostalTradeAddress { - default String getPostcodeCode(){return null;} - default String getLineOne() {return null;} - default String getLineTwo() {return null;} - default String getLineThree() {return null;} - default String getCityName() {return null;} - default String getCountryID() {return null;} - default String getCountrySubDivisionName() {return null;} + default String getPostcodeCode() { + return null; + } + + default String getLineOne() { + return null; + } + + default String getLineTwo() { + return null; + } + + default String getLineThree() { + return null; + } + + default String getCityName() { + return null; + } + + default String getCountryID() { + return null; + } + + default String getCountrySubDivisionName() { + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java index ae9eb5b..d51b394 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableProduct.java @@ -20,11 +20,11 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; +import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants; + import java.math.BigDecimal; import java.util.HashMap; -import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants; - /** * Mustangproject's ZUGFeRD implementation * Necessary interface for ZUGFeRD exporter @@ -37,139 +37,141 @@ public interface IZUGFeRDExportableProduct { - /** - * Unit code of the product - * Most common ones are - * C62 one (piece) - * DAY day - * HAR hectare - * HUR hour - * KGM kilogram - * KTM kilometre - * KWH kilowatt hour - * LS lump sum - * LTR litre - * MIN minute - * MMK square millimetre - * MMT millimetre - * MTK square metre - * MTQ cubic metre - * MTR metre - * NAR number of articles - * NPR number of pairs - * P1 percent - * SET set - * TNE tonne (metric ton) - * WEE week - * - * @return a UN/ECE rec 20 unit code see https://www.unece.org/fileadmin/DAM/cefact/recommendations/rec20/rec20_rev3_Annex2e.pdf - */ - String getUnit(); + /** + * Unit code of the product + * Most common ones are + * C62 one (piece) + * DAY day + * HAR hectare + * HUR hour + * KGM kilogram + * KTM kilometre + * KWH kilowatt hour + * LS lump sum + * LTR litre + * MIN minute + * MMK square millimetre + * MMT millimetre + * MTK square metre + * MTQ cubic metre + * MTR metre + * NAR number of articles + * NPR number of pairs + * P1 percent + * SET set + * TNE tonne (metric ton) + * WEE week + * + * @return a UN/ECE rec 20 unit code see https://www.unece.org/fileadmin/DAM/cefact/recommendations/rec20/rec20_rev3_Annex2e.pdf + */ + String getUnit(); - /** - * Short name of the product - * - * @return Short name of the product - */ - String getName(); + /** + * Short name of the product + * + * @return Short name of the product + */ + String getName(); - /** - * long description of the product - * - * @return long description of the product - */ - String getDescription(); + /** + * long description of the product + * + * @return long description of the product + */ + String getDescription(); - /** - * Get the ID that had been assigned by the seller to - * identify the product - * - * @return seller assigned product ID - */ - default String getSellerAssignedID() { - return null; - } + /** + * Get the ID that had been assigned by the seller to + * identify the product + * + * @return seller assigned product ID + */ + default String getSellerAssignedID() { + return null; + } - /** - * Get the ID that had been assigned by the buyer to - * identify the product - * - * @return buyer assigned product ID - */ - default String getBuyerAssignedID() { - return null; - } + /** + * Get the ID that had been assigned by the buyer to + * identify the product + * + * @return buyer assigned product ID + */ + default String getBuyerAssignedID() { + return null; + } - /** - * VAT percent of the product (e.g. 19, or 5.1 if you like) - * - * @return VAT percent of the product - */ - BigDecimal getVATPercent(); + /** + * VAT percent of the product (e.g. 19, or 5.1 if you like) + * + * @return VAT percent of the product + */ + BigDecimal getVATPercent(); - default boolean isIntraCommunitySupply() { - return false; - } + default boolean isIntraCommunitySupply() { + return false; + } - default boolean isReverseCharge() { - return false; - } + default boolean isReverseCharge() { + return false; + } - default String getTaxCategoryCode() { - if (isIntraCommunitySupply()) { - return TaxCategoryCodeTypeConstants.INTRACOMMUNITY;// "K"; // within europe - } else if (isReverseCharge()) { - return TaxCategoryCodeTypeConstants.REVERSECHARGE;// "AE"; // to out of europe... - } else if (getVATPercent().compareTo(BigDecimal.ZERO) == 0) { - return TaxCategoryCodeTypeConstants.ZEROTAXPRODUCTS; // "Z"; // zero rated goods - } else { - return TaxCategoryCodeTypeConstants.STANDARDRATE;// "S"; // one of the "standard" rates (not - // neccessarily a default rate, even a deducted VAT - // is standard calculation) - } - } + default String getTaxCategoryCode() { + if (isIntraCommunitySupply()) { + return TaxCategoryCodeTypeConstants.INTRACOMMUNITY;// "K"; // within europe + } else if (isReverseCharge()) { + return TaxCategoryCodeTypeConstants.REVERSECHARGE;// "AE"; // to out of europe... + } else if (getVATPercent().compareTo(BigDecimal.ZERO) == 0) { + return TaxCategoryCodeTypeConstants.ZEROTAXPRODUCTS; // "Z"; // zero rated goods + } else { + return TaxCategoryCodeTypeConstants.STANDARDRATE;// "S"; // one of the "standard" rates (not + // neccessarily a default rate, even a deducted VAT + // is standard calculation) + } + } - /** - * customer global identification assigned by the seller - * - * @return customer identification - */ - default String getGlobalID() { - return null; - } - /** - * customer global identification scheme - * - * @return customer identification - */ - default String getGlobalIDScheme() { - return null; - } + /** + * customer global identification assigned by the seller + * + * @return customer identification + */ + default String getGlobalID() { + return null; + } + + /** + * customer global identification scheme + * + * @return customer identification + */ + default String getGlobalIDScheme() { + return null; + } + default String getTaxExemptionReason() { + if (isIntraCommunitySupply()) { + return "Intra-community supply"; + } else if (isReverseCharge()) { + return "Reverse Charge"; + } + return null; + } - default String getTaxExemptionReason() { - if (isIntraCommunitySupply()) { - return "Intra-community supply"; - } else if (isReverseCharge()) { - return "Reverse Charge"; - } - return null; - } + default String getCountryOfOrigin() { + return null; + } - default String getCountryOfOrigin() { - return null; - } + default HashMap getAttributes() { + return null; + } - default HashMap getAttributes() { - return null; - } - - /** - * Detailed information about the product - * - * @return an array containing the product classifications or {@code null} if not set - */ - default IDesignatedProductClassification[] getClassifications() { return null; } + /** + * Detailed information about the product + * + * @return an array containing the product classifications or {@code null} if not set + */ + default IDesignatedProductClassification[] getClassifications() { + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTradeParty.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTradeParty.java index a9977f0..45bda72 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTradeParty.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableTradeParty.java @@ -31,168 +31,169 @@ org.openrewrite.config.CompositeRecipe public interface IZUGFeRDExportableTradeParty { - /** - * customer identification assigned by the seller - * - * @return customer identification - */ - default String getID() { - return null; - } + /** + * customer identification assigned by the seller + * + * @return customer identification + */ + default String getID() { + return null; + } - /** - * customer global identification assigned by the seller - * - * @return customer identification - */ - default String getGlobalID() { - return null; - } + /** + * customer global identification assigned by the seller + * + * @return customer identification + */ + default String getGlobalID() { + return null; + } - /*** - * gets the official representation - * @return the interface with the attributes of the legal organisation - */ - default IZUGFeRDLegalOrganisation getLegalOrganisation() { - return null; - } + /*** + * gets the official representation + * @return the interface with the attributes of the legal organisation + */ + default IZUGFeRDLegalOrganisation getLegalOrganisation() { + return null; + } - /** - * customer global identification scheme - * - * @return customer identification - */ - default String getGlobalIDScheme() { - return null; - } + /** + * customer global identification scheme + * + * @return customer identification + */ + default String getGlobalIDScheme() { + return null; + } - /** - * URIUniversalCommunication scheme (see EAS code list of the ZUGFeRD documentation) - * I believe EM for Email - * @return String with code - */ - default String getUriUniversalCommunicationIDScheme() { - return null; - } + /** + * URIUniversalCommunication scheme (see EAS code list of the ZUGFeRD documentation) + * I believe EM for Email + * @return String with code + */ + default String getUriUniversalCommunicationIDScheme() { + return null; + } - - /** - * The URIID of URIUniversalCommunicationID (e.g. email address) - * It is used by some countries, i.e. Luxembourg, Peppol - * @return the URI as string - */ - default String getUriUniversalCommunicationID() { - return null; - } + /** + * The URIID of URIUniversalCommunicationID (e.g. email address) + * It is used by some countries, i.e. Luxembourg, Peppol + * @return the URI as string + */ + default String getUriUniversalCommunicationID() { + return null; + } - /*** - * gets the email of the organization (not the one of the contact person) - * will return null if not set or if the provided UriUniversalCommunicationID - * is not a email address - * - * @return String the email, or null - */ - default String getEmail() { - if ((getUriUniversalCommunicationIDScheme()!=null)&&(getUriUniversalCommunicationIDScheme().equals("EM"))) { - return getUriUniversalCommunicationID(); - } - return null; - } + /*** + * gets the email of the organization (not the one of the contact person) + * will return null if not set or if the provided UriUniversalCommunicationID + * is not a email address + * + * @return String the email, or null + */ + default String getEmail() { + if ((getUriUniversalCommunicationIDScheme() != null) && (getUriUniversalCommunicationIDScheme().equals("EM"))) { + return getUriUniversalCommunicationID(); + } + return null; + } - /*** - * the named contact person for inquiries - * @return contact - */ - default IZUGFeRDExportableContact getContact() { - return null; - } + /*** + * the named contact person for inquiries + * @return contact + */ + default IZUGFeRDExportableContact getContact() { + return null; + } - /** - * e.g. first and last name of the owner - * - * @return full name of the party - */ - String getName(); + /** + * e.g. first and last name of the owner + * + * @return full name of the party + */ + String getName(); - /** - * @return description, e.g. if it's a small company - */ - default String getDescription() { return null; } + /** + * @return description, e.g. if it's a small company + */ + default String getDescription() { + return null; + } - /** - * Postal code of the recipient - * - * @return Postal code of the recipient - */ - String getZIP(); + /** + * Postal code of the recipient + * + * @return Postal code of the recipient + */ + String getZIP(); - /** - * VAT ID (Umsatzsteueridentifikationsnummer) of the contact - * - * @return VAT ID (Umsatzsteueridentifikationsnummer) of the contact - */ - default String getVATID() { - return null; - } + /** + * VAT ID (Umsatzsteueridentifikationsnummer) of the contact + * + * @return VAT ID (Umsatzsteueridentifikationsnummer) of the contact + */ + default String getVATID() { + return null; + } - /** - * two-letter country code of the contact - * - * @return two-letter iso country code of the contact - */ - String getCountry(); + /** + * two-letter country code of the contact + * + * @return two-letter iso country code of the contact + */ + String getCountry(); - /** - * Returns the city of the contact - * - * @return Returns the city of the recipient - */ - String getLocation(); + /** + * Returns the city of the contact + * + * @return Returns the city of the recipient + */ + String getLocation(); - /** - * Returns the street address (street+number) of the contact - * - * @return street address (street+number) of the contact - */ - String getStreet(); + /** + * Returns the street address (street+number) of the contact + * + * @return street address (street+number) of the contact + */ + String getStreet(); - /** - * returns additional address information which is display in xml tag "LineTwo" - * e.g. "Rear building" - * - * @return additional address information - */ - default String getAdditionalAddress() { - return null; - } + /** + * returns additional address information which is display in xml tag "LineTwo" + * e.g. "Rear building" + * + * @return additional address information + */ + default String getAdditionalAddress() { + return null; + } - /** - * returns additional address information which is display in xml tag "LineThree" - * e.g. "Second floor" if LineTwo is already used, e.g. "Rear Building". - * This attribute could sometimes be BT-165? - * - * @return additional address information - */ - default String getAdditionalAddressExtension() { - return null; - } + /** + * returns additional address information which is display in xml tag "LineThree" + * e.g. "Second floor" if LineTwo is already used, e.g. "Rear Building". + * This attribute could sometimes be BT-165? + * + * @return additional address information + */ + default String getAdditionalAddressExtension() { + return null; + } - /*** - * obligatory for sender but not for recipient - * @return the tax id as string - */ - default String getTaxID() { - return null; - } + /*** + * obligatory for sender but not for recipient + * @return the tax id as string + */ + default String getTaxID() { + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExporter.java index fd4ffb4..bb60974 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExporter.java @@ -18,55 +18,69 @@ org.openrewrite.config.CompositeRecipe *********************************************************************** */ package org.mustangproject.ZUGFeRD; +import jakarta.activation.DataSource; +import org.mustangproject.FileAttachment; + import java.io.Closeable; import java.io.IOException; import java.io.InputStream; -import jakarta.activation.DataSource; -import org.mustangproject.FileAttachment; +public interface IZUGFeRDExporter extends Closeable, IExporter { + /** + * factory: loads a PDF file and returns an appropriate exporter + * + * @param pdfFilename binary of a PDF/A1 compliant document + * @return the generated exporter + * @throws IOException if anything is wrong with filename + */ + public IZUGFeRDExporter load(String pdfFilename) throws IOException; -public interface IZUGFeRDExporter extends Closeable, IExporter { - /** - * factory: loads a PDF file and returns an appropriate exporter - * - * @param pdfFilename binary of a PDF/A1 compliant document - * @return the generated exporter - * @throws IOException if anything is wrong with filename - */ - public IZUGFeRDExporter load(String pdfFilename) throws IOException; + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfBinary binary of a PDF/A1 compliant document + * @return the generated exporter + * @throws IOException (should not happen at all) + */ + public IZUGFeRDExporter load(byte[] pdfBinary) throws IOException; - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfBinary binary of a PDF/A1 compliant document - * @return the generated exporter - * @throws IOException (should not happen at all) - */ - public IZUGFeRDExporter load(byte[] pdfBinary) throws IOException; + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfSource source to read a PDF/A1 compliant document from + * @throws IOException if anything is wrong with inputstream + * @return the generated ZUGFeRDExporter + */ + public IZUGFeRDExporter load(InputStream pdfSource) throws IOException; - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfSource source to read a PDF/A1 compliant document from - * @throws IOException if anything is wrong with inputstream - * @return the generated ZUGFeRDExporter - */ - public IZUGFeRDExporter load(InputStream pdfSource) throws IOException; - public IZUGFeRDExporter setCreator(String creator); - public IZUGFeRDExporter setConformanceLevel(PDFAConformanceLevel newLevel); - public IZUGFeRDExporter setProducer(String producer); - public IZUGFeRDExporter setZUGFeRDVersion(int version); - public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException; - public IZUGFeRDExporter setXML(byte[] zugferdData) throws IOException; - public IZUGFeRDExporter disableFacturX(); - public IZUGFeRDExporter setProfile(Profile zugferdConformanceLevel); - public String getNamespaceForVersion(int ver); - public String getPrefixForVersion(int ver) ; - public IZUGFeRDExporter disableAutoClose(boolean disableAutoClose); - public void attachFile(FileAttachment file); - public void attachFile(String filename, byte[] data, String mimetype, String relation); - public IXMLProvider getProvider(); + public IZUGFeRDExporter setCreator(String creator); + + public IZUGFeRDExporter setConformanceLevel(PDFAConformanceLevel newLevel); + + public IZUGFeRDExporter setProducer(String producer); + + public IZUGFeRDExporter setZUGFeRDVersion(int version); + + public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException; + + public IZUGFeRDExporter setXML(byte[] zugferdData) throws IOException; + + public IZUGFeRDExporter disableFacturX(); + + public IZUGFeRDExporter setProfile(Profile zugferdConformanceLevel); + + public String getNamespaceForVersion(int ver); + + public String getPrefixForVersion(int ver); + + public IZUGFeRDExporter disableAutoClose(boolean disableAutoClose); + + public void attachFile(FileAttachment file); + + public void attachFile(String filename, byte[] data, String mimetype, String relation); + + public IXMLProvider getProvider(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDLegalOrganisation.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDLegalOrganisation.java index 09bf14f..638d5e0 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDLegalOrganisation.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDLegalOrganisation.java @@ -20,17 +20,17 @@ org.openrewrite.config.CompositeRecipe import org.mustangproject.SchemedID; -public interface IZUGFeRDLegalOrganisation { +public interface IZUGFeRDLegalOrganisation { - /** - * - * @return the scheme attribute of the legal organization=the type of the identification, e.g. 0002=Siren, and its value - */ - public SchemedID getSchemedID(); + /** + * + * @return the scheme attribute of the legal organization=the type of the identification, e.g. 0002=Siren, and its value + */ + public SchemedID getSchemedID(); - /*** - * - * @return the TradingBusinessName of the legal organisation - */ - public String getTradingBusinessName(); + /*** + * + * @return the TradingBusinessName of the legal organisation + */ + public String getTradingBusinessName(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDPaymentDiscountTerms.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDPaymentDiscountTerms.java index 4fc5f55..9a24688 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDPaymentDiscountTerms.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDPaymentDiscountTerms.java @@ -5,12 +5,12 @@ org.openrewrite.config.CompositeRecipe public interface IZUGFeRDPaymentDiscountTerms { - BigDecimal getCalculationPercentage(); + BigDecimal getCalculationPercentage(); - Date getBaseDate(); + Date getBaseDate(); - int getBasePeriodMeasure(); + int getBasePeriodMeasure(); - String getBasePeriodUnitCode(); + String getBasePeriodUnitCode(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDPaymentTerms.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDPaymentTerms.java index 6f2cb9a..f8ed27e 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDPaymentTerms.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDPaymentTerms.java @@ -4,9 +4,9 @@ org.openrewrite.config.CompositeRecipe public interface IZUGFeRDPaymentTerms { - String getDescription(); + String getDescription(); - Date getDueDate(); + Date getDueDate(); - IZUGFeRDPaymentDiscountTerms getDiscountTerms(); + IZUGFeRDPaymentDiscountTerms getDiscountTerms(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlement.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlement.java index 3dd18d7..b217a3a 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlement.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlement.java @@ -22,23 +22,22 @@ org.openrewrite.config.CompositeRecipe public interface IZUGFeRDTradeSettlement { - /*** - * gets the applicableHeaderTradeSettlement - * @return zf2 xml - */ - @JsonIgnore - String getSettlementXML(); - + /*** + * gets the applicableHeaderTradeSettlement + * @return zf2 xml + */ + @JsonIgnore + String getSettlementXML(); - /*** - * gets the applicableHeaderTradePayment - * @return zf2 xml - */ - @JsonIgnore - default String getPaymentXML() { - return null; - } - - + + /*** + * gets the applicableHeaderTradePayment + * @return zf2 xml + */ + @JsonIgnore + default String getPaymentXML() { + return null; + } + } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementDebit.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementDebit.java index 7402b92..22907e5 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementDebit.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementDebit.java @@ -22,33 +22,33 @@ org.openrewrite.config.CompositeRecipe public interface IZUGFeRDTradeSettlementDebit extends IZUGFeRDTradeSettlement { - @Override - default String getSettlementXML() { - String xml = "" - + "59" - + "SEPA direct debit" - + "" - + "" + XMLTools.encodeXML(getIBAN()) + "" - + ""; - - xml += ""; - return xml; - } + @Override + default String getSettlementXML() { + String xml = "" + + "59" + + "SEPA direct debit" + + "" + + "" + XMLTools.encodeXML(getIBAN()) + "" + + ""; - @Override - default String getPaymentXML() { - return "" + XMLTools.encodeXML(getMandate()) + ""; - } + xml += ""; + return xml; + } + + @Override + default String getPaymentXML() { + return "" + XMLTools.encodeXML(getMandate()) + ""; + } - /*** - * @return IBAN of the debtor (optional) - */ - String getIBAN(); + /*** + * @return IBAN of the debtor (optional) + */ + String getIBAN(); - /*** - * @return sepa direct debit mandate reference - */ - String getMandate(); + /*** + * @return sepa direct debit mandate reference + */ + String getMandate(); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementPayment.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementPayment.java index 9731a9a..5d2370f 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementPayment.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDTradeSettlementPayment.java @@ -23,75 +23,77 @@ org.openrewrite.config.CompositeRecipe public interface IZUGFeRDTradeSettlementPayment extends IZUGFeRDTradeSettlement { - /** - * get payment information text. e.g. Bank transfer - * - * @return payment information text - */ - @JsonIgnore - default String getOwnPaymentInfoText() { - return null; - } + /** + * get payment information text. e.g. Bank transfer + * + * @return payment information text + */ + @JsonIgnore + default String getOwnPaymentInfoText() { + return null; + } - /** - * BIC of the sender - * - * @return the BIC code of the recipient sender's bank - */ - default String getOwnBIC() { - return null; - } + /** + * BIC of the sender + * + * @return the BIC code of the recipient sender's bank + */ + default String getOwnBIC() { + return null; + } - /** - * IBAN of the sender - * - * @return the IBAN of the invoice sender's bank account - */ - default String getOwnIBAN() { - return null; - } + /** + * IBAN of the sender + * + * @return the IBAN of the invoice sender's bank account + */ + default String getOwnIBAN() { + return null; + } - /*** - * Account name - * - * @return the name of the account holder (if not identical to sender) - */ - default String getAccountName() { return null; } + /*** + * Account name + * + * @return the name of the account holder (if not identical to sender) + */ + default String getAccountName() { + return null; + } - @Override - @JsonIgnore - default String getSettlementXML() { - String accountNameStr=""; - if (getAccountName()!=null) { - accountNameStr="" + XMLTools.encodeXML(getAccountName()) + ""; + @Override + @JsonIgnore + default String getSettlementXML() { + String accountNameStr = ""; + if (getAccountName() != null) { + accountNameStr = "" + XMLTools.encodeXML(getAccountName()) + ""; - } + } - String xml = "" - + "58" - + "SEPA credit transfer" - + "" - + "" + XMLTools.encodeXML(getOwnIBAN()) + ""; - xml+= accountNameStr; - xml+= ""; - if (getOwnBIC()!=null) { - xml+= "" - + "" + XMLTools.encodeXML(getOwnBIC()) + "" - // + " "+trans.getOwnBankName()+"" - // - + ""; + String xml = "" + + "58" + + "SEPA credit transfer" + + "" + + "" + XMLTools.encodeXML(getOwnIBAN()) + ""; + xml += accountNameStr; + xml += ""; + if (getOwnBIC() != null) { + xml += "" + + "" + XMLTools.encodeXML(getOwnBIC()) + "" + // + " "+trans.getOwnBankName()+"" + // + + ""; - } - xml+= ""; - return xml; - } - - - /* I'd love to implement getPaymentXML() and put there because this is where it belongs - * unfortunately, the due date is part of the transaction which is not accessible here :-( - */ + } + xml += ""; + return xml; + } + + + /* I'd love to implement getPaymentXML() and put there because this is where it belongs + * unfortunately, the due date is part of the transaction which is not accessible here :-( + */ } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java b/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java index e319ec7..9b038b2 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java @@ -8,88 +8,88 @@ org.openrewrite.config.CompositeRecipe * @see TransactionCalculator */ public class LineCalculator { - private final BigDecimal price; - private final BigDecimal priceGross; - private final BigDecimal itemTotalNetAmount; - private final BigDecimal itemTotalVATAmount; - private BigDecimal allowance = BigDecimal.ZERO; - private BigDecimal charge = BigDecimal.ZERO; - private BigDecimal allowanceItemTotal = BigDecimal.ZERO; + private final BigDecimal price; + private final BigDecimal priceGross; + private final BigDecimal itemTotalNetAmount; + private final BigDecimal itemTotalVATAmount; + private BigDecimal allowance = BigDecimal.ZERO; + private BigDecimal charge = BigDecimal.ZERO; + private BigDecimal allowanceItemTotal = BigDecimal.ZERO; - public LineCalculator(IZUGFeRDExportableItem currentItem) { + public LineCalculator(IZUGFeRDExportableItem currentItem) { - if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { - for (IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { - addAllowance(allowance.getTotalAmount(currentItem)); - } - } - if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { - for (IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { - addCharge(charge.getTotalAmount(currentItem)); - } - } - if (currentItem.getItemTotalAllowances() != null && currentItem.getItemTotalAllowances().length > 0) { - for (final IZUGFeRDAllowanceCharge itemTotalAllowance : currentItem.getItemTotalAllowances()) { - addAllowanceItemTotal(itemTotalAllowance.getTotalAmount(currentItem)); - } - } - - BigDecimal vatPercent = null; - if (currentItem.getProduct()!=null) { - vatPercent = currentItem.getProduct().getVATPercent(); - } - if (vatPercent == null) { - vatPercent = BigDecimal.ZERO; - } - BigDecimal multiplicator = vatPercent.divide(BigDecimal.valueOf(100)); - priceGross = currentItem.getPrice(); // see https://github.com/ZUGFeRD/mustangproject/issues/159 - price = priceGross.subtract(allowance).add(charge); + if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { + for (IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { + addAllowance(allowance.getTotalAmount(currentItem)); + } + } + if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { + for (IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { + addCharge(charge.getTotalAmount(currentItem)); + } + } + if (currentItem.getItemTotalAllowances() != null && currentItem.getItemTotalAllowances().length > 0) { + for (final IZUGFeRDAllowanceCharge itemTotalAllowance : currentItem.getItemTotalAllowances()) { + addAllowanceItemTotal(itemTotalAllowance.getTotalAmount(currentItem)); + } + } - BigDecimal quantity=BigDecimal.ZERO; - if ((currentItem!=null)&&(currentItem.getQuantity()!=null)) { - quantity=currentItem.getQuantity(); - } + BigDecimal vatPercent = null; + if (currentItem.getProduct() != null) { + vatPercent = currentItem.getProduct().getVATPercent(); + } + if (vatPercent == null) { + vatPercent = BigDecimal.ZERO; + } + BigDecimal multiplicator = vatPercent.divide(BigDecimal.valueOf(100)); + priceGross = currentItem.getPrice(); // see https://github.com/ZUGFeRD/mustangproject/issues/159 + price = priceGross.subtract(allowance).add(charge); - // Division/Zero occurred here. - // Used the setScale only because that's also done in getBasisQuantity - BigDecimal basisQuantity = currentItem.getBasisQuantity().compareTo(BigDecimal.ZERO) == 0 - ? BigDecimal.ONE.setScale(4) - : currentItem.getBasisQuantity(); - itemTotalNetAmount = quantity.multiply(getPrice()).divide(basisQuantity, 18, RoundingMode.HALF_UP) - .subtract(allowanceItemTotal).setScale(2, RoundingMode.HALF_UP); - itemTotalVATAmount = itemTotalNetAmount.multiply(multiplicator); - } + BigDecimal quantity = BigDecimal.ZERO; + if ((currentItem != null) && (currentItem.getQuantity() != null)) { + quantity = currentItem.getQuantity(); + } - public BigDecimal getPrice() { - return price; - } + // Division/Zero occurred here. + // Used the setScale only because that's also done in getBasisQuantity + BigDecimal basisQuantity = currentItem.getBasisQuantity().compareTo(BigDecimal.ZERO) == 0 + ? BigDecimal.ONE.setScale(4) + : currentItem.getBasisQuantity(); + itemTotalNetAmount = quantity.multiply(getPrice()).divide(basisQuantity, 18, RoundingMode.HALF_UP) + .subtract(allowanceItemTotal).setScale(2, RoundingMode.HALF_UP); + itemTotalVATAmount = itemTotalNetAmount.multiply(multiplicator); + } - public BigDecimal getItemTotalNetAmount() { - return itemTotalNetAmount; - } + public BigDecimal getPrice() { + return price; + } - public BigDecimal getItemTotalVATAmount() { - return itemTotalVATAmount; - } + public BigDecimal getItemTotalNetAmount() { + return itemTotalNetAmount; + } - public BigDecimal getItemTotalGrossAmount() { - return itemTotalNetAmount; - } + public BigDecimal getItemTotalVATAmount() { + return itemTotalVATAmount; + } - public BigDecimal getPriceGross() { - return priceGross; - } + public BigDecimal getItemTotalGrossAmount() { + return itemTotalNetAmount; + } - public void addAllowance(BigDecimal b) { - allowance = allowance.add(b); - } + public BigDecimal getPriceGross() { + return priceGross; + } - public void addCharge(BigDecimal b) { - charge = charge.add(b); - } + public void addAllowance(BigDecimal b) { + allowance = allowance.add(b); + } - public void addAllowanceItemTotal(BigDecimal b) { - allowanceItemTotal = allowanceItemTotal.add(b); - } + public void addCharge(BigDecimal b) { + charge = charge.add(b); + } + + public void addAllowanceItemTotal(BigDecimal b) { + allowanceItemTotal = allowanceItemTotal.add(b); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DateTimeTypeConstants.java b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DateTimeTypeConstants.java index 895aa89..7928a84 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DateTimeTypeConstants.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DateTimeTypeConstants.java @@ -19,7 +19,7 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD.model; public class DateTimeTypeConstants { - public static final String DATE = "102"; - public static final String MONTH = "610"; - public static final String WEEK = "616"; + public static final String DATE = "102"; + public static final String MONTH = "610"; + public static final String WEEK = "616"; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java index 74fac56..707609d 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentCodeTypeConstants.java @@ -19,9 +19,9 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD.model; public class DocumentCodeTypeConstants { - public static final String INVOICE = "380"; - public static final String CREDITNOTE = "381"; - public static final String DEBITNOTE = "84"; - public static final String CORRECTEDINVOICE = "384"; - public static final String PARTIAL_BILLING = "326"; + public static final String INVOICE = "380"; + public static final String CREDITNOTE = "381"; + public static final String DEBITNOTE = "84"; + public static final String CORRECTEDINVOICE = "384"; + public static final String PARTIAL_BILLING = "326"; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentContextParameterTypeConstants.java b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentContextParameterTypeConstants.java index d90eabd..6a419bc 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentContextParameterTypeConstants.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/model/DocumentContextParameterTypeConstants.java @@ -19,7 +19,7 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD.model; public class DocumentContextParameterTypeConstants { - public static final String BASIC = "urn:ferd:CrossIndustryDocument:invoice:1p0:basic"; - public static final String COMFORT = "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort"; - public static final String EXTENDED = "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"; + public static final String BASIC = "urn:ferd:CrossIndustryDocument:invoice:1p0:basic"; + public static final String COMFORT = "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort"; + public static final String EXTENDED = "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/model/EventTimeCodeTypeConstants.java b/library/src/main/java/org/mustangproject/ZUGFeRD/model/EventTimeCodeTypeConstants.java index 6ebb54c..c883f87 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/model/EventTimeCodeTypeConstants.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/model/EventTimeCodeTypeConstants.java @@ -19,7 +19,7 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD.model; public class EventTimeCodeTypeConstants { - public static final String INVOICE_DATE = "5"; - public static final String DELIVERY_DATE = "29"; - public static final String PAYMENT_DATE = "72"; + public static final String INVOICE_DATE = "5"; + public static final String DELIVERY_DATE = "29"; + public static final String PAYMENT_DATE = "72"; } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java b/library/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java index c9ecc2a..834d55f 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java @@ -23,13 +23,13 @@ org.openrewrite.config.CompositeRecipe import java.util.stream.Stream; public class TaxCategoryCodeTypeConstants { - public static final String STANDARDRATE = "S"; - public static final String REVERSECHARGE = "AE"; - public static final String TAXEXEMPT = "E"; - public static final String ZEROTAXPRODUCTS = "Z"; - public static final String UNTAXEDSERVICE = "O"; - public static final String INTRACOMMUNITY = "K"; - public static final String FREEEXPORT = "G"; + public static final String STANDARDRATE = "S"; + public static final String REVERSECHARGE = "AE"; + public static final String TAXEXEMPT = "E"; + public static final String ZEROTAXPRODUCTS = "Z"; + public static final String UNTAXEDSERVICE = "O"; + public static final String INTRACOMMUNITY = "K"; + public static final String FREEEXPORT = "G"; - public static Set CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT, FREEEXPORT).collect(Collectors.toSet()); + public static Set CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT, FREEEXPORT).collect(Collectors.toSet()); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java b/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java index 33f95ae..fe54750 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java @@ -19,139 +19,149 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; -import java.io.IOException; -import java.io.InputStream; - +import jakarta.activation.DataSource; import org.apache.pdfbox.preflight.PreflightDocument; import org.apache.pdfbox.preflight.ValidationResult; import org.apache.pdfbox.preflight.exception.ValidationException; import org.apache.pdfbox.preflight.parser.PreflightParser; -import jakarta.activation.DataSource; +import java.io.IOException; +import java.io.InputStream; public class OXExporterFromA1 extends OXExporterFromA3 { - protected boolean ignorePDFAErrors = false; + protected boolean ignorePDFAErrors = false; - @Override - public OXExporterFromA1 ignorePDFAErrors() { - this.ignorePDFAErrors = true; - return this; - } + @Override + public OXExporterFromA1 ignorePDFAErrors() { + this.ignorePDFAErrors = true; + return this; + } - private static boolean isValidA1(DataSource dataSource) throws IOException { - return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource)); - } - /*** - * internal helper function: get namespace for order-x - * @param ver the order-x version - * @return the URN of the namespace - */ - @Override - public String getNamespaceForVersion(int ver) { - return "urn:factur-x:pdfa:CrossIndustryDocument:1p0#"; - } - /*** - * internal helper: returns the namespace prefix for the given order-x version number - * @param ver the ox version - * @return the namespace prefix as string, without colon - */ - @Override - public String getPrefixForVersion(int ver) { - return "fx"; - } + private static boolean isValidA1(DataSource dataSource) throws IOException { + return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource)); + } - private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException { - /* - * Parse the PDF file with PreflightParser that inherits from the - * NonSequentialParser. Some additional controls are present to check a set of - * PDF/A requirements. (Stream length consistency, EOL after some Keyword...) - */ - // might add a Format.PDF_A1A as parameter and iterate through A1 and A3 + /*** + * internal helper function: get namespace for order-x + * @param ver the order-x version + * @return the URN of the namespace + */ + @Override + public String getNamespaceForVersion(int ver) { + return "urn:factur-x:pdfa:CrossIndustryDocument:1p0#"; + } - try (PreflightDocument document = (PreflightDocument) parser.parse()) { - /* - * Once the syntax validation is done, the parser can provide a - * PreflightDocument (that inherits from PDDocument) This document process the - * end of PDF/A validation. - */ + /*** + * internal helper: returns the namespace prefix for the given order-x version number + * @param ver the ox version + * @return the namespace prefix as string, without colon + */ + @Override + public String getPrefixForVersion(int ver) { + return "fx"; + } - ValidationResult res = document.validate(); + private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException { + /* + * Parse the PDF file with PreflightParser that inherits from the + * NonSequentialParser. Some additional controls are present to check a set of + * PDF/A requirements. (Stream length consistency, EOL after some Keyword...) + */ + // might add a Format.PDF_A1A as parameter and iterate through A1 and A3 - // Get validation result - return res.isValid(); - } catch (ValidationException e) { - /* - * the parse method can throw a SyntaxValidationException if the PDF file can't - * be parsed. In this case, the exception contains an instance of - * ValidationResult - */ - return false; - } - } + try (PreflightDocument document = (PreflightDocument) parser.parse()) { + /* + * Once the syntax validation is done, the parser can provide a + * PreflightDocument (that inherits from PDDocument) This document process the + * end of PDF/A validation. + */ + + ValidationResult res = document.validate(); + + // Get validation result + return res.isValid(); + } catch (ValidationException e) { + /* + * the parse method can throw a SyntaxValidationException if the PDF file can't + * be parsed. In this case, the exception contains an instance of + * ValidationResult + */ + return false; + } + } - @Override - public OXExporterFromA1 setProfile(Profile p) { - return (OXExporterFromA1)super.setProfile(p); - } - @Override - public OXExporterFromA1 setProfile(String profileName) { - return (OXExporterFromA1)super.setProfile(profileName); - } + @Override + public OXExporterFromA1 setProfile(Profile p) { + return (OXExporterFromA1) super.setProfile(p); + } - @Override - public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { - if (!ignorePDFAErrors && !isValidA1(dataSource)) { - throw new IOException("File is not a valid PDF/A input file"); - } - return true; - } + @Override + public OXExporterFromA1 setProfile(String profileName) { + return (OXExporterFromA1) super.setProfile(profileName); + } - public OXExporterFromA1() { - setZUGFeRDVersion(ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion); + @Override + public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { + if (!ignorePDFAErrors && !isValidA1(dataSource)) { + throw new IOException("File is not a valid PDF/A input file"); + } + return true; + } - } + public OXExporterFromA1() { + setZUGFeRDVersion(ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion); - @Override - public OXExporterFromA1 load(String pdfFilename) throws IOException { - return (OXExporterFromA1) super.load(pdfFilename); - } - @Override - public OXExporterFromA1 load(byte[] pdfBinary) throws IOException { - return (OXExporterFromA1) super.load(pdfBinary); - } - @Override - public OXExporterFromA1 load(InputStream pdfSource) throws IOException{ - return (OXExporterFromA1) super.load(pdfSource); - } - @Override - public OXExporterFromA1 setCreator(String creator) { - return (OXExporterFromA1) super.setCreator(creator); - } - @Override - public OXExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) { - return (OXExporterFromA1) super.setConformanceLevel(newLevel); - } - @Override - public OXExporterFromA1 setProducer(String producer){ - return (OXExporterFromA1) super.setProducer(producer); - } - @Override - public OXExporterFromA1 setZUGFeRDVersion(int version){ - return (OXExporterFromA1) super.setZUGFeRDVersion(version); - } - @Override - public OXExporterFromA1 setXML(byte[] zugferdData) throws IOException{ - return (OXExporterFromA1) super.setXML(zugferdData); - } + } - @Override - public OXExporterFromA1 disableAutoClose(boolean disableAutoClose){ - return (OXExporterFromA1) super.disableAutoClose(disableAutoClose); - } - public OXExporterFromA1 convertOnly() { - setAttachZUGFeRDHeaders(false); - return this; - } + @Override + public OXExporterFromA1 load(String pdfFilename) throws IOException { + return (OXExporterFromA1) super.load(pdfFilename); + } + + @Override + public OXExporterFromA1 load(byte[] pdfBinary) throws IOException { + return (OXExporterFromA1) super.load(pdfBinary); + } + + @Override + public OXExporterFromA1 load(InputStream pdfSource) throws IOException { + return (OXExporterFromA1) super.load(pdfSource); + } + + @Override + public OXExporterFromA1 setCreator(String creator) { + return (OXExporterFromA1) super.setCreator(creator); + } + + @Override + public OXExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) { + return (OXExporterFromA1) super.setConformanceLevel(newLevel); + } + + @Override + public OXExporterFromA1 setProducer(String producer) { + return (OXExporterFromA1) super.setProducer(producer); + } + + @Override + public OXExporterFromA1 setZUGFeRDVersion(int version) { + return (OXExporterFromA1) super.setZUGFeRDVersion(version); + } + + @Override + public OXExporterFromA1 setXML(byte[] zugferdData) throws IOException { + return (OXExporterFromA1) super.setXML(zugferdData); + } + + @Override + public OXExporterFromA1 disableAutoClose(boolean disableAutoClose) { + return (OXExporterFromA1) super.disableAutoClose(disableAutoClose); + } + + public OXExporterFromA1 convertOnly() { + setAttachZUGFeRDHeaders(false); + return this; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA3.java b/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA3.java index 6e7f3ad..05ff536 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA3.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA3.java @@ -20,26 +20,10 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.transform.TransformerException; - +import jakarta.activation.DataSource; +import jakarta.activation.FileDataSource; import org.apache.pdfbox.Loader; -import org.apache.pdfbox.cos.COSArray; -import org.apache.pdfbox.cos.COSBase; -import org.apache.pdfbox.cos.COSDictionary; -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.cos.COSObject; +import org.apache.pdfbox.cos.*; import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentCatalog; @@ -65,688 +49,692 @@ import org.mustangproject.EStandard; import org.mustangproject.FileAttachment; -import jakarta.activation.DataSource; -import jakarta.activation.FileDataSource; +import javax.xml.transform.TransformerException; +import java.io.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 { - protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE; - protected ArrayList fileAttachments = new ArrayList<>(); + protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE; + protected ArrayList fileAttachments = new ArrayList<>(); - /** - * This flag controls whether or not the metadata is overwritten, or kind of merged. - * The merging probably needs to be overhauled, but for my purpose it was good enough. - */ - protected boolean overwrite = true; + /** + * This flag controls whether or not the metadata is overwritten, or kind of merged. + * The merging probably needs to be overhauled, but for my purpose it was good enough. + */ + protected boolean overwrite = true; - private boolean disableAutoClose; - private boolean fileAttached = false; - private Profile profile = null; - private boolean documentPrepared = false; + private boolean disableAutoClose; + private boolean fileAttached = false; + private Profile profile = null; + private boolean documentPrepared = false; - /** - * Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set, - * in which case passing a IZUGFeRDExportableTransaction is not necessary. By - * default it is null meaning the caller needs to pass a - * IZUGFeRDExportableTransaction for the XML to be populated. - */ - protected PDMetadata metadata = null; - /** - * Producer attribute for PDF - */ - protected String producer = "mustangproject"; - /** - * Author/Creator attribute for PDF - */ - protected String creator = "mustangproject"; - /** - * CreatorTool - */ - protected String creatorTool = "mustangproject"; + /** + * Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set, + * in which case passing a IZUGFeRDExportableTransaction is not necessary. By + * default it is null meaning the caller needs to pass a + * IZUGFeRDExportableTransaction for the XML to be populated. + */ + protected PDMetadata metadata = null; + /** + * Producer attribute for PDF + */ + protected String producer = "mustangproject"; + /** + * Author/Creator attribute for PDF + */ + protected String creator = "mustangproject"; + /** + * CreatorTool + */ + protected String creatorTool = "mustangproject"; - /** - * @deprecated author is never set yet - */ - @Deprecated - protected String author; - /** - * @deprecated title is never set yet - */ - @Deprecated - protected String title; - /** - * @deprecated subject is never set yet - */ - @Deprecated - protected String subject; + /** + * @deprecated author is never set yet + */ + @Deprecated + protected String author; + /** + * @deprecated title is never set yet + */ + @Deprecated + protected String title; + /** + * @deprecated subject is never set yet + */ + @Deprecated + protected String subject; - /** - * OrderX document type. As of version 1.0 it may be - * ORDER, ORDER_RESPONSE, or ORDER_CHANGE - */ - protected String orderXDocumentType = "ORDER"; + /** + * OrderX document type. As of version 1.0 it may be + * ORDER, ORDER_RESPONSE, or ORDER_CHANGE + */ + protected String orderXDocumentType = "ORDER"; - private boolean attachZUGFeRDHeaders = true; + private boolean attachZUGFeRDHeaders = true; - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfFilename filename of an PDF/A1 compliant document - */ - @Override - public OXExporterFromA3 load(String pdfFilename) throws IOException { + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfFilename filename of an PDF/A1 compliant document + */ + @Override + public OXExporterFromA3 load(String pdfFilename) throws IOException { - ensurePDFIsValid(new FileDataSource(pdfFilename)); - try (FileInputStream pdf = new FileInputStream(pdfFilename)) { - return load(readAllBytes(pdf)); - } - } + ensurePDFIsValid(new FileDataSource(pdfFilename)); + try (FileInputStream pdf = new FileInputStream(pdfFilename)) { + return load(readAllBytes(pdf)); + } + } - @Override - public IXMLProvider getProvider() { - return xmlProvider; - } + @Override + public IXMLProvider getProvider() { + return xmlProvider; + } - @Override - public OXExporterFromA3 setProfile(Profile p) { - this.profile = p; - if (xmlProvider != null) { - xmlProvider.setProfile(p); - } - return this; - } + @Override + public OXExporterFromA3 setProfile(Profile p) { + this.profile = p; + if (xmlProvider != null) { + xmlProvider.setProfile(p); + } + return this; + } - @Override - public OXExporterFromA3 setProfile(String profilename) { - this.profile = Profiles.getByName(profilename); + @Override + public OXExporterFromA3 setProfile(String profilename) { + this.profile = Profiles.getByName(profilename); - if (xmlProvider != null) { - xmlProvider.setProfile(this.profile); - } - return this; - } + if (xmlProvider != null) { + xmlProvider.setProfile(this.profile); + } + return this; + } - @Override - public OXExporterFromA3 addAdditionalFile(String name, byte[] content) { - fileAttachments.add(new FileAttachment(name, "text/xml", "Supplement", content).setDescription("ZUGFeRD extension/additional data")); - return this; - } + @Override + public OXExporterFromA3 addAdditionalFile(String name, byte[] content) { + fileAttachments.add(new FileAttachment(name, "text/xml", "Supplement", content).setDescription("ZUGFeRD extension/additional data")); + return this; + } + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfBinary binary of a PDF/A1 compliant document + */ + @Override + public OXExporterFromA3 load(byte[] pdfBinary) throws IOException { + ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); + doc = Loader.loadPDF(pdfBinary); + return this; + } - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfBinary binary of a PDF/A1 compliant document - */ - @Override - public OXExporterFromA3 load(byte[] pdfBinary) throws IOException { - ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); - doc = Loader.loadPDF(pdfBinary); - return this; - } + public OXExporterFromA3() { + super(); + } - public OXExporterFromA3() { - super(); - } + @Override + public void attachFile(FileAttachment file) { + fileAttachments.add(file); + } - @Override - public void attachFile(FileAttachment file) { - fileAttachments.add(file); - } + @Override + public void attachFile(String filename, byte[] data, String mimetype, String relation) { + FileAttachment fa = new FileAttachment(filename, mimetype, relation, data); + fileAttachments.add(fa); + } - @Override - public void attachFile(String filename, byte[] data, String mimetype, String relation) { - FileAttachment fa = new FileAttachment(filename, mimetype, relation, data); - fileAttachments.add(fa); - } + /*** + * Perform the final export to a now ZUGFeRD-enriched PDF file + * @param ZUGFeRDfilename the pdf file name + * @throws IOException if anything is wrong in the target location + */ + @Override + public void export(String ZUGFeRDfilename) throws IOException { + if (!documentPrepared) { + prepareDocument(); + } + if ((!fileAttached) && attachZUGFeRDHeaders) { + throw new IOException( + "File must be attached (usually with setTransaction) before perfoming this operation"); + } + doc.save(ZUGFeRDfilename); + if (!disableAutoClose) { + close(); + } + } - /*** - * Perform the final export to a now ZUGFeRD-enriched PDF file - * @param ZUGFeRDfilename the pdf file name - * @throws IOException if anything is wrong in the target location - */ - @Override - public void export(String ZUGFeRDfilename) throws IOException { - if (!documentPrepared) { - prepareDocument(); - } - if ((!fileAttached) && (attachZUGFeRDHeaders)) { - throw new IOException( - "File must be attached (usually with setTransaction) before perfoming this operation"); - } - doc.save(ZUGFeRDfilename); - if (!disableAutoClose) { - close(); - } - } + @Override + public void close() throws IOException { + if (doc != null) { + doc.close(); + } + } - @Override - public void close() throws IOException { - if (doc != null) { - doc.close(); - } - } + /*** + * Perform the final export to a now ZUGFeRD-enriched PDF file as OutputStream + * @param output the OutputStream + * @throws IOException if anything is wrong in the OutputStream + */ + @Override + public void export(OutputStream output) throws IOException { + if (!documentPrepared) { + prepareDocument(); + } + if ((!fileAttached) && attachZUGFeRDHeaders) { + throw new IOException( + "File must be attached (usually with setTransaction) before perfoming this operation"); + } + doc.save(output); + if (!disableAutoClose) { + close(); + } + } - /*** - * Perform the final export to a now ZUGFeRD-enriched PDF file as OutputStream - * @param output the OutputStream - * @throws IOException if anything is wrong in the OutputStream - */ - @Override - public void export(OutputStream output) throws IOException { - if (!documentPrepared) { - prepareDocument(); - } - if ((!fileAttached) && (attachZUGFeRDHeaders)) { - throw new IOException( - "File must be attached (usually with setTransaction) before perfoming this operation"); - } - doc.save(output); - if (!disableAutoClose) { - close(); - } - } + /** + * Embeds an external file (generic - any type allowed) in the PDF. + * The embedding is done in the default PDF document. + * + * @param filename name of the file that will become attachment name in the PDF + * @param relationship how the file relates to the content, e.g. "Alternative" + * @param description Human-readable description of the file content + * @param subType type of the data e.g. could be "text/xml" - mime like + * @param data the binary data of the file/attachment + * @throws java.io.IOException if anything is wrong with filename + */ + @Override + public void PDFAttachGenericFile(String filename, String relationship, String description, + String subType, byte[] data) throws IOException { + PDFAttachGenericFile(this.doc, filename, relationship, description, subType, data); + } - /** - * Embeds an external file (generic - any type allowed) in the PDF. - * The embedding is done in the default PDF document. - * - * @param filename name of the file that will become attachment name in the PDF - * @param relationship how the file relates to the content, e.g. "Alternative" - * @param description Human-readable description of the file content - * @param subType type of the data e.g. could be "text/xml" - mime like - * @param data the binary data of the file/attachment - * @throws java.io.IOException if anything is wrong with filename - */ - @Override - public void PDFAttachGenericFile(String filename, String relationship, String description, - String subType, byte[] data) throws IOException { - PDFAttachGenericFile(this.doc, filename, relationship, description, subType, data); - } + /** + * Embeds an external file (generic - any type allowed) in the PDF. + * + * @param doc PDDocument to attach the file to. + * @param filename name of the file that will become attachment name in the PDF + * @param relationship how the file relates to the content, e.g. "Alternative" + * @param description Human-readable description of the file content + * @param subType type of the data e.g. could be "text/xml" - mime like + * @param data the binary data of the file/attachment + * @throws IOException if anything is wrong with filename + */ + @Override + public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description, + String subType, byte[] data) throws IOException { + fileAttached = true; - /** - * Embeds an external file (generic - any type allowed) in the PDF. - * - * @param doc PDDocument to attach the file to. - * @param filename name of the file that will become attachment name in the PDF - * @param relationship how the file relates to the content, e.g. "Alternative" - * @param description Human-readable description of the file content - * @param subType type of the data e.g. could be "text/xml" - mime like - * @param data the binary data of the file/attachment - * @throws IOException if anything is wrong with filename - */ - @Override - public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description, - String subType, byte[] data) throws IOException { - fileAttached = true; + PDComplexFileSpecification fs = new PDComplexFileSpecification(); + fs.setFile(filename); - PDComplexFileSpecification fs = new PDComplexFileSpecification(); - fs.setFile(filename); + COSDictionary dict = fs.getCOSObject(); + dict.setName("AFRelationship", relationship); + dict.setString("UF", filename); + dict.setString("Desc", description); - COSDictionary dict = fs.getCOSObject(); - dict.setName("AFRelationship", relationship); - dict.setString("UF", filename); - dict.setString("Desc", description); + ByteArrayInputStream fakeFile = new ByteArrayInputStream(data); + PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile); +// ef.addCompression(); + ef.setSubtype(subType); + ef.setSize(data.length); + ef.setCreationDate(new GregorianCalendar()); - ByteArrayInputStream fakeFile = new ByteArrayInputStream(data); - PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile); -// ef.addCompression(); - ef.setSubtype(subType); - ef.setSize(data.length); - ef.setCreationDate(new GregorianCalendar()); + ef.setModDate(Calendar.getInstance()); - ef.setModDate(Calendar.getInstance()); + fs.setEmbeddedFile(ef); - fs.setEmbeddedFile(ef); + // In addition make sure the embedded file is set under /UF + dict = fs.getCOSObject(); + COSDictionary efDict = (COSDictionary) dict.getDictionaryObject(COSName.EF); + COSBase lowerLevelFile = efDict.getItem(COSName.F); + efDict.setItem(COSName.UF, lowerLevelFile); - // In addition make sure the embedded file is set under /UF - dict = fs.getCOSObject(); - COSDictionary efDict = (COSDictionary) dict.getDictionaryObject(COSName.EF); - COSBase lowerLevelFile = efDict.getItem(COSName.F); - efDict.setItem(COSName.UF, lowerLevelFile); + // now add the entry to the embedded file tree and set in the document. + PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); + PDEmbeddedFilesNameTreeNode efTree = names.getEmbeddedFiles(); + if (efTree == null) { + efTree = new PDEmbeddedFilesNameTreeNode(); + } - // now add the entry to the embedded file tree and set in the document. - PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); - PDEmbeddedFilesNameTreeNode efTree = names.getEmbeddedFiles(); - if (efTree == null) { - efTree = new PDEmbeddedFilesNameTreeNode(); - } + Map namesMap = new HashMap<>(); - Map namesMap = new HashMap<>(); + Map oldNamesMap = efTree.getNames(); + if (oldNamesMap != null) { + for (String key : oldNamesMap.keySet()) { + namesMap.put(key, oldNamesMap.get(key)); + } + } + namesMap.put(filename, fs); + efTree.setNames(namesMap); - Map oldNamesMap = efTree.getNames(); - if (oldNamesMap != null) { - for (String key : oldNamesMap.keySet()) { - namesMap.put(key, oldNamesMap.get(key)); - } - } - namesMap.put(filename, fs); - efTree.setNames(namesMap); + names.setEmbeddedFiles(efTree); + doc.getDocumentCatalog().setNames(names); - names.setEmbeddedFiles(efTree); - doc.getDocumentCatalog().setNames(names); + // AF entry (Array) in catalog with the FileSpec + COSBase AFEntry = doc.getDocumentCatalog().getCOSObject().getItem("AF"); + if (AFEntry == null) { + COSArray cosArray = new COSArray(); + cosArray.add(fs); + doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); + } else if (AFEntry instanceof COSArray) { + COSArray cosArray = (COSArray) AFEntry; + cosArray.add(fs); + doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); + } else if ((AFEntry instanceof COSObject) && + ((COSObject) AFEntry).getObject() instanceof COSArray) { + COSArray cosArray = (COSArray) ((COSObject) AFEntry).getObject(); + cosArray.add(fs); + } else { + throw new IOException("Unexpected object type for PDFDocument/Catalog/COSDictionary/Item(AF)"); + } + } - // AF entry (Array) in catalog with the FileSpec - COSBase AFEntry = doc.getDocumentCatalog().getCOSObject().getItem("AF"); - if ((AFEntry == null)) { - COSArray cosArray = new COSArray(); - cosArray.add(fs); - doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); - } else if (AFEntry instanceof COSArray) { - COSArray cosArray = (COSArray) AFEntry; - cosArray.add(fs); - doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); - } else if ((AFEntry instanceof COSObject) && - ((COSObject) AFEntry).getObject() instanceof COSArray) { - COSArray cosArray = (COSArray) ((COSObject) AFEntry).getObject(); - cosArray.add(fs); - } else { - throw new IOException("Unexpected object type for PDFDocument/Catalog/COSDictionary/Item(AF)"); - } - } + /** + * Sets the ZUGFeRD XML data to be attached as a single byte array. This is + * useful for use-cases where the XML has already been produced by some external + * API or component. + * + * @param zugferdData XML data to be set as a byte array (XML file in raw form). + * @throws IOException (should not happen) + */ + @Override + public OXExporterFromA3 setXML(byte[] zugferdData) throws IOException { + CustomXMLProvider cus = new CustomXMLProvider(); + cus.setXML(zugferdData); + this.setXMLProvider(cus); + prepare(); + return this; + } - /** - * Sets the ZUGFeRD XML data to be attached as a single byte array. This is - * useful for use-cases where the XML has already been produced by some external - * API or component. - * - * @param zugferdData XML data to be set as a byte array (XML file in raw form). - * @throws IOException (should not happen) - */ - @Override - public OXExporterFromA3 setXML(byte[] zugferdData) throws IOException { - CustomXMLProvider cus = new CustomXMLProvider(); - cus.setXML(zugferdData); - this.setXMLProvider(cus); - prepare(); - return this; - } + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfSource source to read a PDF/A1 compliant document from + */ + @Override + public OXExporterFromA3 load(InputStream pdfSource) throws IOException { + return load(readAllBytes(pdfSource)); + } - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfSource source to read a PDF/A1 compliant document from - */ - @Override - public OXExporterFromA3 load(InputStream pdfSource) throws IOException { - return load(readAllBytes(pdfSource)); - } + @Override + public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { + return true; + } - @Override - public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { - return true; - } + private static byte[] readAllBytes(InputStream in) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + IOUtils.copy(in, buffer); + return buffer.toByteArray(); + } - private static byte[] readAllBytes(InputStream in) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - IOUtils.copy(in, buffer); - return buffer.toByteArray(); - } + /** + * All files are PDF/A-3, setConformance refers to the level conformance. + *

+ * PDF/A-3 has three coformance levels, called "A", "U" and "B". + *

+ * PDF/A-3-B where B means only visually preservable, U -standard for Mustang- + * means visually and unicode preservable and A means full compliance, i.e. + * visually, unicode and structurally preservable and tagged PDF, i.e. useful + * metainformation for blind people. + *

+ * Feel free to pass "A" as new level if you know what you are doing :-) + */ + @Override + public OXExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) { + conformanceLevel = newLevel; + return this; + } - /** - * All files are PDF/A-3, setConformance refers to the level conformance. - *

- * PDF/A-3 has three coformance levels, called "A", "U" and "B". - *

- * PDF/A-3-B where B means only visually preservable, U -standard for Mustang- - * means visually and unicode preservable and A means full compliance, i.e. - * visually, unicode and structurally preservable and tagged PDF, i.e. useful - * metainformation for blind people. - *

- * Feel free to pass "A" as new level if you know what you are doing :-) - */ - @Override - public OXExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) { - conformanceLevel = newLevel; - return this; - } + @Override + public OXExporterFromA3 setCreator(String creator) { + this.creator = creator; + return this; + } - @Override - public OXExporterFromA3 setCreator(String creator) { - this.creator = creator; - return this; - } - - @Override - public OXExporterFromA3 setCreatorTool(String creatorTool) { - this.creatorTool = creatorTool; - return this; - } + @Override + public OXExporterFromA3 setCreatorTool(String creatorTool) { + this.creatorTool = creatorTool; + return this; + } - @Override - public OXExporterFromA3 setProducer(String producer) { - this.producer = producer; - return this; - } + @Override + public OXExporterFromA3 setProducer(String producer) { + this.producer = producer; + return this; + } - /** - * Sets the property orderXDocumentType. - * - * @param orderXDocumentType new value. Expected: ORDER, ORDER_RESPONSE, or ORDER_CHANGE - * - * @return this exporter - */ - public OXExporterFromA3 setOrderXDocumentType(String orderXDocumentType) - { - this.orderXDocumentType = orderXDocumentType; + /** + * Sets the property orderXDocumentType. + * + * @param orderXDocumentType new value. Expected: ORDER, ORDER_RESPONSE, or ORDER_CHANGE + * + * @return this exporter + */ + public OXExporterFromA3 setOrderXDocumentType(String orderXDocumentType) + { + this.orderXDocumentType = orderXDocumentType; - return this; - } + return this; + } - @Override - protected OXExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) { - this.attachZUGFeRDHeaders = attachHeaders; - return this; - } + @Override + protected OXExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) { + this.attachZUGFeRDHeaders = attachHeaders; + return this; + } - /** - * This will add both the RDF-indication which embedded file is Zugferd and the - * neccessary PDF/A schema extension description to be able to add this - * information to RDF - * - * @param metadata the PDFbox XMPMetadata object - */ - @Override - protected void addXMP(XMPMetadata metadata) { + /** + * This will add both the RDF-indication which embedded file is Zugferd and the + * neccessary PDF/A schema extension description to be able to add this + * information to RDF + * + * @param metadata the PDFbox XMPMetadata object + */ + @Override + protected void addXMP(XMPMetadata metadata) { - if (attachZUGFeRDHeaders) { - XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, 1, true, xmlProvider.getProfile(), - "urn:factur-x:pdfa:CrossIndustryDocument:1p0#", "fx", - "order-x.xml"); - zf.setType(this.orderXDocumentType); + if (attachZUGFeRDHeaders) { + XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, 1, true, xmlProvider.getProfile(), + "urn:factur-x:pdfa:CrossIndustryDocument:1p0#", "fx", + "order-x.xml"); + zf.setType(this.orderXDocumentType); - metadata.addSchema(zf); - // also add the schema extensions... - XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(this, metadata, 1, attachZUGFeRDHeaders, EStandard.orderx); - pdfaex.setZUGFeRDVersion(1); - metadata.addSchema(pdfaex); - } + metadata.addSchema(zf); + // also add the schema extensions... + XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(this, metadata, 1, attachZUGFeRDHeaders, EStandard.orderx); + pdfaex.setZUGFeRDVersion(1); + metadata.addSchema(pdfaex); + } - } + } - /** - * Embeds the Zugferd XML structure in a file named ZUGFeRD-invoice.xml. - * - * @param trans a IZUGFeRDExportableTransaction that provides the data-model to - * populate the XML. This parameter may be null, if so the XML data - * should hav ebeen set via - * setZUGFeRDXMLData(byte[] zugferdData) - * @throws IOException if anything is wrong with already loaded PDF - */ - @Override - public IExporter setTransaction(IExportableTransaction trans) throws IOException { - this.trans = trans; - return prepare(); - } + /** + * Embeds the Zugferd XML structure in a file named ZUGFeRD-invoice.xml. + * + * @param trans a IZUGFeRDExportableTransaction that provides the data-model to + * populate the XML. This parameter may be null, if so the XML data + * should hav ebeen set via + * setZUGFeRDXMLData(byte[] zugferdData) + * @throws IOException if anything is wrong with already loaded PDF + */ + @Override + public IExporter setTransaction(IExportableTransaction trans) throws IOException { + this.trans = trans; + return prepare(); + } - @Override - public IExporter prepare() throws IOException { - prepareDocument(); - xmlProvider.generateXML(trans); - String filename = "order-x.xml"; - PDFAttachGenericFile(doc, filename, "Alternative", - "Order metadata conforming to the Order-X standard (https://www.ferd-net.de/standards/order-x/index.html)", - "text/xml", xmlProvider.getXML()); + @Override + public IExporter prepare() throws IOException { + prepareDocument(); + xmlProvider.generateXML(trans); + String filename = "order-x.xml"; + PDFAttachGenericFile(doc, filename, "Alternative", + "Order metadata conforming to the Order-X standard (https://www.ferd-net.de/standards/order-x/index.html)", + "text/xml", xmlProvider.getXML()); - for (FileAttachment attachment : fileAttachments) { - PDFAttachGenericFile(doc, attachment.getFilename(), attachment.getRelation(), attachment.getDescription(), attachment.getMimetype(), attachment.getData()); - } + for (FileAttachment attachment : fileAttachments) { + PDFAttachGenericFile(doc, attachment.getFilename(), attachment.getRelation(), attachment.getDescription(), attachment.getMimetype(), attachment.getData()); + } - return this; - } + return this; + } - /** - * Reads the XMPMetadata from the PDDocument, if it exists. - * Otherwise creates XMPMetadata. - */ - @Override - protected XMPMetadata getXmpMetadata() throws IOException { - PDMetadata meta = doc.getDocumentCatalog().getMetadata(); - if ((meta != null) && (meta.getLength() > 0)) { - try { - DomXmpParser xmpParser = new DomXmpParser(); - return xmpParser.parse(meta.toByteArray()); - } catch (XmpParsingException | IOException e) { - throw new IOException(e); - } - } - return XMPMetadata.createXMPMetadata(); - } + /** + * Reads the XMPMetadata from the PDDocument, if it exists. + * Otherwise creates XMPMetadata. + */ + @Override + protected XMPMetadata getXmpMetadata() throws IOException { + PDMetadata meta = doc.getDocumentCatalog().getMetadata(); + if ((meta != null) && (meta.getLength() > 0)) { + try { + DomXmpParser xmpParser = new DomXmpParser(); + return xmpParser.parse(meta.toByteArray()); + } catch (XmpParsingException | IOException e) { + throw new IOException(e); + } + } + return XMPMetadata.createXMPMetadata(); + } - @Override - protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - new XmpSerializer().serialize(xmpMetadata, buffer, true); // see https://github.com/ZUGFeRD/mustangproject/issues/44 - return buffer.toByteArray(); - } + @Override + protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + new XmpSerializer().serialize(xmpMetadata, buffer, true); // see https://github.com/ZUGFeRD/mustangproject/issues/44 + return buffer.toByteArray(); + } - /** - * Sets the producer if the overwrite flag is set or the producer is not already set. - * Sets the PDFVersion to 1.4 if the field is empty. - */ - @Override - protected void writeAdobePDFSchema(XMPMetadata xmp) { - AdobePDFSchema pdf = getAdobePDFSchema(xmp); - if (overwrite || isEmpty(pdf.getProducer())) - pdf.setProducer(producer); - } + /** + * Sets the producer if the overwrite flag is set or the producer is not already set. + * Sets the PDFVersion to 1.4 if the field is empty. + */ + @Override + protected void writeAdobePDFSchema(XMPMetadata xmp) { + AdobePDFSchema pdf = getAdobePDFSchema(xmp); + if (overwrite || isEmpty(pdf.getProducer())) + pdf.setProducer(producer); + } - /** - * Returns the AdobePDFSchema from the XMPMetadata if it exists. - * If the overwrite flag is set or no AdobePDFSchema exists in the XMPMetadata, it is created, added and returned. - */ - @Override - protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) { - AdobePDFSchema pdf = xmp.getAdobePDFSchema(); - if (pdf != null) - if (overwrite) - xmp.removeSchema(pdf); - else - return pdf; - return xmp.createAndAddAdobePDFSchema(); - } + /** + * Returns the AdobePDFSchema from the XMPMetadata if it exists. + * If the overwrite flag is set or no AdobePDFSchema exists in the XMPMetadata, it is created, added and returned. + */ + @Override + protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) { + AdobePDFSchema pdf = xmp.getAdobePDFSchema(); + if (pdf != null) + if (overwrite) + xmp.removeSchema(pdf); + else + return pdf; + return xmp.createAndAddAdobePDFSchema(); + } - @Override - protected void writePDFAIdentificationSchema(XMPMetadata xmp) { - PDFAIdentificationSchema pdfaid = getPDFAIdentificationSchema(xmp); - if (overwrite || isEmpty(pdfaid.getConformance())) { - try { - pdfaid.setConformance(conformanceLevel.getLetter()); - } catch (BadFieldValueException ex) { - // This should be impossible, because it would occur only if an illegal - // conformance level is supplied, - // however the enum enforces that the conformance level is valid. - throw new RuntimeException(ex); - } - } - pdfaid.setPart(3); - } + @Override + protected void writePDFAIdentificationSchema(XMPMetadata xmp) { + PDFAIdentificationSchema pdfaid = getPDFAIdentificationSchema(xmp); + if (overwrite || isEmpty(pdfaid.getConformance())) { + try { + pdfaid.setConformance(conformanceLevel.getLetter()); + } catch (BadFieldValueException ex) { + // This should be impossible, because it would occur only if an illegal + // conformance level is supplied, + // however the enum enforces that the conformance level is valid. + throw new RuntimeException(ex); + } + } + pdfaid.setPart(3); + } - @Override - protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { - PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema(); - if (pdfaid != null) - if (overwrite) - xmp.removeSchema(pdfaid); - else - return pdfaid; - return xmp.createAndAddPDFAIdentificationSchema(); - } + @Override + protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { + PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema(); + if (pdfaid != null) + if (overwrite) + xmp.removeSchema(pdfaid); + else + return pdfaid; + return xmp.createAndAddPDFAIdentificationSchema(); + } - @Override - protected void writeDublinCoreSchema(XMPMetadata xmp) { - DublinCoreSchema dc = getDublinCoreSchema(xmp); - if (dc.getFormat() == null) - dc.setFormat("application/pdf"); - if ((overwrite || dc.getCreators() == null || dc.getCreators().isEmpty()) && creator != null) - dc.addCreator(creator); - if ((overwrite || dc.getDates() == null || dc.getDates().isEmpty()) && creator != null) - dc.addDate(Calendar.getInstance()); + @Override + protected void writeDublinCoreSchema(XMPMetadata xmp) { + DublinCoreSchema dc = getDublinCoreSchema(xmp); + if (dc.getFormat() == null) + dc.setFormat("application/pdf"); + if ((overwrite || dc.getCreators() == null || dc.getCreators().isEmpty()) && creator != null) + dc.addCreator(creator); + if ((overwrite || dc.getDates() == null || dc.getDates().isEmpty()) && creator != null) + dc.addDate(Calendar.getInstance()); - ArrayProperty titleProperty = dc.getTitleProperty(); - if (titleProperty != null) { - if (overwrite && !isEmpty(title)) { - dc.removeProperty(titleProperty); - dc.setTitle(title); - } else if (titleProperty.getElementsAsString().stream().anyMatch("Untitled"::equalsIgnoreCase)) { - // remove unfitting ghostscript default - dc.removeProperty(titleProperty); - } - } else if (!isEmpty(title)) { - dc.setTitle(title); - } - } + ArrayProperty titleProperty = dc.getTitleProperty(); + if (titleProperty != null) { + if (overwrite && !isEmpty(title)) { + dc.removeProperty(titleProperty); + dc.setTitle(title); + } else if (titleProperty.getElementsAsString().stream().anyMatch("Untitled"::equalsIgnoreCase)) { + // remove unfitting ghostscript default + dc.removeProperty(titleProperty); + } + } else if (!isEmpty(title)) { + dc.setTitle(title); + } + } - @Override - protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) { - DublinCoreSchema dc = xmp.getDublinCoreSchema(); - if (dc != null) - if (overwrite) - xmp.removeSchema(dc); - else - return dc; - return xmp.createAndAddDublinCoreSchema(); - } + @Override + protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) { + DublinCoreSchema dc = xmp.getDublinCoreSchema(); + if (dc != null) + if (overwrite) + xmp.removeSchema(dc); + else + return dc; + return xmp.createAndAddDublinCoreSchema(); + } - @Override - protected void writeXMLBasicSchema(XMPMetadata xmp) { - XMPBasicSchema xsb = getXmpBasicSchema(xmp); - if (overwrite || isEmpty(xsb.getCreatorTool()) || "UnknownApplication".equals(xsb.getCreatorTool())) - xsb.setCreatorTool(creatorTool); - if (overwrite || xsb.getCreateDate() == null) - xsb.setCreateDate(Calendar.getInstance()); - } + @Override + protected void writeXMLBasicSchema(XMPMetadata xmp) { + XMPBasicSchema xsb = getXmpBasicSchema(xmp); + if (overwrite || isEmpty(xsb.getCreatorTool()) || "UnknownApplication".equals(xsb.getCreatorTool())) + xsb.setCreatorTool(creatorTool); + if (overwrite || xsb.getCreateDate() == null) + xsb.setCreateDate(Calendar.getInstance()); + } - @Override - protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) { - XMPBasicSchema xsb = xmp.getXMPBasicSchema(); - if (xsb != null) - if (overwrite) - xmp.removeSchema(xsb); - else - return xsb; - return xmp.createAndAddXMPBasicSchema(); - } + @Override + protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) { + XMPBasicSchema xsb = xmp.getXMPBasicSchema(); + if (xsb != null) + if (overwrite) + xmp.removeSchema(xsb); + else + return xsb; + return xmp.createAndAddXMPBasicSchema(); + } - @Override - protected void writeDocumentInformation() { - String fullProducer = producer + " (via mustangproject.org " + Version.VERSION + ")"; - PDDocumentInformation info = doc.getDocumentInformation(); - if (overwrite || info.getCreationDate() == null) - info.setCreationDate(Calendar.getInstance()); - if (overwrite || info.getModificationDate() == null) - info.setModificationDate(Calendar.getInstance()); - if (overwrite || (isEmpty(info.getAuthor()) && !isEmpty(author))) - info.setAuthor(author); - if (overwrite || (isEmpty(info.getProducer()) && !isEmpty(fullProducer))) - info.setProducer(fullProducer); - if (overwrite || (isEmpty(info.getCreator()) && !isEmpty(creator))) - info.setCreator(creator); - if (overwrite || (isEmpty(info.getTitle()) && !isEmpty(title))) - info.setTitle(title); - if (overwrite || (isEmpty(info.getSubject()) && !isEmpty(subject))) - info.setSubject(subject); - } + @Override + protected void writeDocumentInformation() { + String fullProducer = producer + " (via mustangproject.org " + Version.VERSION + ")"; + PDDocumentInformation info = doc.getDocumentInformation(); + if (overwrite || info.getCreationDate() == null) + info.setCreationDate(Calendar.getInstance()); + if (overwrite || info.getModificationDate() == null) + info.setModificationDate(Calendar.getInstance()); + if (overwrite || (isEmpty(info.getAuthor()) && !isEmpty(author))) + info.setAuthor(author); + if (overwrite || (isEmpty(info.getProducer()) && !isEmpty(fullProducer))) + info.setProducer(fullProducer); + if (overwrite || (isEmpty(info.getCreator()) && !isEmpty(creator))) + info.setCreator(creator); + if (overwrite || (isEmpty(info.getTitle()) && !isEmpty(title))) + info.setTitle(title); + if (overwrite || (isEmpty(info.getSubject()) && !isEmpty(subject))) + info.setSubject(subject); + } - /** - * Adds an OutputIntent and the sRGB color profile if no OutputIntent exist - */ - @Override - protected void addSRGBOutputIntend() throws IOException { - if (!doc.getDocumentCatalog().getOutputIntents().isEmpty()) { - return; - } + /** + * Adds an OutputIntent and the sRGB color profile if no OutputIntent exist + */ + @Override + protected void addSRGBOutputIntend() throws IOException { + if (!doc.getDocumentCatalog().getOutputIntents().isEmpty()) { + return; + } - try { - InputStream colorProfile = Thread.currentThread().getContextClassLoader().getResourceAsStream("sRGB.icc"); - if (colorProfile != null) { - PDOutputIntent intent = new PDOutputIntent(doc, colorProfile); - intent.setInfo("sRGB IEC61966-2.1"); - intent.setOutputCondition("sRGB IEC61966-2.1"); - intent.setOutputConditionIdentifier("sRGB IEC61966-2.1"); - intent.setRegistryName("http://www.color.org"); - doc.getDocumentCatalog().addOutputIntent(intent); - } - } catch (IOException e) { - throw e; - } - } + try { + InputStream colorProfile = Thread.currentThread().getContextClassLoader().getResourceAsStream("sRGB.icc"); + if (colorProfile != null) { + PDOutputIntent intent = new PDOutputIntent(doc, colorProfile); + intent.setInfo("sRGB IEC61966-2.1"); + intent.setOutputCondition("sRGB IEC61966-2.1"); + intent.setOutputConditionIdentifier("sRGB IEC61966-2.1"); + intent.setRegistryName("http://www.color.org"); + doc.getDocumentCatalog().addOutputIntent(intent); + } + } catch (IOException e) { + throw e; + } + } - /** - * Adds a MarkInfo element to the PDF if it doesn't already exist and sets it as marked. - */ - @Override - protected void setMarked() { - PDDocumentCatalog catalog = doc.getDocumentCatalog(); - if (catalog.getMarkInfo() == null) { - catalog.setMarkInfo(new PDMarkInfo(doc.getPages().getCOSObject())); - } - catalog.getMarkInfo().setMarked(true); - } + /** + * Adds a MarkInfo element to the PDF if it doesn't already exist and sets it as marked. + */ + @Override + protected void setMarked() { + PDDocumentCatalog catalog = doc.getDocumentCatalog(); + if (catalog.getMarkInfo() == null) { + catalog.setMarkInfo(new PDMarkInfo(doc.getPages().getCOSObject())); + } + catalog.getMarkInfo().setMarked(true); + } - /** - * Adds a StructureTreeRoot element to the PDF if it doesn't already exist. - */ - @Override - protected void addStructureTreeRoot() { - if (doc.getDocumentCatalog().getStructureTreeRoot() == null) { - doc.getDocumentCatalog().setStructureTreeRoot(new PDStructureTreeRoot()); - } - } + /** + * Adds a StructureTreeRoot element to the PDF if it doesn't already exist. + */ + @Override + protected void addStructureTreeRoot() { + if (doc.getDocumentCatalog().getStructureTreeRoot() == null) { + doc.getDocumentCatalog().setStructureTreeRoot(new PDStructureTreeRoot()); + } + } - /** - * @return if pdf file will be automatically closed after adding ZF - */ - @Override - public boolean isAutoCloseDisabled() { - return disableAutoClose; - } + /** + * @return if pdf file will be automatically closed after adding ZF + */ + @Override + public boolean isAutoCloseDisabled() { + return disableAutoClose; + } - /** - * @param disableAutoClose prevent PDF file from being closed after adding ZF - */ - @Override - public OXExporterFromA3 disableAutoClose(boolean disableAutoClose) { - this.disableAutoClose = disableAutoClose; - return this; - } + /** + * @param disableAutoClose prevent PDF file from being closed after adding ZF + */ + @Override + public OXExporterFromA3 disableAutoClose(boolean disableAutoClose) { + this.disableAutoClose = disableAutoClose; + return this; + } - @Override - protected void setXMLProvider(IXMLProvider p) { - this.xmlProvider = p; - if (profile != null) { - xmlProvider.setProfile(profile); - } - } + @Override + protected void setXMLProvider(IXMLProvider p) { + this.xmlProvider = p; + if (profile != null) { + xmlProvider.setProfile(profile); + } + } - @Override - public OXExporterFromA3 setZUGFeRDVersion(int version) { - OXPullProvider z2p = new OXPullProvider(); - setXMLProvider(z2p); - return this; - } + @Override + public OXExporterFromA3 setZUGFeRDVersion(int version) { + OXPullProvider z2p = new OXPullProvider(); + setXMLProvider(z2p); + return this; + } - /** - * Utility method inspired by apache commons-lang3 StringUtils. - * - * @param string the string to test - * @return true if the string is null or empty - */ - private boolean isEmpty(String string) { - return string == null || string.isEmpty(); - } + /** + * Utility method inspired by apache commons-lang3 StringUtils. + * + * @param string the string to test + * @return true if the string is null or empty + */ + private boolean isEmpty(String string) { + return string == null || string.isEmpty(); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/OXPullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/OXPullProvider.java index 1d2a30e..0b19329 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/OXPullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/OXPullProvider.java @@ -20,8 +20,9 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE; -import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE; +import org.mustangproject.EStandard; +import org.mustangproject.FileAttachment; +import org.mustangproject.XMLTools; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; @@ -30,499 +31,494 @@ import java.util.Date; import java.util.Map; -import org.mustangproject.EStandard; -import org.mustangproject.FileAttachment; -import org.mustangproject.XMLTools; +import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE; +import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE; public class OXPullProvider extends ZUGFeRD2PullProvider { - protected IExportableTransaction trans; - protected TransactionCalculator calc; - private String paymentTermsDescription; - protected Profile profile = Profiles.getByName(EStandard.orderx,"basic", 1); + protected IExportableTransaction trans; + protected TransactionCalculator calc; + private String paymentTermsDescription; + protected Profile profile = Profiles.getByName(EStandard.orderx, "basic", 1); - @Override - public void generateXML(IExportableTransaction trans) { - this.trans = trans; - this.calc = new TransactionCalculator(trans); + @Override + public void generateXML(IExportableTransaction trans) { + this.trans = trans; + this.calc = new TransactionCalculator(trans); - boolean hasDueDate = false; - final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); + boolean hasDueDate = false; + final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - final String exemptionReason = ""; + final String exemptionReason = ""; - if (trans.getPaymentTermDescription() != null) { - paymentTermsDescription = XMLTools.encodeXML(trans.getPaymentTermDescription()); - } + if (trans.getPaymentTermDescription() != null) { + paymentTermsDescription = XMLTools.encodeXML(trans.getPaymentTermDescription()); + } - if ((paymentTermsDescription == null) && (trans.getDocumentCode() != CORRECTEDINVOICE)/* && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)*/) { - paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); + if ((paymentTermsDescription == null) && (trans.getDocumentCode() != CORRECTEDINVOICE)/* && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)*/) { + paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); - } + } - final String typecode = "220"; - /*if (trans.getDocumentCode() != null) { - typecode = trans.getDocumentCode(); - }*/ - - String xml = "" - - + "" - // + " - // xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100 - // ../Schema/ZUGFeRD1p0.xsd\"" - + "" - // + " - // "+testBooleanStr+"\n" - // - + "" - + "A1" - + "" - + "" - + "" + getProfile().getID() + "" - + "" - + "" - + "" - + "" + XMLTools.encodeXML(trans.getNumber()) + "" - // + " RECHNUNG" - // + "380" - + "" + typecode + "" - + "" - + DATE.udtFormat(trans.getIssueDate()) + "" // date - + buildNotes(trans) - - + "" - + ""; - int lineID = 0; - for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) { - lineID++; - if (currentItem.getProduct().getTaxExemptionReason() != null) { - // exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; - } + final String typecode = "220"; + /*if (trans.getDocumentCode() != null) { + typecode = trans.getDocumentCode(); + }*/ - final LineCalculator lc = new LineCalculator(currentItem); - xml += "" + - "" - + "" + lineID + "" - + buildItemNotes(currentItem) - + "" + String xml = "" - + ""; - // + " 4012345001235" - if (currentItem.getProduct().getSellerAssignedID() != null) { - xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; - } - if (currentItem.getProduct().getBuyerAssignedID() != null) { - xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; - } - String allowanceChargeStr = ""; - if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { - for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { - allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem); - } - } - if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { - for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { - allowanceChargeStr += getAllowanceChargeStr(charge, currentItem); + + "" + // + " + // xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100 + // ../Schema/ZUGFeRD1p0.xsd\"" + + "" + // + " + // "+testBooleanStr+"\n" + // + + "" + + "A1" + + "" + + "" + + "" + getProfile().getID() + "" + + "" + + "" + + "" + + "" + XMLTools.encodeXML(trans.getNumber()) + "" + // + " RECHNUNG" + // + "380" + + "" + typecode + "" + + "" + + DATE.udtFormat(trans.getIssueDate()) + "" // date + + buildNotes(trans) - } - } + + "" + + ""; + int lineID = 0; + for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) { + lineID++; + if (currentItem.getProduct().getTaxExemptionReason() != null) { + // exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; + } + + final LineCalculator lc = new LineCalculator(currentItem); + xml += "" + + "" + + "" + lineID + "" + + buildItemNotes(currentItem) + + "" + + + ""; + // + " 4012345001235" + if (currentItem.getProduct().getSellerAssignedID() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; + } + if (currentItem.getProduct().getBuyerAssignedID() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; + } + String allowanceChargeStr = ""; + if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { + for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { + allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem); + } + } + if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { + for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { + allowanceChargeStr += getAllowanceChargeStr(charge, currentItem); + + } + } - xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "" - + "" + XMLTools.encodeXML(currentItem.getProduct().getDescription()) - + "" - + "" + xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "" + + "" + XMLTools.encodeXML(currentItem.getProduct().getDescription()) + + "" + + "" - + ""; - /* if (currentItem.getReferencedDocuments() != null) { - for (IReferencedDocument currentReferencedDocument : currentItem.getReferencedDocuments()) { - xml += "\n" + - "" + XMLTools.encodeXML(currentReferencedDocument.getIssuerAssignedID()) + "\n" + - "" + XMLTools.encodeXML(currentReferencedDocument.getTypeCode()) + "\n" + - "" + XMLTools.encodeXML(currentReferencedDocument.getReferenceTypeCode()) + "\n" + - "\n"; + + ""; + /* if (currentItem.getReferencedDocuments() != null) { + for (IReferencedDocument currentReferencedDocument : currentItem.getReferencedDocuments()) { + xml += "\n" + + "" + XMLTools.encodeXML(currentReferencedDocument.getIssuerAssignedID()) + "\n" + + "" + XMLTools.encodeXML(currentReferencedDocument.getTypeCode()) + "\n" + + "" + XMLTools.encodeXML(currentReferencedDocument.getReferenceTypeCode()) + "\n" + + "\n"; + } + }*/ + if (currentItem.getBuyerOrderReferencedDocumentLineID() != null) { + xml += " \n" + + "" + XMLTools.encodeXML(currentItem.getBuyerOrderReferencedDocumentLineID()) + "" + + ""; + + } + xml += "" + + "" + priceFormat(lc.getPriceGross()) + + "" // currencyID=\"EUR\" + + "" + quantityFormat(currentItem.getBasisQuantity()) + "" + + allowanceChargeStr + // + " \n" + // + " false\n" + // + " 0.6667\n" + // + " Rabatt\n" + // + " \n" + + "" + + "" + + "" + priceFormat(lc.getPrice()) + + "" // currencyID=\"EUR\" + + "" + quantityFormat(currentItem.getBasisQuantity()) + "" + + "" + + "" + + + "" + + "" + + quantityFormat(currentItem.getQuantity()) + "" + + "" + + "" + + "" + + "VAT" + + exemptionReason + + "" + currentItem.getProduct().getTaxCategoryCode() + "" + + + "" + + vatFormat(currentItem.getProduct().getVATPercent()) + "" + + ""; + if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) { + xml += ""; + if (currentItem.getDetailedDeliveryPeriodFrom() != null) { + xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodFrom()) + ""; + } + if (currentItem.getDetailedDeliveryPeriodTo() != null) { + xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodTo()) + ""; + } + xml += ""; + + } + + xml += "" + + "" + currencyFormat(lc.getItemTotalNetAmount()) + + "" // currencyID=\"EUR\" + + ""; + /* if (currentItem.getAdditionalReferencedDocumentID() != null) { + xml += "" + currentItem.getAdditionalReferencedDocumentID() + "130"; + }*/ + xml += "" + + ""; + + } + + xml += ""; + if (trans.getReferenceNumber() != null) { + xml += "" + XMLTools.encodeXML(trans.getReferenceNumber()) + ""; + + } + xml += "" + + getTradePartyAsXML(trans.getSender(), true, false) + + "" + + ""; + // + " GE2020211" + // + " 4000001987658" + + xml += getTradePartyAsXML(trans.getRecipient(), false, false); + xml += ""; + + if (trans.getSellerOrderReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" + + ""; + } + if (trans.getBuyerOrderReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" + + ""; + } + if (trans.getContractReferencedDocument() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "" + + ""; + } + + // Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung) + if (trans.getAdditionalReferencedDocuments() != null) { + for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) { + final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData())); + xml += "" + + "" + f.getFilename() + "" + + "916" + + "" + f.getDescription() + "" + + "" + documentContent + "" + + ""; + } + } + + if (trans.getSpecifiedProcuringProjectID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + ""; + if (trans.getSpecifiedProcuringProjectName() != null) { + xml += "" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + ""; + } + xml += ""; + } + xml += "" + + ""; + IZUGFeRDExportableTradeParty deliveryAddress = this.trans.getDeliveryAddress(); + if (deliveryAddress == null) { + deliveryAddress = this.trans.getRecipient(); + } + xml += "" + + getTradePartyAsXML(deliveryAddress, false, true) + + ""; + /* + xml += "" + + ""; + + if (trans.getDeliveryDate() != null) { + xml += DATE.udtFormat(trans.getDeliveryDate()); + } else { + throw new IllegalStateException("No delivery date provided"); + } + xml += "\n"; + xml += "\n" + + */ + /* + * + "\n" + + * "20130603\n" + + * "2013-51112\n" + + * "\n" + */ + xml += "\n" + // + "" + XMLTools.encodeXML(trans.getNumber()) + "" + + "" + trans.getCurrency() + ""; + + if (trans.getTradeSettlementPayment() != null) { + for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { + if (payment != null) { + hasDueDate = true; + // xml += payment.getSettlementXML(); + } + } + } + if (trans.getTradeSettlement() != null) { + for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { + if (payment != null) { + if (payment instanceof IZUGFeRDTradeSettlementPayment) { + hasDueDate = true; + } + // xml += payment.getSettlementXML(); + } + } + } + if (trans.getDocumentCode() != null) { + if (trans.getDocumentCode().equals(CORRECTEDINVOICE)/*||(trans.getDocumentCode().equals (DocumentCodeTypeConstants.CREDITNOTE))*/) { + hasDueDate = false; + } + } + + final Map VATPercentAmountMap = calc.getVATPercentAmountMap(); + for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); + if (amount != null) { + /*final String amountCategoryCode = amount.getCategoryCode(); + final boolean displayExemptionReason = CATEGORY_CODES_WITH_EXEMPTION_REASON.contains(amountCategoryCode); + xml += "\n" + + "" + currencyFormat(amount.getCalculated()) + + "\n" //currencyID=\"EUR\" + + "VAT\n" + + (displayExemptionReason ? exemptionReason : "") + + "" + currencyFormat(amount.getBasis()) + "\n" // currencyID=\"EUR\" + + "" + amountCategoryCode + "\n" + + "" + + vatFormat(currentTaxPercent) + "\n" + "\n"; + + */ + } + } + if ((trans.getDetailedDeliveryPeriodFrom() != null) || (trans.getDetailedDeliveryPeriodTo() != null)) { + xml += ""; + if (trans.getDetailedDeliveryPeriodFrom() != null) { + xml += "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodFrom()) + ""; + } + if (trans.getDetailedDeliveryPeriodTo() != null) { + xml += "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodTo()) + ""; + } + xml += ""; - } + } - }*/ - if (currentItem.getBuyerOrderReferencedDocumentLineID() != null) { - xml += " \n" - + "" + XMLTools.encodeXML(currentItem.getBuyerOrderReferencedDocumentLineID()) + "" - + ""; + if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) { - } - xml += "" - + "" + priceFormat(lc.getPriceGross()) - + "" //currencyID=\"EUR\" - + "" + quantityFormat(currentItem.getBasisQuantity()) + "" - + allowanceChargeStr - // + " \n" - // + " false\n" - // + " 0.6667\n" - // + " Rabatt\n" - // + " \n" - + "" - + "" - + "" + priceFormat(lc.getPrice()) - + "" // currencyID=\"EUR\" - + "" + quantityFormat(currentItem.getBasisQuantity()) + "" - + "" - + "" - - + "" - + "" - + quantityFormat(currentItem.getQuantity()) + "" - + "" - + "" - + "" - + "VAT" - + exemptionReason - + "" + currentItem.getProduct().getTaxCategoryCode() + "" - - + "" - + vatFormat(currentItem.getProduct().getVATPercent()) + "" - + ""; - if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) { - xml += ""; - if (currentItem.getDetailedDeliveryPeriodFrom() != null) { - xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodFrom()) + ""; - } - if (currentItem.getDetailedDeliveryPeriodTo() != null) { - xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodTo()) + ""; - } - xml += ""; - - } - - xml += "" - + "" + currencyFormat(lc.getItemTotalNetAmount()) - + "" // currencyID=\"EUR\" - + ""; - /* if (currentItem.getAdditionalReferencedDocumentID() != null) { - xml += "" + currentItem.getAdditionalReferencedDocumentID() + "130"; - - }*/ - xml += "" - + ""; - - } - - xml += ""; - if (trans.getReferenceNumber() != null) { - xml += "" + XMLTools.encodeXML(trans.getReferenceNumber()) + ""; - - } - xml += "" - + getTradePartyAsXML(trans.getSender(), true, false) - + "" - + ""; - // + " GE2020211" - // + " 4000001987658" - - xml += getTradePartyAsXML(trans.getRecipient(), false, false); - xml += ""; - - if (trans.getSellerOrderReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" - + ""; - } - if (trans.getBuyerOrderReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" - + ""; - } - if (trans.getContractReferencedDocument() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "" - + ""; - } - - // Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung) - if (trans.getAdditionalReferencedDocuments() != null) { - for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) { - final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData())); - xml += "" - + "" + f.getFilename() + "" - + "916" - + "" + f.getDescription() + "" - + "" + documentContent + "" - + ""; - } - } - - if (trans.getSpecifiedProcuringProjectID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + ""; - if (trans.getSpecifiedProcuringProjectName() != null) { - xml += "" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + ""; - } - xml += ""; - } - xml += "" - + ""; - IZUGFeRDExportableTradeParty deliveryAddress=this.trans.getDeliveryAddress(); - if (deliveryAddress == null) { - deliveryAddress = this.trans.getRecipient(); - } - xml += "" + - getTradePartyAsXML(deliveryAddress, false, true) + - ""; -/* - xml += "" - + ""; - - if (trans.getDeliveryDate() != null) { - xml += DATE.udtFormat(trans.getDeliveryDate()); - } else { - throw new IllegalStateException("No delivery date provided"); - } - xml += "\n"; - xml += "\n" - - */ - /* - * + "\n" + - * "20130603\n" + - * "2013-51112\n" + - * "\n" - */ - xml+= "\n" - // + "" + XMLTools.encodeXML(trans.getNumber()) + "" - + "" + trans.getCurrency() + ""; - - if (trans.getTradeSettlementPayment() != null) { - for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { - if (payment != null) { - hasDueDate = true; - // xml += payment.getSettlementXML(); - } - } - } - if (trans.getTradeSettlement() != null) { - for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { - if (payment != null) { - if (payment instanceof IZUGFeRDTradeSettlementPayment) { - hasDueDate = true; - } - // xml += payment.getSettlementXML(); - } - } - } - if (trans.getDocumentCode() != null) { - if ((trans.getDocumentCode().equals(CORRECTEDINVOICE))/*||(trans.getDocumentCode().equals (DocumentCodeTypeConstants.CREDITNOTE))*/) { - hasDueDate = false; - } - } - - final Map VATPercentAmountMap = calc.getVATPercentAmountMap(); - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); - if (amount != null) { - /*final String amountCategoryCode = amount.getCategoryCode(); - final boolean displayExemptionReason = CATEGORY_CODES_WITH_EXEMPTION_REASON.contains(amountCategoryCode); - xml += "\n" - + "" + currencyFormat(amount.getCalculated()) - + "\n" //currencyID=\"EUR\" - + "VAT\n" - + (displayExemptionReason ? exemptionReason : "") - + "" + currencyFormat(amount.getBasis()) + "\n" // currencyID=\"EUR\" - + "" + amountCategoryCode + "\n" - + "" - + vatFormat(currentTaxPercent) + "\n" + "\n"; - - */ - } - } - if ((trans.getDetailedDeliveryPeriodFrom() != null) || (trans.getDetailedDeliveryPeriodTo() != null)) { - xml += ""; - if (trans.getDetailedDeliveryPeriodFrom() != null) { - xml += "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodFrom()) + ""; - } - if (trans.getDetailedDeliveryPeriodTo() != null) { - xml += "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodTo()) + ""; - } - xml += ""; + for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + if (calc.getChargesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { - } + xml += " " + + "" + + "true" + + "" + + "" + currencyFormat(calc.getChargesForPercent(currentTaxPercent)) + "" + + "" + XMLTools.encodeXML(calc.getChargeReasonForPercent(currentTaxPercent)) + "" + + "" + + "VAT" + + "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + + "" + vatFormat(currentTaxPercent) + "" + + "" + + ""; - if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) { + } + } - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - if (calc.getChargesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { + } + + if ((trans.getZFAllowances() != null) && (trans.getZFAllowances().length > 0)) { + for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + if (calc.getAllowancesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { + xml += "" + + "" + + "false" + + "" + + "" + currencyFormat(calc.getAllowancesForPercent(currentTaxPercent)) + "" + + "" + XMLTools.encodeXML(calc.getAllowanceReasonForPercent(currentTaxPercent)) + "" + + "" + + "VAT" + + "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + + "" + vatFormat(currentTaxPercent) + "" + + "" + + " \n"; + } + } + } - xml += " " + - "" + - "true" + - "" + - "" + currencyFormat(calc.getChargesForPercent(currentTaxPercent)) + "" + - "" + XMLTools.encodeXML(calc.getChargeReasonForPercent(currentTaxPercent)) + "" + - "" + - "VAT" + - "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + - "" + vatFormat(currentTaxPercent) + "" + - "" + - ""; + if ((trans.getPaymentTerms() == null) && ((paymentTermsDescription != null) || (trans.getTradeSettlement() != null) || hasDueDate)) { + xml += ""; - } - } + if (paymentTermsDescription != null) { + xml += "" + paymentTermsDescription + ""; + } - } + if (trans.getTradeSettlement() != null) { + for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { + if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { + // not in order-x xml += payment.getPaymentXML(); + } + } + } - if ((trans.getZFAllowances() != null) && (trans.getZFAllowances().length > 0)) { - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - if (calc.getAllowancesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { - xml += "" + - "" + - "false" + - "" + - "" + currencyFormat(calc.getAllowancesForPercent(currentTaxPercent)) + "" + - "" + XMLTools.encodeXML(calc.getAllowanceReasonForPercent(currentTaxPercent)) + "" + - "" + - "VAT" + - "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + - "" + vatFormat(currentTaxPercent) + "" + - "" + - " \n"; - } - } - } + xml += ""; + } else { + xml += buildPaymentTermsXml(); + } - if ((trans.getPaymentTerms() == null) && ((paymentTermsDescription != null) || (trans.getTradeSettlement() != null) || (hasDueDate))) { - xml += ""; + final String allowanceTotalLine = "" + currencyFormat(calc.getAllowancesForPercent(null)) + ""; - if (paymentTermsDescription != null) { - xml += "" + paymentTermsDescription + ""; - } + final String chargesTotalLine = "" + currencyFormat(calc.getChargesForPercent(null)) + ""; - if (trans.getTradeSettlement() != null) { - for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { - if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { - //not in order-x xml += payment.getPaymentXML(); - } - } - } + xml += "" + + "" + currencyFormat(calc.getTotal()) + "" + + chargesTotalLine + + allowanceTotalLine + + "" + currencyFormat(calc.getTaxBasis()) + "" + // // + // currencyID=\"EUR\" + + "" + + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "" + + "" + currencyFormat(calc.getGrandTotal()) + "" + // // + // currencyID=\"EUR\" + // + "" + currencyFormat(calc.getTotalPrepaid()) + "" + // + "" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "" + + ""; + if (trans.getInvoiceReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + ""; + if (trans.getInvoiceReferencedIssueDate() != null) { + xml += "" + + DATE.qdtFormat(trans.getInvoiceReferencedIssueDate()) + + ""; + } + xml += ""; + } - xml += ""; - } else { - xml += buildPaymentTermsXml(); - } + xml += ""; + // + " " + // + " " + // + " " + // + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. + // 2013-51112 in Rechnung zu stellen:\n" + // + " \n" + // + " \n" + // + " \n"; + + xml += "" + + ""; + + final byte[] zugferdRaw; + zugferdRaw = xml.getBytes(StandardCharsets.UTF_8); + + zugferdData = XMLTools.removeBOM(zugferdRaw); + } - final String allowanceTotalLine = "" + currencyFormat(calc.getAllowancesForPercent(null)) + ""; + @Override + public void setProfile(Profile p) { + profile = p; + } - final String chargesTotalLine = "" + currencyFormat(calc.getChargesForPercent(null)) + ""; + @Override + public Profile getProfile() { + return profile; + } - xml += "" - + "" + currencyFormat(calc.getTotal()) + "" - + chargesTotalLine - + allowanceTotalLine - + "" + currencyFormat(calc.getTaxBasis()) + "" - // // - // currencyID=\"EUR\" - + "" - + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "" - + "" + currencyFormat(calc.getGrandTotal()) + "" - // // - // currencyID=\"EUR\" - //+ "" + currencyFormat(calc.getTotalPrepaid()) + "" - //+ "" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "" - + ""; - if (trans.getInvoiceReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + ""; - if (trans.getInvoiceReferencedIssueDate() != null) { - xml += "" - + DATE.qdtFormat(trans.getInvoiceReferencedIssueDate()) - + ""; - } - xml += ""; - } + private String buildPaymentTermsXml() { - xml += ""; - // + " " - // + " " - // + " " - // + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. - // 2013-51112 in Rechnung zu stellen:\n" - // + " \n" - // + " \n" - // + " \n"; + final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms(); + if (paymentTerms == null) { + return ""; + } + String paymentTermsXml = ""; - xml += "" - + ""; + final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms(); + paymentTermsXml += "" + paymentTerms.getDescription() + ""; + if (discountTerms != null) { + paymentTermsXml += ""; + final String currency = trans.getCurrency(); + final String basisAmount = currencyFormat(calc.getGrandTotal()); + paymentTermsXml += "" + basisAmount + ""; + paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString() + + ""; - final byte[] zugferdRaw; - zugferdRaw = xml.getBytes(StandardCharsets.UTF_8); + if (discountTerms.getBaseDate() != null) { + final Date baseDate = discountTerms.getBaseDate(); + paymentTermsXml += ""; + paymentTermsXml += DATE.udtFormat(baseDate); + paymentTermsXml += ""; - zugferdData = XMLTools.removeBOM(zugferdRaw); - } + paymentTermsXml += "" + + discountTerms.getBasePeriodMeasure() + ""; + } + paymentTermsXml += ""; + } - @Override - public void setProfile(Profile p) { - profile = p; - } - - @Override - public Profile getProfile() { - return profile; - } - - private String buildPaymentTermsXml() { - - final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms(); - if (paymentTerms == null) { - return ""; - } - String paymentTermsXml = ""; - - final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms(); - paymentTermsXml += "" + paymentTerms.getDescription() + ""; - if (discountTerms != null) { - paymentTermsXml += ""; - final String currency = trans.getCurrency(); - final String basisAmount = currencyFormat(calc.getGrandTotal()); - paymentTermsXml += "" + basisAmount + ""; - paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString() - + ""; - - if (discountTerms.getBaseDate() != null) { - final Date baseDate = discountTerms.getBaseDate(); - paymentTermsXml += ""; - paymentTermsXml += DATE.udtFormat(baseDate); - paymentTermsXml += ""; - - paymentTermsXml += "" - + discountTerms.getBasePeriodMeasure() + ""; - } - - paymentTermsXml += ""; - } - - paymentTermsXml += ""; - return paymentTermsXml; - } + paymentTermsXml += ""; + return paymentTermsXml; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/PDFAConformanceLevel.java b/library/src/main/java/org/mustangproject/ZUGFeRD/PDFAConformanceLevel.java index 47cfaeb..65fc859 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/PDFAConformanceLevel.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/PDFAConformanceLevel.java @@ -19,24 +19,24 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; public enum PDFAConformanceLevel { - ACCESSIBLE("A"), BASIC("B"), UNICODE("U"); + ACCESSIBLE("A"), BASIC("B"), UNICODE("U"); - private final String letter; + private final String letter; - PDFAConformanceLevel(String letter) { - this.letter = letter; - } + PDFAConformanceLevel(String letter) { + this.letter = letter; + } - public String getLetter() { - return letter; - } + public String getLetter() { + return letter; + } - public static PDFAConformanceLevel findByLetter(String letter) { - for (PDFAConformanceLevel candidate : values()) { - if (candidate.letter.equals(letter)) { - return candidate; - } - } - throw new IllegalArgumentException("PDF conformance level <" + letter + "> is unknown."); - } + public static PDFAConformanceLevel findByLetter(String letter) { + for (PDFAConformanceLevel candidate : values()) { + if (candidate.letter.equals(letter)) { + return candidate; + } + } + throw new IllegalArgumentException("PDF conformance level <" + letter + "> is unknown."); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/PDFBoxUpdateMitigation.java b/library/src/main/java/org/mustangproject/ZUGFeRD/PDFBoxUpdateMitigation.java index 652051b..c623d05 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/PDFBoxUpdateMitigation.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/PDFBoxUpdateMitigation.java @@ -1,99 +1,92 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - +import jakarta.activation.DataSource; import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.preflight.parser.PreflightParser; -import jakarta.activation.DataSource; +import java.io.*; // Copied from PDFBox preflight 2.0.x final class ByteArrayDataSource implements DataSource { - private ByteArrayOutputStream data; - private String type = null; - private String name = null; + private ByteArrayOutputStream data; + private String type = null; + private String name = null; - public ByteArrayDataSource (InputStream is) throws IOException - { - data = new ByteArrayOutputStream (); - IOUtils.copy (is, data); - IOUtils.closeQuietly (is); - } + public ByteArrayDataSource(InputStream is) throws IOException + { + data = new ByteArrayOutputStream(); + IOUtils.copy(is, data); + IOUtils.closeQuietly(is); + } - public String getContentType () - { - return this.type; - } + public String getContentType() + { + return this.type; + } - /** - * @param type + /** + * @param type * the type to set - */ - public void setType (String type) - { - this.type = type; - } + */ + public void setType(String type) + { + this.type = type; + } - /** - * @param name + /** + * @param name * the name to set - */ - public void setName (String name) - { - this.name = name; - } + */ + public void setName(String name) + { + this.name = name; + } - public InputStream getInputStream () throws IOException - { - return new ByteArrayInputStream (data.toByteArray ()); - } + public InputStream getInputStream() throws IOException + { + return new ByteArrayInputStream(data.toByteArray()); + } - public String getName () - { - return this.name; - } + public String getName() + { + return this.name; + } - public OutputStream getOutputStream () throws IOException - { - this.data = new ByteArrayOutputStream (); - return data; - } + public OutputStream getOutputStream() throws IOException + { + this.data = new ByteArrayOutputStream(); + return data; + } } // Try to create an API similar to the 2.x one final class PreflightParserHelper { - private static File createTmpFile (InputStream input) throws IOException - { - FileOutputStream fos = null; - try + private static File createTmpFile(InputStream input) throws IOException { - File tmpFile = File.createTempFile ("mustang-pdf", ".pdf"); - fos = new FileOutputStream (tmpFile); - IOUtils.copy (input, fos); - return tmpFile; + FileOutputStream fos = null; + try + { + File tmpFile = File.createTempFile("mustang-pdf", ".pdf"); + fos = new FileOutputStream(tmpFile); + IOUtils.copy(input, fos); + return tmpFile; + } + finally + { + IOUtils.closeQuietly(input); + IOUtils.closeQuietly(fos); + } } - finally - { - IOUtils.closeQuietly (input); - IOUtils.closeQuietly (fos); - } - } - public static PreflightParser createPreflightParser (DataSource dataSource) throws IOException - { - return new PreflightParser (createTmpFile (dataSource.getInputStream ())); - } + public static PreflightParser createPreflightParser(DataSource dataSource) throws IOException + { + return new PreflightParser(createTmpFile(dataSource.getInputStream())); + } } final class PDFBoxUpdateMitigation { - // Dummy for the name only + // Dummy for the name only } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/PostalTradeAddress.java b/library/src/main/java/org/mustangproject/ZUGFeRD/PostalTradeAddress.java index e40cd07..f0f9c02 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/PostalTradeAddress.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/PostalTradeAddress.java @@ -2,74 +2,74 @@ org.openrewrite.config.CompositeRecipe public class PostalTradeAddress implements IZUGFeRDExportablePostalTradeAddress { - private String postCodeCode; - private String lineOne; - private String lineTwo; - private String lineThree; - private String cityName; - private String countryID; - private String CountrySubDivisionName; + private String postCodeCode; + private String lineOne; + private String lineTwo; + private String lineThree; + private String cityName; + private String countryID; + private String CountrySubDivisionName; - public void setPostCodeCode(String postCodeCode) { - this.postCodeCode = postCodeCode; - } + public void setPostCodeCode(String postCodeCode) { + this.postCodeCode = postCodeCode; + } - public void setLineOne(String lineOne) { - this.lineOne = lineOne; - } + public void setLineOne(String lineOne) { + this.lineOne = lineOne; + } - public void setLineTwo(String lineTwo) { - this.lineTwo = lineTwo; - } + public void setLineTwo(String lineTwo) { + this.lineTwo = lineTwo; + } - public void setLineThree(String lineThree) { - this.lineThree = lineThree; - } + public void setLineThree(String lineThree) { + this.lineThree = lineThree; + } - public void setCityName(String cityName) { - this.cityName = cityName; - } + public void setCityName(String cityName) { + this.cityName = cityName; + } - public void setCountryID(String countryID) { - this.countryID = countryID; - } + public void setCountryID(String countryID) { + this.countryID = countryID; + } - public void setCountrySubDivisionName(String countrySubDivisionName) { - CountrySubDivisionName = countrySubDivisionName; - } + public void setCountrySubDivisionName(String countrySubDivisionName) { + CountrySubDivisionName = countrySubDivisionName; + } - @Override - public String getPostcodeCode() { - return this.postCodeCode; - } + @Override + public String getPostcodeCode() { + return this.postCodeCode; + } - @Override - public String getLineOne() { - return this.lineOne; - } + @Override + public String getLineOne() { + return this.lineOne; + } - @Override - public String getLineTwo() { - return this.lineTwo; - } + @Override + public String getLineTwo() { + return this.lineTwo; + } - @Override - public String getLineThree() { - return this.lineThree; - } + @Override + public String getLineThree() { + return this.lineThree; + } - @Override - public String getCityName() { - return this.cityName; - } + @Override + public String getCityName() { + return this.cityName; + } - @Override - public String getCountryID() { - return this.countryID; - } + @Override + public String getCountryID() { + return this.countryID; + } - @Override - public String getCountrySubDivisionName() { - return this.CountrySubDivisionName; - } + @Override + public String getCountrySubDivisionName() { + return this.CountrySubDivisionName; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/Profile.java b/library/src/main/java/org/mustangproject/ZUGFeRD/Profile.java index 8368b46..9a3fd1f 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/Profile.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/Profile.java @@ -8,45 +8,45 @@ org.openrewrite.config.CompositeRecipe * For the XRechnung at the time being please use Factur-X's Xrechnung */ public class Profile { - protected String name, id; + protected String name, id; - /*** - * Contruct - * @param name human readable name of the profile, also used as basis to detemine the XMP Name - * @param ID XML Guideline ID - */ - public Profile(String name, String ID) { - this.name = name; - this.id = ID; - } + /*** + * Contruct + * @param name human readable name of the profile, also used as basis to detemine the XMP Name + * @param ID XML Guideline ID + */ + public Profile(String name, String ID) { + this.name = name; + this.id = ID; + } - /*** - * gets the name - * @return the name of the profile - */ - public String getName() { - return name; - } + /*** + * gets the name + * @return the name of the profile + */ + public String getName() { + return name; + } - /*** - * get guideline id - * @return the XML Guideline ID of the profile - */ - public String getID() { - return id; - } + /*** + * get guideline id + * @return the XML Guideline ID of the profile + */ + public String getID() { + return id; + } - /*** - * if the profile is embedded in PDF we need RDF metadata - * @return the XMP name string of the profile - */ - public String getXMPName() { - if (name.equals("BASICWL")) { - return "BASIC WL"; - } else if (name.equals("EN16931")) { - return "EN 16931"; - } else { - return name; - } - } + /*** + * if the profile is embedded in PDF we need RDF metadata + * @return the XMP name string of the profile + */ + public String getXMPName() { + if (name.equals("BASICWL")) { + return "BASIC WL"; + } else if (name.equals("EN16931")) { + return "EN 16931"; + } else { + return name; + } + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java b/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java index 3d73e7a..9f0ac17 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/Profiles.java @@ -20,108 +20,108 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; +import org.mustangproject.EStandard; + import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.mustangproject.EStandard; - public class Profiles { - static Map zf2Map = Stream.of(new Object[][]{ - {"MINIMUM", new Profile("MINIMUM", "urn:factur-x.eu:1p0:minimum")}, - {"BASICWL", new Profile("BASICWL", "urn:factur-x.eu:1p0:basicwl")}, - {"BASIC", new Profile("BASIC", "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")}, - {"EN16931", new Profile("EN16931", "urn:cen.eu:en16931:2017")}, - {"EXTENDED", new Profile("EXTENDED", "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")}, - {"XRECHNUNG", new Profile("XRECHNUNG", "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0")} // up next: urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 + static Map zf2Map = Stream.of(new Object[][]{ + {"MINIMUM", new Profile("MINIMUM", "urn:factur-x.eu:1p0:minimum")}, + {"BASICWL", new Profile("BASICWL", "urn:factur-x.eu:1p0:basicwl")}, + {"BASIC", new Profile("BASIC", "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")}, + {"EN16931", new Profile("EN16931", "urn:cen.eu:en16931:2017")}, + {"EXTENDED", new Profile("EXTENDED", "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")}, + {"XRECHNUNG", new Profile("XRECHNUNG", "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0")} // up next: urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 - }).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1])); - static Map zf1Map = Stream.of(new Object[][]{ - {"BASIC", new Profile("BASIC", "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")}, - {"COMFORT", new Profile("COMFORT", "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")}, + }).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1])); + static Map zf1Map = Stream.of(new Object[][]{ + {"BASIC", new Profile("BASIC", "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")}, + {"COMFORT", new Profile("COMFORT", "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")}, {"EXTENDED", new Profile("EXTENDED", "urn:ferd:CrossIndustryDocument:invoice:1p0:extended")}, }).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1])); - static Map ox1Map = Stream.of(new Object[][]{ - {"BASIC", new Profile("BASIC", "urn:order-x.eu:1p0:basic")}, - {"COMFORT", new Profile("COMFORT", "urn:order-x.eu:1p0:comfort")}, + static Map ox1Map = Stream.of(new Object[][]{ + {"BASIC", new Profile("BASIC", "urn:order-x.eu:1p0:basic")}, + {"COMFORT", new Profile("COMFORT", "urn:order-x.eu:1p0:comfort")}, {"EXTENDED", new Profile("EXTENDED", "urn:order-x.eu:1p0:extended")}, }).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1])); - static Map dx1Map = Stream.of(new Object[][]{ - {"PILOT", new Profile("PILOT", "urn:awv-net.de:CIDA:1.0:pilot")} - }).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1])); + static Map dx1Map = Stream.of(new Object[][]{ + {"PILOT", new Profile("PILOT", "urn:awv-net.de:CIDA:1.0:pilot")} + }).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1])); - public static Profile getByName(EStandard standard, String name, int version) { - if (standard == EStandard.orderx) { - Profile result = null; - result = ox1Map.get(name.toUpperCase()); - if (result == null) { - throw new RuntimeException("Profile not found"); - } - return result; - } else if (standard == EStandard.despatchadvice) { - Profile result = null; - result = dx1Map.get(name.toUpperCase()); - if (result == null) { - throw new RuntimeException("Profile not found"); - } - return result; - } else { - int generation = version; - if ((standard==EStandard.facturx) && (version==1)) { - generation = 2; - } - return getByName(name, generation); + public static Profile getByName(EStandard standard, String name, int version) { + if (standard == EStandard.orderx) { + Profile result = null; + result = ox1Map.get(name.toUpperCase()); + if (result == null) { + throw new RuntimeException("Profile not found"); + } + return result; + } else if (standard == EStandard.despatchadvice) { + Profile result = null; + result = dx1Map.get(name.toUpperCase()); + if (result == null) { + throw new RuntimeException("Profile not found"); + } + return result; + } else { + int generation = version; + if ((standard == EStandard.facturx) && (version == 1)) { + generation = 2; + } + return getByName(name, generation); - } - } + } + } - public static Profile getByName(String name, int version) { - Profile result = null; - if (version == 1) { - result = zf1Map.get(name.toUpperCase()); - } else { - result = zf2Map.get(name.toUpperCase()); - } - if (result == null) { - throw new RuntimeException("Profile not found"); - } - return result; - } + public static Profile getByName(String name, int version) { + Profile result = null; + if (version == 1) { + result = zf1Map.get(name.toUpperCase()); + } else { + result = zf2Map.get(name.toUpperCase()); + } + if (result == null) { + throw new RuntimeException("Profile not found"); + } + return result; + } - public static Profile getByName(String name) { - return getByName(name, ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion); - } + public static Profile getByName(String name) { + return getByName(name, ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion); + } - /** - * Obtains a profile by name, disregarding version. First searches among - * 1.x profiles and fatre that among 2.x profiles. - * - * @param name profile name to search for - * - * @return a profile matching the requested name - */ - public static Profile getByNameDisregardingVersion(String name) - { - Profile result = null; + /** + * Obtains a profile by name, disregarding version. First searches among + * 1.x profiles and fatre that among 2.x profiles. + * + * @param name profile name to search for + * + * @return a profile matching the requested name + */ + public static Profile getByNameDisregardingVersion(String name) + { + Profile result = null; - result = zf1Map.get(name.toUpperCase()); + result = zf1Map.get(name.toUpperCase()); - if (result == null) - { - result = zf2Map.get(name.toUpperCase()); - } + if (result == null) + { + result = zf2Map.get(name.toUpperCase()); + } - if (result==null) - { - throw new RuntimeException("Profile " + name + " not found"); - } + if (result == null) + { + throw new RuntimeException("Profile " + name + " not found"); + } - return result; - } + return result; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java b/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java index 8740e15..f0931bf 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java @@ -1,12 +1,12 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; -import static java.math.BigDecimal.ZERO; - import java.math.BigDecimal; import java.math.RoundingMode; import java.util.HashMap; import java.util.stream.Stream; +import static java.math.BigDecimal.ZERO; + /*** * The Transactioncalculator e.g. adds the line totals and applies VAT on whole * invoices @@ -14,240 +14,240 @@ * @see LineCalculator */ public class TransactionCalculator implements IAbsoluteValueProvider { - protected IExportableTransaction trans; + protected IExportableTransaction trans; - /*** - * - * @param trans the invoice (or IExportableTransaction) to be calculated - */ - public TransactionCalculator(IExportableTransaction trans) { - this.trans = trans; - } + /*** + * + * @param trans the invoice (or IExportableTransaction) to be calculated + */ + public TransactionCalculator(IExportableTransaction trans) { + this.trans = trans; + } - /*** - * if something had already been paid in advance, this will get it from the - * transaction - * - * @return prepaid amount - */ - protected BigDecimal getTotalPrepaid() { - if (trans.getTotalPrepaidAmount() == null) { - return BigDecimal.ZERO; - } else { - return trans.getTotalPrepaidAmount().setScale(2, RoundingMode.HALF_UP); - } - } + /*** + * if something had already been paid in advance, this will get it from the + * transaction + * + * @return prepaid amount + */ + protected BigDecimal getTotalPrepaid() { + if (trans.getTotalPrepaidAmount() == null) { + return BigDecimal.ZERO; + } else { + return trans.getTotalPrepaidAmount().setScale(2, RoundingMode.HALF_UP); + } + } - /*** - * the invoice total with VAT, allowances and - * charges, WITHOUT considering prepaid amount - * - * @return the invoice total including taxes - */ - public BigDecimal getGrandTotal() { + /*** + * the invoice total with VAT, allowances and + * charges, WITHOUT considering prepaid amount + * + * @return the invoice total including taxes + */ + public BigDecimal getGrandTotal() { - BigDecimal basis = getTaxBasis(); - return getVATPercentAmountMap().values().stream().map(VATAmount::getCalculated) - .map(p -> p.setScale(2, RoundingMode.HALF_UP)).reduce(BigDecimal.ZERO, BigDecimal::add).add(basis); - } + BigDecimal basis = getTaxBasis(); + return getVATPercentAmountMap().values().stream().map(VATAmount::getCalculated) + .map(p -> p.setScale(2, RoundingMode.HALF_UP)).reduce(BigDecimal.ZERO, BigDecimal::add).add(basis); + } - /*** - * returns total of charges for this tax rate - * - * @param percent a specific rate, or null for any rate - * @return the total amount - */ - protected BigDecimal getChargesForPercent(BigDecimal percent) { - IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges(); - return sumAllowanceCharge(percent, charges); - } + /*** + * returns total of charges for this tax rate + * + * @param percent a specific rate, or null for any rate + * @return the total amount + */ + protected BigDecimal getChargesForPercent(BigDecimal percent) { + IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges(); + return sumAllowanceCharge(percent, charges); + } - private BigDecimal sumAllowanceCharge(BigDecimal percent, IZUGFeRDAllowanceCharge[] charges) { - BigDecimal res = BigDecimal.ZERO; - if ((charges != null) && (charges.length > 0)) { - for (IZUGFeRDAllowanceCharge currentCharge : charges) { - if ((percent == null) || (currentCharge.getTaxPercent().compareTo(percent) == 0)) { - res = res.add(currentCharge.getTotalAmount(this)); - } - } - } - return res; - } + private BigDecimal sumAllowanceCharge(BigDecimal percent, IZUGFeRDAllowanceCharge[] charges) { + BigDecimal res = BigDecimal.ZERO; + if ((charges != null) && (charges.length > 0)) { + for (IZUGFeRDAllowanceCharge currentCharge : charges) { + if ((percent == null) || (currentCharge.getTaxPercent().compareTo(percent) == 0)) { + res = res.add(currentCharge.getTotalAmount(this)); + } + } + } + return res; + } - /*** - * returns a (potentially concatenated) string of charge reasons, or "Charges" - * if none are defined - * - * @param percent a specific rate, or null for any rate - * @return the space separated String - */ - protected String getChargeReasonForPercent(BigDecimal percent) { - IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges(); - String res = getAllowanceChargeReasonForPercent(percent, charges); - if ("".equals(res)) { - res = "Charges"; - } - return res; - } + /*** + * returns a (potentially concatenated) string of charge reasons, or "Charges" + * if none are defined + * + * @param percent a specific rate, or null for any rate + * @return the space separated String + */ + protected String getChargeReasonForPercent(BigDecimal percent) { + IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges(); + String res = getAllowanceChargeReasonForPercent(percent, charges); + if ("".equals(res)) { + res = "Charges"; + } + return res; + } - private String getAllowanceChargeReasonForPercent(BigDecimal percent, IZUGFeRDAllowanceCharge[] charges) { - String res = " "; - if ((charges != null) && (charges.length > 0)) { - for (IZUGFeRDAllowanceCharge currentCharge : charges) { - if ((percent == null) || (currentCharge.getTaxPercent().compareTo(percent) == 0) - && currentCharge.getReason() != null) { - res += currentCharge.getReason() + " "; - } - } - } - res = res.substring(0, res.length() - 1); - return res; - } + private String getAllowanceChargeReasonForPercent(BigDecimal percent, IZUGFeRDAllowanceCharge[] charges) { + String res = " "; + if ((charges != null) && (charges.length > 0)) { + for (IZUGFeRDAllowanceCharge currentCharge : charges) { + if ((percent == null) || (currentCharge.getTaxPercent().compareTo(percent) == 0) + && currentCharge.getReason() != null) { + res += currentCharge.getReason() + " "; + } + } + } + res = res.substring(0, res.length() - 1); + return res; + } - /*** - * returns a (potentially concatenated) string of allowance reasons, or - * "Allowances", if none are defined - * - * @param percent a specific rate, or null for any rate - * @return the space separated String - */ - protected String getAllowanceReasonForPercent(BigDecimal percent) { - IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances(); - String res = getAllowanceChargeReasonForPercent(percent, allowances); - if ("".equals(res)) { - res = "Allowances"; - } - return res; - } + /*** + * returns a (potentially concatenated) string of allowance reasons, or + * "Allowances", if none are defined + * + * @param percent a specific rate, or null for any rate + * @return the space separated String + */ + protected String getAllowanceReasonForPercent(BigDecimal percent) { + IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances(); + String res = getAllowanceChargeReasonForPercent(percent, allowances); + if ("".equals(res)) { + res = "Allowances"; + } + return res; + } - /*** - * returns total of allowances for this tax rate - * - * @param percent a specific rate, or null for any rate - * @return the total amount - */ - protected BigDecimal getAllowancesForPercent(BigDecimal percent) { - IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances(); - return sumAllowanceCharge(percent, allowances); - } + /*** + * returns total of allowances for this tax rate + * + * @param percent a specific rate, or null for any rate + * @return the total amount + */ + protected BigDecimal getAllowancesForPercent(BigDecimal percent) { + IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances(); + return sumAllowanceCharge(percent, allowances); + } - /*** - * returns the total net value of all items, without document level - * charges/allowances - * - * @return item sum - */ - protected BigDecimal getTotal() { - BigDecimal dec = Stream.of(trans.getZFItems()).map(LineCalculator::new) - .map(LineCalculator::getItemTotalNetAmount).reduce(ZERO, BigDecimal::add); - return dec; - } + /*** + * returns the total net value of all items, without document level + * charges/allowances + * + * @return item sum + */ + protected BigDecimal getTotal() { + BigDecimal dec = Stream.of(trans.getZFItems()).map(LineCalculator::new) + .map(LineCalculator::getItemTotalNetAmount).reduce(ZERO, BigDecimal::add); + return dec; + } - /*** - * returns the total net value of the invoice, including charges/allowances on - * document level - * - * @return item sum +- charges/allowances - */ - 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); - } + /*** + * returns the total net value of the invoice, including charges/allowances on + * document level + * + * @return item sum +- charges/allowances + */ + 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); + } - /** - * which taxes have been used with which amounts in this transaction, empty for - * no taxes, or e.g. 19:190 and 7:14 if 1000 Eur were applicable to 19% VAT - * (=190 EUR VAT) and 200 EUR were applicable to 7% (=14 EUR VAT) 190 Eur - * - * @return which taxes have been used with which amounts in this invoice - */ - protected HashMap getVATPercentAmountMap() { - HashMap hm = new HashMap<>(); - final String vatDueDateTypeCode = trans.getVATDueDateTypeCode(); + /** + * which taxes have been used with which amounts in this transaction, empty for + * no taxes, or e.g. 19:190 and 7:14 if 1000 Eur were applicable to 19% VAT + * (=190 EUR VAT) and 200 EUR were applicable to 7% (=14 EUR VAT) 190 Eur + * + * @return which taxes have been used with which amounts in this invoice + */ + protected HashMap getVATPercentAmountMap() { + HashMap hm = new HashMap<>(); + final String vatDueDateTypeCode = trans.getVATDueDateTypeCode(); - for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { - BigDecimal percent = null; - if (currentItem.getProduct()!=null) - { - percent=currentItem.getProduct().getVATPercent(); - } - if (percent != null) { - LineCalculator lc = new LineCalculator(currentItem); - VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), - currentItem.getProduct().getTaxCategoryCode(), vatDueDateTypeCode); - String reasonText = currentItem.getProduct().getTaxExemptionReason(); - if (reasonText != null) { - itemVATAmount.setVatExemptionReasonText(reasonText); - } - VATAmount current = hm.get(percent.stripTrailingZeros()); - if (current == null) { - hm.put(percent.stripTrailingZeros(), itemVATAmount); - } else { - hm.put(percent.stripTrailingZeros(), current.add(itemVATAmount)); - } - } - } + for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { + BigDecimal percent = null; + if (currentItem.getProduct() != null) + { + percent = currentItem.getProduct().getVATPercent(); + } + if (percent != null) { + LineCalculator lc = new LineCalculator(currentItem); + VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), + currentItem.getProduct().getTaxCategoryCode(), vatDueDateTypeCode); + String reasonText = currentItem.getProduct().getTaxExemptionReason(); + if (reasonText != null) { + itemVATAmount.setVatExemptionReasonText(reasonText); + } + VATAmount current = hm.get(percent.stripTrailingZeros()); + if (current == null) { + hm.put(percent.stripTrailingZeros(), itemVATAmount); + } else { + hm.put(percent.stripTrailingZeros(), current.add(itemVATAmount)); + } + } + } - IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges(); - if ((charges != null) && (charges.length > 0)) { - for (IZUGFeRDAllowanceCharge currentCharge : charges) { - BigDecimal taxPercent = currentCharge.getTaxPercent(); - if (taxPercent != null) { - VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros()); - if (theAmount == null) { - theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO, - currentCharge.getCategoryCode() != null ? currentCharge.getCategoryCode() : "S", - vatDueDateTypeCode); - } - theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(this))); - BigDecimal factor = taxPercent.divide(new BigDecimal(100)); - theAmount.setCalculated(theAmount.getBasis().multiply(factor)); - hm.put(taxPercent.stripTrailingZeros(), theAmount); - } - } - } - IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances(); - if ((allowances != null) && (allowances.length > 0)) { - for (IZUGFeRDAllowanceCharge currentAllowance : allowances) { - BigDecimal taxPercent = currentAllowance.getTaxPercent(); - if (taxPercent != null) { - VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros()); - if (theAmount == null) { - theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO, - currentAllowance.getCategoryCode() != null ? currentAllowance.getCategoryCode() : "S", - vatDueDateTypeCode); - } - theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this))); - BigDecimal factor = taxPercent.divide(new BigDecimal(100)); - theAmount.setCalculated(theAmount.getBasis().multiply(factor)); + IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges(); + if ((charges != null) && (charges.length > 0)) { + for (IZUGFeRDAllowanceCharge currentCharge : charges) { + BigDecimal taxPercent = currentCharge.getTaxPercent(); + if (taxPercent != null) { + VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros()); + if (theAmount == null) { + theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO, + currentCharge.getCategoryCode() != null ? currentCharge.getCategoryCode() : "S", + vatDueDateTypeCode); + } + theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(this))); + BigDecimal factor = taxPercent.divide(new BigDecimal(100)); + theAmount.setCalculated(theAmount.getBasis().multiply(factor)); + hm.put(taxPercent.stripTrailingZeros(), theAmount); + } + } + } + IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances(); + if ((allowances != null) && (allowances.length > 0)) { + for (IZUGFeRDAllowanceCharge currentAllowance : allowances) { + BigDecimal taxPercent = currentAllowance.getTaxPercent(); + if (taxPercent != null) { + VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros()); + if (theAmount == null) { + theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO, + currentAllowance.getCategoryCode() != null ? currentAllowance.getCategoryCode() : "S", + vatDueDateTypeCode); + } + theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this))); + BigDecimal factor = taxPercent.divide(new BigDecimal(100)); + theAmount.setCalculated(theAmount.getBasis().multiply(factor)); - hm.put(taxPercent.stripTrailingZeros(), theAmount); - } - } - } + hm.put(taxPercent.stripTrailingZeros(), theAmount); + } + } + } - return hm; - } + return hm; + } - @Override - public BigDecimal getValue() { - return getTotal(); - } + @Override + public BigDecimal getValue() { + return getTotal(); + } - public BigDecimal getChargeTotal() { - return getChargesForPercent(null).setScale(2, RoundingMode.HALF_UP); - } + public BigDecimal getChargeTotal() { + return getChargesForPercent(null).setScale(2, RoundingMode.HALF_UP); + } - public BigDecimal getAllowanceTotal() { - return getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP); - } + public BigDecimal getAllowanceTotal() { + return getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP); + } - public BigDecimal getDuePayable() { - BigDecimal res = getGrandTotal().subtract(getTotalPrepaid()); - if (trans.getRoundingAmount() != null) { - res = res.add(trans.getRoundingAmount()); - } - return res; - } + public BigDecimal getDuePayable() { + BigDecimal res = getGrandTotal().subtract(getTotalPrepaid()); + if (trans.getRoundingAmount() != null) { + res = res.add(trans.getRoundingAmount()); + } + return res; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/UBLDAPullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/UBLDAPullProvider.java index 128af5d..c4bbf01 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/UBLDAPullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/UBLDAPullProvider.java @@ -20,11 +20,6 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import java.io.IOException; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; - import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; @@ -35,120 +30,125 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; + public class UBLDAPullProvider implements IXMLProvider { - private static final Logger LOGGER = LoggerFactory.getLogger (UBLDAPullProvider.class); + private static final Logger LOGGER = LoggerFactory.getLogger(UBLDAPullProvider.class); - protected IExportableTransaction trans; - protected TransactionCalculator calc; - byte[] ublData; - protected Profile profile = Profiles.getByName(EStandard.ubldespatchadvice, "basic", 1); + protected IExportableTransaction trans; + protected TransactionCalculator calc; + byte[] ublData; + protected Profile profile = Profiles.getByName(EStandard.ubldespatchadvice, "basic", 1); - @Override - public void generateXML(IExportableTransaction trans) { - this.trans = trans; - this.calc = new TransactionCalculator(trans); + @Override + public void generateXML(IExportableTransaction trans) { + this.trans = trans; + this.calc = new TransactionCalculator(trans); - final SimpleDateFormat ublDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + final SimpleDateFormat ublDateFormat = new SimpleDateFormat("yyyy-MM-dd"); - String xml = "\n" + - "\n" + - " 2.2\n" + - " 1Lieferschein\n" + - " ubl-xml-only\n" + - " " + XMLTools.encodeXML(trans.getNumber()) + "\n" + - " " + ublDateFormat.format(trans.getIssueDate()) + "\n" + - " 900\n"; - if (trans.getReferenceNumber() != null) { - xml += " " + XMLTools.encodeXML(trans.getNumber()) + "\n"; + String xml = "\n" + + "\n" + + " 2.2\n" + + " 1Lieferschein\n" + + " ubl-xml-only\n" + + " " + XMLTools.encodeXML(trans.getNumber()) + "\n" + + " " + ublDateFormat.format(trans.getIssueDate()) + "\n" + + " 900\n"; + if (trans.getReferenceNumber() != null) { + xml += " " + XMLTools.encodeXML(trans.getNumber()) + "\n"; - } - xml += " " + getPartyXML(trans.getSender()) + "\n" + - " " + getPartyXML(trans.getRecipient()) + "\n"; - if (trans.getDeliveryDate() != null) { - xml += " 1" + ublDateFormat.format(trans.getDeliveryDate()) + ""; - } - int i = 1; - for (IZUGFeRDExportableItem item : trans.getZFItems()) { - xml += - " \n" + - " " + XMLTools.encodeXML(Integer.toString(i++)) + "\n" + - " " + item.getQuantity() + "\n" + - " \n" + - " " + XMLTools.encodeXML(item.getBuyerOrderReferencedDocumentLineID()) + "\n" + - " \n" + - " \n" + - " " + XMLTools.encodeXML(item.getProduct().getName()) + "\n" + - " \n" + - " \n"; + } + xml += " " + getPartyXML(trans.getSender()) + "\n" + + " " + getPartyXML(trans.getRecipient()) + "\n"; + if (trans.getDeliveryDate() != null) { + xml += " 1" + ublDateFormat.format(trans.getDeliveryDate()) + ""; + } + int i = 1; + for (IZUGFeRDExportableItem item : trans.getZFItems()) { + xml += + " \n" + + " " + XMLTools.encodeXML(Integer.toString(i++)) + "\n" + + " " + item.getQuantity() + "\n" + + " \n" + + " " + XMLTools.encodeXML(item.getBuyerOrderReferencedDocumentLineID()) + "\n" + + " \n" + + " \n" + + " " + XMLTools.encodeXML(item.getProduct().getName()) + "\n" + + " \n" + + " \n"; - } - xml += "\n"; - final byte[] ublRaw; - ublRaw = xml.getBytes(StandardCharsets.UTF_8); + } + xml += "\n"; + final byte[] ublRaw; + ublRaw = xml.getBytes(StandardCharsets.UTF_8); - ublData = XMLTools.removeBOM(ublRaw); - } + ublData = XMLTools.removeBOM(ublRaw); + } - public String getPartyXML(IZUGFeRDExportableTradeParty tp) { - return "\n" + - " \n" + - " " + XMLTools.encodeXML(tp.getLocation()) + "\n" + - " \n" + - " " + XMLTools.encodeXML(tp.getName()) + "\n" + - " \n" + - " \n" + - " " + XMLTools.encodeXML(tp.getStreet()) + "\n" + - " \n" + - " \n" + - " " + XMLTools.encodeXML(tp.getCountry()) + "\n" + - " \n" + - " \n" + - " "; - } + public String getPartyXML(IZUGFeRDExportableTradeParty tp) { + return "\n" + + " \n" + + " " + XMLTools.encodeXML(tp.getLocation()) + "\n" + + " \n" + + " " + XMLTools.encodeXML(tp.getName()) + "\n" + + " \n" + + " \n" + + " " + XMLTools.encodeXML(tp.getStreet()) + "\n" + + " \n" + + " \n" + + " " + XMLTools.encodeXML(tp.getCountry()) + "\n" + + " \n" + + " \n" + + " "; + } - @Override - public byte[] getXML() { + @Override + public byte[] getXML() { - byte[] res = ublData; + byte[] res = ublData; - final StringWriter sw = new StringWriter(); - Document document = null; - try { - document = DocumentHelper.parseText(new String(ublData)); - } catch (final DocumentException e1) { - LOGGER.error ("Failed to parse UBL", e1); - } - try { - final OutputFormat format = OutputFormat.createPrettyPrint(); - format.setTrimText(false); - final XMLWriter writer = new XMLWriter(sw, format); - writer.write(document); - res = sw.toString().getBytes(StandardCharsets.UTF_8); + final StringWriter sw = new StringWriter(); + Document document = null; + try { + document = DocumentHelper.parseText(new String(ublData)); + } catch (final DocumentException e1) { + LOGGER.error("Failed to parse UBL", e1); + } + try { + final OutputFormat format = OutputFormat.createPrettyPrint(); + format.setTrimText(false); + final XMLWriter writer = new XMLWriter(sw, format); + writer.write(document); + res = sw.toString().getBytes(StandardCharsets.UTF_8); - } catch (final IOException e) { - LOGGER.error ("Failed to write XML", e); - } + } catch (final IOException e) { + LOGGER.error("Failed to write XML", e); + } - return res; + return res; - } + } - @Override - public void setTest() { + @Override + public void setTest() { - } + } - @Override - public void setProfile(Profile p) { - profile = p; - } + @Override + public void setProfile(Profile p) { + profile = p; + } - @Override - public Profile getProfile() { - return profile; - } + @Override + public Profile getProfile() { + return profile; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ValidationLogVisualizer.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ValidationLogVisualizer.java index a783d84..f3469bd 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ValidationLogVisualizer.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ValidationLogVisualizer.java @@ -1,5 +1,6 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; +import net.sf.saxon.TransformerFactoryImpl; import org.apache.fop.apps.*; import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.configuration.Configuration; @@ -18,119 +19,119 @@ import java.nio.charset.StandardCharsets; public class ValidationLogVisualizer { - private static final Logger LOGGER = LoggerFactory.getLogger(ValidationLogVisualizer.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ValidationLogVisualizer.class); - private TransformerFactory mFactory = null; - private Templates mXsltPDFTemplate = null; + private TransformerFactory mFactory = null; + private Templates mXsltPDFTemplate = null; - public ValidationLogVisualizer() { - mFactory = new net.sf.saxon.TransformerFactoryImpl(); - // fact = TransformerFactory.newInstance(); - mFactory.setURIResolver(new ClasspathResourceURIResolver()); - } + public ValidationLogVisualizer() { + mFactory = new TransformerFactoryImpl(); + // fact = TransformerFactory.newInstance(); + mFactory.setURIResolver(new ClasspathResourceURIResolver()); + } - protected void applyXSLTToPDF(final String xmlContent, final OutputStream outputStream, final ELanguage lang) - throws TransformerException { - Transformer transformer = mXsltPDFTemplate.newTransformer(); - transformer.setParameter("lang", lang.name().toLowerCase()); + protected void applyXSLTToPDF(final String xmlContent, final OutputStream outputStream, final ELanguage lang) + throws TransformerException { + Transformer transformer = mXsltPDFTemplate.newTransformer(); + transformer.setParameter("lang", lang.name().toLowerCase()); - transformer.transform(new StreamSource(new StringReader(xmlContent)), new StreamResult(outputStream)); - } + transformer.transform(new StreamSource(new StringReader(xmlContent)), new StreamResult(outputStream)); + } - protected String toFOP(final String xmlContent, final ELanguage lang) - throws TransformerException { + protected String toFOP(final String xmlContent, final ELanguage lang) + throws TransformerException { - try { - if (mXsltPDFTemplate == null) { - mXsltPDFTemplate = mFactory.newTemplates( - ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.CUSTOM_BASE_PATH + "result-pdf.xsl") - ); - } - } catch (TransformerConfigurationException ex) { - LOGGER.error("Failed to init XSLT templates", ex); - } + try { + if (mXsltPDFTemplate == null) { + mXsltPDFTemplate = mFactory.newTemplates( + ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.CUSTOM_BASE_PATH + "result-pdf.xsl") + ); + } + } catch (TransformerConfigurationException ex) { + LOGGER.error("Failed to init XSLT templates", ex); + } - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { + try { - applyXSLTToPDF(xmlContent, baos, lang); + applyXSLTToPDF(xmlContent, baos, lang); - } catch (Exception e1) { - LOGGER.error("Failed to create PDF", e1); - } + } catch (Exception e1) { + LOGGER.error("Failed to create PDF", e1); + } - return baos.toString(StandardCharsets.UTF_8); - } + return baos.toString(StandardCharsets.UTF_8); + } - @SuppressWarnings("unused") + @SuppressWarnings("unused") public void toPDF(String xmlLogfileContent, String pdfFilename) { - toPDF(xmlLogfileContent, pdfFilename, ELanguage.EN); - } + toPDF(xmlLogfileContent, pdfFilename, ELanguage.EN); + } - public void toPDF(String xmlLogfileContent, String pdfFilename, final ELanguage lang) { + public void toPDF(String xmlLogfileContent, String pdfFilename, final ELanguage lang) { - // the writing part + // the writing part - String result = null; + String result = null; - /* remove file endings so that tests can also pass after checking - out from git with arbitrary options (which may include CSRF changes) - */ - try { - result = this.toFOP(xmlLogfileContent, lang); - } catch (TransformerException e) { - LOGGER.error("Failed to apply FOP", e); - } - DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); + /* remove file endings so that tests can also pass after checking + out from git with arbitrary options (which may include CSRF changes) + */ + try { + result = this.toFOP(xmlLogfileContent, lang); + } catch (TransformerException e) { + LOGGER.error("Failed to apply FOP", e); + } + DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); - Configuration cfg = null; - try { - cfg = cfgBuilder.build(ClasspathResourceURIResolver.CLASS_LOADER.getResourceAsStream("fop-config.xconf")); - } catch (ConfigurationException e) { - throw new RuntimeException(e); - } + Configuration cfg = null; + try { + cfg = cfgBuilder.build(ClasspathResourceURIResolver.CLASS_LOADER.getResourceAsStream("fop-config.xconf")); + } catch (ConfigurationException e) { + throw new RuntimeException(e); + } - FopFactoryBuilder builder = new FopFactoryBuilder(new File(".").toURI(), new ClasspathResolverURIAdapter()).setConfiguration(cfg); + FopFactoryBuilder builder = new FopFactoryBuilder(new File(".").toURI(), new ClasspathResolverURIAdapter()).setConfiguration(cfg); - // Step 1: Construct a FopFactory by specifying a reference to the configuration file - // (reuse if you plan to render multiple documents!) + // Step 1: Construct a FopFactory by specifying a reference to the configuration file + // (reuse if you plan to render multiple documents!) - FopFactory fopFactory = builder.build(); + FopFactory fopFactory = builder.build(); - fopFactory.getFontManager().setResourceResolver( - ResourceResolverFactory.createInternalResourceResolver( - new File(".").toURI(), - new ClasspathResolverURIAdapter())); + fopFactory.getFontManager().setResourceResolver( + ResourceResolverFactory.createInternalResourceResolver( + new File(".").toURI(), + new ClasspathResolverURIAdapter())); - FOUserAgent userAgent = fopFactory.newFOUserAgent(); + FOUserAgent userAgent = fopFactory.newFOUserAgent(); - userAgent.getRendererOptions().put("pdf-a-mode", "PDF/A-3b"); + userAgent.getRendererOptions().put("pdf-a-mode", "PDF/A-3b"); - // Step 2: Set up output stream. - // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams). + // Step 2: Set up output stream. + // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams). - try (OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFilename))) { + try (OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFilename))) { - // Step 3: Construct fop with desired output format - Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out); + // Step 3: Construct fop with desired output format + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out); - // Step 4: Setup JAXP using identity transformer - TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer = factory.newTransformer(); // identity transformer + // Step 4: Setup JAXP using identity transformer + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); // identity transformer - // Step 5: Setup input and output for XSLT transformation - // Setup input stream - Source src = new StreamSource(new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8))); + // Step 5: Setup input and output for XSLT transformation + // Setup input stream + Source src = new StreamSource(new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8))); - // Resulting SAX events (the generated FO) must be piped through to FOP - Result res = new SAXResult(fop.getDefaultHandler()); + // Resulting SAX events (the generated FO) must be piped through to FOP + Result res = new SAXResult(fop.getDefaultHandler()); - // Step 6: Start XSLT transformation and FOP processing - transformer.transform(src, res); + // Step 6: Start XSLT transformation and FOP processing + transformer.transform(src, res); - } catch (FOPException | IOException | TransformerException e) { - LOGGER.error("Failed to create PDF", e); - } - } + } catch (FOPException | IOException | TransformerException e) { + LOGGER.error("Failed to create PDF", e); + } + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/VATAmount.java b/library/src/main/java/org/mustangproject/ZUGFeRD/VATAmount.java index 855e742..cdd6460 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/VATAmount.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/VATAmount.java @@ -33,113 +33,113 @@ org.openrewrite.config.CompositeRecipe public class VATAmount { - protected BigDecimal basis, calculated, applicablePercent; + protected BigDecimal basis, calculated, applicablePercent; - protected String categoryCode; + protected String categoryCode; - protected String vatExemptionReasonText; + protected String vatExemptionReasonText; - protected String dueDateTypeCode; + protected String dueDateTypeCode; - public VATAmount(BigDecimal basis, BigDecimal calculated, String categoryCode) { - super(); - this.basis = basis; - this.calculated = calculated; - this.categoryCode = categoryCode; - this.dueDateTypeCode = null; - } + public VATAmount(BigDecimal basis, BigDecimal calculated, String categoryCode) { + super(); + this.basis = basis; + this.calculated = calculated; + this.categoryCode = categoryCode; + this.dueDateTypeCode = null; + } - public VATAmount(BigDecimal basis, BigDecimal calculated, String categoryCode, String dueDateTypeCode) { - super(); - this.basis = basis; - this.calculated = calculated; - this.categoryCode = categoryCode; - this.dueDateTypeCode = dueDateTypeCode; - } + public VATAmount(BigDecimal basis, BigDecimal calculated, String categoryCode, String dueDateTypeCode) { + super(); + this.basis = basis; + this.calculated = calculated; + this.categoryCode = categoryCode; + this.dueDateTypeCode = dueDateTypeCode; + } - public BigDecimal getApplicablePercent() { - return applicablePercent; - } + public BigDecimal getApplicablePercent() { + return applicablePercent; + } - public VATAmount setApplicablePercent(BigDecimal applicablePercent) { + public VATAmount setApplicablePercent(BigDecimal applicablePercent) { - this.applicablePercent = applicablePercent; - return this; - } + this.applicablePercent = applicablePercent; + return this; + } - public BigDecimal getBasis() { - return basis; - } + public BigDecimal getBasis() { + return basis; + } - public VATAmount setBasis(BigDecimal basis) { - this.basis = basis.setScale(2, RoundingMode.HALF_UP); - return this; - } + public VATAmount setBasis(BigDecimal basis) { + this.basis = basis.setScale(2, RoundingMode.HALF_UP); + return this; + } - public BigDecimal getCalculated() { - return calculated; - } + public BigDecimal getCalculated() { + return calculated; + } - public VATAmount setCalculated(BigDecimal calculated) { - this.calculated = calculated; - return this; - } + public VATAmount setCalculated(BigDecimal calculated) { + this.calculated = calculated; + return this; + } - public String getVatExemptionReasonText() { - return vatExemptionReasonText; - } + public String getVatExemptionReasonText() { + return vatExemptionReasonText; + } - public VATAmount setVatExemptionReasonText(String theText) { - this.vatExemptionReasonText = theText; - return this; - } + public VATAmount setVatExemptionReasonText(String theText) { + this.vatExemptionReasonText = theText; + return this; + } - /** - * - * @deprecated Use {@link #getCategoryCode() instead} - * @return String with category code - */ - @Deprecated - public String getDocumentCode() { - return categoryCode; - } + /** + * + * @deprecated Use {@link #getCategoryCode() instead} + * @return String with category code + */ + @Deprecated + public String getDocumentCode() { + return categoryCode; + } - /** + /** * @param documentCode as String - * @deprecated Use {@link #setCategoryCode(String)} instead - * @return fluent setter - */ - @Deprecated - public VATAmount setDocumentCode(String documentCode) { - this.categoryCode = documentCode; - return this; - } + * @deprecated Use {@link #setCategoryCode(String)} instead + * @return fluent setter + */ + @Deprecated + public VATAmount setDocumentCode(String documentCode) { + this.categoryCode = documentCode; + return this; + } - public String getCategoryCode() { - return categoryCode; - } + public String getCategoryCode() { + return categoryCode; + } - public VATAmount setCategoryCode(String categoryCode) { - this.categoryCode = categoryCode; - return this; - } + public VATAmount setCategoryCode(String categoryCode) { + this.categoryCode = categoryCode; + return this; + } - public String getDueDateTypeCode() { - return dueDateTypeCode; - } + public String getDueDateTypeCode() { + return dueDateTypeCode; + } - public VATAmount setDueDateTypeCode(String dueDateTypeCode) { - this.dueDateTypeCode = dueDateTypeCode; - return this; - } + public VATAmount setDueDateTypeCode(String dueDateTypeCode) { + this.dueDateTypeCode = dueDateTypeCode; + return this; + } - public VATAmount add(VATAmount v) { - return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated()), this.categoryCode, this.dueDateTypeCode).setVatExemptionReasonText(v.getVatExemptionReasonText()); - } + public VATAmount add(VATAmount v) { + return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated()), this.categoryCode, this.dueDateTypeCode).setVatExemptionReasonText(v.getVatExemptionReasonText()); + } - public VATAmount subtract(VATAmount v) { - return new VATAmount(basis.subtract(v.getBasis()), calculated.subtract(v.getCalculated()), this.categoryCode, this.dueDateTypeCode).setVatExemptionReasonText(v.getVatExemptionReasonText()); - } + public VATAmount subtract(VATAmount v) { + return new VATAmount(basis.subtract(v.getBasis()), calculated.subtract(v.getCalculated()), this.categoryCode, this.dueDateTypeCode).setVatExemptionReasonText(v.getVatExemptionReasonText()); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/XMLUpgrader.java b/library/src/main/java/org/mustangproject/ZUGFeRD/XMLUpgrader.java index cf71f2b..451f4bb 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/XMLUpgrader.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/XMLUpgrader.java @@ -1,20 +1,12 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; +import net.sf.saxon.TransformerFactoryImpl; -import javax.xml.transform.Source; -import javax.xml.transform.Templates; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.URIResolver; +import javax.xml.transform.*; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import java.io.*; +import java.nio.charset.StandardCharsets; /*** @@ -25,54 +17,54 @@ */ public class XMLUpgrader { - static final ClassLoader CLASS_LOADER = XMLUpgrader.class.getClassLoader(); - private static final String RESOURCE_PATH = ""; - private TransformerFactory mFactory = null; - private Templates mXsltTemplate = null; + static final ClassLoader CLASS_LOADER = XMLUpgrader.class.getClassLoader(); + private static final String RESOURCE_PATH = ""; + private TransformerFactory mFactory = null; + private Templates mXsltTemplate = null; - public XMLUpgrader() { - mFactory = new net.sf.saxon.TransformerFactoryImpl(); - //fact = TransformerFactory.newInstance(); - mFactory.setURIResolver(new ClasspathResourceURIResolver()); - } + public XMLUpgrader() { + mFactory = new TransformerFactoryImpl(); + // fact = TransformerFactory.newInstance(); + mFactory.setURIResolver(new ClasspathResourceURIResolver()); + } - /*** - * Takes a filename of a ZF1 XML file and returns the string of ZF2 XML - * @param xmlFilename the filename of the source - * @return String the updated XML - * @throws FileNotFoundException if the source could not be found - * @throws TransformerException if the source could not be transformed - */ - public String migrateFromV1ToV2(String xmlFilename) throws FileNotFoundException, TransformerException { - /** - * * - * http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf - * http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf - * http://countwordsfree.com/xmlviewer - */ - mXsltTemplate = mFactory.newTemplates(new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/ZF1ToZF2.xsl"))); + /*** + * Takes a filename of a ZF1 XML file and returns the string of ZF2 XML + * @param xmlFilename the filename of the source + * @return String the updated XML + * @throws FileNotFoundException if the source could not be found + * @throws TransformerException if the source could not be transformed + */ + public String migrateFromV1ToV2(String xmlFilename) throws FileNotFoundException, TransformerException { + /** + * * + * http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf + * http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf + * http://countwordsfree.com/xmlviewer + */ + mXsltTemplate = mFactory.newTemplates(new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/ZF1ToZF2.xsl"))); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - applySchematronXsl(new FileInputStream(xmlFilename), baos); - String res = null; - res = baos.toString(StandardCharsets.UTF_8); - return res; - } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + applySchematronXsl(new FileInputStream(xmlFilename), baos); + String res = null; + res = baos.toString(StandardCharsets.UTF_8); + return res; + } - protected void applySchematronXsl(final InputStream xmlFile, - final OutputStream EN16931Outstream) throws TransformerException { - Transformer transformer = mXsltTemplate.newTransformer(); - transformer.transform(new StreamSource(xmlFile), new StreamResult(EN16931Outstream)); - } + protected void applySchematronXsl(final InputStream xmlFile, + final OutputStream EN16931Outstream) throws TransformerException { + Transformer transformer = mXsltTemplate.newTransformer(); + transformer.transform(new StreamSource(xmlFile), new StreamResult(EN16931Outstream)); + } - private static class ClasspathResourceURIResolver implements URIResolver { - ClasspathResourceURIResolver() { - // Do nothing, just prevents synthetic access warning. - } + private static class ClasspathResourceURIResolver implements URIResolver { + ClasspathResourceURIResolver() { + // Do nothing, just prevents synthetic access warning. + } - @Override - public Source resolve(String href, String base) throws TransformerException { - return new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + href)); - } - } + @Override + public Source resolve(String href, String base) throws TransformerException { + return new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + href)); + } + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/XMPSchemaPDFAExtensions.java b/library/src/main/java/org/mustangproject/ZUGFeRD/XMPSchemaPDFAExtensions.java index 567cd30..114f2f8 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/XMPSchemaPDFAExtensions.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/XMPSchemaPDFAExtensions.java @@ -30,15 +30,7 @@ org.openrewrite.config.CompositeRecipe import org.apache.xmpbox.XMPMetadata; import org.apache.xmpbox.XmpConstants; import org.apache.xmpbox.schema.PDFAExtensionSchema; -import org.apache.xmpbox.type.ArrayProperty; -import org.apache.xmpbox.type.Attribute; -import org.apache.xmpbox.type.Cardinality; -import org.apache.xmpbox.type.ChoiceType; -import org.apache.xmpbox.type.DefinedStructuredType; -import org.apache.xmpbox.type.PDFAPropertyType; -import org.apache.xmpbox.type.PDFASchemaType; -import org.apache.xmpbox.type.StructuredType; -import org.apache.xmpbox.type.TextType; +import org.apache.xmpbox.type.*; import org.mustangproject.EStandard; /** @@ -55,116 +47,116 @@ @StructuredType(preferedPrefix = "pdfaExtension", namespace = "http://www.aiim.org/pdfa/ns/extension/") public class XMPSchemaPDFAExtensions extends PDFAExtensionSchema { - public final String xmlns_pdfaSchema = "http://www.aiim.org/pdfa/ns/schema#"; - public final String prefix_pdfaSchema = "pdfaSchema"; - public final String xmlns_pdfaProperty = "http://www.aiim.org/pdfa/ns/property#"; - public final String prefix_pdfaProperty = "pdfaProperty"; - public String namespace = null; - public String prefix = null; + public final String xmlns_pdfaSchema = "http://www.aiim.org/pdfa/ns/schema#"; + public final String prefix_pdfaSchema = "pdfaSchema"; + public final String xmlns_pdfaProperty = "http://www.aiim.org/pdfa/ns/property#"; + public final String prefix_pdfaProperty = "pdfaProperty"; + public String namespace = null; + public String prefix = null; - protected IZUGFeRDExporter exporter; + protected IZUGFeRDExporter exporter; - protected void setZUGFeRDVersion(int ver) { - namespace = exporter.getNamespaceForVersion(ver); - prefix = exporter.getPrefixForVersion(ver); - } + protected void setZUGFeRDVersion(int ver) { + namespace = exporter.getNamespaceForVersion(ver); + prefix = exporter.getPrefixForVersion(ver); + } - private DefinedStructuredType addProperty(ArrayProperty parent, String name, String type, String category, - String description) { - XMPMetadata metadata = getMetadata(); + private DefinedStructuredType addProperty(ArrayProperty parent, String name, String type, String category, + String description) { + XMPMetadata metadata = getMetadata(); - DefinedStructuredType li = new DefinedStructuredType(metadata, getNamespace(), getPrefix(), - XmpConstants.LIST_NAME); - li.setAttribute(new Attribute(getNamespace(), XmpConstants.PARSE_TYPE, XmpConstants.RESOURCE_NAME)); + DefinedStructuredType li = new DefinedStructuredType(metadata, getNamespace(), getPrefix(), + XmpConstants.LIST_NAME); + li.setAttribute(new Attribute(getNamespace(), XmpConstants.PARSE_TYPE, XmpConstants.RESOURCE_NAME)); - ChoiceType pdfa2 = new ChoiceType(metadata, xmlns_pdfaProperty, prefix_pdfaProperty, PDFAPropertyType.NAME, - name); - li.addProperty(pdfa2); + ChoiceType pdfa2 = new ChoiceType(metadata, xmlns_pdfaProperty, prefix_pdfaProperty, PDFAPropertyType.NAME, + name); + li.addProperty(pdfa2); - pdfa2 = new ChoiceType(metadata, xmlns_pdfaProperty, prefix_pdfaProperty, PDFAPropertyType.VALUETYPE, type); - li.addProperty(pdfa2); + pdfa2 = new ChoiceType(metadata, xmlns_pdfaProperty, prefix_pdfaProperty, PDFAPropertyType.VALUETYPE, type); + li.addProperty(pdfa2); - pdfa2 = new ChoiceType(metadata, xmlns_pdfaProperty, prefix_pdfaProperty, PDFAPropertyType.CATEGORY, category); - li.addProperty(pdfa2); + pdfa2 = new ChoiceType(metadata, xmlns_pdfaProperty, prefix_pdfaProperty, PDFAPropertyType.CATEGORY, category); + li.addProperty(pdfa2); - pdfa2 = new ChoiceType(metadata, xmlns_pdfaProperty, prefix_pdfaProperty, PDFAPropertyType.DESCRIPTION, - description); - li.addProperty(pdfa2); + pdfa2 = new ChoiceType(metadata, xmlns_pdfaProperty, prefix_pdfaProperty, PDFAPropertyType.DESCRIPTION, + description); + li.addProperty(pdfa2); - parent.addProperty(li); + parent.addProperty(li); - return li; - } + return li; + } - public XMPSchemaPDFAExtensions(IZUGFeRDExporter ze, XMPMetadata metadata, int ZFVersion) { - this(ze, metadata, ZFVersion, true); - } + public XMPSchemaPDFAExtensions(IZUGFeRDExporter ze, XMPMetadata metadata, int ZFVersion) { + this(ze, metadata, ZFVersion, true); + } - public XMPSchemaPDFAExtensions(IZUGFeRDExporter ze, XMPMetadata metadata, int ZFVersion, boolean withZF) { - this(ze, metadata, ZFVersion, withZF, null); - } + public XMPSchemaPDFAExtensions(IZUGFeRDExporter ze, XMPMetadata metadata, int ZFVersion, boolean withZF) { + this(ze, metadata, ZFVersion, withZF, null); + } - public XMPSchemaPDFAExtensions(IZUGFeRDExporter ze, XMPMetadata metadata, int ZFVersion, boolean withZF, EStandard eStandard) { - super(metadata); - exporter=ze; - setZUGFeRDVersion(ZFVersion); - attachExtensions(metadata, withZF, eStandard); - } + public XMPSchemaPDFAExtensions(IZUGFeRDExporter ze, XMPMetadata metadata, int ZFVersion, boolean withZF, EStandard eStandard) { + super(metadata); + exporter = ze; + setZUGFeRDVersion(ZFVersion); + attachExtensions(metadata, withZF, eStandard); + } - public void attachExtensions(XMPMetadata metadata, boolean withZF, EStandard eStandard) { + public void attachExtensions(XMPMetadata metadata, boolean withZF, EStandard eStandard) { - addNamespace(xmlns_pdfaSchema, prefix_pdfaSchema); - addNamespace(xmlns_pdfaProperty, prefix_pdfaProperty); + addNamespace(xmlns_pdfaSchema, prefix_pdfaSchema); + addNamespace(xmlns_pdfaProperty, prefix_pdfaProperty); - ArrayProperty newBag = createArrayProperty(SCHEMAS, Cardinality.Bag); - DefinedStructuredType li = new DefinedStructuredType(metadata, getNamespace(), getPrefix(), - XmpConstants.LIST_NAME); - li.setAttribute(new Attribute(getNamespace(), XmpConstants.PARSE_TYPE, XmpConstants.RESOURCE_NAME)); - newBag.addProperty(li); - addProperty(newBag); - if (withZF) { - TextType pdfa1 = new TextType(metadata, xmlns_pdfaSchema, prefix_pdfaSchema, PDFASchemaType.SCHEMA, - "Factur-X PDFA Extension Schema"); - li.addProperty(pdfa1); + ArrayProperty newBag = createArrayProperty(SCHEMAS, Cardinality.Bag); + DefinedStructuredType li = new DefinedStructuredType(metadata, getNamespace(), getPrefix(), + XmpConstants.LIST_NAME); + li.setAttribute(new Attribute(getNamespace(), XmpConstants.PARSE_TYPE, XmpConstants.RESOURCE_NAME)); + newBag.addProperty(li); + addProperty(newBag); + if (withZF) { + TextType pdfa1 = new TextType(metadata, xmlns_pdfaSchema, prefix_pdfaSchema, PDFASchemaType.SCHEMA, + "Factur-X PDFA Extension Schema"); + li.addProperty(pdfa1); - pdfa1 = new TextType(metadata, xmlns_pdfaSchema, prefix_pdfaSchema, PDFASchemaType.NAMESPACE_URI, - namespace); - li.addProperty(pdfa1); + pdfa1 = new TextType(metadata, xmlns_pdfaSchema, prefix_pdfaSchema, PDFASchemaType.NAMESPACE_URI, + namespace); + li.addProperty(pdfa1); - pdfa1 = new TextType(metadata, xmlns_pdfaSchema, prefix_pdfaSchema, PDFASchemaType.PREFIX, prefix); - li.addProperty(pdfa1); + pdfa1 = new TextType(metadata, xmlns_pdfaSchema, prefix_pdfaSchema, PDFASchemaType.PREFIX, prefix); + li.addProperty(pdfa1); - ArrayProperty newSeq = new ArrayProperty(metadata, xmlns_pdfaSchema, prefix_pdfaSchema, - PDFASchemaType.PROPERTY, Cardinality.Seq); - li.addProperty(newSeq); + ArrayProperty newSeq = new ArrayProperty(metadata, xmlns_pdfaSchema, prefix_pdfaSchema, + PDFASchemaType.PROPERTY, Cardinality.Seq); + li.addProperty(newSeq); - if ((eStandard != null) && (eStandard == EStandard.orderx)) - { - addProperty(newSeq, "DocumentFileName", "Text", "external", "Name of the embedded XML Order (or related) file"); - addProperty(newSeq, "DocumentType", "Text", "external", "ORDER, ORDER_RESPONSE, or ORDER_CHANGE"); - addProperty(newSeq, "Version", "Text", "external", "The actual version of the Order-X XML schema"); - addProperty(newSeq, "ConformanceLevel", "Text", "external", - "The selected Order-X profile completeness"); - } else if ((eStandard != null) && (eStandard == EStandard.despatchadvice)) - { - // As of late 2022 the Delivery-X standard is not yet published. See specification: - // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022 - // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3 - // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html - addProperty(newSeq, "DocumentFileName", "Text", "external", "Name of the embedded XML despatch advice file"); - addProperty(newSeq, "DocumentType", "Text", "external", "DESPATCHADVICE"); - addProperty(newSeq, "Version", "Text", "external", "The actual version of the despatch advice dataset"); - addProperty(newSeq, "ConformanceLevel", "Text", "external", "The conformance level of the despatch advice dataset"); - } else - { - addProperty(newSeq, "DocumentFileName", "Text", "external", "name of the embedded XML invoice file"); - addProperty(newSeq, "DocumentType", "Text", "external", "INVOICE"); - addProperty(newSeq, "Version", "Text", "external", "The actual version of the ZUGFeRD XML schema"); - addProperty(newSeq, "ConformanceLevel", "Text", "external", - "The selected ZUGFeRD profile completeness"); - } - } - } + if ((eStandard != null) && (eStandard == EStandard.orderx)) + { + addProperty(newSeq, "DocumentFileName", "Text", "external", "Name of the embedded XML Order (or related) file"); + addProperty(newSeq, "DocumentType", "Text", "external", "ORDER, ORDER_RESPONSE, or ORDER_CHANGE"); + addProperty(newSeq, "Version", "Text", "external", "The actual version of the Order-X XML schema"); + addProperty(newSeq, "ConformanceLevel", "Text", "external", + "The selected Order-X profile completeness"); + } else if ((eStandard != null) && (eStandard == EStandard.despatchadvice)) + { + // As of late 2022 the Delivery-X standard is not yet published. See specification: + // Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022 + // Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3 + // http://docplayer.org/230301085-Der-digitale-lieferschein-dls.html + addProperty(newSeq, "DocumentFileName", "Text", "external", "Name of the embedded XML despatch advice file"); + addProperty(newSeq, "DocumentType", "Text", "external", "DESPATCHADVICE"); + addProperty(newSeq, "Version", "Text", "external", "The actual version of the despatch advice dataset"); + addProperty(newSeq, "ConformanceLevel", "Text", "external", "The conformance level of the despatch advice dataset"); + } else + { + addProperty(newSeq, "DocumentFileName", "Text", "external", "name of the embedded XML invoice file"); + addProperty(newSeq, "DocumentType", "Text", "external", "INVOICE"); + addProperty(newSeq, "Version", "Text", "external", "The actual version of the ZUGFeRD XML schema"); + addProperty(newSeq, "ConformanceLevel", "Text", "external", + "The selected ZUGFeRD profile completeness"); + } + } + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/XMPSchemaZugferd.java b/library/src/main/java/org/mustangproject/ZUGFeRD/XMPSchemaZugferd.java index 58cf55c..a95db64 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/XMPSchemaZugferd.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/XMPSchemaZugferd.java @@ -17,6 +17,7 @@ org.openrewrite.config.CompositeRecipe * *********************************************************************** */ package org.mustangproject.ZUGFeRD; + /** * Mustangproject's ZUGFeRD implementation * ZUGFeRD exporter helper class @@ -31,62 +32,62 @@ public class XMPSchemaZugferd extends XMPSchema { - /*** - * This is what needs to be added to the RDF metadata - basically the name of the embedded Zugferd file - * - * @param metadata the xmp to be added to - * @param zfVersion which ZF version to use (2 for FX) - * @param isFacturX whether to export as Factur-X - * @param conformanceLevel e.g. conformanceLevel.EN16931 - * @param URN the xml URI for the XMP - * @param prefix the xml namespace prefix for the XMP, zf for ZUGFeRD, fx for Factur-X - * @param filename the filename of the invoice - */ - public XMPSchemaZugferd(XMPMetadata metadata, int zfVersion, boolean isFacturX, Profile conformanceLevel, - String URN, String prefix, String filename) { - this(metadata, zfVersion, isFacturX, conformanceLevel, URN, prefix, filename, null); - } + /*** + * This is what needs to be added to the RDF metadata - basically the name of the embedded Zugferd file + * + * @param metadata the xmp to be added to + * @param zfVersion which ZF version to use (2 for FX) + * @param isFacturX whether to export as Factur-X + * @param conformanceLevel e.g. conformanceLevel.EN16931 + * @param URN the xml URI for the XMP + * @param prefix the xml namespace prefix for the XMP, zf for ZUGFeRD, fx for Factur-X + * @param filename the filename of the invoice + */ + public XMPSchemaZugferd(XMPMetadata metadata, int zfVersion, boolean isFacturX, Profile conformanceLevel, + String URN, String prefix, String filename) { + this(metadata, zfVersion, isFacturX, conformanceLevel, URN, prefix, filename, null); + } - /*** - * This is what needs to be added to the RDF metadata - basically the name of the embedded Zugferd file - * - * @param metadata the xmp to be added to - * @param zfVersion which ZF version to use (2 for FX) - * @param isFacturX whether to export as Factur-X - * @param conformanceLevel e.g. conformanceLevel.EN16931 - * @param URN the xml URI for the XMP - * @param prefix the xml namespace prefix for the XMP, zf for ZUGFeRD, fx for Factur-X - * @param filename the filename of the invoice - * @param version meta-data version to set. May be null, and then it is set automatically - */ - public XMPSchemaZugferd(XMPMetadata metadata, int zfVersion, boolean isFacturX, Profile conformanceLevel, - String URN, String prefix, String filename, String version) { - super(metadata, URN, prefix, "ZUGFeRD Schema"); - - setAboutAsSimple(""); - - String conformanceLevelValue = conformanceLevel.getXMPName(); - setTextPropertyValue("ConformanceLevel", conformanceLevelValue); - setTextPropertyValue("DocumentType", "INVOICE"); - setTextPropertyValue("DocumentFileName", filename); - - if (version == null) { - version = "1.0"; - if ((zfVersion==2)&&(!isFacturX)) { - version="2p0"; - } - } - setTextPropertyValue("Version", version); - } - /*** - * Specify a custom XMP metadata document type - * @param type INVOICE or ORDER - * @return fluent setter - */ - public XMPSchemaZugferd setType(String type) { - setTextPropertyValue("DocumentType", type); - return this; - } + * This is what needs to be added to the RDF metadata - basically the name of the embedded Zugferd file + * + * @param metadata the xmp to be added to + * @param zfVersion which ZF version to use (2 for FX) + * @param isFacturX whether to export as Factur-X + * @param conformanceLevel e.g. conformanceLevel.EN16931 + * @param URN the xml URI for the XMP + * @param prefix the xml namespace prefix for the XMP, zf for ZUGFeRD, fx for Factur-X + * @param filename the filename of the invoice + * @param version meta-data version to set. May be null, and then it is set automatically + */ + public XMPSchemaZugferd(XMPMetadata metadata, int zfVersion, boolean isFacturX, Profile conformanceLevel, + String URN, String prefix, String filename, String version) { + super(metadata, URN, prefix, "ZUGFeRD Schema"); + + setAboutAsSimple(""); + + String conformanceLevelValue = conformanceLevel.getXMPName(); + setTextPropertyValue("ConformanceLevel", conformanceLevelValue); + setTextPropertyValue("DocumentType", "INVOICE"); + setTextPropertyValue("DocumentFileName", filename); + + if (version == null) { + version = "1.0"; + if ((zfVersion == 2) && (!isFacturX)) { + version = "2p0"; + } + } + setTextPropertyValue("Version", version); + } + + /*** + * Specify a custom XMP metadata document type + * @param type INVOICE or ORDER + * @return fluent setter + */ + public XMPSchemaZugferd setType(String type) { + setTextPropertyValue("DocumentType", type); + return this; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/XRechnungImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/XRechnungImporter.java index c6fc803..46e9be2 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/XRechnungImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/XRechnungImporter.java @@ -1,54 +1,55 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Paths; - import org.mustangproject.XMLTools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; + public class XRechnungImporter extends ZUGFeRDImporter { - private static final Logger LOGGER = LoggerFactory.getLogger (XRechnungImporter.class); + private static final Logger LOGGER = LoggerFactory.getLogger(XRechnungImporter.class); - public XRechnungImporter(byte[] rawXml) { - super(); + public XRechnungImporter(byte[] rawXml) { + super(); - try { - setRawXML(rawXml); - containsMeta = true; - } catch (final IOException e) { - LOGGER.error ("Failed to set raw XML", e); - throw new ZUGFeRDExportException(e); - } - } + try { + setRawXML(rawXml); + containsMeta = true; + } catch (final IOException e) { + LOGGER.error("Failed to set raw XML", e); + throw new ZUGFeRDExportException(e); + } + } - public XRechnungImporter(String filename) { - super(); + public XRechnungImporter(String filename) { + super(); - try { - setRawXML(Files.readAllBytes(Paths.get(filename))); - containsMeta = true; - } catch (final IOException e) { - LOGGER.error ("Failed to set raw XML", e); - throw new ZUGFeRDExportException(e); - } + try { + setRawXML(Files.readAllBytes(Path.of(filename))); + containsMeta = true; + } catch (final IOException e) { + LOGGER.error("Failed to set raw XML", e); + throw new ZUGFeRDExportException(e); + } - } - public XRechnungImporter(InputStream fileinput) { - super(); + } - try { - setRawXML(XMLTools.getBytesFromStream(fileinput)); - containsMeta = true; - } catch (final IOException e) { - LOGGER.error ("Failed to set raw XML", e); - throw new ZUGFeRDExportException(e); - } + public XRechnungImporter(InputStream fileinput) { + super(); + + try { + setRawXML(XMLTools.getBytesFromStream(fileinput)); + containsMeta = true; + } catch (final IOException e) { + LOGGER.error("Failed to set raw XML", e); + throw new ZUGFeRDExportException(e); + } - } + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/XRExporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/XRExporter.java index 5c2fa2a..16e46ee 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/XRExporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/XRExporter.java @@ -25,30 +25,30 @@ org.openrewrite.config.CompositeRecipe import java.io.IOException; import java.io.OutputStream; -public class XRExporter implements IExporter { - IXMLProvider xmlProvider; - IExportableTransaction trans; +public class XRExporter implements IExporter { + IXMLProvider xmlProvider; + IExportableTransaction trans; - public XRExporter() { - } + public XRExporter() { + } - @Override - public IExporter setTransaction(IExportableTransaction trans) throws IOException { - this.trans=trans; - return this; - } + @Override + public IExporter setTransaction(IExportableTransaction trans) throws IOException { + this.trans = trans; + return this; + } - @Override - public void export(String ZUGFeRDfilename) throws IOException { - export(new FileOutputStream(new File(ZUGFeRDfilename))); + @Override + public void export(String ZUGFeRDfilename) throws IOException { + export(new FileOutputStream(new File(ZUGFeRDfilename))); - } + } - @Override - public void export(OutputStream output) throws IOException { - xmlProvider.generateXML(trans); - byte[] bytes=xmlProvider.getXML(); - output.write(bytes, 0, bytes.length); - } + @Override + public void export(OutputStream output) throws IOException { + xmlProvider.generateXML(trans); + byte[] bytes = xmlProvider.getXML(); + output.write(bytes, 0, bytes.length); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java index b98abeb..4f35971 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java @@ -20,17 +20,6 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE; -import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON; - -import java.io.IOException; -import java.io.StringWriter; -import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; - import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; @@ -40,438 +29,449 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.io.StringWriter; +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; + +import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE; +import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON; + public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider { - private static final Logger LOGGER = LoggerFactory.getLogger (ZUGFeRD1PullProvider.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRD1PullProvider.class); - //// MAIN CLASS + // // MAIN CLASS - protected byte[] zugferdData; - private String paymentTermsDescription; - protected Profile profile = Profiles.getByName("COMFORT", 1); + protected byte[] zugferdData; + private String paymentTermsDescription; + protected Profile profile = Profiles.getByName("COMFORT", 1); - /** - * enables the flag to indicate a test invoice in the XML structure - */ - @Override - public void setTest() { - } + /** + * enables the flag to indicate a test invoice in the XML structure + */ + @Override + public void setTest() { + } - @Override - protected String vatFormat(BigDecimal value) { - return XMLTools.nDigitFormat(value, 2); - } + @Override + protected String vatFormat(BigDecimal value) { + return XMLTools.nDigitFormat(value, 2); + } - @Override - protected String currencyFormat(BigDecimal value) { - return XMLTools.nDigitFormat(value, 2); - } + @Override + protected String currencyFormat(BigDecimal value) { + return XMLTools.nDigitFormat(value, 2); + } - @Override - protected String priceFormat(BigDecimal value) { - return XMLTools.nDigitFormat(value, 4); - } + @Override + protected String priceFormat(BigDecimal value) { + return XMLTools.nDigitFormat(value, 4); + } - @Override - protected String quantityFormat(BigDecimal value) { - return XMLTools.nDigitFormat(value, 4); - } + @Override + protected String quantityFormat(BigDecimal value) { + return XMLTools.nDigitFormat(value, 4); + } - @Override - public Profile getProfile() { - return profile; - } + @Override + public Profile getProfile() { + return profile; + } - @Override - public byte[] getXML() { + @Override + public byte[] getXML() { - byte[] res = zugferdData; + byte[] res = zugferdData; - final StringWriter sw = new StringWriter(); - Document document = null; - try { - document = DocumentHelper.parseText(new String(zugferdData)); - } catch (final DocumentException e1) { - LOGGER.error ("Failed to parse ZUGFeRD data", e1); - } - try { - final OutputFormat format = OutputFormat.createPrettyPrint(); - format.setTrimText(false); - final XMLWriter writer = new XMLWriter(sw, format); - writer.write(document); - res = sw.toString().getBytes(StandardCharsets.UTF_8); + final StringWriter sw = new StringWriter(); + Document document = null; + try { + document = DocumentHelper.parseText(new String(zugferdData)); + } catch (final DocumentException e1) { + LOGGER.error("Failed to parse ZUGFeRD data", e1); + } + try { + final OutputFormat format = OutputFormat.createPrettyPrint(); + format.setTrimText(false); + final XMLWriter writer = new XMLWriter(sw, format); + writer.write(document); + res = sw.toString().getBytes(StandardCharsets.UTF_8); - } catch (final IOException e) { - LOGGER.error ("Failed to write ZUGFeRD data", e); - } + } catch (final IOException e) { + LOGGER.error("Failed to write ZUGFeRD data", e); + } - return res; + return res; - } + } - @Override - public void generateXML(IExportableTransaction trans) { - this.trans = trans; - this.calc = new TransactionCalculator(trans); + @Override + public void generateXML(IExportableTransaction trans) { + this.trans = trans; + this.calc = new TransactionCalculator(trans); - boolean hasDueDate = false; - final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - String exemptionReason = ""; + boolean hasDueDate = false; + final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); + String exemptionReason = ""; - if (trans.getPaymentTermDescription() != null) { - paymentTermsDescription = trans.getPaymentTermDescription(); - } + if (trans.getPaymentTermDescription() != null) { + paymentTermsDescription = trans.getPaymentTermDescription(); + } - if (paymentTermsDescription == null) { - paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); + if (paymentTermsDescription == null) { + paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); - } + } - String senderReg = ""; - if (trans.getOwnOrganisationFullPlaintextInfo() != null) { - senderReg = "" - + XMLTools.encodeXML(trans.getOwnOrganisationFullPlaintextInfo()) + "" - + "REG"; + String senderReg = ""; + if (trans.getOwnOrganisationFullPlaintextInfo() != null) { + senderReg = "" + + XMLTools.encodeXML(trans.getOwnOrganisationFullPlaintextInfo()) + "" + + "REG"; - } + } - String rebateAgreement = ""; - if (trans.rebateAgreementExists()) { - rebateAgreement = "" - + "Es bestehen Rabatt- und Bonusvereinbarungen." - + "AAK"; - } + String rebateAgreement = ""; + if (trans.rebateAgreementExists()) { + rebateAgreement = "" + + "Es bestehen Rabatt- und Bonusvereinbarungen." + + "AAK"; + } - String subjectNote = ""; - if (trans.getSubjectNote() != null) { - subjectNote = "" - + XMLTools.encodeXML(trans.getSubjectNote()) + "" - + ""; - } - String typecode = "380"; - if (trans.getDocumentCode() != null) { - typecode = trans.getDocumentCode(); - } - String xml = "" + String subjectNote = ""; + if (trans.getSubjectNote() != null) { + subjectNote = "" + + XMLTools.encodeXML(trans.getSubjectNote()) + "" + + ""; + } + String typecode = "380"; + if (trans.getDocumentCode() != null) { + typecode = trans.getDocumentCode(); + } + String xml = "" - + "" - + "" - + "" - // + " - // "+testBooleanStr+"" - // - + "" - + "" + getProfile().getID() + "" - + "" - + "" - + "" - + "" + XMLTools.encodeXML(trans.getNumber()) + "" - + "RECHNUNG" - + "" + typecode + "" - + "" - + DATE.udtFormat(trans.getIssueDate()) + "" // date - // format - // was - // 20130605 - + subjectNote - + rebateAgreement - + senderReg + + "" + + "" + + "" + // + " + // "+testBooleanStr+"" + // + + "" + + "" + getProfile().getID() + "" + + "" + + "" + + "" + + "" + XMLTools.encodeXML(trans.getNumber()) + "" + + "RECHNUNG" + + "" + typecode + "" + + "" + + DATE.udtFormat(trans.getIssueDate()) + "" // date + // format + // was + // 20130605 + + subjectNote + + rebateAgreement + + senderReg - + "" - + ""; - xml += ""; - if (trans.getReferenceNumber() != null) { - xml += "" + XMLTools.encodeXML(trans.getReferenceNumber()) + ""; + + "" + + ""; + xml += ""; + if (trans.getReferenceNumber() != null) { + xml += "" + XMLTools.encodeXML(trans.getReferenceNumber()) + ""; - } - xml += ""; - xml += getTradePartyAsXML(trans.getSender(), true, false); - xml += "" - + ""; - // + " GE2020211" - // + " 4000001987658" + } + xml += ""; + xml += getTradePartyAsXML(trans.getSender(), true, false); + xml += "" + + ""; + // + " GE2020211" + // + " 4000001987658" - xml += getTradePartyAsXML(trans.getRecipient(), false, false); - if ((trans.getOwnVATID() != null) && (trans.getOwnOrganisationName() != null)) { - xml += "" - + XMLTools.encodeXML(trans.getOwnVATID()) + "" - + ""; - } + xml += getTradePartyAsXML(trans.getRecipient(), false, false); + if ((trans.getOwnVATID() != null) && (trans.getOwnOrganisationName() != null)) { + xml += "" + + XMLTools.encodeXML(trans.getOwnVATID()) + "" + + ""; + } - xml += ""; + xml += ""; - if (trans.getSellerOrderReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" - + ""; - } - if (trans.getBuyerOrderReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" - + ""; - } - xml += "" - + ""; - if (this.trans.getDeliveryAddress() != null) { - xml += "" + - getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) + - ""; - } + if (trans.getSellerOrderReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" + + ""; + } + if (trans.getBuyerOrderReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" + + ""; + } + xml += "" + + ""; + if (this.trans.getDeliveryAddress() != null) { + xml += "" + + getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) + + ""; + } - xml += "" - + ""; + xml += "" + + ""; - if (trans.getDeliveryDate() != null) { - xml += DATE.udtFormat(trans.getDeliveryDate()); - } else { - throw new IllegalStateException("No delivery date provided"); - } - xml += ""; - xml += "" - /* - * + "" + - * "20130603" + - * "2013-51112" + - * "" - */ - + "" - + "" + XMLTools.encodeXML(trans.getNumber()) + "" - + "" + trans.getCurrency() + ""; + if (trans.getDeliveryDate() != null) { + xml += DATE.udtFormat(trans.getDeliveryDate()); + } else { + throw new IllegalStateException("No delivery date provided"); + } + xml += ""; + xml += "" + /* + * + "" + + * "20130603" + + * "2013-51112" + + * "" + */ + + "" + + "" + XMLTools.encodeXML(trans.getNumber()) + "" + + "" + trans.getCurrency() + ""; - if (trans.getTradeSettlementPayment() != null) { - for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { - if (payment != null) { - hasDueDate = true; - xml += payment.getSettlementXML(); - } - } - } - if (trans.getTradeSettlement() != null) { - for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { - if (payment != null) { - if (payment instanceof IZUGFeRDTradeSettlementPayment) { - hasDueDate = true; - } - xml += payment.getSettlementXML(); - } - } - } + if (trans.getTradeSettlementPayment() != null) { + for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { + if (payment != null) { + hasDueDate = true; + xml += payment.getSettlementXML(); + } + } + } + if (trans.getTradeSettlement() != null) { + for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { + if (payment != null) { + if (payment instanceof IZUGFeRDTradeSettlementPayment) { + hasDueDate = true; + } + xml += payment.getSettlementXML(); + } + } + } - final HashMap VATPercentAmountMap = calc.getVATPercentAmountMap(); - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); - if (amount != null) { - final String amountCategoryCode = amount.getCategoryCode(); - final String amountDueDateTypeCode = amount.getDueDateTypeCode(); - final boolean displayExemptionReason = CATEGORY_CODES_WITH_EXEMPTION_REASON.contains(amountCategoryCode); - xml += "" - + "" + currencyFormat(amount.getCalculated()) - + "" //currencyID=\"EUR\" - + "VAT" - + (displayExemptionReason ? exemptionReason : "") - + "" + currencyFormat(amount.getBasis()) + "" // currencyID=\"EUR\" - + "" + amount.getCategoryCode() + "" - + (amountDueDateTypeCode != null ? "" + amountDueDateTypeCode + "" : "") - + "" + vatFormat(currentTaxPercent) - + ""; - } - } + final HashMap VATPercentAmountMap = calc.getVATPercentAmountMap(); + for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); + if (amount != null) { + final String amountCategoryCode = amount.getCategoryCode(); + final String amountDueDateTypeCode = amount.getDueDateTypeCode(); + final boolean displayExemptionReason = CATEGORY_CODES_WITH_EXEMPTION_REASON.contains(amountCategoryCode); + xml += "" + + "" + currencyFormat(amount.getCalculated()) + + "" // currencyID=\"EUR\" + + "VAT" + + (displayExemptionReason ? exemptionReason : "") + + "" + currencyFormat(amount.getBasis()) + "" // currencyID=\"EUR\" + + "" + amount.getCategoryCode() + "" + + (amountDueDateTypeCode != null ? "" + amountDueDateTypeCode + "" : "") + + "" + vatFormat(currentTaxPercent) + + ""; + } + } - if (trans.getPaymentTerms() == null) { - xml += "" - + "" + paymentTermsDescription + ""; + if (trans.getPaymentTerms() == null) { + xml += "" + + "" + paymentTermsDescription + ""; - if (trans.getTradeSettlement() != null) { - for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { - if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { - xml += payment.getPaymentXML(); - } - } - } + if (trans.getTradeSettlement() != null) { + for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { + if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { + xml += payment.getPaymentXML(); + } + } + } - if (hasDueDate && (trans.getDueDate() != null)) { - xml += "" // $NON-NLS-2$ - + DATE.udtFormat(trans.getDueDate()) - + "";// 20130704 + if (hasDueDate && (trans.getDueDate() != null)) { + xml += "" // $NON-NLS-2$ + + DATE.udtFormat(trans.getDueDate()) + + "";// 20130704 - } - xml += ""; - } else { - xml += buildPaymentTermsXml(); - } + } + xml += ""; + } else { + xml += buildPaymentTermsXml(); + } - xml += "" - + "" + currencyFormat(calc.getTotal()) + "" - // currencyID=\"EUR\" - + "" - + currencyFormat(calc.getChargeTotal()) + "" // currencyID=\"EUR\" - + "" - + currencyFormat(calc.getAllowanceTotal()) + "" // - // currencyID=\"EUR\" - // + " 5.80" - // + " 14.73" - + "" - + currencyFormat(calc.getTaxBasis()) + "" - // // - // currencyID=\"EUR\" - + "" - + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "" - + "" + currencyFormat(calc.getGrandTotal()) + "" - // // - // currencyID=\"EUR\" - + "" + currencyFormat(calc.getTotalPrepaid()) + "" - + "" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "" - // // - // currencyID=\"EUR\" - + "" - + ""; + xml += "" + + "" + currencyFormat(calc.getTotal()) + "" + // currencyID=\"EUR\" + + "" + + currencyFormat(calc.getChargeTotal()) + "" // currencyID=\"EUR\" + + "" + + currencyFormat(calc.getAllowanceTotal()) + "" // + // currencyID=\"EUR\" + // + " 5.80" + // + " 14.73" + + "" + + currencyFormat(calc.getTaxBasis()) + "" + // // + // currencyID=\"EUR\" + + "" + + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "" + + "" + currencyFormat(calc.getGrandTotal()) + "" + // // + // currencyID=\"EUR\" + + "" + currencyFormat(calc.getTotalPrepaid()) + "" + + "" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "" + // // + // currencyID=\"EUR\" + + "" + + ""; - int lineID = 0; - for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) { - lineID++; - if (currentItem.getProduct().getTaxExemptionReason() != null) { - exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; - } + int lineID = 0; + for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) { + lineID++; + if (currentItem.getProduct().getTaxExemptionReason() != null) { + exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; + } - final LineCalculator lc = new LineCalculator(currentItem); - xml += "" + - "" - + "" + lineID + "" - + "" - + "" - + "" - + "" + priceFormat(lc.getPriceGross()) - + "" - + "" + quantityFormat(currentItem.getBasisQuantity()) + "" - // + " " - // + " false" - // + " 0.6667" - // + " Rabatt" - // + " " - + "" - + "" - + "" + priceFormat(currentItem.getPrice()) - + "" - + "" + quantityFormat(currentItem.getBasisQuantity()) + "" - + "" - + "" + final LineCalculator lc = new LineCalculator(currentItem); + xml += "" + + "" + + "" + lineID + "" + + "" + + "" + + "" + + "" + priceFormat(lc.getPriceGross()) + + "" + + "" + quantityFormat(currentItem.getBasisQuantity()) + "" + // + " " + // + " false" + // + " 0.6667" + // + " Rabatt" + // + " " + + "" + + "" + + "" + priceFormat(currentItem.getPrice()) + + "" + + "" + quantityFormat(currentItem.getBasisQuantity()) + "" + + "" + + "" - + "" - + "" - + quantityFormat(currentItem.getQuantity()) + "" - + "" - + "" - + "" - + "VAT" - + exemptionReason - + "" + currentItem.getProduct().getTaxCategoryCode() + "" + + "" + + "" + + quantityFormat(currentItem.getQuantity()) + "" + + "" + + "" + + "" + + "VAT" + + exemptionReason + + "" + currentItem.getProduct().getTaxCategoryCode() + "" - + "" - + vatFormat(currentItem.getProduct().getVATPercent()) + "" - + "" - + "" - + "" + currencyFormat(lc.getItemTotalNetAmount()) - + "" - + ""; - if (currentItem.getAdditionalReferences() != null) { - xml += "" + currentItem.getAdditionalReferences()[0].getIssuerAssignedID() + "130"; - } else if (currentItem.getAdditionalReferencedDocumentID() != null) { - xml += "" + currentItem.getAdditionalReferencedDocumentID() + "130"; - } - xml += "" - + ""; - // + " 4012345001235" - if (currentItem.getProduct().getSellerAssignedID() != null) { - xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; - } - if (currentItem.getProduct().getBuyerAssignedID() != null) { - xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; - } - xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "" - + "" + XMLTools.encodeXML(currentItem.getProduct().getDescription()) - + "" - + "" - + ""; - } + + "" + + vatFormat(currentItem.getProduct().getVATPercent()) + "" + + "" + + "" + + "" + currencyFormat(lc.getItemTotalNetAmount()) + + "" + + ""; + if (currentItem.getAdditionalReferences() != null) { + xml += "" + currentItem.getAdditionalReferences()[0].getIssuerAssignedID() + "130"; + } else if (currentItem.getAdditionalReferencedDocumentID() != null) { + xml += "" + currentItem.getAdditionalReferencedDocumentID() + "130"; + } + xml += "" + + ""; + // + " 4012345001235" + if (currentItem.getProduct().getSellerAssignedID() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; + } + if (currentItem.getProduct().getBuyerAssignedID() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; + } + xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "" + + "" + XMLTools.encodeXML(currentItem.getProduct().getDescription()) + + "" + + "" + + ""; + } - // + " \n" - // + " \n" - // + " \n" - // + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. - // 2013-51112 in Rechnung zu stellen:\n" - // + " \n" - // + " \n" - // + " \n"; + // + " \n" + // + " \n" + // + " \n" + // + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. + // 2013-51112 in Rechnung zu stellen:\n" + // + " \n" + // + " \n" + // + " \n"; - xml += "" - + ""; + xml += "" + + ""; - final byte[] zugferdRaw; - zugferdRaw = xml.getBytes(StandardCharsets.UTF_8); - zugferdData = XMLTools.removeBOM(zugferdRaw); - } + final byte[] zugferdRaw; + zugferdRaw = xml.getBytes(StandardCharsets.UTF_8); + zugferdData = XMLTools.removeBOM(zugferdRaw); + } - @Override - public void setProfile(Profile p) { - profile = p; - } + @Override + public void setProfile(Profile p) { + profile = p; + } - private String buildPaymentTermsXml() { - String paymentTermsXml = ""; + private String buildPaymentTermsXml() { + String paymentTermsXml = ""; - final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms(); - final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms(); - final Date dueDate = paymentTerms.getDueDate(); - if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) { - throw new IllegalStateException( - "if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified"); - } - paymentTermsXml += "" + paymentTerms.getDescription() + ""; - if (dueDate != null) { - paymentTermsXml += ""; - paymentTermsXml += DATE.udtFormat(dueDate); - paymentTermsXml += ""; - } + final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms(); + final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms(); + final Date dueDate = paymentTerms.getDueDate(); + if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) { + throw new IllegalStateException( + "if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified"); + } + paymentTermsXml += "" + paymentTerms.getDescription() + ""; + if (dueDate != null) { + paymentTermsXml += ""; + paymentTermsXml += DATE.udtFormat(dueDate); + paymentTermsXml += ""; + } - if (discountTerms != null) { - paymentTermsXml += ""; - final String currency = trans.getCurrency(); - final String basisAmount = currencyFormat(calc.getGrandTotal()); - paymentTermsXml += "" + basisAmount + ""; - paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString() - + ""; + if (discountTerms != null) { + paymentTermsXml += ""; + final String currency = trans.getCurrency(); + final String basisAmount = currencyFormat(calc.getGrandTotal()); + paymentTermsXml += "" + basisAmount + ""; + paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString() + + ""; - if (discountTerms.getBaseDate() != null) { - final Date baseDate = discountTerms.getBaseDate(); - paymentTermsXml += ""; - paymentTermsXml += DATE.udtFormat(baseDate); - paymentTermsXml += ""; + if (discountTerms.getBaseDate() != null) { + final Date baseDate = discountTerms.getBaseDate(); + paymentTermsXml += ""; + paymentTermsXml += DATE.udtFormat(baseDate); + paymentTermsXml += ""; - paymentTermsXml += "" - + discountTerms.getBasePeriodMeasure() + ""; - } + paymentTermsXml += "" + + discountTerms.getBasePeriodMeasure() + ""; + } - paymentTermsXml += ""; - } + paymentTermsXml += ""; + } - paymentTermsXml += ""; - return paymentTermsXml; - } + paymentTermsXml += ""; + return paymentTermsXml; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 6bd4f95..ffdfc42 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -20,8 +20,17 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE; -import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.io.OutputFormat; +import org.dom4j.io.XMLWriter; +import org.mustangproject.FileAttachment; +import org.mustangproject.IncludedNote; +import org.mustangproject.XMLTools; +import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.StringWriter; @@ -38,969 +47,960 @@ import java.util.Optional; import java.util.stream.Collectors; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.DocumentHelper; -import org.dom4j.io.OutputFormat; -import org.dom4j.io.XMLWriter; -import org.mustangproject.FileAttachment; -import org.mustangproject.IncludedNote; -import org.mustangproject.XMLTools; -import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE; +import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON; public class ZUGFeRD2PullProvider implements IXMLProvider { - private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRD2PullProvider.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRD2PullProvider.class); - protected byte[] zugferdData; - protected IExportableTransaction trans; - protected TransactionCalculator calc; - private String paymentTermsDescription; - protected Profile profile = Profiles.getByName("EN16931"); + protected byte[] zugferdData; + protected IExportableTransaction trans; + protected TransactionCalculator calc; + private String paymentTermsDescription; + protected Profile profile = Profiles.getByName("EN16931"); - /** - * enables the flag to indicate a test invoice in the XML structure - */ - @Override - public void setTest() { - } + /** + * enables the flag to indicate a test invoice in the XML structure + */ + @Override + public void setTest() { + } - protected String vatFormat(BigDecimal value) { - return XMLTools.nDigitFormat(value, 2); - } + protected String vatFormat(BigDecimal value) { + return XMLTools.nDigitFormat(value, 2); + } - protected String currencyFormat(BigDecimal value) { - return XMLTools.nDigitFormat(value, 2); - } + protected String currencyFormat(BigDecimal value) { + return XMLTools.nDigitFormat(value, 2); + } - protected String priceFormat(BigDecimal value) { - // 18 decimals are max for price and qty due to xml restrictions, - // see Chapter 3.2.3 of https://www.w3.org/TR/xmlschema-2/ - return XMLTools.nDigitFormatDecimalRange(value, 18, 4); - } + protected String priceFormat(BigDecimal value) { + // 18 decimals are max for price and qty due to xml restrictions, + // see Chapter 3.2.3 of https://www.w3.org/TR/xmlschema-2/ + return XMLTools.nDigitFormatDecimalRange(value, 18, 4); + } - protected String quantityFormat(BigDecimal value) { - return XMLTools.nDigitFormatDecimalRange(value, 18, 4); - } + protected String quantityFormat(BigDecimal value) { + return XMLTools.nDigitFormatDecimalRange(value, 18, 4); + } - @Override - public byte[] getXML() { + @Override + public byte[] getXML() { - byte[] res = zugferdData; + byte[] res = zugferdData; - final StringWriter sw = new StringWriter(); - Document document = null; - try { - document = DocumentHelper.parseText(new String(zugferdData)); - } catch (final DocumentException e1) { - LOGGER.error("Failed to parse ZUGFeRD data", e1); - } - try { - final OutputFormat format = OutputFormat.createPrettyPrint(); - format.setTrimText(false); - final XMLWriter writer = new XMLWriter(sw, format); - writer.write(document); - res = sw.toString().getBytes(StandardCharsets.UTF_8); + final StringWriter sw = new StringWriter(); + Document document = null; + try { + document = DocumentHelper.parseText(new String(zugferdData)); + } catch (final DocumentException e1) { + LOGGER.error("Failed to parse ZUGFeRD data", e1); + } + try { + final OutputFormat format = OutputFormat.createPrettyPrint(); + format.setTrimText(false); + final XMLWriter writer = new XMLWriter(sw, format); + writer.write(document); + res = sw.toString().getBytes(StandardCharsets.UTF_8); - } catch (final IOException e) { - LOGGER.error("Failed to write ZUGFeRD data", e); - } + } catch (final IOException e) { + LOGGER.error("Failed to write ZUGFeRD data", e); + } - return res; + return res; - } + } - @Override - public Profile getProfile() { - return profile; - } + @Override + public Profile getProfile() { + return profile; + } - // @todo check if the two boolean args can be refactored + // @todo check if the two boolean args can be refactored - /*** - * returns the UN/CEFACT CII XML for companies(tradeparties), which is actually - * the same for ZF1 (v 2013b) and ZF2 (v 2016b) - * @param party any sender, recipient, seller or legal party involved - * @param isSender some attributes are allowed only for senders in certain profiles - * @param isShipToTradeParty some attributes are allowed only for senders or recipients - * @return CII XML - */ - protected String getTradePartyAsXML(IZUGFeRDExportableTradeParty party, boolean isSender, boolean isShipToTradeParty) { - String xml = ""; - // According EN16931 either GlobalID or seller assigned ID might be present for BuyerTradeParty - // and ShipToTradeParty, but not both. Prefer seller assigned ID for now. - if (party.getID() != null) { - xml += "" + XMLTools.encodeXML(party.getID()) + ""; - } - if ((party.getGlobalIDScheme() != null) && (party.getGlobalID() != null)) { - xml += "" - + XMLTools.encodeXML(party.getGlobalID()) + ""; - } - xml += "" + XMLTools.encodeXML(party.getName()) + ""; - if (party.getDescription() != null) { - xml += "" + XMLTools.encodeXML(party.getDescription()) + ""; - } - if (party.getLegalOrganisation() != null) { - xml += " "; - if (party.getLegalOrganisation().getSchemedID() != null) { - if (profile == Profiles.getByName("Minimum")) { - xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + ""; - } else { - xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + ""; - } - } - if (party.getLegalOrganisation().getTradingBusinessName() != null) { - xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getTradingBusinessName()) + ""; - } - xml += ""; - } + /*** + * returns the UN/CEFACT CII XML for companies(tradeparties), which is actually + * the same for ZF1 (v 2013b) and ZF2 (v 2016b) + * @param party any sender, recipient, seller or legal party involved + * @param isSender some attributes are allowed only for senders in certain profiles + * @param isShipToTradeParty some attributes are allowed only for senders or recipients + * @return CII XML + */ + protected String getTradePartyAsXML(IZUGFeRDExportableTradeParty party, boolean isSender, boolean isShipToTradeParty) { + String xml = ""; + // According EN16931 either GlobalID or seller assigned ID might be present for BuyerTradeParty + // and ShipToTradeParty, but not both. Prefer seller assigned ID for now. + if (party.getID() != null) { + xml += "" + XMLTools.encodeXML(party.getID()) + ""; + } + if ((party.getGlobalIDScheme() != null) && (party.getGlobalID() != null)) { + xml += "" + + XMLTools.encodeXML(party.getGlobalID()) + ""; + } + xml += "" + XMLTools.encodeXML(party.getName()) + ""; + if (party.getDescription() != null) { + xml += "" + XMLTools.encodeXML(party.getDescription()) + ""; + } + if (party.getLegalOrganisation() != null) { + xml += " "; + if (party.getLegalOrganisation().getSchemedID() != null) { + if (profile == Profiles.getByName("Minimum")) { + xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + ""; + } else { + xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + ""; + } + } + if (party.getLegalOrganisation().getTradingBusinessName() != null) { + xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getTradingBusinessName()) + ""; + } + xml += ""; + } - if ((party.getContact() != null) && (isSender || profile == Profiles.getByName("EN16931") || profile == Profiles.getByName("Extended") || profile == Profiles.getByName("XRechnung"))) { - xml += ""; - if (party.getContact().getName() != null) { - xml += "" - + XMLTools.encodeXML(party.getContact().getName()) - + ""; - } - if (party.getContact().getPhone() != null) { - xml += "" - + XMLTools.encodeXML(party.getContact().getPhone()) + "" - + ""; - } + if ((party.getContact() != null) && (isSender || profile == Profiles.getByName("EN16931") || profile == Profiles.getByName("Extended") || profile == Profiles.getByName("XRechnung"))) { + xml += ""; + if (party.getContact().getName() != null) { + xml += "" + + XMLTools.encodeXML(party.getContact().getName()) + + ""; + } + if (party.getContact().getPhone() != null) { + xml += "" + + XMLTools.encodeXML(party.getContact().getPhone()) + "" + + ""; + } - if ((party.getContact().getFax() != null) && (profile == Profiles.getByName("Extended"))) { - xml += "" - + XMLTools.encodeXML(party.getContact().getFax()) + "" - + ""; - } - if (party.getContact().getEMail() != null) { - xml += "" - + XMLTools.encodeXML(party.getContact().getEMail()) + "" - + ""; - } - xml += ""; - } + if ((party.getContact().getFax() != null) && (profile == Profiles.getByName("Extended"))) { + xml += "" + + XMLTools.encodeXML(party.getContact().getFax()) + "" + + ""; + } + if (party.getContact().getEMail() != null) { + xml += "" + + XMLTools.encodeXML(party.getContact().getEMail()) + "" + + ""; + } + xml += ""; + } - xml += ""; - if (party.getZIP() != null) { - xml += "" + XMLTools.encodeXML(party.getZIP()) - + ""; - } - if (party.getStreet() != null) { - xml += "" + XMLTools.encodeXML(party.getStreet()) - + ""; - } - if (party.getAdditionalAddress() != null) { - xml += "" + XMLTools.encodeXML(party.getAdditionalAddress()) - + ""; - } - if (party.getAdditionalAddressExtension() != null) { - xml += "" + XMLTools.encodeXML(party.getAdditionalAddressExtension()) - + ""; - } - if (party.getLocation() != null) { - xml += "" + XMLTools.encodeXML(party.getLocation()) - + ""; - } + xml += ""; + if (party.getZIP() != null) { + xml += "" + XMLTools.encodeXML(party.getZIP()) + + ""; + } + if (party.getStreet() != null) { + xml += "" + XMLTools.encodeXML(party.getStreet()) + + ""; + } + if (party.getAdditionalAddress() != null) { + xml += "" + XMLTools.encodeXML(party.getAdditionalAddress()) + + ""; + } + if (party.getAdditionalAddressExtension() != null) { + xml += "" + XMLTools.encodeXML(party.getAdditionalAddressExtension()) + + ""; + } + if (party.getLocation() != null) { + xml += "" + XMLTools.encodeXML(party.getLocation()) + + ""; + } - //country IS mandatory - xml += "" + XMLTools.encodeXML(party.getCountry()) - + "" - + ""; - if (party.getUriUniversalCommunicationID() != null && party.getUriUniversalCommunicationIDScheme() != null) { - xml += "" + - "" + - XMLTools.encodeXML(party.getUriUniversalCommunicationID()) - + ""; - } + // country IS mandatory + xml += "" + XMLTools.encodeXML(party.getCountry()) + + "" + + ""; + if (party.getUriUniversalCommunicationID() != null && party.getUriUniversalCommunicationIDScheme() != null) { + xml += "" + + "" + + XMLTools.encodeXML(party.getUriUniversalCommunicationID()) + + ""; + } - if ((party.getVATID() != null) && (!isShipToTradeParty)) { - xml += "" - + "" + XMLTools.encodeXML(party.getVATID()) - + "" - + ""; - } - if ((party.getTaxID() != null) && (!isShipToTradeParty)) { - xml += "" - + "" + XMLTools.encodeXML(party.getTaxID()) - + "" - + ""; + if ((party.getVATID() != null) && (!isShipToTradeParty)) { + xml += "" + + "" + XMLTools.encodeXML(party.getVATID()) + + "" + + ""; + } + if ((party.getTaxID() != null) && (!isShipToTradeParty)) { + xml += "" + + "" + XMLTools.encodeXML(party.getTaxID()) + + "" + + ""; - } - return xml; + } + return xml; - } + } - protected String getTradePartyPayeeAsXML(IZUGFeRDExportableTradeParty party) { - String xml = ""; - // According EN16931 either GlobalID or seller assigned ID might be present for a Payee - if (party.getID() != null) { - xml += "" + XMLTools.encodeXML(party.getID()) + ""; - } - if ((party.getGlobalIDScheme() != null) && (party.getGlobalID() != null)) { - xml += "" - + XMLTools.encodeXML(party.getGlobalID()) - + ""; - } - xml += "" + XMLTools.encodeXML(party.getName()) + ""; + protected String getTradePartyPayeeAsXML(IZUGFeRDExportableTradeParty party) { + String xml = ""; + // According EN16931 either GlobalID or seller assigned ID might be present for a Payee + if (party.getID() != null) { + xml += "" + XMLTools.encodeXML(party.getID()) + ""; + } + if ((party.getGlobalIDScheme() != null) && (party.getGlobalID() != null)) { + xml += "" + + XMLTools.encodeXML(party.getGlobalID()) + + ""; + } + xml += "" + XMLTools.encodeXML(party.getName()) + ""; - if (party.getLegalOrganisation() != null) { - xml += " "; - if (party.getLegalOrganisation().getSchemedID() != null) { - xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + ""; - } - xml += ""; - } + if (party.getLegalOrganisation() != null) { + xml += " "; + if (party.getLegalOrganisation().getSchemedID() != null) { + xml += "" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + ""; + } + xml += ""; + } - return xml; - } + return xml; + } - /*** - * returns the XML for a charge or allowance on item level - * @param allowance the allowance or charge on this item - * @param item the item - * @return CII XML - */ - protected String getAllowanceChargeStr(IZUGFeRDAllowanceCharge allowance, IAbsoluteValueProvider item) { - String percentage = ""; - String chargeIndicator = "false"; - if ((allowance.getPercent() != null) && (profile == Profiles.getByName("Extended"))) { - percentage = "" + vatFormat(allowance.getPercent()) + ""; - percentage += "" + item.getValue() + ""; - } - if (allowance.isCharge()) { - chargeIndicator = "true"; - } + /*** + * returns the XML for a charge or allowance on item level + * @param allowance the allowance or charge on this item + * @param item the item + * @return CII XML + */ + protected String getAllowanceChargeStr(IZUGFeRDAllowanceCharge allowance, IAbsoluteValueProvider item) { + String percentage = ""; + String chargeIndicator = "false"; + if ((allowance.getPercent() != null) && (profile == Profiles.getByName("Extended"))) { + percentage = "" + vatFormat(allowance.getPercent()) + ""; + percentage += "" + item.getValue() + ""; + } + if (allowance.isCharge()) { + chargeIndicator = "true"; + } - String reason = ""; - if ((allowance.getReason() != null) && (profile == Profiles.getByName("Extended") || profile == Profiles.getByName("XRechnung")) || profile == Profiles.getByName("EN16931")) { - reason = "" + XMLTools.encodeXML(allowance.getReason()) + ""; - } - String reasonCode = ""; - if (allowance.getReasonCode() != null) { - // only in XRechnung profile - reasonCode = "" + allowance.getReasonCode() + ""; - } - final String allowanceChargeStr = "" + - chargeIndicator + "" + percentage + - "" + priceFormat(allowance.getTotalAmount(item)) + "" + - reason + - reasonCode + - ""; - return allowanceChargeStr; - } + String reason = ""; + if ((allowance.getReason() != null) && (profile == Profiles.getByName("Extended") || profile == Profiles.getByName("XRechnung")) || profile == Profiles.getByName("EN16931")) { + reason = "" + XMLTools.encodeXML(allowance.getReason()) + ""; + } + String reasonCode = ""; + if (allowance.getReasonCode() != null) { + // only in XRechnung profile + reasonCode = "" + allowance.getReasonCode() + ""; + } + final String allowanceChargeStr = "" + + chargeIndicator + "" + percentage + + "" + priceFormat(allowance.getTotalAmount(item)) + "" + + reason + + reasonCode + + ""; + return allowanceChargeStr; + } - /*** - * returns the XML for a charge or allowance on item total level - * @param allowance the allowance or charge - * @param item the line - * @return CII XML - */ - protected String getItemTotalAllowanceChargeStr(IZUGFeRDAllowanceCharge allowance, IAbsoluteValueProvider item) { - String percentage = ""; - String chargeIndicator = "false"; - if ((allowance.getPercent() != null) && (profile == Profiles.getByName("Extended"))) { - percentage = "" + vatFormat(allowance.getPercent()) + ""; - percentage += "" + item.getValue() + ""; - } - if (allowance.isCharge()) { - chargeIndicator = "true"; - } + /*** + * returns the XML for a charge or allowance on item total level + * @param allowance the allowance or charge + * @param item the line + * @return CII XML + */ + protected String getItemTotalAllowanceChargeStr(IZUGFeRDAllowanceCharge allowance, IAbsoluteValueProvider item) { + String percentage = ""; + String chargeIndicator = "false"; + if ((allowance.getPercent() != null) && (profile == Profiles.getByName("Extended"))) { + percentage = "" + vatFormat(allowance.getPercent()) + ""; + percentage += "" + item.getValue() + ""; + } + if (allowance.isCharge()) { + chargeIndicator = "true"; + } - String reason = ""; - if ((allowance.getReason() != null) && (profile == Profiles.getByName("Extended") || profile == Profiles.getByName("XRechnung"))) { - reason = "" + XMLTools.encodeXML(allowance.getReason()) + ""; - } - String reasonCode = ""; - if ((allowance.getReasonCode() != null) && (profile == Profiles.getByName("XRechnung"))) { - // only in XRechnung profile - reasonCode = "" + allowance.getReasonCode() + ""; - } - final String itemTotalAllowanceChargeStr = "" + - chargeIndicator + "" + percentage + - "" + currencyFormat(allowance.getTotalAmount(item)) + "" + - reason + - reasonCode + - ""; - return itemTotalAllowanceChargeStr; - } + String reason = ""; + if ((allowance.getReason() != null) && (profile == Profiles.getByName("Extended") || profile == Profiles.getByName("XRechnung"))) { + reason = "" + XMLTools.encodeXML(allowance.getReason()) + ""; + } + String reasonCode = ""; + if ((allowance.getReasonCode() != null) && (profile == Profiles.getByName("XRechnung"))) { + // only in XRechnung profile + reasonCode = "" + allowance.getReasonCode() + ""; + } + final String itemTotalAllowanceChargeStr = "" + + chargeIndicator + "" + percentage + + "" + currencyFormat(allowance.getTotalAmount(item)) + "" + + reason + + reasonCode + + ""; + return itemTotalAllowanceChargeStr; + } - @Override - public void generateXML(IExportableTransaction trans) { - this.trans = trans; - this.calc = new TransactionCalculator(trans); + @Override + public void generateXML(IExportableTransaction trans) { + this.trans = trans; + this.calc = new TransactionCalculator(trans); - boolean hasDueDate = trans.getDueDate() != null; - final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); + boolean hasDueDate = trans.getDueDate() != null; + final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - String exemptionReason = ""; + String exemptionReason = ""; - if (trans.getPaymentTermDescription() != null) { - paymentTermsDescription = XMLTools.encodeXML(trans.getPaymentTermDescription()); - } + if (trans.getPaymentTermDescription() != null) { + paymentTermsDescription = XMLTools.encodeXML(trans.getPaymentTermDescription()); + } - if ((profile == Profiles.getByName("XRechnung")) && (trans.getCashDiscounts() != null) && (trans.getCashDiscounts().length > 0)) { - for (IZUGFeRDCashDiscount discount : trans.getCashDiscounts() - ) { - if (paymentTermsDescription == null) { - paymentTermsDescription = ""; - } - paymentTermsDescription += discount.getAsXRechnung(); - } - } else if ((paymentTermsDescription == null) && (trans.getDocumentCode() != DocumentCodeTypeConstants.CORRECTEDINVOICE) && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)) { - if (trans.getDueDate() != null) { - paymentTermsDescription = "Please remit until " + germanDateFormat.format(trans.getDueDate()); - } - } + if ((profile == Profiles.getByName("XRechnung")) && (trans.getCashDiscounts() != null) && (trans.getCashDiscounts().length > 0)) { + for (IZUGFeRDCashDiscount discount : trans.getCashDiscounts() + ) { + if (paymentTermsDescription == null) { + paymentTermsDescription = ""; + } + paymentTermsDescription += discount.getAsXRechnung(); + } + } else if ((paymentTermsDescription == null) && (trans.getDocumentCode() != DocumentCodeTypeConstants.CORRECTEDINVOICE) && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)) { + if (trans.getDueDate() != null) { + paymentTermsDescription = "Please remit until " + germanDateFormat.format(trans.getDueDate()); + } + } - String typecode = "380"; - if (trans.getDocumentCode() != null) { - typecode = trans.getDocumentCode(); - } - String xml = "" - + "" - + "" - + "\n"; - // + " - // "+testBooleanStr+"" - // + String typecode = "380"; + if (trans.getDocumentCode() != null) { + typecode = trans.getDocumentCode(); + } + String xml = "" + + "" + + "" + + "\n"; + // + " + // "+testBooleanStr+"" + // - if (getProfile() == Profiles.getByName("XRechnung")) { - xml += "\n" - + "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0\n" - + "\n"; - } - xml += - "" - + "" + getProfile().getID() + "" - + "" - + "" - + "" - + "" + XMLTools.encodeXML(trans.getNumber()) + "" - // + "RECHNUNG" - // + "380" - + "" + typecode + "" - + "" - + DATE.udtFormat(trans.getIssueDate()) + "" // date - + buildNotes(trans) + if (getProfile() == Profiles.getByName("XRechnung")) { + xml += "\n" + + "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0\n" + + "\n"; + } + xml += + "" + + "" + getProfile().getID() + "" + + "" + + "" + + "" + + "" + XMLTools.encodeXML(trans.getNumber()) + "" + // + "RECHNUNG" + // + "380" + + "" + typecode + "" + + "" + + DATE.udtFormat(trans.getIssueDate()) + "" // date + + buildNotes(trans) - + "" - + ""; - 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 = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; - } - final LineCalculator lc = new LineCalculator(currentItem); - if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) { - xml += "" + - "" - + "" + lineIDStr + "" - + buildItemNotes(currentItem) - + "" + + "" + + ""; + 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 = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; + } + final LineCalculator lc = new LineCalculator(currentItem); + if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) { + xml += "" + + "" + + "" + lineIDStr + "" + + buildItemNotes(currentItem) + + "" - + ""; - if ((currentItem.getProduct().getGlobalIDScheme() != null) && (currentItem.getProduct().getGlobalID() != null)) { - xml += "" + XMLTools.encodeXML(currentItem.getProduct().getGlobalID()) + ""; - } + + ""; + if ((currentItem.getProduct().getGlobalIDScheme() != null) && (currentItem.getProduct().getGlobalID() != null)) { + xml += "" + XMLTools.encodeXML(currentItem.getProduct().getGlobalID()) + ""; + } - if (currentItem.getProduct().getSellerAssignedID() != null) { - xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; - } - if (currentItem.getProduct().getBuyerAssignedID() != null) { - xml += "" - + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; - } - String allowanceChargeStr = ""; - if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { - for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { - allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem); - } - } - if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { - for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { - allowanceChargeStr += getAllowanceChargeStr(charge, currentItem); + if (currentItem.getProduct().getSellerAssignedID() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + ""; + } + if (currentItem.getProduct().getBuyerAssignedID() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + ""; + } + String allowanceChargeStr = ""; + if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) { + for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) { + allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem); + } + } + if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) { + for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) { + allowanceChargeStr += getAllowanceChargeStr(charge, currentItem); - } - } + } + } - String itemTotalAllowanceChargeStr = ""; - if (currentItem.getItemTotalAllowances() != null && currentItem.getItemTotalAllowances().length > 0) { - for (final IZUGFeRDAllowanceCharge itemTotalAllowance : currentItem.getItemTotalAllowances()) { - itemTotalAllowanceChargeStr += getItemTotalAllowanceChargeStr(itemTotalAllowance, currentItem); - } - } + String itemTotalAllowanceChargeStr = ""; + if (currentItem.getItemTotalAllowances() != null && currentItem.getItemTotalAllowances().length > 0) { + for (final IZUGFeRDAllowanceCharge itemTotalAllowance : currentItem.getItemTotalAllowances()) { + itemTotalAllowanceChargeStr += getItemTotalAllowanceChargeStr(itemTotalAllowance, currentItem); + } + } - xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + ""; - if (currentItem.getProduct().getDescription().length() > 0) { - xml += "" + - XMLTools.encodeXML(currentItem.getProduct().getDescription()) + - ""; - } - if (currentItem.getProduct().getClassifications() != null && currentItem.getProduct().getClassifications().length > 0) { - for (IDesignatedProductClassification classification : currentItem.getProduct().getClassifications()) { - xml += "" - + ""; - if (classification.getClassName() != null) { - xml += "" + XMLTools.encodeXML(classification.getClassName()) + ""; - } - xml += ""; - } - } - if (currentItem.getProduct().getAttributes() != null) { - for (Entry entry : currentItem.getProduct().getAttributes().entrySet()) { - xml += "" + - "" + XMLTools.encodeXML(entry.getKey()) + "" + - "" + XMLTools.encodeXML(entry.getValue()) + "" + - ""; - } - } - if (currentItem.getProduct().getCountryOfOrigin() != null) { - xml += "" + - XMLTools.encodeXML(currentItem.getProduct().getCountryOfOrigin()) + - ""; - } - xml += "" + xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + ""; + if (currentItem.getProduct().getDescription().length() > 0) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getDescription()) + + ""; + } + if (currentItem.getProduct().getClassifications() != null && currentItem.getProduct().getClassifications().length > 0) { + for (IDesignatedProductClassification classification : currentItem.getProduct().getClassifications()) { + xml += "" + + ""; + if (classification.getClassName() != null) { + xml += "" + XMLTools.encodeXML(classification.getClassName()) + ""; + } + xml += ""; + } + } + if (currentItem.getProduct().getAttributes() != null) { + for (Entry entry : currentItem.getProduct().getAttributes().entrySet()) { + xml += "" + + "" + XMLTools.encodeXML(entry.getKey()) + "" + + "" + XMLTools.encodeXML(entry.getValue()) + "" + + ""; + } + } + if (currentItem.getProduct().getCountryOfOrigin() != null) { + xml += "" + + XMLTools.encodeXML(currentItem.getProduct().getCountryOfOrigin()) + + ""; + } + xml += "" - + ""; - if (currentItem.getReferencedDocuments() != null) { - for (final IReferencedDocument currentReferencedDocument : currentItem.getReferencedDocuments()) { - xml += "" + - "" + XMLTools.encodeXML(currentReferencedDocument.getIssuerAssignedID()) + "" + - "" + XMLTools.encodeXML(currentReferencedDocument.getTypeCode()) + "" + - "" + XMLTools.encodeXML(currentReferencedDocument.getReferenceTypeCode()) + "" + - ""; - } - } - if (currentItem.getBuyerOrderReferencedDocumentLineID() != null) { - xml += " " - + "" + XMLTools.encodeXML(currentItem.getBuyerOrderReferencedDocumentLineID()) + "" - + ""; - } + + ""; + if (currentItem.getReferencedDocuments() != null) { + for (final IReferencedDocument currentReferencedDocument : currentItem.getReferencedDocuments()) { + xml += "" + + "" + XMLTools.encodeXML(currentReferencedDocument.getIssuerAssignedID()) + "" + + "" + XMLTools.encodeXML(currentReferencedDocument.getTypeCode()) + "" + + "" + XMLTools.encodeXML(currentReferencedDocument.getReferenceTypeCode()) + "" + + ""; + } + } + if (currentItem.getBuyerOrderReferencedDocumentLineID() != null) { + xml += " " + + "" + XMLTools.encodeXML(currentItem.getBuyerOrderReferencedDocumentLineID()) + "" + + ""; + } - if (!allowanceChargeStr.isEmpty()) { - xml += "" - + "" + priceFormat(lc.getPriceGross()) - + "" //currencyID=\"EUR\" - + "" + quantityFormat(currentItem.getBasisQuantity()) + "" - + allowanceChargeStr - // + "" - // + "false" - // + "0.6667" - // + "Rabatt" - // + "" - + ""; - } + if (!allowanceChargeStr.isEmpty()) { + xml += "" + + "" + priceFormat(lc.getPriceGross()) + + "" // currencyID=\"EUR\" + + "" + quantityFormat(currentItem.getBasisQuantity()) + "" + + allowanceChargeStr + // + "" + // + "false" + // + "0.6667" + // + "Rabatt" + // + "" + + ""; + } - xml += "" - + "" + priceFormat(lc.getPrice()) - + "" // currencyID=\"EUR\" - + "" + quantityFormat(currentItem.getBasisQuantity()) + "" - + "" - + "" - + "" - + "" - + quantityFormat(currentItem.getQuantity()) + "" - + "" - + "" - + "" - + "VAT" - + exemptionReason - + "" + currentItem.getProduct().getTaxCategoryCode() + "" - + "" - + vatFormat(currentItem.getProduct().getVATPercent()) + "" - + ""; - if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) { - xml += ""; - if (currentItem.getDetailedDeliveryPeriodFrom() != null) { - xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodFrom()) + ""; - } - if (currentItem.getDetailedDeliveryPeriodTo() != null) { - xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodTo()) + ""; - } - xml += ""; - } + xml += "" + + "" + priceFormat(lc.getPrice()) + + "" // currencyID=\"EUR\" + + "" + quantityFormat(currentItem.getBasisQuantity()) + "" + + "" + + "" + + "" + + "" + + quantityFormat(currentItem.getQuantity()) + "" + + "" + + "" + + "" + + "VAT" + + exemptionReason + + "" + currentItem.getProduct().getTaxCategoryCode() + "" + + "" + + vatFormat(currentItem.getProduct().getVATPercent()) + "" + + ""; + if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) { + xml += ""; + if (currentItem.getDetailedDeliveryPeriodFrom() != null) { + xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodFrom()) + ""; + } + if (currentItem.getDetailedDeliveryPeriodTo() != null) { + xml += "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodTo()) + ""; + } + xml += ""; + } - xml += itemTotalAllowanceChargeStr; + xml += itemTotalAllowanceChargeStr; - xml += "" - + "" + currencyFormat(lc.getItemTotalNetAmount()) - + "" // currencyID=\"EUR\" - + ""; - if (currentItem.getAdditionalReferences() != null) { - for (final IReferencedDocument currentReference : currentItem.getAdditionalReferences()) { - xml += "" + - "" + XMLTools.encodeXML(currentReference.getIssuerAssignedID()) + "" + - "130" + - "" + XMLTools.encodeXML(currentReference.getReferenceTypeCode()) + "" + - ""; - } - } else if (currentItem.getAdditionalReferencedDocumentID() != null) { - xml += "" + currentItem.getAdditionalReferencedDocumentID() + "130"; - } - xml += "" - + ""; - } + xml += "" + + "" + currencyFormat(lc.getItemTotalNetAmount()) + + "" // currencyID=\"EUR\" + + ""; + if (currentItem.getAdditionalReferences() != null) { + for (final IReferencedDocument currentReference : currentItem.getAdditionalReferences()) { + xml += "" + + "" + XMLTools.encodeXML(currentReference.getIssuerAssignedID()) + "" + + "130" + + "" + XMLTools.encodeXML(currentReference.getReferenceTypeCode()) + "" + + ""; + } + } else if (currentItem.getAdditionalReferencedDocumentID() != null) { + xml += "" + currentItem.getAdditionalReferencedDocumentID() + "130"; + } + xml += "" + + ""; + } - } + } - xml += ""; - if (trans.getReferenceNumber() != null) { - xml += "" + XMLTools.encodeXML(trans.getReferenceNumber()) + ""; + xml += ""; + if (trans.getReferenceNumber() != null) { + xml += "" + XMLTools.encodeXML(trans.getReferenceNumber()) + ""; - } - xml += "" - + getTradePartyAsXML(trans.getSender(), true, false) - + "" - + ""; - // + "GE2020211" - // + "4000001987658" + } + xml += "" + + getTradePartyAsXML(trans.getSender(), true, false) + + "" + + ""; + // + "GE2020211" + // + "4000001987658" - xml += getTradePartyAsXML(trans.getRecipient(), false, false); - xml += ""; + xml += getTradePartyAsXML(trans.getRecipient(), false, false); + xml += ""; - if (trans.getSellerOrderReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" - + ""; - } - if (trans.getBuyerOrderReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" - + ""; - } - if (trans.getContractReferencedDocument() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "" - + ""; - } + if (trans.getSellerOrderReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "" + + ""; + } + if (trans.getBuyerOrderReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "" + + ""; + } + if (trans.getContractReferencedDocument() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "" + + ""; + } - // Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung) - if (trans.getAdditionalReferencedDocuments() != null) { - for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) { - final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData())); - xml += "" - + "" + f.getFilename() + "" - + "916" - + "" + f.getDescription() + "" - + "" + documentContent + "" - + ""; - } - } + // Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung) + if (trans.getAdditionalReferencedDocuments() != null) { + for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) { + final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData())); + xml += "" + + "" + f.getFilename() + "" + + "916" + + "" + f.getDescription() + "" + + "" + documentContent + "" + + ""; + } + } - if (trans.getSpecifiedProcuringProjectID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + ""; - if (trans.getSpecifiedProcuringProjectName() != null) { - xml += "" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + ""; - } - xml += ""; - } - xml += ""; - xml += ""; + if (trans.getSpecifiedProcuringProjectID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + ""; + if (trans.getSpecifiedProcuringProjectName() != null) { + xml += "" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + ""; + } + xml += ""; + } + xml += ""; + xml += ""; - if (this.trans.getDeliveryAddress() != null) { - xml += "" + - getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) + - ""; - } + if (this.trans.getDeliveryAddress() != null) { + xml += "" + + getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) + + ""; + } - if (trans.getDeliveryDate() != null) { - xml += "" - + ""; - xml += DATE.udtFormat(trans.getDeliveryDate()); - xml += ""; - xml += ""; + if (trans.getDeliveryDate() != null) { + xml += "" + + ""; + xml += DATE.udtFormat(trans.getDeliveryDate()); + xml += ""; + xml += ""; - } - /* - * + "" + - * "20130603" + - * "2013-51112" + - * "" - */ - if (trans.getDespatchAdviceReferencedDocumentID() != null) { - xml += ""; - xml += "" + XMLTools.encodeXML(trans.getDespatchAdviceReferencedDocumentID()) + ""; - xml += ""; + } + /* + * + "" + + * "20130603" + + * "2013-51112" + + * "" + */ + if (trans.getDespatchAdviceReferencedDocumentID() != null) { + xml += ""; + xml += "" + XMLTools.encodeXML(trans.getDespatchAdviceReferencedDocumentID()) + ""; + xml += ""; - } + } - xml += ""; - xml += ""; + xml += ""; + xml += ""; - if ((trans.getCreditorReferenceID() != null) && (getProfile() != Profiles.getByName("Minimum"))) { - xml += "" + XMLTools.encodeXML(trans.getCreditorReferenceID()) + ""; - } - if ((trans.getNumber() != null) && (getProfile() != Profiles.getByName("Minimum"))) { - xml += "" + XMLTools.encodeXML(trans.getNumber()) + ""; - } - xml += "" + trans.getCurrency() + ""; - if (this.trans.getPayee() != null) { - xml += "" + - getTradePartyPayeeAsXML(this.trans.getPayee()) + - ""; - } + if ((trans.getCreditorReferenceID() != null) && (getProfile() != Profiles.getByName("Minimum"))) { + xml += "" + XMLTools.encodeXML(trans.getCreditorReferenceID()) + ""; + } + if ((trans.getNumber() != null) && (getProfile() != Profiles.getByName("Minimum"))) { + xml += "" + XMLTools.encodeXML(trans.getNumber()) + ""; + } + xml += "" + trans.getCurrency() + ""; + if (this.trans.getPayee() != null) { + xml += "" + + getTradePartyPayeeAsXML(this.trans.getPayee()) + + ""; + } - if (trans.getTradeSettlementPayment() != null) { - for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { - if (payment != null) { - hasDueDate = true; - if (getProfile() != Profiles.getByName("Minimum")) { - xml += payment.getSettlementXML(); - } - } - } - } - if (trans.getTradeSettlement() != null) { - for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { - if (payment != null) { - if (payment instanceof IZUGFeRDTradeSettlementPayment) { - hasDueDate = true; - } - if (getProfile() != Profiles.getByName("Minimum")) { - xml += payment.getSettlementXML(); - } - } - } - } - if ((trans.getDocumentCode() == DocumentCodeTypeConstants.CORRECTEDINVOICE) || (trans.getDocumentCode() == DocumentCodeTypeConstants.CREDITNOTE)) { - hasDueDate = false; - } + if (trans.getTradeSettlementPayment() != null) { + for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) { + if (payment != null) { + hasDueDate = true; + if (getProfile() != Profiles.getByName("Minimum")) { + xml += payment.getSettlementXML(); + } + } + } + } + if (trans.getTradeSettlement() != null) { + for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { + if (payment != null) { + if (payment instanceof IZUGFeRDTradeSettlementPayment) { + hasDueDate = true; + } + if (getProfile() != Profiles.getByName("Minimum")) { + xml += payment.getSettlementXML(); + } + } + } + } + if ((trans.getDocumentCode() == DocumentCodeTypeConstants.CORRECTEDINVOICE) || (trans.getDocumentCode() == DocumentCodeTypeConstants.CREDITNOTE)) { + hasDueDate = false; + } - final Map VATPercentAmountMap = calc.getVATPercentAmountMap(); - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); - if (amount != null) { - final String amountCategoryCode = amount.getCategoryCode(); - final String amountDueDateTypeCode = amount.getDueDateTypeCode(); - final boolean displayExemptionReason = CATEGORY_CODES_WITH_EXEMPTION_REASON.contains(amountCategoryCode); - if (getProfile() != Profiles.getByName("Minimum")) { - String exemptionReasonTextXML = ""; - if ((displayExemptionReason) && (amount.getVatExemptionReasonText() != null)) { - exemptionReasonTextXML = "" + XMLTools.encodeXML(amount.getVatExemptionReasonText()) + ""; + final Map VATPercentAmountMap = calc.getVATPercentAmountMap(); + for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); + if (amount != null) { + final String amountCategoryCode = amount.getCategoryCode(); + final String amountDueDateTypeCode = amount.getDueDateTypeCode(); + final boolean displayExemptionReason = CATEGORY_CODES_WITH_EXEMPTION_REASON.contains(amountCategoryCode); + if (getProfile() != Profiles.getByName("Minimum")) { + String exemptionReasonTextXML = ""; + if (displayExemptionReason && (amount.getVatExemptionReasonText() != null)) { + exemptionReasonTextXML = "" + XMLTools.encodeXML(amount.getVatExemptionReasonText()) + ""; - } + } - xml += "" - + "" + currencyFormat(amount.getCalculated()) - + "" //currencyID=\"EUR\" - + "VAT" - + exemptionReasonTextXML - + "" + currencyFormat(amount.getBasis()) + "" // currencyID=\"EUR\" - + "" + amountCategoryCode + "" - + (amountDueDateTypeCode != null ? "" + amountDueDateTypeCode + "" : "") - + "" - + vatFormat(currentTaxPercent) + ""; - } - } - } - if ((trans.getDetailedDeliveryPeriodFrom() != null) || (trans.getDetailedDeliveryPeriodTo() != null)) { - xml += ""; - if (trans.getDetailedDeliveryPeriodFrom() != null) { - xml += "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodFrom()) + ""; - } - if (trans.getDetailedDeliveryPeriodTo() != null) { - xml += "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodTo()) + ""; - } - xml += ""; - } + xml += "" + + "" + currencyFormat(amount.getCalculated()) + + "" // currencyID=\"EUR\" + + "VAT" + + exemptionReasonTextXML + + "" + currencyFormat(amount.getBasis()) + "" // currencyID=\"EUR\" + + "" + amountCategoryCode + "" + + (amountDueDateTypeCode != null ? "" + amountDueDateTypeCode + "" : "") + + "" + + vatFormat(currentTaxPercent) + ""; + } + } + } + if ((trans.getDetailedDeliveryPeriodFrom() != null) || (trans.getDetailedDeliveryPeriodTo() != null)) { + xml += ""; + if (trans.getDetailedDeliveryPeriodFrom() != null) { + xml += "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodFrom()) + ""; + } + if (trans.getDetailedDeliveryPeriodTo() != null) { + xml += "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodTo()) + ""; + } + xml += ""; + } - if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) { - if (profile == Profiles.getByName("XRechnung")) { - for (IZUGFeRDAllowanceCharge charge : trans.getZFCharges()) { - xml += "" + - "" + - "true" + - "" + - "" + currencyFormat(charge.getTotalAmount(calc)) + ""; - if (charge.getReason() != null) { - xml += "" + XMLTools.encodeXML(charge.getReason()) + ""; - } - if (charge.getReasonCode() != null) { - xml += "" + charge.getReasonCode() + ""; - } - xml += "" + - "VAT" + - "" + charge.getCategoryCode() + ""; - if (charge.getTaxPercent() != null) { - xml += "" + vatFormat(charge.getTaxPercent()) + ""; - } - xml += "" + - ""; - } - } else { - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - if (calc.getChargesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { - xml += "" + - "" + - "true" + - "" + - "" + currencyFormat(calc.getChargesForPercent(currentTaxPercent)) + "" + - "" + XMLTools.encodeXML(calc.getChargeReasonForPercent(currentTaxPercent)) + "" + - "" + - "VAT" + - "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + - "" + vatFormat(currentTaxPercent) + "" + - "" + - ""; - } - } - } - } + if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) { + if (profile == Profiles.getByName("XRechnung")) { + for (IZUGFeRDAllowanceCharge charge : trans.getZFCharges()) { + xml += "" + + "" + + "true" + + "" + + "" + currencyFormat(charge.getTotalAmount(calc)) + ""; + if (charge.getReason() != null) { + xml += "" + XMLTools.encodeXML(charge.getReason()) + ""; + } + if (charge.getReasonCode() != null) { + xml += "" + charge.getReasonCode() + ""; + } + xml += "" + + "VAT" + + "" + charge.getCategoryCode() + ""; + if (charge.getTaxPercent() != null) { + xml += "" + vatFormat(charge.getTaxPercent()) + ""; + } + xml += "" + + ""; + } + } else { + for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + if (calc.getChargesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { + xml += "" + + "" + + "true" + + "" + + "" + currencyFormat(calc.getChargesForPercent(currentTaxPercent)) + "" + + "" + XMLTools.encodeXML(calc.getChargeReasonForPercent(currentTaxPercent)) + "" + + "" + + "VAT" + + "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + + "" + vatFormat(currentTaxPercent) + "" + + "" + + ""; + } + } + } + } - if ((trans.getZFAllowances() != null) && (trans.getZFAllowances().length > 0)) { - if (profile == Profiles.getByName("XRechnung")) { - for (IZUGFeRDAllowanceCharge allowance : trans.getZFAllowances()) { - xml += "" + - "" + - "false" + - "" + - "" + currencyFormat(allowance.getTotalAmount(calc)) + ""; - if (allowance.getReason() != null) { - xml += "" + XMLTools.encodeXML(allowance.getReason()) + ""; - } - if (allowance.getReasonCode() != null) { - xml += "" + allowance.getReasonCode() + ""; - } - xml += "" + - "VAT" + - "" + allowance.getCategoryCode() + ""; - if (allowance.getTaxPercent() != null) { - xml += "" + vatFormat(allowance.getTaxPercent()) + ""; - } - xml += "" + - ""; - } - } else { - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - if (calc.getAllowancesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { - xml += "" + - "" + - "false" + - "" + - "" + currencyFormat(calc.getAllowancesForPercent(currentTaxPercent)) + "" + - "" + XMLTools.encodeXML(calc.getAllowanceReasonForPercent(currentTaxPercent)) + "" + - "" + - "VAT" + - "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + - "" + vatFormat(currentTaxPercent) + "" + - "" + - ""; - } - } - } - } + if ((trans.getZFAllowances() != null) && (trans.getZFAllowances().length > 0)) { + if (profile == Profiles.getByName("XRechnung")) { + for (IZUGFeRDAllowanceCharge allowance : trans.getZFAllowances()) { + xml += "" + + "" + + "false" + + "" + + "" + currencyFormat(allowance.getTotalAmount(calc)) + ""; + if (allowance.getReason() != null) { + xml += "" + XMLTools.encodeXML(allowance.getReason()) + ""; + } + if (allowance.getReasonCode() != null) { + xml += "" + allowance.getReasonCode() + ""; + } + xml += "" + + "VAT" + + "" + allowance.getCategoryCode() + ""; + if (allowance.getTaxPercent() != null) { + xml += "" + vatFormat(allowance.getTaxPercent()) + ""; + } + xml += "" + + ""; + } + } else { + for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + if (calc.getAllowancesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { + xml += "" + + "" + + "false" + + "" + + "" + currencyFormat(calc.getAllowancesForPercent(currentTaxPercent)) + "" + + "" + XMLTools.encodeXML(calc.getAllowanceReasonForPercent(currentTaxPercent)) + "" + + "" + + "VAT" + + "" + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "" + + "" + vatFormat(currentTaxPercent) + "" + + "" + + ""; + } + } + } + } - if ((trans.getPaymentTerms() == null) && (getProfile() != Profiles.getByName("Minimum")) && ((paymentTermsDescription != null) || (trans.getTradeSettlement() != null) || (hasDueDate))) { - xml += ""; + if ((trans.getPaymentTerms() == null) && (getProfile() != Profiles.getByName("Minimum")) && ((paymentTermsDescription != null) || (trans.getTradeSettlement() != null) || hasDueDate)) { + xml += ""; - if (paymentTermsDescription != null) { - xml += "" + paymentTermsDescription + ""; - } + if (paymentTermsDescription != null) { + xml += "" + paymentTermsDescription + ""; + } - if (trans.getTradeSettlement() != null) { - for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { - if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { - xml += payment.getPaymentXML(); - } - } - } + if (trans.getTradeSettlement() != null) { + for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { + if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { + xml += payment.getPaymentXML(); + } + } + } - if (trans.getDueDate() != null) { - xml += "" // $NON-NLS-2$ - + DATE.udtFormat(trans.getDueDate()) - + "";// 20130704 + if (trans.getDueDate() != null) { + xml += "" // $NON-NLS-2$ + + DATE.udtFormat(trans.getDueDate()) + + "";// 20130704 - } - xml += ""; - } else { - xml += buildPaymentTermsXml(); - } - if ((profile == Profiles.getByName("Extended")) && (trans.getCashDiscounts() != null) && (trans.getCashDiscounts().length > 0)) { - for (IZUGFeRDCashDiscount discount : trans.getCashDiscounts() - ) { - xml += discount.getAsCII(); - } - } + } + xml += ""; + } else { + xml += buildPaymentTermsXml(); + } + if ((profile == Profiles.getByName("Extended")) && (trans.getCashDiscounts() != null) && (trans.getCashDiscounts().length > 0)) { + for (IZUGFeRDCashDiscount discount : trans.getCashDiscounts() + ) { + xml += discount.getAsCII(); + } + } - final String allowanceTotalLine = "" + currencyFormat(calc.getAllowancesForPercent(null)) + ""; + final String allowanceTotalLine = "" + currencyFormat(calc.getAllowancesForPercent(null)) + ""; - final String chargesTotalLine = "" + currencyFormat(calc.getChargesForPercent(null)) + ""; + final String chargesTotalLine = "" + currencyFormat(calc.getChargesForPercent(null)) + ""; - xml += ""; - if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BASICWL"))) { - xml += "" + currencyFormat(calc.getTotal()) + ""; - xml += chargesTotalLine - + allowanceTotalLine; - } - xml += "" + currencyFormat(calc.getTaxBasis()) + "" - // // - // currencyID=\"EUR\" - + "" - + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + ""; - if (trans.getRoundingAmount() != null) { - xml += "" + currencyFormat(trans.getRoundingAmount()) + ""; - } + xml += ""; + if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BASICWL"))) { + xml += "" + currencyFormat(calc.getTotal()) + ""; + xml += chargesTotalLine + + allowanceTotalLine; + } + xml += "" + currencyFormat(calc.getTaxBasis()) + "" + // // + // currencyID=\"EUR\" + + "" + + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + ""; + if (trans.getRoundingAmount() != null) { + xml += "" + currencyFormat(trans.getRoundingAmount()) + ""; + } - xml += "" + currencyFormat(calc.getGrandTotal()) + ""; - // // - // currencyID=\"EUR\" - if (getProfile() != Profiles.getByName("Minimum")) { - xml += "" + currencyFormat(calc.getTotalPrepaid()) + ""; - } - xml += "" + currencyFormat(calc.getDuePayable()) + "" - + ""; - if (trans.getInvoiceReferencedDocumentID() != null) { - xml += "" - + "" - + XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + ""; - if (trans.getInvoiceReferencedIssueDate() != null) { - xml += "" - + DATE.qdtFormat(trans.getInvoiceReferencedIssueDate()) - + ""; - } - xml += ""; - } + xml += "" + currencyFormat(calc.getGrandTotal()) + ""; + // // + // currencyID=\"EUR\" + if (getProfile() != Profiles.getByName("Minimum")) { + xml += "" + currencyFormat(calc.getTotalPrepaid()) + ""; + } + xml += "" + currencyFormat(calc.getDuePayable()) + "" + + ""; + if (trans.getInvoiceReferencedDocumentID() != null) { + xml += "" + + "" + + XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + ""; + if (trans.getInvoiceReferencedIssueDate() != null) { + xml += "" + + DATE.qdtFormat(trans.getInvoiceReferencedIssueDate()) + + ""; + } + xml += ""; + } - xml += ""; - // + "\n" - // + "\n" - // + "\n" - // + "Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. - // 2013-51112 in Rechnung zu stellen:\n" - // + "\n" - // + "\n" - // + "\n"; + xml += ""; + // + "\n" + // + "\n" + // + "\n" + // + "Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. + // 2013-51112 in Rechnung zu stellen:\n" + // + "\n" + // + "\n" + // + "\n"; - xml += "" - + ""; + xml += "" + + ""; - final byte[] zugferdRaw; - zugferdRaw = xml.getBytes(StandardCharsets.UTF_8); + final byte[] zugferdRaw; + zugferdRaw = xml.getBytes(StandardCharsets.UTF_8); - zugferdData = XMLTools.removeBOM(zugferdRaw); - } + zugferdData = XMLTools.removeBOM(zugferdRaw); + } - protected String buildItemNotes(IZUGFeRDExportableItem currentItem) { - if (currentItem.getNotes() == null) { - return ""; - } - return Arrays.stream(currentItem.getNotes()) - .map(IncludedNote::unspecifiedNote) - .map(IncludedNote::toCiiXml) - .collect(Collectors.joining()); - } + protected String buildItemNotes(IZUGFeRDExportableItem currentItem) { + if (currentItem.getNotes() == null) { + return ""; + } + return Arrays.stream(currentItem.getNotes()) + .map(IncludedNote::unspecifiedNote) + .map(IncludedNote::toCiiXml) + .collect(Collectors.joining()); + } - protected String buildNotes(IExportableTransaction exportableTransaction) { - final List includedNotes = new ArrayList<>(); - Optional.ofNullable(exportableTransaction.getNotesWithSubjectCode()).ifPresent(includedNotes::addAll); + protected String buildNotes(IExportableTransaction exportableTransaction) { + final List includedNotes = new ArrayList<>(); + Optional.ofNullable(exportableTransaction.getNotesWithSubjectCode()).ifPresent(includedNotes::addAll); - if (exportableTransaction.getNotes() != null) { - for (final String currentNote : exportableTransaction.getNotes()) { - includedNotes.add(IncludedNote.unspecifiedNote(currentNote)); - } - } - if (exportableTransaction.rebateAgreementExists()) { - includedNotes.add(IncludedNote.discountBonusNote("Es bestehen Rabatt- und Bonusvereinbarungen.")); - } - Optional.ofNullable(exportableTransaction.getOwnOrganisationFullPlaintextInfo()) - .ifPresent(info -> includedNotes.add(IncludedNote.regulatoryNote(info))); + if (exportableTransaction.getNotes() != null) { + for (final String currentNote : exportableTransaction.getNotes()) { + includedNotes.add(IncludedNote.unspecifiedNote(currentNote)); + } + } + if (exportableTransaction.rebateAgreementExists()) { + includedNotes.add(IncludedNote.discountBonusNote("Es bestehen Rabatt- und Bonusvereinbarungen.")); + } + Optional.ofNullable(exportableTransaction.getOwnOrganisationFullPlaintextInfo()) + .ifPresent(info -> includedNotes.add(IncludedNote.regulatoryNote(info))); - Optional.ofNullable(exportableTransaction.getSubjectNote()) - .ifPresent(note -> includedNotes.add(IncludedNote.unspecifiedNote(note))); + Optional.ofNullable(exportableTransaction.getSubjectNote()) + .ifPresent(note -> includedNotes.add(IncludedNote.unspecifiedNote(note))); - return includedNotes.stream().map(IncludedNote::toCiiXml).collect(Collectors.joining("")); - } + return includedNotes.stream().map(IncludedNote::toCiiXml).collect(Collectors.joining("")); + } - @Override - public void setProfile(Profile p) { - profile = p; - } + @Override + public void setProfile(Profile p) { + profile = p; + } - private String buildPaymentTermsXml() { - final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms(); - if (paymentTerms == null) { - return ""; - } - String paymentTermsXml = ""; + private String buildPaymentTermsXml() { + final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms(); + if (paymentTerms == null) { + return ""; + } + String paymentTermsXml = ""; - final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms(); - final Date dueDate = paymentTerms.getDueDate(); - if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) { - throw new IllegalStateException( - "if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified"); - } - paymentTermsXml += "" + paymentTerms.getDescription() + ""; + final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms(); + final Date dueDate = paymentTerms.getDueDate(); + if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) { + throw new IllegalStateException( + "if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified"); + } + paymentTermsXml += "" + paymentTerms.getDescription() + ""; - if (dueDate != null) { - paymentTermsXml += ""; - paymentTermsXml += DATE.udtFormat(dueDate); - paymentTermsXml += ""; - } + if (dueDate != null) { + paymentTermsXml += ""; + paymentTermsXml += DATE.udtFormat(dueDate); + paymentTermsXml += ""; + } - if (trans.getTradeSettlement() != null) { - for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { - if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { - paymentTermsXml += payment.getPaymentXML(); - } - } - } + if (trans.getTradeSettlement() != null) { + for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { + if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) { + paymentTermsXml += payment.getPaymentXML(); + } + } + } - if (discountTerms != null) { - paymentTermsXml += ""; - final String currency = trans.getCurrency(); - final String basisAmount = currencyFormat(calc.getGrandTotal()); - paymentTermsXml += "" + basisAmount + ""; - paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString() - + ""; + if (discountTerms != null) { + paymentTermsXml += ""; + final String currency = trans.getCurrency(); + final String basisAmount = currencyFormat(calc.getGrandTotal()); + paymentTermsXml += "" + basisAmount + ""; + paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString() + + ""; - if (discountTerms.getBaseDate() != null) { - final Date baseDate = discountTerms.getBaseDate(); - paymentTermsXml += ""; - paymentTermsXml += DATE.udtFormat(baseDate); - paymentTermsXml += ""; + if (discountTerms.getBaseDate() != null) { + final Date baseDate = discountTerms.getBaseDate(); + paymentTermsXml += ""; + paymentTermsXml += DATE.udtFormat(baseDate); + paymentTermsXml += ""; - paymentTermsXml += "" - + discountTerms.getBasePeriodMeasure() + ""; - } + paymentTermsXml += "" + + discountTerms.getBasePeriodMeasure() + ""; + } - paymentTermsXml += ""; - } + paymentTermsXml += ""; + } - paymentTermsXml += ""; - return paymentTermsXml; - } + paymentTermsXml += ""; + return paymentTermsXml; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDDateFormat.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDDateFormat.java index d500357..c870205 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDDateFormat.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDDateFormat.java @@ -1,41 +1,43 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; +import org.mustangproject.ZUGFeRD.model.DateTimeTypeConstants; + import java.text.SimpleDateFormat; import java.util.Date; -import org.mustangproject.ZUGFeRD.model.DateTimeTypeConstants; - public enum ZUGFeRDDateFormat { - MONTH_OF_YEAR(DateTimeTypeConstants.MONTH, new SimpleDateFormat("yyyyMM")), - WEEK_OF_YEAR(DateTimeTypeConstants.WEEK, new SimpleDateFormat("yyyyww")), - DATE(DateTimeTypeConstants.DATE, new SimpleDateFormat("yyyyMMdd")); + MONTH_OF_YEAR(DateTimeTypeConstants.MONTH, new SimpleDateFormat("yyyyMM")), + WEEK_OF_YEAR(DateTimeTypeConstants.WEEK, new SimpleDateFormat("yyyyww")), + DATE(DateTimeTypeConstants.DATE, new SimpleDateFormat("yyyyMMdd")); - private String dateTimeType; - private SimpleDateFormat formatter; - private static final String QDT_FORMAT = "%s"; - private static final String UDT_FORMAT = "%s"; + private String dateTimeType; + private SimpleDateFormat formatter; + private static final String QDT_FORMAT = "%s"; + private static final String UDT_FORMAT = "%s"; - private ZUGFeRDDateFormat(String dateTimeType, SimpleDateFormat formatter) { - this.dateTimeType = dateTimeType; - this.formatter = formatter; - } + private ZUGFeRDDateFormat(String dateTimeType, SimpleDateFormat formatter) { + this.dateTimeType = dateTimeType; + this.formatter = formatter; + } - public String getDateTimeType() { - return dateTimeType; - } + public String getDateTimeType() { + return dateTimeType; + } - public SimpleDateFormat getFormatter() { - return formatter; - } - - public String simpleFormat(Date date){ - return getFormatter().format(date); - } - public String qdtFormat(Date date){ - return String.format(QDT_FORMAT, getDateTimeType(), getFormatter().format(date)); - } - public String udtFormat(Date date){ - return String.format(UDT_FORMAT, getDateTimeType(), getFormatter().format(date)); - } + public SimpleDateFormat getFormatter() { + return formatter; + } + + public String simpleFormat(Date date) { + return getFormatter().format(date); + } + + public String qdtFormat(Date date) { + return String.format(QDT_FORMAT, getDateTimeType(), getFormatter().format(date)); + } + + public String udtFormat(Date date) { + return String.format(UDT_FORMAT, getDateTimeType(), getFormatter().format(date)); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA1.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA1.java index 0a5066e..af24c6b 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA1.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA1.java @@ -19,115 +19,124 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; -import java.io.IOException; -import java.io.InputStream; - +import jakarta.activation.DataSource; import org.apache.pdfbox.preflight.PreflightDocument; import org.apache.pdfbox.preflight.ValidationResult; import org.apache.pdfbox.preflight.exception.ValidationException; import org.apache.pdfbox.preflight.parser.PreflightParser; import org.mustangproject.EStandard; -import jakarta.activation.DataSource; +import java.io.IOException; +import java.io.InputStream; public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 { - private static boolean isValidA1(DataSource dataSource) throws IOException { - return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource)); - } + private static boolean isValidA1(DataSource dataSource) throws IOException { + return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource)); + } - private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException { - /* - * Parse the PDF file with PreflightParser that inherits from the - * NonSequentialParser. Some additional controls are present to check a set of - * PDF/A requirements. (Stream length consistency, EOL after some Keyword...) - */ - // might add a Format.PDF_A1A as parameter and iterate through A1 and A3 + private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException { + /* + * Parse the PDF file with PreflightParser that inherits from the + * NonSequentialParser. Some additional controls are present to check a set of + * PDF/A requirements. (Stream length consistency, EOL after some Keyword...) + */ + // might add a Format.PDF_A1A as parameter and iterate through A1 and A3 - try (PreflightDocument document = (PreflightDocument) parser.parse()) { - /* - * Once the syntax validation is done, the parser can provide a - * PreflightDocument (that inherits from PDDocument) This document process the - * end of PDF/A validation. - */ + try (PreflightDocument document = (PreflightDocument) parser.parse()) { + /* + * Once the syntax validation is done, the parser can provide a + * PreflightDocument (that inherits from PDDocument) This document process the + * end of PDF/A validation. + */ - ValidationResult res = document.validate(); + ValidationResult res = document.validate(); - // Get validation result - return res.isValid(); - } catch (ValidationException e) { - /* - * the parse method can throw a SyntaxValidationException if the PDF file can't - * be parsed. In this case, the exception contains an instance of - * ValidationResult - */ - return false; - } - } + // Get validation result + return res.isValid(); + } catch (ValidationException e) { + /* + * the parse method can throw a SyntaxValidationException if the PDF file can't + * be parsed. In this case, the exception contains an instance of + * ValidationResult + */ + return false; + } + } - @Override - public ZUGFeRDExporterFromA1 setProfile(Profile p) { - return (ZUGFeRDExporterFromA1)super.setProfile(p); - } - @Override - public ZUGFeRDExporterFromA1 setProfile(String profileName) { - return (ZUGFeRDExporterFromA1)super.setProfile(profileName); - } + @Override + public ZUGFeRDExporterFromA1 setProfile(Profile p) { + return (ZUGFeRDExporterFromA1) super.setProfile(p); + } - @Override - public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { - if (!ignorePDFAErrors && !isValidA1(dataSource)) { - throw new IOException("File is not a valid PDF/A-1 input file"); - } - return true; - } + @Override + public ZUGFeRDExporterFromA1 setProfile(String profileName) { + return (ZUGFeRDExporterFromA1) super.setProfile(profileName); + } + + @Override + public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { + if (!ignorePDFAErrors && !isValidA1(dataSource)) { + throw new IOException("File is not a valid PDF/A-1 input file"); + } + return true; + } - @Override - public ZUGFeRDExporterFromA1 load(String pdfFilename) throws IOException { - return (ZUGFeRDExporterFromA1) super.load(pdfFilename); - } - @Override - public ZUGFeRDExporterFromA1 load(byte[] pdfBinary) throws IOException { - return (ZUGFeRDExporterFromA1) super.load(pdfBinary); - } - @Override - public ZUGFeRDExporterFromA1 load(InputStream pdfSource) throws IOException{ - return (ZUGFeRDExporterFromA1) super.load(pdfSource); - } - @Override - public ZUGFeRDExporterFromA1 setCreator(String creator) { - return (ZUGFeRDExporterFromA1) super.setCreator(creator); - } - @Override - public ZUGFeRDExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) { - return (ZUGFeRDExporterFromA1) super.setConformanceLevel(newLevel); - } - @Override - public ZUGFeRDExporterFromA1 setProducer(String producer){ - return (ZUGFeRDExporterFromA1) super.setProducer(producer); - } - @Override - public ZUGFeRDExporterFromA1 setZUGFeRDVersion(EStandard est, int version){ - return (ZUGFeRDExporterFromA1) super.setZUGFeRDVersion(est, version); - } - @Override - public ZUGFeRDExporterFromA1 setZUGFeRDVersion(int version){ - return (ZUGFeRDExporterFromA1) super.setZUGFeRDVersion(version); - } - @Override - public ZUGFeRDExporterFromA1 setXML(byte[] zugferdData) throws IOException{ - return (ZUGFeRDExporterFromA1) super.setXML(zugferdData); - } + @Override + public ZUGFeRDExporterFromA1 load(String pdfFilename) throws IOException { + return (ZUGFeRDExporterFromA1) super.load(pdfFilename); + } - @Override - public ZUGFeRDExporterFromA1 disableAutoClose(boolean disableAutoClose){ - return (ZUGFeRDExporterFromA1) super.disableAutoClose(disableAutoClose); - } - public ZUGFeRDExporterFromA1 convertOnly() { - setAttachZUGFeRDHeaders(false); - return this; - } + @Override + public ZUGFeRDExporterFromA1 load(byte[] pdfBinary) throws IOException { + return (ZUGFeRDExporterFromA1) super.load(pdfBinary); + } + + @Override + public ZUGFeRDExporterFromA1 load(InputStream pdfSource) throws IOException { + return (ZUGFeRDExporterFromA1) super.load(pdfSource); + } + + @Override + public ZUGFeRDExporterFromA1 setCreator(String creator) { + return (ZUGFeRDExporterFromA1) super.setCreator(creator); + } + + @Override + public ZUGFeRDExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) { + return (ZUGFeRDExporterFromA1) super.setConformanceLevel(newLevel); + } + + @Override + public ZUGFeRDExporterFromA1 setProducer(String producer) { + return (ZUGFeRDExporterFromA1) super.setProducer(producer); + } + + @Override + public ZUGFeRDExporterFromA1 setZUGFeRDVersion(EStandard est, int version) { + return (ZUGFeRDExporterFromA1) super.setZUGFeRDVersion(est, version); + } + + @Override + public ZUGFeRDExporterFromA1 setZUGFeRDVersion(int version) { + return (ZUGFeRDExporterFromA1) super.setZUGFeRDVersion(version); + } + + @Override + public ZUGFeRDExporterFromA1 setXML(byte[] zugferdData) throws IOException { + return (ZUGFeRDExporterFromA1) super.setXML(zugferdData); + } + + @Override + public ZUGFeRDExporterFromA1 disableAutoClose(boolean disableAutoClose) { + return (ZUGFeRDExporterFromA1) super.disableAutoClose(disableAutoClose); + } + + public ZUGFeRDExporterFromA1 convertOnly() { + setAttachZUGFeRDHeaders(false); + return this; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java index dea69a6..854f813 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java @@ -20,26 +20,10 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Map; - -import javax.xml.transform.TransformerException; - +import jakarta.activation.DataSource; +import jakarta.activation.FileDataSource; import org.apache.pdfbox.Loader; -import org.apache.pdfbox.cos.COSArray; -import org.apache.pdfbox.cos.COSBase; -import org.apache.pdfbox.cos.COSDictionary; -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.cos.COSObject; +import org.apache.pdfbox.cos.*; import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.pdfwriter.compress.CompressParameters; import org.apache.pdfbox.pdmodel.PDDocument; @@ -72,866 +56,869 @@ import org.mustangproject.EStandard; import org.mustangproject.FileAttachment; -import jakarta.activation.DataSource; -import jakarta.activation.FileDataSource; +import javax.xml.transform.TransformerException; +import java.io.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporter { - private boolean isFacturX = true; + private boolean isFacturX = true; - public static final int DefaultZUGFeRDVersion = 2; - protected boolean ignorePDFAErrors = false; + public static final int DefaultZUGFeRDVersion = 2; + protected boolean ignorePDFAErrors = false; - public ZUGFeRDExporterFromA3 ignorePDFAErrors() { - this.ignorePDFAErrors = true; - return this; - } + public ZUGFeRDExporterFromA3 ignorePDFAErrors() { + this.ignorePDFAErrors = true; + return this; + } - protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE; - protected ArrayList fileAttachments = new ArrayList<>(); + protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE; + protected ArrayList fileAttachments = new ArrayList<>(); - /** - * This flag controls whether or not the metadata is overwritten, or kind of merged. - * The merging probably needs to be overhauled, but for my purpose it was good enough. - */ - protected boolean overwrite = true; + /** + * This flag controls whether or not the metadata is overwritten, or kind of merged. + * The merging probably needs to be overhauled, but for my purpose it was good enough. + */ + protected boolean overwrite = true; - private boolean disableAutoClose; - private boolean fileAttached = false; - private Profile profile = null; - protected boolean documentPrepared = false; + private boolean disableAutoClose; + private boolean fileAttached = false; + private Profile profile = null; + protected boolean documentPrepared = false; - /** - * Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set, - * in which case passing a IZUGFeRDExportableTransaction is not necessary. By - * default it is null meaning the caller needs to pass a - * IZUGFeRDExportableTransaction for the XML to be populated. - */ - protected PDMetadata metadata = null; - protected XMPMetadata xmp = null; - /** - * Producer attribute for PDF - */ - protected String producer = "mustangproject"; - /** - * Author/Creator attribute for PDF - */ - protected String creator = "mustangproject"; - /** - * CreatorTool - */ - protected String creatorTool = "mustangproject"; + /** + * Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set, + * in which case passing a IZUGFeRDExportableTransaction is not necessary. By + * default it is null meaning the caller needs to pass a + * IZUGFeRDExportableTransaction for the XML to be populated. + */ + protected PDMetadata metadata = null; + protected XMPMetadata xmp = null; + /** + * Producer attribute for PDF + */ + protected String producer = "mustangproject"; + /** + * Author/Creator attribute for PDF + */ + protected String creator = "mustangproject"; + /** + * CreatorTool + */ + protected String creatorTool = "mustangproject"; - /** - * @deprecated author is never set yet - */ - @Deprecated - protected String author; - /** - * @deprecated title is never set yet - */ - @Deprecated - protected String title; - /** - * @deprecated subject is never set yet - */ - @Deprecated - protected String subject; + /** + * @deprecated author is never set yet + */ + @Deprecated + protected String author; + /** + * @deprecated title is never set yet + */ + @Deprecated + protected String title; + /** + * @deprecated subject is never set yet + */ + @Deprecated + protected String subject; - protected PDDocument doc; + protected PDDocument doc; - protected int ZFVersion = DefaultZUGFeRDVersion; - private boolean attachZUGFeRDHeaders = true; + protected int ZFVersion = DefaultZUGFeRDVersion; + private boolean attachZUGFeRDHeaders = true; - // Specific metaData version in case of XRechnung. We need it to be settable - // by the caller if necessary. - protected String XRechnungVersion = null; // Default XRechnung as of late 2021 is 2p0 + // Specific metaData version in case of XRechnung. We need it to be settable + // by the caller if necessary. + protected String XRechnungVersion = null; // Default XRechnung as of late 2021 is 2p0 - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfFilename filename of an PDF/A1 compliant document - */ - public ZUGFeRDExporterFromA3 load(String pdfFilename) throws IOException { + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfFilename filename of an PDF/A1 compliant document + */ +public ZUGFeRDExporterFromA3 load(String pdfFilename) throws IOException { - ensurePDFIsValid(new FileDataSource(pdfFilename)); - try (FileInputStream pdf = new FileInputStream(pdfFilename)) { - return load(readAllBytes(pdf)); - } - } + ensurePDFIsValid(new FileDataSource(pdfFilename)); + try (FileInputStream pdf = new FileInputStream(pdfFilename)) { + return load(readAllBytes(pdf)); + } + } - public IXMLProvider getProvider() { - return xmlProvider; - } + public IXMLProvider getProvider() { + return xmlProvider; + } - public ZUGFeRDExporterFromA3 setProfile(Profile p) { - this.profile = p; - if (xmlProvider != null) { - xmlProvider.setProfile(p); - } - return this; - } + public ZUGFeRDExporterFromA3 setProfile(Profile p) { + this.profile = p; + if (xmlProvider != null) { + xmlProvider.setProfile(p); + } + return this; + } - public ZUGFeRDExporterFromA3 setProfile(String profilename) { - this.profile = Profiles.getByName(profilename); + public ZUGFeRDExporterFromA3 setProfile(String profilename) { + this.profile = Profiles.getByName(profilename); - if (xmlProvider != null) { - xmlProvider.setProfile(this.profile); - } - return this; - } + if (xmlProvider != null) { + xmlProvider.setProfile(this.profile); + } + return this; + } - public ZUGFeRDExporterFromA3 addAdditionalFile(String name, byte[] content) { - fileAttachments.add(new FileAttachment(name, "text/xml", "Supplement", content).setDescription("ZUGFeRD extension/additional data")); - return this; - } + public ZUGFeRDExporterFromA3 addAdditionalFile(String name, byte[] content) { + fileAttachments.add(new FileAttachment(name, "text/xml", "Supplement", content).setDescription("ZUGFeRD extension/additional data")); + return this; + } - /*** - * internal helper function: get namespace for given zugferd or factur-x version - * @param ver the ZUGFeRD version - * @return the URN of the namespace - */ - public String getNamespaceForVersion(int ver) { - if (isFacturX) { - return "urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#"; - } else if (ver == 1) { - return "urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#"; - } else if (ver == 2) { - return "urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#"; - } else { - throw new IllegalArgumentException("Version not supported"); - } - } + /*** + * internal helper function: get namespace for given zugferd or factur-x version + * @param ver the ZUGFeRD version + * @return the URN of the namespace + */ + public String getNamespaceForVersion(int ver) { + if (isFacturX) { + return "urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#"; + } else if (ver == 1) { + return "urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#"; + } else if (ver == 2) { + return "urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#"; + } else { + throw new IllegalArgumentException("Version not supported"); + } + } - /*** - * internal helper: returns the namespace prefix for the given zf/fx version number - * @param ver the zf/fx version - * @return the namespace prefix as string, without colon - */ - public String getPrefixForVersion(int ver) { - if (isFacturX) { - return "fx"; - } else { - return "zf"; - } - } + /*** + * internal helper: returns the namespace prefix for the given zf/fx version number + * @param ver the zf/fx version + * @return the namespace prefix as string, without colon + */ + public String getPrefixForVersion(int ver) { + if (isFacturX) { + return "fx"; + } else { + return "zf"; + } + } - /*** - * internal helper: return the name of the file attachment for the given zf/fx version - * @param ver the zf/fx version - * @param profile which profile to be used, e.g. Profiles.getByName("EN16931") - * @return the filename of the file to be embedded - */ - public String getFilenameForVersion(int ver, Profile profile) { - if (profile.getName().equals("XRECHNUNG")) { - return "xrechnung.xml"; - } - if (isFacturX) { - return "factur-x.xml"; - } else { - if (ver == 1) { - return "ZUGFeRD-invoice.xml"; - } else { - return "zugferd-invoice.xml"; - } - } - } + /*** + * internal helper: return the name of the file attachment for the given zf/fx version + * @param ver the zf/fx version + * @param profile which profile to be used, e.g. Profiles.getByName("EN16931") + * @return the filename of the file to be embedded + */ + public String getFilenameForVersion(int ver, Profile profile) { + if (profile.getName().equals("XRECHNUNG")) { + return "xrechnung.xml"; + } + if (isFacturX) { + return "factur-x.xml"; + } else { + if (ver == 1) { + return "ZUGFeRD-invoice.xml"; + } else { + return "zugferd-invoice.xml"; + } + } + } - /** - * Factur-X is now set by default since ZF 2.1, you have to disable it if you dont wont it - * Generate ZF2.1 files with filename factur-x.xml - * - * @return this (fluent setter) - * @deprecated It's now the default anyway - */ - @Deprecated - public ZUGFeRDExporterFromA3 setFacturX() { - isFacturX = true; - return this; - } + /** + * Factur-X is now set by default since ZF 2.1, you have to disable it if you dont wont it + * Generate ZF2.1 files with filename factur-x.xml + * + * @return this (fluent setter) + * @deprecated It's now the default anyway + */ + @Deprecated + public ZUGFeRDExporterFromA3 setFacturX() { + isFacturX = true; + return this; + } - /** - * Sets a specific XRechnung version from outside. This version needs to be present in the - * meta-data as well. The caller may wish to generate a specific version of XRechnung - * depending on the time period etc. - * - * @param XRechnungVersion the XRechnung version - */ - public void setXRechnungSpecificVersion(String XRechnungVersion) { - this.XRechnungVersion = XRechnungVersion; - } + /** + * Sets a specific XRechnung version from outside. This version needs to be present in the + * meta-data as well. The caller may wish to generate a specific version of XRechnung + * depending on the time period etc. + * + * @param XRechnungVersion the XRechnung version + */ + public void setXRechnungSpecificVersion(String XRechnungVersion) { + this.XRechnungVersion = XRechnungVersion; + } - /*** - * Generate ZF2.0/2.1 files with filename zugferd-invoice.xml instead of factur-x.xml - */ - public IZUGFeRDExporter disableFacturX() { - isFacturX = false; - return this; - } + /*** + * Generate ZF2.0/2.1 files with filename zugferd-invoice.xml instead of factur-x.xml + */ + public IZUGFeRDExporter disableFacturX() { + isFacturX = false; + return this; + } - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfBinary binary of a PDF/A1 compliant document - */ - public ZUGFeRDExporterFromA3 load(byte[] pdfBinary) throws IOException { - ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); - doc = Loader.loadPDF(pdfBinary); - return this; - } + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfBinary binary of a PDF/A1 compliant document + */ + public ZUGFeRDExporterFromA3 load(byte[] pdfBinary) throws IOException { + ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); + doc = Loader.loadPDF(pdfBinary); + return this; + } - public ZUGFeRDExporterFromA3() { - super(); - setZUGFeRDVersion(ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion); + public ZUGFeRDExporterFromA3() { + super(); + setZUGFeRDVersion(ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion); - } + } - public void attachFile(FileAttachment file) { - fileAttachments.add(file); - } + public void attachFile(FileAttachment file) { + fileAttachments.add(file); + } - public void attachFile(String filename, byte[] data, String mimetype, String relation) { - FileAttachment fa = new FileAttachment(filename, mimetype, relation, data); - fileAttachments.add(fa); - } + public void attachFile(String filename, byte[] data, String mimetype, String relation) { + FileAttachment fa = new FileAttachment(filename, mimetype, relation, data); + fileAttachments.add(fa); + } - /*** - * Perform the final export to a now ZUGFeRD-enriched PDF file - * @param ZUGFeRDfilename the pdf file name - * @throws IOException if anything is wrong in the target location - */ - @Override - public void export(String ZUGFeRDfilename) throws IOException { - if (!documentPrepared) { - prepareDocument(); - } - if ((!fileAttached) && (attachZUGFeRDHeaders)) { - throw new IOException( - "File must be attached (usually with setTransaction) before perfoming this operation"); - } - doc.save(ZUGFeRDfilename, CompressParameters.NO_COMPRESSION); - if (!disableAutoClose) { - close(); - } - } + /*** + * Perform the final export to a now ZUGFeRD-enriched PDF file + * @param ZUGFeRDfilename the pdf file name + * @throws IOException if anything is wrong in the target location + */ + @Override + public void export(String ZUGFeRDfilename) throws IOException { + if (!documentPrepared) { + prepareDocument(); + } + if ((!fileAttached) && attachZUGFeRDHeaders) { + throw new IOException( + "File must be attached (usually with setTransaction) before perfoming this operation"); + } + doc.save(ZUGFeRDfilename, CompressParameters.NO_COMPRESSION); + if (!disableAutoClose) { + close(); + } + } - @Override - public void close() throws IOException { - if (doc != null) { - doc.close(); - } - } + @Override + public void close() throws IOException { + if (doc != null) { + doc.close(); + } + } - /*** - * Perform the final export to a now ZUGFeRD-enriched PDF file as OutputStream - * @param output the OutputStream - * @throws IOException if anything is wrong in the OutputStream - */ - @Override - public void export(OutputStream output) throws IOException { - if (!documentPrepared) { - prepareDocument(); - } - if ((!fileAttached) && (attachZUGFeRDHeaders)) { - throw new IOException( - "File must be attached (usually with setTransaction) before perfoming this operation"); - } - doc.save(output, CompressParameters.NO_COMPRESSION); - if (!disableAutoClose) { - close(); - } - } + /*** + * Perform the final export to a now ZUGFeRD-enriched PDF file as OutputStream + * @param output the OutputStream + * @throws IOException if anything is wrong in the OutputStream + */ + @Override + public void export(OutputStream output) throws IOException { + if (!documentPrepared) { + prepareDocument(); + } + if ((!fileAttached) && attachZUGFeRDHeaders) { + throw new IOException( + "File must be attached (usually with setTransaction) before perfoming this operation"); + } + doc.save(output, CompressParameters.NO_COMPRESSION); + if (!disableAutoClose) { + close(); + } + } - /** - * Embeds an external file (generic - any type allowed) in the PDF. - * The embedding is done in the default PDF document. - * - * @param filename name of the file that will become attachment name in the PDF - * @param relationship how the file relates to the content, e.g. "Alternative" - * @param description Human-readable description of the file content - * @param subType type of the data e.g. could be "text/xml" - mime like - * @param data the binary data of the file/attachment - * @throws java.io.IOException if anything is wrong with filename - */ - public void PDFAttachGenericFile(String filename, String relationship, String description, - String subType, byte[] data) throws IOException { - PDFAttachGenericFile(this.doc, filename, relationship, description, subType, data); - } + /** + * Embeds an external file (generic - any type allowed) in the PDF. + * The embedding is done in the default PDF document. + * + * @param filename name of the file that will become attachment name in the PDF + * @param relationship how the file relates to the content, e.g. "Alternative" + * @param description Human-readable description of the file content + * @param subType type of the data e.g. could be "text/xml" - mime like + * @param data the binary data of the file/attachment + * @throws java.io.IOException if anything is wrong with filename + */ + public void PDFAttachGenericFile(String filename, String relationship, String description, + String subType, byte[] data) throws IOException { + PDFAttachGenericFile(this.doc, filename, relationship, description, subType, data); + } - /** - * Embeds an external file (generic - any type allowed) in the PDF. - * - * @param doc PDDocument to attach the file to. - * @param filename name of the file that will become attachment name in the PDF - * @param relationship how the file relates to the content, e.g. "Alternative" - * @param description Human-readable description of the file content - * @param subType type of the data e.g. could be "text/xml" - mime like - * @param data the binary data of the file/attachment - * @throws java.io.IOException if anything is wrong with filename - */ - public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description, - String subType, byte[] data) throws IOException { - fileAttached = true; + /** + * Embeds an external file (generic - any type allowed) in the PDF. + * + * @param doc PDDocument to attach the file to. + * @param filename name of the file that will become attachment name in the PDF + * @param relationship how the file relates to the content, e.g. "Alternative" + * @param description Human-readable description of the file content + * @param subType type of the data e.g. could be "text/xml" - mime like + * @param data the binary data of the file/attachment + * @throws java.io.IOException if anything is wrong with filename + */ + public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description, + String subType, byte[] data) throws IOException { + fileAttached = true; - PDComplexFileSpecification fs = new PDComplexFileSpecification(); - fs.setFile(filename); + PDComplexFileSpecification fs = new PDComplexFileSpecification(); + fs.setFile(filename); - COSDictionary dict = fs.getCOSObject(); - dict.setName("AFRelationship", relationship); - dict.setString("UF", filename); - dict.setString("Desc", description); + COSDictionary dict = fs.getCOSObject(); + dict.setName("AFRelationship", relationship); + dict.setString("UF", filename); + dict.setString("Desc", description); - ByteArrayInputStream fakeFile = new ByteArrayInputStream(data); - PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile); -// ef.addCompression(); - ef.setSubtype(subType); - ef.setSize(data.length); - ef.setCreationDate(new GregorianCalendar()); + ByteArrayInputStream fakeFile = new ByteArrayInputStream(data); + PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile); +// ef.addCompression(); + ef.setSubtype(subType); + ef.setSize(data.length); + ef.setCreationDate(new GregorianCalendar()); - ef.setModDate(Calendar.getInstance()); + ef.setModDate(Calendar.getInstance()); - fs.setEmbeddedFile(ef); + fs.setEmbeddedFile(ef); - // In addition make sure the embedded file is set under /UF - dict = fs.getCOSObject(); - COSDictionary efDict = (COSDictionary) dict.getDictionaryObject(COSName.EF); - COSBase lowerLevelFile = efDict.getItem(COSName.F); - efDict.setItem(COSName.UF, lowerLevelFile); + // In addition make sure the embedded file is set under /UF + dict = fs.getCOSObject(); + COSDictionary efDict = (COSDictionary) dict.getDictionaryObject(COSName.EF); + COSBase lowerLevelFile = efDict.getItem(COSName.F); + efDict.setItem(COSName.UF, lowerLevelFile); - // now add the entry to the embedded file tree and set in the document. - PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); - PDEmbeddedFilesNameTreeNode efTree = names.getEmbeddedFiles(); - if (efTree == null) { - efTree = new PDEmbeddedFilesNameTreeNode(); - } + // now add the entry to the embedded file tree and set in the document. + PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); + PDEmbeddedFilesNameTreeNode efTree = names.getEmbeddedFiles(); + if (efTree == null) { + efTree = new PDEmbeddedFilesNameTreeNode(); + } - Map namesMap = new HashMap<>(); + Map namesMap = new HashMap<>(); - Map oldNamesMap = efTree.getNames(); - if (oldNamesMap != null) { - for (String key : oldNamesMap.keySet()) { - namesMap.put(key, oldNamesMap.get(key)); - } - } - namesMap.put(filename, fs); - efTree.setNames(namesMap); + Map oldNamesMap = efTree.getNames(); + if (oldNamesMap != null) { + for (String key : oldNamesMap.keySet()) { + namesMap.put(key, oldNamesMap.get(key)); + } + } + namesMap.put(filename, fs); + efTree.setNames(namesMap); - names.setEmbeddedFiles(efTree); - doc.getDocumentCatalog().setNames(names); + names.setEmbeddedFiles(efTree); + doc.getDocumentCatalog().setNames(names); - // AF entry (Array) in catalog with the FileSpec - COSBase AFEntry = doc.getDocumentCatalog().getCOSObject().getItem("AF"); - if ((AFEntry == null)) { - COSArray cosArray = new COSArray(); - cosArray.add(fs); - doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); - } else if (AFEntry instanceof COSArray) { - COSArray cosArray = (COSArray) AFEntry; - cosArray.add(fs); - doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); - } else if ((AFEntry instanceof COSObject) && - ((COSObject) AFEntry).getObject() instanceof COSArray) { - COSArray cosArray = (COSArray) ((COSObject) AFEntry).getObject(); - cosArray.add(fs); - } else { - throw new IOException("Unexpected object type for PDFDocument/Catalog/COSDictionary/Item(AF)"); - } - } + // AF entry (Array) in catalog with the FileSpec + COSBase AFEntry = doc.getDocumentCatalog().getCOSObject().getItem("AF"); + if (AFEntry == null) { + COSArray cosArray = new COSArray(); + cosArray.add(fs); + doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); + } else if (AFEntry instanceof COSArray) { + COSArray cosArray = (COSArray) AFEntry; + cosArray.add(fs); + doc.getDocumentCatalog().getCOSObject().setItem("AF", cosArray); + } else if ((AFEntry instanceof COSObject) && + ((COSObject) AFEntry).getObject() instanceof COSArray) { + COSArray cosArray = (COSArray) ((COSObject) AFEntry).getObject(); + cosArray.add(fs); + } else { + throw new IOException("Unexpected object type for PDFDocument/Catalog/COSDictionary/Item(AF)"); + } + } - /** - * Sets the ZUGFeRD XML data to be attached as a single byte array. This is - * useful for use-cases where the XML has already been produced by some external - * API or component. - * - * @param zugferdData XML data to be set as a byte array (XML file in raw form). - * @throws IOException (should not happen) - */ - public ZUGFeRDExporterFromA3 setXML(byte[] zugferdData) throws IOException { - CustomXMLProvider cus = new CustomXMLProvider(); - cus.setXML(zugferdData); - this.setXMLProvider(cus); - prepare(); - return this; - } + /** + * Sets the ZUGFeRD XML data to be attached as a single byte array. This is + * useful for use-cases where the XML has already been produced by some external + * API or component. + * + * @param zugferdData XML data to be set as a byte array (XML file in raw form). + * @throws IOException (should not happen) + */ + public ZUGFeRDExporterFromA3 setXML(byte[] zugferdData) throws IOException { + CustomXMLProvider cus = new CustomXMLProvider(); + cus.setXML(zugferdData); + this.setXMLProvider(cus); + prepare(); + return this; + } - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfSource source to read a PDF/A1 compliant document from - */ - public ZUGFeRDExporterFromA3 load(InputStream pdfSource) throws IOException { - return load(readAllBytes(pdfSource)); - } + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfSource source to read a PDF/A1 compliant document from + */ + public ZUGFeRDExporterFromA3 load(InputStream pdfSource) throws IOException { + return load(readAllBytes(pdfSource)); + } - public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { - return true; - } + public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { + return true; + } - private static byte[] readAllBytes(InputStream in) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - IOUtils.copy(in, buffer); - return buffer.toByteArray(); - } + private static byte[] readAllBytes(InputStream in) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + IOUtils.copy(in, buffer); + return buffer.toByteArray(); + } - /** - * All files are PDF/A-3, setConformance refers to the level conformance. - *

- * PDF/A-3 has three coformance levels, called "A", "U" and "B". - *

- * PDF/A-3-B where B means only visually preservable, U -standard for Mustang- - * means visually and unicode preservable and A means full compliance, i.e. - * visually, unicode and structurally preservable and tagged PDF, i.e. useful - * metainformation for blind people. - *

- * Feel free to pass "A" as new level if you know what you are doing :-) - */ - public ZUGFeRDExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) { - conformanceLevel = newLevel; - return this; - } + /** + * All files are PDF/A-3, setConformance refers to the level conformance. + *

+ * PDF/A-3 has three coformance levels, called "A", "U" and "B". + *

+ * PDF/A-3-B where B means only visually preservable, U -standard for Mustang- + * means visually and unicode preservable and A means full compliance, i.e. + * visually, unicode and structurally preservable and tagged PDF, i.e. useful + * metainformation for blind people. + *

+ * Feel free to pass "A" as new level if you know what you are doing :-) + */ + public ZUGFeRDExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) { + conformanceLevel = newLevel; + return this; + } - public ZUGFeRDExporterFromA3 setCreator(String creator) { - this.creator = creator; - return this; - } + public ZUGFeRDExporterFromA3 setCreator(String creator) { + this.creator = creator; + return this; + } - public ZUGFeRDExporterFromA3 setCreatorTool(String creatorTool) { - this.creatorTool = creatorTool; - return this; - } - - public ZUGFeRDExporterFromA3 setProducer(String producer) { - this.producer = producer; - return this; - } - - protected ZUGFeRDExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) { - this.attachZUGFeRDHeaders = attachHeaders; - return this; - } + public ZUGFeRDExporterFromA3 setCreatorTool(String creatorTool) { + this.creatorTool = creatorTool; + return this; + } + public ZUGFeRDExporterFromA3 setProducer(String producer) { + this.producer = producer; + return this; + } - /** - * This will add both the RDF-indication which embedded file is Zugferd and the - * neccessary PDF/A schema extension description to be able to add this - * information to RDF - * - * @param metadata the PDFbox XMPMetadata object - */ - protected void addXMP(XMPMetadata metadata) { + protected ZUGFeRDExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) { + this.attachZUGFeRDHeaders = attachHeaders; + return this; + } - String metaDataVersion = null; // default will be used - // The XRechnung version may be settable from outside. - if ((this.XRechnungVersion != null) && (this.profile != null) && - this.profile.getName().equalsIgnoreCase(Profiles.getByName("XRECHNUNG").getName())) { - metaDataVersion = this.XRechnungVersion; - } + /** + * This will add both the RDF-indication which embedded file is Zugferd and the + * neccessary PDF/A schema extension description to be able to add this + * information to RDF + * + * @param metadata the PDFbox XMPMetadata object + */ + protected void addXMP(XMPMetadata metadata) { - if (attachZUGFeRDHeaders) { - XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, ZFVersion, isFacturX, xmlProvider.getProfile(), - getNamespaceForVersion(ZFVersion), getPrefixForVersion(ZFVersion), - getFilenameForVersion(ZFVersion, xmlProvider.getProfile()), metaDataVersion); + String metaDataVersion = null; // default will be used - metadata.addSchema(zf); - } + // The XRechnung version may be settable from outside. + if ((this.XRechnungVersion != null) && (this.profile != null) && + this.profile.getName().equalsIgnoreCase(Profiles.getByName("XRECHNUNG").getName())) { + metaDataVersion = this.XRechnungVersion; + } - XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(this, metadata, ZFVersion, attachZUGFeRDHeaders); - pdfaex.setZUGFeRDVersion(ZFVersion); - metadata.addSchema(pdfaex); - } + if (attachZUGFeRDHeaders) { + XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, ZFVersion, isFacturX, xmlProvider.getProfile(), + getNamespaceForVersion(ZFVersion), getPrefixForVersion(ZFVersion), + getFilenameForVersion(ZFVersion, xmlProvider.getProfile()), metaDataVersion); - private void removeCidSet(PDDocument doc) - throws IOException { - // https://github.com/ZUGFeRD/mustangproject/issues/249 + metadata.addSchema(zf); + } - COSName cidSet = COSName.getPDFName("CIDSet"); + XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(this, metadata, ZFVersion, attachZUGFeRDHeaders); + pdfaex.setZUGFeRDVersion(ZFVersion); + metadata.addSchema(pdfaex); + } - // iterate over all pdf pages + private void removeCidSet(PDDocument doc) + throws IOException { + // https://github.com/ZUGFeRD/mustangproject/issues/249 - for (Object object : doc.getPages()) { - if (object instanceof PDPage) { + COSName cidSet = COSName.getPDFName("CIDSet"); - PDPage page = (PDPage) object; - PDResources res = page.getResources(); - for (COSName fontName : res.getFontNames()) { - try { - PDFont pdFont = res.getFont(fontName); - if (pdFont instanceof PDType0Font) { - PDType0Font typedFont = (PDType0Font) pdFont; + // iterate over all pdf pages - if (typedFont.getDescendantFont() instanceof PDCIDFontType2) { - @SuppressWarnings("unused") - PDCIDFontType2 f = (PDCIDFontType2) typedFont.getDescendantFont(); - PDFontDescriptor fontDescriptor = pdFont.getFontDescriptor(); + for (Object object : doc.getPages()) { + if (object instanceof PDPage) { - fontDescriptor.getCOSObject().removeItem(cidSet); - } - } - } catch (IOException e) { - throw e; - } - // do stuff with the font - } - } - } - } + PDPage page = (PDPage) object; + PDResources res = page.getResources(); + for (COSName fontName : res.getFontNames()) { + try { + PDFont pdFont = res.getFont(fontName); + if (pdFont instanceof PDType0Font) { + PDType0Font typedFont = (PDType0Font) pdFont; - protected void prepareDocument() throws IOException { + if (typedFont.getDescendantFont() instanceof PDCIDFontType2) { + @SuppressWarnings("unused") + PDCIDFontType2 f = (PDCIDFontType2) typedFont.getDescendantFont(); + PDFontDescriptor fontDescriptor = pdFont.getFontDescriptor(); - PDDocumentCatalog cat = doc.getDocumentCatalog(); - metadata = new PDMetadata(doc); - cat.setMetadata(metadata); + fontDescriptor.getCOSObject().removeItem(cidSet); + } + } + } catch (IOException e) { + throw e; + } + // do stuff with the font + } + } + } + } - removeCidSet(doc); - xmp = getXmpMetadata(); - writeAdobePDFSchema(xmp); - writePDFAIdentificationSchema(xmp); - writeDublinCoreSchema(xmp); - writeXMLBasicSchema(xmp); - writeDocumentInformation(); + protected void prepareDocument() throws IOException { - // the following three lines are intended to make the pdf more PDF/A conformant if it isn't already - addSRGBOutputIntend(); - setMarked(); - addStructureTreeRoot(); + PDDocumentCatalog cat = doc.getDocumentCatalog(); + metadata = new PDMetadata(doc); + cat.setMetadata(metadata); - addXMP(xmp); /* - * this is the only line where we do something Zugferd-specific, i.e. add PDF - * metadata specifically for Zugferd, not generically for a embedded file - */ + removeCidSet(doc); + xmp = getXmpMetadata(); + writeAdobePDFSchema(xmp); + writePDFAIdentificationSchema(xmp); + writeDublinCoreSchema(xmp); + writeXMLBasicSchema(xmp); + writeDocumentInformation(); + // the following three lines are intended to make the pdf more PDF/A conformant if it isn't already + addSRGBOutputIntend(); + setMarked(); + addStructureTreeRoot(); - try { - metadata.importXMPMetadata(serializeXmpMetadata(xmp)); + addXMP(xmp); /* + * this is the only line where we do something Zugferd-specific, i.e. add PDF + * metadata specifically for Zugferd, not generically for a embedded file + */ +try { + metadata.importXMPMetadata(serializeXmpMetadata(xmp)); - } catch (TransformerException e) { - throw new ZUGFeRDExportException("Could not export XmpMetadata", e); - } - documentPrepared = true; - } + } catch (TransformerException e) { + throw new ZUGFeRDExportException("Could not export XmpMetadata", e); + } + documentPrepared = true; + } - /** - * Embeds the Zugferd XML structure in a file named ZUGFeRD-invoice.xml. - * - * @param trans a IZUGFeRDExportableTransaction that provides the data-model to - * populate the XML. This parameter may be null, if so the XML data - * should hav ebeen set via - * setZUGFeRDXMLData(byte[] zugferdData) - * @throws IOException if anything is wrong with already loaded PDF - */ - @Override - public IExporter setTransaction(IExportableTransaction trans) throws IOException { - this.trans = trans; - return prepare(); - } + /** + * Embeds the Zugferd XML structure in a file named ZUGFeRD-invoice.xml. + * + * @param trans a IZUGFeRDExportableTransaction that provides the data-model to + * populate the XML. This parameter may be null, if so the XML data + * should hav ebeen set via + * setZUGFeRDXMLData(byte[] zugferdData) + * @throws IOException if anything is wrong with already loaded PDF + */ + @Override + public IExporter setTransaction(IExportableTransaction trans) throws IOException { + this.trans = trans; + return prepare(); + } - public IExporter prepare() throws IOException { - prepareDocument(); - xmlProvider.generateXML(trans); - String filename = getFilenameForVersion(ZFVersion, xmlProvider.getProfile()); + public IExporter prepare() throws IOException { + prepareDocument(); + xmlProvider.generateXML(trans); + String filename = getFilenameForVersion(ZFVersion, xmlProvider.getProfile()); - String relationship = "Alternative"; - // ZUGFeRD 2.1.1 Technical Supplement | Part A | 2.2.2. Data Relationship - // See documentation ZUGFeRD211_EN/Documentation/ZUGFeRD-2.1.1 - Specification_TA_Part-A.pdf - // https://www.ferd-net.de/standards/zugferd-2.1.1/index.html - if ((this.profile != null) && (ZFVersion >= 2)) { - if (this.profile.getName().equalsIgnoreCase(Profiles.getByName("MINIMUM").getName()) || - this.profile.getName().equalsIgnoreCase(Profiles.getByName("BASICWL").getName())) { - relationship = "Data"; - } - } + String relationship = "Alternative"; + // ZUGFeRD 2.1.1 Technical Supplement | Part A | 2.2.2. Data Relationship + // See documentation ZUGFeRD211_EN/Documentation/ZUGFeRD-2.1.1 - Specification_TA_Part-A.pdf + // https://www.ferd-net.de/standards/zugferd-2.1.1/index.html + if ((this.profile != null) && (ZFVersion >= 2)) { + if (this.profile.getName().equalsIgnoreCase(Profiles.getByName("MINIMUM").getName()) || + this.profile.getName().equalsIgnoreCase(Profiles.getByName("BASICWL").getName())) { + relationship = "Data"; + } + } - PDFAttachGenericFile(doc, filename, relationship, - "Invoice metadata conforming to ZUGFeRD standard (http://www.ferd-net.de/front_content.php?idcat=231&lang=4)", - "text/xml", xmlProvider.getXML()); + PDFAttachGenericFile(doc, filename, relationship, + "Invoice metadata conforming to ZUGFeRD standard (http://www.ferd-net.de/front_content.php?idcat=231&lang=4)", + "text/xml", xmlProvider.getXML()); - for (FileAttachment attachment : fileAttachments) { - PDFAttachGenericFile(doc, attachment.getFilename(), attachment.getRelation(), attachment.getDescription(), attachment.getMimetype(), attachment.getData()); - } + for (FileAttachment attachment : fileAttachments) { + PDFAttachGenericFile(doc, attachment.getFilename(), attachment.getRelation(), attachment.getDescription(), attachment.getMimetype(), attachment.getData()); + } - return this; - } + return this; + } - /** - * Reads the XMPMetadata from the PDDocument, if it exists. - * Otherwise creates XMPMetadata. - * - * @return the finished XMPMetadata object - * @throws IOException when e.g. XmpParsingException - */ - protected XMPMetadata getXmpMetadata() - throws IOException { - PDMetadata meta = doc.getDocumentCatalog().getMetadata(); - if ((meta != null) && (meta.getLength() > 0)) { - try { - DomXmpParser xmpParser = new DomXmpParser(); - return xmpParser.parse(meta.toByteArray()); - } catch (XmpParsingException e) { - throw new IOException(e); - } - } - return XMPMetadata.createXMPMetadata(); - } + /** + * Reads the XMPMetadata from the PDDocument, if it exists. + * Otherwise creates XMPMetadata. + * + * @return the finished XMPMetadata object + * @throws IOException when e.g. XmpParsingException + */ + protected XMPMetadata getXmpMetadata() + throws IOException { + PDMetadata meta = doc.getDocumentCatalog().getMetadata(); + if ((meta != null) && (meta.getLength() > 0)) { + try { + DomXmpParser xmpParser = new DomXmpParser(); + return xmpParser.parse(meta.toByteArray()); + } catch (XmpParsingException e) { + throw new IOException(e); + } + } + return XMPMetadata.createXMPMetadata(); + } - protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - new XmpSerializer().serialize(xmpMetadata, buffer, true); // see https://github.com/ZUGFeRD/mustangproject/issues/44 - return buffer.toByteArray(); - } + protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + new XmpSerializer().serialize(xmpMetadata, buffer, true); // see https://github.com/ZUGFeRD/mustangproject/issues/44 + return buffer.toByteArray(); + } - /** - * Sets the producer if the overwrite flag is set or the producer is not already set. - * Sets the PDFVersion to 1.4 if the field is empty. - * - * @param xmp the metadata as XML - */ - protected void writeAdobePDFSchema(XMPMetadata xmp) { - AdobePDFSchema pdf = getAdobePDFSchema(xmp); - if (overwrite || isEmpty(pdf.getProducer())) - pdf.setProducer(producer); - } + /** + * Sets the producer if the overwrite flag is set or the producer is not already set. + * Sets the PDFVersion to 1.4 if the field is empty. + * + * @param xmp the metadata as XML + */ + protected void writeAdobePDFSchema(XMPMetadata xmp) { + AdobePDFSchema pdf = getAdobePDFSchema(xmp); + if (overwrite || isEmpty(pdf.getProducer())) + pdf.setProducer(producer); + } - /** - * Returns the AdobePDFSchema from the XMPMetadata if it exists. - * If the overwrite flag is set or no AdobePDFSchema exists in the XMPMetadata, it is created, added and returned. - * - * @param xmp the metadata to attach to - * @return the pdf schema - */ - protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) { - AdobePDFSchema pdf = xmp.getAdobePDFSchema(); - if (pdf != null) - if (overwrite) - xmp.removeSchema(pdf); - else - return pdf; - return xmp.createAndAddAdobePDFSchema(); - } + /** + * Returns the AdobePDFSchema from the XMPMetadata if it exists. + * If the overwrite flag is set or no AdobePDFSchema exists in the XMPMetadata, it is created, added and returned. + * + * @param xmp the metadata to attach to + * @return the pdf schema + */ + protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) { + AdobePDFSchema pdf = xmp.getAdobePDFSchema(); + if (pdf != null) + if (overwrite) + xmp.removeSchema(pdf); + else + return pdf; + return xmp.createAndAddAdobePDFSchema(); + } - protected void writePDFAIdentificationSchema(XMPMetadata xmp) { - PDFAIdentificationSchema pdfaid = getPDFAIdentificationSchema(xmp); - if (overwrite || isEmpty(pdfaid.getConformance())) { - try { - pdfaid.setConformance(conformanceLevel.getLetter()); - } catch (BadFieldValueException ex) { - // This should be impossible, because it would occur only if an illegal - // conformance level is supplied, - // however the enum enforces that the conformance level is valid. - throw new Error(ex); - } - } - pdfaid.setPart(3); - } + protected void writePDFAIdentificationSchema(XMPMetadata xmp) { + PDFAIdentificationSchema pdfaid = getPDFAIdentificationSchema(xmp); + if (overwrite || isEmpty(pdfaid.getConformance())) { + try { + pdfaid.setConformance(conformanceLevel.getLetter()); + } catch (BadFieldValueException ex) { + // This should be impossible, because it would occur only if an illegal + // conformance level is supplied, + // however the enum enforces that the conformance level is valid. + throw new Error(ex); + } + } + pdfaid.setPart(3); + } - protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { - PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema(); - if (pdfaid != null) - if (overwrite) - xmp.removeSchema(pdfaid); - else - return pdfaid; - return xmp.createAndAddPDFAIdentificationSchema(); - } + protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { + PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema(); + if (pdfaid != null) + if (overwrite) + xmp.removeSchema(pdfaid); + else + return pdfaid; + return xmp.createAndAddPDFAIdentificationSchema(); + } - protected void writeDublinCoreSchema(XMPMetadata xmp) { - DublinCoreSchema dc = getDublinCoreSchema(xmp); - if (dc.getFormat() == null) - dc.setFormat("application/pdf"); - if ((overwrite || dc.getCreators() == null || dc.getCreators().isEmpty()) && creator != null) - dc.addCreator(creator); - if ((overwrite || dc.getDates() == null || dc.getDates().isEmpty()) && creator != null) - dc.addDate(Calendar.getInstance()); + protected void writeDublinCoreSchema(XMPMetadata xmp) { + DublinCoreSchema dc = getDublinCoreSchema(xmp); + if (dc.getFormat() == null) + dc.setFormat("application/pdf"); + if ((overwrite || dc.getCreators() == null || dc.getCreators().isEmpty()) && creator != null) + dc.addCreator(creator); + if ((overwrite || dc.getDates() == null || dc.getDates().isEmpty()) && creator != null) + dc.addDate(Calendar.getInstance()); - ArrayProperty titleProperty = dc.getTitleProperty(); - if (titleProperty != null) { - if (overwrite && !isEmpty(title)) { - dc.removeProperty(titleProperty); - dc.setTitle(title); - } else if (titleProperty.getElementsAsString().stream().anyMatch("Untitled"::equalsIgnoreCase)) { - // remove unfitting ghostscript default - dc.removeProperty(titleProperty); - } - } else if (!isEmpty(title)) { - dc.setTitle(title); - } - } + ArrayProperty titleProperty = dc.getTitleProperty(); + if (titleProperty != null) { + if (overwrite && !isEmpty(title)) { + dc.removeProperty(titleProperty); + dc.setTitle(title); + } else if (titleProperty.getElementsAsString().stream().anyMatch("Untitled"::equalsIgnoreCase)) { + // remove unfitting ghostscript default + dc.removeProperty(titleProperty); + } + } else if (!isEmpty(title)) { + dc.setTitle(title); + } + } - protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) { - DublinCoreSchema dc = xmp.getDublinCoreSchema(); - if (dc != null) - if (overwrite) - xmp.removeSchema(dc); - else - return dc; - return xmp.createAndAddDublinCoreSchema(); - } + protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) { + DublinCoreSchema dc = xmp.getDublinCoreSchema(); + if (dc != null) + if (overwrite) + xmp.removeSchema(dc); + else + return dc; + return xmp.createAndAddDublinCoreSchema(); + } - protected void writeXMLBasicSchema(XMPMetadata xmp) { - XMPBasicSchema xsb = getXmpBasicSchema(xmp); - if (overwrite || isEmpty(xsb.getCreatorTool()) || "UnknownApplication".equals(xsb.getCreatorTool())) - xsb.setCreatorTool(creatorTool); - if (overwrite || xsb.getCreateDate() == null) - xsb.setCreateDate(Calendar.getInstance()); - } + protected void writeXMLBasicSchema(XMPMetadata xmp) { + XMPBasicSchema xsb = getXmpBasicSchema(xmp); + if (overwrite || isEmpty(xsb.getCreatorTool()) || "UnknownApplication".equals(xsb.getCreatorTool())) + xsb.setCreatorTool(creatorTool); + if (overwrite || xsb.getCreateDate() == null) + xsb.setCreateDate(Calendar.getInstance()); + } - protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) { - XMPBasicSchema xsb = xmp.getXMPBasicSchema(); - if (xsb != null) - if (overwrite) - xmp.removeSchema(xsb); - else - return xsb; - return xmp.createAndAddXMPBasicSchema(); - } + protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) { + XMPBasicSchema xsb = xmp.getXMPBasicSchema(); + if (xsb != null) + if (overwrite) + xmp.removeSchema(xsb); + else + return xsb; + return xmp.createAndAddXMPBasicSchema(); + } - protected void writeDocumentInformation() { - String fullProducer = producer + " (via mustangproject.org " + Version.VERSION + ")"; - PDDocumentInformation info = doc.getDocumentInformation(); - if (overwrite || info.getCreationDate() == null) - info.setCreationDate(Calendar.getInstance()); - if (overwrite || info.getModificationDate() == null) - info.setModificationDate(Calendar.getInstance()); - if (overwrite || (isEmpty(info.getAuthor()) && !isEmpty(author))) - info.setAuthor(author); - if (overwrite || (isEmpty(info.getProducer()) && !isEmpty(fullProducer))) - info.setProducer(fullProducer); - if (overwrite || (isEmpty(info.getCreator()) && !isEmpty(creator))) - info.setCreator(creator); - if (overwrite || (isEmpty(info.getTitle()) && !isEmpty(title))) - info.setTitle(title); - if (overwrite || (isEmpty(info.getSubject()) && !isEmpty(subject))) - info.setSubject(subject); - } + protected void writeDocumentInformation() { + String fullProducer = producer + " (via mustangproject.org " + Version.VERSION + ")"; + PDDocumentInformation info = doc.getDocumentInformation(); + if (overwrite || info.getCreationDate() == null) + info.setCreationDate(Calendar.getInstance()); + if (overwrite || info.getModificationDate() == null) + info.setModificationDate(Calendar.getInstance()); + if (overwrite || (isEmpty(info.getAuthor()) && !isEmpty(author))) + info.setAuthor(author); + if (overwrite || (isEmpty(info.getProducer()) && !isEmpty(fullProducer))) + info.setProducer(fullProducer); + if (overwrite || (isEmpty(info.getCreator()) && !isEmpty(creator))) + info.setCreator(creator); + if (overwrite || (isEmpty(info.getTitle()) && !isEmpty(title))) + info.setTitle(title); + if (overwrite || (isEmpty(info.getSubject()) && !isEmpty(subject))) + info.setSubject(subject); + } - /** - * Adds an OutputIntent and the sRGB color profile if no OutputIntent exist - * - * @throws IOException if the ICC file cannot be read or attached to doc - */ - protected void addSRGBOutputIntend() - throws IOException { - if (!doc.getDocumentCatalog().getOutputIntents().isEmpty()) { - return; - } + /** + * Adds an OutputIntent and the sRGB color profile if no OutputIntent exist + * + * @throws IOException if the ICC file cannot be read or attached to doc + */ + protected void addSRGBOutputIntend() + throws IOException { + if (!doc.getDocumentCatalog().getOutputIntents().isEmpty()) { + return; + } - try { - InputStream colorProfile = Thread.currentThread().getContextClassLoader().getResourceAsStream("sRGB.icc"); - if (colorProfile != null) { - PDOutputIntent intent = new PDOutputIntent(doc, colorProfile); - intent.setInfo("sRGB IEC61966-2.1"); - intent.setOutputCondition("sRGB IEC61966-2.1"); - intent.setOutputConditionIdentifier("sRGB IEC61966-2.1"); - intent.setRegistryName("http://www.color.org"); - doc.getDocumentCatalog().addOutputIntent(intent); - } - } catch (IOException e) { - throw e; - } - } + try { + InputStream colorProfile = Thread.currentThread().getContextClassLoader().getResourceAsStream("sRGB.icc"); + if (colorProfile != null) { + PDOutputIntent intent = new PDOutputIntent(doc, colorProfile); + intent.setInfo("sRGB IEC61966-2.1"); + intent.setOutputCondition("sRGB IEC61966-2.1"); + intent.setOutputConditionIdentifier("sRGB IEC61966-2.1"); + intent.setRegistryName("http://www.color.org"); + doc.getDocumentCatalog().addOutputIntent(intent); + } + } catch (IOException e) { + throw e; + } + } - /** - * Adds a MarkInfo element to the PDF if it doesn't already exist and sets it as marked. - */ - protected void setMarked() { - PDDocumentCatalog catalog = doc.getDocumentCatalog(); - if (catalog.getMarkInfo() == null) { - catalog.setMarkInfo(new PDMarkInfo(doc.getPages().getCOSObject())); - } - catalog.getMarkInfo().setMarked(true); - } + /** + * Adds a MarkInfo element to the PDF if it doesn't already exist and sets it as marked. + */ + protected void setMarked() { + PDDocumentCatalog catalog = doc.getDocumentCatalog(); + if (catalog.getMarkInfo() == null) { + catalog.setMarkInfo(new PDMarkInfo(doc.getPages().getCOSObject())); + } + catalog.getMarkInfo().setMarked(true); + } - /** - * Adds a StructureTreeRoot element to the PDF if it doesn't already exist. - */ - protected void addStructureTreeRoot() { - if (doc.getDocumentCatalog().getStructureTreeRoot() == null) { - doc.getDocumentCatalog().setStructureTreeRoot(new PDStructureTreeRoot()); - } - } + /** + * Adds a StructureTreeRoot element to the PDF if it doesn't already exist. + */ + protected void addStructureTreeRoot() { + if (doc.getDocumentCatalog().getStructureTreeRoot() == null) { + doc.getDocumentCatalog().setStructureTreeRoot(new PDStructureTreeRoot()); + } + } - /** - * @return if pdf file will be automatically closed after adding ZF - */ - public boolean isAutoCloseDisabled() { - return disableAutoClose; - } + /** + * @return if pdf file will be automatically closed after adding ZF + */ + public boolean isAutoCloseDisabled() { + return disableAutoClose; + } - /** - * @param disableAutoClose prevent PDF file from being closed after adding ZF - */ - public ZUGFeRDExporterFromA3 disableAutoClose(boolean disableAutoClose) { - this.disableAutoClose = disableAutoClose; - return this; - } + /** + * @param disableAutoClose prevent PDF file from being closed after adding ZF + */ + public ZUGFeRDExporterFromA3 disableAutoClose(boolean disableAutoClose) { + this.disableAutoClose = disableAutoClose; + return this; + } - protected void setXMLProvider(IXMLProvider p) { - this.xmlProvider = p; - if (profile != null) { - xmlProvider.setProfile(profile); - } - } + protected void setXMLProvider(IXMLProvider p) { + this.xmlProvider = p; + if (profile != null) { + xmlProvider.setProfile(profile); + } + } - public ZUGFeRDExporterFromA3 setZUGFeRDVersion(EStandard est, int version) { - this.ZFVersion = version; - if ((version < 1) || (version > 2)) { - throw new IllegalArgumentException("Version not supported"); - } - int generation = version; - if ((est == EStandard.facturx) && (version == 1)) { - generation = 2; - } - if (generation == 1) { - ZUGFeRD1PullProvider z1p = new ZUGFeRD1PullProvider(); - disableFacturX(); - setXMLProvider(z1p); - } else if (generation == 2) { - ZUGFeRD2PullProvider z2p = new ZUGFeRD2PullProvider(); - setXMLProvider(z2p); - } + public ZUGFeRDExporterFromA3 setZUGFeRDVersion(EStandard est, int version) { + this.ZFVersion = version; + if ((version < 1) || (version > 2)) { + throw new IllegalArgumentException("Version not supported"); + } + int generation = version; + if ((est == EStandard.facturx) && (version == 1)) { + generation = 2; + } + if (generation == 1) { + ZUGFeRD1PullProvider z1p = new ZUGFeRD1PullProvider(); + disableFacturX(); + setXMLProvider(z1p); + } else if (generation == 2) { + ZUGFeRD2PullProvider z2p = new ZUGFeRD2PullProvider(); + setXMLProvider(z2p); + } - return this; - } + return this; + } - @Override - public ZUGFeRDExporterFromA3 setZUGFeRDVersion(int version) { - this.ZFVersion = version; - if (version == 1) { - ZUGFeRD1PullProvider z1p = new ZUGFeRD1PullProvider(); - disableFacturX(); - setXMLProvider(z1p); - } else if (version == 2) { - ZUGFeRD2PullProvider z2p = new ZUGFeRD2PullProvider(); - setXMLProvider(z2p); - } else { - throw new IllegalArgumentException("Version not supported"); - } + @Override + public ZUGFeRDExporterFromA3 setZUGFeRDVersion(int version) { + this.ZFVersion = version; + if (version == 1) { + ZUGFeRD1PullProvider z1p = new ZUGFeRD1PullProvider(); + disableFacturX(); + setXMLProvider(z1p); + } else if (version == 2) { + ZUGFeRD2PullProvider z2p = new ZUGFeRD2PullProvider(); + setXMLProvider(z2p); + } else { + throw new IllegalArgumentException("Version not supported"); + } - return this; - } + return this; + } - /** - * Utility method inspired by apache commons-lang3 StringUtils. - * - * @param string the string to test - * @return true if the string is null or empty - */ - private boolean isEmpty(String string) { - return string == null || string.isEmpty(); - } + /** + * Utility method inspired by apache commons-lang3 StringUtils. + * + * @param string the string to test + * @return true if the string is null or empty + */ + private boolean isEmpty(String string) { + return string == null || string.isEmpty(); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromPDFA.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromPDFA.java index c3b9299..e586fb0 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromPDFA.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromPDFA.java @@ -20,12 +20,7 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import java.io.DataInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - +import jakarta.activation.DataSource; import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentCatalog; @@ -38,7 +33,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.activation.DataSource; +import java.io.*; /*** * Auto-detects the source PDF-A-Version and acts accordingly @@ -46,218 +41,218 @@ */ public class ZUGFeRDExporterFromPDFA implements IZUGFeRDExporter { - private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDExporterFromPDFA.class.getCanonicalName()); // log + private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDExporterFromPDFA.class.getCanonicalName()); // log - protected IZUGFeRDExporter theExporter; + protected IZUGFeRDExporter theExporter; - protected boolean ignorePDFAErrors = false; + protected boolean ignorePDFAErrors = false; - public ZUGFeRDExporterFromPDFA ignorePDFAErrors() { - this.ignorePDFAErrors = true; - return this; - } - protected void determineAndSetExporter(int PDFAVersion) { - if (PDFAVersion == 3) { - theExporter = new ZUGFeRDExporterFromA3(); - if (ignorePDFAErrors) { - ((ZUGFeRDExporterFromA3)theExporter).ignorePDFAErrors(); - } - } else if (PDFAVersion == 1) { - theExporter = new ZUGFeRDExporterFromA1(); - if (ignorePDFAErrors) { - ((ZUGFeRDExporterFromA1)theExporter).ignorePDFAErrors(); - } - } else { - throw new IllegalArgumentException("PDF-A version not supported"); - } + public ZUGFeRDExporterFromPDFA ignorePDFAErrors() { + this.ignorePDFAErrors = true; + return this; + } + + protected void determineAndSetExporter(int PDFAVersion) { + if (PDFAVersion == 3) { + theExporter = new ZUGFeRDExporterFromA3(); + if (ignorePDFAErrors) { + ((ZUGFeRDExporterFromA3) theExporter).ignorePDFAErrors(); + } + } else if (PDFAVersion == 1) { + theExporter = new ZUGFeRDExporterFromA1(); + if (ignorePDFAErrors) { + ((ZUGFeRDExporterFromA1) theExporter).ignorePDFAErrors(); + } + } else { + throw new IllegalArgumentException("PDF-A version not supported"); + } - } + } - public IZUGFeRDExporter getExporter() { - if (theExporter==null) { - throw new RuntimeException("In ZUGFeRDExporterFromPDFA, source must always be loaded before other operations are performed."); - } + public IZUGFeRDExporter getExporter() { + if (theExporter == null) { + throw new RuntimeException("In ZUGFeRDExporterFromPDFA, source must always be loaded before other operations are performed."); + } - return theExporter; - } + return theExporter; + } - protected byte[] filenameToByteArray(String pdfFilename) throws IOException { - try (FileInputStream fileInputStream = new FileInputStream(pdfFilename)) { - return inputstreamToByteArray(fileInputStream); - } - } + protected byte[] filenameToByteArray(String pdfFilename) throws IOException { + try (FileInputStream fileInputStream = new FileInputStream(pdfFilename)) { + return inputstreamToByteArray(fileInputStream); + } + } - protected byte[] inputstreamToByteArray(InputStream fileInputStream) throws IOException { - byte[] bytes = new byte[fileInputStream.available()]; - DataInputStream dataInputStream = new DataInputStream(fileInputStream); - dataInputStream.readFully(bytes); - return bytes; - } + protected byte[] inputstreamToByteArray(InputStream fileInputStream) throws IOException { + byte[] bytes = new byte[fileInputStream.available()]; + DataInputStream dataInputStream = new DataInputStream(fileInputStream); + dataInputStream.readFully(bytes); + return bytes; + } - /*** - * - * @param byteArrayInputStream - * @return 0 if unknown, 1 for PDF/A-1 or 3 for PDF/A-3 - * @throws IOException - */ - private int getPDFAVersion(byte[] byteArrayInputStream) throws IOException { - PDDocument document = Loader.loadPDF(byteArrayInputStream); - PDDocumentCatalog catalog = document.getDocumentCatalog(); - PDMetadata metadata = catalog.getMetadata(); - // the PDF version we could get through the document but we want the PDF-A version, - // which is different (and can probably base on different PDF versions) - if (metadata != null) { - try { - DomXmpParser xmpParser = new DomXmpParser(); - XMPMetadata xmp = xmpParser.parse(metadata.createInputStream()); + /*** + * + * @param byteArrayInputStream + * @return 0 if unknown, 1 for PDF/A-1 or 3 for PDF/A-3 + * @throws IOException + */ + private int getPDFAVersion(byte[] byteArrayInputStream) throws IOException { + PDDocument document = Loader.loadPDF(byteArrayInputStream); + PDDocumentCatalog catalog = document.getDocumentCatalog(); + PDMetadata metadata = catalog.getMetadata(); + // the PDF version we could get through the document but we want the PDF-A version, + // which is different (and can probably base on different PDF versions) + if (metadata != null) { + try { + DomXmpParser xmpParser = new DomXmpParser(); + XMPMetadata xmp = xmpParser.parse(metadata.createInputStream()); - PDFAIdentificationSchema pdfaSchema = xmp.getPDFAIdentificationSchema(); - if (pdfaSchema != null) { - return pdfaSchema.getPart(); - } - } catch (XmpParsingException e) { - LOGGER.error("XmpParsingException", e); - } finally { - document.close(); - } - } - return 0; - } + PDFAIdentificationSchema pdfaSchema = xmp.getPDFAIdentificationSchema(); + if (pdfaSchema != null) { + return pdfaSchema.getPart(); + } + } catch (XmpParsingException e) { + LOGGER.error("XmpParsingException", e); + } finally { + document.close(); + } + } + return 0; + } - /*** - * Load from filename - * @param pdfFilename binary of a PDF/A1 compliant document - * @return the A1 or A3 exporter - * @throws IOException e.g. on read error - */ - public IZUGFeRDExporter load(String pdfFilename) throws IOException { - determineAndSetExporter(getPDFAVersion(filenameToByteArray(pdfFilename))); - return theExporter.load(pdfFilename); - } + /*** + * Load from filename + * @param pdfFilename binary of a PDF/A1 compliant document + * @return the A1 or A3 exporter + * @throws IOException e.g. on read error + */ + public IZUGFeRDExporter load(String pdfFilename) throws IOException { + determineAndSetExporter(getPDFAVersion(filenameToByteArray(pdfFilename))); + return theExporter.load(pdfFilename); + } - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfBinary binary of a PDF/A1 compliant document - * @return the generated exporter - * @throws IOException (should not happen at all) - */ - public IZUGFeRDExporter load(byte[] pdfBinary) throws IOException { - determineAndSetExporter(getPDFAVersion(pdfBinary)); - return theExporter.load(pdfBinary); - } + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfBinary binary of a PDF/A1 compliant document + * @return the generated exporter + * @throws IOException (should not happen at all) + */ + public IZUGFeRDExporter load(byte[] pdfBinary) throws IOException { + determineAndSetExporter(getPDFAVersion(pdfBinary)); + return theExporter.load(pdfBinary); + } - /** - * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the - * metadata level, this will not e.g. convert graphics to JPG-2000) - * - * @param pdfSource source to read a PDF/A1 compliant document from - * @return the generated ZUGFeRDExporter - * @throws IOException if anything is wrong with inputstream - */ - public IZUGFeRDExporter load(InputStream pdfSource) throws IOException { - byte[] byteArray=inputstreamToByteArray(pdfSource); - determineAndSetExporter(getPDFAVersion(byteArray)); - return theExporter.load(byteArray); - } + /** + * Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the + * metadata level, this will not e.g. convert graphics to JPG-2000) + * + * @param pdfSource source to read a PDF/A1 compliant document from + * @return the generated ZUGFeRDExporter + * @throws IOException if anything is wrong with inputstream + */ + public IZUGFeRDExporter load(InputStream pdfSource) throws IOException { + byte[] byteArray = inputstreamToByteArray(pdfSource); + determineAndSetExporter(getPDFAVersion(byteArray)); + return theExporter.load(byteArray); + } - public IZUGFeRDExporter setCreator(String creator) { + public IZUGFeRDExporter setCreator(String creator) { - return getExporter().setCreator(creator); - } + return getExporter().setCreator(creator); + } - public IZUGFeRDExporter setProfile(Profile p) { - return getExporter().setProfile(p); - } + public IZUGFeRDExporter setProfile(Profile p) { + return getExporter().setProfile(p); + } - public IZUGFeRDExporter setProfile(String profileName) { - Profile p = Profiles.getByName(profileName); - if (p==null) { - throw new RuntimeException("Profile not found."); - } - return getExporter().setProfile(p); - } + public IZUGFeRDExporter setProfile(String profileName) { + Profile p = Profiles.getByName(profileName); + if (p == null) { + throw new RuntimeException("Profile not found."); + } + return getExporter().setProfile(p); + } - public IZUGFeRDExporter setConformanceLevel(PDFAConformanceLevel newLevel) { - return getExporter().setConformanceLevel(newLevel); - } + public IZUGFeRDExporter setConformanceLevel(PDFAConformanceLevel newLevel) { + return getExporter().setConformanceLevel(newLevel); + } - public IZUGFeRDExporter setProducer(String producer) { + public IZUGFeRDExporter setProducer(String producer) { - return getExporter().setProducer(producer); - } + return getExporter().setProducer(producer); + } - public IZUGFeRDExporter setZUGFeRDVersion(int version) { + public IZUGFeRDExporter setZUGFeRDVersion(int version) { - return getExporter().setZUGFeRDVersion(version); + return getExporter().setZUGFeRDVersion(version); - } + } - public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { + public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException { - return getExporter().ensurePDFIsValid(dataSource); - } + return getExporter().ensurePDFIsValid(dataSource); + } - public IZUGFeRDExporter setXML(byte[] zugferdData) throws IOException { + public IZUGFeRDExporter setXML(byte[] zugferdData) throws IOException { - return getExporter().setXML(zugferdData); - } + return getExporter().setXML(zugferdData); + } - public IZUGFeRDExporter disableFacturX() { + public IZUGFeRDExporter disableFacturX() { - return getExporter().disableFacturX(); - } + return getExporter().disableFacturX(); + } - // public IZUGFeRDExporter setProfile(Profile zugferdConformanceLevel); - public String getNamespaceForVersion(int ver) { + // public IZUGFeRDExporter setProfile(Profile zugferdConformanceLevel); + public String getNamespaceForVersion(int ver) { - return getExporter().getNamespaceForVersion(ver); - } + return getExporter().getNamespaceForVersion(ver); + } - public String getPrefixForVersion(int ver) { + public String getPrefixForVersion(int ver) { - return getExporter().getPrefixForVersion(ver); - } + return getExporter().getPrefixForVersion(ver); + } - public IZUGFeRDExporter disableAutoClose(boolean disableAutoClose) { - return getExporter().disableAutoClose(disableAutoClose); - } + public IZUGFeRDExporter disableAutoClose(boolean disableAutoClose) { + return getExporter().disableAutoClose(disableAutoClose); + } - public IXMLProvider getProvider() { - return getExporter().getProvider(); - } + public IXMLProvider getProvider() { + return getExporter().getProvider(); + } - @Override - public void close() throws IOException { - getExporter().close(); - } + @Override + public void close() throws IOException { + getExporter().close(); + } - @Override - public IExporter setTransaction(IExportableTransaction trans) throws IOException { - return getExporter().setTransaction(trans); - } + @Override + public IExporter setTransaction(IExportableTransaction trans) throws IOException { + return getExporter().setTransaction(trans); + } - @Override - public void export(String ZUGFeRDfilename) throws IOException { - getExporter().export(ZUGFeRDfilename); - } + @Override + public void export(String ZUGFeRDfilename) throws IOException { + getExporter().export(ZUGFeRDfilename); + } - @Override - public void export(OutputStream output) throws IOException { - getExporter().export(output); - } + @Override + public void export(OutputStream output) throws IOException { + getExporter().export(output); + } - public void attachFile(FileAttachment file) { - theExporter.attachFile(file); - } + public void attachFile(FileAttachment file) { + theExporter.attachFile(file); + } - public void attachFile(String filename, byte[] data, String mimetype, String relation) { - theExporter.attachFile(filename, data, mimetype, relation); - } + public void attachFile(String filename, byte[] data, String mimetype, String relation) { + theExporter.attachFile(filename, data, mimetype, relation); + } } - diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExportException.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExportException.java index c318fcc..7aa5cc3 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExportException.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExportException.java @@ -19,23 +19,23 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; public class ZUGFeRDExportException extends RuntimeException { - /** - * - */ - private static final long serialVersionUID = 1L; + /** + * + */ + private static final long serialVersionUID = 1L; - public ZUGFeRDExportException() { - } + public ZUGFeRDExportException() { + } - public ZUGFeRDExportException(String message) { - super(message); - } + public ZUGFeRDExportException(String message) { + super(message); + } - public ZUGFeRDExportException(String message, Throwable cause) { - super(message, cause); - } + public ZUGFeRDExportException(String message, Throwable cause) { + super(message, cause); + } - public ZUGFeRDExportException(Throwable cause) { - super(cause); - } + public ZUGFeRDExportException(Throwable cause) { + super(cause); + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 6ff0a4b..0602000 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -6,6 +6,7 @@ org.openrewrite.config.CompositeRecipe * and limitations under the License. */ package org.mustangproject.ZUGFeRD; + /** * Mustangproject's ZUGFeRD implementation ZUGFeRD importer Licensed under the APLv2 * @@ -13,858 +14,867 @@ * @version 1.1.0 * @author jstaerk */ -import java.io.*; -import java.text.SimpleDateFormat; -import java.util.*; - -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathFactory; - import org.mustangproject.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; +/** + * Mustangproject's ZUGFeRD implementation ZUGFeRD importer Licensed under the APLv2 + * + * @date 2014-07-07 + * @version 1.1.0 + * @author jstaerk + */ +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; + public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter { - private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDImporter.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDImporter.class); - public ZUGFeRDImporter() { - super(); - } + public ZUGFeRDImporter() { + super(); + } - public ZUGFeRDImporter(String filename) { - super(filename); - } + public ZUGFeRDImporter(String filename) { + super(filename); + } - public ZUGFeRDImporter(InputStream stream) { - super(stream); - } + public ZUGFeRDImporter(InputStream stream) { + super(stream); + } - /*** - * return the file names of all files embedded into the PDF - * for XML embedded files please use ZUGFeRDInvoiceImporter.getFileAttachmentsXML - * @return a ArrayList of FileAttachments, empty if none - */ - public List getFileAttachmentsPDF() { - return PDFAttachments; - } + /*** + * return the file names of all files embedded into the PDF + * for XML embedded files please use ZUGFeRDInvoiceImporter.getFileAttachmentsXML + * @return a ArrayList of FileAttachments, empty if none + */ + public List getFileAttachmentsPDF() { + return PDFAttachments; + } + // ////////////////////////////////// - //////////////////////////////////// + /** + * @return the reference (purpose) the sender specified for this invoice + */ + public String getForeignReference() { - /** - * @return the reference (purpose) the sender specified for this invoice - */ - public String getForeignReference() { + return importedInvoice.getNumber(); + } - return importedInvoice.getNumber(); - } + /** + * @return the ZUGFeRD Profile + */ + public String getZUGFeRDProfil() { - /** - * @return the ZUGFeRD Profile - */ - public String getZUGFeRDProfil() { + String guideline = extractString("//*[local-name() = 'GuidelineSpecifiedDocumentContextParameter']//*[local-name() = 'ID']"); + if (guideline.contains("xrechnung")) { + return "XRECHNUNG"; + } + switch (guideline) { + case "urn:cen.eu:en16931:2017": + case "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort": + return "COMFORT"; + case "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic": + case "urn:ferd:CrossIndustryDocument:invoice:1p0:basic": + return "BASIC"; + case "urn:factur-x.eu:1p0:basicwl": + return "BASIC WL"; + case "urn:factur-x.eu:1p0:minimum": + return "MINIMUM"; + case "urn:ferd:CrossIndustryDocument:invoice:1p0:extended": + case "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended": + return "EXTENDED"; + default: + return ""; + } + } - String guideline = extractString("//*[local-name() = 'GuidelineSpecifiedDocumentContextParameter']//*[local-name() = 'ID']"); - if (guideline.contains("xrechnung")) { - return "XRECHNUNG"; - } - switch (guideline) { - case "urn:cen.eu:en16931:2017": - case "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort": - return "COMFORT"; - case "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic": - case "urn:ferd:CrossIndustryDocument:invoice:1p0:basic": - return "BASIC"; - case "urn:factur-x.eu:1p0:basicwl": - return "BASIC WL"; - case "urn:factur-x.eu:1p0:minimum": - return "MINIMUM"; - case "urn:ferd:CrossIndustryDocument:invoice:1p0:extended": - case "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended": - return "EXTENDED"; - default: - return ""; - } - } + /** + * @return the IssuerAssigned ID + */ + public String getIssuerAssignedID() { + return extractIssuerAssignedID("BuyerOrderReferencedDocument"); + } - /** - * @return the IssuerAssigned ID - */ - public String getIssuerAssignedID() { - return extractIssuerAssignedID("BuyerOrderReferencedDocument"); - } + /** + * @return the SellerOrderReferencedDocument IssuerAssigned ID + */ + public String getSellerOrderReferencedDocumentIssuerAssignedID() { + return extractIssuerAssignedID("SellerOrderReferencedDocument"); + } - /** - * @return the SellerOrderReferencedDocument IssuerAssigned ID - */ - public String getSellerOrderReferencedDocumentIssuerAssignedID() { - return extractIssuerAssignedID("SellerOrderReferencedDocument"); - } + /** + * @return the IssuerAssigned ID + */ + public String getContractOrderReferencedDocumentIssuerAssignedID() { + return extractIssuerAssignedID("ContractReferencedDocument"); + } - /** - * @return the IssuerAssigned ID - */ - public String getContractOrderReferencedDocumentIssuerAssignedID() { - return extractIssuerAssignedID("ContractReferencedDocument"); - } + /** + * @return the TaxBasisTotalAmount + */ + public String getTaxBasisTotalAmount() { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'TaxBasisTotalAmount']"); + } else { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'TaxBasisTotalAmount']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - /** - * @return the TaxBasisTotalAmount - */ - public String getTaxBasisTotalAmount() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'TaxBasisTotalAmount']"); - } else { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'TaxBasisTotalAmount']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return the TaxTotalAmount + */ + public String getTaxTotalAmount() { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'TaxTotalAmount']"); + } else { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'TaxTotalAmount']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - /** - * @return the TaxTotalAmount - */ - public String getTaxTotalAmount() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'TaxTotalAmount']"); - } else { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'TaxTotalAmount']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return the RoundingAmount + */ + public String getRoundingAmount() { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'RoundingAmount']"); + } else { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'RoundingAmount']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - /** - * @return the RoundingAmount - */ - public String getRoundingAmount() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'RoundingAmount']"); - } else { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'RoundingAmount']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return the TotalPrepaidAmount + */ + public String getPaidAmount() { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'TotalPrepaidAmount']"); + } else { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'TotalPrepaidAmount']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - /** - * @return the TotalPrepaidAmount - */ - public String getPaidAmount() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'TotalPrepaidAmount']"); - } else { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'TotalPrepaidAmount']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return SellerTradeParty GlobalID + */ + public String getSellerTradePartyGlobalID() { + return extractString("//*[local-name() = 'SellerTradeParty']//*[local-name() = 'GlobalID']"); + } - /** - * @return SellerTradeParty GlobalID - */ - public String getSellerTradePartyGlobalID() { - return extractString("//*[local-name() = 'SellerTradeParty']//*[local-name() = 'GlobalID']"); - } + /** + * @return the BuyerTradeParty GlobalID + */ + public String getBuyerTradePartyGlobalID() { + return extractString("//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'GlobalID']"); + } - /** - * @return the BuyerTradeParty GlobalID - */ - public String getBuyerTradePartyGlobalID() { - return extractString("//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'GlobalID']"); - } + /** + * @return the BuyerTradeParty SpecifiedTaxRegistration ID + */ + public String getBuyertradePartySpecifiedTaxRegistrationID() { + String id = null; + if ((importedInvoice.getRecipient() != null) && (importedInvoice.getRecipient().getLegalOrganisation() != null)) { + // this *should* be the official result + id = importedInvoice.getRecipient().getLegalOrganisation().getSchemedID().getID(); + } + // but also provide some fallback + if (id == null) { + id = getBuyerTradePartyID(); + } + return id; + } - /** - * @return the BuyerTradeParty SpecifiedTaxRegistration ID - */ - public String getBuyertradePartySpecifiedTaxRegistrationID() { - String id = null; - if ((importedInvoice.getRecipient()!=null) && (importedInvoice.getRecipient().getLegalOrganisation()!=null)) { - // this *should* be the official result - id = importedInvoice.getRecipient().getLegalOrganisation().getSchemedID().getID(); - } - // but also provide some fallback - if (id == null) { - id = getBuyerTradePartyID(); - } - return id; - } + /** + * @return the IncludedNote + */ + public String getIncludedNote() { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = 'HeaderExchangedDocument']//*[local-name() = 'IncludedNote']"); + } else { + return extractString("//*[local-name() = 'ExchangedDocument']//*[local-name() = 'IncludedNote']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - /** - * @return the IncludedNote - */ - public String getIncludedNote() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'HeaderExchangedDocument']//*[local-name() = 'IncludedNote']"); - } else { - return extractString("//*[local-name() = 'ExchangedDocument']//*[local-name() = 'IncludedNote']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return the BuyerTradeParty Name + */ + public String getBuyerTradePartyName() { + return importedInvoice.getRecipient().getName(); + } - /** - * @return the BuyerTradeParty Name - */ - public String getBuyerTradePartyName() { - return importedInvoice.getRecipient().getName(); - } + /** + * @return the BuyerTradeParty Name + */ + public String getDeliveryTradePartyName() { + return importedInvoice.getDeliveryAddress().getName(); + } - /** - * @return the BuyerTradeParty Name - */ - public String getDeliveryTradePartyName() { - return importedInvoice.getDeliveryAddress().getName(); - } + /** + * @return the line Total Amount + */ + public String getLineTotalAmount() { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'LineTotalAmount']"); + } else { + return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'LineTotalAmount']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - /** - * @return the line Total Amount - */ - public String getLineTotalAmount() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementMonetarySummation']//*[local-name() = 'LineTotalAmount']"); - } else { - return extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']//*[local-name() = 'LineTotalAmount']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return the Payment Terms + */ + public String getPaymentTerms() { + return importedInvoice.getPaymentTermDescription(); + } - /** - * @return the Payment Terms - */ - public String getPaymentTerms() { - return importedInvoice.getPaymentTermDescription(); - } + /** + * @return the Taxpoint Date + */ + public String getTaxPointDate() { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = 'ActualDeliverySupplyChainEvent']//*[local-name() = 'OccurrenceDateTime']//*[local-name() = 'DateTimeString']"); + } else { + return extractString("//*[local-name() = 'ActualDeliverySupplyChainEvent']//*[local-name() = 'OccurrenceDateTime']//*[local-name() = 'DateTimeString']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - /** - * @return the Taxpoint Date - */ - public String getTaxPointDate() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'ActualDeliverySupplyChainEvent']//*[local-name() = 'OccurrenceDateTime']//*[local-name() = 'DateTimeString']"); - } else { - return extractString("//*[local-name() = 'ActualDeliverySupplyChainEvent']//*[local-name() = 'OccurrenceDateTime']//*[local-name() = 'DateTimeString']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return the Invoice ID + */ + public String getInvoiceID() { + return importedInvoice.getNumber(); + } - /** - * @return the Invoice ID - */ - public String getInvoiceID() { - return importedInvoice.getNumber(); - } + /** + * @return the document code + */ + public String getDocumentCode() { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = 'HeaderExchangedDocument']/*[local-name() = 'TypeCode']"); + } else { + return extractString("//*[local-name() = 'ExchangedDocument']/*[local-name() = 'TypeCode']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - /** - * @return the document code - */ - public String getDocumentCode() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'HeaderExchangedDocument']/*[local-name() = 'TypeCode']"); - } else { - return extractString("//*[local-name() = 'ExchangedDocument']/*[local-name() = 'TypeCode']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return the referred document + */ + public String getReference() { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = 'ApplicableSupplyChainTradeAgreement']/*[local-name() = 'BuyerReference']"); + } else { + return extractString("//*[local-name() = 'ApplicableHeaderTradeAgreement']/*[local-name() = 'BuyerReference']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - /** - * @return the referred document - */ - public String getReference() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'ApplicableSupplyChainTradeAgreement']/*[local-name() = 'BuyerReference']"); - } else { - return extractString("//*[local-name() = 'ApplicableHeaderTradeAgreement']/*[local-name() = 'BuyerReference']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return the sender's bank's BIC code + */ + public String getBIC() { + return extractString("//*[local-name() = 'PayeeSpecifiedCreditorFinancialInstitution']/*[local-name() = 'BICID']"); + } - /** - * @return the sender's bank's BIC code - */ - public String getBIC() { - return extractString("//*[local-name() = 'PayeeSpecifiedCreditorFinancialInstitution']/*[local-name() = 'BICID']"); - } + /** + * @return the sender's bank name + */ + public String getBankName() { + return extractString("//*[local-name() = 'PayeeSpecifiedCreditorFinancialInstitution']/*[local-name() = 'Name']"); + } - /** - * @return the sender's bank name - */ - public String getBankName() { - return extractString("//*[local-name() = 'PayeeSpecifiedCreditorFinancialInstitution']/*[local-name() = 'Name']"); - } + /** + * @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(); + } + if (settlement instanceof IZUGFeRDTradeSettlementPayment) { + return ((IZUGFeRDTradeSettlementPayment) settlement).getOwnIBAN(); + } + } + return null; + } - /** - * @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(); - } - if (settlement instanceof IZUGFeRDTradeSettlementPayment) { - return ((IZUGFeRDTradeSettlementPayment) settlement).getOwnIBAN(); - } - } - return null; - } + public String getHolder() { + return extractString("//*[local-name() = 'SellerTradeParty']/*[local-name() = 'Name']"); + } - public String getHolder() { - return extractString("//*[local-name() = 'SellerTradeParty']/*[local-name() = 'Name']"); - } + /** + * @return the total payable amount + */ + public String getAmount() { + return importedInvoice.getGrandTotal().toPlainString(); + } - /** - * @return the total payable amount - */ - public String getAmount() { - return importedInvoice.getGrandTotal().toPlainString(); - } + /** + * @return when the payment is due + */ + public String getDueDate() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + return sdf.format(importedInvoice.getDueDate()); + } - /** - * @return when the payment is due - */ - public String getDueDate() { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); - return sdf.format(importedInvoice.getDueDate()); - } + // ////////////////// - //////////////////// + /** + * @return the Invoice Currency Code + */ + public String getInvoiceCurrencyCode() { + return importedInvoice.getCurrency(); + } - /** - * @return the Invoice Currency Code - */ - public String getInvoiceCurrencyCode() { - return importedInvoice.getCurrency(); - } + private String extractIssuerAssignedID(String propertyName) { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'ID']"); + } else { + return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'IssuerAssignedID']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } - private String extractIssuerAssignedID(String propertyName) { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'ID']"); - } else { - return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'IssuerAssignedID']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } + /** + * @return the BuyerTradeParty ID + */ + public String getBuyerTradePartyID() { + String id = importedInvoice.getRecipient().getID(); + if (id == null) { + // provide some fallback + id = importedInvoice.getRecipient().getVATID(); + } + return id; + } - /** - * @return the BuyerTradeParty ID - */ - public String getBuyerTradePartyID() { - String id = importedInvoice.getRecipient().getID(); - if (id == null) { - // provide some fallback - id = importedInvoice.getRecipient().getVATID(); - } - return id; - } + /** + * @return the Issue Date() + */ + public String getIssueDate() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + return sdf.format(importedInvoice.getIssueDate()); + } - /** - * @return the Issue Date() - */ - public String getIssueDate() { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); - return sdf.format(importedInvoice.getIssueDate()); - } + public Date getDetailedDeliveryPeriodFrom() { + return importedInvoice.getDetailedDeliveryPeriodFrom(); + } - public Date getDetailedDeliveryPeriodFrom() { - return importedInvoice.getDetailedDeliveryPeriodFrom(); - } + public Date getDetailedDeliveryPeriodTo() { + return importedInvoice.getDetailedDeliveryPeriodTo(); + } - public Date getDetailedDeliveryPeriodTo() { - return importedInvoice.getDetailedDeliveryPeriodTo(); - } + public HashMap getAdditionalData() { + return additionalXMLs; + } - public HashMap getAdditionalData() { - return additionalXMLs; - } + /** + * get xmp metadata of the PDF, null if not available + * + * @return string + */ + public String getXMP() { + return xmpString; + } - /** - * get xmp metadata of the PDF, null if not available - * - * @return string - */ - public String getXMP() { - return xmpString; - } + /** + * @return if export found parseable ZUGFeRD data + */ + public boolean containsMeta() { + return containsMeta; + } - /** - * @return if export found parseable ZUGFeRD data - */ - public boolean containsMeta() { - return containsMeta; - } - - /** - * @param meta raw XML to be set - * @throws IOException if raw can not be set - */ - public void setMeta(String meta) throws IOException { - setRawXML(meta.getBytes()); - } + /** + * @param meta raw XML to be set + * @throws IOException if raw can not be set + */ + public void setMeta(String meta) throws IOException { + setRawXML(meta.getBytes()); + } - /** - * @return raw XML of the invoice - */ - public String getMeta() { - if (rawXML == null) { - return null; - } + /** + * @return raw XML of the invoice + */ + public String getMeta() { + if (rawXML == null) { + return null; + } - return new String(rawXML); - } + return new String(rawXML); + } - public int getVersion() throws Exception { - if (!containsMeta) { - throw new Exception("Not yet parsed"); - } - if (version != null) { - return version; - } + public int getVersion() throws Exception { + if (!containsMeta) { + throw new Exception("Not yet parsed"); + } + if (version != null) { + return version; + } - final String head = getUTF8(); - if (head.contains(" 0) && ((meta.contains("SpecifiedExchangedDocumentContext") - /* ZF1 */ || meta.contains("ExchangedDocumentContext") /* ZF2 */)); - } + // SpecifiedExchangedDocumentContext is in the schema, so a relatively good + // indication if zugferd is present - better than just invoice + final String meta = getMeta(); + return (meta != null) && (meta.length() > 0) && (meta.contains("SpecifiedExchangedDocumentContext") + /* ZF1 */ || meta.contains("ExchangedDocumentContext")); + } - /** - * returns an instance of PostalTradeAddress for SellerTradeParty section - * - * @return an instance of PostalTradeAddress - */ - public PostalTradeAddress getBuyerTradePartyAddress() { + /** + * returns an instance of PostalTradeAddress for SellerTradeParty section + * + * @return an instance of PostalTradeAddress + */ + public PostalTradeAddress getBuyerTradePartyAddress() { - NodeList nl = null; + NodeList nl = null; - try { - if (getVersion() == 1) { - nl = getNodeListByPath("//*[localname() = 'CrossIndustryDocument']//*[local-name() = 'SpecifiedSupplyChainTradeTransaction']/*[local-name() = 'ApplicableSupplyChainTradeAgreement']//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'PostalTradeAddress']"); - } else { - nl = getNodeListByPath("//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeAgreement']//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'PostalTradeAddress']"); - } - } catch (final Exception e) { - // Exception was already logged - return null; - } + try { + if (getVersion() == 1) { + nl = getNodeListByPath("//*[localname() = 'CrossIndustryDocument']//*[local-name() = 'SpecifiedSupplyChainTradeTransaction']/*[local-name() = 'ApplicableSupplyChainTradeAgreement']//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'PostalTradeAddress']"); + } else { + nl = getNodeListByPath("//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeAgreement']//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'PostalTradeAddress']"); + } + } catch (final Exception e) { + // Exception was already logged + return null; + } - return getAddressFromNodeList(nl); - } + return getAddressFromNodeList(nl); + } - /** - * returns an instance of PostalTradeAddress for SellerTradeParty section - * - * @return an instance of PostalTradeAddress - */ - public PostalTradeAddress getSellerTradePartyAddress() { + /** + * returns an instance of PostalTradeAddress for SellerTradeParty section + * + * @return an instance of PostalTradeAddress + */ + public PostalTradeAddress getSellerTradePartyAddress() { - NodeList nl = null; - try { - if (getVersion() == 1) { - nl = getNodeListByPath("//*[local-name() = 'CrossIndustryDocument']//*[local-name() = 'SpecifiedSupplyChainTradeTransaction']//*[local-name() = 'ApplicableSupplyChainTradeAgreement']//*[local-name() = 'SellerTradeParty']//*[local-name() = 'PostalTradeAddress']"); - } else { - nl = getNodeListByPath("//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeAgreement']//*[local-name() = 'SellerTradeParty']//*[local-name() = 'PostalTradeAddress']"); - } - } catch (final Exception e) { - // Exception was already logged - return null; - } + NodeList nl = null; + try { + if (getVersion() == 1) { + nl = getNodeListByPath("//*[local-name() = 'CrossIndustryDocument']//*[local-name() = 'SpecifiedSupplyChainTradeTransaction']//*[local-name() = 'ApplicableSupplyChainTradeAgreement']//*[local-name() = 'SellerTradeParty']//*[local-name() = 'PostalTradeAddress']"); + } else { + nl = getNodeListByPath("//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeAgreement']//*[local-name() = 'SellerTradeParty']//*[local-name() = 'PostalTradeAddress']"); + } + } catch (final Exception e) { + // Exception was already logged + return null; + } - return getAddressFromNodeList(nl); - } + return getAddressFromNodeList(nl); + } - /** - * returns an instance of PostalTradeAddress for ShipToTradeParty section - * - * @return an instance of PostalTradeAddress - */ - public PostalTradeAddress getDeliveryTradePartyAddress() { + /** + * returns an instance of PostalTradeAddress for ShipToTradeParty section + * + * @return an instance of PostalTradeAddress + */ + public PostalTradeAddress getDeliveryTradePartyAddress() { - final NodeList nl; - try { - if (getVersion() == 1) { - nl = getNodeListByPath("//*[local-name() = 'CrossIndustryDocument']//*[local-name() = 'SpecifiedSupplyChainTradeTransaction']//*[local-name() = 'ApplicableSupplyChainTradeDelivery']//*[local-name() = 'ShipToTradeParty']//*[local-name() = 'PostalTradeAddress']"); - } else { - nl = getNodeListByPath("//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeDelivery']//*[local-name() = 'ShipToTradeParty']//*[local-name() = 'PostalTradeAddress']"); - } - } catch (final Exception e) { - // Exception was already logged - return null; - } + final NodeList nl; + try { + if (getVersion() == 1) { + nl = getNodeListByPath("//*[local-name() = 'CrossIndustryDocument']//*[local-name() = 'SpecifiedSupplyChainTradeTransaction']//*[local-name() = 'ApplicableSupplyChainTradeDelivery']//*[local-name() = 'ShipToTradeParty']//*[local-name() = 'PostalTradeAddress']"); + } else { + nl = getNodeListByPath("//*[local-name() = 'CrossIndustryInvoice']//*[local-name() = 'SupplyChainTradeTransaction']//*[local-name() = 'ApplicableHeaderTradeDelivery']//*[local-name() = 'ShipToTradeParty']//*[local-name() = 'PostalTradeAddress']"); + } + } catch (final Exception e) { + // Exception was already logged + return null; + } - return getAddressFromNodeList(nl); - } + return getAddressFromNodeList(nl); + } - private PostalTradeAddress getAddressFromNodeList(NodeList nl) { - final PostalTradeAddress address = new PostalTradeAddress(); + private PostalTradeAddress getAddressFromNodeList(NodeList nl) { + final PostalTradeAddress address = new PostalTradeAddress(); - if (nl != null) { - for (int i = 0; i < nl.getLength(); i++) { - Node n = nl.item(i); - final NodeList nodes = n.getChildNodes(); - for (int j = 0; j < nodes.getLength(); j++) { - n = nodes.item(j); - final short nodeType = n.getNodeType(); - if ((nodeType == Node.ELEMENT_NODE) && (n.getLocalName() != null)) { - switch (n.getLocalName()) { - case "PostcodeCode": - address.setPostCodeCode(""); - if (n.getFirstChild() != null) { - address.setPostCodeCode(n.getFirstChild().getNodeValue()); - } - break; - case "LineOne": - address.setLineOne(""); - if (n.getFirstChild() != null) { - address.setLineOne(n.getFirstChild().getNodeValue()); - } - break; - case "LineTwo": - address.setLineTwo(""); - if (n.getFirstChild() != null) { - address.setLineTwo(n.getFirstChild().getNodeValue()); - } - break; - case "LineThree": - address.setLineThree(""); - if (n.getFirstChild() != null) { - address.setLineThree(n.getFirstChild().getNodeValue()); - } - break; - case "CityName": - address.setCityName(""); - if (n.getFirstChild() != null) { - address.setCityName(n.getFirstChild().getNodeValue()); - } - break; - case "CountryID": - address.setCountryID(""); - if (n.getFirstChild() != null) { - address.setCountryID(n.getFirstChild().getNodeValue()); - } - break; - case "CountrySubDivisionName": - address.setCountrySubDivisionName(""); - if (n.getFirstChild() != null) { - address.setCountrySubDivisionName(n.getFirstChild().getNodeValue()); - } - break; - } - } - } - } - } - return address; - } + if (nl != null) { + for (int i = 0; i < nl.getLength(); i++) { + Node n = nl.item(i); + final NodeList nodes = n.getChildNodes(); + for (int j = 0; j < nodes.getLength(); j++) { + n = nodes.item(j); + final short nodeType = n.getNodeType(); + if ((nodeType == Node.ELEMENT_NODE) && (n.getLocalName() != null)) { + switch (n.getLocalName()) { + case "PostcodeCode": + address.setPostCodeCode(""); + if (n.getFirstChild() != null) { + address.setPostCodeCode(n.getFirstChild().getNodeValue()); + } + break; + case "LineOne": + address.setLineOne(""); + if (n.getFirstChild() != null) { + address.setLineOne(n.getFirstChild().getNodeValue()); + } + break; + case "LineTwo": + address.setLineTwo(""); + if (n.getFirstChild() != null) { + address.setLineTwo(n.getFirstChild().getNodeValue()); + } + break; + case "LineThree": + address.setLineThree(""); + if (n.getFirstChild() != null) { + address.setLineThree(n.getFirstChild().getNodeValue()); + } + break; + case "CityName": + address.setCityName(""); + if (n.getFirstChild() != null) { + address.setCityName(n.getFirstChild().getNodeValue()); + } + break; + case "CountryID": + address.setCountryID(""); + if (n.getFirstChild() != null) { + address.setCountryID(n.getFirstChild().getNodeValue()); + } + break; + case "CountrySubDivisionName": + address.setCountrySubDivisionName(""); + if (n.getFirstChild() != null) { + address.setCountrySubDivisionName(n.getFirstChild().getNodeValue()); + } + break; + } + } + } + } + } + return address; + } - /** - * returns a list of LineItems - * @deprecated use invoiceimporter getZFItems - * - * @return a List of LineItem instances - */ - @Deprecated - public List getLineItemList() { - final List nodeList = getLineItemNodes(); - final List lineItemList = new ArrayList<>(); + /** + * returns a list of LineItems + * @deprecated use invoiceimporter getZFItems + * + * @return a List of LineItem instances + */ + @Deprecated + public List getLineItemList() { + final List nodeList = getLineItemNodes(); + final List lineItemList = new ArrayList<>(); - for (final Node n : nodeList) { - final Item lineItem = new Item(null, null, null); - lineItem.setProduct(new Product(null, null, null, null)); + for (final Node n : nodeList) { + final Item lineItem = new Item(null, null, null); + lineItem.setProduct(new Product(null, null, null, null)); - final NodeList nl = n.getChildNodes(); - for (int i = 0; i < nl.getLength(); i++) { - final Node nn = nl.item(i); - Node node = null; - if (nn.getLocalName() != null) { - switch (nn.getLocalName()) { - case "SpecifiedLineTradeAgreement": - case "SpecifiedSupplyChainTradeAgreement": + final NodeList nl = n.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + final Node nn = nl.item(i); + Node node = null; + if (nn.getLocalName() != null) { + switch (nn.getLocalName()) { + case "SpecifiedLineTradeAgreement": + case "SpecifiedSupplyChainTradeAgreement": - node = getNodeByName(nn.getChildNodes(), "NetPriceProductTradePrice"); - if (node != null) { - final NodeList tradeAgreementChildren = node.getChildNodes(); - node = getNodeByName(tradeAgreementChildren, "ChargeAmount"); - lineItem.setPrice(XMLTools.tryBigDecimal(node)); - node = getNodeByName(tradeAgreementChildren, "BasisQuantity"); - if (node != null && node.getAttributes() != null) { - final Node unitCodeAttribute = node.getAttributes().getNamedItem("unitCode"); - if (unitCodeAttribute != null) { - lineItem.getProduct().setUnit(unitCodeAttribute.getNodeValue()); - } - } - } + node = getNodeByName(nn.getChildNodes(), "NetPriceProductTradePrice"); + if (node != null) { + final NodeList tradeAgreementChildren = node.getChildNodes(); + node = getNodeByName(tradeAgreementChildren, "ChargeAmount"); + lineItem.setPrice(XMLTools.tryBigDecimal(node)); + node = getNodeByName(tradeAgreementChildren, "BasisQuantity"); + if (node != null && node.getAttributes() != null) { + final Node unitCodeAttribute = node.getAttributes().getNamedItem("unitCode"); + if (unitCodeAttribute != null) { + lineItem.getProduct().setUnit(unitCodeAttribute.getNodeValue()); + } + } + } - node = getNodeByName(nn.getChildNodes(), "GrossPriceProductTradePrice"); - if (node != null) { - node = getNodeByName(node.getChildNodes(), "ChargeAmount"); - lineItem.setGrossPrice(XMLTools.tryBigDecimal(node)); - } - break; + node = getNodeByName(nn.getChildNodes(), "GrossPriceProductTradePrice"); + if (node != null) { + node = getNodeByName(node.getChildNodes(), "ChargeAmount"); + lineItem.setGrossPrice(XMLTools.tryBigDecimal(node)); + } + break; - case "AssociatedDocumentLineDocument": + case "AssociatedDocumentLineDocument": - node = getNodeByName(nn.getChildNodes(), "LineID"); - lineItem.setId(XMLTools.getNodeValue(node)); - break; + node = getNodeByName(nn.getChildNodes(), "LineID"); + lineItem.setId(XMLTools.getNodeValue(node)); + break; - case "SpecifiedTradeProduct": - node = getNodeByName(nn.getChildNodes(), "GlobalID"); - if (node != null) { - SchemedID globalId = new SchemedID() - .setScheme(node.getAttributes() - .getNamedItem("schemeID").getNodeValue()) - .setId(XMLTools.getNodeValue(node)); - lineItem.getProduct().addGlobalID(globalId); - } - node = getNodeByName(nn.getChildNodes(), "SellerAssignedID"); - lineItem.getProduct().setSellerAssignedID(XMLTools.getNodeValue(node)); + case "SpecifiedTradeProduct": + node = getNodeByName(nn.getChildNodes(), "GlobalID"); + if (node != null) { + SchemedID globalId = new SchemedID() + .setScheme(node.getAttributes() + .getNamedItem("schemeID").getNodeValue()) + .setId(XMLTools.getNodeValue(node)); + lineItem.getProduct().addGlobalID(globalId); + } + node = getNodeByName(nn.getChildNodes(), "SellerAssignedID"); + lineItem.getProduct().setSellerAssignedID(XMLTools.getNodeValue(node)); - node = getNodeByName(nn.getChildNodes(), "BuyerAssignedID"); - lineItem.getProduct().setBuyerAssignedID(XMLTools.getNodeValue(node)); + node = getNodeByName(nn.getChildNodes(), "BuyerAssignedID"); + lineItem.getProduct().setBuyerAssignedID(XMLTools.getNodeValue(node)); - node = getNodeByName(nn.getChildNodes(), "Name"); - lineItem.getProduct().setName(XMLTools.getNodeValue(node)); + node = getNodeByName(nn.getChildNodes(), "Name"); + lineItem.getProduct().setName(XMLTools.getNodeValue(node)); - node = getNodeByName(nn.getChildNodes(), "Description"); - lineItem.getProduct().setDescription(XMLTools.getNodeValue(node)); - break; + node = getNodeByName(nn.getChildNodes(), "Description"); + lineItem.getProduct().setDescription(XMLTools.getNodeValue(node)); + break; - case "SpecifiedLineTradeDelivery": - case "SpecifiedSupplyChainTradeDelivery": - node = getNodeByName(nn.getChildNodes(), "BilledQuantity"); - lineItem.setQuantity(XMLTools.tryBigDecimal(node)); - break; + case "SpecifiedLineTradeDelivery": + case "SpecifiedSupplyChainTradeDelivery": + node = getNodeByName(nn.getChildNodes(), "BilledQuantity"); + lineItem.setQuantity(XMLTools.tryBigDecimal(node)); + break; - case "SpecifiedLineTradeSettlement": - node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); - if (node != null) { - node = getNodeByName(node.getChildNodes(), "RateApplicablePercent"); - lineItem.getProduct().setVATPercent(XMLTools.tryBigDecimal(node)); - } + case "SpecifiedLineTradeSettlement": + node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); + if (node != null) { + node = getNodeByName(node.getChildNodes(), "RateApplicablePercent"); + lineItem.getProduct().setVATPercent(XMLTools.tryBigDecimal(node)); + } - node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); - if (node != null) { - node = getNodeByName(node.getChildNodes(), "CalculatedAmount"); - lineItem.setTax(XMLTools.tryBigDecimal(node)); - } + node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); + if (node != null) { + node = getNodeByName(node.getChildNodes(), "CalculatedAmount"); + lineItem.setTax(XMLTools.tryBigDecimal(node)); + } - node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); - if (node != null) { - node = getNodeByName(node.getChildNodes(), "CategoryCode"); - if(node != null){ - lineItem.getProduct().setTaxCategoryCode(XMLTools.getNodeValue(node)); - } - } + node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); + if (node != null) { + node = getNodeByName(node.getChildNodes(), "CategoryCode"); + if (node != null) { + lineItem.getProduct().setTaxCategoryCode(XMLTools.getNodeValue(node)); + } + } - node = getNodeByName(nn.getChildNodes(), "BillingSpecifiedPeriod"); - if (node != null) { - final Node start = getNodeByName(node.getChildNodes(), "StartDateTime"); - Node dateTimeStart = null; - if (start != null) { - dateTimeStart = getNodeByName(start.getChildNodes(), "DateTimeString"); - } - final Node end = getNodeByName(node.getChildNodes(), "EndDateTime"); - Node dateTimeEnd = null; - if (end != null) { - dateTimeEnd = getNodeByName(end.getChildNodes(), "DateTimeString"); - } - lineItem.setDetailedDeliveryPeriod(XMLTools.tryDate(dateTimeStart), XMLTools.tryDate(dateTimeEnd)); - } + node = getNodeByName(nn.getChildNodes(), "BillingSpecifiedPeriod"); + if (node != null) { + final Node start = getNodeByName(node.getChildNodes(), "StartDateTime"); + Node dateTimeStart = null; + if (start != null) { + dateTimeStart = getNodeByName(start.getChildNodes(), "DateTimeString"); + } + final Node end = getNodeByName(node.getChildNodes(), "EndDateTime"); + Node dateTimeEnd = null; + if (end != null) { + dateTimeEnd = getNodeByName(end.getChildNodes(), "DateTimeString"); + } + lineItem.setDetailedDeliveryPeriod(XMLTools.tryDate(dateTimeStart), XMLTools.tryDate(dateTimeEnd)); + } - node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementLineMonetarySummation"); - if (node != null) { - node = getNodeByName(node.getChildNodes(), "LineTotalAmount"); - lineItem.setLineTotalAmount(XMLTools.tryBigDecimal(node)); - } - break; - case "SpecifiedSupplyChainTradeSettlement": - //ZF 1! + node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementLineMonetarySummation"); + if (node != null) { + node = getNodeByName(node.getChildNodes(), "LineTotalAmount"); + lineItem.setLineTotalAmount(XMLTools.tryBigDecimal(node)); + } + break; + case "SpecifiedSupplyChainTradeSettlement": + // ZF 1! - node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); - if (node != null) { - node = getNodeByName(node.getChildNodes(), "ApplicablePercent"); - lineItem.getProduct().setVATPercent(XMLTools.tryBigDecimal(node)); - } + node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); + if (node != null) { + node = getNodeByName(node.getChildNodes(), "ApplicablePercent"); + lineItem.getProduct().setVATPercent(XMLTools.tryBigDecimal(node)); + } - node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); - if (node != null) { - node = getNodeByName(node.getChildNodes(), "CalculatedAmount"); - lineItem.setTax(XMLTools.tryBigDecimal(node)); - } + node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); + if (node != null) { + node = getNodeByName(node.getChildNodes(), "CalculatedAmount"); + lineItem.setTax(XMLTools.tryBigDecimal(node)); + } - node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementMonetarySummation"); - if (node != null) { - node = getNodeByName(node.getChildNodes(), "LineTotalAmount"); - lineItem.setLineTotalAmount(XMLTools.tryBigDecimal(node)); - } - break; - } - } - } - lineItemList.add(lineItem); - } - return lineItemList; - } + node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementMonetarySummation"); + if (node != null) { + node = getNodeByName(node.getChildNodes(), "LineTotalAmount"); + lineItem.setLineTotalAmount(XMLTools.tryBigDecimal(node)); + } + break; + } + } + } + lineItemList.add(lineItem); + } + return lineItemList; + } - /** - * returns a List of LineItem Nodes from ZUGFeRD XML - * - * @return a List of Node instances - */ - public List getLineItemNodes() { - final List lineItemNodes = new ArrayList<>(); - NodeList nl = null; - try { - nl = getNodeListByPath("//*[local-name() = 'IncludedSupplyChainTradeLineItem']"); + /** + * returns a List of LineItem Nodes from ZUGFeRD XML + * + * @return a List of Node instances + */ + public List getLineItemNodes() { + final List lineItemNodes = new ArrayList<>(); + NodeList nl = null; + try { + nl = getNodeListByPath("//*[local-name() = 'IncludedSupplyChainTradeLineItem']"); - } catch (final Exception e) { - // Exception was already logged - } + } catch (final Exception e) { + // Exception was already logged + } - for (int i = 0; i < nl.getLength(); i++) { - final Node n = nl.item(i); - lineItemNodes.add(n); - } - return lineItemNodes; - } + for (int i = 0; i < nl.getLength(); i++) { + final Node n = nl.item(i); + lineItemNodes.add(n); + } + return lineItemNodes; + } - /** - * Returns a node, found by name. If more nodes with the same name are present, the first occurence will be returned - * - * @param nl - A NodeList which may contains the searched node - * @param name The nodes name - * @return a Node or null, if nothing is found - */ - private Node getNodeByName(NodeList nl, String name) { - for (int i = 0; i < nl.getLength(); i++) { - if ((nl.item(i).getLocalName() != null) && (nl.item(i).getLocalName().equals(name))) { - return nl.item(i); - } else if (nl.item(i).getChildNodes().getLength() > 0) { - final Node node = getNodeByName(nl.item(i).getChildNodes(), name); - if (node != null) { - return node; - } - } - } - return null; - } + /** + * Returns a node, found by name. If more nodes with the same name are present, the first occurence will be returned + * + * @param nl - A NodeList which may contains the searched node + * @param name The nodes name + * @return a Node or null, if nothing is found + */ + private Node getNodeByName(NodeList nl, String name) { + for (int i = 0; i < nl.getLength(); i++) { + if ((nl.item(i).getLocalName() != null) && (nl.item(i).getLocalName().equals(name))) { + return nl.item(i); + } else if (nl.item(i).getChildNodes().getLength() > 0) { + final Node node = getNodeByName(nl.item(i).getChildNodes(), name); + if (node != null) { + return node; + } + } + } + return null; + } - /** - * Get a NodeList by providing an path - * - * @param path a compliable Path - * @return a Nodelist or null, if an error occurs - */ - public NodeList getNodeListByPath(String path) { + /** + * Get a NodeList by providing an path + * + * @param path a compliable Path + * @return a Nodelist or null, if an error occurs + */ + public NodeList getNodeListByPath(String path) { - final XPathFactory xpathFact = XPathFactory.newInstance(); - final XPath xPath = xpathFact.newXPath(); - final String s = path; + final XPathFactory xpathFact = XPathFactory.newInstance(); + final XPath xPath = xpathFact.newXPath(); + final String s = path; - try { - final XPathExpression xpr = xPath.compile(s); - return (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - } catch (final Exception e) { - LOGGER.error("Failed to evaluate XPath", e); - return null; - } - } + try { + final XPathExpression xpr = xPath.compile(s); + return (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + } catch (final Exception e) { + LOGGER.error("Failed to evaluate XPath", e); + return null; + } + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index 0298847..4d359f6 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -23,7 +23,10 @@ org.openrewrite.config.CompositeRecipe import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.*; -import java.io.*; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -38,1049 +41,1049 @@ public class ZUGFeRDInvoiceImporter { - private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDInvoiceImporter.class.getCanonicalName()); // log - /** - * map filenames of additional XML files to their contents - */ - protected final HashMap additionalXMLs = new HashMap<>(); - /** - * map filenames of all embedded files in the respective PDF - */ - protected final ArrayList PDFAttachments = new ArrayList<>(); - /** - * if metadata has been found - */ - protected boolean containsMeta = false; - /** - * Raw XML form of the extracted data - may be directly obtained. - */ - protected byte[] rawXML = null; - /** - * XMP metadata - */ - protected String xmpString = null; // XMP metadata - /** - * parsed Document - */ - protected Document document; - /*** - * automatically parse into importedInvoice - */ - protected boolean parseAutomatically = true; - protected Integer version; - protected CalculatedInvoice importedInvoice = null; - protected boolean recalcPrice = false; - protected boolean ignoreCalculationErrors = false; + private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDInvoiceImporter.class.getCanonicalName()); // log + /** + * map filenames of additional XML files to their contents + */ +protected final HashMap additionalXMLs = new HashMap<>(); + /** + * map filenames of all embedded files in the respective PDF + */ + protected final ArrayList PDFAttachments = new ArrayList<>(); + /** + * if metadata has been found + */ + protected boolean containsMeta = false; + /** + * Raw XML form of the extracted data - may be directly obtained. + */ + protected byte[] rawXML = null; + /** + * XMP metadata + */ + protected String xmpString = null; // XMP metadata + /** + * parsed Document + */ +protected Document document; + /*** + * automatically parse into importedInvoice + */ + protected boolean parseAutomatically = true; + protected Integer version; + protected CalculatedInvoice importedInvoice = null; + protected boolean recalcPrice = false; + protected boolean ignoreCalculationErrors = false; - public ZUGFeRDInvoiceImporter() { - //constructor for extending classes - } + public ZUGFeRDInvoiceImporter() { + // constructor for extending classes + } - public ZUGFeRDInvoiceImporter(String pdfFilename) { - setPDFFilename(pdfFilename); - } + public ZUGFeRDInvoiceImporter(String pdfFilename) { + setPDFFilename(pdfFilename); + } - public ZUGFeRDInvoiceImporter(InputStream pdfStream) { - setInputStream(pdfStream); - } + public ZUGFeRDInvoiceImporter(InputStream pdfStream) { + setInputStream(pdfStream); + } - public void setPDFFilename(String pdfFilename) { - try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) { - extractLowLevel(bis); - } catch (final IOException e) { - LOGGER.error("Failed to extract ZUGFeRD data", e); - throw new ZUGFeRDExportException(e); - } - } + public void setPDFFilename(String pdfFilename) { + try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) { + extractLowLevel(bis); + } catch (final IOException e) { + LOGGER.error("Failed to extract ZUGFeRD data", e); + throw new ZUGFeRDExportException(e); + } + } - public void setInputStream(InputStream pdfStream) { - try { - extractLowLevel(pdfStream); - } catch (final IOException e) { - LOGGER.error("Failed to extract ZUGFeRD data", e); - throw new ZUGFeRDExportException(e); - } - } + public void setInputStream(InputStream pdfStream) { + try { + extractLowLevel(pdfStream); + } catch (final IOException e) { + LOGGER.error("Failed to extract ZUGFeRD data", e); + throw new ZUGFeRDExportException(e); + } + } - /*** - * return the file names of all files embedded into the PDF - * @see ZUGFeRDInvoiceImporter for XML embedded files please use ZUGFeRDInvoiceImporter.getFileAttachmentsXML - * @return a ArrayList of FileAttachments, empty if none - */ - public List getFileAttachmentsPDF() { - return PDFAttachments; - } + /*** + * return the file names of all files embedded into the PDF + * @see ZUGFeRDInvoiceImporter for XML embedded files please use ZUGFeRDInvoiceImporter.getFileAttachmentsXML + * @return a ArrayList of FileAttachments, empty if none + */ + public List getFileAttachmentsPDF() { + return PDFAttachments; + } - /** - * Extracts a ZUGFeRD invoice from a PDF document represented by an input stream. Errors are reported via exception handling. - * - * @param inStream a inputstream of a pdf file - */ - private void extractLowLevel(InputStream inStream) throws IOException { - BufferedInputStream pdfStream = new BufferedInputStream(inStream); - byte[] pad = new byte[4]; - pdfStream.mark(0); - pdfStream.read(pad); - pdfStream.reset(); - byte[] pdfSignature = {'%', 'P', 'D', 'F'}; - if (Arrays.equals(pad, pdfSignature)) { // we have a pdf + /** + * Extracts a ZUGFeRD invoice from a PDF document represented by an input stream. Errors are reported via exception handling. + * + * @param inStream a inputstream of a pdf file + */ + private void extractLowLevel(InputStream inStream) throws IOException { + BufferedInputStream pdfStream = new BufferedInputStream(inStream); + byte[] pad = new byte[4]; + pdfStream.mark(0); + pdfStream.read(pad); + pdfStream.reset(); + byte[] pdfSignature = {'%', 'P', 'D', 'F'}; + if (Arrays.equals(pad, pdfSignature)) { // we have a pdf - try { - PDDocument doc = Loader.loadPDF(IOUtils.toByteArray(pdfStream)); - // PDDocumentInformation info = doc.getDocumentInformation(); - final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); - //start + try { + PDDocument doc = Loader.loadPDF(IOUtils.toByteArray(pdfStream)); + // PDDocumentInformation info = doc.getDocumentInformation(); + final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); + // start - if (doc.getDocumentCatalog() == null || doc.getDocumentCatalog().getMetadata() == null) { - LOGGER.info("no-xmlpart"); - return; - } + if (doc.getDocumentCatalog() == null || doc.getDocumentCatalog().getMetadata() == null) { + LOGGER.info("no-xmlpart"); + return; + } - final InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata(); + final InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata(); - xmpString = new String(XMLTools.getBytesFromStream(XMP), StandardCharsets.UTF_8); + xmpString = new String(XMLTools.getBytesFromStream(XMP), StandardCharsets.UTF_8); - final PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles(); - if (etn == null) { - return; - } + final PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles(); + if (etn == null) { + return; + } - final Map efMap = etn.getNames(); - // String filePath = "/tmp/"; + final Map efMap = etn.getNames(); + // String filePath = "/tmp/"; - if (efMap != null) { - extractFiles(efMap); // see - // https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/ - } else { + if (efMap != null) { + extractFiles(efMap); // see + // https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/ + } else { - final List> kids = etn.getKids(); - if (kids == null) { - return; - } - for (final PDNameTreeNode node : kids) { - final Map namesL = node.getNames(); - extractFiles(namesL); - } - } - } catch (Exception e) { - LOGGER.error("Failed to parse PDF", e); - //ignore otherwise - } - } else { - // no PDF probably XML - containsMeta = true; - setRawXML(XMLTools.getBytesFromStream(pdfStream)); + final List> kids = etn.getKids(); + if (kids == null) { + return; + } + for (final PDNameTreeNode node : kids) { + final Map namesL = node.getNames(); + extractFiles(namesL); + } + } + } catch (Exception e) { + LOGGER.error("Failed to parse PDF", e); + // ignore otherwise + } + } else { + // no PDF probably XML + containsMeta = true; + setRawXML(XMLTools.getBytesFromStream(pdfStream)); - } - } + } + } - /*** - * have the item prices be determined from the line total. - * That's a workaround for some invoices which just put 0 as item price - */ - public void doRecalculateItemPricesFromLineTotals() { - recalcPrice = true; - } + /*** + * have the item prices be determined from the line total. + * That's a workaround for some invoices which just put 0 as item price + */ + public void doRecalculateItemPricesFromLineTotals() { + recalcPrice = true; + } - /*** - * do not raise ParseExceptions even if the reproduced invoice total does not match the given value - */ - public void doIgnoreCalculationErrors() { - ignoreCalculationErrors = true; - } + /*** + * do not raise ParseExceptions even if the reproduced invoice total does not match the given value + */ + public void doIgnoreCalculationErrors() { + ignoreCalculationErrors = true; + } - /*** - * sets th pdf attachments, and if a file is recognized (e.g. a factur-x.xml) triggers processing - * @param names the Hashmap of String, PDComplexFileSpecification - * @throws IOException - */ - private void extractFiles(Map names) throws IOException { - for (final String alias : names.keySet()) { + /*** + * sets th pdf attachments, and if a file is recognized (e.g. a factur-x.xml) triggers processing + * @param names the Hashmap of String, PDComplexFileSpecification + * @throws IOException + */ + private void extractFiles(Map names) throws IOException { + for (final String alias : names.keySet()) { - final PDComplexFileSpecification fileSpec = names.get(alias); - final String filename = fileSpec.getFilename(); - /** - * filenames for invoice data (ZUGFeRD v1 and v2, Factur-X) - */ + final PDComplexFileSpecification fileSpec = names.get(alias); + final String filename = fileSpec.getFilename(); + /** + * filenames for invoice data (ZUGFeRD v1 and v2, Factur-X) + */ - final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); - if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml")) || filename.equals("xrechnung.xml") || filename.equals("order-x.xml") || filename.equals("cida.xml")) { - containsMeta = true; + final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); + if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml")) || filename.equals("xrechnung.xml") || filename.equals("order-x.xml") || filename.equals("cida.xml")) { + containsMeta = true; - // String embeddedFilename = filePath + filename; - // File file = new File(filePath + filename); - // System.out.println("Writing " + embeddedFilename); - // ByteArrayOutputStream fileBytes=new - // ByteArrayOutputStream(); - // FileOutputStream fos = new FileOutputStream(file); + // String embeddedFilename = filePath + filename; + // File file = new File(filePath + filename); + // System.out.println("Writing " + embeddedFilename); + // ByteArrayOutputStream fileBytes=new + // ByteArrayOutputStream(); + // FileOutputStream fos = new FileOutputStream(file); - setRawXML(embeddedFile.toByteArray()); + setRawXML(embeddedFile.toByteArray()); - // fos.write(embeddedFile.getByteArray()); - // fos.close(); - } - if (filename.startsWith("additional_data")) { - additionalXMLs.put(filename, embeddedFile.toByteArray()); - } - PDFAttachments.add(new FileAttachment(filename, embeddedFile.getSubtype(), "Data", embeddedFile.toByteArray())); - } - } + // fos.write(embeddedFile.getByteArray()); + // fos.close(); + } + if (filename.startsWith("additional_data")) { + additionalXMLs.put(filename, embeddedFile.toByteArray()); + } + PDFAttachments.add(new FileAttachment(filename, embeddedFile.getSubtype(), "Data", embeddedFile.toByteArray())); + } + } - /*** - * set the xml of a CII invoice - * @param rawXML the xml string - * @param doParse automatically parse input for zugferdImporter (not ZUGFeRDInvoiceImporter) - * @throws IOException if parsing xml throws it (unlikely its string based) - */ - public void setRawXML(byte[] rawXML, boolean doParse) throws IOException { - this.containsMeta = true; - this.rawXML = rawXML; - this.version = null; - parseAutomatically = doParse; + /*** + * set the xml of a CII invoice + * @param rawXML the xml string + * @param doParse automatically parse input for zugferdImporter (not ZUGFeRDInvoiceImporter) + * @throws IOException if parsing xml throws it (unlikely its string based) + */ + public void setRawXML(byte[] rawXML, boolean doParse) throws IOException { + this.containsMeta = true; + this.rawXML = rawXML; + this.version = null; + parseAutomatically = doParse; - try { - setDocument(); - } catch (ParserConfigurationException | SAXException | ParseException e) { - LOGGER.error("Failed to parse XML", e); - throw new ZUGFeRDExportException(e); - } + try { + setDocument(); + } catch (ParserConfigurationException | SAXException | ParseException e) { + LOGGER.error("Failed to parse XML", e); + throw new ZUGFeRDExportException(e); + } - } + } - /*** - * set the xml of a CII invoice, simple version - * @param rawXML the cii(?) as a string - * @throws IOException if parsing xml throws it (unlikely its string based) - */ - public void setRawXML(byte[] rawXML) throws IOException { - setRawXML(rawXML, true); - } + /*** + * set the xml of a CII invoice, simple version + * @param rawXML the cii(?) as a string + * @throws IOException if parsing xml throws it (unlikely its string based) + */ + public void setRawXML(byte[] rawXML) throws IOException { + setRawXML(rawXML, true); + } - private void setDocument() throws ParserConfigurationException, IOException, SAXException, ParseException { - final DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); - xmlFact.setNamespaceAware(true); - final DocumentBuilder builder = xmlFact.newDocumentBuilder(); - final ByteArrayInputStream is = new ByteArrayInputStream(rawXML); - /// is.skip(guessBOMSize(is)); - document = builder.parse(is); - if (parseAutomatically) { - try { - importedInvoice = new CalculatedInvoice(); - extractInto(importedInvoice); - } catch (XPathExpressionException e) { - throw new RuntimeException(e); - } - } - } + private void setDocument() throws ParserConfigurationException, IOException, SAXException, ParseException { + final DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); + xmlFact.setNamespaceAware(true); + final DocumentBuilder builder = xmlFact.newDocumentBuilder(); + final ByteArrayInputStream is = new ByteArrayInputStream(rawXML); + // / is.skip(guessBOMSize(is)); + document = builder.parse(is); + if (parseAutomatically) { + try { + importedInvoice = new CalculatedInvoice(); + extractInto(importedInvoice); + } catch (XPathExpressionException e) { + throw new RuntimeException(e); + } + } + } - public void setID(String id) { - String ud = id; - } + 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 - * @return the parsed invoice object - * @throws XPathExpressionException if xpath could not be evaluated - * @throws ParseException if the grand total of the parsed invoice could not be replicated with the new invoice - */ - public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseException { + /*** + * This will parse a XML into the given invoice object + * @param zpp the invoice to be altered + * @return the parsed invoice object + * @throws XPathExpressionException if xpath could not be evaluated + * @throws ParseException if the grand total of the parsed invoice could not be replicated with the new invoice + */ + public Invoice extractInto(Invoice zpp) throws XPathExpressionException, ParseException { - String number = ""; - String typeCode = null; - String deliveryPeriodStart = null; - String deliveryPeriodEnd = null; - /* - * dummywerte sind derzeit noch setDueDate setIssueDate setDeliveryDate - * setSender setRecipient setnumber bspw. due date - * //ExchangedDocument//IssueDateTime//DateTimeString : due date optional - */ - XPathFactory xpathFact = XPathFactory.newInstance(); - XPath xpath = xpathFact.newXPath(); - XPathExpression xpr = xpath.compile("//*[local-name()=\"SellerTradeParty\"]|//*[local-name()=\"AccountingSupplierParty\"]/*"); - NodeList SellerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - XPathExpression shipEx = xpath.compile("//*[local-name()=\"ShipToTradeParty\"]"); - NodeList deliveryNodes = (NodeList) shipEx.evaluate(getDocument(), XPathConstants.NODESET); - if (deliveryNodes != null) { - zpp.setDeliveryAddress(new TradeParty(deliveryNodes)); - } + String number = ""; + String typeCode = null; + String deliveryPeriodStart = null; + String deliveryPeriodEnd = null; + /* + * dummywerte sind derzeit noch setDueDate setIssueDate setDeliveryDate + * setSender setRecipient setnumber bspw. due date + * //ExchangedDocument//IssueDateTime//DateTimeString : due date optional + */ + XPathFactory xpathFact = XPathFactory.newInstance(); + XPath xpath = xpathFact.newXPath(); + XPathExpression xpr = xpath.compile("//*[local-name()=\"SellerTradeParty\"]|//*[local-name()=\"AccountingSupplierParty\"]/*"); + NodeList SellerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + XPathExpression shipEx = xpath.compile("//*[local-name()=\"ShipToTradeParty\"]"); + NodeList deliveryNodes = (NodeList) shipEx.evaluate(getDocument(), XPathConstants.NODESET); + if (deliveryNodes != null) { + zpp.setDeliveryAddress(new TradeParty(deliveryNodes)); + } - List includedNotes = new ArrayList<>(); + List 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); - } + // 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); + 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 -> { + 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)); - }); - }); + 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) - ); + 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()=\"BuyerTradeParty\"]|//*[local-name()=\"AccountingCustomerParty\"]/*"); + NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - xpr = xpath.compile("//*[local-name()=\"PayeeTradeParty\"]"); - NodeList payeeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + 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); + // 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); -// }); -// } -// } +// 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); + xpr = xpath.compile("//*[local-name()=\"ExchangedDocument\"]|//*[local-name()=\"HeaderExchangedDocument\"]"); + NodeList ExchangedDocumentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - xpr = xpath.compile("//*[local-name()=\"GrandTotalAmount\"]|//*[local-name()=\"PayableAmount\"]"); - BigDecimal expectedGrandTotal = null; - NodeList totalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - if (totalNodes.getLength() > 0) { - expectedGrandTotal = new BigDecimal(XMLTools.trimOrNull(totalNodes.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).setGrandTotal(expectedGrandTotal); - } - } + xpr = xpath.compile("//*[local-name()=\"GrandTotalAmount\"]|//*[local-name()=\"PayableAmount\"]"); + BigDecimal expectedGrandTotal = null; + NodeList totalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + if (totalNodes.getLength() > 0) { + expectedGrandTotal = new BigDecimal(XMLTools.trimOrNull(totalNodes.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).setGrandTotal(expectedGrandTotal); + } + } - 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()=\"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()=\"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()=\"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); - BigDecimal duePayableAmount = null; - if (lineDueNodes.getLength() > 0) { - duePayableAmount = new BigDecimal(XMLTools.trimOrNull(lineDueNodes.item(0))); - if (zpp instanceof CalculatedInvoice) { - ((CalculatedInvoice) zpp).setDuePayable(duePayableAmount); - } - } + xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"DuePayableAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"PayableAmount\"]"); + NodeList lineDueNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + BigDecimal duePayableAmount = null; + if (lineDueNodes.getLength() > 0) { + duePayableAmount = new BigDecimal(XMLTools.trimOrNull(lineDueNodes.item(0))); + if (zpp instanceof CalculatedInvoice) { + ((CalculatedInvoice) zpp).setDuePayable(duePayableAmount); + } + } - Date issueDate = null; - Date dueDate = null; - Date deliveryDate = null; - String despatchAdviceReferencedDocument = null; + 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(); - for (int documentChildIndex = 0; documentChildIndex < exchangedDocumentChilds.getLength(); documentChildIndex++) { - Node item = exchangedDocumentChilds.item(documentChildIndex); - if ((item.getLocalName() != null) && (item.getLocalName().equals("ID"))) { - number = XMLTools.trimOrNull(item); - } - if ((item.getLocalName() != null) && (item.getLocalName().equals("TypeCode"))) { - typeCode = XMLTools.trimOrNull(item); - } - if ((item.getLocalName() != null) && (item.getLocalName().equals("IssueDateTime"))) { - NodeList issueDateTimeChilds = item.getChildNodes(); - for (int issueDateChildIndex = 0; issueDateChildIndex < issueDateTimeChilds.getLength(); issueDateChildIndex++) { - if ((issueDateTimeChilds.item(issueDateChildIndex).getLocalName() != null) - && (issueDateTimeChilds.item(issueDateChildIndex).getLocalName().equals("DateTimeString"))) { - issueDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(issueDateTimeChilds.item(issueDateChildIndex))); - } - } - } - if ((item.getLocalName() != null) && (item.getLocalName().equals("IncludedNote"))) { - 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)); - } - } - 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); - String rootNode = extractString("local-name(/*)"); - if (rootNode.equals("Invoice")) { - // UBL... - number = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"ID\"]").trim(); - typeCode = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"InvoiceTypeCode\"]").trim(); - String issueDateStr = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"IssueDate\"]").trim(); - if (issueDateStr.length()>0) { - issueDate = new SimpleDateFormat("yyyy-MM-dd").parse(issueDateStr); - } - String dueDt = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"DueDate\"]").trim(); - if (dueDt.length() > 0) { - dueDate = new SimpleDateFormat("yyyy-MM-dd").parse(dueDt); - } - String deliveryDt = extractString("//*[local-name()=\"Delivery\"]/*[local-name()=\"ActualDeliveryDate\"]").trim(); - if (deliveryDt.length() > 0) { - deliveryDate = new SimpleDateFormat("yyyy-MM-dd").parse(deliveryDt); - } - } + for (int i = 0; i < ExchangedDocumentNodes.getLength(); i++) { + Node exchangedDocumentNode = ExchangedDocumentNodes.item(i); + NodeList exchangedDocumentChilds = exchangedDocumentNode.getChildNodes(); + for (int documentChildIndex = 0; documentChildIndex < exchangedDocumentChilds.getLength(); documentChildIndex++) { + Node item = exchangedDocumentChilds.item(documentChildIndex); + if ((item.getLocalName() != null) && (item.getLocalName().equals("ID"))) { + number = XMLTools.trimOrNull(item); + } + if ((item.getLocalName() != null) && (item.getLocalName().equals("TypeCode"))) { + typeCode = XMLTools.trimOrNull(item); + } + if ((item.getLocalName() != null) && (item.getLocalName().equals("IssueDateTime"))) { + NodeList issueDateTimeChilds = item.getChildNodes(); + for (int issueDateChildIndex = 0; issueDateChildIndex < issueDateTimeChilds.getLength(); issueDateChildIndex++) { + if ((issueDateTimeChilds.item(issueDateChildIndex).getLocalName() != null) + && (issueDateTimeChilds.item(issueDateChildIndex).getLocalName().equals("DateTimeString"))) { + issueDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(issueDateTimeChilds.item(issueDateChildIndex))); + } + } + } + if ((item.getLocalName() != null) && (item.getLocalName().equals("IncludedNote"))) { + 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)); + } + } + 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); + String rootNode = extractString("local-name(/*)"); + if (rootNode.equals("Invoice")) { + // UBL... + number = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"ID\"]").trim(); + typeCode = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"InvoiceTypeCode\"]").trim(); + String issueDateStr = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"IssueDate\"]").trim(); + if (issueDateStr.length() > 0) { + issueDate = new SimpleDateFormat("yyyy-MM-dd").parse(issueDateStr); + } + String dueDt = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"DueDate\"]").trim(); + if (dueDt.length() > 0) { + dueDate = new SimpleDateFormat("yyyy-MM-dd").parse(dueDt); + } + String deliveryDt = extractString("//*[local-name()=\"Delivery\"]/*[local-name()=\"ActualDeliveryDate\"]").trim(); + if (deliveryDt.length() > 0) { + deliveryDate = new SimpleDateFormat("yyyy-MM-dd").parse(deliveryDt); + } + } - xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeDelivery\"]|//*[local-name()=\"Delivery\"]"); - NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + 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++) { - Node headerTradeDeliveryNode = headerTradeDeliveryNodes.item(i); - NodeList headerTradeDeliveryChilds = headerTradeDeliveryNode.getChildNodes(); - for (int deliveryChildIndex = 0; deliveryChildIndex < headerTradeDeliveryChilds.getLength(); deliveryChildIndex++) { - if (headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName() != null) { - if (headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName().equals("ActualDeliverySupplyChainEvent")) { - NodeList actualDeliveryChilds = headerTradeDeliveryChilds.item(deliveryChildIndex).getChildNodes(); - for (int actualDeliveryChildIndex = 0; actualDeliveryChildIndex < actualDeliveryChilds.getLength(); actualDeliveryChildIndex++) { - if ((actualDeliveryChilds.item(actualDeliveryChildIndex).getLocalName() != null) - && (actualDeliveryChilds.item(actualDeliveryChildIndex).getLocalName().equals("OccurrenceDateTime"))) { - NodeList occurenceChilds = actualDeliveryChilds.item(actualDeliveryChildIndex).getChildNodes(); - for (int occurenceChildIndex = 0; occurenceChildIndex < occurenceChilds.getLength(); occurenceChildIndex++) { - if ((occurenceChilds.item(occurenceChildIndex).getLocalName() != null) - && (occurenceChilds.item(occurenceChildIndex).getLocalName().equals("DateTimeString"))) { - deliveryDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(occurenceChilds.item(occurenceChildIndex))); - } - } - } - } - } + for (int i = 0; i < headerTradeDeliveryNodes.getLength(); i++) { + Node headerTradeDeliveryNode = headerTradeDeliveryNodes.item(i); + NodeList headerTradeDeliveryChilds = headerTradeDeliveryNode.getChildNodes(); + for (int deliveryChildIndex = 0; deliveryChildIndex < headerTradeDeliveryChilds.getLength(); deliveryChildIndex++) { + if (headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName() != null) { + if (headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName().equals("ActualDeliverySupplyChainEvent")) { + NodeList actualDeliveryChilds = headerTradeDeliveryChilds.item(deliveryChildIndex).getChildNodes(); + for (int actualDeliveryChildIndex = 0; actualDeliveryChildIndex < actualDeliveryChilds.getLength(); actualDeliveryChildIndex++) { + if ((actualDeliveryChilds.item(actualDeliveryChildIndex).getLocalName() != null) + && (actualDeliveryChilds.item(actualDeliveryChildIndex).getLocalName().equals("OccurrenceDateTime"))) { + NodeList occurenceChilds = actualDeliveryChilds.item(actualDeliveryChildIndex).getChildNodes(); + for (int occurenceChildIndex = 0; occurenceChildIndex < occurenceChilds.getLength(); occurenceChildIndex++) { + if ((occurenceChilds.item(occurenceChildIndex).getLocalName() != null) + && (occurenceChilds.item(occurenceChildIndex).getLocalName().equals("DateTimeString"))) { + deliveryDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(occurenceChilds.item(occurenceChildIndex))); + } + } + } + } + } - if (headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName().equals("DespatchAdviceReferencedDocument")) { - NodeList despatchAdviceChilds = headerTradeDeliveryChilds.item(deliveryChildIndex).getChildNodes(); - for (int despatchAdviceChildIndex = 0; despatchAdviceChildIndex < despatchAdviceChilds.getLength(); despatchAdviceChildIndex++) { - if (despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName() != null - && despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName().equals("IssuerAssignedID")) { - despatchAdviceReferencedDocument = XMLTools.trimOrNull(despatchAdviceChilds.item(despatchAdviceChildIndex)); - } - } - } - } - } - } + if (headerTradeDeliveryChilds.item(deliveryChildIndex).getLocalName().equals("DespatchAdviceReferencedDocument")) { + NodeList despatchAdviceChilds = headerTradeDeliveryChilds.item(deliveryChildIndex).getChildNodes(); + for (int despatchAdviceChildIndex = 0; despatchAdviceChildIndex < despatchAdviceChilds.getLength(); despatchAdviceChildIndex++) { + if (despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName() != null + && despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName().equals("IssuerAssignedID")) { + despatchAdviceReferencedDocument = XMLTools.trimOrNull(despatchAdviceChilds.item(despatchAdviceChildIndex)); + } + } + } + } + } + } - xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeAgreement\"]"); - NodeList headerTradeAgreementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - String buyerOrderIssuerAssignedID = null; - String sellerOrderIssuerAssignedID = null; - for (int i = 0; i < headerTradeAgreementNodes.getLength(); i++) { - // XMLTools.trimOrNull(nodes.item(i)))) { - Node headerTradeAgreementNode = headerTradeAgreementNodes.item(i); - NodeList headerTradeAgreementChilds = headerTradeAgreementNode.getChildNodes(); - for (int agreementChildIndex = 0; agreementChildIndex < headerTradeAgreementChilds.getLength(); agreementChildIndex++) { - if (headerTradeAgreementChilds.item(agreementChildIndex).getLocalName() != null) { - if (headerTradeAgreementChilds.item(agreementChildIndex).getLocalName().equals("BuyerOrderReferencedDocument")) { - NodeList buyerOrderChilds = headerTradeAgreementChilds.item(agreementChildIndex).getChildNodes(); - for (int buyerOrderChildIndex = 0; buyerOrderChildIndex < buyerOrderChilds.getLength(); buyerOrderChildIndex++) { - if ((buyerOrderChilds.item(buyerOrderChildIndex).getLocalName() != null) - && (buyerOrderChilds.item(buyerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) { - buyerOrderIssuerAssignedID = XMLTools.trimOrNull(buyerOrderChilds.item(buyerOrderChildIndex)); - } - } - } + xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeAgreement\"]"); + NodeList headerTradeAgreementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + String buyerOrderIssuerAssignedID = null; + String sellerOrderIssuerAssignedID = null; + for (int i = 0; i < headerTradeAgreementNodes.getLength(); i++) { + // XMLTools.trimOrNull(nodes.item(i)))) { + Node headerTradeAgreementNode = headerTradeAgreementNodes.item(i); + NodeList headerTradeAgreementChilds = headerTradeAgreementNode.getChildNodes(); + for (int agreementChildIndex = 0; agreementChildIndex < headerTradeAgreementChilds.getLength(); agreementChildIndex++) { + if (headerTradeAgreementChilds.item(agreementChildIndex).getLocalName() != null) { + if (headerTradeAgreementChilds.item(agreementChildIndex).getLocalName().equals("BuyerOrderReferencedDocument")) { + NodeList buyerOrderChilds = headerTradeAgreementChilds.item(agreementChildIndex).getChildNodes(); + for (int buyerOrderChildIndex = 0; buyerOrderChildIndex < buyerOrderChilds.getLength(); buyerOrderChildIndex++) { + if ((buyerOrderChilds.item(buyerOrderChildIndex).getLocalName() != null) + && (buyerOrderChilds.item(buyerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) { + buyerOrderIssuerAssignedID = XMLTools.trimOrNull(buyerOrderChilds.item(buyerOrderChildIndex)); + } + } + } - if (headerTradeAgreementChilds.item(agreementChildIndex).getLocalName().equals("SellerOrderReferencedDocument")) { - NodeList sellerOrderChilds = headerTradeAgreementChilds.item(agreementChildIndex).getChildNodes(); - for (int sellerOrderChildIndex = 0; sellerOrderChildIndex < sellerOrderChilds.getLength(); sellerOrderChildIndex++) { - if ((sellerOrderChilds.item(sellerOrderChildIndex).getLocalName() != null) - && (sellerOrderChilds.item(sellerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) { - sellerOrderIssuerAssignedID = XMLTools.trimOrNull(sellerOrderChilds.item(sellerOrderChildIndex)); - } - } - } - } - } + if (headerTradeAgreementChilds.item(agreementChildIndex).getLocalName().equals("SellerOrderReferencedDocument")) { + NodeList sellerOrderChilds = headerTradeAgreementChilds.item(agreementChildIndex).getChildNodes(); + for (int sellerOrderChildIndex = 0; sellerOrderChildIndex < sellerOrderChilds.getLength(); sellerOrderChildIndex++) { + if ((sellerOrderChilds.item(sellerOrderChildIndex).getLocalName() != null) + && (sellerOrderChilds.item(sellerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) { + sellerOrderIssuerAssignedID = XMLTools.trimOrNull(sellerOrderChilds.item(sellerOrderChildIndex)); + } + } + } + } + } - } + } - String currency = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"InvoiceCurrencyCode\"]|//*[local-name()=\"DocumentCurrencyCode\"]"); - zpp.setCurrency(currency); + String currency = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"InvoiceCurrencyCode\"]|//*[local-name()=\"DocumentCurrencyCode\"]"); + zpp.setCurrency(currency); - String paymentTermsDescription = extractString("//*[local-name()=\"SpecifiedTradePaymentTerms\"]/*[local-name()=\"Description\"]|//*[local-name()=\"PaymentTerms\"]/*[local-name()=\"Note\"]"); - if ((paymentTermsDescription!=null)&&(!paymentTermsDescription.isEmpty())) { - zpp.setPaymentTermDescription(paymentTermsDescription); - } + String paymentTermsDescription = extractString("//*[local-name()=\"SpecifiedTradePaymentTerms\"]/*[local-name()=\"Description\"]|//*[local-name()=\"PaymentTerms\"]/*[local-name()=\"Note\"]"); + if ((paymentTermsDescription != null) && (!paymentTermsDescription.isEmpty())) { + zpp.setPaymentTermDescription(paymentTermsDescription); + } - xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]|//*[local-name()=\"ApplicableSupplyChainTradeSettlement\"]"); - NodeList headerTradeSettlementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - List bankDetails = new ArrayList<>(); - String directDebitMandateID = null; - String IBAN = null, BIC = null; + xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]|//*[local-name()=\"ApplicableSupplyChainTradeSettlement\"]"); + NodeList headerTradeSettlementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + List bankDetails = new ArrayList<>(); + String directDebitMandateID = null; + String IBAN = null, BIC = null; - for (int i = 0; i < headerTradeSettlementNodes.getLength(); i++) { - // XMLTools.trimOrNull(nodes.item(i)))) { - Node headerTradeSettlementNode = headerTradeSettlementNodes.item(i); + for (int i = 0; i < headerTradeSettlementNodes.getLength(); i++) { + // XMLTools.trimOrNull(nodes.item(i)))) { + Node headerTradeSettlementNode = headerTradeSettlementNodes.item(i); - NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes(); - for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds.getLength(); settlementChildIndex++) { - if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) - && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradePaymentTerms"))) { - NodeList paymentTermChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); - for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) { - if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("Description"))) { - zpp.setPaymentTermDescription(paymentTermChilds.item(paymentTermChildIndex).getTextContent()); - } - if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DueDateDateTime"))) { - NodeList dueDateChilds = paymentTermChilds.item(paymentTermChildIndex).getChildNodes(); - for (int dueDateChildIndex = 0; dueDateChildIndex < dueDateChilds.getLength(); dueDateChildIndex++) { - if ((dueDateChilds.item(dueDateChildIndex).getLocalName() != null) && (dueDateChilds.item(dueDateChildIndex).getLocalName().equals("DateTimeString"))) { - dueDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(dueDateChilds.item(dueDateChildIndex))); - } - } - } - if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DirectDebitMandateID"))) { - directDebitMandateID = paymentTermChilds.item(paymentTermChildIndex).getTextContent(); - } - } - } + NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes(); + for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds.getLength(); settlementChildIndex++) { + if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) + && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradePaymentTerms"))) { + NodeList paymentTermChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); + for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) { + if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("Description"))) { + zpp.setPaymentTermDescription(paymentTermChilds.item(paymentTermChildIndex).getTextContent()); + } + if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DueDateDateTime"))) { + NodeList dueDateChilds = paymentTermChilds.item(paymentTermChildIndex).getChildNodes(); + for (int dueDateChildIndex = 0; dueDateChildIndex < dueDateChilds.getLength(); dueDateChildIndex++) { + if ((dueDateChilds.item(dueDateChildIndex).getLocalName() != null) && (dueDateChilds.item(dueDateChildIndex).getLocalName().equals("DateTimeString"))) { + dueDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(dueDateChilds.item(dueDateChildIndex))); + } + } + } + if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DirectDebitMandateID"))) { + directDebitMandateID = paymentTermChilds.item(paymentTermChildIndex).getTextContent(); + } + } + } - if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) - && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradeSettlementPaymentMeans"))) { - NodeList paymentMeansChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); - IBAN = null; - BIC = null; - for (int paymentMeansChildIndex = 0; paymentMeansChildIndex < paymentMeansChilds.getLength(); paymentMeansChildIndex++) { + if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) + && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradeSettlementPaymentMeans"))) { + NodeList paymentMeansChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); + IBAN = null; + BIC = null; + for (int paymentMeansChildIndex = 0; paymentMeansChildIndex < paymentMeansChilds.getLength(); paymentMeansChildIndex++) { - if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeePartyCreditorFinancialAccount") || paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayerPartyDebtorFinancialAccount"))) { - NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes(); - for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) { - if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("IBANID"))) {//CII - IBAN = XMLTools.trimOrNull(accountChilds.item(accountChildIndex)); - } - } - } - if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeeSpecifiedCreditorFinancialInstitution"))) { - NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes(); - for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) { - if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("BICID"))) {//CII - BIC = XMLTools.trimOrNull(accountChilds.item(accountChildIndex)); - } - } - } + if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeePartyCreditorFinancialAccount") || paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayerPartyDebtorFinancialAccount"))) { + NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes(); + for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) { + if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("IBANID"))) {// CII + IBAN = XMLTools.trimOrNull(accountChilds.item(accountChildIndex)); + } + } + } + if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeeSpecifiedCreditorFinancialInstitution"))) { + NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes(); + for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) { + if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("BICID"))) {// CII + BIC = XMLTools.trimOrNull(accountChilds.item(accountChildIndex)); + } + } + } - } - if (IBAN != null) { - BankDetails bd = new BankDetails(IBAN); - if (BIC != null) { - bd.setBIC(BIC); - } - bankDetails.add(bd); - } - } - if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) - && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("BillingSpecifiedPeriod"))) { - NodeList periodChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); - for (int periodChildIndex = 0; periodChildIndex < periodChilds.getLength(); periodChildIndex++) { - if ((periodChilds.item(periodChildIndex).getLocalName() != null) && (periodChilds.item(periodChildIndex).getLocalName().equals("StartDateTime"))) { + } + if (IBAN != null) { + BankDetails bd = new BankDetails(IBAN); + if (BIC != null) { + bd.setBIC(BIC); + } + bankDetails.add(bd); + } + } + if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) + && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("BillingSpecifiedPeriod"))) { + NodeList periodChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); + for (int periodChildIndex = 0; periodChildIndex < periodChilds.getLength(); periodChildIndex++) { + if ((periodChilds.item(periodChildIndex).getLocalName() != null) && (periodChilds.item(periodChildIndex).getLocalName().equals("StartDateTime"))) { - NodeList startPeriodChilds = periodChilds.item(periodChildIndex).getChildNodes(); - for (int startPeriodIndex = 0; startPeriodIndex < startPeriodChilds.getLength(); startPeriodIndex++) { - if ((startPeriodChilds.item(startPeriodIndex).getLocalName() != null) && (startPeriodChilds.item(startPeriodIndex).getLocalName().equals("DateTimeString"))) {//CII - deliveryPeriodStart = XMLTools.trimOrNull(startPeriodChilds.item(startPeriodIndex)); - } - } - } - if ((periodChilds.item(periodChildIndex).getLocalName() != null) && (periodChilds.item(periodChildIndex).getLocalName().equals("EndDateTime"))) { - NodeList endPeriodChilds = periodChilds.item(periodChildIndex).getChildNodes(); - for (int endPeriodIndex = 0; endPeriodIndex < endPeriodChilds.getLength(); endPeriodIndex++) { - if ((endPeriodChilds.item(endPeriodIndex).getLocalName() != null) && (endPeriodChilds.item(endPeriodIndex).getLocalName().equals("DateTimeString"))) {//CII - deliveryPeriodEnd = XMLTools.trimOrNull(endPeriodChilds.item(endPeriodIndex)); - } - } - } - } - } - } - } + NodeList startPeriodChilds = periodChilds.item(periodChildIndex).getChildNodes(); + for (int startPeriodIndex = 0; startPeriodIndex < startPeriodChilds.getLength(); startPeriodIndex++) { + if ((startPeriodChilds.item(startPeriodIndex).getLocalName() != null) && (startPeriodChilds.item(startPeriodIndex).getLocalName().equals("DateTimeString"))) {// CII + deliveryPeriodStart = XMLTools.trimOrNull(startPeriodChilds.item(startPeriodIndex)); + } + } + } + if ((periodChilds.item(periodChildIndex).getLocalName() != null) && (periodChilds.item(periodChildIndex).getLocalName().equals("EndDateTime"))) { + NodeList endPeriodChilds = periodChilds.item(periodChildIndex).getChildNodes(); + for (int endPeriodIndex = 0; endPeriodIndex < endPeriodChilds.getLength(); endPeriodIndex++) { + if ((endPeriodChilds.item(endPeriodIndex).getLocalName() != null) && (endPeriodChilds.item(endPeriodIndex).getLocalName().equals("DateTimeString"))) {// CII + deliveryPeriodEnd = XMLTools.trimOrNull(endPeriodChilds.item(endPeriodIndex)); + } + } + } + } + } + } + } - if ((deliveryPeriodStart != null) && (deliveryPeriodEnd != null)) { - zpp.setDetailedDeliveryPeriod(XMLTools.tryDate(deliveryPeriodStart), XMLTools.tryDate(deliveryPeriodEnd)); - } else if (deliveryPeriodStart != null) { - zpp.setDeliveryDate(XMLTools.tryDate(deliveryPeriodStart)); - } + if ((deliveryPeriodStart != null) && (deliveryPeriodEnd != null)) { + zpp.setDetailedDeliveryPeriod(XMLTools.tryDate(deliveryPeriodStart), XMLTools.tryDate(deliveryPeriodEnd)); + } else if (deliveryPeriodStart != null) { + zpp.setDeliveryDate(XMLTools.tryDate(deliveryPeriodStart)); + } - xpr = xpath.compile("//*[local-name()=\"PaymentMeans\"]"); //UBL only - NodeList paymentMeansNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + xpr = xpath.compile("//*[local-name()=\"PaymentMeans\"]"); // UBL only + NodeList paymentMeansNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - for (int i = 0; i < paymentMeansNodes.getLength(); i++) { - // XMLTools.trimOrNull(nodes.item(i)))) { - Node paymentMeansNode = paymentMeansNodes.item(i); - NodeList paymentMeansChilds = paymentMeansNode.getChildNodes(); - for (int meansChildIndex = 0; meansChildIndex < paymentMeansChilds.getLength(); meansChildIndex++) { - if ((paymentMeansChilds.item(meansChildIndex).getLocalName() != null) - && (paymentMeansChilds.item(meansChildIndex).getLocalName().equals("PayeeFinancialAccount"))) { - NodeList paymentTermChilds = paymentMeansChilds.item(meansChildIndex).getChildNodes(); - for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) { - if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("ID"))) { - IBAN = XMLTools.trimOrNull(paymentTermChilds.item(paymentTermChildIndex)); - if (IBAN != null) { - BankDetails bd = new BankDetails(IBAN); - bankDetails.add(bd); - } - } - } - } -// 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(); - } - } + for (int i = 0; i < paymentMeansNodes.getLength(); i++) { + // XMLTools.trimOrNull(nodes.item(i)))) { + Node paymentMeansNode = paymentMeansNodes.item(i); + NodeList paymentMeansChilds = paymentMeansNode.getChildNodes(); + for (int meansChildIndex = 0; meansChildIndex < paymentMeansChilds.getLength(); meansChildIndex++) { + if ((paymentMeansChilds.item(meansChildIndex).getLocalName() != null) + && (paymentMeansChilds.item(meansChildIndex).getLocalName().equals("PayeeFinancialAccount"))) { + NodeList paymentTermChilds = paymentMeansChilds.item(meansChildIndex).getChildNodes(); + for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) { + if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("ID"))) { + IBAN = XMLTools.trimOrNull(paymentTermChilds.item(paymentTermChildIndex)); + if (IBAN != null) { + BankDetails bd = new BankDetails(IBAN); + bankDetails.add(bd); + } + } + } + } +// 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.setIssueDate(issueDate).setDueDate(dueDate).setDeliveryDate(deliveryDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentCode(typeCode); + zpp.setIssueDate(issueDate).setDueDate(dueDate).setDeliveryDate(deliveryDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentCode(typeCode); - if ((directDebitMandateID != null) && (IBAN != null)) { - DirectDebit d = new DirectDebit(IBAN, directDebitMandateID); - zpp.getSender().addDebitDetails(d); - } + if ((directDebitMandateID != null) && (IBAN != null)) { + DirectDebit d = new DirectDebit(IBAN, directDebitMandateID); + zpp.getSender().addDebitDetails(d); + } - bankDetails.forEach(bankDetail -> zpp.getSender().addBankDetails(bankDetail)); + bankDetails.forEach(bankDetail -> zpp.getSender().addBankDetails(bankDetail)); - if (payeeNodes.getLength() > 0) { - zpp.setPayee(new TradeParty(payeeNodes)); - } + if (payeeNodes.getLength() > 0) { + zpp.setPayee(new TradeParty(payeeNodes)); + } - if (buyerOrderIssuerAssignedID != null) { - zpp.setBuyerOrderReferencedDocumentID(buyerOrderIssuerAssignedID); - } 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.setInvoiceReferencedDocumentID(extractString("//*[local-name()=\"InvoiceReferencedDocument\"]/*[local-name()=\"IssuerAssignedID\"]|//*[local-name()=\"BillingReference\"]/*[local-name()=\"InvoiceDocumentReference\"]/*[local-name()=\"ID\"]")); + if (buyerOrderIssuerAssignedID != null) { + zpp.setBuyerOrderReferencedDocumentID(buyerOrderIssuerAssignedID); + } 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.setInvoiceReferencedDocumentID(extractString("//*[local-name()=\"InvoiceReferencedDocument\"]/*[local-name()=\"IssuerAssignedID\"]|//*[local-name()=\"BillingReference\"]/*[local-name()=\"InvoiceDocumentReference\"]/*[local-name()=\"ID\"]")); - zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]|//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyName\"]").trim()); + 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())) { - zpp.setRoundingAmount(new BigDecimal(rounding.trim())); - } + 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; - lineTotalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - if (lineTotalNodes.getLength() > 0) { - buyerReference = XMLTools.trimOrNull(lineTotalNodes.item(0)); - } - if (buyerReference != null) { - zpp.setReferenceNumber(buyerReference); - } + xpr = xpath.compile("//*[local-name()=\"BuyerReference\"]"); + String buyerReference = null; + lineTotalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + if (lineTotalNodes.getLength() > 0) { + buyerReference = XMLTools.trimOrNull(lineTotalNodes.item(0)); + } + if (buyerReference != null) { + zpp.setReferenceNumber(buyerReference); + } - xpr = xpath.compile("//*[local-name()=\"IncludedSupplyChainTradeLineItem\"]|//*[local-name()=\"InvoiceLine\"]"); - NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + xpr = xpath.compile("//*[local-name()=\"IncludedSupplyChainTradeLineItem\"]|//*[local-name()=\"InvoiceLine\"]"); + NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - if (nodes.getLength() != 0) { - for (int i = 0; i < nodes.getLength(); i++) { + if (nodes.getLength() != 0) { + for (int i = 0; i < nodes.getLength(); i++) { - Node currentItemNode = nodes.item(i); - Item it = new Item(currentItemNode.getChildNodes(), recalcPrice); - zpp.addItem(it); + Node currentItemNode = nodes.item(i); + Item it = new Item(currentItemNode.getChildNodes(), recalcPrice); + zpp.addItem(it); - } + } - // now handling base64 encoded attachments AttachmentBinaryObject=CII, EmbeddedDocumentBinaryObject=UBL - xpr = xpath.compile("//*[local-name()=\"AttachmentBinaryObject\"]|//*[local-name()=\"EmbeddedDocumentBinaryObject\"]"); - NodeList attachmentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - for (int i = 0; i < attachmentNodes.getLength(); i++) { - FileAttachment fa = new FileAttachment(attachmentNodes.item(i).getAttributes().getNamedItem("filename").getNodeValue(), attachmentNodes.item(i).getAttributes().getNamedItem("mimeCode").getNodeValue(), "Data", Base64.getDecoder().decode(XMLTools.trimOrNull(attachmentNodes.item(i)))); - zpp.embedFileInXML(fa); - // filename = "Aufmass.png" mimeCode = "image/png" - //EmbeddedDocumentBinaryObject cbc:EmbeddedDocumentBinaryObject mimeCode="image/png" filename="Aufmass.png" - } + // now handling base64 encoded attachments AttachmentBinaryObject=CII, EmbeddedDocumentBinaryObject=UBL + xpr = xpath.compile("//*[local-name()=\"AttachmentBinaryObject\"]|//*[local-name()=\"EmbeddedDocumentBinaryObject\"]"); + NodeList attachmentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + for (int i = 0; i < attachmentNodes.getLength(); i++) { + FileAttachment fa = new FileAttachment(attachmentNodes.item(i).getAttributes().getNamedItem("filename").getNodeValue(), attachmentNodes.item(i).getAttributes().getNamedItem("mimeCode").getNodeValue(), "Data", Base64.getDecoder().decode(XMLTools.trimOrNull(attachmentNodes.item(i)))); + zpp.embedFileInXML(fa); + // filename = "Aufmass.png" mimeCode = "image/png" + // EmbeddedDocumentBinaryObject cbc:EmbeddedDocumentBinaryObject mimeCode="image/png" filename="Aufmass.png" + } - // item level charges+allowances are not yet handled but a lower item price will - // be read, - // so the invoice remains arithmetically correct - // -> parse document level charges+allowances - 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(); - boolean isCharge = true; - String chargeAmount = null; - String reason = null; - String reasonCode = null; - String taxPercent = null; - for (int chargeChildIndex = 0; chargeChildIndex < chargeNodeChilds.getLength(); chargeChildIndex++) { - String chargeChildName = chargeNodeChilds.item(chargeChildIndex).getLocalName(); - if (chargeChildName != null) { + // item level charges+allowances are not yet handled but a lower item price will + // be read, + // so the invoice remains arithmetically correct + // -> parse document level charges+allowances + 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(); + boolean isCharge = true; + String chargeAmount = null; + String reason = null; + String reasonCode = null; + String taxPercent = null; + for (int chargeChildIndex = 0; chargeChildIndex < chargeNodeChilds.getLength(); chargeChildIndex++) { + String chargeChildName = chargeNodeChilds.item(chargeChildIndex).getLocalName(); + if (chargeChildName != null) { - if (chargeChildName.equals("ChargeIndicator")) { - 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"); - } - } - } + if (chargeChildName.equals("ChargeIndicator")) { + 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") || chargeChildName.equals("Amount")) { - chargeAmount = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); - } else if (chargeChildName.equals("Reason") || chargeChildName.equals("AllowanceChargeReason")) { - reason = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); - } else if (chargeChildName.equals("ReasonCode") || chargeChildName.equals("AllowanceChargeReasonCode")) { - reasonCode = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); - } 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") || taxItemName.equals("Percent"))) { - taxPercent = XMLTools.trimOrNull(taxChilds.item(taxChildIndex)); - } - } - } - } - } + } else if (chargeChildName.equals("ActualAmount") || chargeChildName.equals("Amount")) { + chargeAmount = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); + } else if (chargeChildName.equals("Reason") || chargeChildName.equals("AllowanceChargeReason")) { + reason = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); + } else if (chargeChildName.equals("ReasonCode") || chargeChildName.equals("AllowanceChargeReasonCode")) { + reasonCode = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); + } 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") || taxItemName.equals("Percent"))) { + taxPercent = XMLTools.trimOrNull(taxChilds.item(taxChildIndex)); + } + } + } + } + } - if (isCharge) { - Charge c = new Charge(new BigDecimal(chargeAmount)); - if (reason != null) { - c.setReason(reason); - } - if (reasonCode != null) { - c.setReasonCode(reasonCode); - } - if (taxPercent != null) { - c.setTaxPercent(new BigDecimal(taxPercent)); - } - zpp.addCharge(c); - } else { - Allowance a = new Allowance(new BigDecimal(chargeAmount)); - if (reason != null) { - a.setReason(reason); - } - if (reasonCode != null) { - a.setReasonCode(reasonCode); - } - if (taxPercent != null) { - a.setTaxPercent(new BigDecimal(taxPercent)); - } - zpp.addAllowance(a); - } + if (isCharge) { + Charge c = new Charge(new BigDecimal(chargeAmount)); + if (reason != null) { + c.setReason(reason); + } + if (reasonCode != null) { + c.setReasonCode(reasonCode); + } + if (taxPercent != null) { + c.setTaxPercent(new BigDecimal(taxPercent)); + } + zpp.addCharge(c); + } else { + Allowance a = new Allowance(new BigDecimal(chargeAmount)); + if (reason != null) { + a.setReason(reason); + } + if (reasonCode != null) { + a.setReasonCode(reasonCode); + } + if (taxPercent != null) { + a.setTaxPercent(new BigDecimal(taxPercent)); + } + zpp.addAllowance(a); + } - } + } - TransactionCalculator tc = new TransactionCalculator(zpp); - String calculatedPayableTotal = tc.getDuePayable().toPlainString(); - EStandard whichType; - try { - whichType = getStandard(); - } catch (Exception e) { - throw new StructureException("Could not find out if it's an invoice, order, or delivery advice", 0); - } + TransactionCalculator tc = new TransactionCalculator(zpp); + String calculatedPayableTotal = tc.getDuePayable().toPlainString(); + EStandard whichType; + try { + whichType = getStandard(); + } catch (Exception e) { + throw new StructureException("Could not find out if it's an invoice, order, or delivery advice", 0); + } - if (whichType != EStandard.despatchadvice && !ignoreCalculationErrors) { - // Check calculation if document type allows it and calculation errors should not be ignored + if (whichType != EStandard.despatchadvice && !ignoreCalculationErrors) { + // Check calculation if document type allows it and calculation errors should not be ignored - String payableTotalFromXml = XMLTools.nDigitFormat(Objects.requireNonNullElse(duePayableAmount, expectedGrandTotal), 2); - if (!calculatedPayableTotal.equals(payableTotalFromXml)) { - String moreDetails = ""; - try { - moreDetails = " with tax basis " + tc.getTaxBasis() + " and with positions " + tc.getTotal() + " = " - + Stream.of(tc.trans.getZFItems()) - .map(item -> new LineCalculator(item).getItemTotalNetAmount().toPlainString()) - .collect(Collectors.joining(" + ")); - } catch (Exception ignored) { - } - throw new ArithmeticException("Payable total in XML is " + payableTotalFromXml + ", but calculated total is " + calculatedPayableTotal + moreDetails); - } - } - } - return zpp; + String payableTotalFromXml = XMLTools.nDigitFormat(Objects.requireNonNullElse(duePayableAmount, expectedGrandTotal), 2); + if (!calculatedPayableTotal.equals(payableTotalFromXml)) { + String moreDetails = ""; + try { + moreDetails = " with tax basis " + tc.getTaxBasis() + " and with positions " + tc.getTotal() + " = " + + Stream.of(tc.trans.getZFItems()) + .map(item -> new LineCalculator(item).getItemTotalNetAmount().toPlainString()) + .collect(Collectors.joining(" + ")); + } catch (Exception ignored) { + } + throw new ArithmeticException("Payable total in XML is " + payableTotalFromXml + ", but calculated total is " + calculatedPayableTotal + moreDetails); + } + } + } + return zpp; - } + } - protected Document getDocument() { - return document; - } + protected Document getDocument() { + return document; + } - protected String extractString(String xpathStr) { - if (!containsMeta) { - throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found."); - } - final String result; - try { - final Document document = getDocument(); - final XPathFactory xpathFact = XPathFactory.newInstance(); - final XPath xpath = xpathFact.newXPath(); - result = xpath.evaluate(xpathStr, document); - } catch (final XPathExpressionException e) { - LOGGER.error("Failed to evaluate XPath", e); - throw new ZUGFeRDExportException(e); - } - return result; - } + protected String extractString(String xpathStr) { + if (!containsMeta) { + throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found."); + } + final String result; + try { + final Document document = getDocument(); + final XPathFactory xpathFact = XPathFactory.newInstance(); + final XPath xpath = xpathFact.newXPath(); + result = xpath.evaluate(xpathStr, document); + } catch (final XPathExpressionException e) { + LOGGER.error("Failed to evaluate XPath", e); + throw new ZUGFeRDExportException(e); + } + return result; + } - public EStandard getStandard() throws Exception { - if (!containsMeta) { - throw new Exception("Not yet parsed"); - } - final String head = getUTF8(); - String rootNode = extractString("local-name(/*)"); - if (rootNode.equals("CrossIndustryDocument")) { - return EStandard.zugferd; - } else if (rootNode.equals("Invoice")) { - return EStandard.ubl; - } else if (rootNode.equals("CreditNote")) { - return EStandard.ubl; - } else if (rootNode.equals("CrossIndustryInvoice")) { - return EStandard.facturx; - } else if (rootNode.equals("SCRDMCCBDACIDAMessageStructure")) { - return EStandard.despatchadvice; - } else if (head.contains(" getFileAttachmentsXML() { - return new ArrayList<>(Arrays.asList(importedInvoice.getAdditionalReferencedDocuments())); - } + /*** + * + * @return the file attachments embedded in XML (using base64) decoded as byte array, + * for PDF embedded files in FX use getFileAttachmentsPDF() + * @deprecated use invoice.getAdditionalReferencedDocuments + */ + @Deprecated + public List getFileAttachmentsXML() { + return new ArrayList<>(Arrays.asList(importedInvoice.getAdditionalReferencedDocuments())); + } - /*** - * This will parse a XML into a invoice object - * - * @return the parsed invoice object - * @throws XPathExpressionException if internal xpath expressions were wrong - * @throws ParseException if the grand total of the parsed invoice could not be replicated with the new invoice - */ - public Invoice extractInvoice() throws XPathExpressionException, ParseException { - Invoice i = new Invoice(); - return extractInto(i); + /*** + * This will parse a XML into a invoice object + * + * @return the parsed invoice object + * @throws XPathExpressionException if internal xpath expressions were wrong + * @throws ParseException if the grand total of the parsed invoice could not be replicated with the new invoice + */ + public Invoice extractInvoice() throws XPathExpressionException, ParseException { + Invoice i = new Invoice(); + return extractInto(i); - } + } - /*** - * sets the XML for the importer to parse - * @param XML the UBL or CII - */ - public void fromXML(String XML) { - try { - containsMeta = true; - setRawXML(XML.getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); - } - } + /*** + * sets the XML for the importer to parse + * @param XML the UBL or CII + */ + public void fromXML(String XML) { + try { + containsMeta = true; + setRawXML(XML.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); + } + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java index 8f6c30d..2313103 100755 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java @@ -20,34 +20,8 @@ org.openrewrite.config.CompositeRecipe */ package org.mustangproject.ZUGFeRD; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.nio.charset.StandardCharsets; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Templates; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - +import com.helger.commons.io.stream.StreamHelper; +import net.sf.saxon.TransformerFactoryImpl; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; @@ -62,365 +36,379 @@ import org.mustangproject.EStandard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import com.helger.commons.io.stream.StreamHelper; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.*; +import java.nio.charset.StandardCharsets; + public class ZUGFeRDVisualizer { - private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDVisualizer.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDVisualizer.class); - private final TransformerFactory mFactory; + private final TransformerFactory mFactory; - private Templates mXsltXRTemplate = null; - private Templates mXsltUBLTemplate = null; - private Templates mXsltCIOTemplate = null; - private Templates mXsltHTMLTemplate = null; - private Templates mXsltPDFTemplate = null; - private Templates mXsltZF1HTMLTemplate = null; + private Templates mXsltXRTemplate = null; + private Templates mXsltUBLTemplate = null; + private Templates mXsltCIOTemplate = null; + private Templates mXsltHTMLTemplate = null; + private Templates mXsltPDFTemplate = null; + private Templates mXsltZF1HTMLTemplate = null; public ZUGFeRDVisualizer() { - mFactory = new net.sf.saxon.TransformerFactoryImpl(); - // fact = TransformerFactory.newInstance() - mFactory.setURIResolver(new ClasspathResourceURIResolver()); - } + mFactory = new TransformerFactoryImpl(); + // fact = TransformerFactory.newInstance() + mFactory.setURIResolver(new ClasspathResourceURIResolver()); + } - /*** - * returns which standard is used, CII or UBL - * @param fis InputStream (will be consumed) - * @return (facturx = cii) - */ - public EStandard findOutStandardFromRootNode(InputStream fis) { + /*** + * returns which standard is used, CII or UBL + * @param fis InputStream (will be consumed) + * @return (facturx = cii) + */ + public EStandard findOutStandardFromRootNode(InputStream fis) { - String zf1Signature = "CrossIndustryDocument"; - String zf2Signature = "CrossIndustryInvoice"; - String ublSignature = "Invoice"; - String ublCreditNoteSignature = "CreditNote"; - String cioSignature = "SCRDMCCBDACIOMessageStructure"; + String zf1Signature = "CrossIndustryDocument"; + String zf2Signature = "CrossIndustryInvoice"; + String ublSignature = "Invoice"; + String ublCreditNoteSignature = "CreditNote"; + String cioSignature = "SCRDMCCBDACIOMessageStructure"; - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - try { - DocumentBuilder db = dbf.newDocumentBuilder(); - Document doc = db.parse(new InputSource(fis)); - Element root = doc.getDocumentElement(); - if (root.getLocalName().equals(zf1Signature)) { - return EStandard.zugferd; - } else if (root.getLocalName().equals(zf2Signature)) { - return EStandard.facturx; - } else if (root.getLocalName().equals(ublSignature)) { - return EStandard.ubl; - } else if (root.getLocalName().equals(ublCreditNoteSignature)) { - return EStandard.ubl_creditnote; - } else if (root.getLocalName().equals(cioSignature)) { - return EStandard.orderx; - } - } catch (Exception e) { - LOGGER.error("Failed to recognize standard", e); - } - return null; - } + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + try { + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse(new InputSource(fis)); + Element root = doc.getDocumentElement(); + if (root.getLocalName().equals(zf1Signature)) { + return EStandard.zugferd; + } else if (root.getLocalName().equals(zf2Signature)) { + return EStandard.facturx; + } else if (root.getLocalName().equals(ublSignature)) { + return EStandard.ubl; + } else if (root.getLocalName().equals(ublCreditNoteSignature)) { + return EStandard.ubl_creditnote; + } else if (root.getLocalName().equals(cioSignature)) { + return EStandard.orderx; + } + } catch (Exception e) { + LOGGER.error("Failed to recognize standard", e); + } + return null; + } - public String visualize(String xmlFilename, ELanguage lang) - throws TransformerException, IOException, SAXException, ParserConfigurationException { + public String visualize(String xmlFilename, ELanguage lang) + throws TransformerException, IOException, SAXException, ParserConfigurationException { - try { - if (mXsltPDFTemplate == null) { - mXsltPDFTemplate = mFactory.newTemplates( - ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "xr-pdf.xsl") - ); - } - if (mXsltHTMLTemplate == null) { - mXsltHTMLTemplate = mFactory.newTemplates( - /* getSource(CUSTOM_BASE_PATH + "xrechnung-html." + lang.name().toLowerCase() + ".xsl") */ - ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "xrechnung-html.xsl") - ); - } - if (mXsltZF1HTMLTemplate == null) { - mXsltZF1HTMLTemplate = mFactory.newTemplates( - ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.ZF10_BASE_PATH + "ZUGFeRD_1p0_c1p0_s1p0.xslt") - ); - } - } catch (TransformerConfigurationException ex) { - LOGGER.error("Failed to init XSLT templates", ex); - } + try { + if (mXsltPDFTemplate == null) { + mXsltPDFTemplate = mFactory.newTemplates( + ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "xr-pdf.xsl") + ); + } + if (mXsltHTMLTemplate == null) { + mXsltHTMLTemplate = mFactory.newTemplates( + /* getSource(CUSTOM_BASE_PATH + "xrechnung-html." + lang.name().toLowerCase() + ".xsl") */ + ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "xrechnung-html.xsl") + ); + } + if (mXsltZF1HTMLTemplate == null) { + mXsltZF1HTMLTemplate = mFactory.newTemplates( + ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.ZF10_BASE_PATH + "ZUGFeRD_1p0_c1p0_s1p0.xslt") + ); + } + } catch (TransformerConfigurationException ex) { + LOGGER.error("Failed to init XSLT templates", ex); + } - /* - * http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf - * http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf - * http://countwordsfree.com/xmlviewer - */ - FileInputStream fis; + /* + * http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf + * http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf + * http://countwordsfree.com/xmlviewer + */ + FileInputStream fis; - ByteArrayOutputStream iaos = new ByteArrayOutputStream(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteArrayOutputStream iaos = new ByteArrayOutputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - boolean doPostProcessing = false; + boolean doPostProcessing = false; - fis = new FileInputStream(xmlFilename); // fis wont reset() so re-read from beginning - EStandard thestandard = findOutStandardFromRootNode(fis); - fis = new FileInputStream(xmlFilename); // fis wont reset() so re-read from beginning + fis = new FileInputStream(xmlFilename); // fis wont reset() so re-read from beginning + EStandard thestandard = findOutStandardFromRootNode(fis); + fis = new FileInputStream(xmlFilename); // fis wont reset() so re-read from beginning - if (thestandard == EStandard.zugferd) { - applyZF1XSLT(fis, baos); - } else if (thestandard == EStandard.facturx) { - //zf2 or fx - applyZF2XSLT(fis, iaos); - doPostProcessing = true; - } else if (thestandard == EStandard.ubl) { - //zf2 or fx - applyUBL2XSLT(fis, iaos); - doPostProcessing = true; - } else if (thestandard == EStandard.ubl_creditnote) { - //zf2 or fx - applyUBLCreditNote2XSLT(fis, iaos); - doPostProcessing = true; - } else if (thestandard == EStandard.orderx) { - //zf2 or fx - applyCIO2XSLT(fis, iaos); - doPostProcessing = true; - } else { - throw new IllegalArgumentException("File does not look like CII or UBL"); - } - if (doPostProcessing) { - // take the copy of the stream and re-write it to an InputStream - PipedInputStream in = new PipedInputStream(); - PipedOutputStream out; - try { - out = new PipedOutputStream(in); - new Thread(() -> { - try { - // write the original OutputStream to the PipedOutputStream - // note that in order for the below method to work, you need - // to ensure that the data has finished writing to the - // ByteArrayOutputStream - iaos.writeTo(out); - } catch (IOException e) { - LOGGER.error("Failed to write to stream", e); - } finally { - // close the PipedOutputStream here because we're done writing data - // once this thread has completed its run - StreamHelper.close(out); - } - }).start(); - applyXSLTToHTML(in, baos, lang); - } catch (IOException e1) { - LOGGER.error("Failed to create HTML", e1); - } + if (thestandard == EStandard.zugferd) { + applyZF1XSLT(fis, baos); + } else if (thestandard == EStandard.facturx) { + // zf2 or fx + applyZF2XSLT(fis, iaos); + doPostProcessing = true; + } else if (thestandard == EStandard.ubl) { + // zf2 or fx + applyUBL2XSLT(fis, iaos); + doPostProcessing = true; + } else if (thestandard == EStandard.ubl_creditnote) { + // zf2 or fx + applyUBLCreditNote2XSLT(fis, iaos); + doPostProcessing = true; + } else if (thestandard == EStandard.orderx) { + // zf2 or fx + applyCIO2XSLT(fis, iaos); + doPostProcessing = true; + } else { + throw new IllegalArgumentException("File does not look like CII or UBL"); + } + if (doPostProcessing) { + // take the copy of the stream and re-write it to an InputStream + PipedInputStream in = new PipedInputStream(); + PipedOutputStream out; + try { + out = new PipedOutputStream(in); + new Thread(() -> { + try { + // write the original OutputStream to the PipedOutputStream + // note that in order for the below method to work, you need + // to ensure that the data has finished writing to the + // ByteArrayOutputStream + iaos.writeTo(out); + } catch (IOException e) { + LOGGER.error("Failed to write to stream", e); + } finally { + // close the PipedOutputStream here because we're done writing data + // once this thread has completed its run + StreamHelper.close(out); + } + }).start(); + applyXSLTToHTML(in, baos, lang); + } catch (IOException e1) { + LOGGER.error("Failed to create HTML", e1); + } - } + } - return baos.toString(StandardCharsets.UTF_8); - } + return baos.toString(StandardCharsets.UTF_8); + } - protected String toFOP(String xmlFilename, final ELanguage lang) - throws FileNotFoundException, TransformerException { + protected String toFOP(String xmlFilename, final ELanguage lang) + throws FileNotFoundException, TransformerException { - FileInputStream fis = new FileInputStream(xmlFilename); - EStandard theStandard = findOutStandardFromRootNode(fis); - fis = new FileInputStream(xmlFilename);//rewind :-( + FileInputStream fis = new FileInputStream(xmlFilename); + EStandard theStandard = findOutStandardFromRootNode(fis); + fis = new FileInputStream(xmlFilename);// rewind :-( - return toFOP(fis, theStandard, lang); - } + return toFOP(fis, theStandard, lang); + } - protected String toFOP(InputStream is, EStandard theStandard, final ELanguage lang) - throws TransformerException { - - try { - if (mXsltPDFTemplate == null) { - mXsltPDFTemplate = mFactory.newTemplates( - ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "xr-pdf.xsl") - ); - } - } catch (TransformerConfigurationException ex) { - LOGGER.error("Failed to init XSLT templates", ex); - } + protected String toFOP(InputStream is, EStandard theStandard, final ELanguage lang) + throws TransformerException { - ByteArrayOutputStream iaos = new ByteArrayOutputStream(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + if (mXsltPDFTemplate == null) { + mXsltPDFTemplate = mFactory.newTemplates( + ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "xr-pdf.xsl") + ); + } + } catch (TransformerConfigurationException ex) { + LOGGER.error("Failed to init XSLT templates", ex); + } - //zf2 or fx - if (theStandard == EStandard.facturx) { - applyZF2XSLT(is, iaos); - } else if (theStandard == EStandard.ubl) { - applyUBL2XSLT(is, iaos); - } else if (theStandard == EStandard.ubl_creditnote) { - applyUBLCreditNote2XSLT(is, iaos); - } + ByteArrayOutputStream iaos = new ByteArrayOutputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PipedInputStream in = new PipedInputStream(); - PipedOutputStream out; - try { - out = new PipedOutputStream(in); - new Thread(() -> { - try { - // write the original OutputStream to the PipedOutputStream - // note that in order for the below method to work, you need - // to ensure that the data has finished writing to the - // ByteArrayOutputStream - iaos.writeTo(out); - } catch (IOException e) { - LOGGER.error("Failed to write to stream", e); - } finally { - // close the PipedOutputStream here because we're done writing data - // once this thread has completed its run - StreamHelper.close(out); - } - }).start(); - applyXSLTToPDF(in, baos, lang); - } catch (IOException e1) { - LOGGER.error("Failed to create PDF", e1); - } + // zf2 or fx + if (theStandard == EStandard.facturx) { + applyZF2XSLT(is, iaos); + } else if (theStandard == EStandard.ubl) { + applyUBL2XSLT(is, iaos); + } else if (theStandard == EStandard.ubl_creditnote) { + applyUBLCreditNote2XSLT(is, iaos); + } - return baos.toString(StandardCharsets.UTF_8); - } + PipedInputStream in = new PipedInputStream(); + PipedOutputStream out; + try { + out = new PipedOutputStream(in); + new Thread(() -> { + try { + // write the original OutputStream to the PipedOutputStream + // note that in order for the below method to work, you need + // to ensure that the data has finished writing to the + // ByteArrayOutputStream + iaos.writeTo(out); + } catch (IOException e) { + LOGGER.error("Failed to write to stream", e); + } finally { + // close the PipedOutputStream here because we're done writing data + // once this thread has completed its run + StreamHelper.close(out); + } + }).start(); + applyXSLTToPDF(in, baos, lang); + } catch (IOException e1) { + LOGGER.error("Failed to create PDF", e1); + } - public void toPDF(String xmlFilename, String pdfFilename) { - toPDF(xmlFilename, pdfFilename, ELanguage.EN); - } + return baos.toString(StandardCharsets.UTF_8); + } - public void toPDF(String xmlFilename, String pdfFilename, final ELanguage lang) { + public void toPDF(String xmlFilename, String pdfFilename) { + toPDF(xmlFilename, pdfFilename, ELanguage.EN); + } - // the writing part - File xmlFile = new File(xmlFilename); + public void toPDF(String xmlFilename, String pdfFilename, final ELanguage lang) { - String result = null; + // the writing part + File xmlFile = new File(xmlFilename); - /* remove file endings so that tests can also pass after checking - out from git with arbitrary options (which may include CSRF changes) - */ - try { - result = this.toFOP(xmlFile.getAbsolutePath(), lang); - } catch (FileNotFoundException | TransformerException e) { - LOGGER.error("Failed to apply FOP", e); - } - if (result == null) { - throw new IllegalArgumentException(String.format("FOP cannot process XML file '%s'.", xmlFilename)); - } + String result = null; - DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); + /* remove file endings so that tests can also pass after checking + out from git with arbitrary options (which may include CSRF changes) + */ + try { + result = this.toFOP(xmlFile.getAbsolutePath(), lang); + } catch (FileNotFoundException | TransformerException e) { + LOGGER.error("Failed to apply FOP", e); + } + if (result == null) { + throw new IllegalArgumentException(String.format("FOP cannot process XML file '%s'.", xmlFilename)); + } - Configuration cfg; - try { - cfg = cfgBuilder.build(ClasspathResourceURIResolver.CLASS_LOADER.getResourceAsStream("fop-config.xconf")); - } catch (ConfigurationException e) { - throw new IllegalArgumentException("Cannot parse FOP configuration.", e); - } + DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); - FopFactoryBuilder builder = new FopFactoryBuilder(new File(".").toURI(), new ClasspathResolverURIAdapter()).setConfiguration(cfg); - // Step 1: Construct a FopFactory by specifying a reference to the configuration file - // (reuse if you plan to render multiple documents!) + Configuration cfg; + try { + cfg = cfgBuilder.build(ClasspathResourceURIResolver.CLASS_LOADER.getResourceAsStream("fop-config.xconf")); + } catch (ConfigurationException e) { + throw new IllegalArgumentException("Cannot parse FOP configuration.", e); + } - FopFactory fopFactory = builder.build(); - // FopFactory.newInstance(new File("c:\\Users\\jstaerk\\temp\\fop-config.xconf")) + FopFactoryBuilder builder = new FopFactoryBuilder(new File(".").toURI(), new ClasspathResolverURIAdapter()).setConfiguration(cfg); + // Step 1: Construct a FopFactory by specifying a reference to the configuration file + // (reuse if you plan to render multiple documents!) - fopFactory.getFontManager().setResourceResolver( - ResourceResolverFactory.createInternalResourceResolver( - new File(".").toURI(), - new ClasspathResolverURIAdapter())); + FopFactory fopFactory = builder.build(); + // FopFactory.newInstance(new File("c:\\Users\\jstaerk\\temp\\fop-config.xconf")) - FOUserAgent userAgent = fopFactory.newFOUserAgent(); + fopFactory.getFontManager().setResourceResolver( + ResourceResolverFactory.createInternalResourceResolver( + new File(".").toURI(), + new ClasspathResolverURIAdapter())); - userAgent.getRendererOptions().put("pdf-a-mode", "PDF/A-3b"); + FOUserAgent userAgent = fopFactory.newFOUserAgent(); - // Step 2: Set up output stream. - // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams). + userAgent.getRendererOptions().put("pdf-a-mode", "PDF/A-3b"); - try (OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFilename))) { + // Step 2: Set up output stream. + // Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams). - // Step 3: Construct fop with desired output format - Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out); + try (OutputStream out = new BufferedOutputStream(new FileOutputStream(pdfFilename))) { - // Step 4: Setup JAXP using identity transformer - TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer = factory.newTransformer(); // identity transformer + // Step 3: Construct fop with desired output format + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out); - // Step 5: Setup input and output for XSLT transformation - // Setup input stream - Source src = new StreamSource(new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8))); + // Step 4: Setup JAXP using identity transformer + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); // identity transformer - // Resulting SAX events (the generated FO) must be piped through to FOP - Result res = new SAXResult(fop.getDefaultHandler()); + // Step 5: Setup input and output for XSLT transformation + // Setup input stream + Source src = new StreamSource(new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8))); - // Step 6: Start XSLT transformation and FOP processing - transformer.transform(src, res); + // Resulting SAX events (the generated FO) must be piped through to FOP + Result res = new SAXResult(fop.getDefaultHandler()); - } catch (FOPException | IOException | TransformerException e) { - LOGGER.error("Failed to create PDF", e); - } - } + // Step 6: Start XSLT transformation and FOP processing + transformer.transform(src, res); - protected void applyZF2XSLT(final InputStream xmlFile, final OutputStream outputStream) - throws TransformerException { - if (mXsltXRTemplate == null) { - mXsltXRTemplate = mFactory.newTemplates( - ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "cii-xr.xsl") - ); + } catch (FOPException | IOException | TransformerException e) { + LOGGER.error("Failed to create PDF", e); + } + } - } - Transformer transformer = mXsltXRTemplate.newTransformer(); + protected void applyZF2XSLT(final InputStream xmlFile, final OutputStream outputStream) + throws TransformerException { + if (mXsltXRTemplate == null) { + mXsltXRTemplate = mFactory.newTemplates( + ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "cii-xr.xsl") + ); - transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); - } + } + Transformer transformer = mXsltXRTemplate.newTransformer(); - protected void applyCIO2XSLT(final InputStream xmlFile, final OutputStream outputStream) - throws TransformerException { - if (mXsltCIOTemplate == null) { - mXsltCIOTemplate = mFactory.newTemplates( - ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.CUSTOM_BASE_PATH + "cio-xr.xsl") - ); - } - Transformer transformer = mXsltCIOTemplate.newTransformer(); + transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); + } - transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); - } + protected void applyCIO2XSLT(final InputStream xmlFile, final OutputStream outputStream) + throws TransformerException { + if (mXsltCIOTemplate == null) { + mXsltCIOTemplate = mFactory.newTemplates( + ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.CUSTOM_BASE_PATH + "cio-xr.xsl") + ); + } + Transformer transformer = mXsltCIOTemplate.newTransformer(); - protected void applyUBL2XSLT(final InputStream xmlFile, final OutputStream outputStream) - throws TransformerException { - if (mXsltUBLTemplate == null) { - mXsltUBLTemplate = mFactory.newTemplates( - ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "ubl-invoice-xr.xsl") - ); - } - Transformer transformer = mXsltUBLTemplate.newTransformer(); + transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); + } - transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); - } + protected void applyUBL2XSLT(final InputStream xmlFile, final OutputStream outputStream) + throws TransformerException { + if (mXsltUBLTemplate == null) { + mXsltUBLTemplate = mFactory.newTemplates( + ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "ubl-invoice-xr.xsl") + ); + } + Transformer transformer = mXsltUBLTemplate.newTransformer(); - protected void applyUBLCreditNote2XSLT(final InputStream xmlFile, final OutputStream outputStream) - throws TransformerException { - if (mXsltUBLTemplate == null) { - mXsltUBLTemplate = mFactory.newTemplates( - ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "ubl-creditnote-xr.xsl") - ); - } - Transformer transformer = mXsltUBLTemplate.newTransformer(); + transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); + } - transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); - } + protected void applyUBLCreditNote2XSLT(final InputStream xmlFile, final OutputStream outputStream) + throws TransformerException { + if (mXsltUBLTemplate == null) { + mXsltUBLTemplate = mFactory.newTemplates( + ClasspathResourceURIResolver.getSource(ClasspathResourceURIResolver.MAIN_BASE_PATH + "ubl-creditnote-xr.xsl") + ); + } + Transformer transformer = mXsltUBLTemplate.newTransformer(); - protected void applyZF1XSLT(final InputStream xmlFile, final OutputStream outputStream) - throws TransformerException { - Transformer transformer = mXsltZF1HTMLTemplate.newTransformer(); + transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); + } - transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); - } + protected void applyZF1XSLT(final InputStream xmlFile, final OutputStream outputStream) + throws TransformerException { + Transformer transformer = mXsltZF1HTMLTemplate.newTransformer(); - protected void applyXSLTToHTML(final InputStream xmlFile, final OutputStream outputStream, final ELanguage lang) - throws TransformerException { - Transformer transformer = mXsltHTMLTemplate.newTransformer(); - transformer.setParameter("lang", lang.name().toLowerCase()); + transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); + } - transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); - } + protected void applyXSLTToHTML(final InputStream xmlFile, final OutputStream outputStream, final ELanguage lang) + throws TransformerException { + Transformer transformer = mXsltHTMLTemplate.newTransformer(); + transformer.setParameter("lang", lang.name().toLowerCase()); - protected void applyXSLTToPDF(final InputStream xmlFile, final OutputStream outputStream, final ELanguage lang) - throws TransformerException { - Transformer transformer = mXsltPDFTemplate.newTransformer(); - transformer.setParameter("lang", lang.name().toLowerCase()); + transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); + } - transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); - } + protected void applyXSLTToPDF(final InputStream xmlFile, final OutputStream outputStream, final ELanguage lang) + throws TransformerException { + Transformer transformer = mXsltPDFTemplate.newTransformer(); + transformer.setParameter("lang", lang.name().toLowerCase()); + + transformer.transform(new StreamSource(xmlFile), new StreamResult(outputStream)); + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/BackwardCompatibilityTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/BackwardCompatibilityTest.java index b0dbecb..263b097 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/BackwardCompatibilityTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/BackwardCompatibilityTest.java @@ -18,6 +18,9 @@ org.openrewrite.config.CompositeRecipe *********************************************************************** */ package org.mustangproject.ZUGFeRD; +import junit.framework.TestCase; +import org.mustangproject.TradeParty; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -27,9 +30,6 @@ import java.util.Date; import java.util.GregorianCalendar; -import junit.framework.TestCase; -import org.mustangproject.TradeParty; - /*** * This is a test to confirm the minimum steps to implement a interface are still sufficient * @@ -38,396 +38,395 @@ */ public class BackwardCompatibilityTest extends TestCase implements IExportableTransaction { - final String TARGET_PDF_ZF1 = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506zf1.pdf"; - final String TARGET_PDF_ZF2 = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506zf2.pdf"; - final String TARGET_PDF_FX = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506fx.pdf"; + final String TARGET_PDF_ZF1 = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506zf1.pdf"; + final String TARGET_PDF_ZF2 = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506zf2.pdf"; + final String TARGET_PDF_FX = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506fx.pdf"; - /** - * The exporter test bases on @{code - * ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds - * metadata, writes to @{code ./target/testout-*} and then imports to check the - * values. It would not make sense to have it run before the less complex - * importer test (which is probably redundant). As only Name Ascending is - * supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export - */ - public void testZF1Export() { + /** + * The exporter test bases on @{code + * ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds + * metadata, writes to @{code ./target/testout-*} and then imports to check the + * values. It would not make sense to have it run before the less complex + * importer test (which is probably redundant). As only Name Ascending is + * supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export + */ + public void testZF1Export() { - // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); + // the writing part + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); - IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(1).setProfile(Profiles.getByName("Extended",1)).load(SOURCE_PDF)) { + IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(1).setProfile(Profiles.getByName("Extended", 1)).load(SOURCE_PDF)) { - ze.setTransaction(this); - ze.disableAutoClose(true); - ze.export(TARGET_PDF_ZF1); + ze.setTransaction(this); + ze.disableAutoClose(true); + ze.export(TARGET_PDF_ZF1); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ze.export(baos); - ze.close(); - String pdfContent = baos.toString(StandardCharsets.UTF_8); - assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); - // check for pdf-a schema extension -// assertFalse(pdfContent.indexOf("EN 16931") == -1); -// assertFalse(pdfContent.indexOf("zf") == -1); -// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ze.export(baos); + ze.close(); + String pdfContent = baos.toString(StandardCharsets.UTF_8); + assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); + // check for pdf-a schema extension +// assertFalse(pdfContent.indexOf("EN 16931") == -1); +// assertFalse(pdfContent.indexOf("zf") == -1); +// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); - } catch (IOException e) { - fail("IOException should not happen in testZExport"); - } + } catch (IOException e) { + fail("IOException should not happen in testZExport"); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_ZF1); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_ZF1); - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); - assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN()); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getForeignReference(), getNumber()); - - - } + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); + assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); - public void testZF2Export() { - - // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); + } + + public void testZF2Export() { + + + // the writing part + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(2).setProfile("EN16931").load(SOURCE_PDF)) { - ze.setTransaction(this); - ze.disableAutoClose(true); - ze.export(TARGET_PDF_ZF2); + ze.setTransaction(this); + ze.disableAutoClose(true); + ze.export(TARGET_PDF_ZF2); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ze.export(baos); - ze.close(); - String pdfContent = baos.toString(StandardCharsets.UTF_8); - assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); - // check for pdf-a schema extension -// assertFalse(pdfContent.indexOf("EN 16931") == -1); -// assertFalse(pdfContent.indexOf("zf") == -1); -// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ze.export(baos); + ze.close(); + String pdfContent = baos.toString(StandardCharsets.UTF_8); + assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); + // check for pdf-a schema extension +// assertFalse(pdfContent.indexOf("EN 16931") == -1); +// assertFalse(pdfContent.indexOf("zf") == -1); +// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); - } catch (IOException e) { - fail("IOException should not happen in testZExport"); - } + } catch (IOException e) { + fail("IOException should not happen in testZExport"); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_ZF2); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_ZF2); - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); - assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN()); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getForeignReference(), getNumber()); - - - } - public void testFXExport() { + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); + assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); - // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); + + } + + public void testFXExport() { + + // the writing part + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(2).setProfile("EN16931").load(SOURCE_PDF)) { - ze.setTransaction(this); - ze.disableAutoClose(true); - ze.export(TARGET_PDF_FX); + ze.setTransaction(this); + ze.disableAutoClose(true); + ze.export(TARGET_PDF_FX); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ze.export(baos); - ze.close(); - String pdfContent = baos.toString(StandardCharsets.UTF_8); - assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); - // check for pdf-a schema extension -// assertFalse(pdfContent.indexOf("EN 16931") == -1); -// assertFalse(pdfContent.indexOf("zf") == -1); -// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ze.export(baos); + ze.close(); + String pdfContent = baos.toString(StandardCharsets.UTF_8); + assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); + // check for pdf-a schema extension +// assertFalse(pdfContent.indexOf("EN 16931") == -1); +// assertFalse(pdfContent.indexOf("zf") == -1); +// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); - } catch (IOException e) { - fail("IOException should not happen in testZExport"); - } + } catch (IOException e) { + fail("IOException should not happen in testZExport"); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_FX); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_FX); - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); - assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN()); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getForeignReference(), getNumber()); - - - } - class Contact implements IZUGFeRDExportableContact { - public String getCountry() { - return "DE"; - } - - public String getLocation() { - return "Spielkreis"; - } - - public String getName() { - return "Theodor Est"; - } - - public String getStreet() { - return "Bahnstr. 42"; - } - - public String getVATID() { - return "DE999999999"; - } - - public String getZIP() { - return "88802"; - } - - } - class Payment implements IZUGFeRDTradeSettlementPayment { - - @Override - public String getOwnBIC() { - return "bla"; - } - - @Override - public String getOwnIBAN() { - return "bla"; - } - - } - - class Item implements IZUGFeRDExportableItem { - public Item(BigDecimal price, BigDecimal quantity, Product product) { - super(); - this.price = price; - this.quantity = quantity; - this.product = product; - } - - private BigDecimal price, quantity; - private Product product; - - public BigDecimal getPrice() { - return price; - } - - public void setPrice(BigDecimal price) { - this.price = price; - } - - public BigDecimal getQuantity() { - return quantity; - } - - public void setQuantity(BigDecimal quantity) { - this.quantity = quantity; - } - - public Product getProduct() { - return product; - } - - public void setProduct(Product product) { - this.product = product; - } - - public IZUGFeRDAllowanceCharge[] getItemAllowances() { - // TODO Auto-generated method stub - return null; - } - - public IZUGFeRDAllowanceCharge[] getItemCharges() { - // TODO Auto-generated method stub - return null; - } - } - - class Product implements IZUGFeRDExportableProduct { - public Product(String description, String name, String unit, BigDecimal vATPercent) { - super(); - this.description = description; - this.name = name; - this.unit = unit; - VATPercent = vATPercent; - } - - private String description, name, unit; - private BigDecimal VATPercent; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUnit() { - return unit; - } - - public void setUnit(String unit) { - this.unit = unit; - } - - public BigDecimal getVATPercent() { - return VATPercent; - } - - public void setVATPercent(BigDecimal vATPercent) { - VATPercent = vATPercent; - } - } - - @Override - public Date getDeliveryDate() { - return new GregorianCalendar(2019, Calendar.JUNE, 10).getTime(); - } + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), getTradeSettlementPayment()[0].getOwnBIC()); + assertEquals(zi.getIBAN(), getTradeSettlementPayment()[0].getOwnIBAN()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); + } - @Override - public IZUGFeRDExportableTradeParty getRecipient() { - return new TradeParty("name","street","zip","city","DE"); - } + class Contact implements IZUGFeRDExportableContact { + public String getCountry() { + return "DE"; + } - @Override - public IZUGFeRDExportableTradeParty getSender() { - return new TradeParty("Bei Spiel GmbH","street","zip","city","DE"); - } - - - // + public String getLocation() { + return "Spielkreis"; + } + + public String getName() { + return "Theodor Est"; + } + + public String getStreet() { + return "Bahnstr. 42"; + } + + public String getVATID() { + return "DE999999999"; + } + + public String getZIP() { + return "88802"; + } + + } + + class Payment implements IZUGFeRDTradeSettlementPayment { + + @Override + public String getOwnBIC() { + return "bla"; + } + + @Override + public String getOwnIBAN() { + return "bla"; + } + + } + + class Item implements IZUGFeRDExportableItem { + public Item(BigDecimal price, BigDecimal quantity, Product product) { + super(); + this.price = price; + this.quantity = quantity; + this.product = product; + } + + private BigDecimal price, quantity; + private Product product; + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public BigDecimal getQuantity() { + return quantity; + } + + public void setQuantity(BigDecimal quantity) { + this.quantity = quantity; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + + public IZUGFeRDAllowanceCharge[] getItemAllowances() { + // TODO Auto-generated method stub + return null; + } + + public IZUGFeRDAllowanceCharge[] getItemCharges() { + // TODO Auto-generated method stub + return null; + } + } + + class Product implements IZUGFeRDExportableProduct { + public Product(String description, String name, String unit, BigDecimal vATPercent) { + super(); + this.description = description; + this.name = name; + this.unit = unit; + VATPercent = vATPercent; + } + + private String description, name, unit; + private BigDecimal VATPercent; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public BigDecimal getVATPercent() { + return VATPercent; + } + + public void setVATPercent(BigDecimal vATPercent) { + VATPercent = vATPercent; + } + } + + @Override + public Date getDeliveryDate() { + return new GregorianCalendar(2019, Calendar.JUNE, 10).getTime(); + } + + + @Override + public IZUGFeRDExportableTradeParty getRecipient() { + return new TradeParty("name", "street", "zip", "city", "DE"); + } + + @Override + public IZUGFeRDExportableTradeParty getSender() { + return new TradeParty("Bei Spiel GmbH", "street", "zip", "city", "DE"); + } + + + // public IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment() { - Payment P = new Payment(); - IZUGFeRDTradeSettlementPayment[] allP = new Payment[1]; - allP[0] = P; - return allP; + Payment P = new Payment(); + IZUGFeRDTradeSettlementPayment[] allP = new Payment[1]; + allP[0] = P; + return allP; - } + } - public IZUGFeRDAllowanceCharge[] getZFAllowances() { - // TODO Auto-generated method stub - return null; - } + public IZUGFeRDAllowanceCharge[] getZFAllowances() { + // TODO Auto-generated method stub + return null; + } - public IZUGFeRDAllowanceCharge[] getZFCharges() { - // TODO Auto-generated method stub - return null; - } + public IZUGFeRDAllowanceCharge[] getZFCharges() { + // TODO Auto-generated method stub + return null; + } - @Override - public IZUGFeRDExportableItem[] getZFItems() { - Item[] allItems = new Item[3]; - Product designProduct = new Product("", "Design (hours): Of a sample invoice", "HUR", - new BigDecimal("7.000000")); - Product balloonProduct = new Product("", "Ballons: various colors, ~2000ml", "C62", new BigDecimal("19.000000")); - Product airProduct = new Product("", "Hot air „heiße Luft“ (litres)", "LTR", new BigDecimal("19.000000")); + @Override + public IZUGFeRDExportableItem[] getZFItems() { + Item[] allItems = new Item[3]; + Product designProduct = new Product("", "Design (hours): Of a sample invoice", "HUR", + new BigDecimal("7.000000")); + Product balloonProduct = new Product("", "Ballons: various colors, ~2000ml", "C62", new BigDecimal("19.000000")); + Product airProduct = new Product("", "Hot air „heiße Luft“ (litres)", "LTR", new BigDecimal("19.000000")); - allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); - allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); - allItems[2] = new Item(new BigDecimal("0.025"), new BigDecimal("800"), airProduct); - return allItems; - } + allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); + allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); + allItems[2] = new Item(new BigDecimal("0.025"), new BigDecimal("800"), airProduct); + return allItems; + } - public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - // TODO Auto-generated method stub - return null; - } + public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { + // TODO Auto-generated method stub + return null; + } - @Override - public Date getDueDate() { - return new GregorianCalendar(2019, Calendar.JULY, 1).getTime(); - } + @Override + public Date getDueDate() { + return new GregorianCalendar(2019, Calendar.JULY, 1).getTime(); + } - @Override - public Date getIssueDate() { - return new GregorianCalendar(2019, Calendar.JUNE, 10).getTime(); - } + @Override + public Date getIssueDate() { + return new GregorianCalendar(2019, Calendar.JUNE, 10).getTime(); + } - @Override - public String getNumber() { - return "RE-20190610/507"; - } + @Override + public String getNumber() { + return "RE-20190610/507"; + } + public String getOwnBIC() { + return "COBADEFFXXX"; + } - public String getOwnBIC() { - return "COBADEFFXXX"; - } - - public String getOwnBankName() { - return "Commerzbank"; - } + public String getOwnBankName() { + return "Commerzbank"; + } - @Override - public String getOwnCountry() { - return "DE"; - } + @Override + public String getOwnCountry() { + return "DE"; + } - public String getOwnIBAN() { - return "DE88 2008 0000 0970 3757 00"; - } - - - @Override - public String getOwnLocation() { - return "Stadthausen"; - } - - @Override - public String getOwnOrganisationFullPlaintextInfo() { - return "Bei Spiel GmbH\n" + "Ecke 12\n" + "12345 Stadthausen\n" + "Geschäftsführer: Max Mustermann"; - } + public String getOwnIBAN() { + return "DE88 2008 0000 0970 3757 00"; + } - @Override - public String getOwnOrganisationName() { - return "Bei Spiel GmbH"; - } + @Override + public String getOwnLocation() { + return "Stadthausen"; + } - @Override - public String getOwnStreet() { - return "Ecke 12"; - } - - @Override - public String getOwnTaxID() { - return "22/815/0815/4"; - } - - @Override - public String getOwnVATID() { - return "DE136695976"; - } - - @Override - public String getOwnZIP() { - return "12345"; - } + @Override + public String getOwnOrganisationFullPlaintextInfo() { + return "Bei Spiel GmbH\n" + "Ecke 12\n" + "12345 Stadthausen\n" + "Geschäftsführer: Max Mustermann"; + } + @Override + public String getOwnOrganisationName() { + return "Bei Spiel GmbH"; + } + + @Override + public String getOwnStreet() { + return "Ecke 12"; + } + + @Override + public String getOwnTaxID() { + return "22/815/0815/4"; + } + + @Override + public String getOwnVATID() { + return "DE136695976"; + } + + @Override + public String getOwnZIP() { + return "12345"; + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/BaseTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/BaseTest.java index ad6f07c..d6fe9ff 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/BaseTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/BaseTest.java @@ -19,48 +19,48 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; import junit.framework.Test; -import junit.framework.TestSuite; import junit.framework.TestCase; - -import java.math.BigDecimal; +import junit.framework.TestSuite; import org.mustangproject.XMLTools; +import java.math.BigDecimal; + public class BaseTest extends TestCase { - /** - * Create the test case - * - * @param testName name of the test case - */ - public BaseTest(String testName) { - super(testName); - } + /** + * Create the test case + * + * @param testName name of the test case + */ + public BaseTest(String testName) { + super(testName); + } - /** - * @return the suite of tests being tested - */ - public static Test suite() { - return new TestSuite(BaseTest.class); - } + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(BaseTest.class); + } - public void testCorrectDigits() { - assertEquals("0.00", XMLTools.nDigitFormat(BigDecimal.ZERO,2)); - assertEquals("-1.10", XMLTools.nDigitFormat(new BigDecimal("-1.10"),2)); - assertEquals("-1.10", XMLTools.nDigitFormat(new BigDecimal("-1.1"),2)); - assertEquals("-1.01", XMLTools.nDigitFormat(new BigDecimal("-1.01"),2)); - assertEquals("20000123.35", XMLTools.nDigitFormat(new BigDecimal("20000123.3489"),2)); - assertEquals("20000123.34", XMLTools.nDigitFormat(new BigDecimal("20000123.3419"),2)); - assertEquals("12.00", XMLTools.nDigitFormat(new BigDecimal("12"),2)); - assertEquals("12", XMLTools.nDigitFormat(new BigDecimal("12"),0)); - assertEquals("20000123.342", XMLTools.nDigitFormat(new BigDecimal("20000123.3419"),3)); + public void testCorrectDigits() { + assertEquals("0.00", XMLTools.nDigitFormat(BigDecimal.ZERO, 2)); + assertEquals("-1.10", XMLTools.nDigitFormat(new BigDecimal("-1.10"), 2)); + assertEquals("-1.10", XMLTools.nDigitFormat(new BigDecimal("-1.1"), 2)); + assertEquals("-1.01", XMLTools.nDigitFormat(new BigDecimal("-1.01"), 2)); + assertEquals("20000123.35", XMLTools.nDigitFormat(new BigDecimal("20000123.3489"), 2)); + assertEquals("20000123.34", XMLTools.nDigitFormat(new BigDecimal("20000123.3419"), 2)); + assertEquals("12.00", XMLTools.nDigitFormat(new BigDecimal("12"), 2)); + assertEquals("12", XMLTools.nDigitFormat(new BigDecimal("12"), 0)); + assertEquals("20000123.342", XMLTools.nDigitFormat(new BigDecimal("20000123.3419"), 3)); - assertEquals("0.00", XMLTools.nDigitFormatDecimalRange(BigDecimal.ZERO,2, 2)); - assertEquals("-1.10", XMLTools.nDigitFormatDecimalRange(new BigDecimal("-1.100000"), 4,2)); - assertEquals("-1.101", XMLTools.nDigitFormatDecimalRange(new BigDecimal("-1.101000"),10, 3)); - assertEquals("-1.10", XMLTools.nDigitFormatDecimalRange(new BigDecimal("-1.103"), 2,2)); - assertEquals("4", XMLTools.nDigitFormatDecimalRange(new BigDecimal("4"),2, 0)); - assertEquals("3.14", XMLTools.nDigitFormatDecimalRange(new BigDecimal("3.141526"),2, 0)); + assertEquals("0.00", XMLTools.nDigitFormatDecimalRange(BigDecimal.ZERO, 2, 2)); + assertEquals("-1.10", XMLTools.nDigitFormatDecimalRange(new BigDecimal("-1.100000"), 4, 2)); + assertEquals("-1.101", XMLTools.nDigitFormatDecimalRange(new BigDecimal("-1.101000"), 10, 3)); + assertEquals("-1.10", XMLTools.nDigitFormatDecimalRange(new BigDecimal("-1.103"), 2, 2)); + assertEquals("4", XMLTools.nDigitFormatDecimalRange(new BigDecimal("4"), 2, 0)); + assertEquals("3.14", XMLTools.nDigitFormatDecimalRange(new BigDecimal("3.141526"), 2, 0)); - } + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ByteArraySearcherTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ByteArraySearcherTest.java index df752f5..1513ab5 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ByteArraySearcherTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ByteArraySearcherTest.java @@ -1,43 +1,43 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; +import org.junit.Test; +import org.mustangproject.util.ByteArraySearcher; + +import java.nio.charset.StandardCharsets; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; -import java.nio.charset.StandardCharsets; - -import org.junit.Test; -import org.mustangproject.util.ByteArraySearcher; - public class ByteArraySearcherTest { - @Test - public void testIndexOf () { - byte [] haystack = "Hello World".getBytes (StandardCharsets.ISO_8859_1); - assertEquals (0, ByteArraySearcher.indexOf (haystack, new byte [] { 'H' })); - assertEquals (1, ByteArraySearcher.indexOf (haystack, new byte [] { 'e' })); - assertEquals (0, ByteArraySearcher.indexOf (haystack, new byte [] { 'H', 'e' })); - assertEquals (0, ByteArraySearcher.indexOf (haystack, new byte [] { 'H', 'e' })); - assertEquals (0, ByteArraySearcher.indexOf (haystack, new byte [] { 'H', 'e', 'l', 'l' })); - assertEquals (0, ByteArraySearcher.indexOf (haystack, haystack)); - assertEquals (-1, ByteArraySearcher.indexOf (haystack, new byte [0])); - assertEquals (-1, ByteArraySearcher.indexOf (haystack, new byte [] { 'a' })); - assertEquals (-1, ByteArraySearcher.indexOf (haystack, new byte [] { 'h' })); - assertEquals (-1, ByteArraySearcher.indexOf (haystack, new byte [] { 'r', 'o' })); - } + @Test + public void testIndexOf() { + byte[] haystack = "Hello World".getBytes(StandardCharsets.ISO_8859_1); + assertEquals(0, ByteArraySearcher.indexOf(haystack, new byte []{'H'})); + assertEquals(1, ByteArraySearcher.indexOf(haystack, new byte []{'e'})); + assertEquals(0, ByteArraySearcher.indexOf(haystack, new byte []{'H', 'e'})); + assertEquals(0, ByteArraySearcher.indexOf(haystack, new byte []{'H', 'e'})); + assertEquals(0, ByteArraySearcher.indexOf(haystack, new byte []{'H', 'e', 'l', 'l'})); + assertEquals(0, ByteArraySearcher.indexOf(haystack, haystack)); + assertEquals(-1, ByteArraySearcher.indexOf(haystack, new byte [0])); + assertEquals(-1, ByteArraySearcher.indexOf(haystack, new byte []{'a'})); + assertEquals(-1, ByteArraySearcher.indexOf(haystack, new byte []{'h'})); + assertEquals(-1, ByteArraySearcher.indexOf(haystack, new byte []{'r', 'o'})); + } - @Test - public void testStartsWith () { - byte [] haystack = "Hello World".getBytes (StandardCharsets.ISO_8859_1); - assertTrue (ByteArraySearcher.startsWith (haystack, new byte [] { 'H' })); - assertFalse (ByteArraySearcher.startsWith (haystack, new byte [] { 'e' })); - assertTrue (ByteArraySearcher.startsWith (haystack, new byte [] { 'H', 'e' })); - assertTrue (ByteArraySearcher.startsWith (haystack, new byte [] { 'H', 'e' })); - assertTrue (ByteArraySearcher.startsWith (haystack, new byte [] { 'H', 'e', 'l', 'l' })); - assertTrue (ByteArraySearcher.startsWith (haystack, haystack)); - assertFalse (ByteArraySearcher.startsWith (haystack, new byte [0])); - assertFalse (ByteArraySearcher.startsWith (haystack, new byte [] { 'a' })); - assertFalse (ByteArraySearcher.startsWith (haystack, new byte [] { 'h' })); - assertFalse (ByteArraySearcher.startsWith (haystack, new byte [] { 'r', 'o' })); - } + @Test + public void testStartsWith() { + byte[] haystack = "Hello World".getBytes(StandardCharsets.ISO_8859_1); + assertTrue(ByteArraySearcher.startsWith(haystack, new byte []{'H'})); + assertFalse(ByteArraySearcher.startsWith(haystack, new byte []{'e'})); + assertTrue(ByteArraySearcher.startsWith(haystack, new byte []{'H', 'e'})); + assertTrue(ByteArraySearcher.startsWith(haystack, new byte []{'H', 'e'})); + assertTrue(ByteArraySearcher.startsWith(haystack, new byte []{'H', 'e', 'l', 'l'})); + assertTrue(ByteArraySearcher.startsWith(haystack, haystack)); + assertFalse(ByteArraySearcher.startsWith(haystack, new byte [0])); + assertFalse(ByteArraySearcher.startsWith(haystack, new byte []{'a'})); + assertFalse(ByteArraySearcher.startsWith(haystack, new byte []{'h'})); + assertFalse(ByteArraySearcher.startsWith(haystack, new byte []{'r', 'o'})); + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/CalculationTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/CalculationTest.java index 6d84a0f..1ce8ca6 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/CalculationTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/CalculationTest.java @@ -1,9 +1,5 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; -import static java.math.BigDecimal.TEN; -import static java.math.BigDecimal.valueOf; -import static org.junit.Assert.assertEquals; - import org.junit.Test; import org.mustangproject.*; import org.slf4j.Logger; @@ -12,193 +8,197 @@ import java.math.BigDecimal; import java.text.SimpleDateFormat; +import static java.math.BigDecimal.TEN; +import static java.math.BigDecimal.valueOf; +import static org.junit.Assert.assertEquals; + /*** * tests the linecalculator and transactioncalculator classes * */ public class CalculationTest { - private static final Logger LOGGER = LoggerFactory.getLogger(CalculationTest.class); + private static final Logger LOGGER = LoggerFactory.getLogger(CalculationTest.class); - @Test - public void testLineCalculator_simpleAmounts_resultInValidVATAmount() { - final IZUGFeRDExportableProduct product = new IZUGFeRDExportableProductImpl().setVatPercent(valueOf(16)); - final IZUGFeRDExportableItem currentItem = new IZUGFeRDExportableItemImpl().setPrice(valueOf(100)) - .setQuantity(TEN) - .setProduct(product); + @Test + public void testLineCalculator_simpleAmounts_resultInValidVATAmount() { + final IZUGFeRDExportableProduct product = new IZUGFeRDExportableProductImpl().setVatPercent(valueOf(16)); + final IZUGFeRDExportableItem currentItem = new IZUGFeRDExportableItemImpl().setPrice(valueOf(100)) + .setQuantity(TEN) + .setProduct(product); - final LineCalculator calculator = new LineCalculator(currentItem); + final LineCalculator calculator = new LineCalculator(currentItem); - assertEquals(valueOf(100).stripTrailingZeros(), calculator.getPrice().stripTrailingZeros()); - assertEquals(valueOf(1000).stripTrailingZeros(), calculator.getItemTotalNetAmount().stripTrailingZeros()); - assertEquals(valueOf(160).stripTrailingZeros(), calculator.getItemTotalVATAmount().stripTrailingZeros()); - } + assertEquals(valueOf(100).stripTrailingZeros(), calculator.getPrice().stripTrailingZeros()); + assertEquals(valueOf(1000).stripTrailingZeros(), calculator.getItemTotalNetAmount().stripTrailingZeros()); + assertEquals(valueOf(160).stripTrailingZeros(), calculator.getItemTotalVATAmount().stripTrailingZeros()); + } - @Test - public void testLineCalculatorInclusiveAllowance() { - //This test failed with previous implementation. By rounding the totalVATAmount to 2 decimal places the result became wrong - final IZUGFeRDExportableProduct product = new IZUGFeRDExportableProductImpl().setVatPercent(valueOf(16)); - // 10 % discount on each item - final IZUGFeRDAllowanceCharge allowance = new IZUGFeRDAllowanceChargeImpl().setTotalAmount(valueOf(14.8730)); + @Test + public void testLineCalculatorInclusiveAllowance() { + // This test failed with previous implementation. By rounding the totalVATAmount to 2 decimal places the result became wrong + final IZUGFeRDExportableProduct product = new IZUGFeRDExportableProductImpl().setVatPercent(valueOf(16)); + // 10 % discount on each item + final IZUGFeRDAllowanceCharge allowance = new IZUGFeRDAllowanceChargeImpl().setTotalAmount(valueOf(14.8730)); - final IZUGFeRDExportableItem currentItem = new IZUGFeRDExportableItemImpl().setPrice(valueOf(148.73)) - .setQuantity(valueOf(12)) - .setItemAllowances(new IZUGFeRDAllowanceCharge[]{allowance}) - .setProduct(product); + final IZUGFeRDExportableItem currentItem = new IZUGFeRDExportableItemImpl().setPrice(valueOf(148.73)) + .setQuantity(valueOf(12)) + .setItemAllowances(new IZUGFeRDAllowanceCharge[]{allowance}) + .setProduct(product); - final LineCalculator calculator = new LineCalculator(currentItem); + final LineCalculator calculator = new LineCalculator(currentItem); - assertEquals(valueOf(133.857).stripTrailingZeros(), calculator.getPrice().stripTrailingZeros()); - assertEquals(valueOf(1606.28).stripTrailingZeros(), calculator.getItemTotalNetAmount().stripTrailingZeros()); - assertEquals(valueOf(257.0048).stripTrailingZeros(), calculator.getItemTotalVATAmount().stripTrailingZeros()); - } + assertEquals(valueOf(133.857).stripTrailingZeros(), calculator.getPrice().stripTrailingZeros()); + assertEquals(valueOf(1606.28).stripTrailingZeros(), calculator.getItemTotalNetAmount().stripTrailingZeros()); + assertEquals(valueOf(257.0048).stripTrailingZeros(), calculator.getItemTotalVATAmount().stripTrailingZeros()); + } - @Test - public void testLineCalculatorInclusiveAllowanceAndCharge() { - final IZUGFeRDExportableProduct product = new IZUGFeRDExportableProductImpl().setVatPercent(valueOf(16)); - // 10 % discount on each item - final IZUGFeRDAllowanceCharge allowance = new IZUGFeRDAllowanceChargeImpl().setTotalAmount(valueOf(14.873)); - // 20 % charge - final IZUGFeRDAllowanceCharge charge = new IZUGFeRDAllowanceChargeImpl().setTotalAmount(valueOf(29.746)); - final IZUGFeRDExportableItem currentItem = new IZUGFeRDExportableItemImpl().setPrice(valueOf(148.73)) - .setQuantity(valueOf(12)) - .setItemAllowances(new IZUGFeRDAllowanceCharge[]{allowance}) - .setItemCharges(new IZUGFeRDAllowanceCharge[]{charge}) - .setProduct(product); + @Test + public void testLineCalculatorInclusiveAllowanceAndCharge() { + final IZUGFeRDExportableProduct product = new IZUGFeRDExportableProductImpl().setVatPercent(valueOf(16)); + // 10 % discount on each item + final IZUGFeRDAllowanceCharge allowance = new IZUGFeRDAllowanceChargeImpl().setTotalAmount(valueOf(14.873)); + // 20 % charge + final IZUGFeRDAllowanceCharge charge = new IZUGFeRDAllowanceChargeImpl().setTotalAmount(valueOf(29.746)); + final IZUGFeRDExportableItem currentItem = new IZUGFeRDExportableItemImpl().setPrice(valueOf(148.73)) + .setQuantity(valueOf(12)) + .setItemAllowances(new IZUGFeRDAllowanceCharge[]{allowance}) + .setItemCharges(new IZUGFeRDAllowanceCharge[]{charge}) + .setProduct(product); - final LineCalculator calculator = new LineCalculator(currentItem); + final LineCalculator calculator = new LineCalculator(currentItem); - assertEquals(valueOf(163.603).stripTrailingZeros(), calculator.getPrice().stripTrailingZeros()); - assertEquals(valueOf(1963.24).stripTrailingZeros(), calculator.getItemTotalNetAmount().stripTrailingZeros()); - assertEquals(valueOf(314.1184).stripTrailingZeros(), calculator.getItemTotalVATAmount().stripTrailingZeros()); - } + assertEquals(valueOf(163.603).stripTrailingZeros(), calculator.getPrice().stripTrailingZeros()); + assertEquals(valueOf(1963.24).stripTrailingZeros(), calculator.getItemTotalNetAmount().stripTrailingZeros()); + assertEquals(valueOf(314.1184).stripTrailingZeros(), calculator.getItemTotalVATAmount().stripTrailingZeros()); + } - @Test - public void testTotalCalculatorGrandTotalRounding() { - SimpleDateFormat sqlDate = new SimpleDateFormat("yyyy-MM-dd"); + @Test + public void testTotalCalculatorGrandTotalRounding() { + SimpleDateFormat sqlDate = new SimpleDateFormat("yyyy-MM-dd"); - BigDecimal sales_tax_percent1 = new BigDecimal(16); - BigDecimal total_increase_percent = new BigDecimal(0.80); - BigDecimal total_discount_percent = new BigDecimal(2.00); + BigDecimal sales_tax_percent1 = new BigDecimal(16); + BigDecimal total_increase_percent = new BigDecimal(0.80); + BigDecimal total_discount_percent = new BigDecimal(2.00); - /* invoice (1st part) */ + /* invoice (1st part) */ - Invoice invoice = new Invoice(); - invoice.setDocumentName("Rechnung"); - invoice.setNumber("777777"); - try { - invoice.setIssueDate(sqlDate.parse("2020-12-31")); - invoice.setDetailedDeliveryPeriod(sqlDate.parse("2020-12-01 - 2020-12-31".split(" - ")[0]), sqlDate.parse("2020-12-01 - 2020-12-31".split(" - ")[1])); - invoice.setDeliveryDate(sqlDate.parse("2020-12-31")); - invoice.setDueDate(sqlDate.parse("2021-01-15")); - } catch (Exception e) { - LOGGER.error("Failed to set dates", e); + Invoice invoice = new Invoice(); + invoice.setDocumentName("Rechnung"); + invoice.setNumber("777777"); + try { + invoice.setIssueDate(sqlDate.parse("2020-12-31")); + invoice.setDetailedDeliveryPeriod(sqlDate.parse("2020-12-01 - 2020-12-31".split(" - ")[0]), sqlDate.parse("2020-12-01 - 2020-12-31".split(" - ")[1])); + invoice.setDeliveryDate(sqlDate.parse("2020-12-31")); + invoice.setDueDate(sqlDate.parse("2021-01-15")); + } catch (Exception e) { + LOGGER.error("Failed to set dates", e); - } + } - /* trade party (sender) */ - TradeParty sender = new TradeParty("Maier GmbH", "Musterweg 5", "11111", "Testung", "DE"); - sender.addVATID("DE2222222222"); - invoice.setSender(sender); + /* trade party (sender) */ + TradeParty sender = new TradeParty("Maier GmbH", "Musterweg 5", "11111", "Testung", "DE"); + sender.addVATID("DE2222222222"); + invoice.setSender(sender); - /* trade party (recipient) */ - TradeParty recipient = new TradeParty("Teston GmbH" + " " + "Zentrale" + " " + "", "Testweg 5", "11111", "Testung", "DE"); - recipient.setID("111111"); - recipient.addVATID("DE111111111"); - invoice.setRecipient(recipient); + /* trade party (recipient) */ + TradeParty recipient = new TradeParty("Teston GmbH" + " " + "Zentrale" + " " + "", "Testweg 5", "11111", "Testung", "DE"); + recipient.setID("111111"); + recipient.addVATID("DE111111111"); + invoice.setRecipient(recipient); - /* item */ - Product product; - Item item; + /* item */ + Product product; + Item item; - product = new Product("AAA", "", "H84", sales_tax_percent1).setSellerAssignedID("1AAA"); - item = new Item(product, new BigDecimal("4.750"), new BigDecimal(5.00)); + product = new Product("AAA", "", "H84", sales_tax_percent1).setSellerAssignedID("1AAA"); + item = new Item(product, new BigDecimal("4.750"), new BigDecimal(5.00)); - // set values for additional charge and discount used for next lines - BigDecimal item_increase = BigDecimal.ZERO; - BigDecimal item_discount = BigDecimal.valueOf(10.00); + // set values for additional charge and discount used for next lines + BigDecimal item_increase = BigDecimal.ZERO; + BigDecimal item_discount = BigDecimal.valueOf(10.00); - /* lines */ - if (item_increase.compareTo(BigDecimal.ZERO) > 0) { - item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); - } - if (item_discount.compareTo(BigDecimal.ZERO) > 0) { - item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); - } - invoice.addItem(item); + /* lines */ + if (item_increase.compareTo(BigDecimal.ZERO) > 0) { + item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); + } + if (item_discount.compareTo(BigDecimal.ZERO) > 0) { + item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); + } + invoice.addItem(item); - // reset values for additional charge and discount used for next lines - item_increase = BigDecimal.ZERO; - item_discount = BigDecimal.ZERO; + // reset values for additional charge and discount used for next lines + item_increase = BigDecimal.ZERO; + item_discount = BigDecimal.ZERO; - product = new Product("BBB", "", "H84", sales_tax_percent1).setSellerAssignedID("2BBB"); - item = new Item(product, new BigDecimal("5.750"), new BigDecimal(4.00)); - if (item_increase.compareTo(BigDecimal.ZERO) > 0) { - item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); - } - if (item_discount.compareTo(BigDecimal.ZERO) > 0) { - item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); - } - invoice.addItem(item); + product = new Product("BBB", "", "H84", sales_tax_percent1).setSellerAssignedID("2BBB"); + item = new Item(product, new BigDecimal("5.750"), new BigDecimal(4.00)); + if (item_increase.compareTo(BigDecimal.ZERO) > 0) { + item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); + } + if (item_discount.compareTo(BigDecimal.ZERO) > 0) { + item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); + } + invoice.addItem(item); - product = new Product("CCC", "", "H84", sales_tax_percent1).setSellerAssignedID("3CCC"); - item = new Item(product, new BigDecimal("6.750"), new BigDecimal(3.00)); - if (item_increase.compareTo(BigDecimal.ZERO) > 0) { - item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); - } - if (item_discount.compareTo(BigDecimal.ZERO) > 0) { - item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); - } - invoice.addItem(item); + product = new Product("CCC", "", "H84", sales_tax_percent1).setSellerAssignedID("3CCC"); + item = new Item(product, new BigDecimal("6.750"), new BigDecimal(3.00)); + if (item_increase.compareTo(BigDecimal.ZERO) > 0) { + item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); + } + if (item_discount.compareTo(BigDecimal.ZERO) > 0) { + item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); + } + invoice.addItem(item); - product = new Product("DDD", "", "H84", sales_tax_percent1).setSellerAssignedID("4DDD"); - item = new Item(product, new BigDecimal("7.750"), new BigDecimal(2.00)); - if (item_increase.compareTo(BigDecimal.ZERO) > 0) { - item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); - } - if (item_discount.compareTo(BigDecimal.ZERO) > 0) { - item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); - } - invoice.addItem(item); + product = new Product("DDD", "", "H84", sales_tax_percent1).setSellerAssignedID("4DDD"); + item = new Item(product, new BigDecimal("7.750"), new BigDecimal(2.00)); + if (item_increase.compareTo(BigDecimal.ZERO) > 0) { + item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); + } + if (item_discount.compareTo(BigDecimal.ZERO) > 0) { + item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); + } + invoice.addItem(item); - product = new Product("EEE", "", "H84", sales_tax_percent1).setSellerAssignedID("5EEE"); - item = new Item(product, new BigDecimal("8.750"), new BigDecimal(1.00)); - if (item_increase.compareTo(BigDecimal.ZERO) > 0) { - item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); - } - if (item_discount.compareTo(BigDecimal.ZERO) > 0) { - item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); + product = new Product("EEE", "", "H84", sales_tax_percent1).setSellerAssignedID("5EEE"); + item = new Item(product, new BigDecimal("8.750"), new BigDecimal(1.00)); + if (item_increase.compareTo(BigDecimal.ZERO) > 0) { + item.addCharge(new Charge().setPercent(item_increase).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschlag")); + } + if (item_discount.compareTo(BigDecimal.ZERO) > 0) { + item.addAllowance(new Allowance().setPercent(item_discount).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatt")); - } - invoice.addItem(item); + } + invoice.addItem(item); - // reset values for additional charge and discount used on invoice level - item_increase = BigDecimal.valueOf(3.50); - item_discount = BigDecimal.valueOf(10.00); + // reset values for additional charge and discount used on invoice level + item_increase = BigDecimal.valueOf(3.50); + item_discount = BigDecimal.valueOf(10.00); - if (total_increase_percent.compareTo(BigDecimal.ZERO) > 0) { - invoice.addCharge(new Charge().setPercent(total_increase_percent).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschläge")); - } - if (total_discount_percent.compareTo(BigDecimal.ZERO) > 0) { - invoice.addAllowance(new Allowance().setPercent(total_discount_percent).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatte")); - } - TransactionCalculator calculator = new TransactionCalculator(invoice); - assertEquals(valueOf(101.86).stripTrailingZeros(), calculator.getGrandTotal().stripTrailingZeros()); - } + if (total_increase_percent.compareTo(BigDecimal.ZERO) > 0) { + invoice.addCharge(new Charge().setPercent(total_increase_percent).setTaxPercent(sales_tax_percent1).setReasonCode("ZZZ").setReason("Zuschläge")); + } + if (total_discount_percent.compareTo(BigDecimal.ZERO) > 0) { + invoice.addAllowance(new Allowance().setPercent(total_discount_percent).setTaxPercent(sales_tax_percent1).setReasonCode("95").setReason("Rabatte")); + } + TransactionCalculator calculator = new TransactionCalculator(invoice); + assertEquals(valueOf(101.86).stripTrailingZeros(), calculator.getGrandTotal().stripTrailingZeros()); + } - /** - * LineCalculator should not throw an exception when calculating a non-terminating decimal expansion - * */ - @Test - public void testNonTerminatingDecimalExpansion() { - final Product product = new Product(); - final IZUGFeRDExportableItem currentItem = new Item().setPrice(valueOf(386.52)) - .setQuantity(BigDecimal.valueOf(31)) - .setBasisQuantity(BigDecimal.valueOf(366)) - .setProduct(product); - final LineCalculator calculator = new LineCalculator(currentItem); - assertEquals(BigDecimal.valueOf(32.74), calculator.getItemTotalNetAmount()); - } + /** + * LineCalculator should not throw an exception when calculating a non-terminating decimal expansion + * */ + @Test + public void testNonTerminatingDecimalExpansion() { + final Product product = new Product(); + final IZUGFeRDExportableItem currentItem = new Item().setPrice(valueOf(386.52)) + .setQuantity(BigDecimal.valueOf(31)) + .setBasisQuantity(BigDecimal.valueOf(366)) + .setProduct(product); + final LineCalculator calculator = new LineCalculator(currentItem); + assertEquals(BigDecimal.valueOf(32.74), calculator.getItemTotalNetAmount()); + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java index 746e7cb..f69a252 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java @@ -1,4 +1,3 @@ org.openrewrite.config.CompositeRecipe - /** * ********************************************************************* *

@@ -21,11 +20,8 @@ */ package org.mustangproject.ZUGFeRD; -import com.fasterxml.jackson.annotation.JsonInclude; 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.*; @@ -34,7 +30,6 @@ 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; @@ -44,752 +39,752 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class DeSerializationTest extends ResourceCase { - public void testJackson() throws JsonProcessingException { + public void testJackson() throws JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); - Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty("some org", "teststr", "55232", "teststadt", "DE").addTaxID("taxID").addBankDetails(new BankDetails("DE3600000123456", "ABCDEFG1001").setAccountName("Donald Duck")).setEmail("info@company.com")).setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber("0185").addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal("1"), new BigDecimal(1.0))); - String jsonArray = mapper.writeValueAsString(i); + ObjectMapper mapper = new ObjectMapper(); + Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty("some org", "teststr", "55232", "teststadt", "DE").addTaxID("taxID").addBankDetails(new BankDetails("DE3600000123456", "ABCDEFG1001").setAccountName("Donald Duck")).setEmail("info@company.com")).setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber("0185").addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal("1"), new BigDecimal(1.0))); + String jsonArray = mapper.writeValueAsString(i); - // [{"stringValue":"a","intValue":1,"booleanValue":true}, - // {"stringValue":"bc","intValue":3,"booleanValue":false}] + // [{"stringValue":"a","intValue":1,"booleanValue":true}, + // {"stringValue":"bc","intValue":3,"booleanValue":false}] - Invoice fromJSON = mapper.readValue(jsonArray, Invoice.class); - assertEquals(fromJSON.getNumber(), i.getNumber()); - assertEquals(fromJSON.getZFItems().length, i.getZFItems().length); - assertEquals("info@company.com", fromJSON.getSender().getEmail()); - assertEquals("info@company.com", fromJSON.getSender().getUriUniversalCommunicationID()); + Invoice fromJSON = mapper.readValue(jsonArray, Invoice.class); + assertEquals(fromJSON.getNumber(), i.getNumber()); + assertEquals(fromJSON.getZFItems().length, i.getZFItems().length); + assertEquals("info@company.com", fromJSON.getSender().getEmail()); + assertEquals("info@company.com", fromJSON.getSender().getUriUniversalCommunicationID()); - } + } - public void testInvoiceLine() throws JsonProcessingException { - File inputCII = getResourceAsFile("factur-x.xml"); - boolean hasExceptions = false; + 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)); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + try { + zii.fromXML(new String(Files.readAllBytes(inputCII.toPath()), StandardCharsets.UTF_8)); - } catch (IOException e) { - hasExceptions = true; - } + } 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")); + 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 { + public void testAllowanceRead() throws JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); + ObjectMapper mapper = new ObjectMapper(); - // [{"stringValue":"a","intValue":1,"booleanValue":true}, - // {"stringValue":"bc","intValue":3,"booleanValue":false}] + // [{"stringValue":"a","intValue":1,"booleanValue":true}, + // {"stringValue":"bc","intValue":3,"booleanValue":false}] - Invoice fromJSON = mapper.readValue("{\n" + - " \"documentCode\": \"380\",\n" + - " \"number\": \"471102\",\n" + - " \"ownOrganisationName\": \"Lieferant GmbH\",\n" + - " \"currency\": \"EUR\",\n" + - " \"issueDate\": \"2018-03-03T23:00:00.000+00:00\",\n" + - " \"deliveryDate\": \"2018-03-03T23:00:00.000+00:00\",\n" + - " \"sender\": {\n" + - " \"name\": \"Lieferant GmbH\",\n" + - " \"zip\": \"80333\",\n" + - " \"street\": \"Lieferantenstraße 20\",\n" + - " \"location\": \"München\",\n" + - " \"country\": \"DE\",\n" + - " \"taxID\": \"201/113/40209\",\n" + - " \"vatID\": \"DE123456789\",\n" + - " \"vatid\": \"DE123456789\"\n" + - " },\n" + - " \"recipient\": {\n" + - " \"name\": \"Kunden AG Mitte\",\n" + - " \"zip\": \"69876\",\n" + - " \"street\": \"Kundenstraße 15\",\n" + - " \"location\": \"Frankfurt\",\n" + - " \"country\": \"DE\"\n" + - " },\n" + - " \"grandTotal\": 234.43,\n" + - " \"zfitems\": [\n" + - " {\n" + - " \"price\": 9.9,\n" + - " \"quantity\": 20,\n" + - " \"tax\": null,\n" + - " \"grossPrice\": null,\n" + - " \"lineTotalAmount\": null,\n" + - " \"basisQuantity\": 1,\n" + - " \"detailedDeliveryPeriodFrom\": null,\n" + - " \"detailedDeliveryPeriodTo\": null,\n" + - " \"id\": null,\n" + - " \"product\": {\n" + - " \"unit\": \"H87\",\n" + - " \"name\": \"Trennblätter A4\",\n" + - " \"taxCategoryCode\": \"S\",\n" + - " \"attributes\": null,\n" + - " \"vatpercent\": 19\n" + - " },\n" + - " \"value\": 9.9\n" + - " }\n" + - " ],\n" + - " \"tradeSettlement\": null,\n" + - " \"ownTaxID\": \"201/113/40209\",\n" + - " \"ownVATID\": \"DE123456789\",\n" + - " \"ownStreet\": \"Lieferantenstraße 20\",\n" + - " \"ownZIP\": \"80333\",\n" + - " \"ownLocation\": \"München\",\n" + - " \"ownCountry\": \"DE\",\n" + - " \"zfallowances\": [\n" + - " {\n" + - " \"totalAmount\": 1,\n" + - " \"taxPercent\": 19,\n" + - " \"reason\": \"Sondernachlass\",\n" + - " \"reasonCode\": null,\n" + - " \"categoryCode\": \"S\",\n" + - " \"charge\": false\n" + - " }\n" + - " ]\n" + - "}", Invoice.class); - TransactionCalculator tc = new TransactionCalculator(fromJSON); - assertEquals(tc.getGrandTotal(), new BigDecimal("234.43")); - assertEquals(fromJSON.getNumber(), fromJSON.getNumber()); - assertEquals(fromJSON.getZFItems().length, fromJSON.getZFItems().length); + Invoice fromJSON = mapper.readValue("{\n" + + " \"documentCode\": \"380\",\n" + + " \"number\": \"471102\",\n" + + " \"ownOrganisationName\": \"Lieferant GmbH\",\n" + + " \"currency\": \"EUR\",\n" + + " \"issueDate\": \"2018-03-03T23:00:00.000+00:00\",\n" + + " \"deliveryDate\": \"2018-03-03T23:00:00.000+00:00\",\n" + + " \"sender\": {\n" + + " \"name\": \"Lieferant GmbH\",\n" + + " \"zip\": \"80333\",\n" + + " \"street\": \"Lieferantenstraße 20\",\n" + + " \"location\": \"München\",\n" + + " \"country\": \"DE\",\n" + + " \"taxID\": \"201/113/40209\",\n" + + " \"vatID\": \"DE123456789\",\n" + + " \"vatid\": \"DE123456789\"\n" + + " },\n" + + " \"recipient\": {\n" + + " \"name\": \"Kunden AG Mitte\",\n" + + " \"zip\": \"69876\",\n" + + " \"street\": \"Kundenstraße 15\",\n" + + " \"location\": \"Frankfurt\",\n" + + " \"country\": \"DE\"\n" + + " },\n" + + " \"grandTotal\": 234.43,\n" + + " \"zfitems\": [\n" + + " {\n" + + " \"price\": 9.9,\n" + + " \"quantity\": 20,\n" + + " \"tax\": null,\n" + + " \"grossPrice\": null,\n" + + " \"lineTotalAmount\": null,\n" + + " \"basisQuantity\": 1,\n" + + " \"detailedDeliveryPeriodFrom\": null,\n" + + " \"detailedDeliveryPeriodTo\": null,\n" + + " \"id\": null,\n" + + " \"product\": {\n" + + " \"unit\": \"H87\",\n" + + " \"name\": \"Trennblätter A4\",\n" + + " \"taxCategoryCode\": \"S\",\n" + + " \"attributes\": null,\n" + + " \"vatpercent\": 19\n" + + " },\n" + + " \"value\": 9.9\n" + + " }\n" + + " ],\n" + + " \"tradeSettlement\": null,\n" + + " \"ownTaxID\": \"201/113/40209\",\n" + + " \"ownVATID\": \"DE123456789\",\n" + + " \"ownStreet\": \"Lieferantenstraße 20\",\n" + + " \"ownZIP\": \"80333\",\n" + + " \"ownLocation\": \"München\",\n" + + " \"ownCountry\": \"DE\",\n" + + " \"zfallowances\": [\n" + + " {\n" + + " \"totalAmount\": 1,\n" + + " \"taxPercent\": 19,\n" + + " \"reason\": \"Sondernachlass\",\n" + + " \"reasonCode\": null,\n" + + " \"categoryCode\": \"S\",\n" + + " \"charge\": false\n" + + " }\n" + + " ]\n" + + "}", Invoice.class); + 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 testDeserializedFiles() { - File inputUBL = getResourceAsFile("XRECHNUNG_Elektron.ubl.xml"); - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); - zii.doIgnoreCalculationErrors(); - Invoice i = new Invoice(); - String exText = null; + public void testDeserializedFiles() { + File inputUBL = getResourceAsFile("XRECHNUNG_Elektron.ubl.xml"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + zii.doIgnoreCalculationErrors(); + Invoice i = new Invoice(); + String exText = null; - try { - zii.fromXML(new String(Files.readAllBytes(inputUBL.toPath()), StandardCharsets.UTF_8)); - ObjectMapper mapper = new ObjectMapper(); - zii.extractInto(i); - String json = mapper.writeValueAsString(i); - Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); + try { + zii.fromXML(new String(Files.readAllBytes(inputUBL.toPath()), StandardCharsets.UTF_8)); + ObjectMapper mapper = new ObjectMapper(); + zii.extractInto(i); + String json = mapper.writeValueAsString(i); + Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); - assertEquals("181301674", i.getNumber()); - assertEquals(newInvoiceFromJSON.getNumber(), i.getNumber()); - assertEquals(newInvoiceFromJSON.getAdditionalReferencedDocuments()[0].getFilename(), i.getAdditionalReferencedDocuments()[0].getFilename()); - assertEquals(newInvoiceFromJSON.getAdditionalReferencedDocuments().length, 2); + assertEquals("181301674", i.getNumber()); + assertEquals(newInvoiceFromJSON.getNumber(), i.getNumber()); + assertEquals(newInvoiceFromJSON.getAdditionalReferencedDocuments()[0].getFilename(), i.getAdditionalReferencedDocuments()[0].getFilename()); + assertEquals(newInvoiceFromJSON.getAdditionalReferencedDocuments().length, 2); - } catch (IOException e) { - exText = e.getMessage(); - } catch (XPathExpressionException e) { - exText = e.getMessage(); - } catch (ParseException e) { - exText = e.getMessage(); - } - assertNull(exText); + } catch (IOException e) { + exText = e.getMessage(); + } catch (XPathExpressionException e) { + exText = e.getMessage(); + } catch (ParseException e) { + exText = e.getMessage(); + } + assertNull(exText); - } + } - public void testFileSerialization() { + public void testFileSerialization() { - String base64 = "b25ldHdvdGhyZWU="; - String json = "{\n" + - " \"additionalReferencedDocuments\": [\n" + - " {\n" + - " \"data\": \"" + base64 + "\",\n" + - " \"description\": \"Additional file attachment\",\n" + - " \"filename\": \"text.txt\",\n" + - " \"mimetype\": \"text/plain\",\n" + - " \"relation\": \"Data\"\n" + - " }\n" + - "],\n" + - "\n" + - " \"number\": \"471102\",\n" + - " \"currency\": \"EUR\",\n" + - " \"issueDate\": \"2018-03-04T00:00:00.000+01:00\",\n" + - " \"dueDate\": \"2018-03-04T00:00:00.000+01:00\",\n" + - " \"deliveryDate\": \"2018-03-04T00:00:00.000+01:00\",\n" + - " \"sender\": {\n" + - " \"name\": \"Lieferant GmbH\",\n" + - " \"zip\": \"80333\",\n" + - " \"street\": \"Lieferantenstraße 20\",\n" + - " \"location\": \"München\",\n" + - " \"country\": \"DE\",\n" + - " \"taxID\": \"201/113/40209\",\n" + - " \"vatID\": \"DE123456789\",\n" + - " \"globalID\": \"4000001123452\",\n" + - " \"globalIDScheme\": \"0088\"\n" + - " },\n" + - " \"recipient\": {\n" + - " \"name\": \"Kunden AG Mitte\",\n" + - " \"zip\": \"69876\",\n" + - " \"street\": \"Kundenstraße 15\",\n" + - " \"location\": \"Frankfurt\",\n" + - " \"country\": \"DE\"\n" + - " },\n" + - " \"zfitems\": [\n" + - " {\n" + - " \"price\": 9.9,\n" + - " \"quantity\": 20,\n" + - " \"product\": {\n" + - " \"unit\": \"H87\",\n" + - " \"name\": \"Trennblätter A4\",\n" + - " \"description\": \"\",\n" + - " \"vatpercent\": 19,\n" + - " \"taxCategoryCode\": \"S\"\n" + - " }\n" + - " },\n" + - " {\n" + - " \"price\": 5.5,\n" + - " \"quantity\": 50,\n" + - " \"product\": {\n" + - " \"unit\": \"H87\",\n" + - " \"name\": \"Joghurt Banane\",\n" + - " \"description\": \"\",\n" + - " \"vatpercent\": 7,\n" + - " \"taxCategoryCode\": \"S\"\n" + - " }\n" + - " }\n" + - " ]\n" + - "}\n"; + String base64 = "b25ldHdvdGhyZWU="; + String json = "{\n" + + " \"additionalReferencedDocuments\": [\n" + + " {\n" + + " \"data\": \"" + base64 + "\",\n" + + " \"description\": \"Additional file attachment\",\n" + + " \"filename\": \"text.txt\",\n" + + " \"mimetype\": \"text/plain\",\n" + + " \"relation\": \"Data\"\n" + + " }\n" + + "],\n" + + "\n" + + " \"number\": \"471102\",\n" + + " \"currency\": \"EUR\",\n" + + " \"issueDate\": \"2018-03-04T00:00:00.000+01:00\",\n" + + " \"dueDate\": \"2018-03-04T00:00:00.000+01:00\",\n" + + " \"deliveryDate\": \"2018-03-04T00:00:00.000+01:00\",\n" + + " \"sender\": {\n" + + " \"name\": \"Lieferant GmbH\",\n" + + " \"zip\": \"80333\",\n" + + " \"street\": \"Lieferantenstraße 20\",\n" + + " \"location\": \"München\",\n" + + " \"country\": \"DE\",\n" + + " \"taxID\": \"201/113/40209\",\n" + + " \"vatID\": \"DE123456789\",\n" + + " \"globalID\": \"4000001123452\",\n" + + " \"globalIDScheme\": \"0088\"\n" + + " },\n" + + " \"recipient\": {\n" + + " \"name\": \"Kunden AG Mitte\",\n" + + " \"zip\": \"69876\",\n" + + " \"street\": \"Kundenstraße 15\",\n" + + " \"location\": \"Frankfurt\",\n" + + " \"country\": \"DE\"\n" + + " },\n" + + " \"zfitems\": [\n" + + " {\n" + + " \"price\": 9.9,\n" + + " \"quantity\": 20,\n" + + " \"product\": {\n" + + " \"unit\": \"H87\",\n" + + " \"name\": \"Trennblätter A4\",\n" + + " \"description\": \"\",\n" + + " \"vatpercent\": 19,\n" + + " \"taxCategoryCode\": \"S\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"price\": 5.5,\n" + + " \"quantity\": 50,\n" + + " \"product\": {\n" + + " \"unit\": \"H87\",\n" + + " \"name\": \"Joghurt Banane\",\n" + + " \"description\": \"\",\n" + + " \"vatpercent\": 7,\n" + + " \"taxCategoryCode\": \"S\"\n" + + " }\n" + + " }\n" + + " ]\n" + + "}\n"; - ObjectMapper mapper = new ObjectMapper(); + ObjectMapper mapper = new ObjectMapper(); - try { - Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); - ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); - zf2p.setProfile(Profiles.getByName("XRechnung")); - zf2p.generateXML(newInvoiceFromJSON); - String theXML = new String(zf2p.getXML()); - assertTrue(theXML.contains("20180304")); - assertTrue(theXML.contains(base64)); + try { + Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); + ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); + zf2p.setProfile(Profiles.getByName("XRechnung")); + zf2p.generateXML(newInvoiceFromJSON); + String theXML = new String(zf2p.getXML()); + assertTrue(theXML.contains("20180304")); + assertTrue(theXML.contains(base64)); - } catch (Exception e) { - fail("No exception expected"); - } + } catch (Exception e) { + fail("No exception expected"); + } - } + } - public void testFull300Roundtrip() { - File inputCII = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml"); + public void testFull300Roundtrip() { + File inputCII = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml"); - Invoice i = new Invoice(); - String exText = null; - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); - zii.doIgnoreCalculationErrors(); - try { - zii.fromXML(new String(Files.readAllBytes(inputCII.toPath()), StandardCharsets.UTF_8)); - ObjectMapper mapper = new ObjectMapper(); - zii.extractInto(i); - String json = mapper.writeValueAsString(i); - Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); + Invoice i = new Invoice(); + String exText = null; + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + zii.doIgnoreCalculationErrors(); + try { + zii.fromXML(new String(Files.readAllBytes(inputCII.toPath()), StandardCharsets.UTF_8)); + ObjectMapper mapper = new ObjectMapper(); + zii.extractInto(i); + String json = mapper.writeValueAsString(i); + Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); - assertEquals("Test_EeISI_100", i.getNumber()); - assertEquals(newInvoiceFromJSON.getNumber(), i.getNumber()); + assertEquals("Test_EeISI_100", i.getNumber()); + assertEquals(newInvoiceFromJSON.getNumber(), i.getNumber()); - } catch (IOException e) { - exText = e.getMessage(); - } catch (XPathExpressionException e) { - exText = e.getMessage(); - } catch (ParseException e) { - exText = e.getMessage(); - } - assertNull(exText); + } catch (IOException e) { + exText = e.getMessage(); + } catch (XPathExpressionException e) { + exText = e.getMessage(); + } catch (ParseException e) { + exText = e.getMessage(); + } + assertNull(exText); - } + } - public void testIssuerAssignedIDRoundtrip() { - String occurrenceFrom = "20201001"; - String occurrenceTo = "20201005"; - String contractID = "376zreurzu0983"; + 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); + 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 { + public void testDueDateRoundtrip() throws JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); + ObjectMapper mapper = new ObjectMapper(); - // [{"stringValue":"a","intValue":1,"booleanValue":true}, - // {"stringValue":"bc","intValue":3,"booleanValue":false}] + // [{"stringValue":"a","intValue":1,"booleanValue":true}, + // {"stringValue":"bc","intValue":3,"booleanValue":false}] - Invoice fromJSON = mapper.readValue("{\n" + - " \"number\": \"RE - 228\",\n" + - " \"currency\": \"EUR\",\n" + - " \"issueDate\": \"2024-10-24\",\n" + - " \"dueDate\": \"2024-10-26\",\n" + - " \"deliveryDate\": \"2024-10-25\",\n" + - " \"sender\": {\n" + - " \"name\": \"Amazing Company\",\n" + - " \"zip\": \"10000\",\n" + - " \"street\": \"Straße der Kosmonauten 20\",\n" + - " \"location\": \"Berlin\",\n" + - " \"country\": \"DE\",\n" + - " \"taxID\": \"201/113/40209\",\n" + - " \"vatID\": \"DE123456789\",\n" + - " \"globalID\": \"4000001123452\",\n" + - " \"globalIDScheme\": \"0088\"\n" + - " },\n" + - " \"recipient\": {\n" + - " \"name\": \"Amazing Company\",\n" + - " \"zip\": \"1000\",\n" + - " \"street\": \"Straße der Kosmonauten 10\",\n" + - " \"location\": \"Berlin\",\n" + - " \"taxID\": \"201/113/40209\",\n" + - " \"vatID\": \"DE123456789\",\n" + - " \"country\": \"DE\"\n" + - " },\n" + - " \"zfitems\": [\n" + - " {\n" + - " \"price\": 99.9,\n" + - " \"quantity\": 10,\n" + - " \"product\": {\n" + - " \"unit\": \"H87\",\n" + - " \"name\": \"Amazing Archives\",\n" + - " \"description\": \"123\",\n" + - " \"vatpercent\": \"19\",\n" + - " \"taxCategoryCode\": \"3\"\n" + - " }\n" + - " }\n" + - " ]\n" + - "}\n", Invoice.class); - ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); - zf2p.setProfile(Profiles.getByName("XRechnung")); - zf2p.generateXML(fromJSON); - String theXML = new String(zf2p.getXML()); - assertTrue(theXML.contains("20241026")); + Invoice fromJSON = mapper.readValue("{\n" + + " \"number\": \"RE - 228\",\n" + + " \"currency\": \"EUR\",\n" + + " \"issueDate\": \"2024-10-24\",\n" + + " \"dueDate\": \"2024-10-26\",\n" + + " \"deliveryDate\": \"2024-10-25\",\n" + + " \"sender\": {\n" + + " \"name\": \"Amazing Company\",\n" + + " \"zip\": \"10000\",\n" + + " \"street\": \"Straße der Kosmonauten 20\",\n" + + " \"location\": \"Berlin\",\n" + + " \"country\": \"DE\",\n" + + " \"taxID\": \"201/113/40209\",\n" + + " \"vatID\": \"DE123456789\",\n" + + " \"globalID\": \"4000001123452\",\n" + + " \"globalIDScheme\": \"0088\"\n" + + " },\n" + + " \"recipient\": {\n" + + " \"name\": \"Amazing Company\",\n" + + " \"zip\": \"1000\",\n" + + " \"street\": \"Straße der Kosmonauten 10\",\n" + + " \"location\": \"Berlin\",\n" + + " \"taxID\": \"201/113/40209\",\n" + + " \"vatID\": \"DE123456789\",\n" + + " \"country\": \"DE\"\n" + + " },\n" + + " \"zfitems\": [\n" + + " {\n" + + " \"price\": 99.9,\n" + + " \"quantity\": 10,\n" + + " \"product\": {\n" + + " \"unit\": \"H87\",\n" + + " \"name\": \"Amazing Archives\",\n" + + " \"description\": \"123\",\n" + + " \"vatpercent\": \"19\",\n" + + " \"taxCategoryCode\": \"3\"\n" + + " }\n" + + " }\n" + + " ]\n" + + "}\n", Invoice.class); + ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); + zf2p.setProfile(Profiles.getByName("XRechnung")); + zf2p.generateXML(fromJSON); + String theXML = new String(zf2p.getXML()); + assertTrue(theXML.contains("20241026")); - } + } - public void testDirectDebit() throws JsonProcessingException { + public void testDirectDebit() throws JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); + ObjectMapper mapper = new ObjectMapper(); - // [{"stringValue":"a","intValue":1,"booleanValue":true}, - // {"stringValue":"bc","intValue":3,"booleanValue":false}] + // [{"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); + 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); - } + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/DXTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/DXTest.java index 5683912..913a129 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/DXTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/DXTest.java @@ -1,4 +1,3 @@ org.openrewrite.config.CompositeRecipe - /** ********************************************************************** * * Copyright 2019 Jochen Staerk @@ -23,9 +22,7 @@ import junit.framework.TestSuite; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; -import org.mustangproject.EStandard; -import org.mustangproject.Invoice; -import org.mustangproject.TradeParty; +import org.mustangproject.*; import javax.xml.xpath.XPathExpressionException; import java.io.BufferedWriter; @@ -35,7 +32,7 @@ import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Paths; +import java.nio.file.Path; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -46,324 +43,324 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class DXTest extends MustangReaderTestCase { - final String TARGET_PDF = "./target/testout-DX.pdf"; - final String TARGET_XML = "./target/testout-DX.xml"; + final String TARGET_PDF = "./target/testout-DX.pdf"; + final String TARGET_XML = "./target/testout-DX.xml"; - protected class EdgeProduct implements IZUGFeRDExportableProduct { - private String description, name, unit; + protected class EdgeProduct implements IZUGFeRDExportableProduct { + private String description, name, unit; - public EdgeProduct(String description, String name, String unit) { - super(); - this.description = description; - this.name = name; - this.unit = unit; - } + public EdgeProduct(String description, String name, String unit) { + super(); + this.description = description; + this.name = name; + this.unit = unit; + } - @Override - public String getDescription() { - return description; - } + @Override + public String getDescription() { + return description; + } - public void setDescription(String description) { - this.description = description; - } + public void setDescription(String description) { + this.description = description; + } - @Override - public String getName() { - return name; - } + @Override + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - @Override - public String getUnit() { - return unit; - } + @Override + public String getUnit() { + return unit; + } - public void setUnit(String unit) { - this.unit = unit; - } + public void setUnit(String unit) { + this.unit = unit; + } - @Override - public BigDecimal getVATPercent() { - return BigDecimal.ZERO; - } + @Override + public BigDecimal getVATPercent() { + return BigDecimal.ZERO; + } - @Override - public boolean isIntraCommunitySupply() { - return true; // simulate intra community supply - } - } + @Override + public boolean isIntraCommunitySupply() { + return true; // simulate intra community supply + } + } - protected class DebitPayment implements IZUGFeRDTradeSettlementDebit { + protected class DebitPayment implements IZUGFeRDTradeSettlementDebit { - @Override - public String getIBAN() { - return "DE540815"; - } + @Override + public String getIBAN() { + return "DE540815"; + } - @Override - public String getMandate() { - return "DE99XX12345"; - } + @Override + public String getMandate() { + return "DE99XX12345"; + } - } + } - @Override - public IZUGFeRDTradeSettlement[] getTradeSettlement() { - IZUGFeRDTradeSettlement[] payments = new DebitPayment[1]; - payments[0] = new DebitPayment(); - return payments; - } + @Override + public IZUGFeRDTradeSettlement[] getTradeSettlement() { + IZUGFeRDTradeSettlement[] payments = new DebitPayment[1]; + payments[0] = new DebitPayment(); + return payments; + } - @Override - public Date getDeliveryDate() { - return new GregorianCalendar(2017, Calendar.MAY, 7).getTime(); - } + @Override + public Date getDeliveryDate() { + return new GregorianCalendar(2017, Calendar.MAY, 7).getTime(); + } - @Override - public Date getDueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); - } + @Override + public Date getDueDate() { + return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); + } - @Override - public Date getIssueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); - } + @Override + public Date getIssueDate() { + return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); + } - @Override - public String getNumber() { - return "RE-20170509/505"; - } + @Override + public String getNumber() { + return "RE-20170509/505"; + } - @Override - public String getOwnCountry() { - return "DE"; - } + @Override + public String getOwnCountry() { + return "DE"; + } - @Override - public String getOwnLocation() { - return "Stadthausen"; - } + @Override + public String getOwnLocation() { + return "Stadthausen"; + } - @Override - public String getOwnOrganisationName() { - return "Bei Spiel GmbH"; - } + @Override + public String getOwnOrganisationName() { + return "Bei Spiel GmbH"; + } - @Override - public String getOwnStreet() { - return "Ecke 12"; - } + @Override + public String getOwnStreet() { + return "Ecke 12"; + } - @Override - public IZUGFeRDExportableTradeParty getSender() { - return new SenderTradeParty(); - } + @Override + public IZUGFeRDExportableTradeParty getSender() { + return new SenderTradeParty(); + } - @Override - public String getOwnTaxID() { - return "22/815/0815/4"; - } + @Override + public String getOwnTaxID() { + return "22/815/0815/4"; + } - @Override - public String getOwnVATID() { - return "DE136695976"; - } + @Override + public String getOwnVATID() { + return "DE136695976"; + } - @Override - public String getOwnZIP() { - return "12345"; - } + @Override + public String getOwnZIP() { + return "12345"; + } - @Override - public IZUGFeRDExportableTradeParty getRecipient() { - return new RecipientTradeParty(); - } + @Override + public IZUGFeRDExportableTradeParty getRecipient() { + return new RecipientTradeParty(); + } - @Override - public IZUGFeRDExportableTradeParty getDeliveryAddress() { - return new RecipientTradeParty(); - } + @Override + public IZUGFeRDExportableTradeParty getDeliveryAddress() { + return new RecipientTradeParty(); + } - @Override - public String getOwnOrganisationFullPlaintextInfo() { - return null; - } + @Override + public String getOwnOrganisationFullPlaintextInfo() { + return null; + } - @Override - public String getCurrency() { - return "USD"; - } + @Override + public String getCurrency() { + return "USD"; + } - @Override - public IZUGFeRDExportableItem[] getZFItems() { - Item[] allItems = new Item[3]; - EdgeProduct designProduct = new EdgeProduct("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", - "HUR"); - EdgeProduct balloonProduct = new EdgeProduct("", "Bestellerweiterung für E&F Umbau", "C62");// test for issue - // 103 - EdgeProduct airProduct = new EdgeProduct("", "Heiße Luft pro Liter", "LTR"); + @Override + public IZUGFeRDExportableItem[] getZFItems() { + Item[] allItems = new Item[3]; + EdgeProduct designProduct = new EdgeProduct("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", + "HUR"); + EdgeProduct balloonProduct = new EdgeProduct("", "Bestellerweiterung für E&F Umbau", "C62");// test for issue + // 103 + EdgeProduct airProduct = new EdgeProduct("", "Heiße Luft pro Liter", "LTR"); - Item design = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); - design.setAddReference("1825"); - allItems[0] = design; - allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); - allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); - return allItems; - } + Item design = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); + design.setAddReference("1825"); + allItems[0] = design; + allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); + allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); + return allItems; + } - @Override - public String getPaymentTermDescription() { - SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); - } + @Override + public String getPaymentTermDescription() { + SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); + return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); + } - @Override - public IZUGFeRDAllowanceCharge[] getZFAllowances() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFAllowances() { + return null; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFCharges() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFCharges() { + return null; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { + return null; + } - @Override - public String getReferenceNumber() { - return "AB321"; - } + @Override + public String getReferenceNumber() { + return "AB321"; + } - /** - * Create the test case - * - * @param testName name of the test case - */ - public DXTest(String testName) { - super(testName); - } + /** + * Create the test case + * + * @param testName name of the test case + */ + public DXTest(String testName) { + super(testName); + } - /** - * @return the suite of tests being tested - */ - public static Test suite() { - return new TestSuite(DXTest.class); - } + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(DXTest.class); + } - // //////// TESTS - // ////////////////////////////////////////////////////////////////////////////////////////// + // //////// TESTS + // ////////////////////////////////////////////////////////////////////////////////////////// - /** - * The exporter test bases on @{code - * ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds - * metadata, writes to @{code ./target/testout-*} and then imports to check the - * values. - */ - public void testDXExport() { + /** + * The exporter test bases on @{code + * ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds + * metadata, writes to @{code ./target/testout-*} and then imports to check the + * values. + */ + public void testDXExport() { - // the writing part + // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); DXExporterFromA1 oe = new DXExporterFromA1().setProducer("My Application") - .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(1).ignorePDFAErrors() - .load(SOURCE_PDF)) { - oe.setTransaction(this); - String theXML = new String(oe.getProvider().getXML(), StandardCharsets.UTF_8); - assertTrue(theXML.contains("220")); - assertTrue(zi.getUTF8().contains("")); - assertFalse(zi.getUTF8().contains("EUR")); + assertTrue(zi.getUTF8().contains("220")); + assertTrue(zi.getUTF8().contains("")); + assertFalse(zi.getUTF8().contains("EUR")); - assertEquals(zi.getLineItemList().size(),3); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF); - try { - Invoice i = zii.extractInvoice(); + assertEquals(zi.getLineItemList().size(), 3); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF); + try { + Invoice i = zii.extractInvoice(); - assertEquals(new BigDecimal("400.0000"), i.getZFItems()[1].getQuantity()); - /* getting the Quantity is more difficult than usual because in OrderX it's - called requestedQuantity, not BilledQuantity - */ + assertEquals(new BigDecimal("400.0000"), i.getZFItems()[1].getQuantity()); + /* getting the Quantity is more difficult than usual because in OrderX it's + called requestedQuantity, not BilledQuantity + */ - } catch (XPathExpressionException e) { - fail("XPathExpressionException should not be raised in testEdgeExport"); - } catch (ParseException e) { - fail("ParseException should not be raised in testEdgeExport"); - /* a parseException would also be fired if the calculated grand total does not - match the read grand total */ - } + } catch (XPathExpressionException e) { + fail("XPathExpressionException should not be raised in testEdgeExport"); + } catch (ParseException e) { + fail("ParseException should not be raised in testEdgeExport"); + /* a parseException would also be fired if the calculated grand total does not + match the read grand total */ + } - } + } - public void testDAGeneration() { + public void testDAGeneration() { - // the writing part - TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); - Invoice i = createDA(recipient); + // the writing part + TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); + Invoice i = createDA(recipient); - DAPullProvider zf2p = new DAPullProvider(); - zf2p.setProfile(Profiles.getByName(EStandard.despatchadvice,"Pilot",1)); - zf2p.generateXML(i); - String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8); - try { - BufferedWriter writer = new BufferedWriter(new FileWriter(TARGET_XML)); - writer.write(theXML); - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } - assertTrue(theXML.contains(" @@ -38,51 +37,52 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class FXTest extends TestCase { - final String TARGET_XML = "./target/testout-FX.xml"; - public void testFXExport() { + final String TARGET_XML = "./target/testout-FX.xml"; - // test creating factur-x invoices to french authorities, i.e. with SIRET number - // the writing part - TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); - String siret="0815"; - String sirenTypeCode="0002"; - recipient.setLegalOrganisation(new LegalOrganisation(siret,sirenTypeCode)); - Invoice i = createInvoice(recipient); + public void testFXExport() { - ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); - zf2p.setProfile(Profiles.getByName("EN16931")); - zf2p.generateXML(i); - String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8); - assertTrue(theXML.contains("\n" + - "\n" + - "\n" + - "false\n" + - "\n" + - "urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:extended\n" + - "\n" + - "\n" + - "\n" + - "RE-20171118/506\n" + - "RECHNUNG\n" + - "380\n" + - "20171118\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "1\n" + - "\n" + - "\n" + - "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "160.0000\n" + - "1.0000\n" + - "\n" + - "\n" + - "160.0000\n" + - "1.0000\n" + - "\n" + - "\n" + - "\n" + - "1.0000\n" + - "\n" + - "\n" + - "\n" + - "VAT\n" + - "S\n" + - "7.00\n" + - "\n" + - "\n" + - "160.00\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "2\n" + - "\n" + - "\n" + - "Luftballon: Bunt, ca. 500ml\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "0.7900\n" + - "1.0000\n" + - "\n" + - "\n" + - "0.7900\n" + - "1.0000\n" + - "\n" + - "\n" + - "\n" + - "400.0000\n" + - "\n" + - "\n" + - "\n" + - "VAT\n" + - "S\n" + - "19.00\n" + - "\n" + - "\n" + - "316.00\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "3\n" + - "\n" + - "\n" + - "Heiße Luft pro Liter\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "0.1000\n" + - "1.0000\n" + - "\n" + - "\n" + - "0.1000\n" + - "1.0000\n" + - "\n" + - "\n" + - "\n" + - "200.0000\n" + - "\n" + - "\n" + - "\n" + - "VAT\n" + - "S\n" + - "19.00\n" + - "\n" + - "\n" + - "20.00\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "Bei Spiel GmbH\n" + - "\n" + - "12345\n" + - "Ecke 12\n" + - "Stadthausen\n" + - "DE\n" + - "\n" + - "\n" + - "22/815/0815/4\n" + - "\n" + - "\n" + - "DE136695976\n" + - "\n" + - "\n" + - "\n" + - "Theodor Est\n" + - "\n" + - "88802\n" + - "Bahnstr. 42\n" + - "Spielkreis\n" + - "DE\n" + - "\n" + - "\n" + - "DE999999999\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "20171117\n" + - "\n" + - "\n" + - "\n" + - "RE-20171118/506\n" + - "EUR\n" + - "\n" + - "42\n" + - "Überweisung\n" + - "\n" + - "DE88 2008 0000 0970 3757 00\n" + - "44421800\n" + - "\n" + - "\n" + - "COBADEFFXXX\n" + - "41441604\n" + - "Commerzbank\n" + - "\n" + - "\n" + - "\n" + - "11.20\n" + - "VAT\n" + - "160.00\n" + - "S\n" + - "7.00\n" + - "\n" + - "\n" + - "63.84\n" + - "VAT\n" + - "336.00\n" + - "S\n" + - "19.00\n" + - "\n" + - "\n" + - "Zahlbar ohne Abzug bis 09.12.2017\n" + - "20171209\n" + - "\n" + - "\n" + - "496.00\n" + - "0.00\n" + - "0.00\n" + - "496.00\n" + - "75.04\n" + - "571.04\n" + - "571.04\n" + - "\n" + - "\n" + - "\n" + - ""; - zea1.setXML(ownZUGFeRDXML.getBytes(StandardCharsets.UTF_8)); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - zea1.disableAutoClose(true); - zea1.export(TARGET_PDF); - zea1.export(baos); - zea1.close(); - String pdfContent = baos.toString(StandardCharsets.UTF_8); - assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); - assertFalse(pdfContent.indexOf("EN 16931") == -1); + final byte[] UTF8ByteOrderMark = new byte[]{(byte) 0xef, (byte) 0xbb, (byte) 0xbf}; + /* we have much more information than just in the basic profile (comfort or extended) but it's perfectly valid to provide more information, just not less. + * test the export with bom (which is valid) because this will also test the import (which also needs to work and needs to be tested) + * */ + String ownZUGFeRDXML = new String(UTF8ByteOrderMark, StandardCharsets.UTF_8) + "\n" + + "\n" + + "\n" + + "false\n" + + "\n" + + "urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:extended\n" + + "\n" + + "\n" + + "\n" + + "RE-20171118/506\n" + + "RECHNUNG\n" + + "380\n" + + "20171118\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "1\n" + + "\n" + + "\n" + + "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "160.0000\n" + + "1.0000\n" + + "\n" + + "\n" + + "160.0000\n" + + "1.0000\n" + + "\n" + + "\n" + + "\n" + + "1.0000\n" + + "\n" + + "\n" + + "\n" + + "VAT\n" + + "S\n" + + "7.00\n" + + "\n" + + "\n" + + "160.00\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "2\n" + + "\n" + + "\n" + + "Luftballon: Bunt, ca. 500ml\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "0.7900\n" + + "1.0000\n" + + "\n" + + "\n" + + "0.7900\n" + + "1.0000\n" + + "\n" + + "\n" + + "\n" + + "400.0000\n" + + "\n" + + "\n" + + "\n" + + "VAT\n" + + "S\n" + + "19.00\n" + + "\n" + + "\n" + + "316.00\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "3\n" + + "\n" + + "\n" + + "Heiße Luft pro Liter\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "0.1000\n" + + "1.0000\n" + + "\n" + + "\n" + + "0.1000\n" + + "1.0000\n" + + "\n" + + "\n" + + "\n" + + "200.0000\n" + + "\n" + + "\n" + + "\n" + + "VAT\n" + + "S\n" + + "19.00\n" + + "\n" + + "\n" + + "20.00\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "Bei Spiel GmbH\n" + + "\n" + + "12345\n" + + "Ecke 12\n" + + "Stadthausen\n" + + "DE\n" + + "\n" + + "\n" + + "22/815/0815/4\n" + + "\n" + + "\n" + + "DE136695976\n" + + "\n" + + "\n" + + "\n" + + "Theodor Est\n" + + "\n" + + "88802\n" + + "Bahnstr. 42\n" + + "Spielkreis\n" + + "DE\n" + + "\n" + + "\n" + + "DE999999999\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "20171117\n" + + "\n" + + "\n" + + "\n" + + "RE-20171118/506\n" + + "EUR\n" + + "\n" + + "42\n" + + "Überweisung\n" + + "\n" + + "DE88 2008 0000 0970 3757 00\n" + + "44421800\n" + + "\n" + + "\n" + + "COBADEFFXXX\n" + + "41441604\n" + + "Commerzbank\n" + + "\n" + + "\n" + + "\n" + + "11.20\n" + + "VAT\n" + + "160.00\n" + + "S\n" + + "7.00\n" + + "\n" + + "\n" + + "63.84\n" + + "VAT\n" + + "336.00\n" + + "S\n" + + "19.00\n" + + "\n" + + "\n" + + "Zahlbar ohne Abzug bis 09.12.2017\n" + + "20171209\n" + + "\n" + + "\n" + + "496.00\n" + + "0.00\n" + + "0.00\n" + + "496.00\n" + + "75.04\n" + + "571.04\n" + + "571.04\n" + + "\n" + + "\n" + + "\n" + + ""; + zea1.setXML(ownZUGFeRDXML.getBytes(StandardCharsets.UTF_8)); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + zea1.disableAutoClose(true); + zea1.export(TARGET_PDF); + zea1.export(baos); + zea1.close(); + String pdfContent = baos.toString(StandardCharsets.UTF_8); + assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); + assertFalse(pdfContent.indexOf("EN 16931") == -1); - } catch (IOException e) { - e.printStackTrace(); - } + } catch (IOException e) { + e.printStackTrace(); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getBIC(), "COBADEFFXXX"); - assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); - assertEquals(zi.getHolder(), "Bei Spiel GmbH"); - assertEquals(zi.getForeignReference(), "RE-20171118/506"); - } + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), "COBADEFFXXX"); + assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); + assertEquals(zi.getHolder(), "Bei Spiel GmbH"); + assertEquals(zi.getForeignReference(), "RE-20171118/506"); + } - /** - * The exporter test bases on @{code - * ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds - * metadata, writes to @{code ./target/testout-*} and then imports to check the - * values. It would not make sense to have it run before the less complex - * importer test (which is probably redundant). As only Name Ascending is - * supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export - */ - public void testCustomZF1Export() { + /** + * The exporter test bases on @{code + * ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds + * metadata, writes to @{code ./target/testout-*} and then imports to check the + * values. It would not make sense to have it run before the less complex + * importer test (which is probably redundant). As only Name Ascending is + * supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export + */ + public void testCustomZF1Export() { - final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505custom.pdf"; - // the writing part + final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505custom.pdf"; + // the writing part - try { - InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); + try { + InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); - IZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1() - .setProducer("My Application") - .setCreator("Test") - .setZUGFeRDVersion(1) - .setProfile(Profiles.getByName("BASIC",1)) - .load(SOURCE_PDF); - /* we have much more information than just in the basic profile (comfort or extended) but it's perfectly valid to provide more information, just not less. */ - String ownZUGFeRDXML = "\n" - + "\n" + "\n" - + "false\n" + "\n" - + "\n" + "\n" - + "urn:ferd:CrossIndustryDocument:invoice:1p0:basic\n" + "\n" - + "\n" - + "\n" + "\n" - + "RE-20170509/505\n" + "RECHNUNG\n" - + "380\n" + "\n" - + "20170509\n" + "\n" - + "\n" + "\n" - + "\n" + "\n" - + "Bei Spiel GmbH\n" + "\n" - + "12345\n" + "Ecke 12\n" - + "Stadthausen\n" + "DE\n" - + "\n" + "\n" - + "22/815/0815/4\n" + "\n" - + "\n" + "DE136695976\n" - + "\n" + "\n" + "\n" - + "Theodor Est\n" + "\n" - + "88802\n" + "Bahnstr. 42\n" - + "Spielkreis\n" + "DE\n" - + "\n" + "\n" - + "DE999999999\n" + "\n" - + "\n" + "\n" - + "\n" + "\n" - + "\n" - + "20170507\n" - + "\n" + "\n" - + "\n" + "\n" - + "RE-20170509/505\n" - + "EUR\n" - + "\n" + "42\n" - + "Überweisung\n" + "\n" - + "DE88 2008 0000 0970 3757 00\n" - + "44421800\n" - + "\n" - + "\n" - + "COBADEFFXXX\n" - + "41441604\n" - + "Commerzbank\n" - + "\n" - + "\n" + "\n" - + "11.20\n" - + "VAT\n" - + "160.00\n" - + "S\n" - + "7.00\n" + "\n" - + "\n" - + "63.84\n" - + "VAT\n" - + "336.00\n" - + "S\n" - + "19.00\n" + "\n" - + "\n" - + "Zahlbar ohne Abzug bis zum 30.05.2017\n" - + "\n" + "20170530\n" - + "\n" + "\n" - + "\n" - + "496.00\n" - + "0.00\n" - + "0.00\n" - + "496.00\n" - + "75.04\n" - + "571.04\n" - + "571.04\n" - + "\n" - + "\n" + "\n" - + "\n" + "1\n" - + "\n" + "\n" - + "\n" - + "160.0000\n" - + "1.0000\n" - + "\n" + "\n" - + "160.0000\n" - + "1.0000\n" - + "\n" + "\n" - + "\n" - + "1.0000\n" - + "\n" + "\n" - + "\n" + "VAT\n" - + "S\n" - + "7.00\n" + "\n" - + "\n" - + "160.00\n" - + "\n" - + "\n" + "\n" + "\n" - + "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung\n" + "\n" - + "\n" + "\n" - + "\n" + "\n" - + "\n" + "2\n" - + "\n" + "\n" - + "\n" - + "0.7900\n" - + "1.0000\n" - + "\n" + "\n" - + "0.7900\n" - + "1.0000\n" - + "\n" + "\n" - + "\n" - + "400.0000\n" - + "\n" + "\n" - + "\n" + "VAT\n" - + "S\n" - + "19.00\n" + "\n" - + "\n" - + "316.00\n" - + "\n" - + "\n" + "\n" - + "Luftballon: Bunt, ca. 500ml\n" + "\n" - + "\n" + "\n" - + "\n" + "\n" - + "3\n" + "\n" - + "\n" + "\n" - + "0.1000\n" - + "1.0000\n" - + "\n" + "\n" - + "0.1000\n" - + "1.0000\n" - + "\n" + "\n" - + "\n" - + "200.0000\n" - + "\n" + "\n" - + "\n" + "VAT\n" - + "S\n" - + "19.00\n" + "\n" - + "\n" - + "20.00\n" - + "\n" - + "\n" + "\n" - + "Heiße Luft pro Liter\n" + "\n" - + "\n" + "\n" - + "\n" + ""; - zea1.setXML(ownZUGFeRDXML.getBytes(StandardCharsets.UTF_8)); + IZUGFeRDExporter zea1 = new ZUGFeRDExporterFromA1() + .setProducer("My Application") + .setCreator("Test") + .setZUGFeRDVersion(1) + .setProfile(Profiles.getByName("BASIC", 1)) + .load(SOURCE_PDF); + /* we have much more information than just in the basic profile (comfort or extended) but it's perfectly valid to provide more information, just not less. */ + String ownZUGFeRDXML = "\n" + + "\n" + "\n" + + "false\n" + "\n" + + "\n" + "\n" + + "urn:ferd:CrossIndustryDocument:invoice:1p0:basic\n" + "\n" + + "\n" + + "\n" + "\n" + + "RE-20170509/505\n" + "RECHNUNG\n" + + "380\n" + "\n" + + "20170509\n" + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "Bei Spiel GmbH\n" + "\n" + + "12345\n" + "Ecke 12\n" + + "Stadthausen\n" + "DE\n" + + "\n" + "\n" + + "22/815/0815/4\n" + "\n" + + "\n" + "DE136695976\n" + + "\n" + "\n" + "\n" + + "Theodor Est\n" + "\n" + + "88802\n" + "Bahnstr. 42\n" + + "Spielkreis\n" + "DE\n" + + "\n" + "\n" + + "DE999999999\n" + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + + "20170507\n" + + "\n" + "\n" + + "\n" + "\n" + + "RE-20170509/505\n" + + "EUR\n" + + "\n" + "42\n" + + "Überweisung\n" + "\n" + + "DE88 2008 0000 0970 3757 00\n" + + "44421800\n" + + "\n" + + "\n" + + "COBADEFFXXX\n" + + "41441604\n" + + "Commerzbank\n" + + "\n" + + "\n" + "\n" + + "11.20\n" + + "VAT\n" + + "160.00\n" + + "S\n" + + "7.00\n" + "\n" + + "\n" + + "63.84\n" + + "VAT\n" + + "336.00\n" + + "S\n" + + "19.00\n" + "\n" + + "\n" + + "Zahlbar ohne Abzug bis zum 30.05.2017\n" + + "\n" + "20170530\n" + + "\n" + "\n" + + "\n" + + "496.00\n" + + "0.00\n" + + "0.00\n" + + "496.00\n" + + "75.04\n" + + "571.04\n" + + "571.04\n" + + "\n" + + "\n" + "\n" + + "\n" + "1\n" + + "\n" + "\n" + + "\n" + + "160.0000\n" + + "1.0000\n" + + "\n" + "\n" + + "160.0000\n" + + "1.0000\n" + + "\n" + "\n" + + "\n" + + "1.0000\n" + + "\n" + "\n" + + "\n" + "VAT\n" + + "S\n" + + "7.00\n" + "\n" + + "\n" + + "160.00\n" + + "\n" + + "\n" + "\n" + "\n" + + "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung\n" + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "\n" + "2\n" + + "\n" + "\n" + + "\n" + + "0.7900\n" + + "1.0000\n" + + "\n" + "\n" + + "0.7900\n" + + "1.0000\n" + + "\n" + "\n" + + "\n" + + "400.0000\n" + + "\n" + "\n" + + "\n" + "VAT\n" + + "S\n" + + "19.00\n" + "\n" + + "\n" + + "316.00\n" + + "\n" + + "\n" + "\n" + + "Luftballon: Bunt, ca. 500ml\n" + "\n" + + "\n" + "\n" + + "\n" + "\n" + + "3\n" + "\n" + + "\n" + "\n" + + "0.1000\n" + + "1.0000\n" + + "\n" + "\n" + + "0.1000\n" + + "1.0000\n" + + "\n" + "\n" + + "\n" + + "200.0000\n" + + "\n" + "\n" + + "\n" + "VAT\n" + + "S\n" + + "19.00\n" + "\n" + + "\n" + + "20.00\n" + + "\n" + + "\n" + "\n" + + "Heiße Luft pro Liter\n" + "\n" + + "\n" + "\n" + + "\n" + ""; + zea1.setXML(ownZUGFeRDXML.getBytes(StandardCharsets.UTF_8)); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - zea1.disableAutoClose(true); - zea1.export(TARGET_PDF); - zea1.export(baos); - zea1.close(); - String pdfContent = baos.toString(StandardCharsets.UTF_8); - assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); - assertFalse(pdfContent.indexOf("BASIC") == -1); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + zea1.disableAutoClose(true); + zea1.export(TARGET_PDF); + zea1.export(baos); + zea1.close(); + String pdfContent = baos.toString(StandardCharsets.UTF_8); + assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); + assertFalse(pdfContent.indexOf("BASIC") == -1); - } catch (IOException e) { - e.printStackTrace(); - } + } catch (IOException e) { + e.printStackTrace(); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getBIC(), "COBADEFFXXX"); - assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); - assertEquals(zi.getHolder(), "Bei Spiel GmbH"); - assertEquals(zi.getForeignReference(), "RE-20170509/505"); - } + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), "COBADEFFXXX"); + assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); + assertEquals(zi.getHolder(), "Bei Spiel GmbH"); + assertEquals(zi.getForeignReference(), "RE-20170509/505"); + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java index 28dd059..cdb86f2 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java @@ -20,7 +20,6 @@ org.openrewrite.config.CompositeRecipe import junit.framework.Test; import junit.framework.TestSuite; - import org.apache.pdfbox.Loader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.common.PDMetadata; @@ -43,250 +42,250 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class MustangReaderWriterEdgeTest extends MustangReaderTestCase { - protected class EasyRecipientTradeParty extends RecipientTradeParty { - // Not testing extended profile here, lineThree not possible - @Override - public String getAdditionalAddressExtension() { - return null; - } - } + protected class EasyRecipientTradeParty extends RecipientTradeParty { + // Not testing extended profile here, lineThree not possible + @Override + public String getAdditionalAddressExtension() { + return null; + } + } - @Override - public Date getDeliveryDate() { - return new GregorianCalendar(2017, Calendar.MAY, 7).getTime(); - } + @Override + public Date getDeliveryDate() { + return new GregorianCalendar(2017, Calendar.MAY, 7).getTime(); + } - @Override - public Date getDueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); - } + @Override + public Date getDueDate() { + return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); + } - @Override - public Date getIssueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); - } + @Override + public Date getIssueDate() { + return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); + } - @Override - public String getNumber() { - return "RE-20170509/505"; - } + @Override + public String getNumber() { + return "RE-20170509/505"; + } - @Override - public String getOwnCountry() { - return "DE"; - } + @Override + public String getOwnCountry() { + return "DE"; + } - @Override - public String getOwnLocation() { - return "Stadthausen"; - } + @Override + public String getOwnLocation() { + return "Stadthausen"; + } - @Override - public String getOwnOrganisationName() { - return "Bei Spiel GmbH"; - } + @Override + public String getOwnOrganisationName() { + return "Bei Spiel GmbH"; + } - @Override - public String getOwnStreet() { - return "Ecke 12"; - } + @Override + public String getOwnStreet() { + return "Ecke 12"; + } - @Override - public IZUGFeRDExportableTradeParty getSender() { - return new SenderTradeParty(); - - } + @Override + public IZUGFeRDExportableTradeParty getSender() { + return new SenderTradeParty(); - @Override - public String getOwnTaxID() { - return "22/815/0815/4"; - } + } - @Override - public String getOwnVATID() { - return "DE136695976"; - } + @Override + public String getOwnTaxID() { + return "22/815/0815/4"; + } - @Override - public String getOwnZIP() { - return "12345"; - } + @Override + public String getOwnVATID() { + return "DE136695976"; + } - @Override - public IZUGFeRDExportableTradeParty getRecipient() { - return new EasyRecipientTradeParty(); - } + @Override + public String getOwnZIP() { + return "12345"; + } - @Override - public String getOwnOrganisationFullPlaintextInfo() { - return null; - } + @Override + public IZUGFeRDExportableTradeParty getRecipient() { + return new EasyRecipientTradeParty(); + } - @Override - public String getCurrency() { - return "EUR"; - } + @Override + public String getOwnOrganisationFullPlaintextInfo() { + return null; + } - @Override - public IZUGFeRDExportableItem[] getZFItems() { - Item[] allItems = new Item[3]; - Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", new BigDecimal("7.000000")); - Product balloonProduct = new Product("", "Luftballon: Bunt, ca. 500ml", "C62", new BigDecimal("19.000000")); - Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000")); + @Override + public String getCurrency() { + return "EUR"; + } - allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); - allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); - allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); - return allItems; - } + @Override + public IZUGFeRDExportableItem[] getZFItems() { + Item[] allItems = new Item[3]; + Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", new BigDecimal("7.000000")); + Product balloonProduct = new Product("", "Luftballon: Bunt, ca. 500ml", "C62", new BigDecimal("19.000000")); + Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000")); - @Override - public String getPaymentTermDescription() { - SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); - } + allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); + allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); + allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); + return allItems; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFAllowances() { - return null; - } + @Override + public String getPaymentTermDescription() { + SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); + return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); + } - @Override - public IZUGFeRDAllowanceCharge[] getZFCharges() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFAllowances() { + return null; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFCharges() { + return null; + } - @Override - public String getReferenceNumber() { - return "AB321"; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { + return null; + } + + @Override + public String getReferenceNumber() { + return "AB321"; + } - /** - * Create the test case - * - * @param testName name of the test case - */ - public MustangReaderWriterEdgeTest(String testName) { - super(testName); - } + /** + * Create the test case + * + * @param testName name of the test case + */ + public MustangReaderWriterEdgeTest(String testName) { + super(testName); + } - /** - * @return the suite of tests being tested - */ - public static Test suite() { - return new TestSuite(MustangReaderWriterEdgeTest.class); - } + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(MustangReaderWriterEdgeTest.class); + } - // //////// TESTS ////////////////////////////////////////////////////////////////////////////////////////// + // //////// TESTS ////////////////////////////////////////////////////////////////////////////////////////// - /** - * The importer test imports from ./src/test/MustangGnuaccountingBeispielRE-20170509_505.pdf to check the values. - * As only Name Ascending is supported for Test Unit sequence, I renamed the this test-A-Import to run before - * testZExport - */ + /** + * The importer test imports from ./src/test/MustangGnuaccountingBeispielRE-20170509_505.pdf to check the values. + * As only Name Ascending is supported for Test Unit sequence, I renamed the this test-A-Import to run before + * testZExport + */ - public void testAImport() { - InputStream inputStream = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf"); - ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); + public void testAImport() { + InputStream inputStream = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505.pdf"); + ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getBIC(), "COBADEFFXXX"); - assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getDueDate(), "20170530"); - assertEquals(zi.getForeignReference(), getNumber()); - assertEquals(zi.getDocumentCode(), "380"); + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), "COBADEFFXXX"); + assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getDueDate(), "20170530"); + assertEquals(zi.getForeignReference(), getNumber()); + assertEquals(zi.getDocumentCode(), "380"); - } + } - /** - * The exporter test bases on @{code ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds metadata, - * writes to @{code ./target/testout-*} and then imports to check the values. - * It would not make sense to have it run before the less complex importer test (which is probably redundant). - * As only Name Ascending is supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export - */ - public void testEdgeExport() { + /** + * The exporter test bases on @{code ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds metadata, + * writes to @{code ./target/testout-*} and then imports to check the values. + * It would not make sense to have it run before the less complex importer test (which is probably redundant). + * As only Name Ascending is supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export + */ + public void testEdgeExport() { - final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505newEdge.pdf"; - final String SOURCE_PDF = "/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"; + final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505newEdge.pdf"; + final String SOURCE_PDF = "/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"; - // the writing part - setupPdfUnderTest(SOURCE_PDF, TARGET_PDF); + // the writing part + setupPdfUnderTest(SOURCE_PDF, TARGET_PDF); - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); - // Reading ZUGFeRD - assertEquals("571.04", zi.getAmount()); - assertEquals("COBADEFFXXX", zi.getBIC()); - assertEquals("DE88 2008 0000 0970 3757 00", zi.getIBAN()); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getForeignReference(), getNumber()); - try { - assertEquals(zi.getVersion(), 1); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + // Reading ZUGFeRD + assertEquals("571.04", zi.getAmount()); + assertEquals("COBADEFFXXX", zi.getBIC()); + assertEquals("DE88 2008 0000 0970 3757 00", zi.getIBAN()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); + try { + assertEquals(zi.getVersion(), 1); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } - } + } - /** - * This test is based on #testEdgeExport but test only that the PDFIdentificationSchema is present and identifies - * the pdf as PDF/A-3 conformant. - */ - public void testEdgeExportIsPDFA3() throws Exception { + /** + * This test is based on #testEdgeExport but test only that the PDFIdentificationSchema is present and identifies + * the pdf as PDF/A-3 conformant. + */ + public void testEdgeExportIsPDFA3() throws Exception { - final String SOURCE_PDF = "/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"; - final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505newEdge.pdf"; + final String SOURCE_PDF = "/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"; + final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505newEdge.pdf"; - // the writing part - setupPdfUnderTest(SOURCE_PDF, TARGET_PDF); + // the writing part + setupPdfUnderTest(SOURCE_PDF, TARGET_PDF); - // now check the contents - PDDocument doc = Loader.loadPDF(new File(TARGET_PDF)); - PDMetadata meta = doc.getDocumentCatalog().getMetadata(); - assertNotNull("The pdf must contain XMPMetadata", meta); + // now check the contents + PDDocument doc = Loader.loadPDF(new File(TARGET_PDF)); + PDMetadata meta = doc.getDocumentCatalog().getMetadata(); + assertNotNull("The pdf must contain XMPMetadata", meta); - byte[] xmpBytes = meta.toByteArray(); - assertNotNull("The xmp metadata stream must not be null", xmpBytes); + byte[] xmpBytes = meta.toByteArray(); + assertNotNull("The xmp metadata stream must not be null", xmpBytes); - DomXmpParser xmpParser = new DomXmpParser(); - XMPMetadata xmp = xmpParser.parse(xmpBytes); + DomXmpParser xmpParser = new DomXmpParser(); + XMPMetadata xmp = xmpParser.parse(xmpBytes); - PDFAIdentificationSchema pdfai = xmp.getPDFAIdentificationSchema(); - assertNotNull("The pdf must contain a PDFIdentificationSchema", pdfai); + PDFAIdentificationSchema pdfai = xmp.getPDFAIdentificationSchema(); + assertNotNull("The pdf must contain a PDFIdentificationSchema", pdfai); - assertTrue("The PDF/A conformance must be A, B or U", - Arrays.asList("A", "B", "U", "a", "b", "u").contains(pdfai.getConformance())); + assertTrue("The PDF/A conformance must be A, B or U", + Arrays.asList("A", "B", "U", "a", "b", "u").contains(pdfai.getConformance())); - assertEquals("The PDF/A must be 3", (Integer) 3, pdfai.getPart()); - } + assertEquals("The PDF/A must be 3", (Integer) 3, pdfai.getPart()); + } - private void setupPdfUnderTest(String sourcePath, String targetPath) { - try (InputStream inputStream = this.getClass().getResourceAsStream(sourcePath)) { - ZUGFeRDExporterFromA3 ze = new ZUGFeRDExporterFromA3() - .setProducer("My Application") - .setCreator(System.getProperty("user.name")) - .setZUGFeRDVersion(1) - .load(inputStream); - ze.setTransaction(this); - String theXML = new String(ze.getProvider().getXML(), StandardCharsets.UTF_8); - assertTrue(theXML.contains("\n" + - " \n" + - " \n" + - " \n" + - " uuid:6776DD95-DAF6-768E-DAE6-2697750D95C5\n" + - " uuid:47380404-5938-FE2C-8F0B-B505DCE43BF5\n" + - " \n" + - " \n" + - " BASIC\n" + - " ZUGFeRD-invoice.xml\n" + - " INVOICE\n" + - " 1.0\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " ZUGFeRD PDFA Extension Schema\n" + - " urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#\n" + - " zf\n" + - " \n" + - " \n" + - " \n" + - " DocumentFileName\n" + - " Text\n" + - " external\n" + - " name of the embedded XML invoice file\n" + - " \n" + - " \n" + - " DocumentType\n" + - " Text\n" + - " external\n" + - " INVOICE\n" + - " \n" + - " \n" + - " Version\n" + - " Text\n" + - " external\n" + - " The actual version of the ZUGFeRD XML schema\n" + - " \n" + - " \n" + - " ConformanceLevel\n" + - " Text\n" + - " external\n" + - " The conformance level of the embedded ZUGFeRD data\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " 3\n" + - " B\n" + - " \n" + - " \n" + - " 2014-07-11T13:39:46+02:00\n" + - " 2014-07-11T13:39:46+02:00\n" + - " zugferd_invoice.java\n" + - " 2014-07-11T13:39:46+02:00\n" + - " \n" + - " \n" + - " PDFlib Personalization Server 9.0.3 (JDK 1.6/Mac OS X-10.6 64)\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " ZUGFeRD Rechnung $Revision: 1.13 $\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - "", zi.getXMP()); - // this resembles the data written in MustangReaderWriterCustomXMLTest - assertEquals(amount, "1005.55"); + public void testForeignImport() { + InputStream inputStream = this.getClass().getResourceAsStream("/zugferd_invoice.pdf"); + ZUGFeRDImporter zi = new ZUGFeRDImporter(); + zi.doRecalculateItemPricesFromLineTotals(); + zi.doIgnoreCalculationErrors(); + zi.setInputStream(inputStream); + // Reading ZUGFeRD + String amount = zi.getAmount(); - } + assertEquals("\n" + + " \n" + + " \n" + + " \n" + + " uuid:6776DD95-DAF6-768E-DAE6-2697750D95C5\n" + + " uuid:47380404-5938-FE2C-8F0B-B505DCE43BF5\n" + + " \n" + + " \n" + + " BASIC\n" + + " ZUGFeRD-invoice.xml\n" + + " INVOICE\n" + + " 1.0\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " ZUGFeRD PDFA Extension Schema\n" + + " urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#\n" + + " zf\n" + + " \n" + + " \n" + + " \n" + + " DocumentFileName\n" + + " Text\n" + + " external\n" + + " name of the embedded XML invoice file\n" + + " \n" + + " \n" + + " DocumentType\n" + + " Text\n" + + " external\n" + + " INVOICE\n" + + " \n" + + " \n" + + " Version\n" + + " Text\n" + + " external\n" + + " The actual version of the ZUGFeRD XML schema\n" + + " \n" + + " \n" + + " ConformanceLevel\n" + + " Text\n" + + " external\n" + + " The conformance level of the embedded ZUGFeRD data\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 3\n" + + " B\n" + + " \n" + + " \n" + + " 2014-07-11T13:39:46+02:00\n" + + " 2014-07-11T13:39:46+02:00\n" + + " zugferd_invoice.java\n" + + " 2014-07-11T13:39:46+02:00\n" + + " \n" + + " \n" + + " PDFlib Personalization Server 9.0.3 (JDK 1.6/Mac OS X-10.6 64)\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " ZUGFeRD Rechnung $Revision: 1.13 $\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "", zi.getXMP()); + // this resembles the data written in MustangReaderWriterCustomXMLTest + assertEquals(amount, "1005.55"); + + } - public void testMigratePDFA1ToA3() throws IOException { + public void testMigratePDFA1ToA3() throws IOException { // just make sure there is no Exception - InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); + InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); - IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setAttachZUGFeRDHeaders(false).load(SOURCE_PDF); + IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setAttachZUGFeRDHeaders(false).load(SOURCE_PDF); - File tempFile = File.createTempFile("ZUGFeRD-", "-test"); - ze.export(tempFile.getAbsolutePath()); - tempFile.deleteOnExit(); - checkPdfA3B(tempFile); - } + File tempFile = File.createTempFile("ZUGFeRD-", "-test"); + ze.export(tempFile.getAbsolutePath()); + tempFile.deleteOnExit(); + checkPdfA3B(tempFile); + } - public void testMigratePDFA1ToA3Stream() throws IOException { - // just make sure there is no Exception - InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); + public void testMigratePDFA1ToA3Stream() throws IOException { + // just make sure there is no Exception + InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); - IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setAttachZUGFeRDHeaders(false).load(SOURCE_PDF); + IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setAttachZUGFeRDHeaders(false).load(SOURCE_PDF); - File tempFile = File.createTempFile("ZUGFeRD-", "-test"); - tempFile.deleteOnExit(); - try (FileOutputStream fos = new FileOutputStream(tempFile)) { - ze.export(fos); - } - checkPdfA3B(tempFile); - } + File tempFile = File.createTempFile("ZUGFeRD-", "-test"); + tempFile.deleteOnExit(); + try (FileOutputStream fos = new FileOutputStream(tempFile)) { + ze.export(fos); + } + checkPdfA3B(tempFile); + } - private void checkPdfA3B(File tempFile) throws IOException, InvalidPasswordException { - try (PDDocument doc = Loader.loadPDF(tempFile)) { - PDMetadata metadata = doc.getDocumentCatalog().getMetadata(); - InputStream exportXMPMetadata = metadata.exportXMPMetadata(); - byte[] xmpBytes = new byte[exportXMPMetadata.available()]; - exportXMPMetadata.read(xmpBytes); - final XMPMetadata xmp = new DomXmpParser().parse(xmpBytes); - PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema(); - assertEquals(pdfaid.getPart().intValue(), 3); - assertEquals(pdfaid.getConformance(), "U"); - } catch (XmpParsingException e) { - throw new IllegalStateException("Failed to read PDF", e); - } - } + private void checkPdfA3B(File tempFile) throws IOException, InvalidPasswordException { + try (PDDocument doc = Loader.loadPDF(tempFile)) { + PDMetadata metadata = doc.getDocumentCatalog().getMetadata(); + InputStream exportXMPMetadata = metadata.exportXMPMetadata(); + byte[] xmpBytes = new byte[exportXMPMetadata.available()]; + exportXMPMetadata.read(xmpBytes); + final XMPMetadata xmp = new DomXmpParser().parse(xmpBytes); + PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema(); + assertEquals(pdfaid.getPart().intValue(), 3); + assertEquals(pdfaid.getConformance(), "U"); + } catch (XmpParsingException e) { + throw new IllegalStateException("Failed to read PDF", e); + } + } - /** - * The exporter test bases on @{code - * ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds - * metadata, writes to @{code ./target/testout-*} and then imports to check the - * values. It would not make sense to have it run before the less complex - * importer test (which is probably redundant). As only Name Ascending is - * supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export - */ - public void testZExport() { + /** + * The exporter test bases on @{code + * ./src/test/MustangGnuaccountingBeispielRE-20140703_502blanko.pdf}, adds + * metadata, writes to @{code ./target/testout-*} and then imports to check the + * values. It would not make sense to have it run before the less complex + * importer test (which is probably redundant). As only Name Ascending is + * supported for Test Unit sequence, I renamed the Exporter Test test-Z-Export + */ + public void testZExport() { - final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506new.pdf"; + final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506new.pdf"; - // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); + // the writing part + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(2).setProfile(Profiles.getByName("EN16931")).load(SOURCE_PDF)) { - ze.setTransaction(this); - ze.disableAutoClose(true); - ze.export(TARGET_PDF); + ze.setTransaction(this); + ze.disableAutoClose(true); + ze.export(TARGET_PDF); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ze.export(baos); - ze.close(); - String pdfContent = baos.toString(StandardCharsets.UTF_8); - assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); - // check for pdf-a schema extension -// assertFalse(pdfContent.indexOf("EN 16931") == -1); -// assertFalse(pdfContent.indexOf("zf") == -1); -// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ze.export(baos); + ze.close(); + String pdfContent = baos.toString(StandardCharsets.UTF_8); + assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); + // check for pdf-a schema extension +// assertFalse(pdfContent.indexOf("EN 16931") == -1); +// assertFalse(pdfContent.indexOf("zf") == -1); +// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); - } catch (IOException e) { - fail("IOException should not happen in testZExport"); - } + } catch (IOException e) { + fail("IOException should not happen in testZExport"); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getBIC(), "COBADEFFXXX"); - assertEquals(zi.getReference(), getReferenceNumber()); - assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getForeignReference(), getNumber()); - } + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), "COBADEFFXXX"); + assertEquals(zi.getReference(), getReferenceNumber()); + assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); + } - /** - * Quick and dirty copy of testZExport to check if v1 files contain - * the correct profile string when the comfort profile is selected. - */ - public void testZExportv1Profile() { + /** + * Quick and dirty copy of testZExport to check if v1 files contain + * the correct profile string when the comfort profile is selected. + */ + public void testZExportv1Profile() { - final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506new.pdf"; + final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506new.pdf"; - // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); + // the writing part + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); - IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(1).setProfile(Profiles.getByName("COMFORT",1)).load(SOURCE_PDF)) { + IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(1).setProfile(Profiles.getByName("COMFORT", 1)).load(SOURCE_PDF)) { - ze.setTransaction(this); - ze.disableAutoClose(true); - ze.export(TARGET_PDF); + ze.setTransaction(this); + ze.disableAutoClose(true); + ze.export(TARGET_PDF); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ze.export(baos); - ze.close(); - String pdfContent = baos.toString(StandardCharsets.UTF_8); - assertFalse(pdfContent.indexOf(DocumentContextParameterTypeConstants.BASIC) >= 0); - assertFalse(pdfContent.indexOf(DocumentContextParameterTypeConstants.EXTENDED) >= 0); - assertTrue(pdfContent.indexOf(DocumentContextParameterTypeConstants.COMFORT) >= 0); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ze.export(baos); + ze.close(); + String pdfContent = baos.toString(StandardCharsets.UTF_8); + assertFalse(pdfContent.indexOf(DocumentContextParameterTypeConstants.BASIC) >= 0); + assertFalse(pdfContent.indexOf(DocumentContextParameterTypeConstants.EXTENDED) >= 0); + assertTrue(pdfContent.indexOf(DocumentContextParameterTypeConstants.COMFORT) >= 0); - } catch (IOException e) { - fail("IOException should not happen in testZExport"); - } - } + } catch (IOException e) { + fail("IOException should not happen in testZExport"); + } + } - - public void testFXExport() throws Exception { - final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506fx.pdf"; + public void testFXExport() throws Exception { - // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); + final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20171118_506fx.pdf"; + + // the writing part + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20171118_506blanko.pdf"); ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(2).setProfile(Profiles.getByName("EN16931")).load(SOURCE_PDF)) { - ByteArrayOutputStream result = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int length; - while ((length = SOURCE_PDF.read(buffer)) != -1) { - result.write(buffer, 0, length); - } + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = SOURCE_PDF.read(buffer)) != -1) { + result.write(buffer, 0, length); + } - ze.addAdditionalFile("test.pdf", result.toByteArray()); + ze.addAdditionalFile("test.pdf", result.toByteArray()); - ze.setTransaction(this); - ze.disableAutoClose(true); - ze.export(TARGET_PDF); + ze.setTransaction(this); + ze.disableAutoClose(true); + ze.export(TARGET_PDF); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ze.export(baos); - ze.close(); - String pdfContent = baos.toString(StandardCharsets.UTF_8); - assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); - // check for pdf-a schema extension - assertFalse(pdfContent.indexOf("EN 16931") == -1); - assertFalse(pdfContent.indexOf("fx") == -1); - assertFalse(pdfContent.indexOf("urn:cen.eu:en16931:2017") == -1); - } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ze.export(baos); + ze.close(); + String pdfContent = baos.toString(StandardCharsets.UTF_8); + assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1); + // check for pdf-a schema extension + assertFalse(pdfContent.indexOf("EN 16931") == -1); + assertFalse(pdfContent.indexOf("fx") == -1); + assertFalse(pdfContent.indexOf("urn:cen.eu:en16931:2017") == -1); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); - // Reading ZUGFeRD - assertEquals("571.04", zi.getAmount()); - assertEquals("COBADEFFXXX", zi.getBIC()); - assertEquals("DE88 2008 0000 0970 3757 00", zi.getIBAN()); - assertEquals(getOwnOrganisationName(), zi.getHolder()); - assertEquals(getNumber(), zi.getForeignReference()); - } + // Reading ZUGFeRD + assertEquals("571.04", zi.getAmount()); + assertEquals("COBADEFFXXX", zi.getBIC()); + assertEquals("DE88 2008 0000 0970 3757 00", zi.getIBAN()); + assertEquals(getOwnOrganisationName(), zi.getHolder()); + assertEquals(getNumber(), zi.getForeignReference()); + } - public void testExceptionOnPDF14() { + public void testExceptionOnPDF14() { - final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505new.pdf"; + final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20170509_505new.pdf"; - boolean exceptionThrown = false; - // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDF14.pdf"); + boolean exceptionThrown = false; + // the writing part + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDF14.pdf"); IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().load(SOURCE_PDF)) { - ze.setTransaction(this); - ze.export(TARGET_PDF); + ze.setTransaction(this); + ze.export(TARGET_PDF); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ze.export(baos); - } catch (IOException ex) { - // should throw a java.io.IOException: File is not a valid PDF/A-1 input file - exceptionThrown = true; - } - assertTrue(exceptionThrown); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ze.export(baos); + } catch (IOException ex) { + // should throw a java.io.IOException: File is not a valid PDF/A-1 input file + exceptionThrown = true; + } + assertTrue(exceptionThrown); - } + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/OXTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/OXTest.java index f5fa0ab..0991ee5 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/OXTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/OXTest.java @@ -1,4 +1,3 @@ org.openrewrite.config.CompositeRecipe - /** * ********************************************************************* *

@@ -33,7 +32,7 @@ import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Paths; +import java.nio.file.Path; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -42,330 +41,330 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class OXTest extends MustangReaderTestCase { - final String TARGET_PDF = "./target/testout-OX.pdf"; - final String TARGET_PDF_EDGE = "./target/testout-OX-edge.pdf"; - final String TARGET_XML = "./target/testout-OX.xml"; + final String TARGET_PDF = "./target/testout-OX.pdf"; + final String TARGET_PDF_EDGE = "./target/testout-OX-edge.pdf"; + final String TARGET_XML = "./target/testout-OX.xml"; - protected class EdgeProduct implements IZUGFeRDExportableProduct { - private String description, name, unit; + protected class EdgeProduct implements IZUGFeRDExportableProduct { + private String description, name, unit; - public EdgeProduct(String description, String name, String unit) { - super(); - this.description = description; - this.name = name; - this.unit = unit; - } + public EdgeProduct(String description, String name, String unit) { + super(); + this.description = description; + this.name = name; + this.unit = unit; + } - @Override - public String getDescription() { - return description; - } + @Override + public String getDescription() { + return description; + } - public void setDescription(String description) { - this.description = description; - } + public void setDescription(String description) { + this.description = description; + } - @Override - public String getName() { - return name; - } + @Override + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - @Override - public String getUnit() { - return unit; - } + @Override + public String getUnit() { + return unit; + } - public void setUnit(String unit) { - this.unit = unit; - } + public void setUnit(String unit) { + this.unit = unit; + } - @Override - public BigDecimal getVATPercent() { - return BigDecimal.ZERO; - } + @Override + public BigDecimal getVATPercent() { + return BigDecimal.ZERO; + } - @Override - public boolean isIntraCommunitySupply() { - return true; // simulate intra community supply - } - } + @Override + public boolean isIntraCommunitySupply() { + return true; // simulate intra community supply + } + } - protected class DebitPayment implements IZUGFeRDTradeSettlementDebit { + protected class DebitPayment implements IZUGFeRDTradeSettlementDebit { - @Override - public String getIBAN() { - return "DE540815"; - } + @Override + public String getIBAN() { + return "DE540815"; + } - @Override - public String getMandate() { - return "DE99XX12345"; - } + @Override + public String getMandate() { + return "DE99XX12345"; + } - } + } - @Override - public IZUGFeRDTradeSettlement[] getTradeSettlement() { - IZUGFeRDTradeSettlement[] payments = new DebitPayment[1]; - payments[0] = new DebitPayment(); - return payments; - } + @Override + public IZUGFeRDTradeSettlement[] getTradeSettlement() { + IZUGFeRDTradeSettlement[] payments = new DebitPayment[1]; + payments[0] = new DebitPayment(); + return payments; + } - @Override - public Date getDeliveryDate() { - return new GregorianCalendar(2017, Calendar.MAY, 7).getTime(); - } + @Override + public Date getDeliveryDate() { + return new GregorianCalendar(2017, Calendar.MAY, 7).getTime(); + } - @Override - public Date getDueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); - } + @Override + public Date getDueDate() { + return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); + } - @Override - public Date getIssueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); - } + @Override + public Date getIssueDate() { + return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); + } - @Override - public String getNumber() { - return "RE-20170509/505"; - } + @Override + public String getNumber() { + return "RE-20170509/505"; + } - @Override - public String getOwnCountry() { - return "DE"; - } + @Override + public String getOwnCountry() { + return "DE"; + } - @Override - public String getOwnLocation() { - return "Stadthausen"; - } + @Override + public String getOwnLocation() { + return "Stadthausen"; + } - @Override - public String getOwnOrganisationName() { - return "Bei Spiel GmbH"; - } + @Override + public String getOwnOrganisationName() { + return "Bei Spiel GmbH"; + } - @Override - public String getOwnStreet() { - return "Ecke 12"; - } + @Override + public String getOwnStreet() { + return "Ecke 12"; + } - @Override - public IZUGFeRDExportableTradeParty getSender() { - return new SenderTradeParty(); - } + @Override + public IZUGFeRDExportableTradeParty getSender() { + return new SenderTradeParty(); + } - @Override - public String getOwnTaxID() { - return "22/815/0815/4"; - } + @Override + public String getOwnTaxID() { + return "22/815/0815/4"; + } - @Override - public String getOwnVATID() { - return "DE136695976"; - } + @Override + public String getOwnVATID() { + return "DE136695976"; + } - @Override - public String getOwnZIP() { - return "12345"; - } + @Override + public String getOwnZIP() { + return "12345"; + } - @Override - public IZUGFeRDExportableTradeParty getRecipient() { - return new RecipientTradeParty(); - } + @Override + public IZUGFeRDExportableTradeParty getRecipient() { + return new RecipientTradeParty(); + } - @Override - public IZUGFeRDExportableTradeParty getDeliveryAddress() { - return new RecipientTradeParty(); - } + @Override + public IZUGFeRDExportableTradeParty getDeliveryAddress() { + return new RecipientTradeParty(); + } - @Override - public String getOwnOrganisationFullPlaintextInfo() { - return null; - } + @Override + public String getOwnOrganisationFullPlaintextInfo() { + return null; + } - @Override - public String getCurrency() { - return "USD"; - } + @Override + public String getCurrency() { + return "USD"; + } - @Override - public IZUGFeRDExportableItem[] getZFItems() { - Item[] allItems = new Item[3]; - EdgeProduct designProduct = new EdgeProduct("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", - "HUR"); - EdgeProduct balloonProduct = new EdgeProduct("", "Bestellerweiterung für E&F Umbau", "C62");// test for issue - // 103 - EdgeProduct airProduct = new EdgeProduct("", "Heiße Luft pro Liter", "LTR"); + @Override + public IZUGFeRDExportableItem[] getZFItems() { + Item[] allItems = new Item[3]; + EdgeProduct designProduct = new EdgeProduct("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", + "HUR"); + EdgeProduct balloonProduct = new EdgeProduct("", "Bestellerweiterung für E&F Umbau", "C62");// test for issue + // 103 + EdgeProduct airProduct = new EdgeProduct("", "Heiße Luft pro Liter", "LTR"); - Item design = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); - design.setAddReference("1825"); - allItems[0] = design; - allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); - allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); - return allItems; - } + Item design = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); + design.setAddReference("1825"); + allItems[0] = design; + allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); + allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); + return allItems; + } - @Override - public String getPaymentTermDescription() { - SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); - } + @Override + public String getPaymentTermDescription() { + SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); + return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); + } - @Override - public IZUGFeRDAllowanceCharge[] getZFAllowances() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFAllowances() { + return null; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFCharges() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFCharges() { + return null; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { + return null; + } - @Override - public String getReferenceNumber() { - return "AB321"; - } + @Override + public String getReferenceNumber() { + return "AB321"; + } - /** - * Create the test case - * - * @param testName name of the test case - */ - public OXTest(String testName) { - super(testName); - } + /** + * Create the test case + * + * @param testName name of the test case + */ + public OXTest(String testName) { + super(testName); + } - /** - * @return the suite of tests being tested - */ - public static Test suite() { - return new TestSuite(OXTest.class); - } + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(OXTest.class); + } - // //////// TESTS - // ////////////////////////////////////////////////////////////////////////////////////////// + // //////// TESTS + // ////////////////////////////////////////////////////////////////////////////////////////// - /** - * The exporter test bases on @{code - * ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds - * metadata, writes to @{code ./target/testout-*} and then imports to check the - * values. - */ - public void testOXExport() { + /** + * The exporter test bases on @{code + * ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds + * metadata, writes to @{code ./target/testout-*} and then imports to check the + * values. + */ + public void testOXExport() { - // the writing part + // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); OXExporterFromA1 oe = new OXExporterFromA1().setProducer("My Application") - .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(1).ignorePDFAErrors() - .load(SOURCE_PDF)) { - oe.setTransaction(this); - String theXML = new String(oe.getProvider().getXML(), StandardCharsets.UTF_8); - assertTrue(theXML.contains("220")); - assertTrue(zi.getUTF8().contains("")); - assertFalse(zi.getUTF8().contains("EUR")); - assertTrue(zi.getUTF8().contains("USD"));//currency should be USD, test for #150 + assertTrue(zi.getUTF8().contains("220")); + assertTrue(zi.getUTF8().contains("")); + assertFalse(zi.getUTF8().contains("EUR")); + assertTrue(zi.getUTF8().contains("USD"));// currency should be USD, test for #150 - // Now also check the "invoice"Importer - assertEquals("496.00", zi.getAmount()); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF); - try { - Invoice i = zii.extractInvoice(); + // Now also check the "invoice"Importer + assertEquals("496.00", zi.getAmount()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF); + try { + Invoice i = zii.extractInvoice(); - assertEquals(new BigDecimal("400.0000"), i.getZFItems()[1].getQuantity()); - /* getting the Quantity is more difficult than usual because in OrderX it's - called requestedQuantity, not BilledQuantity - */ + assertEquals(new BigDecimal("400.0000"), i.getZFItems()[1].getQuantity()); + /* getting the Quantity is more difficult than usual because in OrderX it's + called requestedQuantity, not BilledQuantity + */ - } catch (XPathExpressionException e) { - fail("XPathExpressionException should not be raised in testEdgeExport"); - } catch (ParseException e) { - fail("ParseException should not be raised in testEdgeExport"); - /* a parseException would also be fired if the calculated grand total does not - match the read grand total */ - } + } catch (XPathExpressionException e) { + fail("XPathExpressionException should not be raised in testEdgeExport"); + } catch (ParseException e) { + fail("ParseException should not be raised in testEdgeExport"); + /* a parseException would also be fired if the calculated grand total does not + match the read grand total */ + } - } + } - public void testOXEdgeExport() { + public void testOXEdgeExport() { - // the writing part + // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); OXExporterFromA1 oe = new OXExporterFromA1().setProducer("My Application") - .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(1).ignorePDFAErrors() - .load(SOURCE_PDF)) { - TradeParty rec=new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); - Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) - .setSender(new TradeParty("Test company", "teststr", "55232", "teststadt", "DE").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890", "COBADEFXXX"))) - .setRecipient(rec) - .setReferenceNumber("991-01484-64")//leitweg-id - .setNumber("123").addItem(new org.mustangproject.Item(new org.mustangproject.Product("Testprodukt", "", "C62", BigDecimal.ZERO), /*price*/ new BigDecimal("1.0"), /*qty*/ new BigDecimal("1.0"))).addItem(new org.mustangproject.Item(new org.mustangproject.Product("Testprodukt", "", "C62", BigDecimal.ZERO), /*price*/ new BigDecimal("1.0"), /*qty*/ new BigDecimal("1.0"))); + .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(1).ignorePDFAErrors() + .load(SOURCE_PDF)) { + TradeParty rec = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); + Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) + .setSender(new TradeParty("Test company", "teststr", "55232", "teststadt", "DE").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890", "COBADEFXXX"))) + .setRecipient(rec) + .setReferenceNumber("991-01484-64")// leitweg-id + .setNumber("123").addItem(new org.mustangproject.Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), /*price*/ new BigDecimal("1.0"), /*qty*/ new BigDecimal("1.0"))).addItem(new org.mustangproject.Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), /*price*/ new BigDecimal("1.0"), /*qty*/ new BigDecimal("1.0"))); - oe.setTransaction(i); - oe.export(TARGET_PDF_EDGE); - } catch (IOException e) { - fail("IOException should not be raised in testEdgeExport"); - } + oe.setTransaction(i); + oe.export(TARGET_PDF_EDGE); + } catch (IOException e) { + fail("IOException should not be raised in testEdgeExport"); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_EDGE); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_EDGE); - assertTrue(zi.getUTF8().contains("220")); - assertTrue(zi.getUTF8().contains("")); - assertTrue(zi.getUTF8().contains("EUR")); + assertTrue(zi.getUTF8().contains("220")); + assertTrue(zi.getUTF8().contains("")); + assertTrue(zi.getUTF8().contains("EUR")); - // Now also check the "invoice"Importer - assertEquals("2.00", zi.getAmount()); - assertEquals(zi.getHolder(), "Test company"); - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF_EDGE); - try { - Invoice i = zii.extractInvoice(); + // Now also check the "invoice"Importer + assertEquals("2.00", zi.getAmount()); + assertEquals(zi.getHolder(), "Test company"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF_EDGE); + try { + Invoice i = zii.extractInvoice(); - assertEquals(new BigDecimal("1.0000"), i.getZFItems()[1].getQuantity()); - /* getting the Quantity is more difficult than usual because in OrderX it's - called requestedQuantity, not BilledQuantity - */ + assertEquals(new BigDecimal("1.0000"), i.getZFItems()[1].getQuantity()); + /* getting the Quantity is more difficult than usual because in OrderX it's + called requestedQuantity, not BilledQuantity + */ - } catch (XPathExpressionException e) { - fail("XPathExpressionException should not be raised in testEdgeExport"); - } catch (ParseException e) { - fail("ParseException should not be raised in testEdgeExport"); - /* a parseException would also be fired if the calculated grand total does not - match the read grand total */ - } + } catch (XPathExpressionException e) { + fail("XPathExpressionException should not be raised in testEdgeExport"); + } catch (ParseException e) { + fail("ParseException should not be raised in testEdgeExport"); + /* a parseException would also be fired if the calculated grand total does not + match the read grand total */ + } - } + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/PDFAWriteTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/PDFAWriteTest.java index 579c829..ee5f454 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/PDFAWriteTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/PDFAWriteTest.java @@ -1,4 +1,3 @@ org.openrewrite.config.CompositeRecipe - /** * ********************************************************************* *

@@ -34,98 +33,101 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class PDFAWriteTest extends ResourceCase { - final String TARGET_PDF_FROM_A1 = "./target/testout-PDFA3FromA3.pdf"; - final String TARGET_PDF_FROM_A3 = "./target/testout-PDFA3FromA3.pdf"; - final String TARGET_PDF_FROM_A3_UNKNOWN = "./target/testout-PDFA3FromUnkownA3.pdf"; - final String TARGET_PDF_FROM_A1_UNKNOWN = "./target/testout-PDFA3FromUnkownA1.pdf"; - public void testA1KnownExport() { - // test creating factur-x invoices to french authorities, i.e. with SIRET number - // the writing part - TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); + final String TARGET_PDF_FROM_A1 = "./target/testout-PDFA3FromA3.pdf"; + final String TARGET_PDF_FROM_A3 = "./target/testout-PDFA3FromA3.pdf"; + final String TARGET_PDF_FROM_A3_UNKNOWN = "./target/testout-PDFA3FromUnkownA3.pdf"; + final String TARGET_PDF_FROM_A1_UNKNOWN = "./target/testout-PDFA3FromUnkownA1.pdf"; - Invoice i = createInvoice(recipient); - File tempFile = getResourceAsFile("MustangGnuaccountingBeispielRE-20201121_508blanko.pdf");//a3 - int exceptions=0; - try { - ZUGFeRDExporterFromA1 zea3 = new ZUGFeRDExporterFromA1().load(tempFile.getAbsolutePath()); - zea3.setTransaction(i); - zea3.export(TARGET_PDF_FROM_A1); + public void testA1KnownExport() { + // test creating factur-x invoices to french authorities, i.e. with SIRET number + // the writing part + TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); - } catch (IOException e) { - exceptions++; - } - assertTrue(exceptions==0); + Invoice i = createInvoice(recipient); + File tempFile = getResourceAsFile("MustangGnuaccountingBeispielRE-20201121_508blanko.pdf");// a3 + int exceptions = 0; + try { + ZUGFeRDExporterFromA1 zea3 = new ZUGFeRDExporterFromA1().load(tempFile.getAbsolutePath()); + zea3.setTransaction(i); + zea3.export(TARGET_PDF_FROM_A1); - } - public void testA3KnownExport() { - TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); + } catch (IOException e) { + exceptions++; + } + assertTrue(exceptions == 0); - Invoice i = createInvoice(recipient); - File tempFile = getResourceAsFile("MustangGnuaccountingBeispielRE-20201121_508blankoA3.pdf");//a3 - int exceptions=0; - try { - ZUGFeRDExporterFromA3 zea3 = new ZUGFeRDExporterFromA3().load(tempFile.getAbsolutePath()); - zea3.setTransaction(i); - zea3.export(TARGET_PDF_FROM_A3); + } - } catch (IOException e) { - exceptions++; - } - assertTrue(exceptions==0); + public void testA3KnownExport() { + TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); - } - public void testA3UnknownExport() { - // test creating factur-x invoices to french authorities, i.e. with SIRET number - // the writing part - TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); - Invoice i = createInvoice(recipient); + Invoice i = createInvoice(recipient); + File tempFile = getResourceAsFile("MustangGnuaccountingBeispielRE-20201121_508blankoA3.pdf");// a3 + int exceptions = 0; + try { + ZUGFeRDExporterFromA3 zea3 = new ZUGFeRDExporterFromA3().load(tempFile.getAbsolutePath()); + zea3.setTransaction(i); + zea3.export(TARGET_PDF_FROM_A3); - File tempFile = getResourceAsFile("MustangGnuaccountingBeispielRE-20201121_508blankoA3.pdf"); - int exceptions=0; - try { - IZUGFeRDExporter zea = new ZUGFeRDExporterFromPDFA().load(tempFile.getAbsolutePath()); - zea.setTransaction(i); - zea.export(TARGET_PDF_FROM_A3_UNKNOWN); + } catch (IOException e) { + exceptions++; + } + assertTrue(exceptions == 0); - } catch (IOException e) { - exceptions++; - } - assertTrue(exceptions==0); + } - } + public void testA3UnknownExport() { + // test creating factur-x invoices to french authorities, i.e. with SIRET number + // the writing part + TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); + Invoice i = createInvoice(recipient); - public void testA3UnknownExportFromA1() { - // test creating factur-x invoices to french authorities, i.e. with SIRET number - // the writing part - TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); - Invoice i = createInvoice(recipient); - File tempFile = getResourceAsFile("MustangGnuaccountingBeispielRE-20201121_508blanko.pdf"); - int exceptions=0; - try { - FileInputStream fis=new FileInputStream(tempFile); - IZUGFeRDExporter zea3 = new ZUGFeRDExporterFromPDFA().load(fis); - zea3.setTransaction(i); - zea3.setProfile(Profiles.getByName("EN16931")); - zea3.export(TARGET_PDF_FROM_A1_UNKNOWN); + File tempFile = getResourceAsFile("MustangGnuaccountingBeispielRE-20201121_508blankoA3.pdf"); + int exceptions = 0; + try { + IZUGFeRDExporter zea = new ZUGFeRDExporterFromPDFA().load(tempFile.getAbsolutePath()); + zea.setTransaction(i); + zea.export(TARGET_PDF_FROM_A3_UNKNOWN); - } catch (IOException e) { - exceptions++; - } - assertTrue(exceptions==0); + } catch (IOException e) { + exceptions++; + } + assertTrue(exceptions == 0); - } + } - private Invoice createInvoice(TradeParty recipient) { - String orgname = "Test company"; - String number = "123"; - String amountStr = "1.00"; - BigDecimal amount = new BigDecimal(amountStr); - return new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) - .setSender(new TradeParty(orgname,"teststr","55232","teststadt","DE").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test","+49123456789","test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890","COBADEFXXX"))) - .setRecipient(recipient) - .setReferenceNumber("991-01484-64")//leitweg-id - // not using any VAT, this is also a test of zero-rated goods: - .setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), amount, new BigDecimal(1.0))); - } + public void testA3UnknownExportFromA1() { + // test creating factur-x invoices to french authorities, i.e. with SIRET number + // the writing part + TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); + Invoice i = createInvoice(recipient); + File tempFile = getResourceAsFile("MustangGnuaccountingBeispielRE-20201121_508blanko.pdf"); + int exceptions = 0; + try { + FileInputStream fis = new FileInputStream(tempFile); + IZUGFeRDExporter zea3 = new ZUGFeRDExporterFromPDFA().load(fis); + zea3.setTransaction(i); + zea3.setProfile(Profiles.getByName("EN16931")); + zea3.export(TARGET_PDF_FROM_A1_UNKNOWN); + + } catch (IOException e) { + exceptions++; + } + assertTrue(exceptions == 0); + + } + + private Invoice createInvoice(TradeParty recipient) { + String orgname = "Test company"; + String number = "123"; + String amountStr = "1.00"; + BigDecimal amount = new BigDecimal(amountStr); + return new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) + .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890", "COBADEFXXX"))) + .setRecipient(recipient) + .setReferenceNumber("991-01484-64")// leitweg-id + // not using any VAT, this is also a test of zero-rated goods: + .setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), amount, new BigDecimal(1.0))); + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/PreValidationTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/PreValidationTest.java index ba7f0e3..263fb96 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/PreValidationTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/PreValidationTest.java @@ -1,4 +1,3 @@ org.openrewrite.config.CompositeRecipe - /** * ********************************************************************* *

@@ -32,56 +31,55 @@ import java.util.Date; - @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class PreValidationTest extends TestCase { - final String TARGET_PDF = "./target/testout-Preval.pdf"; - final String SOURCE_PDF = "/veraPDFtestsuite6-7-11-t01-fail-a.pdf"; + final String TARGET_PDF = "./target/testout-Preval.pdf"; + final String SOURCE_PDF = "/veraPDFtestsuite6-7-11-t01-fail-a.pdf"; - public void testFailIgnore() { + public void testFailIgnore() { - // the writing part + // the writing part - boolean hasEx = false; - try (InputStream source = this.getClass() - .getResourceAsStream(SOURCE_PDF)) { - ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1().setProducer("My Application") - .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2) - .load(source); - ze.setTransaction(createInvoice()); + boolean hasEx = false; + try (InputStream source = this.getClass() + .getResourceAsStream(SOURCE_PDF)) { + ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1().setProducer("My Application") + .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2) + .load(source); + ze.setTransaction(createInvoice()); - ze.export(TARGET_PDF); - } catch (IOException e) { - hasEx = true; - } - assertTrue(hasEx); - hasEx = false; - try (InputStream source = this.getClass() - .getResourceAsStream(SOURCE_PDF)) { - ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1(); - ze.ignorePDFAErrors().load(source); + ze.export(TARGET_PDF); + } catch (IOException e) { + hasEx = true; + } + assertTrue(hasEx); + hasEx = false; + try (InputStream source = this.getClass() + .getResourceAsStream(SOURCE_PDF)) { + ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1(); + ze.ignorePDFAErrors().load(source); - ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2). - setTransaction(createInvoice()); - ze.export(TARGET_PDF); - } catch (IOException e) { - hasEx = true; - } - assertFalse(hasEx); - } + ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2). + setTransaction(createInvoice()); + ze.export(TARGET_PDF); + } catch (IOException e) { + hasEx = true; + } + assertFalse(hasEx); + } - private Invoice createInvoice() { - String orgname = "Test company"; - String number = "123"; - String amountStr = "1.00"; - BigDecimal amount = new BigDecimal(amountStr); - return new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) - .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("DE4711").addVATID("DE0815").setEmail("info@example.org").setContact(new Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890", "COBADEFXXX"))) - .setRecipient(new TradeParty("Theodor Est", "Bahnstr. 42", "88802", "Spielkreis", "DE")) - .setReferenceNumber("991-01484-64")//leitweg-id - // not using any VAT, this is also a test of zero-rated goods: - .setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), amount, new BigDecimal(1.0))); - } + private Invoice createInvoice() { + String orgname = "Test company"; + String number = "123"; + String amountStr = "1.00"; + BigDecimal amount = new BigDecimal(amountStr); + return new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) + .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("DE4711").addVATID("DE0815").setEmail("info@example.org").setContact(new Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890", "COBADEFXXX"))) + .setRecipient(new TradeParty("Theodor Est", "Bahnstr. 42", "88802", "Spielkreis", "DE")) + .setReferenceNumber("991-01484-64")// leitweg-id + // not using any VAT, this is also a test of zero-rated goods: + .setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), amount, new BigDecimal(1.0))); + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ProfilesMinimumBasicWLTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ProfilesMinimumBasicWLTest.java index abe0821..3210c86 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ProfilesMinimumBasicWLTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ProfilesMinimumBasicWLTest.java @@ -36,115 +36,115 @@ org.openrewrite.config.CompositeRecipe */ public class ProfilesMinimumBasicWLTest extends TestCase { - final String TARGET_PDF_FX_MINIMUM_INV = "./target/testout-Minimum-INV.pdf"; - final String TARGET_PDF_FX_MINIMUM_CN = "./target/testout-Minimum-CN.pdf"; + final String TARGET_PDF_FX_MINIMUM_INV = "./target/testout-Minimum-INV.pdf"; + final String TARGET_PDF_FX_MINIMUM_CN = "./target/testout-Minimum-CN.pdf"; - public void testMinimumCreditNote() { - String ownNumber = "NUMFACTURE"; - String ownBIC = "COBADEFFXXX"; - String ownIBAN = "DE88200800000970375700"; - String ownOrgName = "ME"; + public void testMinimumCreditNote() { + String ownNumber = "NUMFACTURE"; + String ownBIC = "COBADEFFXXX"; + String ownIBAN = "DE88200800000970375700"; + String ownOrgName = "ME"; - // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); + // the writing part + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(2).setProfile("Minimum").load(SOURCE_PDF)) { - /*** - * this is a classical example of a french invoice (very low profile, siret number) and an attempt to answer stackoverflow (!) - * https://stackoverflow.com/questions/72450066/creating-a-min-basic-and-basic-wl-factur-x-using-mustang - */ + /*** + * this is a classical example of a french invoice (very low profile, siret number) and an attempt to answer stackoverflow (!) + * https://stackoverflow.com/questions/72450066/creating-a-min-basic-and-basic-wl-factur-x-using-mustang + */ - TradeParty recipient = new TradeParty().setName("Client").setCountry("FR"); - String siret="0815"; - String sirenTypeCode="0002"; - recipient.setLegalOrganisation(new LegalOrganisation(siret,sirenTypeCode)); - Invoice i = new Invoice() - .setIssueDate(new Date()) - .setSender( - new TradeParty().setName(ownOrgName).setCountry("FR").setVATID("FR555444333222111") - .addBankDetails(new BankDetails(ownIBAN, ownBIC))) - .setRecipient(recipient) - .setNumber(ownNumber) - .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal(123), new BigDecimal(1))) - .setCreditNote(); - ze.setTransaction(i); - ze.export(TARGET_PDF_FX_MINIMUM_CN); + TradeParty recipient = new TradeParty().setName("Client").setCountry("FR"); + String siret = "0815"; + String sirenTypeCode = "0002"; + recipient.setLegalOrganisation(new LegalOrganisation(siret, sirenTypeCode)); + Invoice i = new Invoice() + .setIssueDate(new Date()) + .setSender( + new TradeParty().setName(ownOrgName).setCountry("FR").setVATID("FR555444333222111") + .addBankDetails(new BankDetails(ownIBAN, ownBIC))) + .setRecipient(recipient) + .setNumber(ownNumber) + .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal(123), new BigDecimal(1))) + .setCreditNote(); + ze.setTransaction(i); + ze.export(TARGET_PDF_FX_MINIMUM_CN); - // check for pdf-a schema extension -// assertFalse(pdfContent.indexOf("EN 16931") == -1); -// assertFalse(pdfContent.indexOf("zf") == -1); -// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); + // check for pdf-a schema extension +// assertFalse(pdfContent.indexOf("EN 16931") == -1); +// assertFalse(pdfContent.indexOf("zf") == -1); +// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); - } catch (IOException e) { - fail("IOException should not happen in testMinimumExport"); - } + } catch (IOException e) { + fail("IOException should not happen in testMinimumExport"); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_FX_MINIMUM_CN); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_FX_MINIMUM_CN); - // Reading ZUGFeRD - assertEquals("146.37",zi.getAmount()); -// assertEquals(zi.getBIC(), ownBIC); -// assertEquals(zi.getIBAN(), ownIBAN); - assertEquals(ownOrgName, zi.getHolder()); -// assertEquals(zi.getForeignReference(), ownNumber); + // Reading ZUGFeRD + assertEquals("146.37", zi.getAmount()); +// assertEquals(zi.getBIC(), ownBIC); +// assertEquals(zi.getIBAN(), ownIBAN); + assertEquals(ownOrgName, zi.getHolder()); +// assertEquals(zi.getForeignReference(), ownNumber); - } + } - public void testMinimumInvoice() { - String ownNumber = "NUMFACTURE"; - String ownBIC = "COBADEFFXXX"; - String ownIBAN = "DE88200800000970375700"; - String ownOrgName = "ME"; + public void testMinimumInvoice() { + String ownNumber = "NUMFACTURE"; + String ownBIC = "COBADEFFXXX"; + String ownIBAN = "DE88200800000970375700"; + String ownOrgName = "ME"; - // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); + // the writing part + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20190610_507blanko.pdf"); IZUGFeRDExporter ze = new ZUGFeRDExporterFromA1().setZUGFeRDVersion(2).setProfile("Minimum").load(SOURCE_PDF)) { - /*** - * this is a classical example of a french invoice (very low profile, siret number) and an attempt to answer stackoverflow (!) - * https://stackoverflow.com/questions/72450066/creating-a-min-basic-and-basic-wl-factur-x-using-mustang - */ + /*** + * this is a classical example of a french invoice (very low profile, siret number) and an attempt to answer stackoverflow (!) + * https://stackoverflow.com/questions/72450066/creating-a-min-basic-and-basic-wl-factur-x-using-mustang + */ - TradeParty recipient = new TradeParty().setName("Client").setCountry("FR"); - String siret="0815"; - String sirenTypeCode="0002"; - recipient.setLegalOrganisation(new LegalOrganisation(siret,sirenTypeCode)); - Invoice i = new Invoice() - .setIssueDate(new Date()) - .setDueDate(new Date()) - .setSender( - new TradeParty().setName(ownOrgName).setCountry("FR").setVATID("FR555444333222111") - .addBankDetails(new BankDetails(ownIBAN))) - .setRecipient(recipient) - .setNumber(ownNumber).setTotalPrepaidAmount(new BigDecimal("1")) - .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal(123), new BigDecimal(1))); - ze.setTransaction(i); - ze.export(TARGET_PDF_FX_MINIMUM_INV); + TradeParty recipient = new TradeParty().setName("Client").setCountry("FR"); + String siret = "0815"; + String sirenTypeCode = "0002"; + recipient.setLegalOrganisation(new LegalOrganisation(siret, sirenTypeCode)); + Invoice i = new Invoice() + .setIssueDate(new Date()) + .setDueDate(new Date()) + .setSender( + new TradeParty().setName(ownOrgName).setCountry("FR").setVATID("FR555444333222111") + .addBankDetails(new BankDetails(ownIBAN))) + .setRecipient(recipient) + .setNumber(ownNumber).setTotalPrepaidAmount(new BigDecimal("1")) + .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal(123), new BigDecimal(1))); + ze.setTransaction(i); + ze.export(TARGET_PDF_FX_MINIMUM_INV); - // check for pdf-a schema extension -// assertFalse(pdfContent.indexOf("EN 16931") == -1); -// assertFalse(pdfContent.indexOf("zf") == -1); -// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); + // check for pdf-a schema extension +// assertFalse(pdfContent.indexOf("EN 16931") == -1); +// assertFalse(pdfContent.indexOf("zf") == -1); +// assertFalse(pdfContent.indexOf("urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#") == -1); - } catch (IOException e) { - fail("IOException should not happen in testMinimumExport"); - } + } catch (IOException e) { + fail("IOException should not happen in testMinimumExport"); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_FX_MINIMUM_INV); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_FX_MINIMUM_INV); - // Reading ZUGFeRD - assertEquals("146.37",zi.getAmount()); -// assertEquals(zi.getBIC(), ownBIC); -// assertEquals(zi.getIBAN(), ownIBAN); - assertEquals(ownOrgName, zi.getHolder()); -// assertEquals(zi.getForeignReference(), ownNumber); + // Reading ZUGFeRD + assertEquals("146.37", zi.getAmount()); +// assertEquals(zi.getBIC(), ownBIC); +// assertEquals(zi.getIBAN(), ownIBAN); + assertEquals(ownOrgName, zi.getHolder()); +// assertEquals(zi.getForeignReference(), ownNumber); - } + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ResourceCase.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ResourceCase.java index 4ac331d..541a76d 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ResourceCase.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ResourceCase.java @@ -1,7 +1,6 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; import junit.framework.TestCase; - import org.junit.Ignore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,31 +12,31 @@ @Ignore public class ResourceCase extends TestCase { - private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCase.class.getCanonicalName()); // log output is - - public static File getResourceAsFile(String resourcePath) { - try { - InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath); - if (in == null) { - return null; - } + private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCase.class.getCanonicalName()); // log output is + + public static File getResourceAsFile(String resourcePath) { + try { + InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath); + if (in == null) { + return null; + } - File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp"); - tempFile.deleteOnExit(); + File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp"); + tempFile.deleteOnExit(); - try (FileOutputStream out = new FileOutputStream(tempFile)) { - // copy stream - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = in.read(buffer)) != -1) { - out.write(buffer, 0, bytesRead); - } - } - return tempFile; - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); - return null; - } - } + try (FileOutputStream out = new FileOutputStream(tempFile)) { + // copy stream + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + } + return tempFile; + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); + return null; + } + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ResourceUtilities.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ResourceUtilities.java index 734ca7f..7a00e99 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ResourceUtilities.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ResourceUtilities.java @@ -16,202 +16,202 @@ org.openrewrite.config.CompositeRecipe *********************************************************************** */ package org.mustangproject.ZUGFeRD; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.*; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; import java.nio.file.Files; -import java.nio.file.Paths; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.nio.file.Path; /** * This test utility class is providing usability functions to test file resources */ public class ResourceUtilities { - private static final Logger LOGGER = LoggerFactory.getLogger (ResourceUtilities.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ResourceUtilities.class); - /** - * Loading a File into a String using a certain encoding and file path - * @param encoding the charset used in the file - * @param path the path to the file - * @return the file contents as a String - * @throws IOException if the file cannot be read - */ - public static String readFile(Charset encoding, String path) throws IOException { - byte[] content = Files.readAllBytes(Paths.get(path)); - return new String(content, encoding); - } + /** + * Loading a File into a String using a certain encoding and file path + * @param encoding the charset used in the file + * @param path the path to the file + * @return the file contents as a String + * @throws IOException if the file cannot be read + */ + public static String readFile(Charset encoding, String path) throws IOException { + byte[] content = Files.readAllBytes(Path.of(path)); + return new String(content, encoding); + } - /** - * Saving a String as a file to a certain file path - * @param encoding the charset used in the file - * @param path the path to the file - * @param content the contents of the file - * @throws FileNotFoundException if the file cannot be found - */ - public static void saveFile(Charset encoding, String path, String content) throws FileNotFoundException { + /** + * Saving a String as a file to a certain file path + * @param encoding the charset used in the file + * @param path the path to the file + * @param content the contents of the file + * @throws FileNotFoundException if the file cannot be found + */ + public static void saveFile(Charset encoding, String path, String content) throws FileNotFoundException { - // resources will be released automatically - try (PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(path)), encoding), true)) { - out.println(content); - } - } + // resources will be released automatically + try (PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(path)), encoding), true)) { + out.println(content); + } + } - /** - * The relative path of the test file will be resolved and the absolute will be returned - * - * @param relativeFilePath Path of the test resource relative to src/test/resource/. - * @return the absolute path of the test file - * @throws FileNotFoundException If the file could not be found - */ - public static String getAbsolutePath(String relativeFilePath) throws FileNotFoundException { - URI uri = null; - try { - uri = ResourceUtilities.class.getClassLoader().getResource(relativeFilePath).toURI(); - uri = new URI(toExternalForm(uri)); - } catch (URISyntaxException ex) { - LOGGER.error("Failed to parse URI", ex); - } - if (uri == null) { - throw new FileNotFoundException("Could not find the file '" + relativeFilePath + "'!"); - } - return uri.getPath(); - } + /** + * The relative path of the test file will be resolved and the absolute will be returned + * + * @param relativeFilePath Path of the test resource relative to src/test/resource/. + * @return the absolute path of the test file + * @throws FileNotFoundException If the file could not be found + */ + public static String getAbsolutePath(String relativeFilePath) throws FileNotFoundException { + URI uri = null; + try { + uri = ResourceUtilities.class.getClassLoader().getResource(relativeFilePath).toURI(); + uri = new URI(toExternalForm(uri)); + } catch (URISyntaxException ex) { + LOGGER.error("Failed to parse URI", ex); + } + if (uri == null) { + throw new FileNotFoundException("Could not find the file '" + relativeFilePath + "'!"); + } + return uri.getPath(); + } - /** - * The relative path of the test file will be resolved and the absolute will be returned - * - * @param relativeFilePath Path of the test resource relative to src/test/resource/. - * @return the URI created based on the relativeFilePath - * @throws URISyntaxException if no URI could be created from the given relative path - */ - public static URI getURI(String relativeFilePath) throws URISyntaxException { - String filePath = "file:" + ResourceUtilities.class.getClassLoader().getResource(relativeFilePath).getPath(); - filePath = toExternalForm(new URI(filePath)); - return new URI(filePath); - } + /** + * The relative path of the test file will be resolved and the absolute will be returned + * + * @param relativeFilePath Path of the test resource relative to src/test/resource/. + * @return the URI created based on the relativeFilePath + * @throws URISyntaxException if no URI could be created from the given relative path + */ + public static URI getURI(String relativeFilePath) throws URISyntaxException { + String filePath = "file:" + ResourceUtilities.class.getClassLoader().getResource(relativeFilePath).getPath(); + filePath = toExternalForm(new URI(filePath)); + return new URI(filePath); + } - /** - * The relative path of the test file will be used to determine an absolute - * path to a temporary directory in the output directory. - * - * @param relativeFilePath Path of the test resource relative to src/test/resource/. - * @return absolute path to a test output - * @throws IOException if no absolute Path could be created. - */ - public static String getTestOutput(String relativeFilePath) throws IOException { - File tempFile = File.createTempFile(relativeFilePath, null); - tempFile.deleteOnExit(); - return tempFile.getAbsolutePath(); - } + /** + * The relative path of the test file will be used to determine an absolute + * path to a temporary directory in the output directory. + * + * @param relativeFilePath Path of the test resource relative to src/test/resource/. + * @return absolute path to a test output + * @throws IOException if no absolute Path could be created. + */ + public static String getTestOutput(String relativeFilePath) throws IOException { + File tempFile = File.createTempFile(relativeFilePath, null); + tempFile.deleteOnExit(); + return tempFile.getAbsolutePath(); + } - /** - * The Input of the test file will be resolved and the absolute will be returned - * - * @param relativeFilePath Path of the test resource relative to src/test/resource/. - * @return the absolute path of the test file - */ - public static InputStream getTestResourceAsStream(String relativeFilePath) { - return ResourceUtilities.class.getClassLoader().getResourceAsStream(relativeFilePath); - } + /** + * The Input of the test file will be resolved and the absolute will be returned + * + * @param relativeFilePath Path of the test resource relative to src/test/resource/. + * @return the absolute path of the test file + */ + public static InputStream getTestResourceAsStream(String relativeFilePath) { + return ResourceUtilities.class.getClassLoader().getResourceAsStream(relativeFilePath); + } - /** - * Relative to the test output directory a test file will be returned dependent on the relativeFilePath provided. - * - * @param relativeFilePath Path of the test output resource relative to target/test-classes/. - * @return the empty File of the test output (to be filled) - */ - public static File newTestOutputFile(String relativeFilePath) { - String filepath = null; - try { - filepath = ResourceUtilities.class.getClassLoader().getResource("").toURI().getPath() + relativeFilePath; - } catch (URISyntaxException ex) { - LOGGER.error("Failed to parse URI", ex); - } - return new File(filepath); - } + /** + * Relative to the test output directory a test file will be returned dependent on the relativeFilePath provided. + * + * @param relativeFilePath Path of the test output resource relative to target/test-classes/. + * @return the empty File of the test output (to be filled) + */ + public static File newTestOutputFile(String relativeFilePath) { + String filepath = null; + try { + filepath = ResourceUtilities.class.getClassLoader().getResource("").toURI().getPath() + relativeFilePath; + } catch (URISyntaxException ex) { + LOGGER.error("Failed to parse URI", ex); + } + return new File(filepath); + } - /** - * @return the absolute path of the test output folder, which is usually target/test-classes/. - */ - public static String getTestOutputFolder() { - String testFolder = null; - try { - testFolder = ResourceUtilities.class.getClassLoader().getResource("").toURI().getPath(); - } catch (URISyntaxException ex) { - LOGGER.error("Failed to parse URI", ex); - } - return testFolder; - } + /** + * @return the absolute path of the test output folder, which is usually target/test-classes/. + */ + public static String getTestOutputFolder() { + String testFolder = null; + try { + testFolder = ResourceUtilities.class.getClassLoader().getResource("").toURI().getPath(); + } catch (URISyntaxException ex) { + LOGGER.error("Failed to parse URI", ex); + } + return testFolder; + } - public static File getTempTestDirectory() { - File tempDir = new File(ResourceUtilities.getTestOutputFolder() + "temp"); - tempDir.mkdir(); //if it already exist no problem - return tempDir; - } + public static File getTempTestDirectory() { + File tempDir = new File(ResourceUtilities.getTestOutputFolder() + "temp"); + tempDir.mkdir(); // if it already exist no problem + return tempDir; + } - /** - * To fix the 3 slashes bug for File URI: For example: - * file:/C:/work/test.txt gives file:///C:/work/test.txt - * - * @param u - the File URI - * @return the String of the URI - */ - public static String toExternalForm(URI u) { - StringBuilder sb = new StringBuilder(); - if (u.getScheme() != null) { - sb.append(u.getScheme()); - sb.append(':'); - } - if (u.isOpaque()) { - sb.append(u.getSchemeSpecificPart()); - } else { - if (u.getHost() != null) { - sb.append("//"); - if (u.getUserInfo() != null) { - sb.append(u.getUserInfo()); - sb.append('@'); - } - boolean needBrackets = ((u.getHost().indexOf(':') >= 0) && !u.getHost().startsWith("[") && !u.getHost().endsWith("]")); - if (needBrackets) - sb.append('['); - sb.append(u.getHost()); - if (needBrackets) - sb.append(']'); - if (u.getPort() != -1) { - sb.append(':'); - sb.append(u.getPort()); - } - } else if (u.getRawAuthority() != null) { - sb.append("//"); - sb.append(u.getRawAuthority()); - } else { - sb.append("//"); - } - if (u.getRawPath() != null) - sb.append(u.getRawPath()); - if (u.getRawQuery() != null) { - sb.append('?'); - sb.append(u.getRawQuery()); - } - } - if (u.getFragment() != null) { - sb.append('#'); - sb.append(u.getFragment()); - } - String ret = null; - try { - ret = new URI(sb.toString()).toASCIIString(); - } catch (URISyntaxException ex) { - LOGGER.error("Failed to parse URI", ex); - } - return ret; - } + /** + * To fix the 3 slashes bug for File URI: For example: + * file:/C:/work/test.txt gives file:///C:/work/test.txt + * + * @param u - the File URI + * @return the String of the URI + */ + public static String toExternalForm(URI u) { + StringBuilder sb = new StringBuilder(); + if (u.getScheme() != null) { + sb.append(u.getScheme()); + sb.append(':'); + } + if (u.isOpaque()) { + sb.append(u.getSchemeSpecificPart()); + } else { + if (u.getHost() != null) { + sb.append("//"); + if (u.getUserInfo() != null) { + sb.append(u.getUserInfo()); + sb.append('@'); + } + boolean needBrackets = (u.getHost().indexOf(':') >= 0) && !u.getHost().startsWith("[") && !u.getHost().endsWith("]"); + if (needBrackets) + sb.append('['); + sb.append(u.getHost()); + if (needBrackets) + sb.append(']'); + if (u.getPort() != -1) { + sb.append(':'); + sb.append(u.getPort()); + } + } else if (u.getRawAuthority() != null) { + sb.append("//"); + sb.append(u.getRawAuthority()); + } else { + sb.append("//"); + } + if (u.getRawPath() != null) + sb.append(u.getRawPath()); + if (u.getRawQuery() != null) { + sb.append('?'); + sb.append(u.getRawQuery()); + } + } + if (u.getFragment() != null) { + sb.append('#'); + sb.append(u.getFragment()); + } + String ret = null; + try { + ret = new URI(sb.toString()).toASCIIString(); + } catch (URISyntaxException ex) { + LOGGER.error("Failed to parse URI", ex); + } + return ret; + } - private ResourceUtilities() { - } + private ResourceUtilities() { + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/UBLTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/UBLTest.java index 62122f6..cdcdd5a 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/UBLTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/UBLTest.java @@ -1,4 +1,3 @@ org.openrewrite.config.CompositeRecipe - /** * ********************************************************************* *

@@ -21,124 +20,118 @@ */ package org.mustangproject.ZUGFeRD; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.mustangproject.*; +import org.mustangproject.CII.CIIToUBL; + +import javax.xml.xpath.XPathExpressionException; import java.io.*; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Paths; +import java.nio.file.Path; import java.text.ParseException; import java.util.Date; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.mustangproject.BankDetails; -import org.mustangproject.CII.CIIToUBL; -import org.mustangproject.Contact; -import org.mustangproject.Invoice; -import org.mustangproject.Item; -import org.mustangproject.Product; -import org.mustangproject.TradeParty; - -import javax.xml.xpath.XPathExpressionException; - public class UBLTest extends ResourceCase { - final String TARGET_XML = "./target/testout-1Lieferschein.xml"; + final String TARGET_XML = "./target/testout-1Lieferschein.xml"; - public UBLTest() { - } + public UBLTest() { + } - @Test - @Order(2) - public void testUBLBasic() { + @Test + @Order(2) + public void testUBLBasic() { - // the writing part - final CIIToUBL c2u = new CIIToUBL(); - final String sourceFilename = "factur-x.xml"; - final File input = getResourceAsFile(sourceFilename); - final File expectedFile = getResourceAsFile("ubl-conv-ubl-output-factur-x.xml"); - String expected = null; - String result = null; - try { - final File tempFile = File.createTempFile("ZUGFeRD-UBL-", "-test"); - c2u.convert(input, tempFile); - expected = ResourceUtilities.readFile(StandardCharsets.UTF_8, expectedFile.getAbsolutePath()); - result = ResourceUtilities.readFile(StandardCharsets.UTF_8, tempFile.getAbsolutePath()); - } catch (final IOException e) { - fail("Exception should not happen: " + e.getMessage()); - } + // the writing part + final CIIToUBL c2u = new CIIToUBL(); + final String sourceFilename = "factur-x.xml"; + final File input = getResourceAsFile(sourceFilename); + final File expectedFile = getResourceAsFile("ubl-conv-ubl-output-factur-x.xml"); + String expected = null; + String result = null; + try { + final File tempFile = File.createTempFile("ZUGFeRD-UBL-", "-test"); + c2u.convert(input, tempFile); + expected = ResourceUtilities.readFile(StandardCharsets.UTF_8, expectedFile.getAbsolutePath()); + result = ResourceUtilities.readFile(StandardCharsets.UTF_8, tempFile.getAbsolutePath()); + } catch (final IOException e) { + fail("Exception should not happen: " + e.getMessage()); + } - assertNotNull(result); - Assertions.assertThat(result).isXmlEqualTo(expected); - } + assertNotNull(result); + Assertions.assertThat(result).isXmlEqualTo(expected); + } - @Test - @Order(1) - public void test1Lieferschein() { + @Test + @Order(1) + public void test1Lieferschein() { - final EinLieferscheinExporter oe = new EinLieferscheinExporter(); - final Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) - .setSender(new TradeParty("Test company", "teststr", "55232", "teststadt", "DE").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890", "COBADEFXXX"))) - .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")) - .setReferenceNumber("991-01484-64")//leitweg-id - .setNumber("123").addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), /*price*/ new BigDecimal("1.0"), /*qty*/ new BigDecimal("1.0")).addReferencedLineID("A12")); + final EinLieferscheinExporter oe = new EinLieferscheinExporter(); + final Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) + .setSender(new TradeParty("Test company", "teststr", "55232", "teststadt", "DE").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890", "COBADEFXXX"))) + .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")) + .setReferenceNumber("991-01484-64")// leitweg-id + .setNumber("123").addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO), /*price*/ new BigDecimal("1.0"), /*qty*/ new BigDecimal("1.0")).addReferencedLineID("A12")); - try { - oe.setTransaction(i); - final ByteArrayOutputStream baos=new ByteArrayOutputStream(); - oe.export(baos); + try { + oe.setTransaction(i); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + oe.export(baos); - final String theXML = baos.toString(StandardCharsets.UTF_8); - assertTrue(theXML.contains("")); + assertTrue(zi.getUTF8().contains("")); - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getInvoiceID(), "RE-20170509/505"); - assertEquals(zi.getZUGFeRDProfil(), "COMFORT"); - assertEquals(zi.getInvoiceCurrencyCode(), "EUR"); - assertEquals(zi.getIssuerAssignedID(),""); - assertEquals(zi.getIssueDate(), "20170509"); - assertEquals(zi.getTaxPointDate(), "20170507"); - assertEquals(zi.getPaymentTerms(), "Zahlbar ohne Abzug bis zum 30.05.2017"); - assertEquals(zi.getLineTotalAmount(), "496.00"); - assertEquals(zi.getTaxBasisTotalAmount(), "496.00"); - assertEquals(zi.getTaxTotalAmount(),"75.04"); - assertEquals(zi.getRoundingAmount(), ""); - assertEquals(zi.getPaidAmount(), "0.00"); - assertEquals(zi.getBuyerTradePartyName(), "Theodor Est"); - assertEquals(zi.getBuyerTradePartyGlobalID(), ""); - assertEquals(zi.getSellerTradePartyGlobalID(), ""); - assertEquals(zi.getBuyerTradePartyID(), "DE999999999"); - assertEquals(zi.getBuyertradePartySpecifiedTaxRegistrationID(), "DE999999999"); - assertEquals(zi.getIncludedNote(), ""); - assertEquals(zi.getDocumentCode(),"380"); - assertEquals(zi.getReference(),"AB321"); - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getBuyerTradePartyAddress().getPostcodeCode(), "88802"); - assertEquals(zi.getBuyerTradePartyAddress().getLineOne(), "Bahnstr. 42"); - assertEquals(zi.getBuyerTradePartyAddress().getLineTwo(), null); - assertEquals(zi.getBuyerTradePartyAddress().getLineThree(), null); - assertEquals(zi.getBuyerTradePartyAddress().getCountrySubDivisionName(), null); - assertEquals(zi.getBuyerTradePartyAddress().getCountryID(), "DE"); - assertEquals(zi.getBuyerTradePartyAddress().getCityName(), "Spielkreis"); - assertEquals(zi.getSellerTradePartyAddress().getPostcodeCode(), "12345"); - assertEquals(zi.getSellerTradePartyAddress().getLineOne(), "Ecke 12"); - assertEquals(zi.getSellerTradePartyAddress().getLineTwo(), null); - assertEquals(zi.getSellerTradePartyAddress().getLineThree(), null); - assertEquals(zi.getSellerTradePartyAddress().getCountrySubDivisionName(), null); - assertEquals(zi.getSellerTradePartyAddress().getCountryID(), "DE"); - assertEquals(zi.getSellerTradePartyAddress().getCityName(), "Stadthausen"); + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getInvoiceID(), "RE-20170509/505"); + assertEquals(zi.getZUGFeRDProfil(), "COMFORT"); + assertEquals(zi.getInvoiceCurrencyCode(), "EUR"); + assertEquals(zi.getIssuerAssignedID(),""); + assertEquals(zi.getIssueDate(), "20170509"); + assertEquals(zi.getTaxPointDate(), "20170507"); + assertEquals(zi.getPaymentTerms(), "Zahlbar ohne Abzug bis zum 30.05.2017"); + assertEquals(zi.getLineTotalAmount(), "496.00"); + assertEquals(zi.getTaxBasisTotalAmount(), "496.00"); + assertEquals(zi.getTaxTotalAmount(),"75.04"); + assertEquals(zi.getRoundingAmount(), ""); + assertEquals(zi.getPaidAmount(), "0.00"); + assertEquals(zi.getBuyerTradePartyName(), "Theodor Est"); + assertEquals(zi.getBuyerTradePartyGlobalID(), ""); + assertEquals(zi.getSellerTradePartyGlobalID(), ""); + assertEquals(zi.getBuyerTradePartyID(), "DE999999999"); + assertEquals(zi.getBuyertradePartySpecifiedTaxRegistrationID(), "DE999999999"); + assertEquals(zi.getIncludedNote(), ""); + assertEquals(zi.getDocumentCode(),"380"); + assertEquals(zi.getReference(),"AB321"); + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBuyerTradePartyAddress().getPostcodeCode(), "88802"); + assertEquals(zi.getBuyerTradePartyAddress().getLineOne(), "Bahnstr. 42"); + assertEquals(zi.getBuyerTradePartyAddress().getLineTwo(), null); + assertEquals(zi.getBuyerTradePartyAddress().getLineThree(), null); + assertEquals(zi.getBuyerTradePartyAddress().getCountrySubDivisionName(), null); + assertEquals(zi.getBuyerTradePartyAddress().getCountryID(), "DE"); + assertEquals(zi.getBuyerTradePartyAddress().getCityName(), "Spielkreis"); + assertEquals(zi.getSellerTradePartyAddress().getPostcodeCode(), "12345"); + assertEquals(zi.getSellerTradePartyAddress().getLineOne(), "Ecke 12"); + assertEquals(zi.getSellerTradePartyAddress().getLineTwo(), null); + assertEquals(zi.getSellerTradePartyAddress().getLineThree(), null); + assertEquals(zi.getSellerTradePartyAddress().getCountrySubDivisionName(), null); + assertEquals(zi.getSellerTradePartyAddress().getCountryID(), "DE"); + assertEquals(zi.getSellerTradePartyAddress().getCityName(), "Stadthausen"); - List li = zi.getLineItemList(); - assertEquals(zi.getLineItemList().get(0).getId().toString(), "1"); - assertEquals(zi.getLineItemList().get(0).getProduct().getBuyerAssignedID(), ""); - assertEquals(zi.getLineItemList().get(0).getProduct().getSellerAssignedID(), ""); - assertEquals(zi.getLineItemList().get(0).getLineTotalAmount().toString(), "160.00"); - assertEquals(zi.getLineItemList().get(0).getQuantity().toString(), "1.0000"); - assertEquals(zi.getLineItemList().get(0).getGrossPrice().toString(), "160.0000"); - assertEquals(zi.getLineItemList().get(0).getProduct().getVATPercent().toString(), "7.00"); - assertEquals(zi.getLineItemList().get(0).getProduct().getName(), "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung"); - assertEquals(zi.getLineItemList().get(0).getProduct().getDescription(), ""); + List li = zi.getLineItemList(); + assertEquals(zi.getLineItemList().get(0).getId().toString(), "1"); + assertEquals(zi.getLineItemList().get(0).getProduct().getBuyerAssignedID(), ""); + assertEquals(zi.getLineItemList().get(0).getProduct().getSellerAssignedID(), ""); + assertEquals(zi.getLineItemList().get(0).getLineTotalAmount().toString(), "160.00"); + assertEquals(zi.getLineItemList().get(0).getQuantity().toString(), "1.0000"); + assertEquals(zi.getLineItemList().get(0).getGrossPrice().toString(), "160.0000"); + assertEquals(zi.getLineItemList().get(0).getProduct().getVATPercent().toString(), "7.00"); + assertEquals(zi.getLineItemList().get(0).getProduct().getName(), "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung"); + assertEquals(zi.getLineItemList().get(0).getProduct().getDescription(), ""); - try { - assertEquals(zi.getVersion(), 2); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - }*/ - } + try { + assertEquals(zi.getVersion(), 2); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }*/ + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/VisualizationTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/VisualizationTest.java index f078467..bcc3a5b 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/VisualizationTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/VisualizationTest.java @@ -31,283 +31,283 @@ org.openrewrite.config.CompositeRecipe import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Paths; +import java.nio.file.Path; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class VisualizationTest extends ResourceCase { - final String TARGET_PDF_CII = "./target/testout-Visualization-cii.pdf"; - final String TARGET_PDF_UBL = "./target/testout-Visualization-cii.pdf"; + final String TARGET_PDF_CII = "./target/testout-Visualization-cii.pdf"; + final String TARGET_PDF_UBL = "./target/testout-Visualization-cii.pdf"; - public void testCIIVisualizationBasic() { + public void testCIIVisualizationBasic() { - // the writing part - String sourceFilename = "factur-x.xml"; - File CIIinputFile = getResourceAsFile(sourceFilename); + // the writing part + String sourceFilename = "factur-x.xml"; + File CIIinputFile = getResourceAsFile(sourceFilename); - String expected = null; - String result = null; - try { - ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); - /* remove file endings so that tests can also pass after checking - out from git with arbitrary options (which may include CSRF changes) - */ - result = zvi.visualize(CIIinputFile.getAbsolutePath(), ELanguage.FR); - Files.write(Paths.get("./target/testout-factur-x-vis.fr.html"), result.getBytes(StandardCharsets.UTF_8)); - result = result - .replace("\r", "") - .replace("\n", "") - .replace("\t", "") - .replace(" ", ""); + String expected = null; + String result = null; + try { + ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); + /* remove file endings so that tests can also pass after checking + out from git with arbitrary options (which may include CSRF changes) + */ + result = zvi.visualize(CIIinputFile.getAbsolutePath(), ELanguage.FR); + Files.write(Path.of("./target/testout-factur-x-vis.fr.html"), result.getBytes(StandardCharsets.UTF_8)); + result = result + .replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", ""); - File expectedResult = getResourceAsFile("factur-x-vis.fr.html"); - expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8) - .replace("\r", "") - .replace("\n", "") - .replace("\t", "") - .replace(" ", ""); - // remove linebreaks as well... + File expectedResult = getResourceAsFile("factur-x-vis.fr.html"); + expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8) + .replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", ""); + // remove linebreaks as well... - } catch (UnsupportedOperationException e) { - fail("UnsupportedOperationException should not happen: " + e.getMessage()); - } catch (IllegalArgumentException e) { - fail("IllegalArgumentException should not happen: " + e.getMessage()); - } catch (TransformerException e) { - fail("TransformerException should not happen: " + e.getMessage()); - } catch (IOException e) { - fail("IOException should not happen: " + e.getMessage()); - } catch (ParserConfigurationException e) { - fail("ParserConfigurationException should not happen: " + e.getMessage()); - } catch (SAXException e) { - fail("SAXException should not happen: " + e.getMessage()); - } + } catch (UnsupportedOperationException e) { + fail("UnsupportedOperationException should not happen: " + e.getMessage()); + } catch (IllegalArgumentException e) { + fail("IllegalArgumentException should not happen: " + e.getMessage()); + } catch (TransformerException e) { + fail("TransformerException should not happen: " + e.getMessage()); + } catch (IOException e) { + fail("IOException should not happen: " + e.getMessage()); + } catch (ParserConfigurationException e) { + fail("ParserConfigurationException should not happen: " + e.getMessage()); + } catch (SAXException e) { + fail("SAXException should not happen: " + e.getMessage()); + } - assertNotNull(result); - // Reading ZUGFeRD - assertEquals(expected, result); - } + assertNotNull(result); + // Reading ZUGFeRD + assertEquals(expected, result); + } - public void testCIIVisualizationExtended() { + public void testCIIVisualizationExtended() { - // the writing part - String sourceFilename = "factur-x-extended.xml"; - File CIIinputFile = getResourceAsFile(sourceFilename); + // the writing part + String sourceFilename = "factur-x-extended.xml"; + File CIIinputFile = getResourceAsFile(sourceFilename); - String expected = null; - String result = null; - try { - ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); - /* remove file endings so that tests can also pass after checking - out from git with arbitrary options (which may include CSRF changes) - */ - result = zvi.visualize(CIIinputFile.getAbsolutePath(), ELanguage.DE); - Files.write(Paths.get("./target/testout-factur-x-vis-extended.de.html"), result.getBytes(StandardCharsets.UTF_8)); - result = result - .replace("\r", "") - .replace("\n", "") - .replace("\t", "") - .replace(" ", ""); + String expected = null; + String result = null; + try { + ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); + /* remove file endings so that tests can also pass after checking + out from git with arbitrary options (which may include CSRF changes) + */ + result = zvi.visualize(CIIinputFile.getAbsolutePath(), ELanguage.DE); + Files.write(Path.of("./target/testout-factur-x-vis-extended.de.html"), result.getBytes(StandardCharsets.UTF_8)); + result = result + .replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", ""); - File expectedResult = getResourceAsFile("factur-x-vis-extended.de.html"); - expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8) - .replace("\r", "") - .replace("\n", "") - .replace("\t", "") - .replace(" ", ""); - // remove linebreaks as well... + File expectedResult = getResourceAsFile("factur-x-vis-extended.de.html"); + expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8) + .replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", ""); + // remove linebreaks as well... - } catch (UnsupportedOperationException e) { - fail("UnsupportedOperationException should not happen: " + e.getMessage()); - } catch (IllegalArgumentException e) { - fail("IllegalArgumentException should not happen: " + e.getMessage()); - } catch (TransformerException e) { - fail("TransformerException should not happen: " + e.getMessage()); - } catch (IOException e) { - fail("IOException should not happen: " + e.getMessage()); - } catch (ParserConfigurationException e) { - fail("ParserConfigurationException should not happen: " + e.getMessage()); - } catch (SAXException e) { - fail("SAXException should not happen: " + e.getMessage()); - } + } catch (UnsupportedOperationException e) { + fail("UnsupportedOperationException should not happen: " + e.getMessage()); + } catch (IllegalArgumentException e) { + fail("IllegalArgumentException should not happen: " + e.getMessage()); + } catch (TransformerException e) { + fail("TransformerException should not happen: " + e.getMessage()); + } catch (IOException e) { + fail("IOException should not happen: " + e.getMessage()); + } catch (ParserConfigurationException e) { + fail("ParserConfigurationException should not happen: " + e.getMessage()); + } catch (SAXException e) { + fail("SAXException should not happen: " + e.getMessage()); + } - assertNotNull(result); - // Reading ZUGFeRD - assertEquals(expected, result); - } + assertNotNull(result); + // Reading ZUGFeRD + assertEquals(expected, result); + } - public void testUBLCreditNoteVisualizationBasic() { + public void testUBLCreditNoteVisualizationBasic() { - // the writing part - File UBLinputFile = getResourceAsFile("ubl-creditnote.xml"); + // the writing part + File UBLinputFile = getResourceAsFile("ubl-creditnote.xml"); - String expected = null; - String result = null; - try { - ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); - /* remove file endings so that tests can also pass after checking - out from git with arbitrary options (which may include CSRF changes) - */ - result = zvi.visualize(UBLinputFile.getAbsolutePath(), ELanguage.EN); - Files.write(Paths.get("./target/testout-factur-x-vis-ubl-creditnote.en.html"), result.getBytes(StandardCharsets.UTF_8)); - result = result - .replace("\r", "") - .replace("\n", "") - .replace("\t", "") - .replace(" ", ""); + String expected = null; + String result = null; + try { + ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); + /* remove file endings so that tests can also pass after checking + out from git with arbitrary options (which may include CSRF changes) + */ + result = zvi.visualize(UBLinputFile.getAbsolutePath(), ELanguage.EN); + Files.write(Path.of("./target/testout-factur-x-vis-ubl-creditnote.en.html"), result.getBytes(StandardCharsets.UTF_8)); + result = result + .replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", ""); - File expectedResult = getResourceAsFile("factur-x-vis-ubl-creditnote.en.html"); - expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8) - .replace("\r", "") - .replace("\n", "") - .replace("\t", "") - .replace(" ", ""); - // remove linebreaks as well... + File expectedResult = getResourceAsFile("factur-x-vis-ubl-creditnote.en.html"); + expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8) + .replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", ""); + // remove linebreaks as well... - } catch (UnsupportedOperationException e) { - fail("UnsupportedOperationException should not happen: " + e.getMessage()); - } catch (IllegalArgumentException e) { - fail("IllegalArgumentException should not happen: " + e.getMessage()); - } catch (TransformerException e) { - fail("TransformerException should not happen: " + e.getMessage()); - } catch (IOException e) { - fail("IOException should not happen: " + e.getMessage()); - } catch (ParserConfigurationException e) { - fail("ParserConfigurationException should not happen: " + e.getMessage()); - } catch (SAXException e) { - fail("SAXException should not happen: " + e.getMessage()); - } + } catch (UnsupportedOperationException e) { + fail("UnsupportedOperationException should not happen: " + e.getMessage()); + } catch (IllegalArgumentException e) { + fail("IllegalArgumentException should not happen: " + e.getMessage()); + } catch (TransformerException e) { + fail("TransformerException should not happen: " + e.getMessage()); + } catch (IOException e) { + fail("IOException should not happen: " + e.getMessage()); + } catch (ParserConfigurationException e) { + fail("ParserConfigurationException should not happen: " + e.getMessage()); + } catch (SAXException e) { + fail("SAXException should not happen: " + e.getMessage()); + } - assertNotNull(result); - // Reading ZUGFeRD - assertEquals(expected, result); - } + assertNotNull(result); + // Reading ZUGFeRD + assertEquals(expected, result); + } - public void testUBLVisualizationBasic() { + public void testUBLVisualizationBasic() { - // the writing part - File UBLinputFile = getResourceAsFile("ubl/01.01a-INVOICE.ubl.xml"); + // the writing part + File UBLinputFile = getResourceAsFile("ubl/01.01a-INVOICE.ubl.xml"); - String expected = null; - String result = null; - try { - ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); - /* remove file endings so that tests can also pass after checking - out from git with arbitrary options (which may include CSRF changes) - */ - result = zvi.visualize(UBLinputFile.getAbsolutePath(), ELanguage.EN); - Files.write(Paths.get("./target/testout-factur-x-vis-ubl.en.html"), result.getBytes(StandardCharsets.UTF_8)); - result = result - .replace("\r", "") - .replace("\n", "") - .replace("\t", "") - .replace(" ", ""); + String expected = null; + String result = null; + try { + ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); + /* remove file endings so that tests can also pass after checking + out from git with arbitrary options (which may include CSRF changes) + */ + result = zvi.visualize(UBLinputFile.getAbsolutePath(), ELanguage.EN); + Files.write(Path.of("./target/testout-factur-x-vis-ubl.en.html"), result.getBytes(StandardCharsets.UTF_8)); + result = result + .replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", ""); - File expectedResult = getResourceAsFile("factur-x-vis-ubl.en.html"); - expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8) - .replace("\r", "") - .replace("\n", "") - .replace("\t", "") - .replace(" ", ""); - // remove linebreaks as well... + File expectedResult = getResourceAsFile("factur-x-vis-ubl.en.html"); + expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8) + .replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", ""); + // remove linebreaks as well... - } catch (UnsupportedOperationException e) { - fail("UnsupportedOperationException should not happen: " + e.getMessage()); - } catch (IllegalArgumentException e) { - fail("IllegalArgumentException should not happen: " + e.getMessage()); - } catch (TransformerException e) { - fail("TransformerException should not happen: " + e.getMessage()); - } catch (IOException e) { - fail("IOException should not happen: " + e.getMessage()); - } catch (ParserConfigurationException e) { - fail("ParserConfigurationException should not happen: " + e.getMessage()); - } catch (SAXException e) { - fail("SAXException should not happen: " + e.getMessage()); - } + } catch (UnsupportedOperationException e) { + fail("UnsupportedOperationException should not happen: " + e.getMessage()); + } catch (IllegalArgumentException e) { + fail("IllegalArgumentException should not happen: " + e.getMessage()); + } catch (TransformerException e) { + fail("TransformerException should not happen: " + e.getMessage()); + } catch (IOException e) { + fail("IOException should not happen: " + e.getMessage()); + } catch (ParserConfigurationException e) { + fail("ParserConfigurationException should not happen: " + e.getMessage()); + } catch (SAXException e) { + fail("SAXException should not happen: " + e.getMessage()); + } - assertNotNull(result); - // Reading ZUGFeRD - assertEquals(expected, result); - } + assertNotNull(result); + // Reading ZUGFeRD + assertEquals(expected, result); + } - public void testPDFVisualizationCII() { + public void testPDFVisualizationCII() { - File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml"); + File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml"); - // the writing part + // the writing part - String expected = null; - String result = null; - try { - ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); - zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII); - } catch (UnsupportedOperationException e) { - fail("UnsupportedOperationException should not happen: " + e.getMessage()); - } catch (IllegalArgumentException e) { - fail("IllegalArgumentException should not happen: " + e.getMessage()); - } + String expected = null; + String result = null; + try { + ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); + zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII); + } catch (UnsupportedOperationException e) { + fail("UnsupportedOperationException should not happen: " + e.getMessage()); + } catch (IllegalArgumentException e) { + fail("IllegalArgumentException should not happen: " + e.getMessage()); + } - try { - assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'})); - } catch (IOException e) { - fail("IOException should not occur"); - } - } + try { + assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Path.of(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'})); + } catch (IOException e) { + fail("IOException should not occur"); + } + } - public void testPDFVisualizationUBL() { + public void testPDFVisualizationUBL() { - File UBLinputFile = getResourceAsFile("ubl/01.01a-INVOICE.ubl.xml"); + File UBLinputFile = getResourceAsFile("ubl/01.01a-INVOICE.ubl.xml"); - // the writing part - String sourceFilename = "factur-x.xml"; + // the writing part + String sourceFilename = "factur-x.xml"; - String expected = null; - String result = null; - try { - ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); - zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL); - } catch (UnsupportedOperationException e) { - fail("UnsupportedOperationException should not happen: " + e.getMessage()); - } catch (IllegalArgumentException e) { - fail("IllegalArgumentException should not happen: " + e.getMessage()); - } + String expected = null; + String result = null; + try { + ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); + zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL); + } catch (UnsupportedOperationException e) { + fail("UnsupportedOperationException should not happen: " + e.getMessage()); + } catch (IllegalArgumentException e) { + fail("IllegalArgumentException should not happen: " + e.getMessage()); + } - try { - assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'})); - } catch (IOException e) { - fail("IOException should not occur"); - } - } + try { + assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Path.of(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'})); + } catch (IOException e) { + fail("IOException should not occur"); + } + } - public void testPDFVisualizationUBLCreditNote() { + public void testPDFVisualizationUBLCreditNote() { - File UBLinputFile = getResourceAsFile("ubl/UBL-CreditNote-2.1-Example.ubl.xml"); + File UBLinputFile = getResourceAsFile("ubl/UBL-CreditNote-2.1-Example.ubl.xml"); - // the writing part - String sourceFilename = "factur-x.xml"; + // the writing part + String sourceFilename = "factur-x.xml"; - String expected = null; - String result = null; - try { - ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); - zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL); - } catch (UnsupportedOperationException e) { - fail("UnsupportedOperationException should not happen: " + e.getMessage()); - } catch (IllegalArgumentException e) { - fail("IllegalArgumentException should not happen: " + e.getMessage()); - } + String expected = null; + String result = null; + try { + ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); + zvi.toPDF(UBLinputFile.getAbsolutePath(), TARGET_PDF_UBL); + } catch (UnsupportedOperationException e) { + fail("UnsupportedOperationException should not happen: " + e.getMessage()); + } catch (IllegalArgumentException e) { + fail("IllegalArgumentException should not happen: " + e.getMessage()); + } - try { - assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'})); - } catch (IOException e) { - fail("IOException should not occur"); - } - } + try { + assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Path.of(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'})); + } catch (IOException e) { + fail("IOException should not occur"); + } + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java index 3efa4cc..1e3ae13 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java @@ -1,4 +1,3 @@ org.openrewrite.config.CompositeRecipe - /** * ********************************************************************* *

@@ -22,10 +21,9 @@ package org.mustangproject.ZUGFeRD; import junit.framework.TestCase; -import org.mustangproject.*; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; - +import org.mustangproject.*; import javax.xml.xpath.XPathExpressionException; import java.io.BufferedWriter; @@ -36,155 +34,154 @@ import java.text.ParseException; import java.util.Arrays; import java.util.Date; -import java.util.List; import static org.xmlunit.assertj.XmlAssert.assertThat; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class XRTest extends TestCase { - final String TARGET_XML = "./target/testout-XR.xml"; - final String TARGET_EDGE_XML = "./target/testout-XR-Edge.xml"; + final String TARGET_XML = "./target/testout-XR.xml"; + final String TARGET_EDGE_XML = "./target/testout-XR-Edge.xml"; - public void testXRExport() { + public void testXRExport() { - // the writing part - TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); - recipient.setEmail("quack@ducktown.org"); - Invoice i = createInvoice(recipient); + // the writing part + TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE"); + recipient.setEmail("quack@ducktown.org"); + Invoice i = createInvoice(recipient); - ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); - zf2p.setProfile(Profiles.getByName("XRechnung")); - zf2p.generateXML(i); - String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8); - assertTrue(theXML.contains("59")); - assertTrue(resultXML.contains("")); - assertTrue(resultXML.contains("DE540815")); - assertTrue(resultXML.contains("DE99XX12345")); - assertTrue(resultXML.contains("")); - assertFalse(resultXML.contains("EUR")); - assertTrue(resultXML.contains("USD"));//currency should be USD, test for #150 - assertTrue(resultXML.contains("")); - assertTrue(resultXML.contains("123")); + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + String resultXML = zi.getUTF8(); + assertTrue(resultXML.contains("59")); + assertTrue(resultXML.contains("")); + assertTrue(resultXML.contains("DE540815")); + assertTrue(resultXML.contains("DE99XX12345")); + assertTrue(resultXML.contains("")); + assertFalse(resultXML.contains("EUR")); + assertTrue(resultXML.contains("USD"));// currency should be USD, test for #150 + assertTrue(resultXML.contains("")); + assertTrue(resultXML.contains("123")); - // Reading ZUGFeRD - assertEquals("337.60", zi.getAmount()); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getForeignReference(), getNumber()); - try { - assertEquals(zi.getVersion(), 2); - } catch (Exception e) { - e.printStackTrace(); - } + // Reading ZUGFeRD + assertEquals("337.60", zi.getAmount()); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); + try { + assertEquals(zi.getVersion(), 2); + } catch (Exception e) { + e.printStackTrace(); + } - } + } - /** - * The exporter test bases on @{code - * ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds - * metadata, writes to @{code ./target/testout-*} and then imports to check the - * values. - */ - public void testOutputStreamExport() { + /** + * The exporter test bases on @{code + * ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds + * metadata, writes to @{code ./target/testout-*} and then imports to check the + * values. + */ + public void testOutputStreamExport() { - // the writing part + // the writing part - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"); IZUGFeRDExporter ze = new ZUGFeRDExporterFromA3().setProducer("My Application") - .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).disableFacturX() - .load(SOURCE_PDF)) { - ze.setTransaction(this); - String theXML = new String(ze.getProvider().getXML(), StandardCharsets.UTF_8); - assertTrue(theXML.contains(" @@ -21,8 +20,15 @@ */ package org.mustangproject.ZUGFeRD; +import junit.framework.TestCase; +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; +import org.mustangproject.*; +import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; +import org.mustangproject.ZUGFeRD.model.EventTimeCodeTypeConstants; + +import javax.xml.xpath.XPathExpressionException; import java.io.ByteArrayInputStream; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; @@ -30,778 +36,766 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; - -import org.mustangproject.*; -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -import junit.framework.TestCase; - -import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; -import org.mustangproject.ZUGFeRD.model.EventTimeCodeTypeConstants; - -import javax.xml.xpath.XPathExpressionException; import static org.xmlunit.assertj.XmlAssert.assertThat; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class ZF2PushTest extends TestCase { - final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20201121_508.pdf"; - final String TARGET_ALLOWANCESPDF = "./target/testout-ZF2PushAllowances.pdf"; - final String TARGET_CREDITNOTEPDF = "./target/testout-ZF2PushCreditNote.pdf"; - final String TARGET_CORRECTIONPDF = "./target/testout-ZF2PushCorrection.pdf"; - final String TARGET_ITEMCHARGESALLOWANCESPDF = "./target/testout-ZF2PushItemChargesAllowances.pdf"; - final String TARGET_CHARGESALLOWANCESPDF = "./target/testout-ZF2PushChargesAllowances.pdf"; - final String TARGET_RELATIVECHARGESALLOWANCESPDF = "./target/testout-ZF2PushRelativeChargesAllowances.pdf"; - final String TARGET_ATTACHMENTSPDF = "./target/testout-ZF2PushAttachments.pdf"; - final String TARGET_BANKPDF = "./target/testout-ZF2PushBank.pdf"; - final String TARGET_PUSHEDGE = "./target/testout-ZF2PushEdge.pdf"; - final String TARGET_INTRACOMMUNITYSUPPLYMANUALPDF = "./target/testout-ZF2PushIntraCommunitySupplyManual.pdf"; - final String TARGET_INTRACOMMUNITYSUPPLYPDF = "./target/testout-ZF2PushIntraCommunitySupply.pdf"; - final String TARGET_REVERSECHARGEPDF = "./target/testout-ZF2PushReverseCharge.pdf"; + final String TARGET_PDF = "./target/testout-MustangGnuaccountingBeispielRE-20201121_508.pdf"; + final String TARGET_ALLOWANCESPDF = "./target/testout-ZF2PushAllowances.pdf"; + final String TARGET_CREDITNOTEPDF = "./target/testout-ZF2PushCreditNote.pdf"; + final String TARGET_CORRECTIONPDF = "./target/testout-ZF2PushCorrection.pdf"; + final String TARGET_ITEMCHARGESALLOWANCESPDF = "./target/testout-ZF2PushItemChargesAllowances.pdf"; + final String TARGET_CHARGESALLOWANCESPDF = "./target/testout-ZF2PushChargesAllowances.pdf"; + final String TARGET_RELATIVECHARGESALLOWANCESPDF = "./target/testout-ZF2PushRelativeChargesAllowances.pdf"; + final String TARGET_ATTACHMENTSPDF = "./target/testout-ZF2PushAttachments.pdf"; + final String TARGET_BANKPDF = "./target/testout-ZF2PushBank.pdf"; + final String TARGET_PUSHEDGE = "./target/testout-ZF2PushEdge.pdf"; + final String TARGET_INTRACOMMUNITYSUPPLYMANUALPDF = "./target/testout-ZF2PushIntraCommunitySupplyManual.pdf"; + final String TARGET_INTRACOMMUNITYSUPPLYPDF = "./target/testout-ZF2PushIntraCommunitySupply.pdf"; + 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?) - */ - // the writing part - String orgname = "Bei Spiel GmbH"; - String number = "RE-20201121/508"; - String priceStr = "160.00"; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + public void testPushExport() { + /*** + * 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"; + String priceStr = "160.00"; + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - BigDecimal price = new BigDecimal(priceStr); - try { - InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20201121_508blanko.pdf"); + BigDecimal price = new BigDecimal(priceStr); + try { + InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20201121_508blanko.pdf"); - ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1(); - ze.ignorePDFAErrors(); - ze.load(SOURCE_PDF); - ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2); - ze.setTransaction(new Invoice().setDueDate(sdf.parse("2020-12-12")).setIssueDate(sdf.parse("2020-11-21")).setDeliveryDate(sdf.parse("2020-11-10")) - .setSender(new TradeParty(orgname, "Ecke 12", "12345", "Stadthausen", "DE").addBankDetails(new BankDetails("DE88200800000970375700", "COBADEFFXXX").setAccountName("Max Mustermann")).addVATID("DE136695976")) - .setRecipient(new TradeParty("Theodor Est", "Bahnstr. 42", "88802", "Spielkreis", "DE") - .setContact(new Contact("Ingmar N. Fo", "(555) 23 78-23", "info@localhost.local")).setID("2")) - .setNumber(number) - .setReferenceNumber("AB321") - .addItem(new Item(new Product("Design (hours)", "Of a sample invoice", "HUR", new BigDecimal(7)), price, new BigDecimal(1.0))) - .addItem(new Item(new Product("Ballons", "various colors, ~2000ml", "H87", new BigDecimal(19)), new BigDecimal("0.79"), new BigDecimal(400.0))) - .addItem(new Item(new Product("Hot air „heiße Luft“ (litres)", "", "LTR", new BigDecimal(19)), new BigDecimal("0.025"), new BigDecimal(800.0))) - .setRoundingAmount(new BigDecimal("1")) - ); + ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1(); + ze.ignorePDFAErrors(); + ze.load(SOURCE_PDF); + ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2); + ze.setTransaction(new Invoice().setDueDate(sdf.parse("2020-12-12")).setIssueDate(sdf.parse("2020-11-21")).setDeliveryDate(sdf.parse("2020-11-10")) + .setSender(new TradeParty(orgname, "Ecke 12", "12345", "Stadthausen", "DE").addBankDetails(new BankDetails("DE88200800000970375700", "COBADEFFXXX").setAccountName("Max Mustermann")).addVATID("DE136695976")) + .setRecipient(new TradeParty("Theodor Est", "Bahnstr. 42", "88802", "Spielkreis", "DE") + .setContact(new Contact("Ingmar N. Fo", "(555) 23 78-23", "info@localhost.local")).setID("2")) + .setNumber(number) + .setReferenceNumber("AB321") + .addItem(new Item(new Product("Design (hours)", "Of a sample invoice", "HUR", new BigDecimal(7)), price, new BigDecimal(1.0))) + .addItem(new Item(new Product("Ballons", "various colors, ~2000ml", "H87", new BigDecimal(19)), new BigDecimal("0.79"), new BigDecimal(400.0))) + .addItem(new Item(new Product("Hot air „heiße Luft“ (litres)", "", "LTR", new BigDecimal(19)), new BigDecimal("0.025"), new BigDecimal(800.0))) + .setRoundingAmount(new BigDecimal("1")) + ); - ze.export(TARGET_PDF); - } catch (IOException | ParseException e) { - fail("Exception should not be raised"); - } + ze.export(TARGET_PDF); + } catch (IOException | ParseException e) { + fail("Exception should not be raised"); + } - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF); - Invoice i = new Invoice(); - try { - zii.extractInto(i); - } catch (XPathExpressionException e) { - throw new RuntimeException(e); - } catch (ParseException e) { - throw new RuntimeException(e); - } + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF); + Invoice i = new Invoice(); + try { + zii.extractInto(i); + } catch (XPathExpressionException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); + } - // now check the contents (like MustangReaderTest) - ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); - assertTrue(zi.getUTF8().contains("DE88200800000970375700")); //the iban - assertTrue(zi.getUTF8().contains("Max Mustermann")); //account holder - assertTrue(zi.getUTF8().contains("DueDateDateTime")); //account holder - assertTrue(zi.getUTF8().contains("20201212")); //account holder + // now check the contents (like MustangReaderTest) + ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF); + assertTrue(zi.getUTF8().contains("DE88200800000970375700")); // the iban + assertTrue(zi.getUTF8().contains("Max Mustermann")); // account holder + assertTrue(zi.getUTF8().contains("DueDateDateTime")); // account holder + assertTrue(zi.getUTF8().contains("20201212")); // account holder - assertTrue(zi.getUTF8().contains("")); // maybe add a direct debit mandate to the class in the future then this would fail - assertTrue(zi.getUTF8().contains("Hinterhaus")); - assertThat(zi.getUTF8()).valueByXPath("//*[local-name()='BuyerTradeParty']/*[local-name()='GlobalID'][@schemeID=0088]").asString().isEqualTo("4304171000002"); - assertThat(zi.getUTF8()).valueByXPath("//*[local-name()='SpecifiedTradeProduct']/*[local-name()='GlobalID'][@schemeID=0160]").asString().isEqualTo("2001015001325"); - assertTrue(zi.getUTF8().contains("2001015001325")); - assertTrue(zi.getUTF8().contains("4304171000002")); - assertTrue(zi.getUTF8().contains("0088")); - assertTrue(zi.getUTF8().contains(orgID)); - assertTrue(zi.getUTF8().contains("ram:BuyerOrderReferencedDocument")); - 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 + assertFalse(zi.getUTF8().contains("")); // maybe add a direct debit mandate to the class in the future then this would fail + assertTrue(zi.getUTF8().contains("Hinterhaus")); + assertThat(zi.getUTF8()).valueByXPath("//*[local-name()='BuyerTradeParty']/*[local-name()='GlobalID'][@schemeID=0088]").asString().isEqualTo("4304171000002"); + assertThat(zi.getUTF8()).valueByXPath("//*[local-name()='SpecifiedTradeProduct']/*[local-name()='GlobalID'][@schemeID=0160]").asString().isEqualTo("2001015001325"); + assertTrue(zi.getUTF8().contains("2001015001325")); + assertTrue(zi.getUTF8().contains("4304171000002")); + assertTrue(zi.getUTF8().contains("0088")); + assertTrue(zi.getUTF8().contains(orgID)); + assertTrue(zi.getUTF8().contains("ram:BuyerOrderReferencedDocument")); + 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 - assertTrue(zi.getUTF8().contains("item level 1/1")); - assertTrue(zi.getUTF8().contains("DE4711")); // the VAT ID should be there... - assertFalse(zi.getUTF8().contains("DE47110")); // but not the VAT ID of the shiptotradeparty - assertTrue(zi.getUTF8().contains("document level 2/2")); - assertTrue(zi.getUTF8().contains("++49555123456")); - assertTrue(zi.getUTF8().contains("Cash Discount")); // default description for cash discounts - assertThat(zi.getUTF8()).valueByXPath("//*[local-name()='ApplicableTradeTax']/*[local-name()='DueDateTypeCode']").asString().isEqualTo(EventTimeCodeTypeConstants.PAYMENT_DATE); + assertTrue(zi.getUTF8().contains("item level 1/1")); + assertTrue(zi.getUTF8().contains("DE4711")); // the VAT ID should be there... + assertFalse(zi.getUTF8().contains("DE47110")); // but not the VAT ID of the shiptotradeparty + assertTrue(zi.getUTF8().contains("document level 2/2")); + assertTrue(zi.getUTF8().contains("++49555123456")); + assertTrue(zi.getUTF8().contains("Cash Discount")); // default description for cash discounts + assertThat(zi.getUTF8()).valueByXPath("//*[local-name()='ApplicableTradeTax']/*[local-name()='DueDateTypeCode']").asString().isEqualTo(EventTimeCodeTypeConstants.PAYMENT_DATE); - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PUSHEDGE); - try { - Invoice i = zii.extractInvoice(); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PUSHEDGE); + try { + Invoice i = zii.extractInvoice(); - assertEquals("abc123", i.getInvoiceReferencedDocumentID()); - assertEquals("4304171000002", i.getRecipient().getGlobalID()); - assertEquals("2001015001325", i.getZFItems()[0].getProduct().getGlobalID()); - assertEquals(orgID, i.getSender().getID()); + assertEquals("abc123", i.getInvoiceReferencedDocumentID()); + assertEquals("4304171000002", i.getRecipient().getGlobalID()); + assertEquals("2001015001325", i.getZFItems()[0].getProduct().getGlobalID()); + assertEquals(orgID, i.getSender().getID()); - } catch (XPathExpressionException e) { - fail("XPathExpressionException should not be raised"); - } catch (ParseException e) { - fail("ParseException should not be raised"); - /* a parseException would also be fired if the calculated grand total does not - match the read grand total */ - } - } + } catch (XPathExpressionException e) { + fail("XPathExpressionException should not be raised"); + } catch (ParseException e) { + fail("ParseException should not be raised"); + /* a parseException would also be fired if the calculated grand total does not + match the read grand total */ + } + } - public void testAllowancesExport() { + public void testAllowancesExport() { - String orgname = "Test company"; - String number = "123"; - BigDecimal qty = new BigDecimal("20"); - try { - InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); + String orgname = "Test company"; + String number = "123"; + BigDecimal qty = new BigDecimal("20"); + try { + InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); - ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1(); - ze.ignorePDFAErrors().load(SOURCE_PDF); + ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1(); + ze.ignorePDFAErrors().load(SOURCE_PDF); - ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("en16931")); + ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("en16931")); - ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) - .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")) - .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")) - .setNumber(number) - .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal(500.0), qty).addAllowance(new Allowance(new BigDecimal(300)).setTaxPercent(new BigDecimal(19)))) - .addAllowance(new Allowance(new BigDecimal(600)).setTaxPercent(new BigDecimal(19))) - ); - String theXML = new String(ze.getProvider().getXML()); - assertTrue(theXML.contains(" @@ -21,6 +20,11 @@ */ package org.mustangproject.ZUGFeRD; +import junit.framework.Test; +import junit.framework.TestSuite; +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; @@ -30,284 +34,278 @@ import java.util.GregorianCalendar; import java.util.List; -import junit.framework.Test; -import junit.framework.TestSuite; - -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class ZF2Test extends MustangReaderTestCase { - final String TARGET_PDF = "./target/testout-ZF2new.pdf"; + final String TARGET_PDF = "./target/testout-ZF2new.pdf"; - @Override - public Date getDeliveryDate() { - return new GregorianCalendar(2017, Calendar.MAY, 7).getTime(); - } + @Override + public Date getDeliveryDate() { + return new GregorianCalendar(2017, Calendar.MAY, 7).getTime(); + } - @Override - public Date getDueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); - } + @Override + public Date getDueDate() { + return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); + } - @Override - public Date getIssueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); - } + @Override + public Date getIssueDate() { + return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); + } - @Override - public String getNumber() { - return "RE-20170509/505"; - } + @Override + public String getNumber() { + return "RE-20170509/505"; + } - @Override - public IZUGFeRDExportableTradeParty getSender() { - return new SenderTradeParty(); + @Override + public IZUGFeRDExportableTradeParty getSender() { + return new SenderTradeParty(); - } + } - @Override - public String getOwnTaxID() { - return "22/815/0815/4"; - } + @Override + public String getOwnTaxID() { + return "22/815/0815/4"; + } - @Override - public String getOwnVATID() { - return "DE136695976"; - } + @Override + public String getOwnVATID() { + return "DE136695976"; + } - @Override - public String getOwnZIP() { - return "12345"; - } + @Override + public String getOwnZIP() { + return "12345"; + } - @Override - public IZUGFeRDExportableTradeParty getRecipient() { - return new RecipientTradeParty(); - } + @Override + public IZUGFeRDExportableTradeParty getRecipient() { + return new RecipientTradeParty(); + } - @Override - public String getOwnOrganisationFullPlaintextInfo() { - return null; - } + @Override + public String getOwnOrganisationFullPlaintextInfo() { + return null; + } - @Override - public String getCurrency() { - return "EUR"; - } + @Override + public String getCurrency() { + return "EUR"; + } - @Override - public IZUGFeRDExportableItem[] getZFItems() { - final Item[] allItems = new Item[3]; - final Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", - new BigDecimal("7.000000")); - final Product balloonProduct = new Product("", "Bestellerweiterung für E&F Umbau", "C62", - new BigDecimal("19.000000"));// test for issue 103 - final Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000")); + @Override + public IZUGFeRDExportableItem[] getZFItems() { + final Item[] allItems = new Item[3]; + final Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", + new BigDecimal("7.000000")); + final Product balloonProduct = new Product("", "Bestellerweiterung für E&F Umbau", "C62", + new BigDecimal("19.000000"));// test for issue 103 + final Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000")); - allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); - allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); - allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); - return allItems; - } + allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); + allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct); + allItems[2] = new Item(new BigDecimal("0.10"), new BigDecimal("200"), airProduct); + return allItems; + } - @Override - public String getPaymentTermDescription() { - final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); - } + @Override + public String getPaymentTermDescription() { + final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); + return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); + } - @Override - public IZUGFeRDAllowanceCharge[] getZFAllowances() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFAllowances() { + return null; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFCharges() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFCharges() { + return null; + } - @Override - public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - return null; - } + @Override + public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { + return null; + } - @Override - public String getReferenceNumber() { - return "AB321"; - } + @Override + public String getReferenceNumber() { + return "AB321"; + } - /** - * Create the test case - * - * @param testName name of the test case - */ - public ZF2Test(String testName) { - super(testName); - } + /** + * Create the test case + * + * @param testName name of the test case + */ + public ZF2Test(String testName) { + super(testName); + } - /** - * @return the suite of tests being tested - */ - public static Test suite() { - return new TestSuite(ZF2Test.class); - } + /** + * @return the suite of tests being tested + */ + public static Test suite() { + return new TestSuite(ZF2Test.class); + } - // //////// TESTS - // ////////////////////////////////////////////////////////////////////////////////////////// + // //////// TESTS + // ////////////////////////////////////////////////////////////////////////////////////////// - /** - * The exporter test bases on @{code - * ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds - * metadata, writes to @{code ./target/testout-*} and then imports to check the - * values. - */ - public void testExport() { + /** + * The exporter test bases on @{code + * ./src/test/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf}, adds + * metadata, writes to @{code ./target/testout-*} and then imports to check the + * values. + */ + public void testExport() { - // the writing part + // the writing part - try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"); + try (InputStream SOURCE_PDF = this.getClass() + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"); ZUGFeRDExporterFromA3 ze = new ZUGFeRDExporterFromA3().setProducer("My Application") - .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("EN16931") - .load(SOURCE_PDF)) { + .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("EN16931") + .load(SOURCE_PDF)) { - ze.setTransaction(this); - final String theXML = new String(ze.getProvider().getXML()); - assertTrue(theXML.contains("")); + assertTrue(zi.getUTF8().contains("")); - // Reading ZUGFeRD - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getInvoiceID(), "RE-20170509/505"); - assertEquals(zi.getZUGFeRDProfil(), "COMFORT"); - assertEquals(zi.getInvoiceCurrencyCode(), "EUR"); - assertEquals(zi.getIssuerAssignedID(), ""); - assertEquals(zi.getIssueDate(), "20170509"); - assertEquals(zi.getTaxPointDate(), "20170507"); - assertEquals(zi.getPaymentTerms(), "Zahlbar ohne Abzug bis zum 30.05.2017"); - assertEquals(zi.getLineTotalAmount(), "496.00"); - assertEquals(zi.getTaxBasisTotalAmount(), "496.00"); - assertEquals(zi.getTaxTotalAmount(), "75.04"); - assertEquals(zi.getRoundingAmount(), ""); - assertEquals(zi.getPaidAmount(), "0.00"); - assertEquals(zi.getBuyerTradePartyName(), "Theodor Est"); - assertEquals(zi.getBuyerTradePartyGlobalID(), ""); - assertEquals(zi.getSellerTradePartyGlobalID(), ""); - assertEquals(zi.getBuyerTradePartyID(), "DE999999999"); - assertEquals(zi.getBuyertradePartySpecifiedTaxRegistrationID(), "DE999999999"); - assertEquals(zi.getIncludedNote(), ""); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getDocumentCode(), "380"); - assertEquals(zi.getReference(), "AB321"); - assertEquals(zi.getAmount(), "571.04"); - assertEquals(zi.getBIC(), "COBADEFFXXX"); - assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getForeignReference(), getNumber()); - assertEquals(zi.getBuyerTradePartyAddress().getPostcodeCode(), "88802"); - assertEquals(zi.getBuyerTradePartyAddress().getLineOne(), "Bahnstr. 42"); - assertEquals(zi.getBuyerTradePartyAddress().getLineTwo(), "Hinterhaus"); - assertEquals(zi.getBuyerTradePartyAddress().getLineThree(), "Zweiter Stock"); - assertEquals(zi.getBuyerTradePartyAddress().getCountrySubDivisionName(), null); - assertEquals(zi.getBuyerTradePartyAddress().getCountryID(), "DE"); - assertEquals(zi.getBuyerTradePartyAddress().getCityName(), "Spielkreis"); - assertEquals(zi.getSellerTradePartyAddress().getPostcodeCode(), "12345"); - assertEquals(zi.getSellerTradePartyAddress().getLineOne(), "Ecke 12"); - assertEquals(zi.getSellerTradePartyAddress().getLineTwo(), null); - assertEquals(zi.getSellerTradePartyAddress().getLineThree(), null); - assertEquals(zi.getSellerTradePartyAddress().getCountrySubDivisionName(), null); - assertEquals(zi.getSellerTradePartyAddress().getCountryID(), "DE"); - assertEquals(zi.getSellerTradePartyAddress().getCityName(), "Stadthausen"); + // Reading ZUGFeRD + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getInvoiceID(), "RE-20170509/505"); + assertEquals(zi.getZUGFeRDProfil(), "COMFORT"); + assertEquals(zi.getInvoiceCurrencyCode(), "EUR"); + assertEquals(zi.getIssuerAssignedID(), ""); + assertEquals(zi.getIssueDate(), "20170509"); + assertEquals(zi.getTaxPointDate(), "20170507"); + assertEquals(zi.getPaymentTerms(), "Zahlbar ohne Abzug bis zum 30.05.2017"); + assertEquals(zi.getLineTotalAmount(), "496.00"); + assertEquals(zi.getTaxBasisTotalAmount(), "496.00"); + assertEquals(zi.getTaxTotalAmount(), "75.04"); + assertEquals(zi.getRoundingAmount(), ""); + assertEquals(zi.getPaidAmount(), "0.00"); + assertEquals(zi.getBuyerTradePartyName(), "Theodor Est"); + assertEquals(zi.getBuyerTradePartyGlobalID(), ""); + assertEquals(zi.getSellerTradePartyGlobalID(), ""); + assertEquals(zi.getBuyerTradePartyID(), "DE999999999"); + assertEquals(zi.getBuyertradePartySpecifiedTaxRegistrationID(), "DE999999999"); + assertEquals(zi.getIncludedNote(), ""); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getDocumentCode(), "380"); + assertEquals(zi.getReference(), "AB321"); + assertEquals(zi.getAmount(), "571.04"); + assertEquals(zi.getBIC(), "COBADEFFXXX"); + assertEquals(zi.getIBAN(), "DE88 2008 0000 0970 3757 00"); + assertEquals(zi.getHolder(), getOwnOrganisationName()); + assertEquals(zi.getForeignReference(), getNumber()); + assertEquals(zi.getBuyerTradePartyAddress().getPostcodeCode(), "88802"); + assertEquals(zi.getBuyerTradePartyAddress().getLineOne(), "Bahnstr. 42"); + assertEquals(zi.getBuyerTradePartyAddress().getLineTwo(), "Hinterhaus"); + assertEquals(zi.getBuyerTradePartyAddress().getLineThree(), "Zweiter Stock"); + assertEquals(zi.getBuyerTradePartyAddress().getCountrySubDivisionName(), null); + assertEquals(zi.getBuyerTradePartyAddress().getCountryID(), "DE"); + assertEquals(zi.getBuyerTradePartyAddress().getCityName(), "Spielkreis"); + assertEquals(zi.getSellerTradePartyAddress().getPostcodeCode(), "12345"); + assertEquals(zi.getSellerTradePartyAddress().getLineOne(), "Ecke 12"); + assertEquals(zi.getSellerTradePartyAddress().getLineTwo(), null); + assertEquals(zi.getSellerTradePartyAddress().getLineThree(), null); + assertEquals(zi.getSellerTradePartyAddress().getCountrySubDivisionName(), null); + assertEquals(zi.getSellerTradePartyAddress().getCountryID(), "DE"); + assertEquals(zi.getSellerTradePartyAddress().getCityName(), "Stadthausen"); - final List li = zi.getLineItemList(); - assertEquals(li.get(0).getId().toString(), "1"); - assertEquals(li.get(0).getProduct().getBuyerAssignedID(), ""); - assertEquals(li.get(0).getProduct().getSellerAssignedID(), ""); - assertEquals(li.get(0).getLineTotalAmount().toString(), "160.00"); - assertEquals(li.get(0).getQuantity().toString(), "1.0000"); - assertEquals(li.get(0).getProduct().getVATPercent().toString(), "7.00"); - assertEquals(li.get(0).getProduct().getName(), "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung"); - assertEquals(li.get(0).getProduct().getDescription(), ""); + final List li = zi.getLineItemList(); + assertEquals(li.get(0).getId().toString(), "1"); + assertEquals(li.get(0).getProduct().getBuyerAssignedID(), ""); + assertEquals(li.get(0).getProduct().getSellerAssignedID(), ""); + assertEquals(li.get(0).getLineTotalAmount().toString(), "160.00"); + assertEquals(li.get(0).getQuantity().toString(), "1.0000"); + assertEquals(li.get(0).getProduct().getVATPercent().toString(), "7.00"); + assertEquals(li.get(0).getProduct().getName(), "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung"); + assertEquals(li.get(0).getProduct().getDescription(), ""); - try { - assertEquals(zi.getVersion(), 2); - } catch (final Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + try { + assertEquals(zi.getVersion(), 2); + } catch (final Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } - /** - * The exporter test bases on @{code - * ./src/test/MustangBeispiel20221026.pdf}, adds - * metadata, writes to @{code ./target/testout-*} and then imports to check the - * values. - */ - public void testImport() { - // now check the contents (like MustangReaderTest) - final ZUGFeRDImporter zi = new ZUGFeRDImporter("src/test/resources/MustangBeispiel20221026.pdf"); + /** + * The exporter test bases on @{code + * ./src/test/MustangBeispiel20221026.pdf}, adds + * metadata, writes to @{code ./target/testout-*} and then imports to check the + * values. + */ + public void testImport() { + // now check the contents (like MustangReaderTest) + final ZUGFeRDImporter zi = new ZUGFeRDImporter("src/test/resources/MustangBeispiel20221026.pdf"); - // Reading ZUGFeRD - assertEquals("963.11", zi.getAmount()); - assertEquals("RE1001", zi.getInvoiceID()); - assertEquals("COMFORT", zi.getZUGFeRDProfil()); - assertEquals("EUR", zi.getInvoiceCurrencyCode()); - assertEquals("20221026", zi.getIssueDate()); - assertEquals("20221026", zi.getTaxPointDate()); - assertEquals("Innerhalb von 30 Tagen 2% Skonto, 60 Tage ohne Abzug", zi.getPaymentTerms()); - assertEquals("804.35", zi.getLineTotalAmount()); - assertEquals("809.34", zi.getTaxBasisTotalAmount()); - assertEquals("153.77", zi.getTaxTotalAmount()); - assertEquals("", zi.getRoundingAmount()); - assertEquals("0.00", zi.getPaidAmount()); - assertEquals("Beispiel AG", zi.getBuyerTradePartyName()); - assertEquals("", zi.getBuyerTradePartyGlobalID()); - assertEquals("", zi.getSellerTradePartyGlobalID()); - assertEquals("10000", zi.getBuyerTradePartyID()); - assertEquals("\n weclapp.com\nSomestreet 42\n08155 Some city\nDE\n ", zi.getIncludedNote()); - assertEquals("weclapp.com", zi.getHolder()); - assertEquals("380", zi.getDocumentCode()); - assertEquals("01-95", zi.getReference()); - assertEquals("RE1001", zi.getForeignReference()); - assertEquals("54321", zi.getBuyerTradePartyAddress().getPostcodeCode()); - assertEquals("Feldstraße 34", zi.getBuyerTradePartyAddress().getLineOne()); - assertEquals(null, zi.getBuyerTradePartyAddress().getLineTwo()); - assertEquals(null, zi.getBuyerTradePartyAddress().getLineThree()); - assertEquals(null, zi.getBuyerTradePartyAddress().getCountrySubDivisionName()); - assertEquals("DE", zi.getBuyerTradePartyAddress().getCountryID()); - assertEquals("Hithausen", zi.getBuyerTradePartyAddress().getCityName()); - assertEquals("Beispiel Lager AG", zi.getDeliveryTradePartyName()); - assertEquals("54321", zi.getDeliveryTradePartyAddress().getPostcodeCode()); - assertEquals("Feldstraße 39", zi.getDeliveryTradePartyAddress().getLineOne()); - assertEquals(null, zi.getDeliveryTradePartyAddress().getLineTwo()); - assertEquals(null, zi.getDeliveryTradePartyAddress().getLineThree()); - assertEquals(null, zi.getDeliveryTradePartyAddress().getCountrySubDivisionName()); - assertEquals("DE", zi.getDeliveryTradePartyAddress().getCountryID()); - assertEquals("Hithausen", zi.getDeliveryTradePartyAddress().getCityName()); - assertEquals("08155", zi.getSellerTradePartyAddress().getPostcodeCode()); - assertEquals("Somestreet 42", zi.getSellerTradePartyAddress().getLineOne()); - assertEquals(null, zi.getSellerTradePartyAddress().getLineTwo()); - assertEquals(null, zi.getSellerTradePartyAddress().getLineThree()); - assertEquals(null, zi.getSellerTradePartyAddress().getCountrySubDivisionName()); - assertEquals("DE", zi.getSellerTradePartyAddress().getCountryID()); - assertEquals("Some city", zi.getSellerTradePartyAddress().getCityName()); + // Reading ZUGFeRD + assertEquals("963.11", zi.getAmount()); + assertEquals("RE1001", zi.getInvoiceID()); + assertEquals("COMFORT", zi.getZUGFeRDProfil()); + assertEquals("EUR", zi.getInvoiceCurrencyCode()); + assertEquals("20221026", zi.getIssueDate()); + assertEquals("20221026", zi.getTaxPointDate()); + assertEquals("Innerhalb von 30 Tagen 2% Skonto, 60 Tage ohne Abzug", zi.getPaymentTerms()); + assertEquals("804.35", zi.getLineTotalAmount()); + assertEquals("809.34", zi.getTaxBasisTotalAmount()); + assertEquals("153.77", zi.getTaxTotalAmount()); + assertEquals("", zi.getRoundingAmount()); + assertEquals("0.00", zi.getPaidAmount()); + assertEquals("Beispiel AG", zi.getBuyerTradePartyName()); + assertEquals("", zi.getBuyerTradePartyGlobalID()); + assertEquals("", zi.getSellerTradePartyGlobalID()); + assertEquals("10000", zi.getBuyerTradePartyID()); + assertEquals("\n weclapp.com\nSomestreet 42\n08155 Some city\nDE\n ", zi.getIncludedNote()); + assertEquals("weclapp.com", zi.getHolder()); + assertEquals("380", zi.getDocumentCode()); + assertEquals("01-95", zi.getReference()); + assertEquals("RE1001", zi.getForeignReference()); + assertEquals("54321", zi.getBuyerTradePartyAddress().getPostcodeCode()); + assertEquals("Feldstraße 34", zi.getBuyerTradePartyAddress().getLineOne()); + assertEquals(null, zi.getBuyerTradePartyAddress().getLineTwo()); + assertEquals(null, zi.getBuyerTradePartyAddress().getLineThree()); + assertEquals(null, zi.getBuyerTradePartyAddress().getCountrySubDivisionName()); + assertEquals("DE", zi.getBuyerTradePartyAddress().getCountryID()); + assertEquals("Hithausen", zi.getBuyerTradePartyAddress().getCityName()); + assertEquals("Beispiel Lager AG", zi.getDeliveryTradePartyName()); + assertEquals("54321", zi.getDeliveryTradePartyAddress().getPostcodeCode()); + assertEquals("Feldstraße 39", zi.getDeliveryTradePartyAddress().getLineOne()); + assertEquals(null, zi.getDeliveryTradePartyAddress().getLineTwo()); + assertEquals(null, zi.getDeliveryTradePartyAddress().getLineThree()); + assertEquals(null, zi.getDeliveryTradePartyAddress().getCountrySubDivisionName()); + assertEquals("DE", zi.getDeliveryTradePartyAddress().getCountryID()); + assertEquals("Hithausen", zi.getDeliveryTradePartyAddress().getCityName()); + assertEquals("08155", zi.getSellerTradePartyAddress().getPostcodeCode()); + assertEquals("Somestreet 42", zi.getSellerTradePartyAddress().getLineOne()); + assertEquals(null, zi.getSellerTradePartyAddress().getLineTwo()); + assertEquals(null, zi.getSellerTradePartyAddress().getLineThree()); + assertEquals(null, zi.getSellerTradePartyAddress().getCountrySubDivisionName()); + assertEquals("DE", zi.getSellerTradePartyAddress().getCountryID()); + assertEquals("Some city", zi.getSellerTradePartyAddress().getCityName()); - try { - assertEquals(zi.getVersion(), 2); - } catch (final Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + try { + assertEquals(zi.getVersion(), 2); + } catch (final Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java index 7d2e6ab..f65271c 100755 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2ZInvoiceImporterTest.java @@ -21,7 +21,6 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; import com.fasterxml.jackson.databind.ObjectMapper; - import org.junit.jupiter.api.Test; import org.mustangproject.*; @@ -34,7 +33,7 @@ import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.Paths; +import java.nio.file.Path; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -50,424 +49,424 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase { - public void testInvoiceImport() { + public void testInvoiceImport() { - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2new.pdf"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2new.pdf"); - boolean hasExceptions = false; - Invoice invoice = null; - try { - invoice = zii.extractInvoice(); - } catch (XPathExpressionException | ParseException e) { - hasExceptions = true; - } - assertFalse(hasExceptions); - // Reading ZUGFeRD - assertEquals("Bei Spiel GmbH", invoice.getOwnOrganisationName()); - assertEquals(3, invoice.getZFItems().length); - assertEquals("400.0000", invoice.getZFItems()[1].getQuantity().toString()); + boolean hasExceptions = false; + Invoice invoice = null; + try { + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); + // Reading ZUGFeRD + assertEquals("Bei Spiel GmbH", invoice.getOwnOrganisationName()); + assertEquals(3, invoice.getZFItems().length); + assertEquals("400.0000", invoice.getZFItems()[1].getQuantity().toString()); - assertEquals("AB321", invoice.getReferenceNumber()); - assertEquals("160.0000", invoice.getZFItems()[0].getPrice().toString()); - assertEquals("Heiße Luft pro Liter", invoice.getZFItems()[2].getProduct().getName()); - assertEquals("LTR", invoice.getZFItems()[2].getProduct().getUnit()); - assertEquals("7.00", invoice.getZFItems()[0].getProduct().getVATPercent().toString()); - assertEquals("RE-20170509/505", invoice.getNumber()); - assertEquals("Zahlbar ohne Abzug bis zum 30.05.2017", invoice.getPaymentTermDescription()); + assertEquals("AB321", invoice.getReferenceNumber()); + assertEquals("160.0000", invoice.getZFItems()[0].getPrice().toString()); + assertEquals("Heiße Luft pro Liter", invoice.getZFItems()[2].getProduct().getName()); + assertEquals("LTR", invoice.getZFItems()[2].getProduct().getUnit()); + assertEquals("7.00", invoice.getZFItems()[0].getProduct().getVATPercent().toString()); + assertEquals("RE-20170509/505", invoice.getNumber()); + assertEquals("Zahlbar ohne Abzug bis zum 30.05.2017", invoice.getPaymentTermDescription()); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - assertEquals("2017-05-09", sdf.format(invoice.getIssueDate())); - assertEquals("2017-05-07", sdf.format(invoice.getDeliveryDate())); - assertEquals("2017-05-30", sdf.format(invoice.getDueDate())); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + assertEquals("2017-05-09", sdf.format(invoice.getIssueDate())); + assertEquals("2017-05-07", sdf.format(invoice.getDeliveryDate())); + assertEquals("2017-05-30", sdf.format(invoice.getDueDate())); - assertEquals("Bahnstr. 42", invoice.getRecipient().getStreet()); - assertEquals("Hinterhaus", invoice.getRecipient().getAdditionalAddress()); - assertEquals("Zweiter Stock", invoice.getRecipient().getAdditionalAddressExtension()); - assertEquals("88802", invoice.getRecipient().getZIP()); - assertEquals("DE", invoice.getRecipient().getCountry()); - assertEquals("Spielkreis", invoice.getRecipient().getLocation()); + assertEquals("Bahnstr. 42", invoice.getRecipient().getStreet()); + assertEquals("Hinterhaus", invoice.getRecipient().getAdditionalAddress()); + assertEquals("Zweiter Stock", invoice.getRecipient().getAdditionalAddressExtension()); + assertEquals("88802", invoice.getRecipient().getZIP()); + assertEquals("DE", invoice.getRecipient().getCountry()); + assertEquals("Spielkreis", invoice.getRecipient().getLocation()); - assertEquals("Ecke 12", invoice.getSender().getStreet()); - assertEquals("12345", invoice.getSender().getZIP()); - assertEquals("DE", invoice.getSender().getCountry()); - assertEquals("Stadthausen", invoice.getSender().getLocation()); + assertEquals("Ecke 12", invoice.getSender().getStreet()); + assertEquals("12345", invoice.getSender().getZIP()); + assertEquals("DE", invoice.getSender().getCountry()); + assertEquals("Stadthausen", invoice.getSender().getLocation()); - TransactionCalculator tc = new TransactionCalculator(invoice); - assertEquals(new BigDecimal("571.04"), tc.getGrandTotal()); + TransactionCalculator tc = new TransactionCalculator(invoice); + assertEquals(new BigDecimal("571.04"), tc.getGrandTotal()); - // name street location zip country, contact name phone email, total amount + // name street location zip country, contact name phone email, total amount - } + } - public void testInvoiceImportUBL() { + public void testInvoiceImportUBL() { - boolean hasExceptions = false; + boolean hasExceptions = false; - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); - File expectedResult = getResourceAsFile("testout-ZF2new.ubl.xml"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + File expectedResult = getResourceAsFile("testout-ZF2new.ubl.xml"); - Invoice invoice = null; - try { - String xml = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r", "").replace("\n", ""); + Invoice invoice = null; + try { + String xml = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r", "").replace("\n", ""); - zii.fromXML(xml); + zii.fromXML(xml); - invoice = zii.extractInvoice(); - } catch (XPathExpressionException | ParseException | IOException e) { - hasExceptions = true; - } - assertFalse(hasExceptions); - // Reading ZUGFeRD - assertEquals("Bei Spiel GmbH", invoice.getOwnOrganisationName()); - assertEquals(3, invoice.getZFItems().length); - assertEquals(invoice.getZFItems()[0].getNotesWithSubjectCode().get(0).getContent(), "Something"); - assertEquals(invoice.getZFItems()[0].getNotesWithSubjectCode().size(), 1); - assertEquals("400", invoice.getZFItems()[1].getQuantity().toString()); - assertEquals("Zahlbar ohne Abzug bis zum 30.05.2017", invoice.getPaymentTermDescription()); - assertEquals("AB321", invoice.getReferenceNumber()); - assertEquals("160", invoice.getZFItems()[0].getPrice().toString()); - assertEquals("Heiße Luft pro Liter", invoice.getZFItems()[2].getProduct().getName()); - assertEquals("LTR", invoice.getZFItems()[2].getProduct().getUnit()); - assertEquals("7", invoice.getZFItems()[0].getProduct().getVATPercent().toString()); - assertEquals("RE-20170509/505", invoice.getNumber()); + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException | IOException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); + // Reading ZUGFeRD + assertEquals("Bei Spiel GmbH", invoice.getOwnOrganisationName()); + assertEquals(3, invoice.getZFItems().length); + assertEquals(invoice.getZFItems()[0].getNotesWithSubjectCode().get(0).getContent(), "Something"); + assertEquals(invoice.getZFItems()[0].getNotesWithSubjectCode().size(), 1); + assertEquals("400", invoice.getZFItems()[1].getQuantity().toString()); + assertEquals("Zahlbar ohne Abzug bis zum 30.05.2017", invoice.getPaymentTermDescription()); + assertEquals("AB321", invoice.getReferenceNumber()); + assertEquals("160", invoice.getZFItems()[0].getPrice().toString()); + assertEquals("Heiße Luft pro Liter", invoice.getZFItems()[2].getProduct().getName()); + assertEquals("LTR", invoice.getZFItems()[2].getProduct().getUnit()); + assertEquals("7", invoice.getZFItems()[0].getProduct().getVATPercent().toString()); + assertEquals("RE-20170509/505", invoice.getNumber()); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - assertEquals("2017-05-09", sdf.format(invoice.getIssueDate())); - assertEquals("2017-05-07", sdf.format(invoice.getDeliveryDate())); - assertEquals("2017-05-30", sdf.format(invoice.getDueDate())); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + assertEquals("2017-05-09", sdf.format(invoice.getIssueDate())); + assertEquals("2017-05-07", sdf.format(invoice.getDeliveryDate())); + assertEquals("2017-05-30", sdf.format(invoice.getDueDate())); - assertEquals("Bahnstr. 42", invoice.getRecipient().getStreet()); - assertEquals("Hinterhaus", invoice.getRecipient().getAdditionalAddress()); - assertEquals("Zweiter Stock", invoice.getRecipient().getAdditionalAddressExtension()); - assertEquals("88802", invoice.getRecipient().getZIP()); - assertEquals("DE", invoice.getRecipient().getCountry()); - assertEquals("Spielkreis", invoice.getRecipient().getLocation()); + assertEquals("Bahnstr. 42", invoice.getRecipient().getStreet()); + assertEquals("Hinterhaus", invoice.getRecipient().getAdditionalAddress()); + assertEquals("Zweiter Stock", invoice.getRecipient().getAdditionalAddressExtension()); + assertEquals("88802", invoice.getRecipient().getZIP()); + assertEquals("DE", invoice.getRecipient().getCountry()); + assertEquals("Spielkreis", invoice.getRecipient().getLocation()); - assertEquals("Ecke 12", invoice.getSender().getStreet()); - assertEquals("12345", invoice.getSender().getZIP()); - assertEquals("DE", invoice.getSender().getCountry()); - assertEquals("Stadthausen", invoice.getSender().getLocation()); + assertEquals("Ecke 12", invoice.getSender().getStreet()); + assertEquals("12345", invoice.getSender().getZIP()); + assertEquals("DE", invoice.getSender().getCountry()); + assertEquals("Stadthausen", invoice.getSender().getLocation()); - assertTrue(invoice.getPayee() != null); - assertEquals("VR Factoring GmbH", invoice.getPayee().getName()); + assertTrue(invoice.getPayee() != null); + assertEquals("VR Factoring GmbH", invoice.getPayee().getName()); - TransactionCalculator tc = new TransactionCalculator(invoice); - assertEquals(new BigDecimal("571.04"), tc.getGrandTotal()); + TransactionCalculator tc = new TransactionCalculator(invoice); + assertEquals(new BigDecimal("571.04"), tc.getGrandTotal()); - // name street location zip country, contact name phone email, total amount + // name street location zip country, contact name phone email, total amount - } + } - public void testEdgeInvoiceImport() { + public void testEdgeInvoiceImport() { - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushEdge.pdf"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushEdge.pdf"); - boolean hasExceptions = false; - Invoice invoice = null; - try { - invoice = zii.extractInvoice(); - } catch (XPathExpressionException | ParseException e) { - hasExceptions = true; - } - assertFalse(hasExceptions); - // Reading ZUGFeRD - assertEquals("4711", invoice.getZFItems()[0].getProduct().getSellerAssignedID()); - assertEquals("9384", invoice.getSellerOrderReferencedDocumentID()); - assertEquals("sender@test.org", invoice.getSender().getEmail()); - assertEquals("recipient@test.org", invoice.getRecipient().getEmail()); - assertEquals("28934", invoice.getBuyerOrderReferencedDocumentID()); + boolean hasExceptions = false; + Invoice invoice = null; + try { + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); + // Reading ZUGFeRD + assertEquals("4711", invoice.getZFItems()[0].getProduct().getSellerAssignedID()); + assertEquals("9384", invoice.getSellerOrderReferencedDocumentID()); + assertEquals("sender@test.org", invoice.getSender().getEmail()); + assertEquals("recipient@test.org", invoice.getRecipient().getEmail()); + assertEquals("28934", invoice.getBuyerOrderReferencedDocumentID()); - } + } - public void testZF1Import() { + public void testZF1Import() { - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-MustangGnuaccountingBeispielRE-20171118_506zf1.pdf"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-MustangGnuaccountingBeispielRE-20171118_506zf1.pdf"); - boolean hasExceptions = false; - Invoice invoice = null; - try { - invoice = zii.extractInvoice(); - } catch (XPathExpressionException | ParseException e) { - hasExceptions = true; - } - assertFalse(hasExceptions); - // Reading ZUGFeRD - assertEquals("Bei Spiel GmbH", invoice.getOwnOrganisationName()); - assertEquals(3, invoice.getZFItems().length); - assertEquals("400.0000", invoice.getZFItems()[1].getQuantity().toString()); + boolean hasExceptions = false; + Invoice invoice = null; + try { + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); + // Reading ZUGFeRD + assertEquals("Bei Spiel GmbH", invoice.getOwnOrganisationName()); + assertEquals(3, invoice.getZFItems().length); + assertEquals("400.0000", invoice.getZFItems()[1].getQuantity().toString()); - assertEquals("160.0000", invoice.getZFItems()[0].getPrice().toString()); - assertEquals("Hot air „heiße Luft“ (litres)", invoice.getZFItems()[2].getProduct().getName()); - assertEquals("LTR", invoice.getZFItems()[2].getProduct().getUnit()); - assertEquals("7.00", invoice.getZFItems()[0].getProduct().getVATPercent().toString()); - assertEquals("RE-20190610/507", invoice.getNumber()); + assertEquals("160.0000", invoice.getZFItems()[0].getPrice().toString()); + assertEquals("Hot air „heiße Luft“ (litres)", invoice.getZFItems()[2].getProduct().getName()); + assertEquals("LTR", invoice.getZFItems()[2].getProduct().getUnit()); + assertEquals("7.00", invoice.getZFItems()[0].getProduct().getVATPercent().toString()); + assertEquals("RE-20190610/507", invoice.getNumber()); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - assertEquals("2019-06-10", sdf.format(invoice.getIssueDate())); - assertEquals("2019-07-01", sdf.format(invoice.getDueDate())); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + assertEquals("2019-06-10", sdf.format(invoice.getIssueDate())); + assertEquals("2019-07-01", sdf.format(invoice.getDueDate())); - assertEquals("street", invoice.getRecipient().getStreet()); - assertEquals("zip", invoice.getRecipient().getZIP()); - assertEquals("DE", invoice.getRecipient().getCountry()); - assertEquals("city", invoice.getRecipient().getLocation()); + assertEquals("street", invoice.getRecipient().getStreet()); + assertEquals("zip", invoice.getRecipient().getZIP()); + assertEquals("DE", invoice.getRecipient().getCountry()); + assertEquals("city", invoice.getRecipient().getLocation()); - assertEquals("street", invoice.getSender().getStreet()); - assertEquals("zip", invoice.getSender().getZIP()); - assertEquals("DE", invoice.getSender().getCountry()); - assertEquals("city", invoice.getSender().getLocation()); + assertEquals("street", invoice.getSender().getStreet()); + assertEquals("zip", invoice.getSender().getZIP()); + assertEquals("DE", invoice.getSender().getCountry()); + assertEquals("city", invoice.getSender().getLocation()); - TransactionCalculator tc = new TransactionCalculator(invoice); - assertEquals(new BigDecimal("571.04"), tc.getGrandTotal()); + TransactionCalculator tc = new TransactionCalculator(invoice); + assertEquals(new BigDecimal("571.04"), tc.getGrandTotal()); - // name street location zip country, contact name phone email, total amount + // name street location zip country, contact name phone email, total amount - } + } - public void testItemAllowancesChargesImport() { + public void testItemAllowancesChargesImport() { - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushItemChargesAllowances.pdf"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushItemChargesAllowances.pdf"); - boolean hasExceptions = false; - Invoice invoice = null; - try { - invoice = zii.extractInvoice(); - } catch (XPathExpressionException | ParseException e) { - hasExceptions = true; - } - assertFalse(hasExceptions); - TransactionCalculator tc = new TransactionCalculator(invoice); - assertEquals(new BigDecimal("18.33"), tc.getGrandTotal()); - } + boolean hasExceptions = false; + Invoice invoice = null; + try { + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); + TransactionCalculator tc = new TransactionCalculator(invoice); + assertEquals(new BigDecimal("18.33"), tc.getGrandTotal()); + } - public void testBasisQuantityImport() { + public void testBasisQuantityImport() { - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2newEdge.pdf"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2newEdge.pdf"); - boolean hasExceptions = false; - Invoice invoice = null; - try { - invoice = zii.extractInvoice(); - } catch (XPathExpressionException | ParseException e) { - hasExceptions = true; - } - assertFalse(hasExceptions); - TransactionCalculator tc = new TransactionCalculator(invoice); - assertEquals(new BigDecimal("337.60"), tc.getGrandTotal()); - } + boolean hasExceptions = false; + Invoice invoice = null; + try { + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); + TransactionCalculator tc = new TransactionCalculator(invoice); + assertEquals(new BigDecimal("337.60"), tc.getGrandTotal()); + } - public void testAllowancesChargesImport() { + public void testAllowancesChargesImport() { - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushChargesAllowances.pdf"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushChargesAllowances.pdf"); - boolean hasExceptions = false; - Invoice invoice = null; - try { - invoice = zii.extractInvoice(); - } catch (XPathExpressionException | ParseException e) { - hasExceptions = true; - } - assertFalse(hasExceptions); - TransactionCalculator tc = new TransactionCalculator(invoice); - assertEquals(new BigDecimal("11.07"), tc.getGrandTotal()); + boolean hasExceptions = false; + Invoice invoice = null; + try { + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); + TransactionCalculator tc = new TransactionCalculator(invoice); + assertEquals(new BigDecimal("11.07"), tc.getGrandTotal()); - } + } - public void testXRImport() { - boolean hasExceptions = false; + public void testXRImport() { + boolean hasExceptions = false; - ZUGFeRDImporter zii = new ZUGFeRDImporter(); + 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); - } + int version = -1; + try { + zii.fromXML(new String(Files.readAllBytes(Path.of("./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; - try { - invoice = zii.extractInvoice(); - } catch (XPathExpressionException | ParseException e) { - hasExceptions = true; - } - assertFalse(hasExceptions); + Invoice invoice = null; + try { + invoice = zii.extractInvoice(); + } catch (XPathExpressionException | ParseException e) { + hasExceptions = true; + } + assertFalse(hasExceptions); - TransactionCalculator tc = new TransactionCalculator(invoice); - assertEquals(new BigDecimal("1.00"), tc.getGrandTotal()); + 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); + 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]; - assertEquals("DE12500105170648489890", paym.getOwnIBAN()); - assertEquals("COBADEFXXX", paym.getOwnBIC()); + assertTrue(invoice.getTradeSettlement().length == 1); + assertTrue(invoice.getTradeSettlement()[0] instanceof IZUGFeRDTradeSettlementPayment); + IZUGFeRDTradeSettlementPayment paym = (IZUGFeRDTradeSettlementPayment) invoice.getTradeSettlement()[0]; + assertEquals("DE12500105170648489890", paym.getOwnIBAN()); + assertEquals("COBADEFXXX", paym.getOwnBIC()); - assertTrue(invoice.getPayee() != null); - assertEquals("VR Factoring GmbH", invoice.getPayee().getName()); - } + assertTrue(invoice.getPayee() != null); + assertEquals("VR Factoring GmbH", invoice.getPayee().getName()); + } - /** - * testing if other files embedded in pdf additionally to the invoice can be read correctly - */ - public void testDetach() { - boolean hasExceptions = false; + /** + * testing if other files embedded in pdf additionally to the invoice can be read correctly + */ + public void testDetach() { + boolean hasExceptions = false; - byte[] fileA = null; - byte[] fileB = null; + byte[] fileA = null; + byte[] fileB = null; - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushAttachments.pdf"); - for (FileAttachment fa : zii.getFileAttachmentsPDF()) { - if (fa.getFilename().equals("one.pdf")) { - fileA = fa.getData(); - } else if (fa.getFilename().equals("two.pdf")) { - fileB = fa.getData(); - } - } - byte[] b = {12, 13}; // the sample data that was used to write the files + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushAttachments.pdf"); + for (FileAttachment fa : zii.getFileAttachmentsPDF()) { + if (fa.getFilename().equals("one.pdf")) { + fileA = fa.getData(); + } else if (fa.getFilename().equals("two.pdf")) { + fileB = fa.getData(); + } + } + byte[] b = {12, 13}; // the sample data that was used to write the files - assertTrue(Arrays.equals(fileA, b)); - assertEquals(fileA.length, 2); - assertTrue(Arrays.equals(fileB, b)); - assertEquals(fileB.length, 2); - } + assertTrue(Arrays.equals(fileA, b)); + assertEquals(fileA.length, 2); + assertTrue(Arrays.equals(fileB, b)); + assertEquals(fileB.length, 2); + } - public void testImportDebit() { - File CIIinputFile = getResourceAsFile("cii/minimalDebit.xml"); - try { - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile)); - Invoice i = zii.extractInvoice(); + public void testImportDebit() { + File CIIinputFile = getResourceAsFile("cii/minimalDebit.xml"); + try { + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile)); + Invoice i = zii.extractInvoice(); - assertEquals("DE21860000000086001055", i.getSender().getBankDetails().get(0).getIBAN()); - ObjectMapper mapper = new ObjectMapper(); + assertEquals("DE21860000000086001055", i.getSender().getBankDetails().get(0).getIBAN()); + ObjectMapper mapper = new ObjectMapper(); - String jsonArray = mapper.writeValueAsString(i); + String jsonArray = mapper.writeValueAsString(i); - // assertEquals("",jsonArray); + // assertEquals("",jsonArray); - } catch (IOException e) { - fail("IOException not expected"); - } catch (XPathExpressionException e) { - throw new RuntimeException(e); - } catch (ParseException e) { - throw new RuntimeException(e); - } + } catch (IOException e) { + fail("IOException not expected"); + } catch (XPathExpressionException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); + } - } + } - public void testImportMinimum() { - File CIIinputFile = getResourceAsFile("cii/facturFrMinimum.xml"); - try { - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile)); + public void testImportMinimum() { + File CIIinputFile = getResourceAsFile("cii/facturFrMinimum.xml"); + try { + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile)); - CalculatedInvoice i = new CalculatedInvoice(); - zii.extractInto(i); - assertEquals("671.15", i.getGrandTotal().toString()); + CalculatedInvoice i = new CalculatedInvoice(); + zii.extractInto(i); + assertEquals("671.15", i.getGrandTotal().toString()); - } catch (IOException e) { - fail("IOException not expected"); - } catch (XPathExpressionException e) { - throw new RuntimeException(e); - } catch (ParseException e) { - throw new RuntimeException(e); - } + } catch (IOException e) { + fail("IOException not expected"); + } catch (XPathExpressionException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); + } - } + } - @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); + @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); + 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); - } + 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() - .getResourceAsStream("/EN16931_Einfach.pdf"); - ZUGFeRDInvoiceImporter importer = new ZUGFeRDInvoiceImporter(inputStream); - Invoice invoice = importer.extractInvoice(); - List notesWithSubjectCode = invoice.getNotesWithSubjectCode(); - assertThat(notesWithSubjectCode).hasSize(2); - assertThat(notesWithSubjectCode.get(0).getSubjectCode()).isNull(); - assertThat(notesWithSubjectCode.get(0).getContent()).isEqualTo("Rechnung gemäß Bestellung vom 01.11.2024."); - assertThat(notesWithSubjectCode.get(1).getSubjectCode()).isEqualTo(SubjectCode.REG); - assertThat(notesWithSubjectCode.get(1).getContent()).isEqualTo("Lieferant GmbH\t\t\t\t\n" - + "Lieferantenstraße 20\t\t\t\t\n" - + "80333 München\t\t\t\t\n" - + "Deutschland\t\t\t\t\n" - + "Geschäftsführer: Hans Muster\n" - + "Handelsregisternummer: H A 123"); + @Test + public void testImportIncludedNotes() throws XPathExpressionException, ParseException { + InputStream inputStream = this.getClass() + .getResourceAsStream("/EN16931_Einfach.pdf"); + ZUGFeRDInvoiceImporter importer = new ZUGFeRDInvoiceImporter(inputStream); + Invoice invoice = importer.extractInvoice(); + List notesWithSubjectCode = invoice.getNotesWithSubjectCode(); + assertThat(notesWithSubjectCode).hasSize(2); + assertThat(notesWithSubjectCode.get(0).getSubjectCode()).isNull(); + assertThat(notesWithSubjectCode.get(0).getContent()).isEqualTo("Rechnung gemäß Bestellung vom 01.11.2024."); + assertThat(notesWithSubjectCode.get(1).getSubjectCode()).isEqualTo(SubjectCode.REG); + assertThat(notesWithSubjectCode.get(1).getContent()).isEqualTo("Lieferant GmbH\t\t\t\t\n" + + "Lieferantenstraße 20\t\t\t\t\n" + + "80333 München\t\t\t\t\n" + + "Deutschland\t\t\t\t\n" + + "Geschäftsführer: Hans Muster\n" + + "Handelsregisternummer: H A 123"); - } + } - @Test - public void testImportPositionIncludedNotes() throws FileNotFoundException, XPathExpressionException, ParseException { - File inputFile = getResourceAsFile("ZTESTZUGFERD_1_INVDSS_012015738820PDF-1.pdf"); - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile)); + @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()); - } + 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)); + @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); - } + Invoice invoice = zii.extractInvoice(); + assertEquals(1, invoice.getZFItems().length); + assertFalse(invoice.getZFItems()[0].getNotes() == null); + assertEquals(1, invoice.getZFItems()[0].getNotes().length); + } - @Test - public void testImportXRechnungWithoutCalculationErrors() throws FileNotFoundException { - File inputFile = getResourceAsFile("cii/02.03a-INVOICE_uncefact.xml"); - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile)); + @Test + public void testImportXRechnungWithoutCalculationErrors() throws FileNotFoundException { + File inputFile = getResourceAsFile("cii/02.03a-INVOICE_uncefact.xml"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile)); - assertEquals("0", zii.importedInvoice.getDuePayable().toPlainString()); - } + assertEquals("0", zii.importedInvoice.getDuePayable().toPlainString()); + } } diff --git a/library/src/main/java-templates/org/mustangproject/ZUGFeRD/Version.java b/library/src/main/java-templates/org/mustangproject/ZUGFeRD/Version.java index f669dfe..a85d022 100755 --- a/library/src/main/java-templates/org/mustangproject/ZUGFeRD/Version.java +++ b/library/src/main/java-templates/org/mustangproject/ZUGFeRD/Version.java @@ -19,5 +19,5 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.ZUGFeRD; public final class Version { - public static final String VERSION = "${project.version}"; + public static final String VERSION = "${project.version}"; } diff --git a/validator/src/main/java/org/mustangproject/validator/EPart.java b/validator/src/main/java/org/mustangproject/validator/EPart.java index b56268a..03eab06 100755 --- a/validator/src/main/java/org/mustangproject/validator/EPart.java +++ b/validator/src/main/java/org/mustangproject/validator/EPart.java @@ -1,5 +1,5 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.validator; public enum EPart { - fx, ox, xr, pdf, none + fx, ox, xr, pdf, none } diff --git a/validator/src/main/java/org/mustangproject/validator/ESeverity.java b/validator/src/main/java/org/mustangproject/validator/ESeverity.java index e793001..ddf35a9 100755 --- a/validator/src/main/java/org/mustangproject/validator/ESeverity.java +++ b/validator/src/main/java/org/mustangproject/validator/ESeverity.java @@ -1,5 +1,5 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.validator; public enum ESeverity { - notice, warning, error, fatal, exception + notice, warning, error, fatal, exception } diff --git a/validator/src/main/java/org/mustangproject/validator/IrrecoverableValidationError.java b/validator/src/main/java/org/mustangproject/validator/IrrecoverableValidationError.java index ce8cbe0..8c6e235 100755 --- a/validator/src/main/java/org/mustangproject/validator/IrrecoverableValidationError.java +++ b/validator/src/main/java/org/mustangproject/validator/IrrecoverableValidationError.java @@ -2,12 +2,13 @@ org.openrewrite.config.CompositeRecipe public class IrrecoverableValidationError extends Exception { - /** - * - */ - private static final long serialVersionUID = 1L; - public IrrecoverableValidationError(String message) { - super(message); - } + /** + * + */ + private static final long serialVersionUID = 1L; + + public IrrecoverableValidationError(String message) { + super(message); + } } diff --git a/validator/src/main/java/org/mustangproject/validator/PDFValidator.java b/validator/src/main/java/org/mustangproject/validator/PDFValidator.java index 283b6df..eb2c7f5 100755 --- a/validator/src/main/java/org/mustangproject/validator/PDFValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/PDFValidator.java @@ -1,28 +1,7 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.validator; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Calendar; -import java.util.EnumSet; -import java.util.HashMap; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - -import org.mustangproject.util.ByteArraySearcher; import org.mustangproject.ZUGFeRD.ZUGFeRDImporter; +import org.mustangproject.util.ByteArraySearcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.verapdf.features.FeatureExtractorConfig; @@ -33,11 +12,7 @@ import org.verapdf.pdfa.flavours.PDFAFlavour; import org.verapdf.pdfa.validation.validators.ValidatorConfig; import org.verapdf.pdfa.validation.validators.ValidatorFactory; -import org.verapdf.processor.ItemProcessor; -import org.verapdf.processor.ProcessorConfig; -import org.verapdf.processor.ProcessorFactory; -import org.verapdf.processor.ProcessorResult; -import org.verapdf.processor.TaskType; +import org.verapdf.processor.*; import org.verapdf.processor.plugins.PluginsCollectionConfig; import org.verapdf.processor.reports.ItemDetails; import org.w3c.dom.Document; @@ -45,309 +20,329 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Calendar; +import java.util.EnumSet; +import java.util.HashMap; + public class PDFValidator extends Validator { - public PDFValidator(ValidationContext ctx) { - super(ctx); - } + public PDFValidator(ValidationContext ctx) { + super(ctx); + } - private static final Logger LOGGER = LoggerFactory.getLogger(PDFValidator.class.getCanonicalName()); // log output - private static final PDFAFlavour[] PDF_A_3_FLAVOURS = {PDFAFlavour.PDFA_3_A, PDFAFlavour.PDFA_3_B, PDFAFlavour.PDFA_3_U}; + private static final Logger LOGGER = LoggerFactory.getLogger(PDFValidator.class.getCanonicalName()); // log output + private static final PDFAFlavour[] PDF_A_3_FLAVOURS = {PDFAFlavour.PDFA_3_A, PDFAFlavour.PDFA_3_B, PDFAFlavour.PDFA_3_U}; - private String pdfFilename; + private String pdfFilename; - private byte[] fileContents; + private byte[] fileContents; - private String pdfReport; - private ProcessorResult processorResult = null; + private String pdfReport; + private ProcessorResult processorResult = null; - private String Signature; + private String Signature; - private String zfXML = null; - protected boolean autoload = true; + private String zfXML = null; + protected boolean autoload = true; - protected static boolean stringArrayContains(String[] arr, String targetValue) { - return Arrays.asList(arr).contains(targetValue); - } + protected static boolean stringArrayContains(String[] arr, String targetValue) { + return Arrays.asList(arr).contains(targetValue); + } - @Override - public void validate() throws IrrecoverableValidationError { + @Override + public void validate() throws IrrecoverableValidationError { - zfXML = null; - // file existence must have been checked before - if (!ByteArraySearcher.startsWith(fileContents, new byte[]{'%', 'P', 'D', 'F'})) { - context.addResultItem( - new ValidationResultItem(ESeverity.fatal, "Not a PDF file " + pdfFilename).setSection(20).setPart(EPart.pdf)); + zfXML = null; + // file existence must have been checked before + if (!ByteArraySearcher.startsWith(fileContents, new byte[]{'%', 'P', 'D', 'F'})) { + context.addResultItem( + new ValidationResultItem(ESeverity.fatal, "Not a PDF file " + pdfFilename).setSection(20).setPart(EPart.pdf)); - } + } - final long startPDFTime = Calendar.getInstance().getTimeInMillis(); + final long startPDFTime = Calendar.getInstance().getTimeInMillis(); - // Step 1 Validate PDF + // Step 1 Validate PDF - VeraGreenfieldFoundryProvider.initialise(); - // Default validator config - final ValidatorConfig validatorConfig = ValidatorFactory.defaultConfig(); - // Default features config - final FeatureExtractorConfig featureConfig = FeatureFactory.defaultConfig(); - // Default plugins config - final PluginsCollectionConfig pluginsConfig = PluginsCollectionConfig.defaultConfig(); - // Default fixer config - final MetadataFixerConfig fixerConfig = FixerFactory.defaultConfig(); - // Tasks configuring - final EnumSet tasks = EnumSet.noneOf(TaskType.class); - tasks.add(TaskType.VALIDATE); - // tasks.add(TaskType.EXTRACT_FEATURES); - // tasks.add(TaskType.FIX_METADATA); - // Creating processor config - final ProcessorConfig processorConfig = ProcessorFactory.fromValues(validatorConfig, featureConfig, pluginsConfig, - fixerConfig, tasks - ); - // Creating processor and output stream. - final InputStream inputStream = new ByteArrayInputStream(fileContents); - try (ItemProcessor processor = ProcessorFactory.createProcessor(processorConfig)) { - // Generating list of files for processing - // starting the processor - ItemDetails itemDetails = ItemDetails.fromValues(pdfFilename); - inputStream.mark(Integer.MAX_VALUE); - processorResult = processor.process(itemDetails, inputStream); - pdfReport = processorResult.getValidationResult().toString().replaceAll( - "<\\?xml version=\"1\\.0\" encoding=\"utf-8\"\\?>", - "" - ); - inputStream.reset(); - } catch (final Exception excep) { - context.addResultItem(new ValidationResultItem(ESeverity.exception, excep.getMessage()).setSection(7) - .setPart(EPart.pdf).setStacktrace(excep.getStackTrace().toString())); - } + VeraGreenfieldFoundryProvider.initialise(); + // Default validator config + final ValidatorConfig validatorConfig = ValidatorFactory.defaultConfig(); + // Default features config + final FeatureExtractorConfig featureConfig = FeatureFactory.defaultConfig(); + // Default plugins config + final PluginsCollectionConfig pluginsConfig = PluginsCollectionConfig.defaultConfig(); + // Default fixer config + final MetadataFixerConfig fixerConfig = FixerFactory.defaultConfig(); + // Tasks configuring + final EnumSet tasks = EnumSet.noneOf(TaskType.class); + tasks.add(TaskType.VALIDATE); + // tasks.add(TaskType.EXTRACT_FEATURES); + // tasks.add(TaskType.FIX_METADATA); + // Creating processor config + final ProcessorConfig processorConfig = ProcessorFactory.fromValues(validatorConfig, featureConfig, pluginsConfig, + fixerConfig, tasks + ); + // Creating processor and output stream. + final InputStream inputStream = new ByteArrayInputStream(fileContents); + try (ItemProcessor processor = ProcessorFactory.createProcessor(processorConfig)) { + // Generating list of files for processing + // starting the processor + ItemDetails itemDetails = ItemDetails.fromValues(pdfFilename); + inputStream.mark(Integer.MAX_VALUE); + processorResult = processor.process(itemDetails, inputStream); + pdfReport = processorResult.getValidationResult().toString().replaceAll( + "<\\?xml version=\"1\\.0\" encoding=\"utf-8\"\\?>", + "" + ); + inputStream.reset(); + } catch (final Exception excep) { + context.addResultItem(new ValidationResultItem(ESeverity.exception, excep.getMessage()).setSection(7) + .setPart(EPart.pdf).setStacktrace(excep.getStackTrace().toString())); + } - // step 2 validate XMP - final ZUGFeRDImporter zi = new ZUGFeRDImporter(); - zi.doIgnoreCalculationErrors();//of course the calculation will still be schematron checked - zi.setInputStream(inputStream); - final String xmp = zi.getXMP(); + // step 2 validate XMP + 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(); - final Document docXMP; + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + final Document docXMP; - if (xmp == null || xmp.length() == 0) { - context.addResultItem(new ValidationResultItem(ESeverity.error, "Invalid XMP Metadata not found") - .setSection(17).setPart(EPart.pdf)); - } else - /* - * checking for sth like EXTENDED - * INVOICE - * ZUGFeRD-invoice.xml - * 1.0 - */ - try { - final DocumentBuilder builder = factory.newDocumentBuilder(); - final InputSource is = new InputSource(new StringReader(xmp)); - docXMP = builder.parse(is); + if (xmp == null || xmp.length() == 0) { + context.addResultItem(new ValidationResultItem(ESeverity.error, "Invalid XMP Metadata not found") + .setSection(17).setPart(EPart.pdf)); + } else + /* + * checking for sth like EXTENDED + * INVOICE + * ZUGFeRD-invoice.xml + * 1.0 + */ + try { + final DocumentBuilder builder = factory.newDocumentBuilder(); + final InputSource is = new InputSource(new StringReader(xmp)); + docXMP = builder.parse(is); - final XPathFactory xpathFactory = XPathFactory.newInstance(); + final XPathFactory xpathFactory = XPathFactory.newInstance(); - // Create XPath object XPath xpath = xpathFactory.newXPath(); XPathExpression + // Create XPath object XPath xpath = xpathFactory.newXPath(); XPathExpression - final XPath xpath = xpathFactory.newXPath(); - // xpath.compile("//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/[local-name()=\"ID\"]"); - // evaluate expression result on XML document ndList = (NodeList) + final XPath xpath = xpathFactory.newXPath(); + // xpath.compile("//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/[local-name()=\"ID\"]"); + // evaluate expression result on XML document ndList = (NodeList) - // get the first element - XPathExpression xpr = xpath.compile( - "//*[local-name()=\"ConformanceLevel\"]|//*[local-name()=\"Description\"]/@ConformanceLevel"); - NodeList nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET); + // get the first element + XPathExpression xpr = xpath.compile( + "//*[local-name()=\"ConformanceLevel\"]|//*[local-name()=\"Description\"]/@ConformanceLevel"); + NodeList nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET); - if (nodes.getLength() == 0) { - context.addResultItem( - new ValidationResultItem(ESeverity.error, "XMP Metadata: ConformanceLevel not found") - .setSection(11).setPart(EPart.pdf)); - } + if (nodes.getLength() == 0) { + context.addResultItem( + new ValidationResultItem(ESeverity.error, "XMP Metadata: ConformanceLevel not found") + .setSection(11).setPart(EPart.pdf)); + } - boolean conformanceLevelValid = false; - for (int i = 0; i < nodes.getLength(); i++) { + boolean conformanceLevelValid = false; + for (int i = 0; i < nodes.getLength(); i++) { - final String[] valueArray = {"BASIC WL", "BASIC", "MINIMUM", "EN 16931", "COMFORT", "CIUS", "EXTENDED", "XRECHNUNG"}; - if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { - conformanceLevelValid = true; - } - } - if (!conformanceLevelValid) { - context.addResultItem(new ValidationResultItem( - ESeverity.error, - "XMP Metadata: ConformanceLevel contains invalid value" - ).setSection(12).setPart(EPart.pdf)); + final String[] valueArray = {"BASIC WL", "BASIC", "MINIMUM", "EN 16931", "COMFORT", "CIUS", "EXTENDED", "XRECHNUNG"}; + if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { + conformanceLevelValid = true; + } + } + if (!conformanceLevelValid) { + context.addResultItem(new ValidationResultItem( + ESeverity.error, + "XMP Metadata: ConformanceLevel contains invalid value" + ).setSection(12).setPart(EPart.pdf)); - } - xpr = xpath.compile("//*[local-name()=\"DocumentType\"]|//*[local-name()=\"Description\"]/@DocumentType"); - nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET); + } + xpr = xpath.compile("//*[local-name()=\"DocumentType\"]|//*[local-name()=\"Description\"]/@DocumentType"); + nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET); - if (nodes.getLength() == 0) { - context.addResultItem(new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentType not found") - .setSection(13).setPart(EPart.pdf)); - } + if (nodes.getLength() == 0) { + context.addResultItem(new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentType not found") + .setSection(13).setPart(EPart.pdf)); + } - boolean documentTypeValid = false; - for (int i = 0; i < nodes.getLength(); i++) { - if (nodes.item(i).getTextContent().equals("INVOICE") || nodes.item(i).getTextContent().equals("ORDER") - || nodes.item(i).getTextContent().equals("ORDER_RESPONSE") || nodes.item(i).getTextContent() - .equals("ORDER_CHANGE")) { - documentTypeValid = true; - } - } - if (!documentTypeValid) { - context.addResultItem( - new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentType invalid") - .setSection(14).setPart(EPart.pdf)); + boolean documentTypeValid = false; + for (int i = 0; i < nodes.getLength(); i++) { + if (nodes.item(i).getTextContent().equals("INVOICE") || nodes.item(i).getTextContent().equals("ORDER") + || nodes.item(i).getTextContent().equals("ORDER_RESPONSE") || nodes.item(i).getTextContent() + .equals("ORDER_CHANGE")) { + documentTypeValid = true; + } + } + if (!documentTypeValid) { + context.addResultItem( + new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentType invalid") + .setSection(14).setPart(EPart.pdf)); - } - xpr = xpath.compile( - "//*[local-name()=\"DocumentFileName\"]|//*[local-name()=\"Description\"]/@DocumentFileName"); - nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET); + } + xpr = xpath.compile( + "//*[local-name()=\"DocumentFileName\"]|//*[local-name()=\"Description\"]/@DocumentFileName"); + nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET); - if (nodes.getLength() == 0) { - context.addResultItem( - new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentFileName not found") - .setSection(21).setPart(EPart.pdf)); - } - boolean documentFilenameValid = false; - for (int i = 0; i < nodes.getLength(); i++) { - final String[] valueArray = {"factur-x.xml", "ZUGFeRD-invoice.xml", "zugferd-invoice.xml", "xrechnung.xml", "order-x.xml"}; - if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { - documentFilenameValid = true; - } + if (nodes.getLength() == 0) { + context.addResultItem( + new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentFileName not found") + .setSection(21).setPart(EPart.pdf)); + } + boolean documentFilenameValid = false; + for (int i = 0; i < nodes.getLength(); i++) { + final String[] valueArray = {"factur-x.xml", "ZUGFeRD-invoice.xml", "zugferd-invoice.xml", "xrechnung.xml", "order-x.xml"}; + if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { + documentFilenameValid = true; + } - // e.g. ZUGFeRD-invoice.xml - } - if (!documentFilenameValid) { + // e.g. ZUGFeRD-invoice.xml + } + if (!documentFilenameValid) { - context.addResultItem(new ValidationResultItem( - ESeverity.error, - "XMP Metadata: DocumentFileName contains invalid value" - ).setSection(19).setPart(EPart.pdf)); - } - xpr = xpath.compile("//*[local-name()=\"Version\"]|//*[local-name()=\"Description\"]/@Version"); - nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET); + context.addResultItem(new ValidationResultItem( + ESeverity.error, + "XMP Metadata: DocumentFileName contains invalid value" + ).setSection(19).setPart(EPart.pdf)); + } + xpr = xpath.compile("//*[local-name()=\"Version\"]|//*[local-name()=\"Description\"]/@Version"); + nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET); - // get all child nodes - // NodeList nodes = element.getChildNodes(); - // expr.evaluate(docXMP, XPathConstants.NODESET); - // print the text content of each child - if (nodes.getLength() == 0) { - context.addResultItem(new ValidationResultItem(ESeverity.error, "XMP Metadata: Version not found") - .setSection(15).setPart(EPart.pdf)); - } + // get all child nodes + // NodeList nodes = element.getChildNodes(); + // expr.evaluate(docXMP, XPathConstants.NODESET); + // print the text content of each child + if (nodes.getLength() == 0) { + context.addResultItem(new ValidationResultItem(ESeverity.error, "XMP Metadata: Version not found") + .setSection(15).setPart(EPart.pdf)); + } - boolean versionValid = false; - for (int i = 0; i < nodes.getLength(); i++) { - final String[] valueArray = {"1.0", "1p0", "2p0", "1.2", "2.0", "2.1", "2.2", "2.3", "3.0"}; //1.2, 2.0, 2.1, 2.2, 2.3 and 3.0 are for xrechnung 1.2, 2p0 can be ZF 2.0, 2.1, 2.1.1 + boolean versionValid = false; + for (int i = 0; i < nodes.getLength(); i++) { + final String[] valueArray = {"1.0", "1p0", "2p0", "1.2", "2.0", "2.1", "2.2", "2.3", "3.0"}; // 1.2, 2.0, 2.1, 2.2, 2.3 and 3.0 are for xrechnung 1.2, 2p0 can be ZF 2.0, 2.1, 2.1.1 - if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { - versionValid = true; - } // e.g. 1.0 - } - if (!versionValid) { - context.addResultItem( - new ValidationResultItem(ESeverity.error, "XMP Metadata: Version contains invalid value") - .setSection(16).setPart(EPart.pdf)); + if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { + versionValid = true; + } // e.g. 1.0 + } + if (!versionValid) { + context.addResultItem( + new ValidationResultItem(ESeverity.error, "XMP Metadata: Version contains invalid value") + .setSection(16).setPart(EPart.pdf)); - } - } catch (final SAXException | IOException | ParserConfigurationException | XPathExpressionException e) { - LOGGER.error(e.getMessage(), e); - } - zfXML = zi.getUTF8(); + } + } catch (final SAXException | IOException | ParserConfigurationException | XPathExpressionException e) { + LOGGER.error(e.getMessage(), e); + } + zfXML = zi.getUTF8(); - // step 3 find signatures - final byte[] symtraxSignature = "Symtrax".getBytes(StandardCharsets.UTF_8); - final byte[] mustangSignature = "via mustangproject".getBytes(StandardCharsets.UTF_8); - final byte[] facturxpythonSignature = "by Alexis de Lattre".getBytes(StandardCharsets.UTF_8); - final byte[] intarsysSignature = "intarsys ".getBytes(StandardCharsets.UTF_8); - final byte[] konikSignature = "Konik".getBytes(StandardCharsets.UTF_8); - final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes(StandardCharsets.UTF_8); - final byte[] ghostscriptSignature = "%%Invocation:".getBytes(StandardCharsets.UTF_8); - final byte[] cibpdfbrewerSignature = "CIB pdf brewer".getBytes(StandardCharsets.UTF_8); - final byte[] lexofficeSignature = "lexoffice".getBytes(StandardCharsets.UTF_8); + // step 3 find signatures + final byte[] symtraxSignature = "Symtrax".getBytes(StandardCharsets.UTF_8); + final byte[] mustangSignature = "via mustangproject".getBytes(StandardCharsets.UTF_8); + final byte[] facturxpythonSignature = "by Alexis de Lattre".getBytes(StandardCharsets.UTF_8); + final byte[] intarsysSignature = "intarsys ".getBytes(StandardCharsets.UTF_8); + final byte[] konikSignature = "Konik".getBytes(StandardCharsets.UTF_8); + final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes(StandardCharsets.UTF_8); + final byte[] ghostscriptSignature = "%%Invocation:".getBytes(StandardCharsets.UTF_8); + final byte[] cibpdfbrewerSignature = "CIB pdf brewer".getBytes(StandardCharsets.UTF_8); + final byte[] lexofficeSignature = "lexoffice".getBytes(StandardCharsets.UTF_8); - if (ByteArraySearcher.contains(fileContents, symtraxSignature)) { - Signature = "Symtrax"; - } else if (ByteArraySearcher.contains(fileContents, mustangSignature)) { - Signature = "Mustang"; - } else if (ByteArraySearcher.contains(fileContents, facturxpythonSignature)) { - Signature = "Factur/X Python"; - } else if (ByteArraySearcher.contains(fileContents, intarsysSignature)) { - Signature = "Intarsys"; - } else if (ByteArraySearcher.contains(fileContents, konikSignature)) { - Signature = "Konik"; - } else if (ByteArraySearcher.contains(fileContents, pdfMachineSignature)) { - Signature = "pdfMachine"; - } else if (ByteArraySearcher.contains(fileContents, ghostscriptSignature)) { - Signature = "Ghostscript"; - } else if (ByteArraySearcher.contains(fileContents, cibpdfbrewerSignature)) { - Signature = "CIB pdf brewer"; - } else if (ByteArraySearcher.contains(fileContents, lexofficeSignature)) { - Signature = "Lexware office"; - } + if (ByteArraySearcher.contains(fileContents, symtraxSignature)) { + Signature = "Symtrax"; + } else if (ByteArraySearcher.contains(fileContents, mustangSignature)) { + Signature = "Mustang"; + } else if (ByteArraySearcher.contains(fileContents, facturxpythonSignature)) { + Signature = "Factur/X Python"; + } else if (ByteArraySearcher.contains(fileContents, intarsysSignature)) { + Signature = "Intarsys"; + } else if (ByteArraySearcher.contains(fileContents, konikSignature)) { + Signature = "Konik"; + } else if (ByteArraySearcher.contains(fileContents, pdfMachineSignature)) { + Signature = "pdfMachine"; + } else if (ByteArraySearcher.contains(fileContents, ghostscriptSignature)) { + Signature = "Ghostscript"; + } else if (ByteArraySearcher.contains(fileContents, cibpdfbrewerSignature)) { + Signature = "CIB pdf brewer"; + } else if (ByteArraySearcher.contains(fileContents, lexofficeSignature)) { + Signature = "Lexware office"; + } - context.setSignature(Signature); + context.setSignature(Signature); - // step 4:validate additional data - final HashMap additionalData = zi.getAdditionalData(); - for (final String filename : additionalData.keySet()) { - // validating xml in byte[] additionalData.get(filename) - LOGGER.info("validating additionalData " + filename); - validateSchema(additionalData.get(filename), "logistics_invoice_0.1/additional_data_base_schema.xsd", 2, EPart.pdf); // schemaPath adapted to new structure - } + // step 4:validate additional data + final HashMap additionalData = zi.getAdditionalData(); + for (final String filename : additionalData.keySet()) { + // validating xml in byte[] additionalData.get(filename) + LOGGER.info("validating additionalData {}", filename); + validateSchema(additionalData.get(filename), "logistics_invoice_0.1/additional_data_base_schema.xsd", 2, EPart.pdf); // schemaPath adapted to new structure + } - //end + // end - final long endTime = Calendar.getInstance().getTimeInMillis(); - if (!processorResult.getValidationResult().isCompliant()) { - context.setInvalid(); - } + final long endTime = Calendar.getInstance().getTimeInMillis(); + if (!processorResult.getValidationResult().isCompliant()) { + context.setInvalid(); + } - PDFAFlavour pdfaFlavourFromValidationResult = processorResult.getValidationResult().getPDFAFlavour(); - if (Arrays.stream(PDF_A_3_FLAVOURS) - .noneMatch(pdfaFlavourFromValidationResult::equals)) { - context.addResultItem( - new ValidationResultItem(ESeverity.error, "Not a PDF/A-3").setSection(23).setPart(EPart.pdf)); + PDFAFlavour pdfaFlavourFromValidationResult = processorResult.getValidationResult().getPDFAFlavour(); + if (Arrays.stream(PDF_A_3_FLAVOURS) + .noneMatch(pdfaFlavourFromValidationResult::equals)) { + context.addResultItem( + new ValidationResultItem(ESeverity.error, "Not a PDF/A-3").setSection(23).setPart(EPart.pdf)); - } - context.addCustomXML(pdfReport + "" - + ((context.getSignature() != null) ? context.getSignature() : "unknown") - + "" + (endTime - startPDFTime) + ""); + } + context.addCustomXML(pdfReport + "" + + (context.getSignature() != null ? context.getSignature() : "unknown") + + "" + (endTime - startPDFTime) + ""); - } + } - @Override - public void setFilename(String filename) throws IrrecoverableValidationError { - this.pdfFilename = filename; - if (autoload) { - try { - fileContents = Files.readAllBytes(Paths.get(pdfFilename)); - } catch (IOException ex) { - throw new IrrecoverableValidationError("Could not read file"); - } - } - } + @Override + public void setFilename(String filename) throws IrrecoverableValidationError { + this.pdfFilename = filename; + if (autoload) { + try { + fileContents = Files.readAllBytes(Path.of(pdfFilename)); + } catch (IOException ex) { + throw new IrrecoverableValidationError("Could not read file"); + } + } + } - public void setFileContents(byte[] fileContents) { - this.fileContents = fileContents; - } + public void setFileContents(byte[] fileContents) { + this.fileContents = fileContents; + } - public void setFilenameAndContents(String filename, byte[] fileContents) { - this.pdfFilename = filename; - this.fileContents = fileContents; - } + public void setFilenameAndContents(String filename, byte[] fileContents) { + this.pdfFilename = filename; + this.fileContents = fileContents; + } - public String getRawXML() { - return zfXML; + public String getRawXML() { + return zfXML; - } + } - public String getSignature() { - return Signature; - } + public String getSignature() { + return Signature; + } } diff --git a/validator/src/main/java/org/mustangproject/validator/ValidationContext.java b/validator/src/main/java/org/mustangproject/validator/ValidationContext.java index 73b95f2..3f50aaa 100755 --- a/validator/src/main/java/org/mustangproject/validator/ValidationContext.java +++ b/validator/src/main/java/org/mustangproject/validator/ValidationContext.java @@ -1,177 +1,178 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.validator; +import org.slf4j.Logger; + import java.util.ArrayList; import java.util.List; import java.util.Vector; -import org.slf4j.Logger; - public class ValidationContext { - protected Vector results; - protected String customXML = ""; - private String format = "CII";// CII or UBL - private String generation = null; // generation 1 is ZF1, gen 2 is ZF2, XRechnung, Factur-X or UBL - private String profile = null; - private String signature = null; - private boolean isValid = true; - protected Logger logger; - private String filename; + protected Vector results; + protected String customXML = ""; + private String format = "CII";// CII or UBL + private String generation = null; // generation 1 is ZF1, gen 2 is ZF2, XRechnung, Factur-X or UBL + private String profile = null; + private String signature = null; + private boolean isValid = true; + protected Logger logger; + private String filename; - public ValidationContext(Logger log) { - logger = log; - results = new Vector<>(); - } + public ValidationContext(Logger log) { + logger = log; + results = new Vector<>(); + } - public void addResultItem(ValidationResultItem vr) throws IrrecoverableValidationError { - results.add(vr); + public void addResultItem(ValidationResultItem vr) throws IrrecoverableValidationError { + results.add(vr); - if ((vr.getSeverity() == ESeverity.fatal) || (vr.getSeverity() == ESeverity.exception) - || (vr.getSeverity() == ESeverity.error)) { - isValid = false; + if ((vr.getSeverity() == ESeverity.fatal) || (vr.getSeverity() == ESeverity.exception) + || (vr.getSeverity() == ESeverity.error)) { + isValid = false; - } - if (logger != null) { - if ((vr.getSeverity() == ESeverity.fatal) || (vr.getSeverity() == ESeverity.exception)) { - logger.error("Fatal Error " + vr.getSection() + ": " + vr.getMessage()); - } else if ((vr.getSeverity() == ESeverity.error)) { - logger.error("Error " + vr.getSection() + ": " + vr.getMessage()); - } else if (vr.getSeverity() == ESeverity.warning) { - logger.warn("Warning " + vr.getSection() + ": " + vr.getMessage()); - } else if (vr.getSeverity() == ESeverity.notice) { - logger.info("Notice " + vr.getSection() + ": " + vr.getMessage()); - } - } + } + if (logger != null) { + if ((vr.getSeverity() == ESeverity.fatal) || (vr.getSeverity() == ESeverity.exception)) { + logger.error("Fatal Error {}: {}", vr.getSection(), vr.getMessage()); + } else if (vr.getSeverity() == ESeverity.error) { + logger.error("Error {}: {}", vr.getSection(), vr.getMessage()); + } else if (vr.getSeverity() == ESeverity.warning) { + logger.warn("Warning {}: {}", vr.getSection(), vr.getMessage()); + } else if (vr.getSeverity() == ESeverity.notice) { + logger.info("Notice {}: {}", vr.getSection(), vr.getMessage()); + } + } - if ((vr.getSeverity() == ESeverity.fatal) || (vr.getSeverity() == ESeverity.exception)) { - throw new IrrecoverableValidationError(vr.getMessage()); - } + if ((vr.getSeverity() == ESeverity.fatal) || (vr.getSeverity() == ESeverity.exception)) { + throw new IrrecoverableValidationError(vr.getMessage()); + } - } + } - public void clearCustomXML() { - customXML = ""; - } - - public void addCustomXML(String XML) { - customXML += XML; - } + public void clearCustomXML() { + customXML = ""; + } - public String getCustomXML() { - return customXML; - } + public void addCustomXML(String XML) { + customXML += XML; + } - public void setFormat(String format) { - this.format=format; - } + public String getCustomXML() { + return customXML; + } - public ValidationContext setGeneration(String version) { - this.generation = version; - return this; - } + public void setFormat(String format) { + this.format = format; + } - public ValidationContext setProfile(String profile) { - this.profile = profile; - return this; - } + public ValidationContext setGeneration(String version) { + this.generation = version; + return this; + } - public ValidationContext setSignature(String signature) { - this.signature = signature; - return this; - } + public ValidationContext setProfile(String profile) { + this.profile = profile; + return this; + } - public String getGeneration() { - return generation; - } + public ValidationContext setSignature(String signature) { + this.signature = signature; + return this; + } - public String getProfile() { - return profile; - } + public String getGeneration() { + return generation; + } - public String getSignature() { - return signature; - } + public String getProfile() { + return profile; + } - public boolean isValid() { - return isValid; - } + public String getSignature() { + return signature; + } - public void clear() { - results.clear(); - isValid = true; - clearCustomXML(); - generation = null; - profile = null; - signature = null; + public boolean isValid() { + return isValid; + } - } + public void clear() { + results.clear(); + isValid = true; + clearCustomXML(); + generation = null; + profile = null; + signature = null; - public String getXMLResult() { - String res = getCustomXML(); - if (results.size() > 0) { - res += ""; - } + } - for (final ValidationResultItem validationResultItem : results) { - // xml and pdf are handled in their respective sections - res += validationResultItem.getXMLOnce() + "\n"; - } - if (results.size() > 0) { - res += ""; - } - res += "

"; - return res; - } + public String getXMLResult() { + String res = getCustomXML(); + if (results.size() > 0) { + res += ""; + } - /*** - * - * @return the unique error types as comma separated string - */ - public String getCSVResult() { - final ArrayList errorcodes = new ArrayList<>(); - for (final ValidationResultItem validationResultItem : results) { - final String errorCodeStr=Integer.toString(validationResultItem.getSection()); - errorcodes.add(errorCodeStr); - } - return String.join(",", errorcodes); - } + for (final ValidationResultItem validationResultItem : results) { + // xml and pdf are handled in their respective sections + res += validationResultItem.getXMLOnce() + "\n"; + } + if (results.size() > 0) { + res += ""; + } + res += ""; + return res; + } - /*** - * - * @return the unique error IDs as comma separated string - */ - public String getCSVIDResult() { - final ArrayList errorIDs = new ArrayList<>(); - for (final ValidationResultItem validationResultItem : results) { - if (!validationResultItem.getID().isEmpty()) { - final String errorID=validationResultItem.getID(); - errorIDs.add(errorID); + /*** + * + * @return the unique error types as comma separated string + */ + public String getCSVResult() { + final ArrayList errorcodes = new ArrayList<>(); + for (final ValidationResultItem validationResultItem : results) { + final String errorCodeStr = Integer.toString(validationResultItem.getSection()); + errorcodes.add(errorCodeStr); + } + return String.join(",", errorcodes); + } - } - } - return String.join(",", errorIDs); - } + /*** + * + * @return the unique error IDs as comma separated string + */ + public String getCSVIDResult() { + final ArrayList errorIDs = new ArrayList<>(); + for (final ValidationResultItem validationResultItem : results) { + if (!validationResultItem.getID().isEmpty()) { + final String errorID = validationResultItem.getID(); + errorIDs.add(errorID); - public void setInvalid() { - isValid = false; - } + } + } + return String.join(",", errorIDs); + } - public void setFilename(String filename) { - this.filename=filename; - } - public String getFilename() { - if (filename==null) { - return ""; - } else { - return filename; - } - } + public void setInvalid() { + isValid = false; + } - public String getFormat() { - return format; - } + public void setFilename(String filename) { + this.filename = filename; + } - public List getResults() { - return results; - } + public String getFilename() { + if (filename == null) { + return ""; + } else { + return filename; + } + } + + public String getFormat() { + return format; + } + + public List getResults() { + return results; + } } diff --git a/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java b/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java index b0d6b5a..c3ac417 100755 --- a/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java +++ b/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java @@ -5,124 +5,131 @@ org.openrewrite.config.CompositeRecipe import org.slf4j.LoggerFactory; public class ValidationResultItem { - private static final Logger LOGGER = LoggerFactory.getLogger(ValidationResultItem.class.getCanonicalName()); // log output is - // ignored for the - // time being + private static final Logger LOGGER = LoggerFactory.getLogger(ValidationResultItem.class.getCanonicalName()); // log output is + // ignored for the + // time being - - protected String message, location=null; - protected int section =-1; - protected String id =""; // e.g. "FX-SCH-A-000026" + + protected String message, location = null; + protected int section = -1; + protected String id = ""; // e.g. "FX-SCH-A-000026" - private ESeverity severity=ESeverity.error; - private String criterion=null; + private ESeverity severity = ESeverity.error; + private String criterion = null; - private String stacktrace=null; - private boolean hasBeenOutputted=false; + private String stacktrace = null; + private boolean hasBeenOutputted = false; - private EPart part; - private XMLTools xt; + private EPart part; + private XMLTools xt; - public ValidationResultItem(ESeverity sev, String msg) { - setSeverity(sev); - setMessage(msg); - xt=new XMLTools(); - } - public ValidationResultItem setMessage(String msg) { - message=msg; - return this; - } + public ValidationResultItem(ESeverity sev, String msg) { + setSeverity(sev); + setMessage(msg); + xt = new XMLTools(); + } - public ValidationResultItem setSection(int sec) { - section=sec; - return this; - } - public ValidationResultItem setLocation(String loc) { - location=loc; - return this; - } - public ValidationResultItem setPart(EPart loc) { - part=loc; - return this; - } - public EPart getPart() { - return part; - } - public ValidationResultItem setSeverity(ESeverity sev) { - severity=sev; - return this; - } - public ValidationResultItem setStacktrace(String stack) { - stacktrace=stack; - return this; - } - - - public String getXML() { - String tagname="error"; - if (severity==ESeverity.exception) { - tagname="exception"; - } else if (severity==ESeverity.warning) { - tagname="warning"; - } else if (severity==ESeverity.notice) { - tagname="notice"; - } - String additionalAttributes=""; - String additionalContents=""; - if (section!=-1) { - additionalAttributes+=" type=\""+section+"\""; - } - if (location!=null) { - additionalAttributes+=" location=\""+xt.escapeAttributeEntities(location)+"\""; - } - if (criterion!=null) { - additionalAttributes+=" criterion=\""+xt.escapeAttributeEntities(criterion)+"\""; - } - if (stacktrace!=null) { - additionalContents+=""+xt.escapeAttributeEntities(stacktrace)+""; - } - hasBeenOutputted=true; - return "<"+tagname+additionalAttributes+">"+xt.escapeElementEntities(message+additionalContents)+""; - } - - public String getXMLOnce() { - if (!hasBeenOutputted) { - return getXML(); - } else { - return ""; - } - } - - public ValidationResultItem setCriterion(String test) { - criterion = test; - return this; - } - public ESeverity getSeverity() { - return severity; - } + public ValidationResultItem setMessage(String msg) { + message = msg; + return this; + } - public ValidationResultItem setID(String id) { - this.id=id; - return this; - } + public ValidationResultItem setSection(int sec) { + section = sec; + return this; + } - public String getID() { - return id; - } + public ValidationResultItem setLocation(String loc) { + location = loc; + return this; + } - public int getSection() { - return section; - } + public ValidationResultItem setPart(EPart loc) { + part = loc; + return this; + } - public String getMessage() { - return message; - } + public EPart getPart() { + return part; + } - public String getLocation() { - return location; - } + public ValidationResultItem setSeverity(ESeverity sev) { + severity = sev; + return this; + } + + public ValidationResultItem setStacktrace(String stack) { + stacktrace = stack; + return this; + } + + + public String getXML() { + String tagname = "error"; + if (severity == ESeverity.exception) { + tagname = "exception"; + } else if (severity == ESeverity.warning) { + tagname = "warning"; + } else if (severity == ESeverity.notice) { + tagname = "notice"; + } + String additionalAttributes = ""; + String additionalContents = ""; + if (section != -1) { + additionalAttributes += " type=\"" + section + "\""; + } + if (location != null) { + additionalAttributes += " location=\"" + xt.escapeAttributeEntities(location) + "\""; + } + if (criterion != null) { + additionalAttributes += " criterion=\"" + xt.escapeAttributeEntities(criterion) + "\""; + } + if (stacktrace != null) { + additionalContents += "" + xt.escapeAttributeEntities(stacktrace) + ""; + } + hasBeenOutputted = true; + return "<" + tagname + additionalAttributes + ">" + xt.escapeElementEntities(message + additionalContents) + ""; + } + + public String getXMLOnce() { + if (!hasBeenOutputted) { + return getXML(); + } else { + return ""; + } + } + + public ValidationResultItem setCriterion(String test) { + criterion = test; + return this; + } + + public ESeverity getSeverity() { + return severity; + } + + public ValidationResultItem setID(String id) { + this.id = id; + return this; + } + + public String getID() { + return id; + } + + public int getSection() { + return section; + } + + public String getMessage() { + return message; + } + + public String getLocation() { + return location; + } } diff --git a/validator/src/main/java/org/mustangproject/validator/Validator.java b/validator/src/main/java/org/mustangproject/validator/Validator.java index 9da9517..dab3eb3 100755 --- a/validator/src/main/java/org/mustangproject/validator/Validator.java +++ b/validator/src/main/java/org/mustangproject/validator/Validator.java @@ -1,93 +1,92 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.validator; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.URL; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; import javax.xml.XMLConstants; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.net.URL; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.xml.sax.SAXException; - -//abstract class +// abstract class public abstract class Validator { - private static final Logger LOGGER = LoggerFactory.getLogger(Validator.class.getCanonicalName()); // log output + private static final Logger LOGGER = LoggerFactory.getLogger(Validator.class.getCanonicalName()); // log output - protected ValidationContext context; - protected boolean autoload = true; + protected ValidationContext context; + protected boolean autoload = true; - public Validator(ValidationContext ctx) { - this.context = ctx; - } + public Validator(ValidationContext ctx) { + this.context = ctx; + } - //abstract method + // abstract method - /*** - * prepare validation - * @param filename the filename of the xml file to be examined - * @throws IrrecoverableValidationError when any fatal errors arise, e.g. when the source file can not be found - */ - public abstract void setFilename(String filename) throws IrrecoverableValidationError; + /*** + * prepare validation + * @param filename the filename of the xml file to be examined + * @throws IrrecoverableValidationError when any fatal errors arise, e.g. when the source file can not be found + */ + public abstract void setFilename(String filename) throws IrrecoverableValidationError; - /*** - * perform the validation - * @throws IrrecoverableValidationError any fatal errors, e.g. when the source file can not be found - */ - public abstract void validate() throws IrrecoverableValidationError; + /*** + * perform the validation + * @throws IrrecoverableValidationError any fatal errors, e.g. when the source file can not be found + */ + public abstract void validate() throws IrrecoverableValidationError; - /** - * get validation result - * - * @return validation result as xml string - */ - public String getXMLResult() { - return context.getXMLResult(); - } + /** + * get validation result + * + * @return validation result as xml string + */ + public String getXMLResult() { + return context.getXMLResult(); + } - /*** - * validates a schema, which can only be needed in XML validation - and in pdf validation for additional data - * @param xmlRawData the XML to be validated - * @param schemaPath the filename of the schema file - * @param section the error message type code - * @param part whether the error message occurs in the pdf or xml part - * @throws IrrecoverableValidationError when any fatal errors arise, e.g. when the source file can not be found - */ - protected void validateSchema(byte[] xmlRawData, String schemaPath, int section, EPart part) throws IrrecoverableValidationError { - LOGGER.debug( - "protected void validateSchema(byte[] xmlRawData, String schemaPath='{}', int section={}, EPart part={})", - schemaPath, - section, - part - ); - URL schemaFile = Thread.currentThread().getContextClassLoader().getResource(schemaPath); // Prefix "schema/" not needed anymore. - Source xmlData = new StreamSource(new ByteArrayInputStream(xmlRawData)); - SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - try { - Schema schema = schemaFactory.newSchema(schemaFile); - javax.xml.validation.Validator validator = schema.newValidator(); - validator.validate(xmlData); - } catch (SAXException e) { - context.addResultItem(new ValidationResultItem(ESeverity.error, "schema validation fails:" + e) - .setSection(section).setPart(part)); - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); - } + /*** + * validates a schema, which can only be needed in XML validation - and in pdf validation for additional data + * @param xmlRawData the XML to be validated + * @param schemaPath the filename of the schema file + * @param section the error message type code + * @param part whether the error message occurs in the pdf or xml part + * @throws IrrecoverableValidationError when any fatal errors arise, e.g. when the source file can not be found + */ + protected void validateSchema(byte[] xmlRawData, String schemaPath, int section, EPart part) throws IrrecoverableValidationError { + LOGGER.debug( + "protected void validateSchema(byte[] xmlRawData, String schemaPath='{}', int section={}, EPart part={})", + schemaPath, + section, + part + ); + URL schemaFile = Thread.currentThread().getContextClassLoader().getResource(schemaPath); // Prefix "schema/" not needed anymore. + Source xmlData = new StreamSource(new ByteArrayInputStream(xmlRawData)); + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + try { + Schema schema = schemaFactory.newSchema(schemaFile); + javax.xml.validation.Validator validator = schema.newValidator(); + validator.validate(xmlData); + } catch (SAXException e) { + context.addResultItem(new ValidationResultItem(ESeverity.error, "schema validation fails:" + e) + .setSection(section).setPart(part)); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); + } - } + } - public ValidationContext getValidationContext() { - return context; - } + public ValidationContext getValidationContext() { + return context; + } - public void setAutoload(boolean autoload) { - this.autoload = autoload; - } + public void setAutoload(boolean autoload) { + this.autoload = autoload; + } } diff --git a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java index 91fb723..8a94cc3 100755 --- a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java @@ -1,24 +1,9 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.validator; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.UncheckedIOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Calendar; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.stream.StreamSource; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - +import com.helger.schematron.ISchematronResource; +import com.helger.schematron.svrl.SVRLMarshaller; +import com.helger.schematron.svrl.jaxb.SchematronOutputType; +import com.helger.schematron.xslt.SchematronResourceXSLT; import org.mustangproject.XMLTools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,565 +13,578 @@ import org.w3c.dom.NodeList; import org.xml.sax.InputSource; -import com.helger.schematron.ISchematronResource; -import com.helger.schematron.svrl.SVRLMarshaller; -import com.helger.schematron.svrl.jaxb.SchematronOutputType; -import com.helger.schematron.xslt.SchematronResourceXSLT; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.stream.StreamSource; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Calendar; public class XMLValidator extends Validator { - private static final Logger LOGGER = LoggerFactory.getLogger(XMLValidator.class.getCanonicalName()); - // log output is ignored for the time being + private static final Logger LOGGER = LoggerFactory.getLogger(XMLValidator.class.getCanonicalName()); + // log output is ignored for the time being - private static final String INVOICE = "Invoice"; - private static final String UNSUPPORTED_PROFILE_TYPE = "Unsupported profile type: '%s'"; + private static final String INVOICE = "Invoice"; + private static final String UNSUPPORTED_PROFILE_TYPE = "Unsupported profile type: '%s'"; - protected String zfXML = ""; - protected String filename = ""; - int firedRules = 0; - int failedRules = 0; - boolean disableNotices = false; + protected String zfXML = ""; + protected String filename = ""; + int firedRules = 0; + int failedRules = 0; + boolean disableNotices = false; - public XMLValidator(ValidationContext ctx) { - super(ctx); - } + public XMLValidator(ValidationContext ctx) { + super(ctx); + } - /*** - * set source file - * @param name the absolute filename of an XML file to validate - * @throws IrrecoverableValidationError if e.g. the file can not be found, or does not contain XML, so no further validation can take place - */ - @Override - public void setFilename(String name) throws IrrecoverableValidationError { // from XML Filename - LOGGER.debug("public void setFilename(String name='{}')", name); - filename = name; - // file existence must have been checked before - if (autoload) { - try { - zfXML = new String(XMLTools.removeBOM(Files.readAllBytes(Paths.get(filename))), StandardCharsets.UTF_8); - } catch (final IOException e) { + /*** + * set source file + * @param name the absolute filename of an XML file to validate + * @throws IrrecoverableValidationError if e.g. the file can not be found, or does not contain XML, so no further validation can take place + */ + @Override + public void setFilename(String name) throws IrrecoverableValidationError { // from XML Filename + LOGGER.debug("public void setFilename(String name='{}')", name); + filename = name; + // file existence must have been checked before + if (autoload) { + try { + zfXML = new String(XMLTools.removeBOM(Files.readAllBytes(Path.of(filename))), StandardCharsets.UTF_8); + } catch (final IOException e) { - final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9) - .setPart(EPart.fx); - try (final StringWriter sw = new StringWriter(); + final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9) + .setPart(EPart.fx); + try (final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw)) { - e.printStackTrace(pw); - vri.setStacktrace(sw.toString()); - context.addResultItem(vri); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - } + LOGGER.error("Exception", e); + vri.setStacktrace(sw.toString()); + context.addResultItem(vri); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } - } + } - } + } - /*** - * manually set the xml content - * @param xml the xml to be checked - */ - public void setStringContent(String xml) { - zfXML = xml; - } + /*** + * manually set the xml content + * @param xml the xml to be checked + */ + public void setStringContent(String xml) { + zfXML = xml; + } - /** - * whether uri1 has the same meaning as uri1 (it has, if it only differs in the fragment, i.e. uri1#1==uri1#2 ) - * - * @param uri1 basis guideline ID - * @param uri2 guideline ID to be checked - * @return true if semantically identical - */ - public static boolean matchesURI(String uri1, String uri2) { - return (uri1.equals(uri2) || uri1.startsWith(uri2 + "#")); - } + /** + * whether uri1 has the same meaning as uri1 (it has, if it only differs in the fragment, i.e. uri1#1==uri1#2 ) + * + * @param uri1 basis guideline ID + * @param uri2 guideline ID to be checked + * @return true if semantically identical + */ + public static boolean matchesURI(String uri1, String uri2) { + return uri1.equals(uri2) || uri1.startsWith(uri2 + "#"); + } - /*** - * don't report notices in validation report - */ - public void disableNotices() { - disableNotices = true; - } + /*** + * don't report notices in validation report + */ + public void disableNotices() { + disableNotices = true; + } - /*** - * perform validation - * @throws IrrecoverableValidationError if any fatal errors occur, e.g. source file can not be read - */ - @Override - public void validate() throws IrrecoverableValidationError { - final long startXMLTime = Calendar.getInstance().getTimeInMillis(); - firedRules = 0; - failedRules = 0; + /*** + * perform validation + * @throws IrrecoverableValidationError if any fatal errors occur, e.g. source file can not be read + */ + @Override + public void validate() throws IrrecoverableValidationError { + final long startXMLTime = Calendar.getInstance().getTimeInMillis(); + firedRules = 0; + failedRules = 0; - if (zfXML.isEmpty()) { - final ValidationResultItem res = new ValidationResultItem(ESeverity.exception, - "XML data not found in " + filename - + ": did you specify a pdf or xml file and does the xml file contain an embedded XML file?") - .setSection(3); - context.addResultItem(res); + if (zfXML.isEmpty()) { + final ValidationResultItem res = new ValidationResultItem(ESeverity.exception, + "XML data not found in " + filename + + ": did you specify a pdf or xml file and does the xml file contain an embedded XML file?") + .setSection(3); + context.addResultItem(res); - } else { + } else { - // final ISchematronResource aResSCH = - // SchematronResourceSCH.fromFile (new File("ZUGFeRD_1p0.scmt")); - // ... DOES work but is highly deprecated (and rightly so) because - // it takes 30-40min, + // final ISchematronResource aResSCH = + // SchematronResourceSCH.fromFile (new File("ZUGFeRD_1p0.scmt")); + // ... DOES work but is highly deprecated (and rightly so) because + // it takes 30-40min, - try { - ESeverity severity = ESeverity.notice; - /* - * private static final String VALID_SCHEMATRON = "test-sch/valid01.sch"; - * private static final String VALID_XMLINSTANCE = "test-xml/valid01.xml"; - * - * @Test public void testWriteValid () throws Exception { final Document aDoc = - * SchematronResourceSCH.fromClassPath (VALID_SCHEMATRON) - * .applySchematronValidation (new ClassPathResource (VALID_XMLINSTANCE)); - * - */ + try { + ESeverity severity = ESeverity.notice; + /* + * private static final String VALID_SCHEMATRON = "test-sch/valid01.sch"; + * private static final String VALID_XMLINSTANCE = "test-xml/valid01.xml"; + * + * @Test public void testWriteValid () throws Exception { final Document aDoc = + * SchematronResourceSCH.fromClassPath (VALID_SCHEMATRON) + * .applySchematronValidation (new ClassPathResource (VALID_XMLINSTANCE)); + * + */ - final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); // otherwise we can not act namespace independently, i.e. use - // document.getElementsByTagNameNS("*",... + final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); // otherwise we can not act namespace independently, i.e. use + // document.getElementsByTagNameNS("*",... - final DocumentBuilder db = dbf.newDocumentBuilder(); - final InputSource is = new InputSource(new StringReader(zfXML)); - final Document doc = db.parse(is); + final DocumentBuilder db = dbf.newDocumentBuilder(); + final InputSource is = new InputSource(new StringReader(zfXML)); + final Document doc = db.parse(is); - final Element root = doc.getDocumentElement(); + final Element root = doc.getDocumentElement(); - final NodeList ndList; + final NodeList ndList; - // rootNode = document.getDocumentElement(); - // ApplicableSupplyChainTradeSettlement + // rootNode = document.getDocumentElement(); + // ApplicableSupplyChainTradeSettlement - // Create XPathFactory object - final XPathFactory xpathFactory = XPathFactory.newInstance(); + // Create XPathFactory object + final XPathFactory xpathFactory = XPathFactory.newInstance(); - // Create XPath object - final XPath xpath = xpathFactory.newXPath(); - final XPathExpression expr = xpath.compile( - "(//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/*[local-name()=\"ID\"])/text()|//*[local-name()=\"CustomizationID\"]/text()"); - // evaluate expression result on XML document - ndList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); + // Create XPath object + final XPath xpath = xpathFactory.newXPath(); + final XPathExpression expr = xpath.compile( + "(//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/*[local-name()=\"ID\"])/text()|//*[local-name()=\"CustomizationID\"]/text()"); + // evaluate expression result on XML document + ndList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); - for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { - final Node booking = ndList.item(bookingIndex); - // if there is an attribute in the tag number:value - // urn:ferd:CrossIndustryDocument:invoice:1p0:extended - // setForeignReference(booking.getTextContent()); + for (int bookingIndex = 0; bookingIndex < ndList.getLength(); bookingIndex++) { + final Node booking = ndList.item(bookingIndex); + // if there is an attribute in the tag number:value + // urn:ferd:CrossIndustryDocument:invoice:1p0:extended + // setForeignReference(booking.getTextContent()); - context.setProfile(booking.getNodeValue()); - } - boolean isOrderX = false; - boolean isMinimum; - boolean isBasic = false; - boolean isBasicWithoutLines; - boolean isEN16931 = false; - boolean isExtended; - boolean isXRechnung = false; - int mainSchematronSectionErrorTypeCode = 4; - String xsltFilename = null; - // urn:ferd:CrossIndustryDocument:invoice:1p0:extended, - // urn:ferd:CrossIndustryDocument:invoice:1p0:comfort, - // urn:ferd:CrossIndustryDocument:invoice:1p0:basic, + context.setProfile(booking.getNodeValue()); + } + boolean isOrderX = false; + boolean isMinimum; + boolean isBasic = false; + boolean isBasicWithoutLines; + boolean isEN16931 = false; + boolean isExtended; + boolean isXRechnung = false; + int mainSchematronSectionErrorTypeCode = 4; + String xsltFilename = null; + // urn:ferd:CrossIndustryDocument:invoice:1p0:extended, + // urn:ferd:CrossIndustryDocument:invoice:1p0:comfort, + // urn:ferd:CrossIndustryDocument:invoice:1p0:basic, - // urn:cen.eu:en16931:2017 - // urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:basic - if (root.getLocalName().equalsIgnoreCase("SCRDMCCBDACIOMessageStructure")) { - context.setGeneration("1"); - isOrderX = true; - isBasic = context.getProfile().contains("basic"); - isEN16931 = context.getProfile().contains("comfort"); - isExtended = context.getProfile().contains("extended"); - if (isBasic) { - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.OX_10_BASIC), 99, EPart.ox); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.OX_10_BASIC); - } else if (isExtended) { - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.OX_10_EXTENDED), 99, EPart.ox); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.OX_10_EXTENDED); - } else { - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.OX_10_COMFORT), 99, EPart.ox); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.OX_10_COMFORT); - } + // urn:cen.eu:en16931:2017 + // urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:basic + if (root.getLocalName().equalsIgnoreCase("SCRDMCCBDACIOMessageStructure")) { + context.setGeneration("1"); + isOrderX = true; + isBasic = context.getProfile().contains("basic"); + isEN16931 = context.getProfile().contains("comfort"); + isExtended = context.getProfile().contains("extended"); + if (isBasic) { + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.OX_10_BASIC), 99, EPart.ox); + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.OX_10_BASIC); + } else if (isExtended) { + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.OX_10_EXTENDED), 99, EPart.ox); + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.OX_10_EXTENDED); + } else { + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.OX_10_COMFORT), 99, EPart.ox); + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.OX_10_COMFORT); + } - } else if (root.getLocalName().equalsIgnoreCase("CrossIndustryInvoice")) { // ZUGFeRD 2.0 or Factur-X - context.setGeneration("2"); + } else if (root.getLocalName().equalsIgnoreCase("CrossIndustryInvoice")) { // ZUGFeRD 2.0 or Factur-X + context.setGeneration("2"); - isMinimum = context.getProfile().contains("minimum"); - isBasic = context.getProfile().contains("basic"); - isBasicWithoutLines = context.getProfile().contains("basicwl"); - if (isBasicWithoutLines) { - isBasic = false;// basicwl also contains the string basic... - } - isEN16931 = matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931") - || matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017"); + isMinimum = context.getProfile().contains("minimum"); + isBasic = context.getProfile().contains("basic"); + isBasicWithoutLines = context.getProfile().contains("basicwl"); + if (isBasicWithoutLines) { + isBasic = false;// basicwl also contains the string basic... + } + isEN16931 = matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931") + || matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017"); - isExtended = context.getProfile().contains("extended"); - isXRechnung = context.getProfile().contains("xrechnung"); + isExtended = context.getProfile().contains("extended"); + isXRechnung = context.getProfile().contains("xrechnung"); - if ((isExtended) || (isXRechnung)) { - isEN16931 = false;// the uri for extended is urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended and thus contains en16931... - } - if (isMinimum) { - LOGGER.debug("is Minimum"); - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_MINIMUM), 18, EPart.fx); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_MINIMUM); - } else if (isBasicWithoutLines) { - LOGGER.debug("is Basic/WL"); - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_BASIC_WL), 18, EPart.fx); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_BASIC_WL); - } else if (isBasic) { - LOGGER.debug("is Basic"); - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_BASIC), 18, EPart.fx); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_BASIC); - } else if (isEN16931) { - LOGGER.debug("is EN16931"); - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_EN16931), 18, EPart.fx); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_EN16931); - } else if (isXRechnung) { - LOGGER.debug("is XRechnung"); - /* - the validation against the XRechnung Schematron will happen below but a - XRechnung is a EN16931 subset so the validation vis a vis FACTUR-X_EN16931.xslt=schematron also has to pass - * */ - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_EN16931), 18, EPart.fx); + if (isExtended || isXRechnung) { + isEN16931 = false;// the uri for extended is urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended and thus contains en16931... + } + if (isMinimum) { + LOGGER.debug("is Minimum"); + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_MINIMUM), 18, EPart.fx); + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_MINIMUM); + } else if (isBasicWithoutLines) { + LOGGER.debug("is Basic/WL"); + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_BASIC_WL), 18, EPart.fx); + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_BASIC_WL); + } else if (isBasic) { + LOGGER.debug("is Basic"); + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_BASIC), 18, EPart.fx); + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_BASIC); + } else if (isEN16931) { + LOGGER.debug("is EN16931"); + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_EN16931), 18, EPart.fx); + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_EN16931); + } else if (isXRechnung) { + LOGGER.debug("is XRechnung"); + /* + the validation against the XRechnung Schematron will happen below but a + XRechnung is a EN16931 subset so the validation vis a vis FACTUR-X_EN16931.xslt=schematron also has to pass + * */ + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_EN16931), 18, EPart.fx); - severity = ESeverity.error; - } else if (isExtended) { - LOGGER.debug("is EXTENDED"); - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_EXTENDED), 18, EPart.fx); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_EXTENDED); - } + severity = ESeverity.error; + } else if (isExtended) { + LOGGER.debug("is EXTENDED"); + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_23_EXTENDED), 18, EPart.fx); + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_23_EXTENDED); + } - // takes around 10 Seconds. // - // http://www.bentoweb.org/refs/TCDL2.0/tsdtf_schematron.html // explains that - // this xslt can be created using sth like - // saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s - // tcdl2.0.tsdtf.sch iso_svrl.xsl + // takes around 10 Seconds. // + // http://www.bentoweb.org/refs/TCDL2.0/tsdtf_schematron.html // explains that + // this xslt can be created using sth like + // saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s + // tcdl2.0.tsdtf.sch iso_svrl.xsl - } else if (root.getLocalName().equalsIgnoreCase(INVOICE) || root.getLocalName().equalsIgnoreCase("CreditNote")) { - String profile = context.getProfile(); - String rootName = root.getLocalName(); - context.setGeneration("2"); - context.setFormat("UBL"); - isXRechnung = profile.contains("xrechnung"); - // UBL - LOGGER.debug("UBL"); - if (rootName.equalsIgnoreCase(INVOICE)) { - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.UBL_24_INVOICE), 18, EPart.fx); - } else { - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.UBL_24_CREDIT_NOTE), 18, EPart.fx); - } - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.EN16931_UBL); + } else if (root.getLocalName().equalsIgnoreCase(INVOICE) || root.getLocalName().equalsIgnoreCase("CreditNote")) { + String profile = context.getProfile(); + String rootName = root.getLocalName(); + context.setGeneration("2"); + context.setFormat("UBL"); + isXRechnung = profile.contains("xrechnung"); + // UBL + LOGGER.debug("UBL"); + if (rootName.equalsIgnoreCase(INVOICE)) { + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.UBL_24_INVOICE), 18, EPart.fx); + } else { + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.UBL_24_CREDIT_NOTE), 18, EPart.fx); + } + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.EN16931_UBL); - mainSchematronSectionErrorTypeCode = 24; + mainSchematronSectionErrorTypeCode = 24; - if (isXRechnung) { - validateSchematron(zfXML, xsltFilename, 24, ESeverity.error); - /* - the validation against the XRechnung Schematron will happen below but a - XRechnung is a EN16931 subset so the validation vis a vis FACTUR-X_EN16931.xslt=schematron also has to pass - * */ - //validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_211/EN16931/FACTUR-X_EN16931.xsd", 18, EPart.fx); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(getVersion(getXRVersion(profile), rootName)); - severity = ESeverity.error; - mainSchematronSectionErrorTypeCode = 27; + if (isXRechnung) { + validateSchematron(zfXML, xsltFilename, 24, ESeverity.error); + /* + the validation against the XRechnung Schematron will happen below but a + XRechnung is a EN16931 subset so the validation vis a vis FACTUR-X_EN16931.xslt=schematron also has to pass + * */ + // validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_211/EN16931/FACTUR-X_EN16931.xsd", 18, EPart.fx); + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(getVersion(getXRVersion(profile), rootName)); + severity = ESeverity.error; + mainSchematronSectionErrorTypeCode = 27; - } + } - } else if (root.getLocalName().equalsIgnoreCase("CrossIndustryDocument")) { // ZUGFeRD 1.0 - context.setGeneration("1"); - // - if ((!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { - context.addResultItem(new ValidationResultItem(ESeverity.error, String.format(UNSUPPORTED_PROFILE_TYPE, context.getProfile())) - .setSection(25).setPart(EPart.fx)); - } - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_10), 18, EPart.fx); + } else if (root.getLocalName().equalsIgnoreCase("CrossIndustryDocument")) { // ZUGFeRD 1.0 + context.setGeneration("1"); + // + if ((!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")) + && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) + && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { + context.addResultItem(new ValidationResultItem(ESeverity.error, String.format(UNSUPPORTED_PROFILE_TYPE, context.getProfile())) + .setSection(25).setPart(EPart.fx)); + } + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), SchemesPerVersion.mapOfSchemesPerVersion.get(EVersion.ZF_10), 18, EPart.fx); - xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_10); - } else { // unknown document root - context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Unsupported root element") - .setSection(3).setPart(EPart.fx)); - } - if (context.getFormat().equals("CII")) { + xsltFilename = ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.ZF_10); + } else { // unknown document root + context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Unsupported root element") + .setSection(3).setPart(EPart.fx)); + } + if (context.getFormat().equals("CII")) { - if (context.getGeneration().equals("2")) { - if ((!matchesURI(context.getProfile(), "urn:factur-x.eu:1p0:minimum")) - && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:minimum")) - && (!matchesURI(context.getProfile(), "urn:factur-x.eu:1p0:basicwl")) - && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:basicwl")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:basic")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended"))) { - context.addResultItem( - new ValidationResultItem(ESeverity.error, String.format(UNSUPPORTED_PROFILE_TYPE, context.getProfile())) - .setSection(25).setPart(EPart.fx)); + if (context.getGeneration().equals("2")) { + if ((!matchesURI(context.getProfile(), "urn:factur-x.eu:1p0:minimum")) + && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:minimum")) + && (!matchesURI(context.getProfile(), "urn:factur-x.eu:1p0:basicwl")) + && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:basicwl")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:basic")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended"))) { + context.addResultItem( + new ValidationResultItem(ESeverity.error, String.format(UNSUPPORTED_PROFILE_TYPE, context.getProfile())) + .setSection(25).setPart(EPart.fx)); - } - } else /* v1 */ { - if (isOrderX) { - //order-x 1.0 - if ((!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:comfort")) - && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:extended"))) { - //zf 1.0 - context.addResultItem(new ValidationResultItem(ESeverity.error, String.format(UNSUPPORTED_PROFILE_TYPE, context.getProfile())) - .setSection(25).setPart(EPart.fx)); + } + } else /* v1 */ { + if (isOrderX) { + // order-x 1.0 + if ((!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:basic")) + && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:comfort")) + && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:extended"))) { + // zf 1.0 + context.addResultItem(new ValidationResultItem(ESeverity.error, String.format(UNSUPPORTED_PROFILE_TYPE, context.getProfile())) + .setSection(25).setPart(EPart.fx)); - } - } else if ((!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { - //zf 1.0 - context.addResultItem(new ValidationResultItem(ESeverity.error, String.format(UNSUPPORTED_PROFILE_TYPE, context.getProfile())) - .setSection(25).setPart(EPart.fx)); + } + } else if ((!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")) + && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) + && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { + // zf 1.0 + context.addResultItem(new ValidationResultItem(ESeverity.error, String.format(UNSUPPORTED_PROFILE_TYPE, context.getProfile())) + .setSection(25).setPart(EPart.fx)); - } - } - } + } + } + } - if (xsltFilename != null) { - // main schematron validation - validateSchematron(zfXML, xsltFilename, mainSchematronSectionErrorTypeCode, ESeverity.error); + if (xsltFilename != null) { + // main schematron validation + validateSchematron(zfXML, xsltFilename, mainSchematronSectionErrorTypeCode, ESeverity.error); - } + } - if (context.getFormat().equals("CII") && context.getGeneration().equals("2") - && (isBasic || isEN16931 || isXRechnung)) { - //additionally validate against CEN - validateSchematron(zfXML, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.EN16931_CII), 24, ESeverity.error); - if (!disableNotices || severity != ESeverity.notice) { - validateXR(zfXML, severity); - } - } + if (context.getFormat().equals("CII") && context.getGeneration().equals("2") + && (isBasic || isEN16931 || isXRechnung)) { + // additionally validate against CEN + validateSchematron(zfXML, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.EN16931_CII), 24, ESeverity.error); + if (!disableNotices || severity != ESeverity.notice) { + validateXR(zfXML, severity); + } + } - } catch (final IrrecoverableValidationError er) { - throw er; - } catch (final Exception e) { - final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(22) - .setPart(EPart.fx); - try (final StringWriter sw = new StringWriter(); + } catch (final IrrecoverableValidationError er) { + throw er; + } catch (final Exception e) { + final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(22) + .setPart(EPart.fx); + try (final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw)) { - e.printStackTrace(pw); - vri.setStacktrace(sw.toString()); - context.addResultItem(vri); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - } + LOGGER.error("Exception", e); + vri.setStacktrace(sw.toString()); + context.addResultItem(vri); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } - } - final long endTime = Calendar.getInstance().getTimeInMillis(); + } + final long endTime = Calendar.getInstance().getTimeInMillis(); - context.addCustomXML("" + ((context.getGeneration() != null) ? context.getGeneration() : "invalid") - + "" + ((context.getProfile() != null) ? context.getProfile() : "invalid") + - "" + firedRules + "" + failedRules + "" + "" + (endTime - startXMLTime) + ""); + context.addCustomXML("" + (context.getGeneration() != null ? context.getGeneration() : "invalid") + + "" + (context.getProfile() != null ? context.getProfile() : "invalid") + + "" + firedRules + "" + failedRules + "" + "" + (endTime - startXMLTime) + ""); - } + } - private String getXRVersion(final String profile) throws IllegalArgumentException { - String rv = profile.substring(profile.length() - 3).replace(".", ""); - if ( - !rv.equals("12") - && !rv.equals("20") - && !rv.equals("21") - && !rv.equals("22") - && !rv.equals("23") - && !rv.equals("30") - ) { - throw new IllegalArgumentException("Unsupported XR version"); - } - LOGGER.debug("is XRechnung v{}", rv); - return rv; - } + private String getXRVersion(final String profile) throws IllegalArgumentException { + String rv = profile.substring(profile.length() - 3).replace(".", ""); + if ( + !rv.equals("12") + && !rv.equals("20") + && !rv.equals("21") + && !rv.equals("22") + && !rv.equals("23") + && !rv.equals("30") + ) { + throw new IllegalArgumentException("Unsupported XR version"); + } + LOGGER.debug("is XRechnung v{}", rv); + return rv; + } - private EVersion getVersion(final String xrVersion, final String rootName) { - EVersion rv; - try { - switch (xrVersion) { - case "12": - case "20": - case "21": - case "22": - if (rootName.equalsIgnoreCase(INVOICE)) { - rv = EVersion.valueOf(String.format("XR_%s_UBL_INVOICE", xrVersion)); - } else { - rv = EVersion.valueOf(String.format("XR_%s_UBL_CREDIT_NOTE", xrVersion)); - } - break; - case "23": - case "30": - rv = EVersion.valueOf(String.format("XR_%s_UBL", xrVersion)); - break; - default: - rv = EVersion.XR_30_UBL; - break; - } - } catch (IllegalArgumentException e) { - rv = EVersion.XR_30_UBL; - } - return rv; - } + private EVersion getVersion(final String xrVersion, final String rootName) { + EVersion rv; + try { + switch (xrVersion) { + case "12": + case "20": + case "21": + case "22": + if (rootName.equalsIgnoreCase(INVOICE)) { + rv = EVersion.valueOf(String.format("XR_%s_UBL_INVOICE", xrVersion)); + } else { + rv = EVersion.valueOf(String.format("XR_%s_UBL_CREDIT_NOTE", xrVersion)); + } + break; + case "23": + case "30": + rv = EVersion.valueOf(String.format("XR_%s_UBL", xrVersion)); + break; + default: + rv = EVersion.XR_30_UBL; + break; + } + } catch (IllegalArgumentException e) { + rv = EVersion.XR_30_UBL; + } + return rv; + } - public void validateXR(String xml, ESeverity errorImpact) throws IrrecoverableValidationError { + public void validateXR(String xml, ESeverity errorImpact) throws IrrecoverableValidationError { - //Guideline ID=urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_1.2 or - if (xml.contains(":xrechnung_1.")) { - validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_12_CII), 27, errorImpact); - } else if (xml.contains(":xrechnung_2.0")) { - // urn:cen.eu:en16931:2017#compliant#urn:xoev-dede:kosit:standard:xrechnung_2.0#conformant#urn:xoev-de:kosit:extension:xrechnung_2.0 - validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_20_CII), 27, errorImpact); - } else if (xml.contains(":xrechnung_2.1")) { // This is the default check which is also run on en16931 files to generate notices. - validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_21_CII), 27, errorImpact); - } else if (xml.contains(":xrechnung_2.2")) { // This is the default check which is also run on en16931 files to generate notices. - validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_22_CII), 27, errorImpact); - } else if (xml.contains(":xrechnung_2.3")) { // This is the default check which is also run on en16931 files to generate notices. - validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_23_CII), 27, errorImpact); - } else { // This is the default check which is also run on en16931 files to generate notices. - validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_30_CII), 27, errorImpact); - } + // Guideline ID=urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_1.2 or + if (xml.contains(":xrechnung_1.")) { + validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_12_CII), 27, errorImpact); + } else if (xml.contains(":xrechnung_2.0")) { + // urn:cen.eu:en16931:2017#compliant#urn:xoev-dede:kosit:standard:xrechnung_2.0#conformant#urn:xoev-de:kosit:extension:xrechnung_2.0 + validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_20_CII), 27, errorImpact); + } else if (xml.contains(":xrechnung_2.1")) { // This is the default check which is also run on en16931 files to generate notices. + validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_21_CII), 27, errorImpact); + } else if (xml.contains(":xrechnung_2.2")) { // This is the default check which is also run on en16931 files to generate notices. + validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_22_CII), 27, errorImpact); + } else if (xml.contains(":xrechnung_2.3")) { // This is the default check which is also run on en16931 files to generate notices. + validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_23_CII), 27, errorImpact); + } else { // This is the default check which is also run on en16931 files to generate notices. + validateSchematron(xml, ScriptsPerVersion.mapOfScriptsPerVersion.get(EVersion.XR_30_CII), 27, errorImpact); + } - } + } - /*** - * validate using a xslt file generated from a schematron in the build preparation of this software - * @param xml the xml to be checked - * @param xsltFilename the filename of the intermediate XSLT file - * @param section the error type code, if one arises - * @param defaultSeverity how serious an error should be treated - may only be notice - * @throws IrrecoverableValidationError if anything happened that prevents further checks - */ - public void validateSchematron(String xml, String xsltFilename, int section, ESeverity defaultSeverity) throws IrrecoverableValidationError { - LOGGER.debug( - "public void validateSchematron(String xml, String xsltFilename='{}', int section={}, ESeverity defaultSeverity={})", - xsltFilename, - section, - defaultSeverity - ); - ISchematronResource aResSCH = SchematronResourceXSLT.fromClassPath(xsltFilename); + /*** + * validate using a xslt file generated from a schematron in the build preparation of this software + * @param xml the xml to be checked + * @param xsltFilename the filename of the intermediate XSLT file + * @param section the error type code, if one arises + * @param defaultSeverity how serious an error should be treated - may only be notice + * @throws IrrecoverableValidationError if anything happened that prevents further checks + */ + public void validateSchematron(String xml, String xsltFilename, int section, ESeverity defaultSeverity) throws IrrecoverableValidationError { + LOGGER.debug( + "public void validateSchematron(String xml, String xsltFilename='{}', int section={}, ESeverity defaultSeverity={})", + xsltFilename, + section, + defaultSeverity + ); + ISchematronResource aResSCH = SchematronResourceXSLT.fromClassPath(xsltFilename); - if (!aResSCH.isValidSchematron()) { - throw new IllegalArgumentException(xsltFilename + " is invalid Schematron!"); - } + if (!aResSCH.isValidSchematron()) { + throw new IllegalArgumentException(xsltFilename + " is invalid Schematron!"); + } - final SchematronOutputType sout; - try { - sout = aResSCH - .applySchematronValidationToSVRL(new StreamSource(new StringReader(xml))); - } catch (final Exception e) { - throw new IrrecoverableValidationError(e.getMessage()); - } - if (sout == null) { - throw new IrrecoverableValidationError("Cannot retrieve SVRL report."); - } - // SVRLHelper.getAllFailedAssertions (sout); - Document document = new SVRLMarshaller().getAsDocument(sout); - XPath xPath = XPathFactory.newInstance().newXPath(); - String expression = "//*[local-name() = 'failed-assert']"; - NodeList failedAsserts; - try { - failedAsserts = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET); + final SchematronOutputType sout; + try { + sout = aResSCH + .applySchematronValidationToSVRL(new StreamSource(new StringReader(xml))); + } catch (final Exception e) { + throw new IrrecoverableValidationError(e.getMessage()); + } + if (sout == null) { + throw new IrrecoverableValidationError("Cannot retrieve SVRL report."); + } + // SVRLHelper.getAllFailedAssertions (sout); + Document document = new SVRLMarshaller().getAsDocument(sout); + XPath xPath = XPathFactory.newInstance().newXPath(); + String expression = "//*[local-name() = 'failed-assert']"; + NodeList failedAsserts; + try { + failedAsserts = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET); - String thisFailText = ""; - String thisFailID = ""; - String thisFailIDStr = ""; - String thisFailTest = ""; - String thisFailLocation = ""; - if (failedAsserts.getLength() > 0) { + String thisFailText = ""; + String thisFailID = ""; + String thisFailIDStr = ""; + String thisFailTest = ""; + String thisFailLocation = ""; + if (failedAsserts.getLength() > 0) { - for (int nodeIndex = 0; nodeIndex < failedAsserts.getLength(); nodeIndex++) { - //nodes.item(i).getTextContent())) { - Node currentFailNode = failedAsserts.item(nodeIndex); - if (currentFailNode.getAttributes().getNamedItem("id") != null) { - thisFailID = currentFailNode.getAttributes().getNamedItem("id").getNodeValue(); - thisFailIDStr = " [ID " + thisFailID + "]"; - } - if (currentFailNode.getAttributes().getNamedItem("test") != null) { - thisFailTest = currentFailNode.getAttributes().getNamedItem("test").getNodeValue(); - } - if (currentFailNode.getAttributes().getNamedItem("location") != null) { - thisFailLocation = currentFailNode.getAttributes().getNamedItem("location").getNodeValue(); - } + for (int nodeIndex = 0; nodeIndex < failedAsserts.getLength(); nodeIndex++) { + // nodes.item(i).getTextContent())) { + Node currentFailNode = failedAsserts.item(nodeIndex); + if (currentFailNode.getAttributes().getNamedItem("id") != null) { + thisFailID = currentFailNode.getAttributes().getNamedItem("id").getNodeValue(); + thisFailIDStr = " [ID " + thisFailID + "]"; + } + if (currentFailNode.getAttributes().getNamedItem("test") != null) { + thisFailTest = currentFailNode.getAttributes().getNamedItem("test").getNodeValue(); + } + if (currentFailNode.getAttributes().getNamedItem("location") != null) { + thisFailLocation = currentFailNode.getAttributes().getNamedItem("location").getNodeValue(); + } - 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 - severity = ESeverity.warning; - } else { - severity = ESeverity.error; - } + 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 + severity = ESeverity.warning; + } else { + severity = ESeverity.error; + } - NodeList nodes = currentFailNode.getChildNodes(); - for (int failChildIndex = 0; failChildIndex < nodes.getLength(); failChildIndex++) { - if (nodes.item(failChildIndex).getLocalName() != null && nodes.item(failChildIndex).getLocalName().equals("text")) { - // if (itemChilds.item(failChildIndex).getAttributes().getNamedItem("schemeID") != null) { - thisFailText = nodes.item(failChildIndex).getTextContent(); + NodeList nodes = currentFailNode.getChildNodes(); + for (int failChildIndex = 0; failChildIndex < nodes.getLength(); failChildIndex++) { + if (nodes.item(failChildIndex).getLocalName() != null && nodes.item(failChildIndex).getLocalName().equals("text")) { + // if (itemChilds.item(failChildIndex).getAttributes().getNamedItem("schemeID") != null) { + thisFailText = nodes.item(failChildIndex).getTextContent(); - } + } - } + } - LOGGER.info("FailedAssert {}", thisFailText); + LOGGER.info("FailedAssert {}", thisFailText); - context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailIDStr + " from " + xsltFilename + ")") - .setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section).setID(thisFailID) - .setPart(EPart.fx)); - failedRules++; + context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailIDStr + " from " + xsltFilename + ")") + .setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section).setID(thisFailID) + .setPart(EPart.fx)); + failedRules++; - } + } - } + } - } catch (XPathExpressionException e) { - LOGGER.error(e.getMessage(), e); - } - expression = "//*[local-name() = 'fired-rule']"; - NodeList firedAsserts; - try { - firedAsserts = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET); - firedRules = firedAsserts.getLength(); - } catch (XPathExpressionException e) { - LOGGER.error(e.getMessage(), e); - } - /* int activePatterns=0; - expression = "//*[local-name() = 'active-pattern']"; - firedAsserts = null; - try { - firedAsserts = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET); - activePatterns = firedAsserts.getLength(); - } catch (XPathExpressionException e) { - LOGGER.error(e.getMessage(), e); - }*/ + } catch (XPathExpressionException e) { + LOGGER.error(e.getMessage(), e); + } + expression = "//*[local-name() = 'fired-rule']"; + NodeList firedAsserts; + try { + firedAsserts = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET); + firedRules = firedAsserts.getLength(); + } catch (XPathExpressionException e) { + LOGGER.error(e.getMessage(), e); + } + /* int activePatterns=0; + expression = "//*[local-name() = 'active-pattern']"; + firedAsserts = null; + try { + firedAsserts = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET); + activePatterns = firedAsserts.getLength(); + } catch (XPathExpressionException e) { + LOGGER.error(e.getMessage(), e); + }*/ - if (firedRules == 0) { - context.addResultItem(new ValidationResultItem(ESeverity.error, "No rules matched, XML to minimal?").setSection(26) - .setPart(EPart.fx)); + if (firedRules == 0) { + context.addResultItem(new ValidationResultItem(ESeverity.error, "No rules matched, XML to minimal?").setSection(26) + .setPart(EPart.fx)); - } - // for (String currentString : sout.getText()) { - // schematronValidationString += "" + currentString + ""; - // } + } + // for (String currentString : sout.getText()) { + // schematronValidationString += "" + currentString + ""; + // } - // schematronValidationString += new SVRLMarshaller ().getAsString (sout); - // returns the complete SVRL + // schematronValidationString += new SVRLMarshaller ().getAsString (sout); + // returns the complete SVRL - } + } - @SuppressWarnings("unused") - public int getFiredRules() { - return firedRules; - } + @SuppressWarnings("unused") + public int getFiredRules() { + return firedRules; + } - @SuppressWarnings("unused") - public int getFailedRules() { - return failedRules; - } + @SuppressWarnings("unused") + public int getFailedRules() { + return failedRules; + } } diff --git a/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java b/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java index 4bffb5a..704a774 100755 --- a/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java @@ -1,5 +1,22 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.validator; +import com.helger.commons.io.stream.StreamHelper; +import jakarta.xml.bind.DatatypeConverter; +import org.apache.commons.io.IOUtils; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.io.OutputFormat; +import org.dom4j.io.XMLWriter; +import org.mustangproject.XMLTools; +import org.mustangproject.util.ByteArraySearcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; @@ -17,345 +34,322 @@ import java.util.Calendar; import java.util.Date; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import org.apache.commons.io.IOUtils; -import org.dom4j.DocumentException; -import org.dom4j.DocumentHelper; -import org.dom4j.io.OutputFormat; -import org.dom4j.io.XMLWriter; -import org.mustangproject.util.ByteArraySearcher; -import org.mustangproject.XMLTools; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.InputSource; - -import com.helger.commons.io.stream.StreamHelper; - -import jakarta.xml.bind.DatatypeConverter; - -//abstract class +// abstract class public class ZUGFeRDValidator { - private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDValidator.class.getCanonicalName()); // log - // output - protected ValidationContext context = new ValidationContext(LOGGER); - protected String sha1Checksum; - protected boolean pdfValidity; - protected boolean displayXMLValidationOutput; - protected long startTime; - protected boolean optionsRecognized; - protected boolean disableNotices = false; - protected String Signature; - protected boolean wasCompletelyValid = false; - protected String logAppend = null; + private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDValidator.class.getCanonicalName()); // log + // output + protected ValidationContext context = new ValidationContext(LOGGER); + protected String sha1Checksum; + protected boolean pdfValidity; + protected boolean displayXMLValidationOutput; + protected long startTime; + protected boolean optionsRecognized; + protected boolean disableNotices = false; + protected String Signature; + protected boolean wasCompletelyValid = false; + protected String logAppend = null; - /*** - * within the validation it turned out something in the options was wrong, e.g. - * the file did not exist. recommendation to show the help text again. Should be - * false if XML or PDF file was found - * @return false if any valid option was picked up - */ - public boolean hasOptionsError() { - return !optionsRecognized; + /*** + * within the validation it turned out something in the options was wrong, e.g. + * the file did not exist. recommendation to show the help text again. Should be + * false if XML or PDF file was found + * @return false if any valid option was picked up + */ + public boolean hasOptionsError() { + return !optionsRecognized; - } + } - public void setLogAppend(String tobeappended) { - logAppend = tobeappended; - } + public void setLogAppend(String tobeappended) { + logAppend = tobeappended; + } - /*** - * in case the result was not valid the error code of the app will be set to -1 - * - * @return true if both xml and pdf were valid (contained no errors, notices are ignored) - */ - public boolean wasCompletelyValid() { - return wasCompletelyValid; + /*** + * in case the result was not valid the error code of the app will be set to -1 + * + * @return true if both xml and pdf were valid (contained no errors, notices are ignored) + */ + public boolean wasCompletelyValid() { + return wasCompletelyValid; - } + } - private String internalValidate(String contextFilename, InputStream inputStream, long inputLength) { - context.clear(); - StringBuilder finalStringResult = new StringBuilder(); - SimpleDateFormat isoDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Date date = new Date(); - startTime = Calendar.getInstance().getTimeInMillis(); - context.setFilename(contextFilename);// fallback to provided name - finalStringResult.append(""); + private String internalValidate(String contextFilename, InputStream inputStream, long inputLength) { + context.clear(); + StringBuilder finalStringResult = new StringBuilder(); + SimpleDateFormat isoDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + startTime = Calendar.getInstance().getTimeInMillis(); + context.setFilename(contextFilename);// fallback to provided name + finalStringResult.append(""); - boolean isPDF = false; - byte[] content = null; - try { + boolean isPDF = false; + byte[] content = null; + try { - if (contextFilename == null || contextFilename.isEmpty()) { - optionsRecognized = false; - context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Filename not specified").setSection(10) - .setPart(EPart.pdf)); - } + if (contextFilename == null || contextFilename.isEmpty()) { + optionsRecognized = false; + context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Filename not specified").setSection(10) + .setPart(EPart.pdf)); + } - PDFValidator pdfv = new PDFValidator(context); - if (inputStream == null) { - context.addResultItem( - new ValidationResultItem(ESeverity.fatal, "File not found").setSection(1).setPart(EPart.pdf)); - } else if (inputLength < 32) { - // with less than 32 bytes it can not even be a proper XML file - // Except it is "" LOL - context.addResultItem( - new ValidationResultItem(ESeverity.fatal, "File too small").setSection(5).setPart(EPart.pdf)); - } else if (inputLength >= Integer.MAX_VALUE) { - // Byte arrays are limited to 2GB in Java - context.addResultItem( - new ValidationResultItem(ESeverity.fatal, "File too big").setSection(5).setPart(EPart.pdf)); - } else { - content = IOUtils.toByteArray(inputStream); - XMLValidator xv = new XMLValidator(context); - if (disableNotices) { - xv.disableNotices(); - } - isPDF = ByteArraySearcher.startsWith(content, new byte[]{'%', 'P', 'D', 'F'}); - if (isPDF) { - // Avoid reading again from file - pdfv.setFilenameAndContents(contextFilename, content); + PDFValidator pdfv = new PDFValidator(context); + if (inputStream == null) { + context.addResultItem( + new ValidationResultItem(ESeverity.fatal, "File not found").setSection(1).setPart(EPart.pdf)); + } else if (inputLength < 32) { + // with less than 32 bytes it can not even be a proper XML file + // Except it is "" LOL + context.addResultItem( + new ValidationResultItem(ESeverity.fatal, "File too small").setSection(5).setPart(EPart.pdf)); + } else if (inputLength >= Integer.MAX_VALUE) { + // Byte arrays are limited to 2GB in Java + context.addResultItem( + new ValidationResultItem(ESeverity.fatal, "File too big").setSection(5).setPart(EPart.pdf)); + } else { + content = IOUtils.toByteArray(inputStream); + XMLValidator xv = new XMLValidator(context); + if (disableNotices) { + xv.disableNotices(); + } + isPDF = ByteArraySearcher.startsWith(content, new byte[]{'%', 'P', 'D', 'F'}); + if (isPDF) { + // Avoid reading again from file + pdfv.setFilenameAndContents(contextFilename, content); - optionsRecognized = true; - finalStringResult.append(""); - try { - pdfv.validate(); + optionsRecognized = true; + finalStringResult.append(""); + try { + pdfv.validate(); - sha1Checksum = calcSHA1(content); + sha1Checksum = calcSHA1(content); - // Validate PDF + // Validate PDF - getPdfValidationResults(finalStringResult, pdfv, xv); - } catch (IrrecoverableValidationError irx) { - LOGGER.info(irx.getMessage()); - } + getPdfValidationResults(finalStringResult, pdfv, xv); + } catch (IrrecoverableValidationError irx) { + LOGGER.info("", irx); + } - finalStringResult.append("\n"); + finalStringResult.append("\n"); - context.clearCustomXML(); - } else { - boolean isXML = false; - String xmlAsString = null; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); + context.clearCustomXML(); + } else { + boolean isXML = false; + String xmlAsString = null; + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); - content = XMLTools.removeBOM(content); - xmlAsString = new String(content, StandardCharsets.UTF_8); - InputSource is = new InputSource(new StringReader(xmlAsString)); - Document doc = db.parse(is); + content = XMLTools.removeBOM(content); + xmlAsString = new String(content, StandardCharsets.UTF_8); + InputSource is = new InputSource(new StringReader(xmlAsString)); + Document doc = db.parse(is); - Element root = doc.getDocumentElement(); - isXML = true;//no exception so far + Element root = doc.getDocumentElement(); + isXML = true;// no exception so far - } catch (Exception ex) { - // probably no xml file, sth like SAXParseException content not allowed in prolog - // ignore isXML is already false - // in the tests, this may error-out anyway - LOGGER.info("No XML part provided"); - } - if (isXML) { - pdfValidity = true; - optionsRecognized = true; - xv.setStringContent(xmlAsString); - xv.setAutoload(false); - xv.setFilename(contextFilename); - sha1Checksum = calcSHA1(content); + } catch (Exception ex) { + // probably no xml file, sth like SAXParseException content not allowed in prolog + // ignore isXML is already false + // in the tests, this may error-out anyway + LOGGER.info("No XML part provided"); + } + if (isXML) { + pdfValidity = true; + optionsRecognized = true; + xv.setStringContent(xmlAsString); + xv.setAutoload(false); + xv.setFilename(contextFilename); + sha1Checksum = calcSHA1(content); - displayXMLValidationOutput = true; + displayXMLValidationOutput = true; - } else { - optionsRecognized = false; - context.addResultItem(new ValidationResultItem(ESeverity.exception, - "File does not look like PDF nor XML (contains neither %PDF nor "); - try { - xv.validate(); - } catch (IrrecoverableValidationError irx) { - LOGGER.error("XML validation threw an exception ", irx); - } - finalStringResult.append(xv.getXMLResult()); - finalStringResult.append(""); - context.clearCustomXML(); - } + } + } + if (optionsRecognized && displayXMLValidationOutput) { + finalStringResult.append(""); + try { + xv.validate(); + } catch (IrrecoverableValidationError irx) { + LOGGER.error("XML validation threw an exception ", irx); + } + finalStringResult.append(xv.getXMLResult()); + finalStringResult.append(""); + context.clearCustomXML(); + } - if ((isPDF) && (!pdfValidity)) { - context.setInvalid(); - } + if (isPDF && (!pdfValidity)) { + context.setInvalid(); + } - } - } catch (IrrecoverableValidationError | IOException irx) { - LOGGER.info(irx.getMessage()); - context.setInvalid(); - } finally { - finalStringResult.append(context.getXMLResult()); - finalStringResult.append(""); + } + } catch (IrrecoverableValidationError | IOException irx) { + LOGGER.info("", irx); + context.setInvalid(); + } finally { + finalStringResult.append(context.getXMLResult()); + finalStringResult.append(""); - } + } - return formatOutput(finalStringResult, isPDF); - } + return formatOutput(finalStringResult, isPDF); + } - /*** - * performs a validation on the file filename - * - * @param filename the complete absolute filename of a PDF or XML - * @return a xml string with the validation result - */ - public String validate(String filename) { - LOGGER.debug("public String validate(String filename='{}')", filename); - String contextFilename; - InputStream inputStream; - long inputLength; - if (filename == null) { - // No filename provided - contextFilename = ""; - inputStream = null; - inputLength = 0; - } else { - File file = new File(filename); - // set filename without path - contextFilename = file.getName(); - if (file.isFile()) { - try { - inputStream = new FileInputStream(file); - inputLength = Files.size(file.toPath()); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - } else { - // Non-existing or Directory - inputStream = null; - inputLength = 0; - } - } - try { - return internalValidate(contextFilename, inputStream, inputLength); - } finally { - StreamHelper.close(inputStream); - } - } + /*** + * performs a validation on the file filename + * + * @param filename the complete absolute filename of a PDF or XML + * @return a xml string with the validation result + */ + public String validate(String filename) { + LOGGER.debug("public String validate(String filename='{}')", filename); + String contextFilename; + InputStream inputStream; + long inputLength; + if (filename == null) { + // No filename provided + contextFilename = ""; + inputStream = null; + inputLength = 0; + } else { + File file = new File(filename); + // set filename without path + contextFilename = file.getName(); + if (file.isFile()) { + try { + inputStream = new FileInputStream(file); + inputLength = Files.size(file.toPath()); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } else { + // Non-existing or Directory + inputStream = null; + inputLength = 0; + } + } + try { + return internalValidate(contextFilename, inputStream, inputLength); + } finally { + StreamHelper.close(inputStream); + } + } - public String validate(InputStream inputStream, String fileNameOfInputStream) { - long inputLength; - try { - inputLength = inputStream == null ? 0 : inputStream.available(); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - try { - return internalValidate(fileNameOfInputStream, inputStream, inputLength); - } finally { - StreamHelper.close(inputStream); - } - } + public String validate(InputStream inputStream, String fileNameOfInputStream) { + long inputLength; + try { + inputLength = inputStream == null ? 0 : inputStream.available(); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + try { + return internalValidate(fileNameOfInputStream, inputStream, inputLength); + } finally { + StreamHelper.close(inputStream); + } + } - public String validate(byte[] bytes, String fileNameOfInputStream) { - try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) { - return internalValidate(fileNameOfInputStream, bais, bytes.length); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - } + public String validate(byte[] bytes, String fileNameOfInputStream) { + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) { + return internalValidate(fileNameOfInputStream, bais, bytes.length); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } - private void getPdfValidationResults(StringBuilder finalStringResult, PDFValidator pdfv, XMLValidator xv) throws IrrecoverableValidationError { - finalStringResult.append(pdfv.getXMLResult()); - pdfValidity = context.isValid(); + private void getPdfValidationResults(StringBuilder finalStringResult, PDFValidator pdfv, XMLValidator xv) throws IrrecoverableValidationError { + finalStringResult.append(pdfv.getXMLResult()); + pdfValidity = context.isValid(); - Signature = context.getSignature(); - context.clear();// clear sets valid to true again - if (pdfv.getRawXML() != null) { - xv.setStringContent(pdfv.getRawXML()); - displayXMLValidationOutput = true; - } else { - context.addResultItem( - new ValidationResultItem(ESeverity.exception, "XML could not be extracted") - .setSection(17)); - } - } + Signature = context.getSignature(); + context.clear();// clear sets valid to true again + if (pdfv.getRawXML() != null) { + xv.setStringContent(pdfv.getRawXML()); + displayXMLValidationOutput = true; + } else { + context.addResultItem( + new ValidationResultItem(ESeverity.exception, "XML could not be extracted") + .setSection(17)); + } + } - private String formatOutput(StringBuilder finalStringResult, boolean isPDF) { - boolean xmlValidity; - OutputFormat format = OutputFormat.createPrettyPrint(); - StringWriter sw = new StringWriter(); - org.dom4j.Document document = null; - try { - document = DocumentHelper.parseText(new String(finalStringResult)); - } catch (DocumentException e1) { - LOGGER.error(e1.getMessage()); - } - XMLWriter writer = new XMLWriter(sw, format); - try { - writer.write(document); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } + private String formatOutput(StringBuilder finalStringResult, boolean isPDF) { + boolean xmlValidity; + OutputFormat format = OutputFormat.createPrettyPrint(); + StringWriter sw = new StringWriter(); + org.dom4j.Document document = null; + try { + document = DocumentHelper.parseText(new String(finalStringResult)); + } catch (DocumentException e1) { + LOGGER.error("", e1); + } + XMLWriter writer = new XMLWriter(sw, format); + try { + writer.write(document); + } catch (Exception e) { + LOGGER.error("", e); + } - xmlValidity = context.isValid(); - long duration = Calendar.getInstance().getTimeInMillis() - startTime; + xmlValidity = context.isValid(); + long duration = Calendar.getInstance().getTimeInMillis() - startTime; - String toBeAppended = ""; - if (logAppend != null) { - toBeAppended = logAppend; - } + String toBeAppended = ""; + if (logAppend != null) { + toBeAppended = logAppend; + } - String pdfResult = "invalid"; - if (!isPDF) { - pdfResult = "absent"; - } else if (pdfValidity) { - pdfResult = "valid"; - } + String pdfResult = "invalid"; + if (!isPDF) { + pdfResult = "absent"; + } else if (pdfValidity) { + pdfResult = "valid"; + } - 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() - + "] ErrorIDs: [" + context.getCSVIDResult() + "]" + toBeAppended); - wasCompletelyValid = ((pdfValidity) && (xmlValidity)); - return sw.toString(); - } + LOGGER.info("Parsed PDF:{} XML:{} Signature:{} Checksum:{} Profile:{} Version:{} Took:{}ms Errors:[{}] ErrorIDs: [{}]{}", pdfResult, (xmlValidity ? "valid" : "invalid"), Signature, sha1Checksum, context.getProfile(), context.getGeneration(), duration, context.getCSVResult(), context.getCSVIDResult(), toBeAppended); + wasCompletelyValid = pdfValidity && xmlValidity; + return sw.toString(); + } - /*** - * don't report notices in validation report - */ - public void disableNotices() { - disableNotices = true; - } + /*** + * don't report notices in validation report + */ + public void disableNotices() { + disableNotices = true; + } - /** - * Read the file and calculate the SHA-1 checksum - * - * @param data the InputStream to read - * @return the hex representation of the SHA-1 using uppercase chars - * @throws FileNotFoundException if the file does not exist, is a directory - * rather than a regular file, or for some - * other reason cannot be opened for reading - * @throws IOException if an I/O error occurs - * @throws NoSuchAlgorithmException should never happen - */ - private static String calcSHA1(byte[] data) { - MessageDigest sha1 = null; - try { + /** + * Read the file and calculate the SHA-1 checksum + * + * @param data the InputStream to read + * @return the hex representation of the SHA-1 using uppercase chars + * @throws FileNotFoundException if the file does not exist, is a directory + * rather than a regular file, or for some + * other reason cannot be opened for reading + * @throws IOException if an I/O error occurs + * @throws NoSuchAlgorithmException should never happen + */ + private static String calcSHA1(byte[] data) { + MessageDigest sha1 = null; + try { - sha1 = MessageDigest.getInstance("SHA-1"); - sha1.update(data, 0, data.length); - } catch (NoSuchAlgorithmException e) { - LOGGER.error(e.getMessage(), e); - } - if (sha1 == null) { - return ""; - } else { - return DatatypeConverter.printHexBinary(sha1.digest()); - } - } + sha1 = MessageDigest.getInstance("SHA-1"); + sha1.update(data, 0, data.length); + } catch (NoSuchAlgorithmException e) { + LOGGER.error(e.getMessage(), e); + } + if (sha1 == null) { + return ""; + } else { + return DatatypeConverter.printHexBinary(sha1.digest()); + } + } } diff --git a/validator/src/test/java/org/mustangproject/validator/LibraryTest.java b/validator/src/test/java/org/mustangproject/validator/LibraryTest.java index dbee3b3..41a97ce 100755 --- a/validator/src/test/java/org/mustangproject/validator/LibraryTest.java +++ b/validator/src/test/java/org/mustangproject/validator/LibraryTest.java @@ -6,288 +6,292 @@ org.openrewrite.config.CompositeRecipe public class LibraryTest extends ResourceCase { - public void testLibraryPush() { - File tempFile = new File("../library/target/testout-MustangGnuaccountingBeispielRE-20201121_508.pdf"); - assertTrue(tempFile.exists()); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + public void testLibraryPush() { + File tempFile = new File("../library/target/testout-MustangGnuaccountingBeispielRE-20201121_508.pdf"); + assertTrue(tempFile.exists()); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - String res = zfv.validate(tempFile.getAbsolutePath()); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); - tempFile = new File("../library/target/testout-ZF2PushCorrection.pdf"); - assertTrue(tempFile.exists()); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); + tempFile = new File("../library/target/testout-ZF2PushCorrection.pdf"); + assertTrue(tempFile.exists()); - res = zfv.validate(tempFile.getAbsolutePath()); + res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); - } - public void testLibraryPushCorrection() { - File tempFile = new File("../library/target/testout-ZF2PushCorrection.pdf"); - assertTrue(tempFile.exists()); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + } - String res = zfv.validate(tempFile.getAbsolutePath()); + public void testLibraryPushCorrection() { + File tempFile = new File("../library/target/testout-ZF2PushCorrection.pdf"); + assertTrue(tempFile.exists()); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); - } - public void testLibraryPushItemAllowances() { - File tempFile = new File("../library/target/testout-ZF2PushItemChargesAllowances.pdf"); - assertTrue(tempFile.exists()); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); - String res = zfv.validate(tempFile.getAbsolutePath()); + } + public void testLibraryPushItemAllowances() { + File tempFile = new File("../library/target/testout-ZF2PushItemChargesAllowances.pdf"); + assertTrue(tempFile.exists()); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("valid"); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); - } + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); - public void testLibraryPushRelativeAllowances() { - File tempFile = new File("../library/target/testout-ZF2PushRelativeChargesAllowances.pdf"); - assertTrue(tempFile.exists()); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); - String res = zfv.validate(tempFile.getAbsolutePath()); + } + public void testLibraryPushRelativeAllowances() { + File tempFile = new File("../library/target/testout-ZF2PushRelativeChargesAllowances.pdf"); + assertTrue(tempFile.exists()); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("valid"); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); - } + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); - public void testLibraryPushEdge() { - File tempFile = new File("../library/target/testout-ZF2PushEdge.pdf"); - assertTrue(tempFile.exists()); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); - String res = zfv.validate(tempFile.getAbsolutePath()); + } + public void testLibraryPushEdge() { + File tempFile = new File("../library/target/testout-ZF2PushEdge.pdf"); + assertTrue(tempFile.exists()); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("valid"); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); - } - public void testLibraryPushAllowances() { - File tempFile = new File("../library/target/testout-ZF2PushChargesAllowances.pdf"); - assertTrue(tempFile.exists()); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); - String res = zfv.validate(tempFile.getAbsolutePath()); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); + } - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("valid"); + public void testLibraryPushAllowances() { + File tempFile = new File("../library/target/testout-ZF2PushChargesAllowances.pdf"); + assertTrue(tempFile.exists()); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); - } + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); - public void testZF1validity() { - File tempFile = new File("../library/target/testout-MustangGnuaccountingBeispielRE-20171118_506zf1.pdf"); - assertTrue(tempFile.exists()); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); - String res = zfv.validate(tempFile.getAbsolutePath()); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); + } - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("valid"); + public void testZF1validity() { + File tempFile = new File("../library/target/testout-MustangGnuaccountingBeispielRE-20171118_506zf1.pdf"); + assertTrue(tempFile.exists()); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); - } - public void testPDFA3Exporter() { - // testout-MustangGnuaccountingBeispielRE-20170509_505newEdge.pdf was a A3 file - // already in import (MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf), - // so it's important to check that we did not screw anythig up in that scenario - File tempFile = new File("../library/target/testout-MustangGnuaccountingBeispielRE-20170509_505newEdge.pdf"); - assertTrue(tempFile.exists()); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); + + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); + + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); + } + + public void testPDFA3Exporter() { + // testout-MustangGnuaccountingBeispielRE-20170509_505newEdge.pdf was a A3 file + // already in import (MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf), + // so it's important to check that we did not screw anythig up in that scenario + + File tempFile = new File("../library/target/testout-MustangGnuaccountingBeispielRE-20170509_505newEdge.pdf"); + assertTrue(tempFile.exists()); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + + String res = zfv.validate(tempFile.getAbsolutePath()); + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); + } - String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); - } + /** + * automatically test the xrechnung + */ + public void testXREdgeValidation() { + File tempFile = new File("../library/target/testout-XR-Edge.xml"); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - /** - * automatically test the xrechnung - */ - public void testXREdgeValidation() { - File tempFile = new File("../library/target/testout-XR-Edge.xml"); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + String res = zfv.validate(tempFile.getAbsolutePath()); + assertThat(res).valueByXPath("count(//error)") + .asInt() + .isEqualTo(0); + assertThat(res).valueByXPath("/validation/summary/@status") + .asString() + .isEqualTo("valid");// expect to be valid because XR notices are, well, only notices + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .asString() + .isEqualTo("valid"); - String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("count(//error)") - .asInt() - .isEqualTo(0); - assertThat(res).valueByXPath("/validation/summary/@status") - .asString() - .isEqualTo("valid");// expect to be valid because XR notices are, well, only notices - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .asString() - .isEqualTo("valid"); - - assertThat(res).valueByXPath("count(//notice)") - .asInt() - .isEqualTo(0); + assertThat(res).valueByXPath("count(//notice)") + .asInt() + .isEqualTo(0); - } + } - /** - * automatically test the xrechnung - */ - public void testOXValidationSimple() { - File tempFile = new File("../library/target/testout-OX.pdf"); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + /** + * automatically test the xrechnung + */ + public void testOXValidationSimple() { + File tempFile = new File("../library/target/testout-OX.pdf"); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - String res = zfv.validate(tempFile.getAbsolutePath()); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("count(//error)") - .asInt() - .isEqualTo(2); // OX_10_BASIC - assertThat(res).valueByXPath("/validation/summary/@status") - .asString() - .isEqualTo("invalid"); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .asString() - .isEqualTo("invalid"); - /** end of errors due to version mismatch*/ + assertThat(res).valueByXPath("count(//error)") + .asInt() + .isEqualTo(2); // OX_10_BASIC + assertThat(res).valueByXPath("/validation/summary/@status") + .asString() + .isEqualTo("invalid"); + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .asString() + .isEqualTo("invalid"); + /** end of errors due to version mismatch*/ - assertThat(res).valueByXPath("count(//notice)") - .asInt() - .isEqualTo(0); + assertThat(res).valueByXPath("count(//notice)") + .asInt() + .isEqualTo(0); + } - } - /** - * automatically test the xrechnung - */ - public void testOXValidationEdge() { - File tempFile = new File("../library/target/testout-OX-edge.pdf"); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + /** + * automatically test the xrechnung + */ + public void testOXValidationEdge() { + File tempFile = new File("../library/target/testout-OX-edge.pdf"); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - String res = zfv.validate(tempFile.getAbsolutePath()); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("count(//error)") - .asInt() - .isEqualTo(2); // OX_10_BASIC - assertThat(res).valueByXPath("/validation/summary/@status") - .asString() - .isEqualTo("invalid"); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .asString() - .isEqualTo("invalid"); - /** end of errors due to version mismatch*/ + assertThat(res).valueByXPath("count(//error)") + .asInt() + .isEqualTo(2); // OX_10_BASIC + assertThat(res).valueByXPath("/validation/summary/@status") + .asString() + .isEqualTo("invalid"); + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .asString() + .isEqualTo("invalid"); + /** end of errors due to version mismatch*/ - assertThat(res).valueByXPath("count(//notice)") - .asInt() - .isEqualTo(0); - } + assertThat(res).valueByXPath("count(//notice)") + .asInt() + .isEqualTo(0); + } - public void testMinimumProfileValidityInvoice() { - File tempFile = new File("../library/target/testout-Minimum-INV.pdf"); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + public void testMinimumProfileValidityInvoice() { + File tempFile = new File("../library/target/testout-Minimum-INV.pdf"); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - String res = zfv.validate(tempFile.getAbsolutePath()); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("count(//error)") - .asInt() - .isEqualTo(0); - assertThat(res).valueByXPath("/validation/summary/@status") - .asString() - .isEqualTo("valid");// expect to be valid because XR notices are, well, only notices - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .asString() - .isEqualTo("valid"); - /** end of errors due to version mismatch*/ + assertThat(res).valueByXPath("count(//error)") + .asInt() + .isEqualTo(0); + assertThat(res).valueByXPath("/validation/summary/@status") + .asString() + .isEqualTo("valid");// expect to be valid because XR notices are, well, only notices + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .asString() + .isEqualTo("valid"); + /** end of errors due to version mismatch*/ - assertThat(res).valueByXPath("count(//notice)") - .asInt() - .isEqualTo(0); - } + assertThat(res).valueByXPath("count(//notice)") + .asInt() + .isEqualTo(0); + } - public void testMinimumProfileValidityCreditNote() { - File tempFile = new File("../library/target/testout-Minimum-CN.pdf"); - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + public void testMinimumProfileValidityCreditNote() { + File tempFile = new File("../library/target/testout-Minimum-CN.pdf"); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - String res = zfv.validate(tempFile.getAbsolutePath()); + String res = zfv.validate(tempFile.getAbsolutePath()); - assertThat(res).valueByXPath("count(//error)") - .asInt() - .isEqualTo(0); - assertThat(res).valueByXPath("/validation/summary/@status") - .asString() - .isEqualTo("valid");// expect to be valid because XR notices are, well, only notices - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .asString() - .isEqualTo("valid"); - /** end of errors due to version mismatch*/ + assertThat(res).valueByXPath("count(//error)") + .asInt() + .isEqualTo(0); + assertThat(res).valueByXPath("/validation/summary/@status") + .asString() + .isEqualTo("valid");// expect to be valid because XR notices are, well, only notices + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .asString() + .isEqualTo("valid"); + /** end of errors due to version mismatch*/ - assertThat(res).valueByXPath("count(//notice)") - .asInt() - .isEqualTo(0); - } + assertThat(res).valueByXPath("count(//notice)") + .asInt() + .isEqualTo(0); + } } diff --git a/validator/src/test/java/org/mustangproject/validator/MiscValidatorTest.java b/validator/src/test/java/org/mustangproject/validator/MiscValidatorTest.java index 1243ca8..794e2b7 100755 --- a/validator/src/test/java/org/mustangproject/validator/MiscValidatorTest.java +++ b/validator/src/test/java/org/mustangproject/validator/MiscValidatorTest.java @@ -5,84 +5,84 @@ org.openrewrite.config.CompositeRecipe import java.io.FileWriter; import java.io.IOException; -public class MiscValidatorTest extends ResourceCase { +public class MiscValidatorTest extends ResourceCase { - public void testInvalidFileValidation() { + public void testInvalidFileValidation() { - ZUGFeRDValidator zfv=new ZUGFeRDValidator(); + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - String res=zfv.validate(null); - assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" + - "\n" + - "\n" + - " \n" + - " Filename not specified \n" + - " \n" + - " \n" + - "\n" + - "")); + String res = zfv.validate(null); + assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" + + "\n" + + "\n" + + " \n" + + " Filename not specified \n" + + " \n" + + " \n" + + "\n" + + "")); - res=zfv.validate("/dhfkbv/sfjkh"); - assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" + - "\n" + - "\n" + - " \n" + - " File not found \n" + - " \n" + - " \n" + - "\n")); + res = zfv.validate("/dhfkbv/sfjkh"); + assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" + + "\n" + + "\n" + + " \n" + + " File not found \n" + + " \n" + + " \n" + + "\n")); - boolean noExceptionOccurred=true; - File tempFile=null; - try { - tempFile = File.createTempFile("hello", ".tmp"); - } catch (IOException e) { - noExceptionOccurred=true; - } - assertTrue(noExceptionOccurred); + boolean noExceptionOccurred = true; + File tempFile = null; + try { + tempFile = File.createTempFile("hello", ".tmp"); + } catch (IOException e) { + noExceptionOccurred = true; + } + assertTrue(noExceptionOccurred); - res=zfv.validate(tempFile.getAbsolutePath()); - assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" + - "\n" + - "\n" + - " \n" + - " File too small \n" + - " \n" + - " \n" + - "\n" + - "")); - - - String fileContent = "ladhvkdbfk wkhfbkhdhkb svbkfsvbksfbvk sdvsdvbksjdvbkfdsv sdvbskdvbsjhkvbfskh dvbskfvbkfsbvke" - + "ladhvkdbfk wkhfbkhdhkb svbkfsvbksfbvk sdvsdvbksjdvbkfdsv sdvbskdvbsjhkvbfskh dvbskfvbkfsbvke"; - noExceptionOccurred=true; - BufferedWriter writer; - try { - writer = new BufferedWriter(new FileWriter(tempFile)); - writer.write(fileContent); - writer.close(); - } catch (IOException e) { - noExceptionOccurred=false; - } - assertTrue(noExceptionOccurred); - + res = zfv.validate(tempFile.getAbsolutePath()); + assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" + + "\n" + + "\n" + + " \n" + + " File too small \n" + + " \n" + + " \n" + + "\n" + + "")); - res=zfv.validate(tempFile.getAbsolutePath()); - assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" + - "\n" + - "\n" + - " \n" + - " File does not look like PDF nor XML \\(contains neither %PDF nor <\\?xml\\) \n" + - " \n" + - " \n" + - "\n" + - "")); - - // clean up - tempFile.delete(); - - } - + String fileContent = "ladhvkdbfk wkhfbkhdhkb svbkfsvbksfbvk sdvsdvbksjdvbkfdsv sdvbskdvbsjhkvbfskh dvbskfvbkfsbvke" + + "ladhvkdbfk wkhfbkhdhkb svbkfsvbksfbvk sdvsdvbksjdvbkfdsv sdvbskdvbsjhkvbfskh dvbskfvbkfsbvke"; + noExceptionOccurred = true; + BufferedWriter writer; + try { + writer = new BufferedWriter(new FileWriter(tempFile)); + writer.write(fileContent); + writer.close(); + } catch (IOException e) { + noExceptionOccurred = false; + } + assertTrue(noExceptionOccurred); + + + res = zfv.validate(tempFile.getAbsolutePath()); + assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" + + "\n" + + "\n" + + " \n" + + " File does not look like PDF nor XML \\(contains neither %PDF nor <\\?xml\\) \n" + + " \n" + + " \n" + + "\n" + + "")); + + + // clean up + tempFile.delete(); + + } + } diff --git a/validator/src/test/java/org/mustangproject/validator/PDFValidatorTest.java b/validator/src/test/java/org/mustangproject/validator/PDFValidatorTest.java index 7fe508b..31e217c 100755 --- a/validator/src/test/java/org/mustangproject/validator/PDFValidatorTest.java +++ b/validator/src/test/java/org/mustangproject/validator/PDFValidatorTest.java @@ -1,178 +1,179 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.validator; -import java.io.File; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; + public class PDFValidatorTest extends ResourceCase { - private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDValidator.class.getCanonicalName()); // log + private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDValidator.class.getCanonicalName()); // log - public void testPDFPotentialA3SourceValidation() { - final ValidationContext vc = new ValidationContext(null); - final PDFValidator pv = new PDFValidator(vc); + public void testPDFPotentialA3SourceValidation() { + final ValidationContext vc = new ValidationContext(null); + final PDFValidator pv = new PDFValidator(vc); - try { + try { - File tempFile = new File("../library/target/testout-PDFA3FromA3.pdf"); - assertTrue(tempFile.exists()); + File tempFile = new File("../library/target/testout-PDFA3FromA3.pdf"); + assertTrue(tempFile.exists()); - pv.setFilename(tempFile.getAbsolutePath()); - pv.validate(); - String actual = pv.getXMLResult(); - assertEquals(true, actual.contains("summary status=\"valid")); - assertEquals(false, actual.contains("summary status=\"invalid")); + pv.setFilename(tempFile.getAbsolutePath()); + pv.validate(); + String actual = pv.getXMLResult(); + assertEquals(true, actual.contains("summary status=\"valid")); + assertEquals(false, actual.contains("summary status=\"invalid")); - tempFile = new File("../library/target/testout-PDFA3FromUnkownA3.pdf"); - assertTrue(tempFile.exists()); + tempFile = new File("../library/target/testout-PDFA3FromUnkownA3.pdf"); + assertTrue(tempFile.exists()); - pv.setFilename(tempFile.getAbsolutePath()); - vc.clear(); - pv.validate(); - actual = pv.getXMLResult(); - assertEquals(true, actual.contains("summary status=\"valid")); - assertEquals(false, actual.contains("summary status=\"invalid")); + pv.setFilename(tempFile.getAbsolutePath()); + vc.clear(); + pv.validate(); + actual = pv.getXMLResult(); + assertEquals(true, actual.contains("summary status=\"valid")); + assertEquals(false, actual.contains("summary status=\"invalid")); - tempFile = new File("../library/target/testout-PDFA3FromUnkownA1.pdf"); - assertTrue(tempFile.exists()); + tempFile = new File("../library/target/testout-PDFA3FromUnkownA1.pdf"); + assertTrue(tempFile.exists()); - pv.setFilename(tempFile.getAbsolutePath()); - vc.clear(); - pv.validate(); - actual = pv.getXMLResult(); - assertEquals(true, actual.contains("summary status=\"valid")); - assertEquals(false, actual.contains("summary status=\"invalid")); + pv.setFilename(tempFile.getAbsolutePath()); + vc.clear(); + pv.validate(); + actual = pv.getXMLResult(); + assertEquals(true, actual.contains("summary status=\"valid")); + assertEquals(false, actual.contains("summary status=\"invalid")); - } catch (final IrrecoverableValidationError e) { - // ignore, will be in XML output anyway - } + } catch (final IrrecoverableValidationError e) { + // ignore, will be in XML output anyway + } - } - public void testPDFValidation() { - final ValidationContext vc = new ValidationContext(null); - final PDFValidator pv = new PDFValidator(vc); + } - try { + public void testPDFValidation() { + final ValidationContext vc = new ValidationContext(null); + final PDFValidator pv = new PDFValidator(vc); - byte [] contents = getResourceAsByteArray("XMLinvalidV2PDF.pdf");// need a more invalid file here + try { - pv.setFilenameAndContents("XMLinvalidV2PDF.pdf", contents); - pv.validate(); - // assertEquals("", pv.getXMLResult()); + byte[] contents = getResourceAsByteArray("XMLinvalidV2PDF.pdf");// need a more invalid file here - // - contents = getResourceAsByteArray("Facture_F20180027.pdf"); - pv.setFilenameAndContents("Facture_F20180027.pdf", contents); - pv.validate(); - String actual = pv.getXMLResult(); - assertEquals(true, actual.contains("summary status=\"valid")); - assertEquals(false, actual.contains("summary status=\"invalid")); + pv.setFilenameAndContents("XMLinvalidV2PDF.pdf", contents); + pv.validate(); + // assertEquals("", pv.getXMLResult()); - final XMLValidator xv = new XMLValidator(vc); - xv.setStringContent(pv.getRawXML()); - xv.validate(); - actual = vc.getXMLResult(); + // + contents = getResourceAsByteArray("Facture_F20180027.pdf"); + pv.setFilenameAndContents("Facture_F20180027.pdf", contents); + pv.validate(); + String actual = pv.getXMLResult(); + assertEquals(true, actual.contains("summary status=\"valid")); + assertEquals(false, actual.contains("summary status=\"invalid")); - assertEquals(true, actual.contains("flavour=3u")); - assertEquals(true, actual.contains("flavour=3b")); - assertEquals(true, - actual.contains("isCompliant=true")); - // test some xml - // assertEquals(true, actual.contains("[CII-DT-031] - currencyID should not be - // present")); - // test some binary signature recognition - assertEquals(true, actual.contains("2")); + final XMLValidator xv = new XMLValidator(vc); + xv.setStringContent(pv.getRawXML()); + xv.validate(); + actual = vc.getXMLResult(); - // valid one - contents = getResourceAsByteArray("validV2PDF.pdf"); + assertEquals(true, actual.contains("flavour=3u")); + assertEquals(true, actual.contains("flavour=3b")); + assertEquals(true, + actual.contains("isCompliant=true")); + // test some xml + // assertEquals(true, actual.contains("[CII-DT-031] - currencyID should not be + // present")); + // test some binary signature recognition + assertEquals(true, actual.contains("2")); - pv.setFilenameAndContents("validV2PDF.pdf", contents); - vc.clear(); - pv.validate(); - actual = pv.getXMLResult(); - assertEquals(true, actual.contains("flavour=3u")); - assertEquals(true, actual.contains("summary status=\"valid")); - assertEquals(false, actual.contains("summary status=\"invalid")); + // valid one + contents = getResourceAsByteArray("validV2PDF.pdf"); - assertEquals(false, actual.contains("XMP Metadata: ConformanceLevel contains invalid value")); - xv = new XMLValidator(vc); + contents = getResourceAsByteArray("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf"); - xv.setStringContent(pv.getRawXML()); - xv.validate(); - xmlvres = xv.getXMLResult(); - assertEquals(true, pdfvres.contains("valid") && !pdfvres.contains("invalid")); - assertEquals(true, xmlvres.contains("valid") && !xmlvres.contains("invalid")); - } catch (final IrrecoverableValidationError e) { - // ignore, will be in XML output anyway - }*/ + pv.setFilenameAndContents("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf", contents); + vc.clear(); + pv.validate(); + actual = pv.getXMLResult(); - } + assertEquals(false, actual.contains("XMP Metadata: ConformanceLevel contains invalid value")); - - contents = getResourceAsByteArray("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf"); - - pv.setFilenameAndContents("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf", contents); - vc.clear(); - pv.validate(); - actual = pv.getXMLResult(); - - assertEquals(false, actual.contains("\n" - * + - * "Eine Rechnung (INVOICE) muss die Summe der Rechnungspositionen-Nettobeträge „Sum of Invoice line net amount“ (BT-106) enthalten.\n" - * + - * "\n" - * + - * "Der Inhalt des Elementes „Invoice total amount without VAT“ (BT-109) entspricht der Summe aller Inhalte der Elemente „Invoice line net amount“ (BT-131) abzüglich der Summe aller in der Rechnung enthaltenen Nachlässe der Dokumentenebene „Sum of allowances on document level“ (BT-107) zuzüglich der Summe aller in der Rechnung enthaltenen Abgaben der Dokumentenebene „Sum of charges on document level“ (BT-108).\n" - * + - * "\n" - * + - * "Der Inhalt des Elementes „Invoice total amount with VAT“ (BT-112) entspricht der Summe des Inhalts des Elementes „Invoice total amount without VAT“ (BT-109) und des Elementes „Invoice total VAT amount“ (BT-110).\n" - * + - * "\n" - * + - * "Der Inhalt des Elementes „Sum of Invoice line net amount“ (BT-106) entspricht der Summe aller Inhalte der Elemente „Invoice line net amount“ (BT-131).\n" - * + - * "\n" - * + - * "Eine Rechnung (INVOICE) muss den Erwerbernamen „Buyer name“ (BT-44) enthalten.\n" - * + - * "\n" - * + "Das Element 'ram:Name' muss genau 1 mal auftreten.\n" + - * "\n" - * + "Das Element 'ram:LineTotalAmount' muss genau 1 mal auftreten.\n" - * + - * "\n" - * + "Wert von '@unitCode' ist unzulässig.\n" + - * "")); - * - */ + /* + * assertEquals(true, xv.getXMLResult(). + * contains("\n" + * + + * "Eine Rechnung (INVOICE) muss die Summe der Rechnungspositionen-Nettobeträge „Sum of Invoice line net amount“ (BT-106) enthalten.\n" + * + + * "\n" + * + + * "Der Inhalt des Elementes „Invoice total amount without VAT“ (BT-109) entspricht der Summe aller Inhalte der Elemente „Invoice line net amount“ (BT-131) abzüglich der Summe aller in der Rechnung enthaltenen Nachlässe der Dokumentenebene „Sum of allowances on document level“ (BT-107) zuzüglich der Summe aller in der Rechnung enthaltenen Abgaben der Dokumentenebene „Sum of charges on document level“ (BT-108).\n" + * + + * "\n" + * + + * "Der Inhalt des Elementes „Invoice total amount with VAT“ (BT-112) entspricht der Summe des Inhalts des Elementes „Invoice total amount without VAT“ (BT-109) und des Elementes „Invoice total VAT amount“ (BT-110).\n" + * + + * "\n" + * + + * "Der Inhalt des Elementes „Sum of Invoice line net amount“ (BT-106) entspricht der Summe aller Inhalte der Elemente „Invoice line net amount“ (BT-131).\n" + * + + * "\n" + * + + * "Eine Rechnung (INVOICE) muss den Erwerbernamen „Buyer name“ (BT-44) enthalten.\n" + * + + * "\n" + * + "Das Element 'ram:Name' muss genau 1 mal auftreten.\n" + + * "\n" + * + "Das Element 'ram:LineTotalAmount' muss genau 1 mal auftreten.\n" + * + + * "\n" + * + "Wert von '@unitCode' ist unzulässig.\n" + + * "")); + * + */ - tempFile = getResourceAsFile("invalidV2Profile.xml"); + tempFile = getResourceAsFile("invalidV2Profile.xml"); - xv.setFilename(tempFile.getAbsolutePath()); + xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); - } catch (final IrrecoverableValidationError e) { - noException = false; //after corrected dependencies no longer expecting a exception here - } - assertTrue(noException); - noException=true;// moving on... - assertTrue(xv.getXMLResult().contains(""; + content = "" + res + ""; - /*assertThat(content).valueByXPath("count(//error)") - .asInt() - .isGreaterThan(0); //1 error has to be there, 2 are OK because there is a known bug in FX/ZF + /*assertThat(content).valueByXPath("count(//error)") + .asInt() + .isGreaterThan(0); //1 error has to be there, 2 are OK because there is a known bug in FX/ZF - assertThat(content).valueByXPath("//error[@type=\"4\"]") - .asString() - .contains( - "In Deutschland sind die Profile MINIMUM und BASIC WL nur als Buchungshilfe (TypeCode: 751) zugelassen."); + assertThat(content).valueByXPath("//error[@type=\"4\"]") + .asString() + .contains( + "In Deutschland sind die Profile MINIMUM und BASIC WL nur als Buchungshilfe (TypeCode: 751) zugelassen."); */ - ctx.clear(); - tempFile = getResourceAsFile("validV2Basic.xml"); - try { + ctx.clear(); + tempFile = getResourceAsFile("validV2Basic.xml"); + try { - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); - assertEquals(true, xv.getXMLResult().contains("valid") && !xv.getXMLResult().contains("invalid")); + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); + assertEquals(true, xv.getXMLResult().contains("valid") && !xv.getXMLResult().contains("invalid")); - ctx.clear(); - tempFile = getResourceAsFile("ZUGFeRD-invoice_rabatte_3_abschlag_duepayableamount.xml"); - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); - assertEquals(true, xv.getXMLResult().contains("valid") && !xv.getXMLResult().contains("invalid")); + ctx.clear(); + tempFile = getResourceAsFile("ZUGFeRD-invoice_rabatte_3_abschlag_duepayableamount.xml"); + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); + assertEquals(true, xv.getXMLResult().contains("valid") && !xv.getXMLResult().contains("invalid")); - ctx.clear(); - tempFile = getResourceAsFile("valid_Avoir_FR_type380_minimum_factur-x.xml"); - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); + ctx.clear(); + tempFile = getResourceAsFile("valid_Avoir_FR_type380_minimum_factur-x.xml"); + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); - source = Input.fromString("" + xv.getXMLResult() + "").build(); - content = xpath.evaluate("/validation/summary/@status", source); - assertEquals("invalid", content); + source = Input.fromString("" + xv.getXMLResult() + "").build(); + content = xpath.evaluate("/validation/summary/@status", source); + assertEquals("invalid", content); - // assertEquals(true, xv.getXMLResult().contains("valid") && - // !xv.getXMLResult().contains("invalid")); + // assertEquals(true, xv.getXMLResult().contains("valid") && + // !xv.getXMLResult().contains("invalid")); - /* - * this test failure might have to be upstreamed ctx.clear(); tempFile = - * getResourceAsFile( - * "ZUGFeRD-invoice_rabatte_4_abschlag_taxbasistotalamount.xml"); - * xv.setFilename(tempFile.getAbsolutePath()); xv.validate(); assertEquals(true, - * xv.getXMLResult().contains("valid") && - * !xv.getXMLResult().contains("invalid")); - */ - ctx.clear(); - tempFile = getResourceAsFile("attributeBasedXMP_zugferd_2p0_EN16931_Einfach_corrected.xml"); - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); - assertEquals(true, xv.getXMLResult().contains("valid") && !xv.getXMLResult().contains("invalid")); + /* + * this test failure might have to be upstreamed ctx.clear(); tempFile = + * getResourceAsFile( + * "ZUGFeRD-invoice_rabatte_4_abschlag_taxbasistotalamount.xml"); + * xv.setFilename(tempFile.getAbsolutePath()); xv.validate(); assertEquals(true, + * xv.getXMLResult().contains("valid") && + * !xv.getXMLResult().contains("invalid")); + */ + ctx.clear(); + tempFile = getResourceAsFile("attributeBasedXMP_zugferd_2p0_EN16931_Einfach_corrected.xml"); + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); + assertEquals(true, xv.getXMLResult().contains("valid") && !xv.getXMLResult().contains("invalid")); - ctx.clear(); - tempFile = getResourceAsFile("validZREtestZugferd.xml"); - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); + ctx.clear(); + tempFile = getResourceAsFile("validZREtestZugferd.xml"); + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); - source = Input.fromString("" + xv.getXMLResult() + "").build(); - content = xpath.evaluate("/validation/summary/@status", source); - assertEquals("invalid", content); - } catch (final IrrecoverableValidationError e) { - // ignore, will be in XML output anyway - noException = false; - } - assertTrue(noException); - try { - ctx.clear(); - tempFile = getResourceAsFile("invalidV2Root.xml"); - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); + source = Input.fromString("" + xv.getXMLResult() + "").build(); + content = xpath.evaluate("/validation/summary/@status", source); + assertEquals("invalid", content); + } catch (final IrrecoverableValidationError e) { + // ignore, will be in XML output anyway + noException = false; + } + assertTrue(noException); + try { + ctx.clear(); + tempFile = getResourceAsFile("invalidV2Root.xml"); + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); - } catch (final IrrecoverableValidationError e) { - // do expect this! - noException = false; - } - assertFalse(noException); - noException=true; + } catch (final IrrecoverableValidationError e) { + // do expect this! + noException = false; + } + assertFalse(noException); + noException = true; - } + } - public void testZF1XMLValidation() { - final ValidationContext ctx = new ValidationContext(null); - final XMLValidator xv = new XMLValidator(ctx); - File tempFile = getResourceAsFile("validV1.xml"); - try { - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); - assertEquals(true, xv.getXMLResult().contains("valid") && !xv.getXMLResult().contains("invalid")); + public void testZF1XMLValidation() { + final ValidationContext ctx = new ValidationContext(null); + final XMLValidator xv = new XMLValidator(ctx); + File tempFile = getResourceAsFile("validV1.xml"); + try { + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); + assertEquals(true, xv.getXMLResult().contains("valid") && !xv.getXMLResult().contains("invalid")); - tempFile = getResourceAsFile("invalidV1ExtraTags.xml"); - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); - assertEquals(true, xv.getXMLResult().contains("invalid")); + tempFile = getResourceAsFile("invalidV1ExtraTags.xml"); + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); + assertEquals(true, xv.getXMLResult().contains("invalid")); - tempFile = getResourceAsFile("invalidV1TooMinimal.xml"); - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); - assertEquals(true, xv.getXMLResult().contains("" + xv.getXMLResult() + "").build(); + Source source = Input.fromString("" + xv.getXMLResult() + "").build(); - // THEN validation returns only warning message - boolean onlyWarnings = Boolean.parseBoolean(xpath.evaluate("not(//messages/*[not(self::warning)])", source)); - assertTrue(onlyWarnings); + // THEN validation returns only warning message + boolean onlyWarnings = Boolean.parseBoolean(xpath.evaluate("not(//messages/*[not(self::warning)])", source)); + assertTrue(onlyWarnings); - // THEN validation returns summary status valid - String status = xpath.evaluate("/validation/summary/@status", source); - assertEquals("valid", status); - } catch (IrrecoverableValidationError e) { - noExceptions = false; - } - assertTrue(noExceptions); - } + // THEN validation returns summary status valid + String status = xpath.evaluate("/validation/summary/@status", source); + assertEquals("valid", status); + } catch (IrrecoverableValidationError e) { + noExceptions = false; + } + assertTrue(noExceptions); + } - public void testXRValidation() { - final ValidationContext ctx = new ValidationContext(null); - final XMLValidator xv = new XMLValidator(ctx); - final XPathEngine xpath = new JAXPXPathEngine(); + public void testXRValidation() { + final ValidationContext ctx = new ValidationContext(null); + final XMLValidator xv = new XMLValidator(ctx); + final XPathEngine xpath = new JAXPXPathEngine(); - File tempFile = getResourceAsFile("validXRv2.xml"); - try { - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); + File tempFile = getResourceAsFile("validXRv2.xml"); + try { + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); - Source source = Input.fromString("" + xv.getXMLResult() + "").build(); - String content = xpath.evaluate("/validation/summary/@status", source); - assertEquals("valid", content); + Source source = Input.fromString("" + xv.getXMLResult() + "").build(); + String content = xpath.evaluate("/validation/summary/@status", source); + assertEquals("valid", content); - tempFile = getResourceAsFile("invalidXRv2.xml"); - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); + tempFile = getResourceAsFile("invalidXRv2.xml"); + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); - source = Input.fromString("" + xv.getXMLResult() + "").build(); - content = xpath.evaluate("/validation/summary/@status", source); - assertEquals("invalid", content); + source = Input.fromString("" + xv.getXMLResult() + "").build(); + content = xpath.evaluate("/validation/summary/@status", source); + assertEquals("invalid", content); - } catch (final IrrecoverableValidationError e) { - // ignore, will be in XML output anyway - } + } catch (final IrrecoverableValidationError e) { + // ignore, will be in XML output anyway + } - } + } - public void testXRSchemaValidation() { - final ValidationContext ctx = new ValidationContext(null); - final XMLValidator xv = new XMLValidator(ctx); - final XPathEngine xpath = new JAXPXPathEngine(); + public void testXRSchemaValidation() { + final ValidationContext ctx = new ValidationContext(null); + final XMLValidator xv = new XMLValidator(ctx); + final XPathEngine xpath = new JAXPXPathEngine(); - File tempFile = getResourceAsFile("invalidXRSchemav2.xml"); - try { - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); + File tempFile = getResourceAsFile("invalidXRSchemav2.xml"); + try { + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); - Source source = Input.fromString("" + xv.getXMLResult() + "").build(); - String content = xpath.evaluate("/validation/summary/@status", source); - assertEquals("invalid", content); + Source source = Input.fromString("" + xv.getXMLResult() + "").build(); + String content = xpath.evaluate("/validation/summary/@status", source); + assertEquals("invalid", content); - } catch (final IrrecoverableValidationError e) { - // ignore, will be in XML output anyway - } + } catch (final IrrecoverableValidationError e) { + // ignore, will be in XML output anyway + } - } + } - public void testXRValidationUBL() { - ValidationContext ctx = new ValidationContext(null); - XMLValidator xv = new XMLValidator(ctx); - XPathEngine xpath = new JAXPXPathEngine(); + public void testXRValidationUBL() { + ValidationContext ctx = new ValidationContext(null); + XMLValidator xv = new XMLValidator(ctx); + XPathEngine xpath = new JAXPXPathEngine(); - boolean noExceptions = true; - File tempFile = getResourceAsFile("01.01a-INVOICE_ubl.xml"); - try { - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); + boolean noExceptions = true; + File tempFile = getResourceAsFile("01.01a-INVOICE_ubl.xml"); + try { + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); - Source source = Input.fromString("" + xv.getXMLResult() + "").build(); - String content = xpath.evaluate("/validation/summary/@status", source); - assertEquals("valid", content); + Source source = Input.fromString("" + xv.getXMLResult() + "").build(); + String content = xpath.evaluate("/validation/summary/@status", source); + assertEquals("valid", content); - } catch (IrrecoverableValidationError e) { + } catch (IrrecoverableValidationError e) { - noExceptions = false; - } - assertTrue(noExceptions); + noExceptions = false; + } + assertTrue(noExceptions); - } + } - public void testUBLValidation() { - ValidationContext ctx = new ValidationContext(null); - XMLValidator xv = new XMLValidator(ctx); - XPathEngine xpath = new JAXPXPathEngine(); + public void testUBLValidation() { + ValidationContext ctx = new ValidationContext(null); + XMLValidator xv = new XMLValidator(ctx); + XPathEngine xpath = new JAXPXPathEngine(); - boolean noExceptions = true; - File tempFile = getResourceAsFile("EN16931_Einfach.ubl.xml"); - try { - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); + boolean noExceptions = true; + File tempFile = getResourceAsFile("EN16931_Einfach.ubl.xml"); + try { + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); - Source source = Input.fromString("" + xv.getXMLResult() + "").build(); - String content = xpath.evaluate("/validation/summary/@status", source); - assertEquals("valid", content); + Source source = Input.fromString("" + xv.getXMLResult() + "").build(); + String content = xpath.evaluate("/validation/summary/@status", source); + assertEquals("valid", content); - } catch (IrrecoverableValidationError e) { + } catch (IrrecoverableValidationError e) { - noExceptions = false; - } - assertTrue(noExceptions); - tempFile = getResourceAsFile("ubl-tc434-creditnote1.xml"); - try { - xv.setFilename(tempFile.getAbsolutePath()); - xv.validate(); + noExceptions = false; + } + assertTrue(noExceptions); + tempFile = getResourceAsFile("ubl-tc434-creditnote1.xml"); + try { + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); - Source source = Input.fromString("" + xv.getXMLResult() + "").build(); - String content = xpath.evaluate("/validation/summary/@status", source); - assertEquals("valid", content); + Source source = Input.fromString("" + xv.getXMLResult() + "").build(); + String content = xpath.evaluate("/validation/summary/@status", source); + assertEquals("valid", content); - } catch (IrrecoverableValidationError e) { + } catch (IrrecoverableValidationError e) { - noExceptions = false; - } - assertTrue(noExceptions); + noExceptions = false; + } + assertTrue(noExceptions); - } + } } diff --git a/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileChecker.java b/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileChecker.java index e089910..48b62c6 100755 --- a/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileChecker.java +++ b/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileChecker.java @@ -18,80 +18,80 @@ org.openrewrite.config.CompositeRecipe *********************************************************************** */ package org.mustangproject.commandline; -import java.math.BigDecimal; - import org.mustangproject.ZUGFeRD.ZUGFeRDImporter; +import java.math.BigDecimal; + public class FileChecker { - String filename; - StatRun thisRun; - boolean isPDF = false; + String filename; + StatRun thisRun; + boolean isPDF = false; - public FileChecker(String filename, StatRun statistics) { - this.filename = filename; - thisRun = statistics; - thisRun.incFileCount(); - String extension = ""; - if (!thisRun.shallIgnoreFileExt()) { - int extIndex = filename.lastIndexOf("."); - if (extIndex >= 0) { - extension = filename.substring(extIndex).toLowerCase(); - isPDF = extension.equals(".pdf");// alternative check for PDF: File starts with %PDF- - if (isPDF) { - thisRun.incPDFCount(); - } - } + public FileChecker(String filename, StatRun statistics) { + this.filename = filename; + thisRun = statistics; + thisRun.incFileCount(); + String extension = ""; + if (!thisRun.shallIgnoreFileExt()) { + int extIndex = filename.lastIndexOf("."); + if (extIndex >= 0) { + extension = filename.substring(extIndex).toLowerCase(); + isPDF = extension.equals(".pdf");// alternative check for PDF: File starts with %PDF- + if (isPDF) { + thisRun.incPDFCount(); + } + } - } else { - thisRun.incPDFCount(); - } - } + } else { + thisRun.incPDFCount(); + } + } - public boolean checkForZUGFeRD() { - if ((!isPDF) && (!thisRun.shallIgnoreFileExt())) { - return false; - } - ZUGFeRDImporter zi = new ZUGFeRDImporter(); - zi.doIgnoreCalculationErrors(); - zi.setPDFFilename(filename); - try { - if (zi.canParse()) { - thisRun.incZUGFeRDCount(zi.getVersion()); - thisRun.incTotal(new BigDecimal(zi.getAmount())); - return true; - } else { - return false; - } - } catch (NullPointerException e) { - // something really rare happened -- corrupted ZF? - /*** - * e.g. Exception in thread "main" java.lang.NullPointerException - at org.mustangproject.ZUGFeRD.ZUGFeRDImporter.extractLowLevel(ZUGFeRDImporter.java:90) - at org.mustangproject.ZUGFeRD.ZUGFeRDImporter.extract(ZUGFeRDImporter.java:64) - at toecount.FileChecker.checkForZUGFeRD(FileChecker.java:33) - at toecount.Toecount.main(Toecount.java:111) - * - */ - // Ignore nevertheless, most likely we're batch processing - return false; - } catch (Exception e2) { - /** - * probably thrown up from - AM org.apache.pdfbox.pdfparser.PDFParser parse, most likely - INFORMATION: Document is encrypted - but also other internal PDF errors possible like - ..Okt 23, 2015 11:17:53 AM org.apache.pdfbox.pdfparser.XrefTrailerResolver setStartxref - */ - return false; - } - } + public boolean checkForZUGFeRD() { + if ((!isPDF) && (!thisRun.shallIgnoreFileExt())) { + return false; + } + ZUGFeRDImporter zi = new ZUGFeRDImporter(); + zi.doIgnoreCalculationErrors(); + zi.setPDFFilename(filename); + try { + if (zi.canParse()) { + thisRun.incZUGFeRDCount(zi.getVersion()); + thisRun.incTotal(new BigDecimal(zi.getAmount())); + return true; + } else { + return false; + } + } catch (NullPointerException e) { + // something really rare happened -- corrupted ZF? + /*** + * e.g. Exception in thread "main" java.lang.NullPointerException + at org.mustangproject.ZUGFeRD.ZUGFeRDImporter.extractLowLevel(ZUGFeRDImporter.java:90) + at org.mustangproject.ZUGFeRD.ZUGFeRDImporter.extract(ZUGFeRDImporter.java:64) + at toecount.FileChecker.checkForZUGFeRD(FileChecker.java:33) + at toecount.Toecount.main(Toecount.java:111) + * + */ + // Ignore nevertheless, most likely we're batch processing + return false; + } catch (Exception e2) { + /** + * probably thrown up from + AM org.apache.pdfbox.pdfparser.PDFParser parse, most likely + INFORMATION: Document is encrypted + but also other internal PDF errors possible like + ..Okt 23, 2015 11:17:53 AM org.apache.pdfbox.pdfparser.XrefTrailerResolver setStartxref + */ + return false; + } + } - public boolean isPDF() { - return isPDF; - } + public boolean isPDF() { + return isPDF; + } - public String getOutputLine() { - return thisRun.getOutputLine(); - } + public String getOutputLine() { + return thisRun.getOutputLine(); + } } diff --git a/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileTraverser.java b/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileTraverser.java index b0df662..f1d944e 100755 --- a/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileTraverser.java +++ b/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileTraverser.java @@ -29,47 +29,47 @@ org.openrewrite.config.CompositeRecipe public class FileTraverser extends SimpleFileVisitor { - private StatRun thisRun; + private StatRun thisRun; - public FileTraverser(StatRun statistics) { - this.thisRun = statistics; - } + public FileTraverser(StatRun statistics) { + this.thisRun = statistics; + } - /** - * check each file - */ - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attr) { - if (attr.isSymbolicLink()) { - // Not yet handled - } else if (attr.isRegularFile()) { - String filename = file.toString(); - FileChecker fc = new FileChecker(filename, thisRun); - fc.checkForZUGFeRD(); - System.out.print(fc.getOutputLine()); + /** + * check each file + */ + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attr) { + if (attr.isSymbolicLink()) { + // Not yet handled + } else if (attr.isRegularFile()) { + String filename = file.toString(); + FileChecker fc = new FileChecker(filename, thisRun); + fc.checkForZUGFeRD(); + System.out.print(fc.getOutputLine()); - } - return CONTINUE; - } + } + return CONTINUE; + } - /** - * for each directory - */ - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) { - // System.out.format("Directory: %s%n", dir); - thisRun.incDirCount(); - return CONTINUE; - } + /** + * for each directory + */ + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { + // System.out.format("Directory: %s%n", dir); + thisRun.incDirCount(); + return CONTINUE; + } - /** - * show errors like file permission stacktraces - */ - @Override - public FileVisitResult visitFileFailed(Path file, IOException exc) { - System.err.println(exc); - return CONTINUE; - } + /** + * show errors like file permission stacktraces + */ + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + System.err.println(exc); + return CONTINUE; + } } diff --git a/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java b/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java index bf571c7..bd0272c 100755 --- a/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java +++ b/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java @@ -25,6 +25,7 @@ org.openrewrite.config.CompositeRecipe import org.mustangproject.FileAttachment; import org.mustangproject.ZUGFeRD.*; import org.mustangproject.validator.ZUGFeRDValidator; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.xml.transform.TransformerException; @@ -32,907 +33,908 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; +import org.mustangproject.ZUGFeRD.Version; + public class Main { - private static org.slf4j.Logger LOGGER; // log output + private static Logger LOGGER; // log output - private static void printUsage() { - System.err.println(getUsage()); - } + private static void printUsage() { + System.err.println(getUsage()); + } - private static String getUsage() { - return "Usage: --action metrics|combine|extract|a3only|ubl|validate|validateExpectInvalid|validateExpectValid|visualize [-d,--directory] [-l,--listfromstdin] [-i,--ignore fileextension, PDF/A errors] [--disable-file-logging] | [-h,--help] \r\n" - + " --action license display open source license and notice\n" - + " --action metrics\n" - + " -d, --directory count ZUGFeRD files in directory to be scanned\n" - + " If it is a directory, it will recurse.\n" - + " -l, --listfromstdin count ZUGFeRD files from a list of linefeed separated files on runtime.\n" - + " It will start once a blank line has been entered.\n" + "\n" - + " Additional parameter for both count operations\n" - + " [-i, --ignorefileextension] Check for all files (*.*) instead of PDF files only (*.pdf) in metrics, ignore PDF/A input file errors in combine\n" - + " [--disable-file-logging] disable logging to file.\n" - + " --action extract extract Factur-X PDF to XML file\n" - + " Additional parameters (optional - user will be prompted if not defined)\n" - + " [--source ]: set input PDF file\n" - + " [--out ]: set output XML file\n" - + " --action a3only upgrade from PDF/A1 to A3 only (no ZUGFeRD data attached)\n" - + " Additional parameters (optional - user will be prompted if not defined)\n" - + " [--source ]: set input PDF file\n" - + " [--out ]: set output PDF file\n" - + " --action combine combine XML and PDF file to Factur-X PDF file\n" - + " Additional parameters (optional - user will be prompted if not defined)\n" - + " [--source ]: set input PDF file\n" - + " [--source-xml ]: set input XML file\n" - + " [--out ]: set output PDF file\n" - + " [--format ]: set Factur-X, ZUGFeRD, Order-X or Cross Industry Despatch Advice\n" - + " [--version <1|2>]: set ZUGFeRD version\n" - + " [--profile <...>]: set ZUGFeRD profile\n" - + " For ZUGFeRD v1 or Order-X: ASIC, OMFORT or EXENDED\n" - + " For ZUGFeRD v2: INIMUM, BASIC L, ASIC, IUS, N16931, Rechnung, EXENDED\n" - + " [--attachments ]: list of file attachments (passing a single empty file name prevents prompting)\n" - + " [--no-additional-attachments]: prevent prompting for attachments\n" - + " --action ubl convert UN/CEFACT 2016b CII XML to UBL XML\n" - + " [--source ]: set input XML file\n" - + " [--out ]: set output XML file\n" - + " --action upgrade upgrade ZUGFeRD XML to ZUGFeRD 2 XML\n" - + " Additional parameters (optional - user will be prompted if not defined)\n" - + " [--source ]: set input XML ZUGFeRD 1 file\n" - + " [--out ]: set output XML ZUGFeRD 2 file\n" - + " --action validate validate XML or PDF file \n" - + " [--no-notices]: refrain from reporting notices\n" - + " [--logAppend ]: text to be added to log line\n" - + " Additional parameters (optional - user will be prompted if not defined)\n" - + " [--source ]: input PDF or XML file\n" - + " [--log-as-pdf]: save log output as pdf\n" - + " --action validateExpectInvalid validate directory expecting negative results \n" - + " [--no-notices]: refrain from reporting notices\n" - + " Additional parameters (optional - user will be prompted if not defined)\n" - + " -d, --directory to check recursively\n" - + " --action validateExpectValid validate directory expecting positive results \n" - + " [--no-notices]: refrain from reporting notices\n" - + " Additional parameters (optional - user will be prompted if not defined)\n" - + " -d, --directory to check recursively \n" - + " --action visualize convert XML to HTML \n" - + " [--language ]: set output lang (en, fr or de)\n" - + " [--source ]: set input XML file\n" - + " [--out ]: set output HTML file\n" - + " --action pdf convert XML to PDF \n" - + " [--language ]: set output lang (en, fr or de)\n" - + " [--source ]: set input XML file\n" - + " [--out ]: set output PDF file\n" - ; - } + private static String getUsage() { + return "Usage: --action metrics|combine|extract|a3only|ubl|validate|validateExpectInvalid|validateExpectValid|visualize [-d,--directory] [-l,--listfromstdin] [-i,--ignore fileextension, PDF/A errors] [--disable-file-logging] | [-h,--help] \r\n" + + " --action license display open source license and notice\n" + + " --action metrics\n" + + " -d, --directory count ZUGFeRD files in directory to be scanned\n" + + " If it is a directory, it will recurse.\n" + + " -l, --listfromstdin count ZUGFeRD files from a list of linefeed separated files on runtime.\n" + + " It will start once a blank line has been entered.\n" + "\n" + + " Additional parameter for both count operations\n" + + " [-i, --ignorefileextension] Check for all files (*.*) instead of PDF files only (*.pdf) in metrics, ignore PDF/A input file errors in combine\n" + + " [--disable-file-logging] disable logging to file.\n" + + " --action extract extract Factur-X PDF to XML file\n" + + " Additional parameters (optional - user will be prompted if not defined)\n" + + " [--source ]: set input PDF file\n" + + " [--out ]: set output XML file\n" + + " --action a3only upgrade from PDF/A1 to A3 only (no ZUGFeRD data attached)\n" + + " Additional parameters (optional - user will be prompted if not defined)\n" + + " [--source ]: set input PDF file\n" + + " [--out ]: set output PDF file\n" + + " --action combine combine XML and PDF file to Factur-X PDF file\n" + + " Additional parameters (optional - user will be prompted if not defined)\n" + + " [--source ]: set input PDF file\n" + + " [--source-xml ]: set input XML file\n" + + " [--out ]: set output PDF file\n" + + " [--format ]: set Factur-X, ZUGFeRD, Order-X or Cross Industry Despatch Advice\n" + + " [--version <1|2>]: set ZUGFeRD version\n" + + " [--profile <...>]: set ZUGFeRD profile\n" + + " For ZUGFeRD v1 or Order-X: ASIC, OMFORT or EXENDED\n" + + " For ZUGFeRD v2: INIMUM, BASIC L, ASIC, IUS, N16931, Rechnung, EXENDED\n" + + " [--attachments ]: list of file attachments (passing a single empty file name prevents prompting)\n" + + " [--no-additional-attachments]: prevent prompting for attachments\n" + + " --action ubl convert UN/CEFACT 2016b CII XML to UBL XML\n" + + " [--source ]: set input XML file\n" + + " [--out ]: set output XML file\n" + + " --action upgrade upgrade ZUGFeRD XML to ZUGFeRD 2 XML\n" + + " Additional parameters (optional - user will be prompted if not defined)\n" + + " [--source ]: set input XML ZUGFeRD 1 file\n" + + " [--out ]: set output XML ZUGFeRD 2 file\n" + + " --action validate validate XML or PDF file \n" + + " [--no-notices]: refrain from reporting notices\n" + + " [--logAppend ]: text to be added to log line\n" + + " Additional parameters (optional - user will be prompted if not defined)\n" + + " [--source ]: input PDF or XML file\n" + + " [--log-as-pdf]: save log output as pdf\n" + + " --action validateExpectInvalid validate directory expecting negative results \n" + + " [--no-notices]: refrain from reporting notices\n" + + " Additional parameters (optional - user will be prompted if not defined)\n" + + " -d, --directory to check recursively\n" + + " --action validateExpectValid validate directory expecting positive results \n" + + " [--no-notices]: refrain from reporting notices\n" + + " Additional parameters (optional - user will be prompted if not defined)\n" + + " -d, --directory to check recursively \n" + + " --action visualize convert XML to HTML \n" + + " [--language ]: set output lang (en, fr or de)\n" + + " [--source ]: set input XML file\n" + + " [--out ]: set output HTML file\n" + + " --action pdf convert XML to PDF \n" + + " [--language ]: set output lang (en, fr or de)\n" + + " [--source ]: set input XML file\n" + + " [--out ]: set output PDF file\n" + ; + } - private static void printHelp() { - System.out.println("Mustangproject.org " + org.mustangproject.ZUGFeRD.Version.VERSION + " \r\n" - + "A Apache Public License tool for e-invoices with\r\n" - + "ZUGFeRD Metadata (http://www.zugferd.org)\r\n" + "\r\n" + getUsage() + "\r\n"); - } + private static void printHelp() { + System.out.println("Mustangproject.org " + Version.VERSION + " \r\n" + + "A Apache Public License tool for e-invoices with\r\n" + + "ZUGFeRD Metadata (http://www.zugferd.org)\r\n" + "\r\n" + getUsage() + "\r\n"); + } - /** - * Asks the user (repeatedly, if necessary) on the command line for a String - * (offering a defaultValue) conforming to a Regex pattern - * - * @param prompt the question to be asked to the user - * @param defaultValue the default return value if user hits enter - * @param pattern a regex of acceptable values - * @return the user answer conforming to pattern - * @throws Exception if pattern not compilable or IOException on input - */ - protected static String getStringFromUser(String prompt, String defaultValue, String pattern) throws Exception { - String input = ""; - if (!defaultValue.matches(pattern)) { - throw new Exception("Default value must match pattern"); - } - boolean firstInput = true; - do { - // for a more sophisticated dialogue maybe https://github.com/mabe02/lanterna/ - // could be taken into account - System.out.print(prompt + " (default: " + defaultValue + ")"); - if ((!firstInput) && (pattern.length() > 0)) { - System.out.print("\n(allowed pattern: " + pattern + ")"); + /** + * Asks the user (repeatedly, if necessary) on the command line for a String + * (offering a defaultValue) conforming to a Regex pattern + * + * @param prompt the question to be asked to the user + * @param defaultValue the default return value if user hits enter + * @param pattern a regex of acceptable values + * @return the user answer conforming to pattern + * @throws Exception if pattern not compilable or IOException on input + */ + protected static String getStringFromUser(String prompt, String defaultValue, String pattern) throws Exception { + String input = ""; + if (!defaultValue.matches(pattern)) { + throw new Exception("Default value must match pattern"); + } + boolean firstInput = true; + do { + // for a more sophisticated dialogue maybe https://github.com/mabe02/lanterna/ + // could be taken into account + System.out.print(prompt + " (default: " + defaultValue + ")"); + if ((!firstInput) && (pattern.length() > 0)) { + System.out.print("\n(allowed pattern: " + pattern + ")"); - } - System.out.print(":"); - BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in)); - try { - input = buffer.readLine(); - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); + } + System.out.print(":"); + BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in)); + try { + input = buffer.readLine(); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); - } + } - if (input.isEmpty()) { - // pressed return without entering anything - input = defaultValue; - } + if (input.isEmpty()) { + // pressed return without entering anything + input = defaultValue; + } - firstInput = false; - } while (!input.matches(pattern)); + firstInput = false; + } while (!input.matches(pattern)); - return input; - } + return input; + } - /** - * Prompts the user for a input or output filename - * - * @param prompt the text the user is asked - * @param defaultFilename a default Filename. Passing an empty string indicates that specifying a file is optional - * @param expectedExtension will warn if filename does not match expected file extension, "or" possible with e.g. pdf|xml - * @param ensureFileExists will warn if file does NOT exist (for input files) - * @param ensureFileNotExists will warn if file DOES exist (for output files) - * @return String - */ - protected static String getFilenameFromUser(String prompt, String defaultFilename, String expectedExtension, - boolean ensureFileExists, boolean ensureFileNotExists) { - boolean fileExistenceOK = false; - String selectedName = ""; - do { - // for a more sophisticated dialogue maybe https://github.com/mabe02/lanterna/ - // could be taken into account - System.out.print(prompt + (defaultFilename.isEmpty() ? ":" : " (default: " + defaultFilename + "):")); - BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in)); - try { - selectedName = buffer.readLine(); - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); + /** + * Prompts the user for a input or output filename + * + * @param prompt the text the user is asked + * @param defaultFilename a default Filename. Passing an empty string indicates that specifying a file is optional + * @param expectedExtension will warn if filename does not match expected file extension, "or" possible with e.g. pdf|xml + * @param ensureFileExists will warn if file does NOT exist (for input files) + * @param ensureFileNotExists will warn if file DOES exist (for output files) + * @return String + */ + protected static String getFilenameFromUser(String prompt, String defaultFilename, String expectedExtension, + boolean ensureFileExists, boolean ensureFileNotExists) { + boolean fileExistenceOK = false; + String selectedName = ""; + do { + // for a more sophisticated dialogue maybe https://github.com/mabe02/lanterna/ + // could be taken into account + System.out.print(prompt + (defaultFilename.isEmpty() ? ":" : " (default: " + defaultFilename + "):")); + BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in)); + try { + selectedName = buffer.readLine(); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); - } + } - if (selectedName.isEmpty()) { - // pressed return without entering anything - if (defaultFilename.isEmpty()) { - return ""; //no default -> this is an optional filename - } - selectedName = defaultFilename; - } + if (selectedName.isEmpty()) { + // pressed return without entering anything + if (defaultFilename.isEmpty()) { + return ""; // no default -> this is an optional filename + } + selectedName = defaultFilename; + } - boolean hasCorrectExtension = false; - String[] expectedExtensions = expectedExtension.split("\\|"); - for (String currentExtension : expectedExtensions) { - if (selectedName.toLowerCase().endsWith(currentExtension.toLowerCase())) { - hasCorrectExtension = true; - break; - } - } - // error cases - if (ensureFileExists) { - if (fileExists(selectedName)) { - fileExistenceOK = true; - } else { - System.out.println("File does not exist, try again or CTRL+C to cancel"); - // discard the input, a scanner.reset is not sufficient - fileExistenceOK = false; - } - } else if (!hasCorrectExtension) { - System.err.println("Expected " + expectedExtension - + " extension, this may corrupt your file. Do you still want to continue?(Y|N)"); - String selectedAnswer = ""; - try { - selectedAnswer = buffer.readLine(); - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); - } - if (!selectedAnswer.equals("Y") && !selectedAnswer.equals("y")) { - System.err.println("Aborted by user"); - System.exit(-1); - } + boolean hasCorrectExtension = false; + String[] expectedExtensions = expectedExtension.split("\\|"); + for (String currentExtension : expectedExtensions) { + if (selectedName.toLowerCase().endsWith(currentExtension.toLowerCase())) { + hasCorrectExtension = true; + break; + } + } + // error cases + if (ensureFileExists) { + if (fileExists(selectedName)) { + fileExistenceOK = true; + } else { + System.out.println("File does not exist, try again or CTRL+C to cancel"); + // discard the input, a scanner.reset is not sufficient + fileExistenceOK = false; + } + } else if (!hasCorrectExtension) { + System.err.println("Expected " + expectedExtension + + " extension, this may corrupt your file. Do you still want to continue?(Y|N)"); + String selectedAnswer = ""; + try { + selectedAnswer = buffer.readLine(); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); + } + if (!selectedAnswer.equals("Y") && !selectedAnswer.equals("y")) { + System.err.println("Aborted by user"); + System.exit(-1); + } - } else { - fileExistenceOK = true; + } else { + fileExistenceOK = true; - if (ensureFileNotExists) { - if (fileExists(selectedName)) { - fileExistenceOK = false; - System.out.println("Output file already exists, try again or CTRL+C to cancel"); - // discard the input, a scanner.reset is not sufficient - } - } else { - fileExistenceOK = true; - } - } + if (ensureFileNotExists) { + if (fileExists(selectedName)) { + fileExistenceOK = false; + System.out.println("Output file already exists, try again or CTRL+C to cancel"); + // discard the input, a scanner.reset is not sufficient + } + } else { + fileExistenceOK = true; + } + } - } while (!fileExistenceOK); + } while (!fileExistenceOK); - return selectedName; - } + return selectedName; + } - private static void performUpgrade(String xmlName, String outName) throws IOException, TransformerException { + private static void performUpgrade(String xmlName, String outName) throws IOException, TransformerException { - // Get params from user if not already defined - if (xmlName == null) { - xmlName = getFilenameFromUser("ZUGFeRD 1.0 XML source", "ZUGFeRD-invoice.xml", "xml", true, false); - } else { - System.out.println("ZUGFeRD 1.0 XML source set to " + xmlName); - } - if (outName == null) { - outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "factur-x.xml", "xml", false, true); - } else { - System.out.println("ZUGFeRD 2 XML target to " + outName); - } + // Get params from user if not already defined + if (xmlName == null) { + xmlName = getFilenameFromUser("ZUGFeRD 1.0 XML source", "ZUGFeRD-invoice.xml", "xml", true, false); + } else { + System.out.println("ZUGFeRD 1.0 XML source set to " + xmlName); + } + if (outName == null) { + outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "factur-x.xml", "xml", false, true); + } else { + System.out.println("ZUGFeRD 2 XML target to " + outName); + } - // Verify params - ensureFileExists(xmlName); - ensureFileNotExists(outName); + // Verify params + ensureFileExists(xmlName); + ensureFileNotExists(outName); - // All params are good! continue... - XMLUpgrader zmi = new XMLUpgrader(); - String xml = zmi.migrateFromV1ToV2(xmlName); - Files.write(Paths.get(outName), xml.getBytes()); - System.out.println("Written to " + outName); + // All params are good! continue... + XMLUpgrader zmi = new XMLUpgrader(); + String xml = zmi.migrateFromV1ToV2(xmlName); + Files.write(Path.of(outName), xml.getBytes()); + System.out.println("Written to " + outName); - } + } - /*** - * converts from CII to UBL - * @param xmlName the name of the xml file - * @param outName the name of the output file - * @throws IOException - * @throws TransformerException - */ - private static void performUBL(String xmlName, String outName) throws IOException, TransformerException { + /*** + * converts from CII to UBL + * @param xmlName the name of the xml file + * @param outName the name of the output file + * @throws IOException + * @throws TransformerException + */ + private static void performUBL(String xmlName, String outName) throws IOException, TransformerException { - // Get params from user if not already defined - if (xmlName == null) { - xmlName = getFilenameFromUser("Factur-X XML source", "factur-x.xml", "xml", true, false); - } else { - System.out.println("Factur-X XML source set to " + xmlName); - } - if (outName == null) { - outName = getFilenameFromUser("UBL target", "ubl-invoice.xml", "xml", false, true); - } else { - System.out.println("UBL target to " + outName); - } + // Get params from user if not already defined + if (xmlName == null) { + xmlName = getFilenameFromUser("Factur-X XML source", "factur-x.xml", "xml", true, false); + } else { + System.out.println("Factur-X XML source set to " + xmlName); + } + if (outName == null) { + outName = getFilenameFromUser("UBL target", "ubl-invoice.xml", "xml", false, true); + } else { + System.out.println("UBL target to " + outName); + } - // Verify params - ensureFileExists(xmlName); - ensureFileNotExists(outName); + // Verify params + ensureFileExists(xmlName); + ensureFileNotExists(outName); - // All params are good! continue... - CIIToUBL c2u = new CIIToUBL(); - c2u.convert(new File(xmlName), new File(outName)); - System.out.println("Written to " + outName); + // All params are good! continue... + CIIToUBL c2u = new CIIToUBL(); + c2u.convert(new File(xmlName), new File(outName)); + System.out.println("Written to " + outName); - } + } - public static void printLicense() { - InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("LICENSE"); - System.out.println(convertInputStreamToString(is)); - is = Thread.currentThread().getContextClassLoader().getResourceAsStream("NOTICE"); - System.out.println(convertInputStreamToString(is)); + public static void printLicense() { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("LICENSE"); + System.out.println(convertInputStreamToString(is)); + is = Thread.currentThread().getContextClassLoader().getResourceAsStream("NOTICE"); + System.out.println(convertInputStreamToString(is)); - } + } - // Plain Java - // based on https://mkyong.com/java/how-to-convert-inputstream-to-string-in-java/ - private static String convertInputStreamToString(InputStream is) { - int DEFAULT_BUFFER_SIZE = 8192; - ByteArrayOutputStream result = new ByteArrayOutputStream(); - byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; - int length; - try { - while ((length = is.read(buffer)) != -1) { - result.write(buffer, 0, length); - } + // Plain Java + // based on https://mkyong.com/java/how-to-convert-inputstream-to-string-in-java/ + private static String convertInputStreamToString(InputStream is) { + int DEFAULT_BUFFER_SIZE = 8192; + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; + int length; + try { + while ((length = is.read(buffer)) != -1) { + result.write(buffer, 0, length); + } - // Java 1.1 - return result.toString(StandardCharsets.UTF_8.name()); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - // Java 10 - // return result.toString(StandardCharsets.UTF_8); + // Java 1.1 + return result.toString(StandardCharsets.UTF_8.name()); + } catch (IOException e) { + LOGGER.error("Exception", e); + } + return null; + // Java 10 + // return result.toString(StandardCharsets.UTF_8); - } + } - /*** - * the main function of the commandline tool... - * @param args the commandline args, see also https://www.mustangproject.org/commandline/#verbose - */ - public static void main(String[] args) { - try { - CommandLine cmd; - CommandLineParser parser = new DefaultParser(); + /*** + * the main function of the commandline tool... + * @param args the commandline args, see also https://www.mustangproject.org/commandline/#verbose + */ + public static void main(String[] args) { + try { + CommandLine cmd; + CommandLineParser parser = new DefaultParser(); - // create Options object - Options options = new Options(); - options.addOption(new Option("h", "help", false, "display usage")); - options.addOption(new Option("a", "action", true, "which action to perform")); - options.addOption(new Option("f", "format", true, "which format to output")); - options.addOption(new Option("version", "version", true, "which version of the standard to use")); - options.addOption(new Option("profile", "profile", true, "which profile of the standard to use")); - options.addOption(new Option("no-additional-attachments", "no-additional-attachments", false, "prevent prompting for attachments")); - Option attachmentOpt = new Option("attachments", "attachments", true, "File attachments"); - attachmentOpt.setValueSeparator(','); - attachmentOpt.setArgs(Option.UNLIMITED_VALUES); + // create Options object + Options options = new Options(); + options.addOption(new Option("h", "help", false, "display usage")); + options.addOption(new Option("a", "action", true, "which action to perform")); + options.addOption(new Option("f", "format", true, "which format to output")); + options.addOption(new Option("version", "version", true, "which version of the standard to use")); + options.addOption(new Option("profile", "profile", true, "which profile of the standard to use")); + options.addOption(new Option("no-additional-attachments", "no-additional-attachments", false, "prevent prompting for attachments")); + Option attachmentOpt = new Option("attachments", "attachments", true, "File attachments"); + attachmentOpt.setValueSeparator(','); + attachmentOpt.setArgs(Option.UNLIMITED_VALUES); - options.addOption(attachmentOpt); - options.addOption(new Option("source", "source", true, "which source file to use")); - options.addOption(new Option("source-xml", "source-xml", true, "which source file to use")); - options.addOption(new Option("language", "language", true, "output language (en, de or fr)")); - options.addOption(new Option("out", "out", true, "which output file to write to")); - options.addOption(new Option("no-notices", "no-notices", false, "suppress non-fatal errors")); - options.addOption(new Option("logAppend", "logAppend", true, "freeform text to be appended to log messages")); - options.addOption(new Option("disable-file-logging", "disable-file-logging", false, "suppress logging to file")); - options.addOption(new Option("d", "directory", true, "which directory to operate on")); - options.addOption(new Option("i", "ignorefileextension", false, "ignore non-matching file extensions")); - options.addOption(new Option("l", "listfromstdin", false, "take list of files from commandline")); - options.addOption(new Option("log-as-pdf", "log-as-pdf", false, "saving log output to pdf file")); + options.addOption(attachmentOpt); + options.addOption(new Option("source", "source", true, "which source file to use")); + options.addOption(new Option("source-xml", "source-xml", true, "which source file to use")); + options.addOption(new Option("language", "language", true, "output language (en, de or fr)")); + options.addOption(new Option("out", "out", true, "which output file to write to")); + options.addOption(new Option("no-notices", "no-notices", false, "suppress non-fatal errors")); + options.addOption(new Option("logAppend", "logAppend", true, "freeform text to be appended to log messages")); + options.addOption(new Option("disable-file-logging", "disable-file-logging", false, "suppress logging to file")); + options.addOption(new Option("d", "directory", true, "which directory to operate on")); + options.addOption(new Option("i", "ignorefileextension", false, "ignore non-matching file extensions")); + options.addOption(new Option("l", "listfromstdin", false, "take list of files from commandline")); + options.addOption(new Option("log-as-pdf", "log-as-pdf", false, "saving log output to pdf file")); - boolean optionsRecognized = false; - String action = ""; + boolean optionsRecognized = false; + String action = ""; - Boolean disableFileLogging = false; - try { - cmd = parser.parse(options, args); + Boolean disableFileLogging = false; + try { + cmd = parser.parse(options, args); - // Retrieve all options - action = cmd.getOptionValue("action"); - String directoryName = cmd.getOptionValue("directory"); - Boolean filesFromStdIn = cmd.hasOption("listfromstdin");//((Number)cmdLine.getParsedOptionValue("integer-option")).intValue(); - Boolean ignoreFileExt = cmd.hasOption("ignorefileextension"); - Boolean noAttachments = cmd.hasOption("no-additional-attachments"); - Boolean helpRequested = cmd.hasOption("help") || ((action != null) && (action.equals("help"))); - disableFileLogging = cmd.hasOption("disable-file-logging"); + // Retrieve all options + action = cmd.getOptionValue("action"); + String directoryName = cmd.getOptionValue("directory"); + Boolean filesFromStdIn = cmd.hasOption("listfromstdin");// ((Number)cmdLine.getParsedOptionValue("integer-option")).intValue(); + Boolean ignoreFileExt = cmd.hasOption("ignorefileextension"); + Boolean noAttachments = cmd.hasOption("no-additional-attachments"); + Boolean helpRequested = cmd.hasOption("help") || ((action != null) && (action.equals("help"))); + disableFileLogging = cmd.hasOption("disable-file-logging"); - String sourceName = cmd.getOptionValue("source"); - String sourceXMLName = cmd.getOptionValue("source-xml"); - String outName = cmd.getOptionValue("out"); - String format = cmd.getOptionValue("format"); - String lang = cmd.getOptionValue("language"); - Boolean noNotices = cmd.hasOption("no-notices"); - Boolean LogAsPDF = cmd.hasOption("log-as-pdf"); + String sourceName = cmd.getOptionValue("source"); + String sourceXMLName = cmd.getOptionValue("source-xml"); + String outName = cmd.getOptionValue("out"); + String format = cmd.getOptionValue("format"); + String lang = cmd.getOptionValue("language"); + Boolean noNotices = cmd.hasOption("no-notices"); + Boolean LogAsPDF = cmd.hasOption("log-as-pdf"); - String zugferdVersion = cmd.getOptionValue("version"); - String zugferdProfile = cmd.getOptionValue("profile"); + String zugferdVersion = cmd.getOptionValue("version"); + String zugferdProfile = cmd.getOptionValue("profile"); - String[] attachmentFilenames = cmd.hasOption("attachments") ? cmd.getOptionValues("attachments") : null; + String[] attachmentFilenames = cmd.hasOption("attachments") ? cmd.getOptionValues("attachments") : null; - ArrayList attachments = new ArrayList<>(); - /* - setting system property to disable FILE appender and - suppress creation of files and folders. - */ - System.setProperty("FILE_APPENDER_ENABLED", ((Boolean) (disableFileLogging == false)).toString()); + ArrayList attachments = new ArrayList<>(); + /* + setting system property to disable FILE appender and + suppress creation of files and folders. + */ + System.setProperty("FILE_APPENDER_ENABLED", ((Boolean) (disableFileLogging == false)).toString()); - LOGGER = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + LOGGER = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - if (helpRequested) { - printHelp(); - optionsRecognized = true; - } /* else if ((action!=null)&&(action.equals("license"))) { - printLicense(); - optionsRecognized=true; - } */ else if ((action != null) && (action.equals("metrics"))) { - performMetrics(directoryName, filesFromStdIn, ignoreFileExt); - optionsRecognized = true; - } else if ((action != null) && (action.equals("combine"))) { - performCombine(sourceName, sourceXMLName, outName, format, zugferdVersion, zugferdProfile, ignoreFileExt, attachmentFilenames, attachments, noAttachments); - optionsRecognized = true; - } else if ((action != null) && (action.equals("extract"))) { - performExtract(sourceName, outName); - optionsRecognized = true; - } else if ((action != null) && (action.equals("a3only"))) { - performConvert(sourceName, outName); - optionsRecognized = true; - } else if ((action != null) && (action.equals("pdf"))) { - performVisualization(sourceName, lang, outName, true); - optionsRecognized = true; - } else if ((action != null) && (action.equals("visualize"))) { - performVisualization(sourceName, lang, outName, false); - optionsRecognized = true; - } else if ((action != null) && (action.equals("upgrade"))) { - performUpgrade(sourceName, outName); - optionsRecognized = true; - } else if ((action != null) && (action.equals("ubl"))) { - performUBL(sourceName, outName); - optionsRecognized = true; - } else if ((action != null) && (action.equals("validate"))) { - optionsRecognized = performValidate(sourceName, lang, noNotices, cmd.getOptionValue("logAppend"), LogAsPDF); - } else if ((action != null) && (action.equals("validateExpectValid"))) { - optionsRecognized = performValidateExpect(true, directoryName); - } else if ((action != null) && (action.equals("validateExpectInvalid"))) { - optionsRecognized = performValidateExpect(false, directoryName); - } + if (helpRequested) { + printHelp(); + optionsRecognized = true; + } /* else if ((action!=null)&&(action.equals("license"))) { + printLicense(); + optionsRecognized=true; + } */ else if ((action != null) && (action.equals("metrics"))) { + performMetrics(directoryName, filesFromStdIn, ignoreFileExt); + optionsRecognized = true; + } else if ((action != null) && (action.equals("combine"))) { + performCombine(sourceName, sourceXMLName, outName, format, zugferdVersion, zugferdProfile, ignoreFileExt, attachmentFilenames, attachments, noAttachments); + optionsRecognized = true; + } else if ((action != null) && (action.equals("extract"))) { + performExtract(sourceName, outName); + optionsRecognized = true; + } else if ((action != null) && (action.equals("a3only"))) { + performConvert(sourceName, outName); + optionsRecognized = true; + } else if ((action != null) && (action.equals("pdf"))) { + performVisualization(sourceName, lang, outName, true); + optionsRecognized = true; + } else if ((action != null) && (action.equals("visualize"))) { + performVisualization(sourceName, lang, outName, false); + optionsRecognized = true; + } else if ((action != null) && (action.equals("upgrade"))) { + performUpgrade(sourceName, outName); + optionsRecognized = true; + } else if ((action != null) && (action.equals("ubl"))) { + performUBL(sourceName, outName); + optionsRecognized = true; + } else if ((action != null) && (action.equals("validate"))) { + optionsRecognized = performValidate(sourceName, lang, noNotices, cmd.getOptionValue("logAppend"), LogAsPDF); + } else if ((action != null) && (action.equals("validateExpectValid"))) { + optionsRecognized = performValidateExpect(true, directoryName); + } else if ((action != null) && (action.equals("validateExpectInvalid"))) { + optionsRecognized = performValidateExpect(false, directoryName); + } - } catch (UnrecognizedOptionException ex) { - optionsRecognized = false; - } + } catch (UnrecognizedOptionException ex) { + optionsRecognized = false; + } - if (!optionsRecognized) { - // no argument or argument unknown - printUsage(); - System.exit(2); - } - } catch (Exception e) { - if (LOGGER != null) { - LOGGER.error(e.getMessage(), e); - } else { - System.err.println(e.getMessage()); - } - System.exit(-1); - } + if (!optionsRecognized) { + // no argument or argument unknown + printUsage(); + System.exit(2); + } + } catch (Exception e) { + if (LOGGER != null) { + LOGGER.error(e.getMessage(), e); + } else { + System.err.println(e.getMessage()); + } + System.exit(-1); + } - } + } - private static boolean performValidate(String sourceName, String lang, boolean noNotices, String logAppend, boolean createLogAsPDF) { - boolean optionsRecognized; - if (sourceName == null) { - sourceName = getFilenameFromUser("Source PDF or XML", "invoice.pdf", "pdf|xml", true, false); - } - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - if ((logAppend != null) && (logAppend.length() > 0)) { - zfv.setLogAppend(logAppend); - } - if (noNotices) { - zfv.disableNotices(); - } + private static boolean performValidate(String sourceName, String lang, boolean noNotices, String logAppend, boolean createLogAsPDF) { + boolean optionsRecognized; + if (sourceName == null) { + sourceName = getFilenameFromUser("Source PDF or XML", "invoice.pdf", "pdf|xml", true, false); + } + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + if ((logAppend != null) && (logAppend.length() > 0)) { + zfv.setLogAppend(logAppend); + } + if (noNotices) { + zfv.disableNotices(); + } - String validationResultXML = zfv.validate(sourceName); - System.out.println(validationResultXML); + String validationResultXML = zfv.validate(sourceName); + System.out.println(validationResultXML); - if (createLogAsPDF) { - ValidationLogVisualizer vlvi = new ValidationLogVisualizer(); - String fileBasename = FilenameUtils.getBaseName(sourceName); + if (createLogAsPDF) { + ValidationLogVisualizer vlvi = new ValidationLogVisualizer(); + String fileBasename = FilenameUtils.getBaseName(sourceName); - vlvi.toPDF(validationResultXML, fileBasename + "_result.pdf", getLanguage(lang)); - } - optionsRecognized = !zfv.hasOptionsError(); - if (!zfv.wasCompletelyValid()) { - System.exit(-1); - } - return optionsRecognized; - } + vlvi.toPDF(validationResultXML, fileBasename + "_result.pdf", getLanguage(lang)); + } + optionsRecognized = !zfv.hasOptionsError(); + if (!zfv.wasCompletelyValid()) { + System.exit(-1); + } + return optionsRecognized; + } - private static boolean performValidateExpect(boolean valid, String dirName) { - ValidatorFileWalker zfWalk = new ValidatorFileWalker(valid); - Path startingDir = Paths.get(dirName); - try { - Files.walkFileTree(startingDir, zfWalk); + private static boolean performValidateExpect(boolean valid, String dirName) { + ValidatorFileWalker zfWalk = new ValidatorFileWalker(valid); + Path startingDir = Path.of(dirName); + try { + Files.walkFileTree(startingDir, zfWalk); - } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - String totalResult = "valid"; - if (!zfWalk.getResult()) { - totalResult = "invalid"; - System.exit(-1); - } + } catch (IOException e1) { + // TODO Auto-generated catch block + LOGGER.error("Exception", e1); + } + String totalResult = "valid"; + if (!zfWalk.getResult()) { + totalResult = "invalid"; + System.exit(-1); + } - System.out.println("Overall test result: " + totalResult); + System.out.println("Overall test result: " + totalResult); - return true; - } + return true; + } - private static void performConvert(String pdfName, String outName) throws IOException { - /* - * ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory() - * .setProducer("toecount") .setCreator(System.getProperty("user.name")) - * .loadFromPDFA1("invoice.pdf"); - */ - // Get params from user if not already defined - if (pdfName == null) { - pdfName = getFilenameFromUser("Source PDF", "invoice.pdf", "pdf", true, false); - } else { - System.out.println("Source PDF set to " + pdfName); - } - if (outName == null) { - outName = getFilenameFromUser("Target PDF", "invoice.a3.pdf", "pdf", false, true); - } else { - System.out.println("Target PDF set to " + outName); - } + private static void performConvert(String pdfName, String outName) throws IOException { + /* + * ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory() + * .setProducer("toecount") .setCreator(System.getProperty("user.name")) + * .loadFromPDFA1("invoice.pdf"); + */ + // Get params from user if not already defined + if (pdfName == null) { + pdfName = getFilenameFromUser("Source PDF", "invoice.pdf", "pdf", true, false); + } else { + System.out.println("Source PDF set to " + pdfName); + } + if (outName == null) { + outName = getFilenameFromUser("Target PDF", "invoice.a3.pdf", "pdf", false, true); + } else { + System.out.println("Target PDF set to " + outName); + } - // Verify params - ensureFileExists(pdfName); - ensureFileNotExists(outName); + // Verify params + ensureFileExists(pdfName); + ensureFileNotExists(outName); - // All params are good! continue... - try (ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1()) { - ze.convertOnly().load(pdfName); - ze.export(outName); - System.out.println("Written to " + outName); - } - } + // All params are good! continue... + try (ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1()) { + ze.convertOnly().load(pdfName); + ze.export(outName); + System.out.println("Written to " + outName); + } + } - private static void performExtract(String pdfName, String xmlName) throws IOException { - // Get params from user if not already defined - if (pdfName == null) { - pdfName = getFilenameFromUser("Source PDF", "invoice.pdf", "pdf", true, false); - } else { - System.out.println("Source PDF set to " + pdfName); - } - if (xmlName == null) { - xmlName = getFilenameFromUser("ZUGFeRD XML", "factur-x.xml", "xml", false, true); - } else { - System.out.println("ZUGFeRD XML set to " + pdfName); - } + private static void performExtract(String pdfName, String xmlName) throws IOException { + // Get params from user if not already defined + if (pdfName == null) { + pdfName = getFilenameFromUser("Source PDF", "invoice.pdf", "pdf", true, false); + } else { + System.out.println("Source PDF set to " + pdfName); + } + if (xmlName == null) { + xmlName = getFilenameFromUser("ZUGFeRD XML", "factur-x.xml", "xml", false, true); + } else { + System.out.println("ZUGFeRD XML set to " + pdfName); + } - // Verify params - ensureFileExists(pdfName); - ensureFileNotExists(xmlName); + // Verify params + ensureFileExists(pdfName); + ensureFileNotExists(xmlName); - // All params are good! continue... - ZUGFeRDImporter zi = new ZUGFeRDImporter(pdfName); - byte[] XMLContent = zi.getRawXML(); - if (XMLContent == null) { - System.err.println("No ZUGFeRD XML found in PDF file"); + // All params are good! continue... + ZUGFeRDImporter zi = new ZUGFeRDImporter(pdfName); + byte[] XMLContent = zi.getRawXML(); + if (XMLContent == null) { + System.err.println("No ZUGFeRD XML found in PDF file"); - } else { - Files.write(Paths.get(xmlName), XMLContent); - System.out.println("Written to " + xmlName); - } - } + } else { + Files.write(Path.of(xmlName), XMLContent); + System.out.println("Written to " + xmlName); + } + } - private static void performCombine(String pdfName, String xmlName, String outName, String format, String zfVersion, - String zfProfile, Boolean ignoreInputErrors, String[] attachmentFilenames, ArrayList attachments, Boolean noAttachments) throws Exception { - /* - * ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory() - * .setProducer("toecount") .setCreator(System.getProperty("user.name")) - * .loadFromPDFA1("invoice.pdf"); - */ - try { - int zfIntVersion = ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion; - Profile zfConformanceLevelProfile = Profiles.getByName("EXTENDED"); + private static void performCombine(String pdfName, String xmlName, String outName, String format, String zfVersion, + String zfProfile, Boolean ignoreInputErrors, String[] attachmentFilenames, ArrayList attachments, Boolean noAttachments) throws Exception { + /* + * ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory() + * .setProducer("toecount") .setCreator(System.getProperty("user.name")) + * .loadFromPDFA1("invoice.pdf"); + */ + try { + int zfIntVersion = ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion; + Profile zfConformanceLevelProfile = Profiles.getByName("EXTENDED"); - if (pdfName == null) { - pdfName = getFilenameFromUser("Source PDF", "invoice.pdf", "pdf", true, false); - } else { - System.out.println("Source PDF set to " + pdfName); - } + if (pdfName == null) { + pdfName = getFilenameFromUser("Source PDF", "invoice.pdf", "pdf", true, false); + } else { + System.out.println("Source PDF set to " + pdfName); + } - if (xmlName == null) { - xmlName = getFilenameFromUser("ZUGFeRD XML", "factur-x.xml", "xml", true, false); - } else { - System.out.println("ZUGFeRD XML set to " + xmlName); - } + if (xmlName == null) { + xmlName = getFilenameFromUser("ZUGFeRD XML", "factur-x.xml", "xml", true, false); + } else { + System.out.println("ZUGFeRD XML set to " + xmlName); + } - if (outName == null) { - outName = getFilenameFromUser("Output PDF", "invoice.ZUGFeRD.pdf", "pdf", false, true); - } else { - System.out.println("Output PDF set to " + outName); - } + if (outName == null) { + outName = getFilenameFromUser("Output PDF", "invoice.ZUGFeRD.pdf", "pdf", false, true); + } else { + System.out.println("Output PDF set to " + outName); + } - if (attachmentFilenames == null) { - byte attachmentContents[] = null; - String attachmentFilename, attachmentMime; - if (!noAttachments) { - attachmentFilename = getFilenameFromUser("Additional file attachments filename (empty for none)", "", "pdf", true, false); - if (attachmentFilename.length() != 0) { - attachmentContents = Files.readAllBytes(Paths.get(attachmentFilename)); - attachmentMime = Files.probeContentType(Paths.get(attachmentFilename)); - attachments.add(new FileAttachment(attachmentFilename, attachmentMime, "Data", attachmentContents)); - } - } - } else { - for (int i = 0; i < attachmentFilenames.length; i++) { - String attachmentFilename = attachmentFilenames[i]; - if (!attachmentFilename.isEmpty()) { - byte[] attachmentContents = Files.readAllBytes(Paths.get(attachmentFilename)); - String attachmentMime = Files.probeContentType(Paths.get(attachmentFilename)); - attachments.add(new FileAttachment(attachmentFilename, attachmentMime, "Data", attachmentContents)); - } - } - } + if (attachmentFilenames == null) { + byte attachmentContents[] = null; + String attachmentFilename, attachmentMime; + if (!noAttachments) { + attachmentFilename = getFilenameFromUser("Additional file attachments filename (empty for none)", "", "pdf", true, false); + if (attachmentFilename.length() != 0) { + attachmentContents = Files.readAllBytes(Path.of(attachmentFilename)); + attachmentMime = Files.probeContentType(Path.of(attachmentFilename)); + attachments.add(new FileAttachment(attachmentFilename, attachmentMime, "Data", attachmentContents)); + } + } + } else { + for (int i = 0; i < attachmentFilenames.length; i++) { + String attachmentFilename = attachmentFilenames[i]; + if (!attachmentFilename.isEmpty()) { + byte[] attachmentContents = Files.readAllBytes(Path.of(attachmentFilename)); + String attachmentMime = Files.probeContentType(Path.of(attachmentFilename)); + attachments.add(new FileAttachment(attachmentFilename, attachmentMime, "Data", attachmentContents)); + } + } + } - if (format == null) { - try { - format = getStringFromUser("Format (fx=Factur-X, zf=ZUGFeRD, ox=Order-X, da=Cross Industry Despatch Advice)", "fx", "fx|zf|ox|da"); - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - } - } else { - System.out.println("Format set to " + format); - } + if (format == null) { + try { + format = getStringFromUser("Format (fx=Factur-X, zf=ZUGFeRD, ox=Order-X, da=Cross Industry Despatch Advice)", "fx", "fx|zf|ox|da"); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + } else { + System.out.println("Format set to " + format); + } - if (zfVersion == null) { - try { - zfVersion = getStringFromUser("Version (1 or 2)", "1", "1|2");//fx default version is 1 - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - } - } else { - System.out.println("Version set to " + zfVersion); - } - zfIntVersion = Integer.valueOf(zfVersion); + if (zfVersion == null) { + try { + zfVersion = getStringFromUser("Version (1 or 2)", "1", "1|2");// fx default version is 1 + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + } else { + System.out.println("Version set to " + zfVersion); + } + zfIntVersion = Integer.valueOf(zfVersion); - if (zfProfile == null) { - try { - if ((format.equals("zf") && (zfIntVersion == 1)) || (format.equals("ox"))) { - zfProfile = getStringFromUser("Profile (b)asic, (c)omfort or ex(t)ended", "t", "B|b|C|c|T|t"); - } else if ((format.equals("da"))) { - zfProfile = getStringFromUser("Profile (p)ilot", "p", "P|p"); - } else { - zfProfile = getStringFromUser( - "Profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n" + "[C]IUS, [E]N16931, EX[T]ENDED or [X]RECHNUNG", "E", - "M|m|W|w|B|b|C|c|E|e|T|t|X|x|"); - } - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - } - } else { - System.out.println("Profile set to " + zfProfile); - } - zfProfile = zfProfile.toLowerCase(); + if (zfProfile == null) { + try { + if ((format.equals("zf") && (zfIntVersion == 1)) || (format.equals("ox"))) { + zfProfile = getStringFromUser("Profile (b)asic, (c)omfort or ex(t)ended", "t", "B|b|C|c|T|t"); + } else if (format.equals("da")) { + zfProfile = getStringFromUser("Profile (p)ilot", "p", "P|p"); + } else { + zfProfile = getStringFromUser( + "Profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n" + "[C]IUS, [E]N16931, EX[T]ENDED or [X]RECHNUNG", "E", + "M|m|W|w|B|b|C|c|E|e|T|t|X|x|"); + } + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + } else { + System.out.println("Profile set to " + zfProfile); + } + zfProfile = zfProfile.toLowerCase(); - // Verify params - ensureFileExists(pdfName); - ensureFileExists(xmlName); - ensureFileNotExists(outName); + // Verify params + ensureFileExists(pdfName); + ensureFileExists(xmlName); + ensureFileNotExists(outName); - if ((format.equals("fx")) && (zfIntVersion > 1)) { - throw new Exception("Factur-X is only available in version 1 (roughly corresponding to ZF2)"); - } + if ((format.equals("fx")) && (zfIntVersion > 1)) { + throw new Exception("Factur-X is only available in version 1 (roughly corresponding to ZF2)"); + } - EStandard standard = EStandard.facturx; - if (format.equals("zf")) { - standard = EStandard.zugferd; - } - if (format.equals("da")) { - standard = EStandard.despatchadvice; + EStandard standard = EStandard.facturx; + if (format.equals("zf")) { + standard = EStandard.zugferd; + } + if (format.equals("da")) { + standard = EStandard.despatchadvice; - zfConformanceLevelProfile = Profiles.getByName(standard, "PILOT", 1); - } else if (((format.equals("zf")) && (zfIntVersion == 1)) || (format.equals("ox"))) { - if (format.equals("ox")) { - standard = EStandard.orderx; - } - if (zfProfile.equals("b")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "BASIC", zfIntVersion); - } else if (zfProfile.equals("c")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "COMFORT", zfIntVersion); - } else if (zfProfile.equals("t")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "EXTENDED", zfIntVersion); - } else { - throw new Exception(String.format("Unknown ZUGFeRD profile '%s'", zfProfile)); - } - } else if (((format.equals("zf")) && (zfIntVersion == 2)) || (format.equals("fx"))) { - if (zfProfile.equals("m")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "MINIMUM", zfIntVersion); - } else if (zfProfile.equals("w")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "BASICWL", zfIntVersion); - } else if (zfProfile.equals("b")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "BASIC", zfIntVersion); - } else if (zfProfile.equals("c")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "CIUS", zfIntVersion); - } else if (zfProfile.equals("e")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "EN16931", zfIntVersion); - } else if (zfProfile.equals("t")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "EXTENDED", zfIntVersion); - } else if (zfProfile.equals("x")) { - zfConformanceLevelProfile = Profiles.getByName(standard, "XRECHNUNG", zfIntVersion); - } else { - throw new Exception(String.format("Unknown ZUGFeRD profile '%s'", zfProfile)); - } - } else { - throw new Exception(String.format("Unknown version '%d'", zfIntVersion)); - } + zfConformanceLevelProfile = Profiles.getByName(standard, "PILOT", 1); + } else if (((format.equals("zf")) && (zfIntVersion == 1)) || (format.equals("ox"))) { + if (format.equals("ox")) { + standard = EStandard.orderx; + } + if (zfProfile.equals("b")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "BASIC", zfIntVersion); + } else if (zfProfile.equals("c")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "COMFORT", zfIntVersion); + } else if (zfProfile.equals("t")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "EXTENDED", zfIntVersion); + } else { + throw new Exception(String.format("Unknown ZUGFeRD profile '%s'", zfProfile)); + } + } else if (((format.equals("zf")) && (zfIntVersion == 2)) || (format.equals("fx"))) { + if (zfProfile.equals("m")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "MINIMUM", zfIntVersion); + } else if (zfProfile.equals("w")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "BASICWL", zfIntVersion); + } else if (zfProfile.equals("b")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "BASIC", zfIntVersion); + } else if (zfProfile.equals("c")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "CIUS", zfIntVersion); + } else if (zfProfile.equals("e")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "EN16931", zfIntVersion); + } else if (zfProfile.equals("t")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "EXTENDED", zfIntVersion); + } else if (zfProfile.equals("x")) { + zfConformanceLevelProfile = Profiles.getByName(standard, "XRECHNUNG", zfIntVersion); + } else { + throw new Exception(String.format("Unknown ZUGFeRD profile '%s'", zfProfile)); + } + } else { + throw new Exception(String.format("Unknown version '%d'", zfIntVersion)); + } - IZUGFeRDExporter ze = null; - // All params are good! continue... - if (format.equals("ox")) { - ze = new OXExporterFromA1(); - if (ignoreInputErrors) { - ((OXExporterFromA1) ze).ignorePDFAErrors(); - } - } else if (format.equals("da")) { - ze = new DXExporterFromA1(); - if (ignoreInputErrors) { - ((DXExporterFromA1) ze).ignorePDFAErrors(); - } - } else { - if (format.equals("fx")) { - zfIntVersion = 2;// actually we are talking of generation, not version - // so even if someone correctly requested factur-x 1 internally we call it zugferd 2 :-( - } - ze = new ZUGFeRDExporterFromPDFA(); - if (ignoreInputErrors) { - ((ZUGFeRDExporterFromPDFA) ze).ignorePDFAErrors(); - } - } + IZUGFeRDExporter ze = null; + // All params are good! continue... + if (format.equals("ox")) { + ze = new OXExporterFromA1(); + if (ignoreInputErrors) { + ((OXExporterFromA1) ze).ignorePDFAErrors(); + } + } else if (format.equals("da")) { + ze = new DXExporterFromA1(); + if (ignoreInputErrors) { + ((DXExporterFromA1) ze).ignorePDFAErrors(); + } + } else { + if (format.equals("fx")) { + zfIntVersion = 2;// actually we are talking of generation, not version + // so even if someone correctly requested factur-x 1 internally we call it zugferd 2 :-( + } + ze = new ZUGFeRDExporterFromPDFA(); + if (ignoreInputErrors) { + ((ZUGFeRDExporterFromPDFA) ze).ignorePDFAErrors(); + } + } - ze.load(pdfName); - ze.setProducer("Mustang-cli") - .setZUGFeRDVersion(zfIntVersion) - .setCreator(System.getProperty("user.name")).setProfile(zfConformanceLevelProfile); + ze.load(pdfName); + ze.setProducer("Mustang-cli") + .setZUGFeRDVersion(zfIntVersion) + .setCreator(System.getProperty("user.name")).setProfile(zfConformanceLevelProfile); - if (format.equals("zf")) { - ze.disableFacturX(); - } + if (format.equals("zf")) { + ze.disableFacturX(); + } - for (FileAttachment attachment : attachments) { - ze.attachFile(attachment.getFilename(), attachment.getData(), attachment.getMimetype(), attachment.getRelation()); - } + for (FileAttachment attachment : attachments) { + ze.attachFile(attachment.getFilename(), attachment.getData(), attachment.getMimetype(), attachment.getRelation()); + } - ze.setXML(Files.readAllBytes(Paths.get(xmlName))); + ze.setXML(Files.readAllBytes(Path.of(xmlName))); - ze.export(outName); - System.out.println("Written to " + outName); + ze.export(outName); + System.out.println("Written to " + outName); - } catch (Exception e) { - if (LOGGER != null) { - LOGGER.error(e.getMessage(), e); - } - System.err.println(e.getMessage()); - } - } + } catch (Exception e) { + if (LOGGER != null) { + LOGGER.error(e.getMessage(), e); + } + System.err.println(e.getMessage()); + } + } - private static void performMetrics(String directoryName, Boolean filesFromStdIn, Boolean ignoreFileExt) - throws IOException { + private static void performMetrics(String directoryName, Boolean filesFromStdIn, Boolean ignoreFileExt) + throws IOException { - StatRun sr = new StatRun(); - if (ignoreFileExt) { - sr.ignoreFileExtension(); - } - if (directoryName != null) { - Path startingDir = Paths.get(directoryName); + StatRun sr = new StatRun(); + if (ignoreFileExt) { + sr.ignoreFileExtension(); + } + if (directoryName != null) { + Path startingDir = Path.of(directoryName); - if (Files.isRegularFile(startingDir)) { - String filename = startingDir.toString(); - FileChecker fc = new FileChecker(filename, sr); + if (Files.isRegularFile(startingDir)) { + String filename = startingDir.toString(); + FileChecker fc = new FileChecker(filename, sr); - fc.checkForZUGFeRD(); - System.out.print(fc.getOutputLine()); + fc.checkForZUGFeRD(); + System.out.print(fc.getOutputLine()); - } else if (Files.isDirectory(startingDir)) { - FileTraverser pf = new FileTraverser(sr); - Files.walkFileTree(startingDir, pf); - } - } + } else if (Files.isDirectory(startingDir)) { + FileTraverser pf = new FileTraverser(sr); + Files.walkFileTree(startingDir, pf); + } + } - if (filesFromStdIn) { - BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); - String s; - while ((s = in.readLine()) != null && s.length() != 0) { - FileChecker fc = new FileChecker(s, sr); + if (filesFromStdIn) { + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + String s; + while ((s = in.readLine()) != null && s.length() != 0) { + FileChecker fc = new FileChecker(s, sr); - fc.checkForZUGFeRD(); - System.out.print(fc.getOutputLine()); + fc.checkForZUGFeRD(); + System.out.print(fc.getOutputLine()); - } + } - } - System.out.println(sr.getSummaryLine()); - } + } + System.out.println(sr.getSummaryLine()); + } - private static void performVisualization(String sourceName, String lang, String outName, boolean intoPDF) { - // Get params from user if not already defined - if (sourceName == null) { - sourceName = getFilenameFromUser("ZUGFeRD XML source", "factur-x.xml", "xml", true, false); - } else { - System.out.println("ZUGFeRD XML source set to " + sourceName); - } - if (!intoPDF) { - if (lang == null) { - try { - lang = getStringFromUser("Output language", "en", "en|de|fr"); - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - lang = "en"; - } - } - } else { - if (lang == null) { - lang = "en"; - } - } - System.out.println("Output language set to " + lang); + private static void performVisualization(String sourceName, String lang, String outName, boolean intoPDF) { + // Get params from user if not already defined + if (sourceName == null) { + sourceName = getFilenameFromUser("ZUGFeRD XML source", "factur-x.xml", "xml", true, false); + } else { + System.out.println("ZUGFeRD XML source set to " + sourceName); + } + if (!intoPDF) { + if (lang == null) { + try { + lang = getStringFromUser("Output language", "en", "en|de|fr"); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + lang = "en"; + } + } + } else { + if (lang == null) { + lang = "en"; + } + } + System.out.println("Output language set to " + lang); - if (outName == null) { - String defaultFilename = "factur-x.html"; - String defaultExtension = "html"; - if (intoPDF) { - defaultFilename = "factur-x.pdf"; - defaultExtension = "pdf"; - } - outName = getFilenameFromUser("Target file", defaultFilename, defaultExtension, false, true); - } else { - System.out.println("Target set to " + outName); - } + if (outName == null) { + String defaultFilename = "factur-x.html"; + String defaultExtension = "html"; + if (intoPDF) { + defaultFilename = "factur-x.pdf"; + defaultExtension = "pdf"; + } + outName = getFilenameFromUser("Target file", defaultFilename, defaultExtension, false, true); + } else { + System.out.println("Target set to " + outName); + } - // Verify params - try { - ensureFileExists(sourceName); - ensureFileNotExists(outName); - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); - } + // Verify params + try { + ensureFileExists(sourceName); + ensureFileNotExists(outName); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); + } - ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); - String xml = null; - try { - ELanguage langCode = getLanguage(lang); - if (!intoPDF) { - xml = zvi.visualize(sourceName, langCode); - Files.write(Paths.get(outName), xml.getBytes()); - } else { - zvi.toPDF(sourceName, outName, langCode); - } - System.out.println("Written to " + outName); - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - System.err.println(e.getMessage()); - } + ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); + String xml = null; + try { + ELanguage langCode = getLanguage(lang); + if (!intoPDF) { + xml = zvi.visualize(sourceName, langCode); + Files.write(Path.of(outName), xml.getBytes()); + } else { + zvi.toPDF(sourceName, outName, langCode); + } + System.out.println("Written to " + outName); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + System.err.println(e.getMessage()); + } - // The following is not needed anymore: - /* - if (!intoPDF) { - try { - ExportResource("xrechnung-viewer.css"); - ExportResource("xrechnung-viewer.js"); - ExportResource("FileSaver-v2.0.5.js"); - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - } - } - */ - } + // The following is not needed anymore: + /* + if (!intoPDF) { + try { + ExportResource("xrechnung-viewer.css"); + ExportResource("xrechnung-viewer.js"); + ExportResource("FileSaver-v2.0.5.js"); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + } + */ + } - private static ELanguage getLanguage(final String s) { - ELanguage rv = ELanguage.EN; - if (s != null && !s.isEmpty()) { - if (s.equalsIgnoreCase("de")) { - rv = ELanguage.DE; - } - if (s.equalsIgnoreCase("fr")) { - rv = ELanguage.FR; - } - } - return rv; - } + private static ELanguage getLanguage(final String s) { + ELanguage rv = ELanguage.EN; + if (s != null && !s.isEmpty()) { + if (s.equalsIgnoreCase("de")) { + rv = ELanguage.DE; + } + if (s.equalsIgnoreCase("fr")) { + rv = ELanguage.FR; + } + } + return rv; + } - /** - * Export a resource embedded into a Jar file to the local file path. - * - * @param resourceName ie.: "/SmartLibrary.dll" - * @throws Exception e.g. if the specified resource does not exist at the specified location - */ - @SuppressWarnings("unused") - public static void ExportResource(final String resourceName) throws Exception { - String resourcePath = ClasspathResourceURIResolver.MAIN_BASE_PATH + resourceName; - try (InputStream is = Main.class.getClassLoader().getResourceAsStream(resourcePath)) { - // note that each / is a directory down in the "jar tree" been the jar the root of the tree - if (is != null) { - int readBytes; - byte[] buffer = new byte[4096]; - String jarFolder = System.getProperty("user.dir"); - try (FileOutputStream fos = new FileOutputStream(jarFolder + resourceName)) { - while ((readBytes = is.read(buffer)) > 0) { - fos.write(buffer, 0, readBytes); - } - } - } else { - throw new Exception(String.format("Cannot get resource '%s' from JAR file.", resourceName)); - } - } - System.out.printf("'%s' written (to local working directory).%n", resourceName); - } + /** + * Export a resource embedded into a Jar file to the local file path. + * + * @param resourceName ie.: "/SmartLibrary.dll" + * @throws Exception e.g. if the specified resource does not exist at the specified location + */ + @SuppressWarnings("unused") + public static void ExportResource(final String resourceName) throws Exception { + String resourcePath = ClasspathResourceURIResolver.MAIN_BASE_PATH + resourceName; + try (InputStream is = Main.class.getClassLoader().getResourceAsStream(resourcePath)) { + // note that each / is a directory down in the "jar tree" been the jar the root of the tree + if (is != null) { + int readBytes; + byte[] buffer = new byte[4096]; + String jarFolder = System.getProperty("user.dir"); + try (FileOutputStream fos = new FileOutputStream(jarFolder + resourceName)) { + while ((readBytes = is.read(buffer)) > 0) { + fos.write(buffer, 0, readBytes); + } + } + } else { + throw new Exception(String.format("Cannot get resource '%s' from JAR file.", resourceName)); + } + } + System.out.printf("'%s' written (to local working directory).%n", resourceName); + } - private static void ensureFileExists(String fileName) throws IOException { - if (!fileExists(fileName)) { - throw new IOException(String.format("File %s does not exist.", fileName)); - } - } + private static void ensureFileExists(String fileName) throws IOException { + if (!fileExists(fileName)) { + throw new IOException(String.format("File %s does not exist.", fileName)); + } + } - private static void ensureFileNotExists(String fileName) throws IOException { - if (fileExists(fileName)) { - throw new IOException(String.format("File %s already exists", fileName)); - } - } + private static void ensureFileNotExists(String fileName) throws IOException { + if (fileExists(fileName)) { + throw new IOException(String.format("File %s already exists", fileName)); + } + } - private static Boolean fileExists(String fileName) { - if (fileName == null) - return false; - File f = new File(fileName); - // "exists" also returns true for directories - return f.isFile(); - } + private static Boolean fileExists(String fileName) { + if (fileName == null) + return false; + File f = new File(fileName); + // "exists" also returns true for directories + return f.isFile(); + } } diff --git a/Mustang-CLI/src/main/java/org/mustangproject/commandline/StatRun.java b/Mustang-CLI/src/main/java/org/mustangproject/commandline/StatRun.java index 36df0f3..e465bc3 100755 --- a/Mustang-CLI/src/main/java/org/mustangproject/commandline/StatRun.java +++ b/Mustang-CLI/src/main/java/org/mustangproject/commandline/StatRun.java @@ -21,79 +21,79 @@ org.openrewrite.config.CompositeRecipe import java.math.BigDecimal; public class StatRun { - private int pdfCount = 0; - private int horseCount = 0; - private int fileCount = 0; - private int dirCount = 0; - private BigDecimal total = BigDecimal.ZERO; - private boolean checkFileExt = true; + private int pdfCount = 0; + private int horseCount = 0; + private int fileCount = 0; + private int dirCount = 0; + private BigDecimal total = BigDecimal.ZERO; + private boolean checkFileExt = true; - public void ignoreFileExtension() { - checkFileExt = false; - } + public void ignoreFileExtension() { + checkFileExt = false; + } - public boolean shallIgnoreFileExt() { - return !checkFileExt; - } + public boolean shallIgnoreFileExt() { + return !checkFileExt; + } - public void incFileCount() { - fileCount++; - } + public void incFileCount() { + fileCount++; + } - public void incPDFCount() { - pdfCount++; - } + public void incPDFCount() { + pdfCount++; + } - public void incZUGFeRDCount(int version) { - horseCount++; - } + public void incZUGFeRDCount(int version) { + horseCount++; + } - public void incDirCount() { - dirCount++; - } + public void incDirCount() { + dirCount++; + } - public int getFileCount() { - return fileCount; - } + public int getFileCount() { + return fileCount; + } - public int getPDFCount() { - return pdfCount; - } + public int getPDFCount() { + return pdfCount; + } - public int getZUGFeRDCount() { - return horseCount; - } + public int getZUGFeRDCount() { + return horseCount; + } - public int getDirCount() { - return dirCount; - } + public int getDirCount() { + return dirCount; + } - /** - * returns final statistics - * - * @return english string with linefeeds detailling number of files, directories, number of pdfs and of zugferd files - */ - public String getSummaryLine() { + /** + * returns final statistics + * + * @return english string with linefeeds detailling number of files, directories, number of pdfs and of zugferd files + */ + public String getSummaryLine() { - return "\r\n===================================================================\r\n" + String.format( - "Files:\t%d\tDirs:\t%d\tPDF:\t%d\tZUGFeRD:\t%d\tTotal:\t%s\r\n", - getFileCount(), getDirCount(), getPDFCount(), getZUGFeRDCount(), total.toString()); + return "\r\n===================================================================\r\n" + String.format( + "Files:\t%d\tDirs:\t%d\tPDF:\t%d\tZUGFeRD:\t%d\tTotal:\t%s\r\n", + getFileCount(), getDirCount(), getPDFCount(), getZUGFeRDCount(), total.toString()); - } + } - /** - * show that something is happening - * - * @return String, usually a dot - */ - public String getOutputLine() { - return "."; - } + /** + * show that something is happening + * + * @return String, usually a dot + */ + public String getOutputLine() { + return "."; + } - public void incTotal(BigDecimal delta) { - total=total.add(delta); - - } + public void incTotal(BigDecimal delta) { + total = total.add(delta); + + } } diff --git a/Mustang-CLI/src/main/java/org/mustangproject/commandline/ValidatorFileWalker.java b/Mustang-CLI/src/main/java/org/mustangproject/commandline/ValidatorFileWalker.java index 5b5d834..fe55d83 100755 --- a/Mustang-CLI/src/main/java/org/mustangproject/commandline/ValidatorFileWalker.java +++ b/Mustang-CLI/src/main/java/org/mustangproject/commandline/ValidatorFileWalker.java @@ -2,6 +2,10 @@ org.openrewrite.config.CompositeRecipe +import org.mustangproject.validator.ZUGFeRDValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; @@ -12,58 +16,57 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.mustangproject.validator.ZUGFeRDValidator; import static org.xmlunit.assertj.XmlAssert.assertThat; public class ValidatorFileWalker - extends SimpleFileVisitor { - private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorFileWalker.class.getCanonicalName()); // log - protected PathMatcher matcher; - protected ZUGFeRDValidator zul; - protected int fileCount=1; - protected boolean expectValid=true; - protected boolean allValid=true; + extends SimpleFileVisitor { + private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorFileWalker.class.getCanonicalName()); // log + protected PathMatcher matcher; + protected ZUGFeRDValidator zul; + protected int fileCount = 1; + protected boolean expectValid = true; + protected boolean allValid = true; - public ValidatorFileWalker(boolean expectValid) { - this.zul = new ZUGFeRDValidator(); - this.expectValid=expectValid; - matcher = FileSystems.getDefault().getPathMatcher("glob:*.{pdf,xml}"); + public ValidatorFileWalker(boolean expectValid) { + this.zul = new ZUGFeRDValidator(); + this.expectValid = expectValid; + matcher = FileSystems.getDefault().getPathMatcher("glob:*.{pdf,xml}"); - } + } - public boolean getResult() { - return allValid; - } + public boolean getResult() { + return allValid; + } + // Print information about // each type of file. @Override public FileVisitResult visitFile(Path file, - BasicFileAttributes attr) { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - //get current date time with Date() + BasicFileAttributes attr) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + // get current date time with Date() Date date = new Date(); - String expectedString="valid"; + String expectedString = "valid"; if (!expectValid) { - expectedString="invalid"; + expectedString = "invalid"; } - if ((attr!=null)&&(attr.isRegularFile())) { - if (matcher.matches(file.getFileName())) { - String thisResultString=" valid"; - try { - assertThat(zul.validate(file.toAbsolutePath().toString())).valueByXPath("/validation/summary/@status") - .asString() - .isEqualTo(expectedString); - - } catch (AssertionError ae) { - thisResultString="invalid"; - allValid=false; - } - LOGGER.info(String.format("\n@%s Testing file %d: %s (%s)", dateFormat.format(date), fileCount++, thisResultString, file)); - - } + if ((attr != null) && (attr.isRegularFile())) { + if (matcher.matches(file.getFileName())) { + String thisResultString = " valid"; + try { + assertThat(zul.validate(file.toAbsolutePath().toString())).valueByXPath("/validation/summary/@status") + .asString() + .isEqualTo(expectedString); + + } catch (AssertionError ae) { + thisResultString = "invalid"; + allValid = false; + } + LOGGER.info(" +@{} Testing file {}: {} ({})", dateFormat.format(date), fileCount++, thisResultString, file); + + } } return FileVisitResult.CONTINUE; } @@ -71,7 +74,7 @@ // Print each directory visited. @Override public FileVisitResult postVisitDirectory(Path dir, - IOException exc) { + IOException exc) { LOGGER.info("\nDirectory: %s%n", dir); return FileVisitResult.CONTINUE; } @@ -83,8 +86,8 @@ // is thrown. @Override public FileVisitResult visitFileFailed(Path file, - IOException exc) { - LOGGER.error(exc.getMessage(),exc); + IOException exc) { + LOGGER.error(exc.getMessage(), exc); return FileVisitResult.CONTINUE; } } diff --git a/Mustang-CLI/src/test/java/org/mustangproject/commandline/CliIT.java b/Mustang-CLI/src/test/java/org/mustangproject/commandline/CliIT.java index a6cf0bd..e003d6c 100755 --- a/Mustang-CLI/src/test/java/org/mustangproject/commandline/CliIT.java +++ b/Mustang-CLI/src/test/java/org/mustangproject/commandline/CliIT.java @@ -1,82 +1,81 @@ org.openrewrite.config.CompositeRecipe package org.mustangproject.commandline; +import org.junit.jupiter.api.Test; + import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; - public class CliIT { - public static File getResourceAsFile(String resourcePath) { - try { - InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath); - if (in == null) { - return null; - } + public static File getResourceAsFile(String resourcePath) { + try { + InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath); + if (in == null) { + return null; + } - File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp"); - tempFile.deleteOnExit(); + File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp"); + tempFile.deleteOnExit(); - try (FileOutputStream out = new FileOutputStream(tempFile)) { - // copy stream - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = in.read(buffer)) != -1) { - out.write(buffer, 0, bytesRead); - } - } - return tempFile; - } catch (IOException e) { - return null; - } - } + try (FileOutputStream out = new FileOutputStream(tempFile)) { + // copy stream + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + } + return tempFile; + } catch (IOException e) { + return null; + } + } - @Test - public void testCii2Ubl() throws Exception { - Path output = Paths.get("target/ubl.xml"); - Files.deleteIfExists(output); - Path jar = Files.newDirectoryStream(Paths.get("target"), "Mustang-CLI-*.jar").iterator().next(); - ProcessBuilder pb = new ProcessBuilder("java", "-jar", jar.toString(), - "--action", "ubl", "--source", "src/test/resources/cii.xml", "--out", - output.toString()); - pb.redirectErrorStream(true); - Process process = pb.start(); - String result = getOutput(process); - process.waitFor(10, TimeUnit.SECONDS); - if (!result.isEmpty()) { - System.out.println(result); - } - assertTrue(new String(Files.readAllBytes(output), StandardCharsets.UTF_8).contains("Invoice")); - } + @Test + public void testCii2Ubl() throws Exception { + Path output = Path.of("target/ubl.xml"); + Files.deleteIfExists(output); + Path jar = Files.newDirectoryStream(Path.of("target"), "Mustang-CLI-*.jar").iterator().next(); + ProcessBuilder pb = new ProcessBuilder("java", "-jar", jar.toString(), + "--action", "ubl", "--source", "src/test/resources/cii.xml", "--out", + output.toString()); + pb.redirectErrorStream(true); + Process process = pb.start(); + String result = getOutput(process); + process.waitFor(10, TimeUnit.SECONDS); + if (!result.isEmpty()) { + System.out.println(result); + } + assertTrue(new String(Files.readAllBytes(output), StandardCharsets.UTF_8).contains("Invoice")); + } - private String getOutput(Process process) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - StringBuilder builder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - builder.append(line); - builder.append(System.getProperty("line.separator")); - } - return builder.toString(); - } + private String getOutput(Process process) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line); + builder.append(System.getProperty("line.separator")); + } + return builder.toString(); + } - @Test - public void testMetric() { - StatRun sr = new StatRun(); - File tempFile = getResourceAsFile("corrupt-factur-x-waytoosmall.pdf"); + @Test + public void testMetric() { + StatRun sr = new StatRun(); + File tempFile = getResourceAsFile("corrupt-factur-x-waytoosmall.pdf"); - FileChecker fc = new FileChecker(tempFile.getAbsolutePath(), sr); + FileChecker fc = new FileChecker(tempFile.getAbsolutePath(), sr); - fc.checkForZUGFeRD(); - System.out.print(fc.getOutputLine()); + fc.checkForZUGFeRD(); + System.out.print(fc.getOutputLine()); - } + } }