Merge branch 'ZUGFeRD:master' into issues/628-invoice-referenced-documents
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
|
||||
2.15.2
|
||||
=======
|
||||
2024-12-19
|
||||
- correcly write charge reason codes also for non-Xrechnung #617
|
||||
- correctly import additional referenced documents into invoice/corrected setting of attachments from jackson
|
||||
- corrected parseException structure
|
||||
- allow 1p0 as potential xmp version number
|
||||
- #618 import BT-20
|
||||
- #599 add tax category code for free export
|
||||
- #600 Fixes a problem where a stream was not safely closed
|
||||
|
||||
2.15.1
|
||||
=======
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.15.2-SNAPSHOT</version>
|
||||
<version>2.15.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
@@ -12,7 +12,7 @@
|
||||
should also work for XRechnung/CII.
|
||||
</name>
|
||||
<packaging>jar</packaging>
|
||||
<version>2.15.2-SNAPSHOT</version>
|
||||
<version>2.15.3-SNAPSHOT</version>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.compilerVersion>11</maven.compiler.compilerVersion>
|
||||
@@ -23,7 +23,7 @@
|
||||
<dependency>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>validator</artifactId>
|
||||
<version>2.15.2-SNAPSHOT</version>
|
||||
<version>2.15.3-SNAPSHOT</version>
|
||||
<!-- prototypes of new mustangproject versions can be installed by referring to them and installed to the local repo from a jar file with
|
||||
mvn install:install-file -Dfile=mustang-1.5.4-SNAPSHOT.jar -DgroupId=org.mustangproject.ZUGFeRD -DartifactId=mustang -Dversion=1.5.4 -Dpackaging=jar -DgeneratePom=true
|
||||
-->
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
package org.mustangproject.commandline;
|
||||
|
||||
import org.apache.commons.cli.*;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.mustangproject.CII.CIIToUBL;
|
||||
import org.mustangproject.EStandard;
|
||||
import org.mustangproject.FileAttachment;
|
||||
@@ -84,6 +85,7 @@ public class Main {
|
||||
+ " [--logAppend <text>]: text to be added to log line\n"
|
||||
+ " Additional parameters (optional - user will be prompted if not defined)\n"
|
||||
+ " [--source <filename>]: 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"
|
||||
@@ -357,6 +359,7 @@ public class Main {
|
||||
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 = "";
|
||||
@@ -380,6 +383,7 @@ public class Main {
|
||||
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");
|
||||
@@ -427,7 +431,7 @@ public class Main {
|
||||
performUBL(sourceName, outName);
|
||||
optionsRecognized = true;
|
||||
} else if ((action != null) && (action.equals("validate"))) {
|
||||
optionsRecognized = performValidate(sourceName, noNotices, cmd.getOptionValue("logAppend"));
|
||||
optionsRecognized = performValidate(sourceName, noNotices, cmd.getOptionValue("logAppend"), LogAsPDF);
|
||||
} else if ((action != null) && (action.equals("validateExpectValid"))) {
|
||||
optionsRecognized = performValidateExpect(true, directoryName);
|
||||
} else if ((action != null) && (action.equals("validateExpectInvalid"))) {
|
||||
@@ -454,7 +458,7 @@ public class Main {
|
||||
|
||||
}
|
||||
|
||||
private static boolean performValidate(String sourceName, boolean noNotices, String logAppend) {
|
||||
private static boolean performValidate(String sourceName, boolean noNotices, String logAppend, boolean createLogAsPDF) {
|
||||
boolean optionsRecognized;
|
||||
if (sourceName == null) {
|
||||
sourceName = getFilenameFromUser("Source PDF or XML", "invoice.pdf", "pdf|xml", true, false);
|
||||
@@ -466,7 +470,16 @@ public class Main {
|
||||
if (noNotices) {
|
||||
zfv.disableNotices();
|
||||
}
|
||||
System.out.println(zfv.validate(sourceName));
|
||||
|
||||
String validationResultXML = zfv.validate(sourceName);
|
||||
System.out.println(validationResultXML);
|
||||
|
||||
if( createLogAsPDF) {
|
||||
ValidationLogVisualizer vlvi = new ValidationLogVisualizer();
|
||||
String fileBasename = FilenameUtils.getBaseName(sourceName);
|
||||
|
||||
vlvi.toPDF(validationResultXML, fileBasename + "_result.pdf");
|
||||
}
|
||||
optionsRecognized = !zfv.hasOptionsError();
|
||||
if (!zfv.wasCompletelyValid()) {
|
||||
System.exit(-1);
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<parent>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.15.2-SNAPSHOT</version>
|
||||
<version>2.15.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>library</artifactId>
|
||||
<version>2.15.2-SNAPSHOT</version>
|
||||
<version>2.15.3-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>Library to write, read and validate e-invoices (Factur-X, ZUGFeRD, Order-X, XRechnung/CII)</name>
|
||||
<description>FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT
|
||||
@@ -200,21 +200,51 @@
|
||||
</manifest>
|
||||
<manifestSections>
|
||||
<manifestSection>
|
||||
<name>FreeSans.ttf</name>
|
||||
<name>SourceSansPro-Regular.ttf</name>
|
||||
<manifestEntries>
|
||||
<Content-Type>font/ttf</Content-Type>
|
||||
</manifestEntries>
|
||||
</manifestSection>
|
||||
<manifestSection>
|
||||
<name>FreeSerif.ttf</name>
|
||||
<name>SourceSansPro-It.ttf</name>
|
||||
<manifestEntries>
|
||||
<Content-Type>application/x-font</Content-Type>
|
||||
<Content-Type>font/ttf</Content-Type>
|
||||
</manifestEntries>
|
||||
</manifestSection>
|
||||
<manifestSection>
|
||||
<name>Times-Bold.ttf</name>
|
||||
<name>SourceSansPro-Bold.ttf</name>
|
||||
<manifestEntries>
|
||||
<Content-Type>application/x-font</Content-Type>
|
||||
<Content-Type>font/ttf</Content-Type>
|
||||
</manifestEntries>
|
||||
</manifestSection>
|
||||
<manifestSection>
|
||||
<name>SourceSansPro-BoldIt.ttf</name>
|
||||
<manifestEntries>
|
||||
<Content-Type>font/ttf</Content-Type>
|
||||
</manifestEntries>
|
||||
</manifestSection>
|
||||
<manifestSection>
|
||||
<name>SourceSerifPro-Regular.ttf</name>
|
||||
<manifestEntries>
|
||||
<Content-Type>font/ttf</Content-Type>
|
||||
</manifestEntries>
|
||||
</manifestSection>
|
||||
<manifestSection>
|
||||
<name>SourceSerifPro-It.ttf</name>
|
||||
<manifestEntries>
|
||||
<Content-Type>font/ttf</Content-Type>
|
||||
</manifestEntries>
|
||||
</manifestSection>
|
||||
<manifestSection>
|
||||
<name>SourceSerifPro-Bold.ttf</name>
|
||||
<manifestEntries>
|
||||
<Content-Type>font/ttf</Content-Type>
|
||||
</manifestEntries>
|
||||
</manifestSection>
|
||||
<manifestSection>
|
||||
<name>SourceSerifPro-BoldIt.ttf</name>
|
||||
<manifestEntries>
|
||||
<Content-Type>font/ttf</Content-Type>
|
||||
</manifestEntries>
|
||||
</manifestSection>
|
||||
</manifestSections>
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import org.apache.fop.apps.*;
|
||||
import org.apache.fop.apps.io.ResourceResolverFactory;
|
||||
import org.apache.fop.configuration.Configuration;
|
||||
import org.apache.fop.configuration.ConfigurationException;
|
||||
import org.apache.fop.configuration.DefaultConfigurationBuilder;
|
||||
import org.apache.xmlgraphics.util.MimeConstants;
|
||||
import org.mustangproject.ClasspathResolverURIAdapter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.xml.transform.*;
|
||||
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 ValidationLogVisualizer {
|
||||
public enum Language {
|
||||
EN,
|
||||
FR,
|
||||
DE
|
||||
}
|
||||
|
||||
static final ClassLoader CLASS_LOADER = ValidationLogVisualizer.class.getClassLoader();
|
||||
private static final String RESOURCE_PATH = "";
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ValidationLogVisualizer.class);
|
||||
|
||||
private TransformerFactory mFactory = null;
|
||||
private Templates mXsltPDFTemplate = null;
|
||||
|
||||
|
||||
public ValidationLogVisualizer() {
|
||||
mFactory = new net.sf.saxon.TransformerFactoryImpl();
|
||||
// fact = TransformerFactory.newInstance();
|
||||
mFactory.setURIResolver(new ValidationLogVisualizer.ClasspathResourceURIResolver());
|
||||
}
|
||||
|
||||
protected void applyXSLTToPDF(final String xmlContent, final OutputStream PDFOutstream)
|
||||
throws TransformerException {
|
||||
Transformer transformer = mXsltPDFTemplate.newTransformer();
|
||||
|
||||
transformer.transform(new StreamSource(new StringReader(xmlContent)), new StreamResult(PDFOutstream));
|
||||
}
|
||||
|
||||
protected String toFOP(final String xmlContent)
|
||||
throws TransformerException {
|
||||
|
||||
try {
|
||||
if (mXsltPDFTemplate == null) {
|
||||
mXsltPDFTemplate = mFactory.newTemplates(
|
||||
new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/result-pdf.xsl")));
|
||||
}
|
||||
} catch (TransformerConfigurationException ex) {
|
||||
LOGGER.error("Failed to init XSLT templates", ex);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
try {
|
||||
|
||||
applyXSLTToPDF(xmlContent, baos);
|
||||
|
||||
} catch (Exception e1) {
|
||||
LOGGER.error("Failed to create PDF", e1);
|
||||
}
|
||||
|
||||
return baos.toString(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public void toPDF(String xmlLogfileContent, String pdfFilename) {
|
||||
|
||||
// the writing part
|
||||
|
||||
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);
|
||||
} catch ( TransformerException e) {
|
||||
LOGGER.error("Failed to apply FOP", e);
|
||||
}
|
||||
DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
|
||||
|
||||
Configuration cfg = null;
|
||||
try {
|
||||
cfg = cfgBuilder.build(CLASS_LOADER.getResourceAsStream("fop-config.xconf"));
|
||||
} catch (ConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
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 fopFactory = builder.build();
|
||||
|
||||
fopFactory.getFontManager().setResourceResolver(
|
||||
ResourceResolverFactory.createInternalResourceResolver(
|
||||
new File(".").toURI(),
|
||||
new ClasspathResolverURIAdapter()));
|
||||
|
||||
FOUserAgent userAgent = fopFactory.newFOUserAgent();
|
||||
|
||||
userAgent.getRendererOptions().put("pdf-a-mode", "PDF/A-3b");
|
||||
|
||||
// Step 2: Set up output stream.
|
||||
// Note: Using BufferedOutputStream for performance reasons (helpful with FileOutputStreams).
|
||||
|
||||
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 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)));
|
||||
|
||||
// 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);
|
||||
|
||||
} catch (FOPException | IOException | TransformerException e) {
|
||||
LOGGER.error("Failed to create PDF", e);
|
||||
}
|
||||
}
|
||||
|
||||
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 + "stylesheets/" + href));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,9 @@ public class ZUGFeRDExporterFromPDFA implements IZUGFeRDExporter {
|
||||
}
|
||||
|
||||
protected byte[] filenameToByteArray(String pdfFilename) throws IOException {
|
||||
FileInputStream fileInputStream = new FileInputStream(pdfFilename);
|
||||
return inputstreamToByteArray(fileInputStream);
|
||||
try (FileInputStream fileInputStream = new FileInputStream(pdfFilename)) {
|
||||
return inputstreamToByteArray(fileInputStream);
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] inputstreamToByteArray(InputStream fileInputStream) throws IOException {
|
||||
|
||||
@@ -659,6 +659,7 @@ public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
|
||||
*
|
||||
* @return a List of LineItem instances
|
||||
*/
|
||||
@Deprecated
|
||||
public List<Item> getLineItemList() {
|
||||
final List<Node> nodeList = getLineItemNodes();
|
||||
final List<Item> lineItemList = new ArrayList<>();
|
||||
|
||||
@@ -1053,6 +1053,7 @@ public class ZUGFeRDInvoiceImporter {
|
||||
* for PDF embedded files in FX use getFileAttachmentsPDF()
|
||||
* @deprecated use invoice.getAdditionalReferencedDocuments
|
||||
*/
|
||||
@Deprecated
|
||||
public List<FileAttachment> getFileAttachmentsXML() {
|
||||
return new ArrayList<>(Arrays.asList(importedInvoice.getAdditionalReferencedDocuments()));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ public class TaxCategoryCodeTypeConstants {
|
||||
public static final String ZEROTAXPRODUCTS = "Z";
|
||||
public static final String UNTAXEDSERVICE = "O";
|
||||
public static final String INTRACOMMUNITY = "K";
|
||||
|
||||
public static Set<String> CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT).collect(Collectors.toSet());
|
||||
public static final String FREEEXPORT = "G";
|
||||
|
||||
public static Set<String> CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT, FREEEXPORT).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
BIN
library/src/main/resources/fonts/SourceSansPro-Bold.ttf
Normal file
BIN
library/src/main/resources/fonts/SourceSansPro-Bold.ttf
Normal file
Binary file not shown.
BIN
library/src/main/resources/fonts/SourceSansPro-BoldIt.ttf
Normal file
BIN
library/src/main/resources/fonts/SourceSansPro-BoldIt.ttf
Normal file
Binary file not shown.
BIN
library/src/main/resources/fonts/SourceSansPro-It.ttf
Normal file
BIN
library/src/main/resources/fonts/SourceSansPro-It.ttf
Normal file
Binary file not shown.
BIN
library/src/main/resources/fonts/SourceSansPro-Regular.ttf
Normal file
BIN
library/src/main/resources/fonts/SourceSansPro-Regular.ttf
Normal file
Binary file not shown.
BIN
library/src/main/resources/fonts/SourceSerifPro-Bold.ttf
Normal file
BIN
library/src/main/resources/fonts/SourceSerifPro-Bold.ttf
Normal file
Binary file not shown.
BIN
library/src/main/resources/fonts/SourceSerifPro-BoldIt.ttf
Normal file
BIN
library/src/main/resources/fonts/SourceSerifPro-BoldIt.ttf
Normal file
Binary file not shown.
BIN
library/src/main/resources/fonts/SourceSerifPro-It.ttf
Normal file
BIN
library/src/main/resources/fonts/SourceSerifPro-It.ttf
Normal file
Binary file not shown.
BIN
library/src/main/resources/fonts/SourceSerifPro-Regular.ttf
Normal file
BIN
library/src/main/resources/fonts/SourceSerifPro-Regular.ttf
Normal file
Binary file not shown.
@@ -1,37 +1,57 @@
|
||||
<fop version="1.0">
|
||||
|
||||
<!-- Strict user configuration -->
|
||||
<strict-configuration>true</strict-configuration>
|
||||
|
||||
<!-- Strict FO validation -->
|
||||
<strict-validation>true</strict-validation>
|
||||
|
||||
<!-- Base URL for resolving relative URLs -->
|
||||
|
||||
<!-- Font Base URL for resolving relative font URLs -->
|
||||
|
||||
<!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi -->
|
||||
<source-resolution>96</source-resolution>
|
||||
<!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi -->
|
||||
<target-resolution>96</target-resolution>
|
||||
|
||||
<!-- default page-height and page-width, in case
|
||||
value is specified as auto -->
|
||||
<default-page-settings height="297mm" width="210mm"/><!-- DIN A/4 -->
|
||||
|
||||
<!-- etc. etc..... -->
|
||||
|
||||
<renderers>
|
||||
<renderer mime="application/pdf">
|
||||
<fonts><!-- https://xmlgraphics.apache.org/fop/1.1/fonts.html auto-embed -->
|
||||
<auto-detect/>
|
||||
<font kerning="no" embed-url="classpath:FreeSans.ttf" embedding-mode="subset">
|
||||
<font-triplet name="SourceSerifPro" style="normal" weight="normal" />
|
||||
<font-triplet name="Times-Bold" style="normal" weight="normal" />
|
||||
</font>
|
||||
</fonts>
|
||||
<output-profile>classpath:AdobeCompat-v2.icc</output-profile>
|
||||
</renderer>
|
||||
</renderers>
|
||||
|
||||
</fop>
|
||||
<fop version="1.0">
|
||||
|
||||
<!-- Strict user configuration -->
|
||||
<strict-configuration>true</strict-configuration>
|
||||
|
||||
<!-- Strict FO validation -->
|
||||
<strict-validation>true</strict-validation>
|
||||
|
||||
<!-- Base URL for resolving relative URLs -->
|
||||
|
||||
<!-- Font Base URL for resolving relative font URLs -->
|
||||
|
||||
<!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi -->
|
||||
<source-resolution>96</source-resolution>
|
||||
<!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi -->
|
||||
<target-resolution>96</target-resolution>
|
||||
|
||||
<!-- default page-height and page-width, in case
|
||||
value is specified as auto -->
|
||||
<default-page-settings height="297mm" width="210mm"/><!-- DIN A/4 -->
|
||||
|
||||
<!-- etc. etc..... -->
|
||||
|
||||
<renderers>
|
||||
<renderer mime="application/pdf">
|
||||
<fonts>
|
||||
<!-- https://xmlgraphics.apache.org/fop/1.1/fonts.html auto-embed -->
|
||||
<auto-detect/>
|
||||
<font kerning="yes" embed-url="classpath:fonts/SourceSansPro-Regular.ttf" embedding-mode="subset">
|
||||
<font-triplet name="SourceSansPro" style="normal" weight="400"/>
|
||||
</font>
|
||||
<font kerning="yes" embed-url="classpath:fonts/SourceSansPro-It.ttf" embedding-mode="subset">
|
||||
<font-triplet name="SourceSansPro" style="italic" weight="400"/>
|
||||
</font>
|
||||
<font kerning="yes" embed-url="classpath:fonts/SourceSansPro-Bold.ttf" embedding-mode="subset">
|
||||
<font-triplet name="SourceSansPro" style="normal" weight="700"/>
|
||||
</font>
|
||||
<font kerning="yes" embed-url="classpath:fonts/SourceSansPro-BoldIt.ttf" embedding-mode="subset">
|
||||
<font-triplet name="SourceSansPro" style="italic" weight="700"/>
|
||||
</font>
|
||||
<font kerning="yes" embed-url="classpath:fonts/SourceSerifPro-Regular.ttf" embedding-mode="subset">
|
||||
<font-triplet name="SourceSerifPro" style="normal" weight="400"/>
|
||||
</font>
|
||||
<font kerning="yes" embed-url="classpath:fonts/SourceSerifPro-It.ttf" embedding-mode="subset">
|
||||
<font-triplet name="SourceSerifPro" style="italic" weight="400"/>
|
||||
</font>
|
||||
<font kerning="yes" embed-url="classpath:fonts/SourceSerifPro-Bold.ttf" embedding-mode="subset">
|
||||
<font-triplet name="SourceSerifPro" style="normal" weight="700"/>
|
||||
</font>
|
||||
<font kerning="yes" embed-url="classpath:fonts/SourceSerifPro-BoldIt.ttf" embedding-mode="subset">
|
||||
<font-triplet name="SourceSerifPro" style="italic" weight="700"/>
|
||||
</font>
|
||||
</fonts>
|
||||
<output-profile>classpath:AdobeCompat-v2.icc</output-profile>
|
||||
</renderer>
|
||||
</renderers>
|
||||
</fop>
|
||||
|
||||
227
library/src/main/resources/stylesheets/result-pdf.xsl
Normal file
227
library/src/main/resources/stylesheets/result-pdf.xsl
Normal file
@@ -0,0 +1,227 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:axf="http://www.antennahouse.com/names/XSL/Extensions"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
version="2.0">
|
||||
<!-- ==========================================================================
|
||||
== Imports
|
||||
=========================================================================== -->
|
||||
<xsl:import href="common-xr.xsl"/>
|
||||
|
||||
<xsl:import href="xr-pdf/lib/konstanten.xsl"/>
|
||||
|
||||
<!-- FO engine used can be specified. Specific extensions will be then enabled.
|
||||
Supported values are:
|
||||
axf - Antenna House XSL Formatter
|
||||
fop - Apache FOP
|
||||
-->
|
||||
<xsl:param name="foengine"/>
|
||||
|
||||
<xsl:param name="axf.extensions" select="if ($foengine eq 'axf') then true() else false()"/>
|
||||
<xsl:param name="fop.extensions" select="if ($foengine eq 'fop') then true() else false()"/>
|
||||
|
||||
|
||||
<xsl:variable name="xml_result_color">
|
||||
<xsl:if test="/validation/xml/summary/@status = 'valid' ">
|
||||
<xsl:text>green</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="/validation/xml/summary/@status = 'invalid' ">
|
||||
<xsl:text>red</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:variable name="pdf_result_color">
|
||||
<xsl:if test="/validation/pdf/summary/@status = 'valid' ">
|
||||
<xsl:text>green</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="/validation/pdf/summary/@status = 'invalid' ">
|
||||
<xsl:text>red</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:variable name="pdf_result_text">
|
||||
<xsl:if test="/validation/xml/summary/@status = 'valid' ">
|
||||
<xsl:text>Das ZUGFeRD-PDF ist valide.</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="/validation/xml/summary/@status = 'invalid' ">
|
||||
<xsl:text>Das ZUGFeRD-PDF ist nicht valide.</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:variable name="result_text">
|
||||
<xsl:if test="/validation/xml/summary/@status = 'valid' ">
|
||||
<xsl:text>Es wird empfohlen das Dokument anzunehmen und weiter zu verarbeiten.</xsl:text>
|
||||
</xsl:if>
|
||||
<xsl:if test="/validation/xml/summary/@status = 'invalid' ">
|
||||
<xsl:text>Es wird empfohlen das Dokument zurückzuweisen.</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:template match="validation">
|
||||
<fo:root xmlns:pdf="http://xmlgraphics.apache.org/fop/extensions/pdf"
|
||||
language="{$lang}" font-family="{$fontSans}">
|
||||
<fo:layout-master-set>
|
||||
<fo:simple-page-master master-name="DIN-A4" page-height="297mm" page-width="210mm">
|
||||
<fo:region-body region-name="body" margin="20mm 10mm 20mm 20mm" />
|
||||
</fo:simple-page-master>
|
||||
</fo:layout-master-set>
|
||||
|
||||
<fo:page-sequence master-reference="DIN-A4">
|
||||
<fo:flow flow-name="body">
|
||||
<fo:block font-size="24px" font-weight="bold">
|
||||
Prüfbericht
|
||||
</fo:block>
|
||||
|
||||
<xsl:call-template name="SubHeader">
|
||||
<xsl:with-param name="text" select='"Angaben zum geprüften Dokument"' />
|
||||
<xsl:with-param name="color" select='"black"' />
|
||||
</xsl:call-template>
|
||||
|
||||
<fo:block>
|
||||
<fo:block text-align="justify">
|
||||
<fo:float float="right">
|
||||
<fo:block >
|
||||
<xsl:value-of select="/validation/@filename" />
|
||||
</fo:block>
|
||||
</fo:float>
|
||||
Referenz:
|
||||
</fo:block>
|
||||
</fo:block>
|
||||
<fo:block>
|
||||
<fo:block text-align="justify">
|
||||
<fo:float float="right">
|
||||
<fo:block >
|
||||
<xsl:value-of select="/validation/@datetime" />
|
||||
</fo:block>
|
||||
</fo:float>
|
||||
Zeitpunkt der Prüfung:
|
||||
</fo:block>
|
||||
</fo:block>
|
||||
<fo:block>
|
||||
<fo:block text-align="justify">
|
||||
<fo:float float="right">
|
||||
<fo:block >
|
||||
<xsl:value-of select="/validation/xml/info/profile" />
|
||||
</fo:block>
|
||||
</fo:float>
|
||||
Erkannter Dokumenttyp:
|
||||
</fo:block>
|
||||
</fo:block>
|
||||
|
||||
<xsl:apply-templates select="/validation/pdf" />
|
||||
|
||||
<!--<xsl:call-template name="SubHeader" >
|
||||
<xsl:with-param name="text" select='"Konformitätsprüfung:"' />
|
||||
<xsl:with-param name="color" select='"black"' />
|
||||
</xsl:call-template>-->
|
||||
|
||||
<xsl:call-template name="SubHeader" >
|
||||
<xsl:with-param name="text" select="concat('Bewertung: ', $result_text)" />
|
||||
<xsl:with-param name="color" select="$xml_result_color" />
|
||||
</xsl:call-template>
|
||||
|
||||
<fo:block>Validierungsergebnisse im Detail:</fo:block>
|
||||
|
||||
<fo:table>
|
||||
<fo:table-column border-style="solid" />
|
||||
<fo:table-column border-style="solid" />
|
||||
<fo:table-column border-style="solid" />
|
||||
<fo:table-column column-width="70%" border-style="solid" />
|
||||
<fo:table-header>
|
||||
<fo:table-row background-color="#E0E0E0" font-weight="bold">
|
||||
<fo:table-cell>
|
||||
<fo:block>Type</fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell>
|
||||
<fo:block>Code</fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell>
|
||||
<fo:block>Schwere</fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell>
|
||||
<fo:block>Text</fo:block>
|
||||
</fo:table-cell>
|
||||
</fo:table-row>
|
||||
</fo:table-header>
|
||||
<fo:table-body>
|
||||
<xsl:apply-templates select="/validation/xml/messages" />
|
||||
</fo:table-body>
|
||||
</fo:table>
|
||||
|
||||
</fo:flow>
|
||||
</fo:page-sequence>
|
||||
</fo:root>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="notice|error">
|
||||
<fo:table-row font-size="12px" border-style="solid">
|
||||
<fo:table-cell number-rows-spanned="2">
|
||||
<fo:block>
|
||||
<xsl:value-of select="@type" />
|
||||
</fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell number-rows-spanned="2">
|
||||
<fo:block>
|
||||
<xsl:call-template name="SUBID" >
|
||||
<xsl:with-param name="myparam" select="substring-after(.,' [ID ')" />
|
||||
</xsl:call-template>
|
||||
</fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell number-rows-spanned="2">
|
||||
<fo:block >
|
||||
<xsl:choose>
|
||||
<xsl:when test="name() = 'error'">
|
||||
<xsl:attribute name="color">red</xsl:attribute>
|
||||
Fehler
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
Hinweis
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</fo:block>
|
||||
</fo:table-cell>
|
||||
<fo:table-cell>
|
||||
<fo:block>
|
||||
<xsl:if test="name() = 'error'">
|
||||
<xsl:attribute name="color">red</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="substring-before(.,' [ID')" />
|
||||
</fo:block>
|
||||
</fo:table-cell>
|
||||
</fo:table-row>
|
||||
<fo:table-row font-size="12px" border-style="solid">
|
||||
<fo:table-cell>
|
||||
<fo:block>
|
||||
<xsl:if test="name() = 'error'">
|
||||
<xsl:attribute name="color">red</xsl:attribute>
|
||||
</xsl:if>
|
||||
Pfad:
|
||||
<xsl:value-of select="@location" />
|
||||
</fo:block>
|
||||
</fo:table-cell>
|
||||
</fo:table-row>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="pdf">
|
||||
<xsl:call-template name="SubHeader" >
|
||||
<xsl:with-param name="text" select="concat('ZUGFeRD-PDF: ', $pdf_result_text)" />
|
||||
<xsl:with-param name="color" select='"black"' />
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="SubHeader">
|
||||
<xsl:param name="text" />
|
||||
<xsl:param name="color" />
|
||||
<fo:block color="{$color}" background-color="#E0E0E0" margin-bottom="10px" padding="3px" font-weight="bold" margin-top="10px">
|
||||
<xsl:value-of select="$text" />
|
||||
</fo:block>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="SUBID">
|
||||
<xsl:param name="myparam" />
|
||||
<xsl:variable name="myparam.end" select="substring-before($myparam, ']')"/>
|
||||
<xsl:value-of select="$myparam.end"/>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
@@ -1,235 +1,235 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:axf="http://www.antennahouse.com/names/XSL/Extensions"
|
||||
xmlns:xr="urn:ce.eu:en16931:2017:xoev-de:kosit:standard:xrechnung-1"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xrv="http://www.example.org/XRechnung-Viewer"
|
||||
xmlns:xrf="https://projekte.kosit.org/xrechnung/xrechnung-visualization/functions"
|
||||
version="2.0">
|
||||
|
||||
<!-- ==========================================================================
|
||||
== Schriften
|
||||
=========================================================================== -->
|
||||
|
||||
<xsl:variable name="fontSans">SourceSerifPro</xsl:variable>
|
||||
<xsl:variable name="fontSerif">SourceSerifPro</xsl:variable>
|
||||
|
||||
<xsl:variable name="amount-picture" select="xrf:_('amount-format')"/>
|
||||
<xsl:variable name="percentage-picture" select="xrf:_('percentage-format')"/>
|
||||
|
||||
|
||||
<!-- ==========================================================================
|
||||
== Attribute-Sets
|
||||
=========================================================================== -->
|
||||
|
||||
<!-- Fliesstext -->
|
||||
<xsl:attribute-set name="fliesstext">
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSans"/></xsl:attribute>
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="line-height">12pt</xsl:attribute>
|
||||
<xsl:attribute name="hyphenation-ladder-count">3</xsl:attribute>
|
||||
<xsl:attribute name="hyphenate">true</xsl:attribute>
|
||||
<xsl:attribute name="language">de</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H1 Marker -->
|
||||
<xsl:attribute-set name="marker">
|
||||
<xsl:attribute name="font-size">18pt</xsl:attribute>
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSerif"/></xsl:attribute>
|
||||
<xsl:attribute name="hyphenate">false</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H1 -->
|
||||
<xsl:attribute-set name="h1">
|
||||
<xsl:attribute name="font-size">18pt</xsl:attribute>
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSerif"/></xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">4mm</xsl:attribute>
|
||||
<xsl:attribute name="hyphenate">false</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H2-Container -->
|
||||
<xsl:attribute-set name="h2-container">
|
||||
<xsl:attribute name="border-top">0.5pt solid</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">2.5pt</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">4mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H2 -->
|
||||
<xsl:attribute-set name="h2">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSans"/></xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="border">0.5pt solid</xsl:attribute>
|
||||
<xsl:attribute name="padding">4pt 6pt</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
<xsl:attribute name="margin">0</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H3 -->
|
||||
<xsl:attribute-set name="h3">
|
||||
<xsl:attribute name="font-size">10pt</xsl:attribute>
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSans"/></xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">1mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">2mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-top">2mm</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Separator -->
|
||||
<xsl:attribute-set name="separator">
|
||||
<xsl:attribute name="margin-left">2mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">3mm</xsl:attribute>
|
||||
<xsl:attribute name="border-bottom">0.5pt dotted</xsl:attribute>
|
||||
<xsl:attribute name="color">#999999</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Wert-Felder -->
|
||||
<xsl:variable name="wertHG">#eeeeee</xsl:variable>
|
||||
<xsl:variable name="wert-legende-breite">28</xsl:variable>
|
||||
|
||||
<xsl:attribute-set name="wert-legende">
|
||||
<xsl:attribute name="font-size">7pt</xsl:attribute>
|
||||
<xsl:attribute name="line-height">10pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">1mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">1mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="wert-ausgabe">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="line-height">10pt</xsl:attribute>
|
||||
<xsl:attribute name="background-color"><xsl:value-of select="$wertHG"/></xsl:attribute>
|
||||
<xsl:attribute name="padding-top">1mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">1mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">2mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-together.within-column">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Rechnung-Felder -->
|
||||
<xsl:attribute-set name="rechnung-legende">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-steuer">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-wert">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">right</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">0mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-legende-summe">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.4mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
<xsl:attribute name="border-top">0.1pt solid #999999</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-steuer-summe">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.4mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
<xsl:attribute name="border-top">0.1pt solid #999999</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-wert-summe">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="text-align">right</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.4mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">0mm</xsl:attribute>
|
||||
<xsl:attribute name="border-top">0.1pt solid #999999</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Box-Container -->
|
||||
<xsl:attribute-set name="box-container-kapitel">
|
||||
<xsl:attribute name="margin-bottom">10mm</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="box-container-bereich">
|
||||
<xsl:attribute name="margin-bottom">2mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-together.within-page">always</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="box-container-inner">
|
||||
<xsl:attribute name="margin-bottom">2mm</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Tabular invoice lines -->
|
||||
<xsl:attribute-set name="invoicelines-table">
|
||||
<xsl:attribute name="padding-left">2pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">2pt</xsl:attribute>
|
||||
<xsl:attribute name="width">100%</xsl:attribute>
|
||||
<xsl:attribute name="table-layout">fixed</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">2mm</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="invoicelines-table-header">
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="invoicelines-table-row">
|
||||
<!-- Nested sub-invoice lines will recursively decrease font-size -->
|
||||
<xsl:attribute name="font-size" select="if (self::xr:SUB_INVOICE_LINE) then '90%' else '100%'"/>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="invoicelines-nested-info">
|
||||
<xsl:attribute name="font-size">80%</xsl:attribute>
|
||||
<xsl:attribute name="font-style">italic</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="invoicelines-allowances-table">
|
||||
<xsl:attribute name="padding-left">2pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">2pt</xsl:attribute>
|
||||
<xsl:attribute name="width">100%</xsl:attribute>
|
||||
<xsl:attribute name="table-layout">fixed</xsl:attribute>
|
||||
<xsl:attribute name="font-size">80%</xsl:attribute>
|
||||
<xsl:attribute name="font-style">italic</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
</xsl:stylesheet>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:axf="http://www.antennahouse.com/names/XSL/Extensions"
|
||||
xmlns:xr="urn:ce.eu:en16931:2017:xoev-de:kosit:standard:xrechnung-1"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xrv="http://www.example.org/XRechnung-Viewer"
|
||||
xmlns:xrf="https://projekte.kosit.org/xrechnung/xrechnung-visualization/functions"
|
||||
version="2.0">
|
||||
|
||||
<!-- ==========================================================================
|
||||
== Schriften
|
||||
=========================================================================== -->
|
||||
|
||||
<xsl:variable name="fontSans">SourceSansPro</xsl:variable>
|
||||
<xsl:variable name="fontSerif">SourceSerifPro</xsl:variable>
|
||||
|
||||
<xsl:variable name="amount-picture" select="xrf:_('amount-format')"/>
|
||||
<xsl:variable name="percentage-picture" select="xrf:_('percentage-format')"/>
|
||||
|
||||
|
||||
<!-- ==========================================================================
|
||||
== Attribute-Sets
|
||||
=========================================================================== -->
|
||||
|
||||
<!-- Fliesstext -->
|
||||
<xsl:attribute-set name="fliesstext">
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSans"/></xsl:attribute>
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="line-height">12pt</xsl:attribute>
|
||||
<xsl:attribute name="hyphenation-ladder-count">3</xsl:attribute>
|
||||
<xsl:attribute name="hyphenate">true</xsl:attribute>
|
||||
<xsl:attribute name="language">de</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H1 Marker -->
|
||||
<xsl:attribute-set name="marker">
|
||||
<xsl:attribute name="font-size">18pt</xsl:attribute>
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSerif"/></xsl:attribute>
|
||||
<xsl:attribute name="hyphenate">false</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H1 -->
|
||||
<xsl:attribute-set name="h1">
|
||||
<xsl:attribute name="font-size">18pt</xsl:attribute>
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSerif"/></xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">4mm</xsl:attribute>
|
||||
<xsl:attribute name="hyphenate">false</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H2-Container -->
|
||||
<xsl:attribute-set name="h2-container">
|
||||
<xsl:attribute name="border-top">0.5pt solid</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">2.5pt</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">4mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H2 -->
|
||||
<xsl:attribute-set name="h2">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSans"/></xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="border">0.5pt solid</xsl:attribute>
|
||||
<xsl:attribute name="padding">4pt 6pt</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
<xsl:attribute name="margin">0</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- H3 -->
|
||||
<xsl:attribute-set name="h3">
|
||||
<xsl:attribute name="font-size">10pt</xsl:attribute>
|
||||
<xsl:attribute name="font-family"><xsl:value-of select="$fontSans"/></xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">1mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">2mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-top">2mm</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Separator -->
|
||||
<xsl:attribute-set name="separator">
|
||||
<xsl:attribute name="margin-left">2mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">3mm</xsl:attribute>
|
||||
<xsl:attribute name="border-bottom">0.5pt dotted</xsl:attribute>
|
||||
<xsl:attribute name="color">#999999</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Wert-Felder -->
|
||||
<xsl:variable name="wertHG">#eeeeee</xsl:variable>
|
||||
<xsl:variable name="wert-legende-breite">28</xsl:variable>
|
||||
|
||||
<xsl:attribute-set name="wert-legende">
|
||||
<xsl:attribute name="font-size">7pt</xsl:attribute>
|
||||
<xsl:attribute name="line-height">10pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">1mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">1mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="wert-ausgabe">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="line-height">10pt</xsl:attribute>
|
||||
<xsl:attribute name="background-color"><xsl:value-of select="$wertHG"/></xsl:attribute>
|
||||
<xsl:attribute name="padding-top">1mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">1mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">2mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-together.within-column">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Rechnung-Felder -->
|
||||
<xsl:attribute-set name="rechnung-legende">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-steuer">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-wert">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">right</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">0mm</xsl:attribute>
|
||||
<xsl:attribute name="margin-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-legende-summe">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.4mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
<xsl:attribute name="border-top">0.1pt solid #999999</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-steuer-summe">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="text-align">left</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.4mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">1mm</xsl:attribute>
|
||||
<xsl:attribute name="border-top">0.1pt solid #999999</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="rechnung-wert-summe">
|
||||
<xsl:attribute name="font-size">9pt</xsl:attribute>
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
<xsl:attribute name="text-align">right</xsl:attribute>
|
||||
<xsl:attribute name="padding-top">0.4mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-bottom">0.2mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-left">0mm</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">0mm</xsl:attribute>
|
||||
<xsl:attribute name="border-top">0.1pt solid #999999</xsl:attribute>
|
||||
<xsl:attribute name="keep-with-next.within-page">always</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Box-Container -->
|
||||
<xsl:attribute-set name="box-container-kapitel">
|
||||
<xsl:attribute name="margin-bottom">10mm</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="box-container-bereich">
|
||||
<xsl:attribute name="margin-bottom">2mm</xsl:attribute>
|
||||
<xsl:attribute name="keep-together.within-page">always</xsl:attribute>
|
||||
<xsl:attribute name="span">all</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="box-container-inner">
|
||||
<xsl:attribute name="margin-bottom">2mm</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<!-- Tabular invoice lines -->
|
||||
<xsl:attribute-set name="invoicelines-table">
|
||||
<xsl:attribute name="padding-left">2pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">2pt</xsl:attribute>
|
||||
<xsl:attribute name="width">100%</xsl:attribute>
|
||||
<xsl:attribute name="table-layout">fixed</xsl:attribute>
|
||||
<xsl:attribute name="margin-bottom">2mm</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="invoicelines-table-header">
|
||||
<xsl:attribute name="font-weight">bold</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="invoicelines-table-row">
|
||||
<!-- Nested sub-invoice lines will recursively decrease font-size -->
|
||||
<xsl:attribute name="font-size" select="if (self::xr:SUB_INVOICE_LINE) then '90%' else '100%'"/>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="invoicelines-nested-info">
|
||||
<xsl:attribute name="font-size">80%</xsl:attribute>
|
||||
<xsl:attribute name="font-style">italic</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
<xsl:attribute-set name="invoicelines-allowances-table">
|
||||
<xsl:attribute name="padding-left">2pt</xsl:attribute>
|
||||
<xsl:attribute name="padding-right">2pt</xsl:attribute>
|
||||
<xsl:attribute name="width">100%</xsl:attribute>
|
||||
<xsl:attribute name="table-layout">fixed</xsl:attribute>
|
||||
<xsl:attribute name="font-size">80%</xsl:attribute>
|
||||
<xsl:attribute name="font-style">italic</xsl:attribute>
|
||||
</xsl:attribute-set>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
||||
@@ -1,289 +1,313 @@
|
||||
/**
|
||||
* *********************************************************************
|
||||
* <p>
|
||||
* Copyright 2019 Jochen Staerk
|
||||
* <p>
|
||||
* Use is subject to license terms.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* <p>
|
||||
* **********************************************************************
|
||||
*/
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.mustangproject.util.ByteArraySearcher;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@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";
|
||||
|
||||
public void testCIIVisualizationBasic() {
|
||||
|
||||
// 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(), ZUGFeRDVisualizer.Language.FR)
|
||||
.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...
|
||||
|
||||
} 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);
|
||||
}
|
||||
|
||||
public void testCIIVisualizationExtended() {
|
||||
|
||||
// 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(), ZUGFeRDVisualizer.Language.DE).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...
|
||||
|
||||
} 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);
|
||||
}
|
||||
|
||||
public void testUBLCreditNoteVisualizationBasic() {
|
||||
|
||||
// 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(), ZUGFeRDVisualizer.Language.EN).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...
|
||||
|
||||
} 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);
|
||||
}
|
||||
|
||||
|
||||
public void testUBLVisualizationBasic() {
|
||||
|
||||
// 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(), ZUGFeRDVisualizer.Language.EN).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...
|
||||
|
||||
} 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);
|
||||
}
|
||||
|
||||
public void testPDFVisualizationCII() {
|
||||
|
||||
File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml");
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
try {
|
||||
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
|
||||
} catch (IOException e) {
|
||||
fail("IOException should not occur");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPDFVisualizationUBL() {
|
||||
|
||||
File UBLinputFile = getResourceAsFile("ubl/01.01a-INVOICE.ubl.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());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
|
||||
} catch (IOException e) {
|
||||
fail("IOException should not occur");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPDFVisualizationUBLCreditNote() {
|
||||
|
||||
File UBLinputFile = getResourceAsFile("ubl/UBL-CreditNote-2.1-Example.ubl.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());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
|
||||
} catch (IOException e) {
|
||||
fail("IOException should not occur");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* *********************************************************************
|
||||
* <p>
|
||||
* Copyright 2019 Jochen Staerk
|
||||
* <p>
|
||||
* Use is subject to license terms.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* <p>
|
||||
* **********************************************************************
|
||||
*/
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.mustangproject.util.ByteArraySearcher;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@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";
|
||||
|
||||
public void testCIIVisualizationBasic() {
|
||||
|
||||
// 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(), ZUGFeRDVisualizer.Language.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(" ", "");
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
assertNotNull(result);
|
||||
// Reading ZUGFeRD
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
public void testCIIVisualizationExtended() {
|
||||
|
||||
// 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(), ZUGFeRDVisualizer.Language.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(" ", "");
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
assertNotNull(result);
|
||||
// Reading ZUGFeRD
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
public void testUBLCreditNoteVisualizationBasic() {
|
||||
|
||||
// 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(), ZUGFeRDVisualizer.Language.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(" ", "");
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
assertNotNull(result);
|
||||
// Reading ZUGFeRD
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
|
||||
public void testUBLVisualizationBasic() {
|
||||
|
||||
// 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(), ZUGFeRDVisualizer.Language.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(" ", "");
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
assertNotNull(result);
|
||||
// Reading ZUGFeRD
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
public void testPDFVisualizationCII() {
|
||||
|
||||
File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml");
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
try {
|
||||
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
|
||||
} catch (IOException e) {
|
||||
fail("IOException should not occur");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPDFVisualizationUBL() {
|
||||
|
||||
File UBLinputFile = getResourceAsFile("ubl/01.01a-INVOICE.ubl.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());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
|
||||
} catch (IOException e) {
|
||||
fail("IOException should not occur");
|
||||
}
|
||||
}
|
||||
|
||||
public void testPDFVisualizationUBLCreditNote() {
|
||||
|
||||
File UBLinputFile = getResourceAsFile("ubl/UBL-CreditNote-2.1-Example.ubl.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());
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
|
||||
} catch (IOException e) {
|
||||
fail("IOException should not occur");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ public class ZF2PushTest extends TestCase {
|
||||
.setNumber(number)
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance(new BigDecimal("0.1"))))
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50))))
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(2.0)).addCharge(new Charge(new BigDecimal(1)).setReasonCode("AK")))
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(2.0)).addCharge(new Charge(new BigDecimal(1)).setReasonCode("ABK")))
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addCharge(new Charge(new BigDecimal(1))).addAllowance(new Allowance(new BigDecimal("1"))))
|
||||
);
|
||||
|
||||
@@ -805,24 +805,5 @@ public class ZF2PushTest extends TestCase {
|
||||
match the read grand total */
|
||||
}
|
||||
}
|
||||
public void testRead() {
|
||||
|
||||
|
||||
|
||||
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("\\Users\\jstaerk\\temp\\1424413_anonymized.xml");
|
||||
try {
|
||||
Invoice i = zii.extractInvoice();
|
||||
|
||||
TransactionCalculator tc=new TransactionCalculator(i);
|
||||
assertEquals(0,tc.getGrandTotal().compareTo(new BigDecimal("442.83")));
|
||||
|
||||
} 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 */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.15.2-SNAPSHOT</version>
|
||||
<version>2.15.3-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Mustang</name>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.15.2-SNAPSHOT</version>
|
||||
<version>2.15.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.mustangproject</groupId>
|
||||
@@ -11,7 +11,7 @@
|
||||
<name>Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung)</name>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
<version>2.15.2-SNAPSHOT</version>
|
||||
<version>2.15.3-SNAPSHOT</version>
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- for jargs -->
|
||||
@@ -38,7 +38,7 @@
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>library</artifactId>
|
||||
<version>2.15.2-SNAPSHOT</version>
|
||||
<version>2.15.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dom4j</groupId>
|
||||
|
||||
Reference in New Issue
Block a user