From c16a32f644aa3345c5a1ab657e08dd140e11a734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20Sta=CC=88rk?= Date: Tue, 3 Oct 2017 18:46:27 +0200 Subject: [PATCH] ZF1 and ZF2 as XMLProvider --- ZUGFeRD-invoice.xml | 0 .../ZUGFeRD/CustomXMLProvider.java | 28 ++ .../mustangproject/ZUGFeRD/IXMLProvider.java | 10 + .../ZUGFeRD/ZUGFeRD1PullProvider.java | 87 ++++ .../ZUGFeRD/ZUGFeRD2PullProvider.java | 435 ++++++++++++++++++ .../ZUGFeRD/ZUGFeRDExporter.java | 80 +--- 6 files changed, 573 insertions(+), 67 deletions(-) create mode 100644 ZUGFeRD-invoice.xml create mode 100644 src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java create mode 100644 src/main/java/org/mustangproject/ZUGFeRD/IXMLProvider.java create mode 100644 src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java create mode 100644 src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java diff --git a/ZUGFeRD-invoice.xml b/ZUGFeRD-invoice.xml new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java b/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java new file mode 100644 index 00000000..fe083bf4 --- /dev/null +++ b/src/main/java/org/mustangproject/ZUGFeRD/CustomXMLProvider.java @@ -0,0 +1,28 @@ +package org.mustangproject.ZUGFeRD; + +public class CustomXMLProvider implements IXMLProvider { + + protected byte[] zugferdData; + + @Override + public byte[] getXML() { + return zugferdData; + } + + public void setXML(byte[] newData) { + zugferdData=newData; + } + + @Override + public void generateXML(IZUGFeRDExportableTransaction trans) { + // TODO Auto-generated method stub + + } + + @Override + public void setTest() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/org/mustangproject/ZUGFeRD/IXMLProvider.java b/src/main/java/org/mustangproject/ZUGFeRD/IXMLProvider.java new file mode 100644 index 00000000..459e3ca1 --- /dev/null +++ b/src/main/java/org/mustangproject/ZUGFeRD/IXMLProvider.java @@ -0,0 +1,10 @@ +package org.mustangproject.ZUGFeRD; + +public interface IXMLProvider { + + public byte[] getXML(); + public void setTest(); + + public void generateXML(IZUGFeRDExportableTransaction trans); + +} diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java new file mode 100644 index 00000000..8ceb611b --- /dev/null +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java @@ -0,0 +1,87 @@ +package org.mustangproject.ZUGFeRD; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; + +public class ZUGFeRD1PullProvider implements IXMLProvider { + + + protected byte[] zugferdData; + private Marshaller marshaller; + + private boolean isTest; + + + + /** + * enables the flag to indicate a test invoice in the XML structure + * + */ + public void setTest() { + isTest = true; + } + public ZUGFeRD1PullProvider() { + // TODO Auto-generated constructor stub + try { + marshaller = JAXBContext.newInstance("org.mustangproject.ZUGFeRD.model").createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); + } catch (JAXBException e) { + throw new ZUGFeRDExportException("Could not initialize JAXB", e); + } + + } + + private String createZugferdXMLForTransaction(IZUGFeRDExportableTransaction trans) { + + JAXBElement jaxElement = + new ZUGFeRDTransactionModelConverter(trans).withTest(isTest).convertToModel(); + + try { + return marshalJaxToXMLString(jaxElement); + } catch (JAXBException e) { + throw new ZUGFeRDExportException("Could not marshal ZUGFeRD transaction to XML", e); + } + } + + private String marshalJaxToXMLString(Object jaxElement) throws JAXBException { + ByteArrayOutputStream outputXml = new ByteArrayOutputStream(); + marshaller.marshal(jaxElement, outputXml); + return outputXml.toString(); + } + + + @Override + public byte[] getXML() { + // TODO Auto-generated method stub + return null; + } + + + @Override + public void generateXML(IZUGFeRDExportableTransaction trans) { + // create a dummy file stream, this would probably normally be a + // FileInputStream + + byte[] zugferdRaw = createZugferdXMLForTransaction(trans).getBytes(); //$NON-NLS-1$ + + 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; + } + } + + + +} diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java new file mode 100644 index 00000000..a7c64c92 --- /dev/null +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -0,0 +1,435 @@ +package org.mustangproject.ZUGFeRD; + +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.HashMap; + +public class ZUGFeRD2PullProvider implements IXMLProvider { + + private class LineCalc { + private IZUGFeRDExportableItem currentItem=null; + private BigDecimal totalGross; + private BigDecimal itemTotalNetAmount; + private BigDecimal itemTotalVATAmount; + + public LineCalc(IZUGFeRDExportableItem currentItem) { + this.currentItem=currentItem; + BigDecimal multiplicator=currentItem.getProduct().getVATPercent().divide(new BigDecimal(100)).add(new BigDecimal(1)); +// priceGross=currentItem.getPrice().multiply(multiplicator); + totalGross=currentItem.getPrice().multiply(multiplicator).multiply(currentItem.getQuantity()); + itemTotalNetAmount=currentItem.getQuantity().multiply(currentItem.getPrice()).setScale(2,BigDecimal.ROUND_HALF_UP); + itemTotalVATAmount=totalGross.subtract(itemTotalNetAmount); + } + + public BigDecimal getItemTotalNetAmount() { + return itemTotalNetAmount; + } + + public BigDecimal getItemTotalVATAmount() { + return itemTotalVATAmount; + } + + } + + + + //// MAIN CLASS + + protected byte[] zugferdData; + private IZUGFeRDExportableTransaction trans; + private boolean isTest; + + /** + * enables the flag to indicate a test invoice in the XML structure + * + */ + public void setTest() { + isTest = true; + } + + private 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 + * + * This function will cut off, i.e. floor() subcent values Tests: + * System.err.println(utils.currencyFormat(new BigDecimal(0), + * ".")+"\n"+utils.currencyFormat(new BigDecimal("-1.10"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.1"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.01"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3489"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3419"), + * ",")+"\n"+utils.currencyFormat(new BigDecimal("12"), ",")); + * + * results 0.00 -1,10 -1,10 -1,01 20000123,34 20000123,34 12,00 + */ + value=value.setScale( scale, BigDecimal.ROUND_HALF_UP ); // first, round so that e.g. 1.189999999999999946709294817992486059665679931640625 becomes 1.19 + char[] repeat = new char[scale]; + Arrays.fill(repeat, '0'); + + DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(); + otherSymbols.setDecimalSeparator('.'); + DecimalFormat dec = new DecimalFormat("0."+new String(repeat), otherSymbols); + return dec.format(value); + + } + + private String vatFormat(BigDecimal value) { + return nDigitFormat(value, 2); + } + + private String currencyFormat(BigDecimal value) { + return nDigitFormat(value, 2); + } + + private String priceFormat(BigDecimal value) { + return nDigitFormat(value, 4); + } + private String quantityFormat(BigDecimal value) { + return nDigitFormat(value, 4); + } + + @Override + public byte[] getXML() { + // TODO Auto-generated method stub + return null; + } + + + + + + private BigDecimal getTotalGross() { + + BigDecimal res=getTotal(); + HashMap VATPercentAmountMap=getVATPercentAmountMap(); + for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); + res=res.add(amount.getCalculated()); + } + + + return res; + } + + private BigDecimal getTotal() { + BigDecimal res=new BigDecimal(0); + for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { + LineCalc lc=new LineCalc(currentItem); + res=res.add(lc.getItemTotalNetAmount()); + } + return res; + } + + /** + * which taxes have been used with which amounts in this transaction, + * empty for no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable + * to 19% VAT (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT) + * 190 Eur + * @return + * + */ + private HashMap getVATPercentAmountMap() { + HashMap hm=new HashMap (); + + for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { + BigDecimal percent=currentItem.getProduct().getVATPercent(); + LineCalc lc=new LineCalc(currentItem); + VATAmount itemVATAmount=new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount() ) ; + VATAmount current=hm.get(percent); + if (current==null) { + hm.put(percent, itemVATAmount); + } else { + hm.put(percent, current.add(itemVATAmount)); + + } + } + + return hm; + } + + + @Override + public void generateXML(IZUGFeRDExportableTransaction trans) { + + this.trans=trans; + SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); //$NON-NLS-1$ + SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd"); //$NON-NLS-1$ + String testBooleanStr="false"; + if (isTest) { + testBooleanStr="true"; + + } + String senderReg=""; + if (trans.getOwnOrganisationFullPlaintextInfo()!=null) { + senderReg="" + + "\n" + + " \n" + + trans.getOwnOrganisationFullPlaintextInfo() + + " \n" + + "REG\n" + + "\n"; + + } + String xml= "\n" //$NON-NLS-1$ + + + "\n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " urn:ferd:CrossIndustryDocument:invoice:1p0:comfort\n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getNumber()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " RECHNUNG\n" //$NON-NLS-1$ + + " 380\n" //$NON-NLS-1$ + + " "+zugferdDateFormat.format(trans.getIssueDate())+"\n" //date format was 20130605 //$NON-NLS-1$ //$NON-NLS-2$ + + senderReg +// + " \n" +// + " \n" +// + "Rechnung gemäß Bestellung Nr. 2013-471331 vom 01.03.2013.\n" +// + "\n" +// + " \n" +// + " \n" +// + " \n" +// + " \n" +// + "Es bestehen Rabatt- und Bonusvereinbarungen.\n" +// + " \n" +// + " AAK\n" +// + " \n" + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ +// + " AB-312\n" + + " \n" //$NON-NLS-1$ +// + " 4000001123452\n" + + " "+trans.getOwnOrganisationName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" + + " "+trans.getOwnZIP()+"\n" + + " "+trans.getOwnStreet()+"\n" + + " "+trans.getOwnLocation()+"\n" + + " "+trans.getOwnCountry()+"\n" + + " \n" + + " \n" //$NON-NLS-1$ + + " "+trans.getOwnTaxID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getOwnVATID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ +// + " GE2020211\n" +// + " 4000001987658\n" + + " "+trans.getRecipient().getName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ +// + " \n" +// + " xxx\n" +// + " \n" + + " \n" //$NON-NLS-1$ + + " "+trans.getRecipient().getZIP()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+trans.getRecipient().getStreet()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+trans.getRecipient().getLocation()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+trans.getRecipient().getCountry()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getRecipient().getVATID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ +// + " \n" +// + " 20130301\n" +// + " 2013-471331\n" +// + " \n" + + " \n" //$NON-NLS-1$ + + " \n" + + " \n" + + " "+zugferdDateFormat.format(trans.getDeliveryDate())+"\n" + + " \n" + /* + + " \n" + + " 20130603\n" + + " 2013-51112\n" + + " \n" */ + + " \n" + + " \n" //$NON-NLS-1$ + + " "+trans.getNumber()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " EUR\n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " 42\n" //$NON-NLS-1$ + + " Überweisung\n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getOwnIBAN()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+trans.getOwnBIC()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+trans.getOwnBankName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n"; //$NON-NLS-1$ + + + + HashMap VATPercentAmountMap=getVATPercentAmountMap(); + for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { + VATAmount amount = VATPercentAmountMap.get(currentTaxPercent); + if (amount != null) { + xml += " \n" //$NON-NLS-1$ + + " "+currencyFormat(amount.getCalculated())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " VAT\n" //$NON-NLS-1$ + + " "+currencyFormat(amount.getBasis())+"\n" + + " S\n" //$NON-NLS-1$ + + " "+vatFormat(currentTaxPercent)+"\n" //$NON-NLS-1$ + + " \n"; //$NON-NLS-1$ + + + + } + } +/* xml+= " + + " \n" + + " false\n" + + " 10\n" + + " 1.00\n" + + " Sondernachlass\n" + + " \n" + + " VAT\n" + + " S\n" + + " 19\n" + + " \n" + + " \n" + + " \n" + + " false\n" + + " 137.30\n" + + " 13.73\n" + + " Sondernachlass\n" + + " \n" + + " VAT\n" + + " S\n" + + " 7\n" + + " \n" + + " \n" + + " \n" + + " Versandkosten\n" + + " 5.80\n" + + " \n" + + " VAT\n" + + " S\n" + + " 7\n" + + " \n" + + " \n"*/ + + xml=xml+ " \n" //$NON-NLS-1$ + + " Zahlbar ohne Abzug bis "+germanDateFormat.format(trans.getDueDate())+"\n" + + " "+zugferdDateFormat.format(trans.getDueDate())+"\n"//20130704 //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+currencyFormat(getTotal())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " 0.00\n" //$NON-NLS-1$ + + " 0.00\n" //$NON-NLS-1$ +// + " 5.80\n" +// + " 14.73\n" + + " "+currencyFormat(getTotal())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+currencyFormat(getTotalGross().subtract(getTotal()))+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+currencyFormat(getTotalGross())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ +// + " 0.00\n" + + " "+currencyFormat(getTotalGross())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n"; //$NON-NLS-1$ +// + " \n" +// + " \n" +// + " \n" +// + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. 2013-51112 in Rechnung zu stellen:\n" +// + " \n" +// + " \n" +// + " \n"; + + + int lineID=0; + for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { + lineID++; + + LineCalc lc=new LineCalc(currentItem); + xml=xml+ " \n"+ //$NON-NLS-1$ + " \n" //$NON-NLS-1$ + + " "+lineID+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+priceFormat(currentItem.getPrice())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " 1.0000\n" //$NON-NLS-1$ //$NON-NLS-2$ +// + " \n" +// + " false\n" +// + " 0.6667\n" +// + " Rabatt\n" +// + " \n" + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+priceFormat(currentItem.getPrice())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " 1.0000\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + + " \n" //$NON-NLS-1$ + + " "+quantityFormat(currentItem.getQuantity())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " VAT\n" //$NON-NLS-1$ + + " S\n" //$NON-NLS-1$ + + " "+vatFormat(currentItem.getProduct().getVATPercent())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " "+currencyFormat(lc.getItemTotalNetAmount())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ + + " \n" //$NON-NLS-1$ +// + " 4012345001235\n" +// + " KR3M\n" +// + " 55T01\n" + + " "+currentItem.getProduct().getName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " "+currentItem.getProduct().getDescription()+"\n" //$NON-NLS-1$ //$NON-NLS-2$ + + " \n" //$NON-NLS-1$ + + " \n"; //$NON-NLS-1$ + + + + } + + + xml=xml + " \n" //$NON-NLS-1$ + + ""; //$NON-NLS-1$ + byte[] zugferdRaw; + try { + zugferdRaw = xml.getBytes("UTF-8"); + + 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; + } + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } //$NON-NLS-1$ + } + +} diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java index 161eec09..56925015 100644 --- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java +++ b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporter.java @@ -20,15 +20,9 @@ import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; -import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; import javax.xml.transform.TransformerException; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; import java.io.IOException; @@ -40,17 +34,6 @@ import java.util.Map; public class ZUGFeRDExporter implements Closeable { - - private void init() { - try { - marshaller = JAXBContext.newInstance("org.mustangproject.ZUGFeRD.model").createMarshaller(); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); - marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); - } catch (JAXBException e) { - throw new ZUGFeRDExportException("Could not initialize JAXB", e); - } - - } /** * * You will need Apache PDFBox. To use the ZUGFeRD exporter, implement * IZUGFeRDExportableTransaction in yourTransaction (which will require you @@ -68,13 +51,13 @@ public class ZUGFeRDExporter implements Closeable { * the {@link ZUGFeRDExporterFromA1Factory} instead * */ - @Deprecated - public ZUGFeRDExporter() { - init(); - } + public ZUGFeRDExporter() { + ZUGFeRD1PullProvider z1p =new ZUGFeRD1PullProvider(); + this.xmlProvider=z1p; + + } public ZUGFeRDExporter(PDDocument doc2) { - init(); doc=doc2; } @@ -92,8 +75,7 @@ public class ZUGFeRDExporter implements Closeable { * necessary. By default it is null meaning the caller needs to pass a * IZUGFeRDExportableTransaction for the XML to be populated. */ - byte[] zugferdData = null; - private boolean isTest; + IXMLProvider xmlProvider; @Deprecated private boolean ignoreA1Errors; private PDDocument doc; @@ -144,7 +126,7 @@ public class ZUGFeRDExporter implements Closeable { * */ public void setTest() { - isTest = true; + xmlProvider.setTest(); } /** @@ -235,26 +217,6 @@ public class ZUGFeRDExporter implements Closeable { } } - private Marshaller marshaller; - - private String createZugferdXMLForTransaction(IZUGFeRDExportableTransaction trans) { - - JAXBElement jaxElement = - new ZUGFeRDTransactionModelConverter(trans).withTest(isTest).convertToModel(); - - try { - return marshalJaxToXMLString(jaxElement); - } catch (JAXBException e) { - throw new ZUGFeRDExportException("Could not marshal ZUGFeRD transaction to XML", e); - } - } - - private String marshalJaxToXMLString(Object jaxElement) throws JAXBException { - ByteArrayOutputStream outputXml = new ByteArrayOutputStream(); - marshaller.marshal(jaxElement, outputXml); - return outputXml.toString(); - } - /** * Embeds the Zugferd XML structure in a file named ZUGFeRD-invoice.xml. @@ -268,32 +230,14 @@ public class ZUGFeRDExporter implements Closeable { public void PDFattachZugferdFile(IZUGFeRDExportableTransaction trans) throws IOException { - if (zugferdData == null) // XML ZUGFeRD data not set externally, needs - // to be built - { - // create a dummy file stream, this would probably normally be a - // FileInputStream - - byte[] zugferdRaw = createZugferdXMLForTransaction(trans).getBytes(); //$NON-NLS-1$ - - 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; - } - } - + xmlProvider.generateXML(trans); + PDFAttachGenericFile( doc, "ZUGFeRD-invoice.xml", "Alternative", "Invoice metadata conforming to ZUGFeRD standard (http://www.ferd-net.de/front_content.php?idcat=231&lang=4)", - "text/xml", zugferdData); + "text/xml", xmlProvider.getXML()); } public void export(String ZUGFeRDfilename) throws IOException { @@ -395,7 +339,9 @@ public class ZUGFeRDExporter implements Closeable { * XML data to be set as a byte array (XML file in raw form). */ public void setZUGFeRDXMLData(byte[] zugferdData) throws IOException { - this.zugferdData = zugferdData; + CustomXMLProvider cus =new CustomXMLProvider(); + cus.setXML(zugferdData); + this.xmlProvider=cus; PDFattachZugferdFile(null); }