diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java b/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java deleted file mode 100644 index fc25c64f..00000000 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA1.java +++ /dev/null @@ -1,124 +0,0 @@ -/** ********************************************************************** - * - * Copyright 2018 Jochen Staerk - * - * Use is subject to license terms. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - * - *********************************************************************** */ -package org.mustangproject.ZUGFeRD; - - -import org.apache.pdfbox.preflight.PreflightDocument; -import org.apache.pdfbox.preflight.exception.ValidationException; -import org.apache.pdfbox.preflight.parser.PreflightParser; - -import javax.activation.DataSource; -import java.io.IOException; -import java.io.InputStream; - -public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExporter { - protected boolean ignorePDFAErrors = false; - - public OXExporterFromA1 ignorePDFAErrors() { - this.ignorePDFAErrors = true; - return this; - } - - private static boolean isValidA1(DataSource dataSource) throws IOException { - return getPDFAParserValidationResult(new PreflightParser(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...) - */ - parser.parse();// might add a Format.PDF_A1A as parameter and iterate through A1 and A3 - - try (PreflightDocument document = parser.getPreflightDocument()) { - /* - * 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. - */ - - document.validate(); - - // Get validation result - return document.getResult().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; - } - } - - - public OXExporterFromA1 setProfile(Profile p) { - return (OXExporterFromA1)super.setProfile(p); - } - public OXExporterFromA1 setProfile(String profileName) { - return (OXExporterFromA1)super.setProfile(profileName); - } - - 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); - - } - - public OXExporterFromA1 load(String pdfFilename) throws IOException { - return (OXExporterFromA1) super.load(pdfFilename); - } - public OXExporterFromA1 load(byte[] pdfBinary) throws IOException { - return (OXExporterFromA1) super.load(pdfBinary); - } - public OXExporterFromA1 load(InputStream pdfSource) throws IOException{ - return (OXExporterFromA1) super.load(pdfSource); - } - public OXExporterFromA1 setCreator(String creator) { - return (OXExporterFromA1) super.setCreator(creator); - } - public OXExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) { - return (OXExporterFromA1) super.setConformanceLevel(newLevel); - } - public OXExporterFromA1 setProducer(String producer){ - return (OXExporterFromA1) super.setProducer(producer); - } - public OXExporterFromA1 setZUGFeRDVersion(int version){ - return (OXExporterFromA1) super.setZUGFeRDVersion(version); - } - public OXExporterFromA1 setXML(byte[] zugferdData) throws IOException{ - return (OXExporterFromA1) super.setXML(zugferdData); - } - - 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 deleted file mode 100644 index 9d7073e4..00000000 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/OXExporterFromA3.java +++ /dev/null @@ -1,659 +0,0 @@ -/** - * ********************************************************************* - *

- * Copyright 2018 Jochen Staerk - *

- * Use is subject to license terms. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0. - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - *

- * See the License for the specific language governing permissions and - * limitations under the License. - *

- * ********************************************************************** - */ -package org.mustangproject.ZUGFeRD; - -import org.apache.pdfbox.cos.*; -import org.apache.pdfbox.io.IOUtils; -import org.apache.pdfbox.pdmodel.*; -import org.apache.pdfbox.pdmodel.common.PDMetadata; -import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; -import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; -import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo; -import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot; -import org.apache.pdfbox.pdmodel.font.PDCIDFontType2; -import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDFontDescriptor; -import org.apache.pdfbox.pdmodel.font.PDType0Font; -import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent; -import org.apache.pdfbox.preflight.utils.ByteArrayDataSource; -import org.apache.xmpbox.XMPMetadata; -import org.apache.xmpbox.schema.AdobePDFSchema; -import org.apache.xmpbox.schema.DublinCoreSchema; -import org.apache.xmpbox.schema.PDFAIdentificationSchema; -import org.apache.xmpbox.schema.XMPBasicSchema; -import org.apache.xmpbox.type.ArrayProperty; -import org.apache.xmpbox.type.BadFieldValueException; -import org.apache.xmpbox.xml.DomXmpParser; -import org.apache.xmpbox.xml.XmpParsingException; -import org.apache.xmpbox.xml.XmpSerializer; -import org.mustangproject.FileAttachment; - -import javax.activation.DataSource; -import javax.activation.FileDataSource; -import javax.xml.transform.TransformerException; -import java.io.*; -import java.util.*; - -public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 { - - 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; - - 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"; - - /** - * @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; - - - private HashMap additionalXMLs = new HashMap(); - - - 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 - */ - public OXExporterFromA3 load(String pdfFilename) throws IOException { - - ensurePDFIsValid(new FileDataSource(pdfFilename)); - try (FileInputStream pdf = new FileInputStream(pdfFilename)) { - return load(readAllBytes(pdf)); - } - } - - public IXMLProvider getProvider() { - return xmlProvider; - } - - public OXExporterFromA3 setProfile(Profile p) { - this.profile = p; - if (xmlProvider != null) { - xmlProvider.setProfile(p); - } - return this; - } - - public OXExporterFromA3 setProfile(String profilename) { - this.profile = Profiles.getByName(profilename); - - if (xmlProvider != null) { - xmlProvider.setProfile(this.profile); - } - return this; - } - - 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 - */ - public OXExporterFromA3 load(byte[] pdfBinary) throws IOException { - ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); - doc = PDDocument.load(pdfBinary); - return this; - } - - public OXExporterFromA3() { - super(); - } - - 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); - } - - /*** - * 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 - */ - 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(); - } - } - - - /*** - * 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 - */ - 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. - * - * @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 - */ - 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); - - 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()); - - ef.setModDate(GregorianCalendar.getInstance()); - - 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); - - // 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 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); - - // AF entry (Array) in catalog with the FileSpec - COSBase AFEntry = (COSBase) 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 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 - */ - public OXExporterFromA3 load(InputStream pdfSource) throws IOException { - return load(readAllBytes(pdfSource)); - } - - 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(); - } - - - /** - * 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 OXExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) { - conformanceLevel = newLevel; - return this; - } - - - public OXExporterFromA3 setCreator(String creator) { - this.creator = creator; - return this; - } - - public OXExporterFromA3 setCreatorTool(String creatorTool) { - this.creatorTool = creatorTool; - return this; - } - - public OXExporterFromA3 setProducer(String producer) { - this.producer = producer; - return this; - } - - 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 - */ - 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"); - - metadata.addSchema(zf); - } - - XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(this, metadata, 1, attachZUGFeRDHeaders); - 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 - */ - public IExporter setTransaction(IExportableTransaction trans) throws IOException { - this.trans = trans; - return prepare(); - } - - public IExporter prepare() throws IOException { - prepareDocument(); - xmlProvider.generateXML(trans); - String filename = "order-x.xml"; - PDFAttachGenericFile(doc, filename, "Alternative", - "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()); - } - - return this; - } - - /** - * Reads the XMPMetadata from the PDDocument, if it exists. - * Otherwise creates XMPMetadata. - */ - protected XMPMetadata getXmpMetadata() { - PDMetadata meta = doc.getDocumentCatalog().getMetadata(); - if (meta != null) { - try { - DomXmpParser xmpParser = new DomXmpParser(); - return xmpParser.parse(meta.toByteArray()); - } catch (XmpParsingException | IOException e) { - // TODO use logging or handle the error somehow - } - } - 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(); - } - - /** - * 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. - */ - 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. - */ - 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 PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { - PDFAIdentificationSchema pdfaid = xmp.getPDFIdentificationSchema(); - if (pdfaid != null) - if (overwrite) - xmp.removeSchema(pdfaid); - else - return pdfaid; - return xmp.createAndAddPFAIdentificationSchema(); - } - - 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); - } - } - - 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(GregorianCalendar.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 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 - */ - protected void addSRGBOutputIntend() { - 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) { - // TODO use logging or handle the error somehow - } - } - - /** - * 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()); - } - } - - - /** - * @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 OXExporterFromA3 disableAutoClose(boolean disableAutoClose) { - this.disableAutoClose = disableAutoClose; - return this; - } - - 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; - } - - /** - * 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 deleted file mode 100644 index efb6f26b..00000000 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/OXPullProvider.java +++ /dev/null @@ -1,585 +0,0 @@ -/** - * ********************************************************************* - *

- * Copyright 2018 Jochen Staerk - *

- * Use is subject to license terms. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0. - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - *

- * See the License for the specific language governing permissions and - * limitations under the License. - *

- * ********************************************************************** - */ -package org.mustangproject.ZUGFeRD; - -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.XMLTools; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.UnsupportedEncodingException; -import java.math.BigDecimal; -import java.text.SimpleDateFormat; -import java.util.Base64; -import java.util.Date; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE; -import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE; -import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON; - -public class OXPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider { - - protected IExportableTransaction trans; - protected TransactionCalculator calc; - private String paymentTermsDescription; - protected Profile profile = Profiles.getByName("EN16931"); - - - - - - @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 = ""; - - if (trans.getPaymentTermDescription() != null) { - paymentTermsDescription = trans.getPaymentTermDescription(); - } - - if ((paymentTermsDescription == null) && (trans.getDocumentCode() != CORRECTEDINVOICE)/* && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)*/) { - paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate()); - - } - - String senderReg = ""; - if (trans.getOwnOrganisationFullPlaintextInfo() != null) { - senderReg = "" + "\n" + " \n" - + XMLTools.encodeXML(trans.getOwnOrganisationFullPlaintextInfo()) + " \n" - + "REG\n" + "\n"; - - } - - String rebateAgreement = ""; - if (trans.rebateAgreementExists()) { - rebateAgreement = "\n" + " " - + "Es bestehen Rabatt- und Bonusvereinbarungen.\n" - + "AAK\n" + "\n"; - } - - String subjectNote = ""; - if (trans.getSubjectNote() != null) { - subjectNote = "\n" + " " - + XMLTools.encodeXML(trans.getSubjectNote()) + "\n" - + "\n"; - } - - String typecode = "380"; - if (trans.getDocumentCode() != null) { - typecode = trans.getDocumentCode(); - } - String notes = ""; - if (trans.getNotes() != null) { - for (final String currentNote : trans.getNotes()) { - notes = notes + "" + XMLTools.encodeXML(currentNote) + ""; - - } - } - String xml = "\n" - - +"\n" - // + " - // xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100 - // ../Schema/ZUGFeRD1p0.xsd\"" - + " xmlns:ram=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100\"" - + " xmlns:udt=\"urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100\"" - + " xmlns:qdt=\"urn:un:unece:uncefact:data:standard:QualifiedDataType:100\">\n" - + " \n" - // + " - // "+testBooleanStr+"\n" - // - + " \n" - + " " + getProfile().getID() + "\n" - + " \n" - + " \n" - + " \n" - + " " + XMLTools.encodeXML(trans.getNumber()) + "\n" - // + " RECHNUNG\n" - // + " 380\n" - + " " + typecode + "\n" - + " " - + DATE.udtFormat(trans.getIssueDate()) + "\n" // date - + notes - + subjectNote - + rebateAgreement - + senderReg - - + " \n" - + " \n"; - int lineID = 0; - for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) { - lineID++; - if (currentItem.getProduct().getTaxExemptionReason() != null) { - exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; - } - notes = ""; - if (currentItem.getNotes() != null) { - for (final String currentNote : currentItem.getNotes()) { - notes = notes + "" + XMLTools.encodeXML(currentNote) + ""; - - } - } - final LineCalculator lc = new LineCalculator(currentItem); - xml = xml + " \n" + - " \n" - + " " + lineID + "\n" - + notes - + " \n" - - + " \n"; - // + " 4012345001235\n" - if (currentItem.getProduct().getSellerAssignedID() != null) { - xml = xml + " " - + XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + "\n"; - } - if (currentItem.getProduct().getBuyerAssignedID() != null) { - xml = xml + " " - + XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "\n"; - } - 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 = xml + " " + XMLTools.encodeXML(currentItem.getProduct().getName()) + "\n" - + " " + XMLTools.encodeXML(currentItem.getProduct().getDescription()) - + "\n" - + " \n" - - + " \n"; - if (currentItem.getReferencedDocuments() != null) { - for (IReferencedDocument currentReferencedDocument : currentItem.getReferencedDocuments()) { - xml = xml + "\n" + - "" + XMLTools.encodeXML(currentReferencedDocument.getIssuerAssignedID()) + "\n" + - "" + XMLTools.encodeXML(currentReferencedDocument.getTypeCode()) + "\n" + - "" + XMLTools.encodeXML(currentReferencedDocument.getReferenceTypeCode()) + "\n" + - "\n"; - - - } - - } - if (currentItem.getBuyerOrderReferencedDocumentLineID() != null) { - xml = xml + " \n" - + " " + XMLTools.encodeXML(currentItem.getBuyerOrderReferencedDocumentLineID()) + "\n" - + " \n"; - - } - xml = xml + " \n" - + " " + priceFormat(lc.getPriceGross()) - + "\n" //currencyID=\"EUR\" - + "" + quantityFormat(currentItem.getBasisQuantity()) + "\n" - + allowanceChargeStr - // + " \n" - // + " false\n" - // + " 0.6667\n" - // + " Rabatt\n" - // + " \n" - + " \n" - + " \n" - + " " + priceFormat(lc.getPrice()) - + "\n" // currencyID=\"EUR\" - + " " + quantityFormat(currentItem.getBasisQuantity()) + "\n" - + " \n" - + " \n" - - + " \n" - + " " - + quantityFormat(currentItem.getQuantity()) + "\n" - + " \n" - + " \n" - + " \n" - + " VAT\n" - + exemptionReason - + " " + currentItem.getProduct().getTaxCategoryCode() + "\n" - - + " " - + vatFormat(currentItem.getProduct().getVATPercent()) + "\n" - + " \n"; - if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) { - xml = xml + ""; - if (currentItem.getDetailedDeliveryPeriodFrom() != null) { - xml = xml + "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodFrom()) + ""; - } - if (currentItem.getDetailedDeliveryPeriodTo() != null) { - xml = xml + "" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodTo()) + ""; - } - xml = xml + ""; - - } - - xml = xml + " \n" - + " " + currencyFormat(lc.getItemTotalNetAmount()) - + "\n" // currencyID=\"EUR\" - + " \n"; - if (currentItem.getAdditionalReferencedDocumentID() != null) { - xml = xml + " " + currentItem.getAdditionalReferencedDocumentID() + "130\n"; - - } - xml = xml + " \n" - + " \n"; - - } - - xml = xml + " \n"; - if (trans.getReferenceNumber() != null) { - xml = xml + " " + XMLTools.encodeXML(trans.getReferenceNumber()) + "\n"; - - } - xml = xml + " \n" - + getTradePartyAsXML(trans.getSender(), true, false) - + " \n" - + " \n"; - // + " GE2020211\n" - // + " 4000001987658\n" - - xml += getTradePartyAsXML(trans.getRecipient(), false, false); - xml += " \n"; - - if (trans.getSellerOrderReferencedDocumentID() != null) { - xml = xml + " \n" - + " " - + XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "\n" - + " \n"; - } - if (trans.getBuyerOrderReferencedDocumentID() != null) { - xml = xml + " \n" - + " " - + XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "\n" - + " \n"; - } - if (trans.getContractReferencedDocument() != null) { - xml = xml + " \n" - + " " - + XMLTools.encodeXML(trans.getContractReferencedDocument()) + "\n" - + " \n"; - } - - // 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 = xml + " \n" - + " " + f.getFilename() + "\n" - + " 916\n" - + " " + f.getDescription() + "\n" - + " " + documentContent + "\n" - + " \n"; - } - } - - if (trans.getSpecifiedProcuringProjectID() != null) { - xml = xml + " \n" - + " " - + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + "\n"; - if(trans.getSpecifiedProcuringProjectName()!= null) { - xml += " " + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + "\n"; - } - xml += " \n"; - } - xml = xml + " \n" - + " \n"; - if (this.trans.getDeliveryAddress() != null) { - xml += "" + - getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) + - ""; - } - - xml += " \n" - + " "; - - 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" - */ - + " \n" + " \n" - + " " + XMLTools.encodeXML(trans.getNumber()) + "\n" - + " " + trans.getCurrency() + "\n"; - - 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() == 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 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 = xml + ""; - if (trans.getDetailedDeliveryPeriodFrom() != null) { - xml = xml + "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodFrom()) + ""; - } - if (trans.getDetailedDeliveryPeriodTo() != null) { - xml = xml + "" + DATE.udtFormat(trans.getDetailedDeliveryPeriodTo()) + ""; - } - xml = xml + ""; - - - } - - if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) { - - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - if (calc.getChargesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { - - - xml = xml + " \n" + - " \n" + - " true\n" + - " \n" + - " " + currencyFormat(calc.getChargesForPercent(currentTaxPercent)) + "\n" + - " " + XMLTools.encodeXML(calc.getChargeReasonForPercent(currentTaxPercent)) + "\n" + - " \n" + - " VAT\n" + - " " + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "\n" + - " " + vatFormat(currentTaxPercent) + "\n" + - " \n" + - " \n"; - - } - } - - } - - if ((trans.getZFAllowances() != null) && (trans.getZFAllowances().length > 0)) { - for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) { - if (calc.getAllowancesForPercent(currentTaxPercent).compareTo(BigDecimal.ZERO) != 0) { - xml = xml + " \n" + - " \n" + - " false\n" + - " \n" + - " " + currencyFormat(calc.getAllowancesForPercent(currentTaxPercent)) + "\n" + - " " + XMLTools.encodeXML(calc.getAllowanceReasonForPercent(currentTaxPercent)) + "\n" + - " \n" + - " VAT\n" + - " " + VATPercentAmountMap.get(currentTaxPercent).getCategoryCode() + "\n" + - " " + vatFormat(currentTaxPercent) + "\n" + - " \n" + - " \n"; - } - } - } - - - if ((trans.getPaymentTerms() == null) && ((paymentTermsDescription != null) || (trans.getTradeSettlement() != null) || (hasDueDate))) { - xml = xml + "\n"; - - if (paymentTermsDescription != null) { - xml = xml + "" + paymentTermsDescription + "\n"; - } - - 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 = xml + " " // $NON-NLS-2$ - + DATE.udtFormat(trans.getDueDate()) - + "\n";// 20130704 - - } - xml = xml + " \n"; - } else { - xml = xml + buildPaymentTermsXml(); - } - - - final String allowanceTotalLine = "" + currencyFormat(calc.getAllowancesForPercent(null)) + ""; - - final String chargesTotalLine = "" + currencyFormat(calc.getChargesForPercent(null)) + ""; - - xml = xml + " \n" - + " " + currencyFormat(calc.getTotal()) + "\n" - + chargesTotalLine - + allowanceTotalLine - + " " + currencyFormat(calc.getTaxBasis()) + "\n" - // // - // currencyID=\"EUR\" - + " " - + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "\n" - + " " + currencyFormat(calc.getGrandTotal()) + "\n" - // // - // currencyID=\"EUR\" - + " " + currencyFormat(calc.getTotalPrepaid()) + "\n" - + " " + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "\n" - + " \n"; - if (trans.getInvoiceReferencedDocumentID() != null) { - xml = xml + " \n" - + " " - + XMLTools.encodeXML(trans.getInvoiceReferencedDocumentID()) + "\n"; - if(trans.getInvoiceReferencedIssueDate()!= null){ - xml += "" - + DATE.qdtFormat(trans.getInvoiceReferencedIssueDate()) - + "\n"; - } - xml += " \n"; - } - - xml = xml + " \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 + " \n" - + ""; - - final byte[] zugferdRaw; - try { - zugferdRaw = xml.getBytes("UTF-8"); - - zugferdData = XMLTools.removeBOM(zugferdRaw); - } catch (final UnsupportedEncodingException e) { - Logger.getLogger(OXPullProvider.class.getName()).log(Level.SEVERE, null, e); - } - } - - - @Override - public void setProfile(Profile p) { - profile = p; - } - - 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() + ""; - 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.getBaseDate() != null) { - final Date baseDate = discountTerms.getBaseDate(); - paymentTermsXml += ""; - paymentTermsXml += DATE.udtFormat(baseDate); - paymentTermsXml += ""; - - paymentTermsXml += "" - + discountTerms.getBasePeriodMeasure() + ""; - } - - paymentTermsXml += ""; - } - - paymentTermsXml += ""; - return paymentTermsXml; - } - -} diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java index 55b221a4..a5bd0457 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD1PullProvider.java @@ -57,19 +57,19 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr public void setTest() { } - protected String vatFormat(BigDecimal value) { + private String vatFormat(BigDecimal value) { return XMLTools.nDigitFormat(value, 2); } - protected String currencyFormat(BigDecimal value) { + private String currencyFormat(BigDecimal value) { return XMLTools.nDigitFormat(value, 2); } - protected String priceFormat(BigDecimal value) { + private String priceFormat(BigDecimal value) { return XMLTools.nDigitFormat(value, 4); } - protected String quantityFormat(BigDecimal value) { + private String quantityFormat(BigDecimal value) { return XMLTools.nDigitFormat(value, 4); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 6502b65c..f4996ff0 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -59,19 +59,19 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { public void setTest() { } - protected String vatFormat(BigDecimal value) { + private String vatFormat(BigDecimal value) { return XMLTools.nDigitFormat(value, 2); } - protected String currencyFormat(BigDecimal value) { + private String currencyFormat(BigDecimal value) { return XMLTools.nDigitFormat(value, 2); } - protected String priceFormat(BigDecimal value) { + private String priceFormat(BigDecimal value) { return XMLTools.nDigitFormat(value, 4); } - protected String quantityFormat(BigDecimal value) { + private String quantityFormat(BigDecimal value) { return XMLTools.nDigitFormat(value, 4); } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java index 5730d337..4113811d 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromA3.java @@ -69,7 +69,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte private boolean disableAutoClose; private boolean fileAttached = false; private Profile profile = null; - protected boolean documentPrepared = false; + private boolean documentPrepared = false; /** * Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set, @@ -108,7 +108,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte @Deprecated protected String subject; - protected PDDocument doc; + private PDDocument doc; private HashMap additionalXMLs = new HashMap(); @@ -481,7 +481,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte metadata.addSchema(pdfaex); } - protected void removeCidSet(PDDocumentCatalog catalog, PDDocument doc) { + private void removeCidSet(PDDocumentCatalog catalog, PDDocument doc) { // https://github.com/ZUGFeRD/mustangproject/issues/249 diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java index 4ea4fdaf..b68e7dfe 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterEdgeTest.java @@ -135,7 +135,8 @@ public class MustangReaderWriterEdgeTest extends MustangReaderTestCase { @Override public String getPaymentTermDescription() { - return "#SKONTO#TAGE=7#PROZENT=3.00#BASISBETRAG=571.04#\n"; + SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); + return "Zahlbar ohne Abzug bis zum " + germanDateFormat.format(getDueDate()); } @Override diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/OXTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/OXTest.java deleted file mode 100644 index f0cd421e..00000000 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/OXTest.java +++ /dev/null @@ -1,299 +0,0 @@ - -/** ********************************************************************** - * - * Copyright 2019 Jochen Staerk - * - * Use is subject to license terms. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - * - *********************************************************************** */ -package org.mustangproject.ZUGFeRD; - -import junit.framework.Test; -import junit.framework.TestSuite; -import org.junit.FixMethodOrder; -import org.junit.runners.MethodSorters; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; - -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class OXTest extends MustangReaderTestCase implements IExportableTransaction { - final String TARGET_PDF = "./target/testout-OX.pdf"; - - 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; - } - - @Override - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @Override - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public String getUnit() { - return unit; - } - - public void setUnit(String unit) { - this.unit = unit; - } - - @Override - public BigDecimal getVATPercent() { - return BigDecimal.ZERO; - } - - @Override - public boolean isIntraCommunitySupply() { - return true; // simulate intra community supply - } - } - - protected class DebitPayment implements IZUGFeRDTradeSettlementDebit { - - @Override - public String getIBAN() { - return "DE540815"; - } - - @Override - public String getMandate() { - return "DE99XX12345"; - } - - } - - @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 getDueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 30).getTime(); - } - - @Override - public Date getIssueDate() { - return new GregorianCalendar(2017, Calendar.MAY, 9).getTime(); - } - - @Override - public String getNumber() { - return "RE-20170509/505"; - } - - @Override - public String getOwnCountry() { - return "DE"; - } - - @Override - public String getOwnLocation() { - return "Stadthausen"; - } - - @Override - public String getOwnOrganisationName() { - return "Bei Spiel GmbH"; - } - - @Override - public String getOwnStreet() { - return "Ecke 12"; - } - - @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 getOwnZIP() { - return "12345"; - } - - @Override - public IZUGFeRDExportableTradeParty getRecipient() { - return new RecipientTradeParty(); - } - - @Override - public IZUGFeRDExportableTradeParty getDeliveryAddress() { - return new RecipientTradeParty(); - } - - @Override - public String getOwnOrganisationFullPlaintextInfo() { - return null; - } - - @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"); - - 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 IZUGFeRDAllowanceCharge[] getZFAllowances() { - return null; - } - - @Override - public IZUGFeRDAllowanceCharge[] getZFCharges() { - return null; - } - - @Override - public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { - return null; - } - - @Override - public String getReferenceNumber() { - return "AB321"; - } - - /** - * 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); - } - - // //////// 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 writing part - - 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("59")); - assertTrue(zi.getUTF8().contains("")); - assertTrue(zi.getUTF8().contains("DE540815")); - assertTrue(zi.getUTF8().contains("DE99XX12345")); - assertFalse(zi.getUTF8().contains("")); - assertFalse(zi.getUTF8().contains("EUR")); - assertTrue(zi.getUTF8().contains("USD"));//currency should be USD, test for #150 - - // Reading ZUGFeRD - assertEquals("496.00", zi.getAmount()); - assertEquals(zi.getHolder(), getOwnOrganisationName()); - assertEquals(zi.getForeignReference(), getNumber()); - try { - assertEquals(zi.getVersion(), 2); - } catch (Exception e) { - e.printStackTrace(); - } - - } - -}