feature: pdf visualization translations

This commit is contained in:
Aaron
2026-03-20 16:25:08 +01:00
parent 85457033fa
commit 08b3fbc227
5 changed files with 633 additions and 317 deletions

View File

@@ -104,8 +104,7 @@ public class Main {
+ " [--out <filename>]: set output HTML file\n" + " [--out <filename>]: set output HTML file\n"
+ " --action pdf convert XML to PDF \n" + " --action pdf convert XML to PDF \n"
+ " [--source <filename>]: set input XML file\n" + " [--source <filename>]: set input XML file\n"
+ " [--out <filename>]: set output PDF file\n" + " [--out <filename>]: set output PDF file\n";
;
} }
private static void printHelp() { private static void printHelp() {
@@ -162,8 +161,10 @@ public class Main {
* Prompts the user for a input or output filename * Prompts the user for a input or output filename
* *
* @param prompt the text the user is asked * @param prompt the text the user is asked
* @param defaultFilename a default Filename. Passing an empty string indicates that specifying a file is optional * @param defaultFilename a default Filename. Passing an empty string
* @param expectedExtension will warn if filename does not match expected file extension, "or" possible with e.g. pdf|xml * indicates that specifying a file is optional
* @param expectedExtension will warn if filename does not match expected file
* extension, "or" possible with e.g. pdf|xml
* @param ensureFileExists will warn if file does NOT exist (for input files) * @param ensureFileExists will warn if file does NOT exist (for input files)
* @param ensureFileNotExists will warn if file DOES exist (for output files) * @param ensureFileNotExists will warn if file DOES exist (for output files)
* @return String * @return String
@@ -270,6 +271,7 @@ public class Main {
/*** /***
* converts from CII to UBL * converts from CII to UBL
*
* @param xmlName the name of the xml file * @param xmlName the name of the xml file
* @param outName the name of the output file * @param outName the name of the output file
* @throws IOException * @throws IOException
@@ -309,7 +311,8 @@ public class Main {
} }
// Plain Java // Plain Java
// based on https://mkyong.com/java/how-to-convert-inputstream-to-string-in-java/ // based on
// https://mkyong.com/java/how-to-convert-inputstream-to-string-in-java/
private static String convertInputStreamToString(InputStream is) { private static String convertInputStreamToString(InputStream is) {
try (InputStream inputStream = is) { try (InputStream inputStream = is) {
int DEFAULT_BUFFER_SIZE = 8192; int DEFAULT_BUFFER_SIZE = 8192;
@@ -333,7 +336,9 @@ public class Main {
/*** /***
* the main function of the commandline tool... * the main function of the commandline tool...
* @param args the commandline args, see also https://www.mustangproject.org/commandline/#verbose *
* @param args the commandline args, see also
* https://www.mustangproject.org/commandline/#verbose
*/ */
public static void main(String[] args) { public static void main(String[] args) {
try { try {
@@ -347,12 +352,14 @@ public class Main {
options.addOption(new Option("f", "format", true, "which format to output")); options.addOption(new Option("f", "format", true, "which format to output"));
options.addOption(new Option("version", "version", true, "which version of the standard to use")); options.addOption(new Option("version", "version", true, "which version of the standard to use"));
options.addOption(new Option("profile", "profile", true, "which profile of the standard to use")); options.addOption(new Option("profile", "profile", true, "which profile of the standard to use"));
options.addOption(new Option("no-additional-attachments", "no-additional-attachments", false, "prevent prompting for attachments")); options.addOption(new Option("no-additional-attachments", "no-additional-attachments", false,
"prevent prompting for attachments"));
Option attachmentOpt = new Option("attachments", "attachments", true, "File attachments"); Option attachmentOpt = new Option("attachments", "attachments", true, "File attachments");
attachmentOpt.setValueSeparator(','); attachmentOpt.setValueSeparator(',');
attachmentOpt.setArgs(Option.UNLIMITED_VALUES); attachmentOpt.setArgs(Option.UNLIMITED_VALUES);
options.addOption(attachmentOpt); options.addOption(attachmentOpt);
Option excludeOpt = new Option("exclude", "exclude", true, "Files to exclude from recursive directory traversal"); Option excludeOpt = new Option("exclude", "exclude", true,
"Files to exclude from recursive directory traversal");
excludeOpt.setValueSeparator(','); excludeOpt.setValueSeparator(',');
excludeOpt.setArgs(Option.UNLIMITED_VALUES); excludeOpt.setArgs(Option.UNLIMITED_VALUES);
options.addOption(excludeOpt); options.addOption(excludeOpt);
@@ -361,8 +368,10 @@ public class Main {
options.addOption(new Option("language", "language", true, "output language (en, de or fr)")); options.addOption(new Option("language", "language", true, "output language (en, de or fr)"));
options.addOption(new Option("out", "out", true, "which output file to write to")); options.addOption(new Option("out", "out", true, "which output file to write to"));
options.addOption(new Option("no-notices", "no-notices", false, "suppress non-fatal errors")); options.addOption(new Option("no-notices", "no-notices", false, "suppress non-fatal errors"));
options.addOption(new Option("logAppend", "logAppend", true, "freeform text to be appended to log messages")); options.addOption(
options.addOption(new Option("disable-file-logging", "disable-file-logging", false, "suppress logging to file")); new Option("logAppend", "logAppend", true, "freeform text to be appended to log messages"));
options.addOption(
new Option("disable-file-logging", "disable-file-logging", false, "suppress logging to file"));
options.addOption(new Option("d", "directory", true, "which directory to operate on")); options.addOption(new Option("d", "directory", true, "which directory to operate on"));
options.addOption(new Option("i", "ignorefileextension", false, "ignore non-matching file extensions")); 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("l", "listfromstdin", false, "take list of files from commandline"));
@@ -398,11 +407,10 @@ public class Main {
String[] attachmentFilenames = cmd.hasOption("attachments") ? cmd.getOptionValues("attachments") : null; String[] attachmentFilenames = cmd.hasOption("attachments") ? cmd.getOptionValues("attachments") : null;
String[] excludedFilenames = cmd.hasOption("exclude") ? cmd.getOptionValues("exclude") : null; String[] excludedFilenames = cmd.hasOption("exclude") ? cmd.getOptionValues("exclude") : null;
ArrayList<FileAttachment> attachments = new ArrayList<>(); ArrayList<FileAttachment> attachments = new ArrayList<>();
/* /*
setting system property to disable FILE appender and * setting system property to disable FILE appender and
suppress creation of files and folders. * suppress creation of files and folders.
*/ */
System.setProperty("FILE_APPENDER_ENABLED", ((Boolean) (disableFileLogging == false)).toString()); System.setProperty("FILE_APPENDER_ENABLED", ((Boolean) (disableFileLogging == false)).toString());
@@ -411,14 +419,17 @@ public class Main {
if (helpRequested) { if (helpRequested) {
printHelp(); printHelp();
optionsRecognized = true; optionsRecognized = true;
} /* else if ((action!=null)&&(action.equals("license"))) { } /*
printLicense(); * else if ((action!=null)&&(action.equals("license"))) {
optionsRecognized=true; * printLicense();
} */ else if ((action != null) && (action.equals("metrics"))) { * optionsRecognized=true;
* }
*/ else if ((action != null) && (action.equals("metrics"))) {
performMetrics(directoryName, filesFromStdIn, ignoreFileExt); performMetrics(directoryName, filesFromStdIn, ignoreFileExt);
optionsRecognized = true; optionsRecognized = true;
} else if ((action != null) && (action.equals("combine"))) { } else if ((action != null) && (action.equals("combine"))) {
performCombine(sourceName, sourceXMLName, outName, format, zugferdVersion, zugferdProfile, ignoreFileExt, attachmentFilenames, attachments, noAttachments); performCombine(sourceName, sourceXMLName, outName, format, zugferdVersion, zugferdProfile,
ignoreFileExt, attachmentFilenames, attachments, noAttachments);
optionsRecognized = true; optionsRecognized = true;
} else if ((action != null) && (action.equals("extract"))) { } else if ((action != null) && (action.equals("extract"))) {
performExtract(sourceName, outName); performExtract(sourceName, outName);
@@ -439,7 +450,8 @@ public class Main {
performUBL(sourceName, outName); performUBL(sourceName, outName);
optionsRecognized = true; optionsRecognized = true;
} else if ((action != null) && (action.equals("validate"))) { } else if ((action != null) && (action.equals("validate"))) {
optionsRecognized = performValidate(sourceName, noNotices, cmd.getOptionValue("logAppend"), LogAsPDF); optionsRecognized = performValidate(sourceName, noNotices, cmd.getOptionValue("logAppend"),
LogAsPDF);
} else if ((action != null) && (action.equals("validateExpectValid"))) { } else if ((action != null) && (action.equals("validateExpectValid"))) {
optionsRecognized = performValidateExpect(true, directoryName, excludedFilenames); optionsRecognized = performValidateExpect(true, directoryName, excludedFilenames);
} else if ((action != null) && (action.equals("validateExpectInvalid"))) { } else if ((action != null) && (action.equals("validateExpectInvalid"))) {
@@ -466,7 +478,8 @@ public class Main {
} }
private static boolean performValidate(String sourceName, boolean noNotices, String logAppend, boolean createLogAsPDF) { private static boolean performValidate(String sourceName, boolean noNotices, String logAppend,
boolean createLogAsPDF) {
boolean optionsRecognized; boolean optionsRecognized;
if (sourceName == null) { if (sourceName == null) {
sourceName = getFilenameFromUser("Source PDF or XML", "invoice.pdf", "pdf|xml", true, false); sourceName = getFilenameFromUser("Source PDF or XML", "invoice.pdf", "pdf|xml", true, false);
@@ -516,7 +529,6 @@ public class Main {
return true; return true;
} }
private static void performConvert(String pdfName, String outName) throws IOException { private static void performConvert(String pdfName, String outName) throws IOException {
/* /*
* ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory() * ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory()
@@ -579,7 +591,8 @@ public class Main {
} }
private static void performCombine(String pdfName, String xmlName, String outName, String format, String zfVersion, private static void performCombine(String pdfName, String xmlName, String outName, String format, String zfVersion,
String zfProfile, Boolean ignoreInputErrors, String[] attachmentFilenames, ArrayList<FileAttachment> attachments, Boolean noAttachments) throws Exception { String zfProfile, Boolean ignoreInputErrors, String[] attachmentFilenames,
ArrayList<FileAttachment> attachments, Boolean noAttachments) throws Exception {
/* /*
* ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory() * ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory()
* .setProducer("toecount") .setCreator(System.getProperty("user.name")) * .setProducer("toecount") .setCreator(System.getProperty("user.name"))
@@ -611,11 +624,13 @@ public class Main {
byte attachmentContents[] = null; byte attachmentContents[] = null;
String attachmentFilename, attachmentMime; String attachmentFilename, attachmentMime;
if (!noAttachments) { if (!noAttachments) {
attachmentFilename = getFilenameFromUser("Additional file attachments filename (empty for none)", "", "pdf", true, false); attachmentFilename = getFilenameFromUser("Additional file attachments filename (empty for none)",
"", "pdf", true, false);
if (attachmentFilename.length() != 0) { if (attachmentFilename.length() != 0) {
attachmentContents = Files.readAllBytes(Paths.get(attachmentFilename)); attachmentContents = Files.readAllBytes(Paths.get(attachmentFilename));
attachmentMime = Files.probeContentType(Paths.get(attachmentFilename)); attachmentMime = Files.probeContentType(Paths.get(attachmentFilename));
attachments.add(new FileAttachment(attachmentFilename, attachmentMime, "Data", attachmentContents)); attachments.add(
new FileAttachment(attachmentFilename, attachmentMime, "Data", attachmentContents));
} }
} }
} else { } else {
@@ -624,15 +639,17 @@ public class Main {
if (!attachmentFilename.isEmpty()) { if (!attachmentFilename.isEmpty()) {
byte[] attachmentContents = Files.readAllBytes(Paths.get(attachmentFilename)); byte[] attachmentContents = Files.readAllBytes(Paths.get(attachmentFilename));
String attachmentMime = Files.probeContentType(Paths.get(attachmentFilename)); String attachmentMime = Files.probeContentType(Paths.get(attachmentFilename));
attachments.add(new FileAttachment(attachmentFilename, attachmentMime, "Data", attachmentContents)); attachments.add(
new FileAttachment(attachmentFilename, attachmentMime, "Data", attachmentContents));
} }
} }
} }
if (format == null) { if (format == null) {
try { try {
format = getStringFromUser("Format (fx=Factur-X, zf=ZUGFeRD, ox=Order-X, da=Cross Industry Despatch Advice)", "fx", "fx|zf|ox|da"); format = getStringFromUser(
"Format (fx=Factur-X, zf=ZUGFeRD, ox=Order-X, da=Cross Industry Despatch Advice)", "fx",
"fx|zf|ox|da");
} catch (Exception e) { } catch (Exception e) {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
} }
@@ -659,7 +676,9 @@ public class Main {
zfProfile = getStringFromUser("Profile (p)ilot", "p", "P|p"); zfProfile = getStringFromUser("Profile (p)ilot", "p", "P|p");
} else { } else {
zfProfile = getStringFromUser( zfProfile = getStringFromUser(
"Profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n" + "[C]IUS, [E]N16931, EX[T]ENDED or [X]RECHNUNG", "E", "Profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n"
+ "[C]IUS, [E]N16931, EX[T]ENDED or [X]RECHNUNG",
"E",
"M|m|W|w|B|b|C|c|E|e|T|t|X|x|"); "M|m|W|w|B|b|C|c|E|e|T|t|X|x|");
} }
} catch (Exception e) { } catch (Exception e) {
@@ -670,7 +689,6 @@ public class Main {
} }
zfProfile = zfProfile.toLowerCase(); zfProfile = zfProfile.toLowerCase();
// Verify params // Verify params
ensureFileExists(pdfName); ensureFileExists(pdfName);
ensureFileExists(xmlName); ensureFileExists(xmlName);
@@ -738,7 +756,8 @@ public class Main {
} else { } else {
if (format.equals("fx")) { if (format.equals("fx")) {
zfIntVersion = 2;// actually we are talking of generation, not version zfIntVersion = 2;// actually we are talking of generation, not version
// so even if someone correctly requested factur-x 1 internally we call it zugferd 2 :-( // so even if someone correctly requested factur-x 1 internally we call it
// zugferd 2 :-(
} }
ze = new ZUGFeRDExporterFromPDFA(); ze = new ZUGFeRDExporterFromPDFA();
if (ignoreInputErrors) { if (ignoreInputErrors) {
@@ -755,9 +774,9 @@ public class Main {
ze.disableFacturX(); ze.disableFacturX();
} }
for (FileAttachment attachment : attachments) { for (FileAttachment attachment : attachments) {
ze.attachFile(attachment.getFilename(), attachment.getData(), attachment.getMimetype(), attachment.getRelation()); ze.attachFile(attachment.getFilename(), attachment.getData(), attachment.getMimetype(),
attachment.getRelation());
} }
ze.setXML(Files.readAllBytes(Paths.get(xmlName))); ze.setXML(Files.readAllBytes(Paths.get(xmlName)));
@@ -818,7 +837,6 @@ public class Main {
} else { } else {
System.out.println("ZUGFeRD XML source set to " + sourceName); System.out.println("ZUGFeRD XML source set to " + sourceName);
} }
if (!intoPDF) {
if (lang == null) { if (lang == null) {
try { try {
lang = getStringFromUser("Output language", "en", "en|de|fr"); lang = getStringFromUser("Output language", "en", "en|de|fr");
@@ -828,7 +846,6 @@ public class Main {
} else { } else {
System.out.println("Output language set to " + lang); System.out.println("Output language set to " + lang);
} }
}
if (outName == null) { if (outName == null) {
String defaultFilename = "factur-x.html"; String defaultFilename = "factur-x.html";
@@ -855,7 +872,6 @@ public class Main {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
String xml = null; String xml = null;
try { try {
if (!intoPDF) {
ZUGFeRDVisualizer.Language langCode = ZUGFeRDVisualizer.Language.EN; ZUGFeRDVisualizer.Language langCode = ZUGFeRDVisualizer.Language.EN;
if (lang.equalsIgnoreCase("de")) { if (lang.equalsIgnoreCase("de")) {
langCode = ZUGFeRDVisualizer.Language.DE; langCode = ZUGFeRDVisualizer.Language.DE;
@@ -863,10 +879,11 @@ public class Main {
if (lang.equalsIgnoreCase("fr")) { if (lang.equalsIgnoreCase("fr")) {
langCode = ZUGFeRDVisualizer.Language.FR; langCode = ZUGFeRDVisualizer.Language.FR;
} }
if (!intoPDF) {
xml = zvi.visualize(sourceName, langCode); xml = zvi.visualize(sourceName, langCode);
Files.write(Paths.get(outName), xml.getBytes()); Files.write(Paths.get(outName), xml.getBytes());
} else { } else {
zvi.toPDF(sourceName, outName); zvi.toPDF(sourceName, outName, langCode);
} }
} catch (Exception e) { } catch (Exception e) {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
@@ -880,13 +897,13 @@ public class Main {
ExportResource("/xrechnung-viewer.css"); ExportResource("/xrechnung-viewer.css");
ExportResource("/xrechnung-viewer.js"); ExportResource("/xrechnung-viewer.js");
System.out.println("xrechnung-viewer.css and xrechnung-viewer.js written as well (to local working dir)"); System.out
.println("xrechnung-viewer.css and xrechnung-viewer.js written as well (to local working dir)");
} catch (Exception e) { } catch (Exception e) {
LOGGER.error(e.getMessage(), e); LOGGER.error(e.getMessage(), e);
} }
} }
} }
/** /**
@@ -894,11 +911,14 @@ public class Main {
* *
* @param resourceName ie.: "/SmartLibrary.dll" * @param resourceName ie.: "/SmartLibrary.dll"
* @return The path to the exported resource * @return The path to the exported resource
* @throws Exception e.g. if the specified resource does not exist at the specified location * @throws Exception e.g. if the specified resource does not exist at the
* specified location
*/ */
static public String ExportResource(String resourceName) throws Exception { static public String ExportResource(String resourceName) throws Exception {
String jarFolder; String jarFolder;
try (InputStream stream = Main.class.getResourceAsStream(resourceName)) {//note that each / is a directory down in the "jar tree" been the jar the root of the tree try (InputStream stream = Main.class.getResourceAsStream(resourceName)) {// note that each / is a directory down
// in the "jar tree" been the jar
// the root of the tree
if (stream == null) { if (stream == null) {
throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file."); throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file.");
} }

View File

@@ -47,8 +47,6 @@ import javax.xml.transform.stream.StreamSource;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -252,7 +250,7 @@ public class ZUGFeRDVisualizer {
} }
} }
protected String toFOP(String xmlFilename) protected String toFOP(String xmlFilename, Language lang)
throws IOException, TransformerException, ParserConfigurationException { throws IOException, TransformerException, ParserConfigurationException {
EStandard theStandard; EStandard theStandard;
try (FileInputStream fis = new FileInputStream(xmlFilename)) { try (FileInputStream fis = new FileInputStream(xmlFilename)) {
@@ -260,11 +258,11 @@ public class ZUGFeRDVisualizer {
} }
try (FileInputStream fis = new FileInputStream(xmlFilename)) { try (FileInputStream fis = new FileInputStream(xmlFilename)) {
return toFOP(fis, theStandard); return toFOP(fis, theStandard, lang);
} }
} }
protected String toFOP(InputStream is, EStandard theStandard) protected String toFOP(InputStream is, EStandard theStandard, Language lang)
throws TransformerException, IOException { throws TransformerException, IOException {
try { try {
@@ -291,12 +289,16 @@ public class ZUGFeRDVisualizer {
Optional<InputStream> in = copyStream(iaos); Optional<InputStream> in = copyStream(iaos);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (in.isPresent()) { if (in.isPresent()) {
applyXSLTToPDF(in.get(), baos); applyXSLTToPDF(in.get(), baos, lang);
} }
return baos.toString(StandardCharsets.UTF_8); return baos.toString(StandardCharsets.UTF_8);
} }
public void toPDF(String xmlFilename, String pdfFilename) { public void toPDF(String xmlFilename, String pdfFilename) {
toPDF(xmlFilename, pdfFilename, Language.DE);
}
public void toPDF(String xmlFilename, String pdfFilename, Language lang) {
// the writing part // the writing part
File XMLinputFile = new File(xmlFilename); File XMLinputFile = new File(xmlFilename);
@@ -307,7 +309,7 @@ public class ZUGFeRDVisualizer {
out from git with arbitrary options (which may include CSRF changes) out from git with arbitrary options (which may include CSRF changes)
*/ */
try { try {
fopInput = this.toFOP(XMLinputFile.getAbsolutePath()); fopInput = this.toFOP(XMLinputFile.getAbsolutePath(), lang);
} catch (TransformerException | IOException | ParserConfigurationException e) { } catch (TransformerException | IOException | ParserConfigurationException e) {
LOGGER.error("Failed to apply FOP", e); LOGGER.error("Failed to apply FOP", e);
} }
@@ -323,6 +325,10 @@ public class ZUGFeRDVisualizer {
} }
public byte[] toPDF(String xmlContent) { public byte[] toPDF(String xmlContent) {
return toPDF(xmlContent, Language.DE);
}
public byte[] toPDF(String xmlContent, Language lang) {
String fopInput = null; String fopInput = null;
@@ -334,7 +340,7 @@ public class ZUGFeRDVisualizer {
EStandard theStandard = findOutStandardFromRootNode(fis); EStandard theStandard = findOutStandardFromRootNode(fis);
fis = new ByteArrayInputStream(xmlContent.getBytes(StandardCharsets.UTF_8));//rewind :-( fis = new ByteArrayInputStream(xmlContent.getBytes(StandardCharsets.UTF_8));//rewind :-(
fopInput = toFOP(fis, theStandard); fopInput = toFOP(fis, theStandard, lang);
} catch (TransformerException | IOException | ParserConfigurationException e) { } catch (TransformerException | IOException | ParserConfigurationException e) {
LOGGER.error("Failed to apply FOP", e); LOGGER.error("Failed to apply FOP", e);
} }
@@ -470,9 +476,10 @@ public class ZUGFeRDVisualizer {
xmlFile.close(); xmlFile.close();
} }
protected void applyXSLTToPDF(final InputStream xmlFile, final OutputStream PDFOutstream) protected void applyXSLTToPDF(final InputStream xmlFile, final OutputStream PDFOutstream, Language lang)
throws TransformerException, IOException { throws TransformerException, IOException {
Transformer transformer = mXsltPDFTemplate.newTransformer(); Transformer transformer = mXsltPDFTemplate.newTransformer();
transformer.setParameter("lang", lang.name().toLowerCase());
transformer.transform(new StreamSource(xmlFile), new StreamResult(PDFOutstream)); transformer.transform(new StreamSource(xmlFile), new StreamResult(PDFOutstream));
xmlFile.close(); xmlFile.close();

View File

@@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8"?>
<properties>
<entry key="xr:Buyer_reference" id="BT-10">Référence acheteur</entry>
<entry key="xr:Buyer_name" id="BT-44">Nom</entry>
<entry key="xr:Buyer_address_line_1" id="BT-50">Adresse ligne 1</entry>
<entry key="xr:Buyer_address_line_2" id="BT-51">Adresse ligne 2</entry>
<entry key="xr:Buyer_address_line_3" id="BT-163">Adresse ligne 3</entry>
<entry key="xr:Buyer_post_code" id="BT-53">Code postal</entry>
<entry key="xr:Buyer_city" id="BT-52">Ville</entry>
<entry key="xr:Buyer_country_code" id="BT-55">Code pays</entry>
<entry key="xr:Buyer_identifier" id="BT-46">Identifiant</entry>
<entry key="xr:Buyer_identifier/@scheme_identifier" id="BT-46_scheme">Schéma de l'identifiant</entry>
<entry key="xr:Buyer_contact_point" id="BT-56">Nom</entry>
<entry key="xr:Buyer_contact_telephone_number" id="BT-57">Téléphone</entry>
<entry key="xr:Buyer_contact_email_address" id="BT-58">Adresse e-mail</entry>
<entry key="xr:Seller_name" id="BT-27">Raison sociale</entry>
<entry key="xr:Seller_address_line_1" id="BT-35">Adresse ligne 1</entry>
<entry key="xr:Seller_address_line_2" id="BT-36">Adresse ligne 2</entry>
<entry key="xr:Seller_address_line_3" id="BT-162">Adresse ligne 3</entry>
<entry key="xr:Seller_post_code" id="BT-38">Code postal</entry>
<entry key="xr:Seller_city" id="BT-37">Ville</entry>
<entry key="xr:Seller_country_subdivision" id="BT-39">Région</entry>
<entry key="xr:Seller_country_code" id="BT-40">Code pays</entry>
<entry key="xr:Seller_identifier" id="BT-29">Identifiant</entry>
<entry key="xr:Seller_identifier/@scheme_identifier" id="BT-29_scheme">Schéma de l'identifiant</entry>
<entry key="xr:Seller_contact_point" id="BT-41">Nom</entry>
<entry key="xr:Seller_contact_telephone_number" id="BT-42">Téléphone</entry>
<entry key="xr:Seller_contact_email_address" id="BT-43">Adresse e-mail</entry>
<entry key="xr:Invoice_number" id="BT-1">Numéro de facture</entry>
<entry key="xr:Invoice_issue_date" id="BT-2">Date de facture</entry>
<entry key="xr:Invoice_type_code" id="BT-3">Type de facture</entry>
<entry key="xr:Invoice_currency_code" id="BT-5">Devise</entry>
<entry key="xr:Project_reference" id="BT-11">Numéro de projet</entry>
<entry key="xr:Contract_reference" id="BT-12">Numéro de contrat</entry>
<entry key="xr:Purchase_order_reference" id="BT-13">Numéro de commande</entry>
<entry key="xr:Sales_order_reference" id="BT-14">Référence de commande client</entry>
<!-- Be aware that these are for the whole invoice -->
<entry key="xr:Invoicing_period_start_date" id="BT-73">Du</entry>
<entry key="xr:Invoicing_period_end_date" id="BT-74">Au</entry>
<entry key="xr:Preceding_Invoice_reference" id="BT-25">Numéro de facture</entry>
<entry key="xr:Preceding_Invoice_issue_date" id="BT-26">Date de facture</entry>
<entry key="xr:Sum_of_Invoice_line_net_amount" id="BT-106">Total des lignes</entry>
<entry key="xr:Sum_of_allowances_on_document_level" id="BT-107">Total des remises</entry>
<entry key="xr:Sum_of_charges_on_document_level" id="BT-108">Total des frais</entry>
<entry key="xr:Invoice_total_amount_without_VAT" id="BT-109">Total HT</entry>
<entry key="xr:Invoice_total_VAT_amount" id="BT-110">Total TVA</entry>
<entry key="xr:Invoice_total_VAT_amount_in_accounting_currency" id="BT-111">Total TVA en devise comptable</entry>
<entry key="xr:Invoice_total_amount_with_VAT" id="BT-112">Total TTC</entry>
<entry key="xr:Paid_amount" id="BT-113">Montant payé</entry>
<entry key="xr:Rounding_amount" id="BT-114">Montant d'arrondi</entry>
<entry key="xr:Amount_due_for_payment" id="BT-115">Montant dû</entry>
<entry key="xr:VAT_category_code" id="BT-118">Catégorie de TVA</entry>
<entry key="xr:VAT_category_taxable_amount" id="BT-116">Total</entry>
<entry key="xr:VAT_category_rate" id="BT-119">Taux de TVA</entry>
<entry key="xr:VAT_category_tax_amount" id="BT-117">Montant de TVA</entry>
<entry key="xr:VAT_exemption_reason_text" id="BT-120">Motif d'exonération</entry>
<entry key="xr:VAT_exemption_reason_code" id="BT-121">Code du motif d'exonération</entry>
<!-- Remises -->
<entry key="xr:Document_level_allowance_VAT_category_code" id="BT-95">Catégorie de TVA de la remise</entry>
<entry key="xr:Document_level_allowance_base_amount" id="BT-93">Montant de base</entry>
<entry key="xr:Document_level_allowance_percentage" id="BT-94">Pourcentage</entry>
<entry key="xr:Document_level_allowance_amount" id="BT-92">Remise</entry>
<entry key="xr:Document_level_allowance_VAT_rate" id="BT-96">Taux de TVA de la remise</entry>
<entry key="xr:Document_level_allowance_reason" id="BT-97">Motif de la remise</entry>
<entry key="xr:Document_level_allowance_reason_code" id="BT-98">Code du motif de la remise</entry>
<!-- Frais -->
<entry key="xr:Document_level_charge_VAT_category_code" id="BT-102">Catégorie de TVA des frais</entry>
<entry key="xr:Document_level_charge_base_amount" id="BT-100">Montant de base</entry>
<entry key="xr:Document_level_charge_percentage" id="BT-101">Pourcentage</entry>
<entry key="xr:Document_level_charge_amount" id="BT-99">Frais</entry>
<entry key="xr:Document_level_charge_VAT_rate" id="BT-103">Taux de TVA des frais</entry>
<entry key="xr:Document_level_charge_reason" id="BT-104">Motif des frais</entry>
<entry key="xr:Document_level_charge_reason_code" id="BT-105">Code du motif des frais</entry>
<entry key="xr:Payment_terms" id="BT-20">Escompte ; autres conditions de paiement</entry>
<entry key="xr:Payment_due_date" id="BT-9">Date d'échéance</entry>
<entry key="xr:Payment_means_type_code" id="BT-81">Code du moyen de paiement</entry>
<entry key="xr:Payment_means_text" id="BT-82">Moyen de paiement</entry>
<entry key="xr:Remittance_information" id="BT-83">Référence de paiement</entry>
<entry key="xr:Payment_card_primary_account_number" id="BT-87">Numéro de carte</entry>
<entry key="xr:Payment_card_holder_name" id="BT-88">Titulaire de la carte</entry>
<!-- BG-19 Direct Debit -->
<entry key="xr:Mandate_reference_identifier" id="BT-89">Référence du mandat</entry>
<entry key="xr:Debited_account_identifier" id="BT-91">IBAN</entry>
<entry key="xr:Bank_assigned_creditor_identifier" id="BT-90">Identifiant créancier</entry>
<!-- BG-17 Credit Transfer-->
<entry key="xr:Payment_account_name" id="BT-85">Titulaire du compte</entry>
<entry key="xr:Payment_account_identifier" id="BT-84">IBAN</entry>
<entry key="xr:Payment_service_provider_identifier" id="BT-86">BIC</entry>
<entry key="xr:Invoice_note_subject_code" id="BT-21">Objet</entry>
<entry key="xr:Invoice_note" id="BT-22">Remarque</entry>
<!-- BG-4 Seller and others -->
<entry key="xr:Seller_trading_name" id="BT-28">Nom commercial</entry>
<entry key="xr:Seller_electronic_address" id="BT-34">Adresse électronique</entry>
<entry key="xr:Seller_electronic_address/@scheme_identifier" id="BT-34_scheme">Schéma de l'adresse électronique</entry>
<entry key="xr:Seller_legal_registration_identifier" id="BT-30">Numéro SIRET/SIREN</entry>
<entry key="xr:Seller_legal_registration_identifier/@scheme_identifier" id="BT-30_scheme">Schéma du numéro d'enregistrement</entry>
<entry key="xr:Seller_VAT_identifier" id="BT-31">Numéro de TVA intracommunautaire</entry>
<entry key="xr:Seller_tax_registration_identifier" id="BT-32">Numéro fiscal</entry>
<entry key="xr:Seller_additional_legal_information" id="BT-33">Informations juridiques complémentaires</entry>
<entry key="xr:VAT_accounting_currency_code" id="BT-6">Code devise de la TVA</entry>
<!-- BG 12 and 11 Tax Representative party -->
<entry key="xr:Seller_tax_representative_name" id="BT-62">Nom</entry>
<entry key="xr:Tax_representative_address_line_1" id="BT-64">Adresse ligne 1</entry>
<entry key="xr:Tax_representative_address_line_2" id="BT-65">Adresse ligne 2</entry>
<entry key="xr:Tax_representative_address_line_3" id="BT-164">Adresse ligne 3</entry>
<entry key="xr:Tax_representative_post_code" id="BT-67">Code postal</entry>
<entry key="xr:Tax_representative_city" id="BT-66">Ville</entry>
<entry key="xr:Tax_representative_country_subdivision" id="BT-68">Région</entry>
<entry key="xr:Tax_representative_country_code" id="BT-69">Code pays</entry>
<entry key="xr:Seller_tax_representative_VAT_identifier" id="BT-63">Numéro de TVA intracommunautaire</entry>
<!-- Additional buyer information from different bgs -->
<entry key="xr:Buyer_trading_name" id="BT-45">Nom commercial</entry>
<entry key="xr:Buyer_country_subdivision" id="BT-54">Région</entry>
<entry key="xr:Buyer_electronic_address" id="BT-49">Adresse électronique</entry>
<entry key="xr:Buyer_electronic_address/@scheme_identifier" id="BT-49_scheme">Schéma de l'adresse électronique</entry>
<entry key="xr:Buyer_legal_registration_identifier" id="BT-47">Numéro SIRET/SIREN</entry>
<entry key="xr:Buyer_legal_registration_identifier/@scheme_identifier" id="BT-47_scheme">Schéma du numéro d'enregistrement</entry>
<entry key="xr:Buyer_VAT_identifier" id="BT-48">Numéro de TVA intracommunautaire</entry>
<entry key="xr:Value_added_tax_point_date" id="BT-7">Date d'exigibilité de la TVA</entry>
<entry key="xr:Value_added_tax_point_date_code" id="BT-8">Code de la date d'exigibilité de la TVA</entry>
<entry key="xr:Buyer_accounting_reference" id="BT-19">Référence comptable</entry>
<entry key="xr:Deliver_to_location_identifier" id="BT-71">Identifiant du lieu de livraison</entry>
<entry key="xr:Deliver_to_location_identifier/@scheme_identifier" id="BT-71_scheme">Schéma de l'identifiant</entry>
<entry key="xr:Actual_delivery_date" id="BT-72">Date de livraison</entry>
<entry key="xr:Deliver_to_party_name" id="BT-70">Nom du destinataire</entry>
<entry key="xr:Deliver_to_address_line_1" id="BT-75">Adresse ligne 1</entry>
<entry key="xr:Deliver_to_address_line_2" id="BT-76">Adresse ligne 2</entry>
<entry key="xr:Deliver_to_address_line_3" id="BT-165">Adresse ligne 3</entry>
<entry key="xr:Deliver_to_post_code" id="BT-78">Code postal</entry>
<entry key="xr:Deliver_to_city" id="BT-77">Ville</entry>
<entry key="xr:Deliver_to_country_subdivision" id="BT-79">Région</entry>
<entry key="xr:Deliver_to_country_code" id="BT-80">Code pays</entry>
<entry key="xr:Tender_or_lot_reference" id="BT-17">Numéro d'appel d'offres</entry>
<entry key="xr:Receiving_advice_reference" id="BT-15">Référence de l'avis de réception</entry>
<entry key="xr:Despatch_advice_reference" id="BT-16">Référence de l'avis d'expédition</entry>
<entry key="xr:Business_process_type" id="BT-23">Identifiant du processus</entry>
<entry key="xr:Specification_identifier" id="BT-24">Identifiant de spécification</entry>
<entry key="xr:Invoiced_object_identifier" id="BT-18">Identifiant de l'objet</entry>
<entry key="xr:Invoiced_object_identifier/@scheme_identifier" id="BT-18_scheme">Schéma de l'identifiant de l'objet</entry>
<!-- BG 10 -->
<entry key="xr:Payee_name" id="BT-59">Nom</entry>
<entry key="xr:Payee_identifier" id="BT-60">Identifiant</entry>
<entry key="xr:Payee_identifier/@scheme_identifier" id="BT-60_scheme">Schéma de l'identifiant</entry>
<entry key="xr:Payee_legal_registration_identifier" id="BT-61">Numéro SIRET/SIREN</entry>
<entry key="xr:Payee_legal_registration_identifier/@scheme_identifier" id="BT-61_scheme">Schéma du numéro d'enregistrement</entry>
<!-- BG 24 Additonal supporting Documents -->
<entry key="xr:Supporting_document_reference" id="BT-122">Identifiant</entry>
<entry key="xr:Supporting_document_description" id="BT-123">Description</entry>
<entry key="xr:External_document_location" id="BT-124">Référence (ex. adresse Internet)</entry>
<entry key="xr:Attached_document" id="BT-125">Document joint</entry>
<entry key="xr:Attached_document/@mime_code" id="BT-125_mime_code">Format du document joint</entry>
<entry key="xr:Attached_document/@filename" id="BT-125_filename">Nom du document joint</entry>
<entry key="xrv:zeitstempel">Date/Heure</entry>
<entry key="xrv:betreff">Objet</entry>
<entry key="xrv:text">Texte</entry>
<entry key="xrv:details">Détails</entry>
<entry key="xr:Invoice_line_identifier" id="BT-126">Position</entry>
<entry key="xr:Invoice_line_note" id="BT-127">Texte libre</entry>
<entry key="xr:Invoice_line_object_identifier" id="BT-128_identifier">Identifiant de l'objet</entry>
<entry key="xr:Invoice_line_object_identifier/@scheme_identifier" id="BT-128_scheme">Schéma de l'identifiant de l'objet</entry>
<entry key="xr:Referenced_purchase_order_line_reference" id="BT-132">Numéro de ligne de commande</entry>
<entry key="xr:Invoice_line_Buyer_accounting_reference" id="BT-133">Référence comptable</entry>
<entry key="xr:Invoice_line_period_start_date" id="BT-134">Du</entry>
<entry key="xr:Invoice_line_period_end_date" id="BT-135">Au</entry>
<entry key="xr:Invoiced_quantity" id="BT-129">Quantité</entry>
<entry key="xr:Invoiced_quantity_unit_of_measure_code" id="BT-130">Unité</entry>
<entry key="xr:Item_net_price" id="BT-146">Prix unitaire (HT)</entry>
<entry key="xr:Invoice_line_net_amount" id="BT-131">Prix total (HT)</entry>
<entry key="xr:Item_price_discount" id="BT-147">Remise (HT)</entry>
<entry key="xr:Item_gross_price" id="BT-148">Prix catalogue (HT)</entry>
<entry key="xr:Item_price_base_quantity" id="BT-149">Quantité de base</entry>
<entry key="xr:Item_price_base_quantity_unit_of_measure" id="BT-150">Code de l'unité de mesure</entry>
<entry key="xr:Invoiced_item_VAT_category_code" id="BT-151">TVA</entry>
<entry key="xr:Invoiced_item_VAT_rate" id="BT-152">Taux de TVA</entry>
<entry key="xr:Item_name" id="BT-153">Désignation</entry>
<entry key="xr:Item_description" id="BT-154">Description</entry>
<entry key="xr:Item_Sellers_identifier" id="BT-155">Référence article</entry>
<entry key="xr:Item_Buyers_identifier" id="BT-156">Référence article acheteur</entry>
<entry key="xr:Item_standard_identifier" id="BT-157">Identifiant article</entry>
<entry key="xr:Item_standard_identifier/@scheme_identifier" class="BT-157_scheme">Schéma de l'identifiant article</entry>
<entry key="xr:Item_classification_identifier" id="BT-158">Code de classification article</entry>
<entry key="xr:Item_classification_identifier/@scheme_identifier" id="BT-158_scheme">Identifiant du schéma</entry>
<entry key="xr:Item_classification_identifier/@scheme_version_identifier" id="BT-158_scheme_version">Version du schéma</entry>
<entry key="xr:Item_country_of_origin" id="BT-159">Code du pays d'origine</entry>
<entry key="xr:Invoice_line_allowance_base_amount" id="BT-137">Montant de base (HT)</entry>
<entry key="xr:Invoice_line_allowance_percentage" id="BT-138">Pourcentage</entry>
<entry key="xr:Invoice_line_allowance_amount" id="BT-136">Remise (HT)</entry>
<entry key="xr:Invoice_line_allowance_reason" id="BT-139">Motif de la remise</entry>
<entry key="xr:Invoice_line_allowance_reason_code" id="BT-140">Code du motif de la remise</entry>
<entry key="xr:Invoice_line_charge_base_amount" id="BT-142">Montant de base (HT)</entry>
<entry key="xr:Invoice_line_charge_percentage" id="BT-143">Pourcentage</entry>
<entry key="xr:Invoice_line_charge_amount" id="BT-141">Frais (HT)</entry>
<entry key="xr:Invoice_line_charge_reason" id="BT-144">Motif des frais</entry>
<entry key="xr:Invoice_line_charge_reason_code" id="BT-145">Code du motif des frais</entry>
<entry key="xr:Third_party_payment_type" id="BT-DEX-001">Type de créance tierce</entry>
<entry key="xr:Third_party_payment_amount" id="BT-DEX-002">Montant de la créance tierce</entry>
<entry key="xr:Third_party_payment_description" id="BT-DEX-003">Description de la créance tierce</entry>
<entry key="uebersicht">Données de la facture électronique</entry>
<entry key="uebersichtKaeufer" id="BG-7">Informations sur l'acheteur</entry>
<entry key="uebersichtVerkaeufer" id="BG-4">Informations sur le vendeur</entry>
<entry key="uebersichtRechnungsInfo" id="invoice-data">Données de facturation</entry>
<entry key="uebersichtRechnungsuebersicht" id="BG-22">Totaux de la facture</entry>
<entry key="uebersichtFremdleistungen" id="BG-DEX-09">Créance tierce</entry>
<entry key="uebersichtUmsatzsteuer" id="BG-23">Ventilation de la TVA au niveau de la facture</entry>
<entry key="uebersichtNachlass" id="BG-20">Remise au niveau de la facture</entry>
<entry key="uebersichtZuschlaege" id="BG-21">Frais au niveau de la facture</entry>
<entry key="uebersichtRechnungAbrechnungszeitraum">Période de facturation</entry>
<entry key="uebersichtRechnungVorausgegangeneRechnungen" id="BG-3">Factures précédentes</entry>
<entry key="uebersichtZahlungInfo" id="BG-4">Informations de paiement</entry>
<entry key="uebersichtZahlungKarte" id="BG-18">Informations carte</entry>
<entry key="uebersichtZahlungLastschrift" id="BG-19">Prélèvement</entry>
<entry key="uebersichtZahlungUeberweisung" id="BG-17">Virement</entry>
<entry key="uebersichtBemerkungen" id="BG-1">Remarques sur la facture</entry>
<entry key="details">Lignes de facture</entry>
<entry key="detailsPositionAbrechnungszeitraum" id="BG-26">Période de facturation</entry>
<entry key="detailsPositionPreiseinzelheiten" id="BG-29">Détails du prix</entry>
<entry key="detailsPositionNachlaesse" id="BG-27">Remises au niveau de la ligne de facture</entry>
<entry key="detailsPositionZuschlaege" id="BG-28">Frais au niveau de la ligne de facture</entry>
<entry key="detailsPositionArtikelinformationen" id="BG-31">Informations sur l'article</entry>
<entry key="detailsPositionArtikeleigenschaften" id="BG-32">Caractéristiques de l'article</entry>
<entry key="zusaetze">Compléments</entry>
<entry key="zusaetzeVerkaeufer" id="BG-4">Informations sur le vendeur</entry>
<entry key="zusaetzeSteuervertreter" id="BG-11">Représentant fiscal du vendeur</entry>
<entry key="zusaetzeKaeufer" id="BG-7">Informations sur l'acheteur</entry>
<entry key="zusaetzeLieferung" id="BG-13">Informations de livraison</entry>
<entry key="zusaetzeVertrag">Informations contractuelles</entry>
<entry key="zusaetzeZahlungsempfaenger" id="BG-10">Bénéficiaire différent du vendeur</entry>
<entry key="laufzettel">Fiche de suivi</entry>
<entry key="laufzettelHistorie">Historique de traitement</entry>
<entry key="anlagen">Pièces jointes</entry>
<entry key="anlagenListe">Documents justificatifs</entry>
<entry key="date-format">[D]/[M]/[Y]</entry>
<entry key="datetime-format">[D]/[M]/[Y] [H]:[m]:[s]</entry>
<entry key="amount-format">###.##0,00</entry>
<entry key="percentage-format">##0,00</entry>
<entry key="at-least-two-format">###.##0,#################</entry>
<entry key="sum-of-third-party-payment-amounts" id="BT-DEX-002_sum">Total des créances tierces</entry>
<entry key="_disclaimer">Nous déclinons toute responsabilité quant à l'exactitude des données.</entry>
<entry key="_invoice-note-group">Remarques sur la facture</entry>
<entry key="_open">Ouvrir</entry>
<entry key="no-data">Aucune donnée disponible</entry>
<entry key="_net">HT</entry>
<entry key="_gross">TTC</entry>
<entry key="_no-content">Les sections sans contenu ne sont pas affichées !</entry>
<entry key="_description">Description</entry>
<entry key="_price">Prix</entry>
<entry key="_price-unit">Unité de prix</entry>
<entry key="_vat">Taux TVA</entry>
<entry key="_tax-code">Code taxe</entry>
<entry key="_total">Total</entry>
<entry key="_page">Page</entry>
</properties>

View File

@@ -8,6 +8,7 @@
xmlns:xrf="https://projekte.kosit.org/xrechnung/xrechnung-visualization/functions"> xmlns:xrf="https://projekte.kosit.org/xrechnung/xrechnung-visualization/functions">
<xsl:decimal-format name="de" decimal-separator="," grouping-separator="." NaN="" /> <xsl:decimal-format name="de" decimal-separator="," grouping-separator="." NaN="" />
<xsl:decimal-format name="fr" decimal-separator="," grouping-separator="." NaN="" />
<xsl:decimal-format name="en" decimal-separator="." grouping-separator="," NaN="" /> <xsl:decimal-format name="en" decimal-separator="." grouping-separator="," NaN="" />
<xsl:template name="uebersicht"> <xsl:template name="uebersicht">

View File

@@ -32,8 +32,6 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class VisualizationTest extends ResourceCase { public class VisualizationTest extends ResourceCase {
@@ -98,13 +96,8 @@ public class VisualizationTest extends ResourceCase {
public void testPDFVisualizationCII() { public void testPDFVisualizationCII() {
File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml"); File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml");
// the writing part
String expected = null;
String result = null;
try { try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII); zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII);
@@ -116,6 +109,47 @@ public class VisualizationTest extends ResourceCase {
try { try {
assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'})); assertTrue(ByteArraySearcher.startsWith(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), new byte[]{'%', 'P', 'D', 'F'}));
assertTrue(ByteArraySearcher.contains(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), "<rdf:li>de</rdf:li>".getBytes()));
} catch (IOException e) {
fail("IOException should not occur");
}
}
public void testPDFVisualizationCIIEnglish() {
File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml");
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII, Language.EN);
} 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'}));
assertTrue(ByteArraySearcher.contains(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), "<rdf:li>en</rdf:li>".getBytes()));
} catch (IOException e) {
fail("IOException should not occur");
}
}
public void testPDFVisualizationCIIFrench() {
File CIIinputFile = getResourceAsFile("cii/01.01a-INVOICE.cii.xml");
try {
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
zvi.toPDF(CIIinputFile.getAbsolutePath(), TARGET_PDF_CII, Language.FR);
} 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'}));
assertTrue(ByteArraySearcher.contains(Files.readAllBytes(Paths.get(TARGET_PDF_CII)), "<rdf:li>fr</rdf:li>".getBytes()));
} catch (IOException e) { } catch (IOException e) {
fail("IOException should not occur"); fail("IOException should not occur");
} }