diff --git a/History.md b/History.md index 295e18ca..a829860d 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,77 @@ +- 639 +- 633 +-626, +-622, +-356 +allow to add includedNotes with type +- - 645 +- 631 multiple invoice referenced documents +- 629 +- 630 #296 #565 +- + +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 +======= +2024-12-07 +- #566 Failed to parse PDF - Could not reproduce the invoice +- closes #579 prepaidamount is only read in UBL +- #581 parse lineTotalAmount, TaxBasisAmount, duePayableAmount +- #576 read lineid, #578 set lineid +- log error ids, be able to access them from context +- #503 import more ubl +- allow jackson to run over more classes, e.g., DirectDebit, bean contructor for direct debit +- allow json in document includedNotes and +- #591 Import IncludedNotes also on item level +- #595 Treat all fatal XR schematron rules as errors, not as warnings. +- #577 dom4j: exclude all (optional) dependencies to avoid potential conflicts. +- #575 Fix compilation problems. +- #573 Feature/category code +- #601 exceptions in metrics +- #606 also parse BT-25 + + +2.15.0 +======= +2024-11-18 +- #435 use invoiceimporter as common technical basis also for zugferdimporter +- also import delivery address +- #527 metrics may raise error on some pdf files +- #517 read product GlobalID +- #380 Added test for input stream validation +- #518 corrently validate more XRechnung versions +- make document charges and allowances serializable +- #523 Verapdf claims PDF-A/3s created witth visualize are invalid +- #530 duedate can not be set directly +- #532 support validation warnings! +- #534 new signature +- #538 Mustang validator always claims PDF is invalid if flavour is PDF/A-3A +- #555 be able to validate ubl credit notes +- when parsing now distinguishing between the parseExceptions StructureException and ArithmetricException +- #554 Import IncludedNotes on invoice extraction +- #542 Visualize SpecifiedLogisticsServiceCharge +- #531 Support ZUGFeRD 2.3.2 +- #480 Support netherlands Euro + +2.14.2 +======= +2024-10-14 + +- also parse BICs in InvoiceImporter not only IBANs +- #509 CLI currently does not write a logfile +- #505 crash after invoking ZUGFeRD2PullProvider +- #506 Fix POM missing dependencies + 2.14.1 ======= 2024-10-06 diff --git a/Mustang-CLI/pom.xml b/Mustang-CLI/pom.xml index 3ea82b7d..5780bd71 100644 --- a/Mustang-CLI/pom.xml +++ b/Mustang-CLI/pom.xml @@ -3,7 +3,7 @@ org.mustangproject core - 2.15.0-SNAPSHOT + 2.15.3-SNAPSHOT 4.0.0 org.mustangproject @@ -12,7 +12,7 @@ should also work for XRechnung/CII. jar - 2.15.0-SNAPSHOT + 2.15.3-SNAPSHOT UTF-8 11 @@ -23,7 +23,7 @@ org.mustangproject validator - 2.15.0-SNAPSHOT + 2.15.3-SNAPSHOT @@ -35,11 +35,30 @@ 1.8.0 + + + + ch.qos.logback + logback-classic + 1.2.13 + + + ch.qos.logback + logback-core + 1.5.13 + + + + org.codehaus.janino + janino + 3.1.7 + org.slf4j slf4j-simple 2.0.12 + org.junit.jupiter diff --git a/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileChecker.java b/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileChecker.java index 2a587c72..e0899108 100644 --- a/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileChecker.java +++ b/Mustang-CLI/src/main/java/org/mustangproject/commandline/FileChecker.java @@ -51,7 +51,9 @@ public class FileChecker { if ((!isPDF) && (!thisRun.shallIgnoreFileExt())) { return false; } - ZUGFeRDImporter zi = new ZUGFeRDImporter(filename); + ZUGFeRDImporter zi = new ZUGFeRDImporter(); + zi.doIgnoreCalculationErrors(); + zi.setPDFFilename(filename); try { if (zi.canParse()) { thisRun.incZUGFeRDCount(zi.getVersion()); diff --git a/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java b/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java index 6687297e..275da445 100755 --- a/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java +++ b/Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java @@ -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 to be added to log line\n" + " Additional parameters (optional - user will be prompted if not defined)\n" + " [--source ]: input PDF or XML file\n" + + " [--log-as-pdf]: save log output as pdf\n" + " --action validateExpectInvalid validate directory expecting negative results \n" + " [--no-notices]: refrain from reporting notices\n" + " Additional parameters (optional - user will be prompted if not defined)\n" @@ -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); diff --git a/Mustang-CLI/src/test/java/org/mustangproject/commandline/CliIT.java b/Mustang-CLI/src/test/java/org/mustangproject/commandline/CliIT.java index 73c35cd0..a6cf0bd9 100644 --- a/Mustang-CLI/src/test/java/org/mustangproject/commandline/CliIT.java +++ b/Mustang-CLI/src/test/java/org/mustangproject/commandline/CliIT.java @@ -1,8 +1,6 @@ package org.mustangproject.commandline; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -10,18 +8,43 @@ import java.nio.file.Paths; import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.Test; public class CliIT { + public static File getResourceAsFile(String resourcePath) { + try { + InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath); + if (in == null) { + return null; + } + + File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp"); + tempFile.deleteOnExit(); + + try (FileOutputStream out = new FileOutputStream(tempFile)) { + // copy stream + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + } + return tempFile; + } catch (IOException e) { + return null; + } + } + @Test public void testCii2Ubl() throws Exception { Path output = Paths.get("target/ubl.xml"); Files.deleteIfExists(output); Path jar = Files.newDirectoryStream(Paths.get("target"), "Mustang-CLI-*.jar").iterator().next(); ProcessBuilder pb = new ProcessBuilder("java", "-jar", jar.toString(), - "--action", "ubl", "--source", "src/test/resources/cii.xml", "--out", - output.toString()); + "--action", "ubl", "--source", "src/test/resources/cii.xml", "--out", + output.toString()); pb.redirectErrorStream(true); Process process = pb.start(); String result = getOutput(process); @@ -43,4 +66,17 @@ public class CliIT { return builder.toString(); } + @Test + public void testMetric() { + StatRun sr = new StatRun(); + File tempFile = getResourceAsFile("corrupt-factur-x-waytoosmall.pdf"); + + FileChecker fc = new FileChecker(tempFile.getAbsolutePath(), sr); + + fc.checkForZUGFeRD(); + System.out.print(fc.getOutputLine()); + + + } + } diff --git a/Mustang-CLI/src/test/resources/corrupt-factur-x-waytoosmall.pdf b/Mustang-CLI/src/test/resources/corrupt-factur-x-waytoosmall.pdf new file mode 100644 index 00000000..672888d1 --- /dev/null +++ b/Mustang-CLI/src/test/resources/corrupt-factur-x-waytoosmall.pdf @@ -0,0 +1,2 @@ +%PDF-1.4 +%ª«¬­ diff --git a/README.md b/README.md index f41a4671..43ea3671 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,10 @@ If you set up a Maven project, you can reference the mustang artifact like this: ```xml - org.mustangproject - library - 2.14.0 + org.mustangproject + validator + 2.15.0 + shaded ``` diff --git a/library/pom.xml b/library/pom.xml index ccdde504..073661c1 100644 --- a/library/pom.xml +++ b/library/pom.xml @@ -3,13 +3,13 @@ org.mustangproject core - 2.15.0-SNAPSHOT + 2.15.3-SNAPSHOT 4.0.0 org.mustangproject library - 2.15.0-SNAPSHOT + 2.15.3-SNAPSHOT jar Library to write, read and validate e-invoices (Factur-X, ZUGFeRD, Order-X, XRechnung/CII) FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT @@ -64,7 +64,8 @@ net.sf.saxon Saxon-HE 12.4 - + + com.fasterxml.jackson.core jackson-databind @@ -74,7 +75,7 @@ org.apache.xmlgraphics fop - 2.9 + 2.10 xml-apis @@ -82,18 +83,24 @@ - + jakarta.xml.bind jakarta.xml.bind-api 4.0.2 - + + + org.glassfish.jaxb + jaxb-runtime + 4.0.5 + + org.eclipse.angus angus-activation 2.0.2 - + org.apache.pdfbox preflight @@ -104,11 +111,26 @@ pdfbox 3.0.2 + org.dom4j dom4j 2.1.4 + + + * + * + + + + + com.helger + en16931-cii2ubl + 2.2.4 + + + org.junit.jupiter junit-jupiter-api @@ -121,27 +143,12 @@ 5.10.2 test - - - - com.helger - en16931-cii2ubl - 2.2.4 - - - - org.glassfish.jaxb - jaxb-runtime - 4.0.5 - - org.xmlunit xmlunit-core 2.10.0 test - org.xmlunit xmlunit-assertj @@ -193,21 +200,51 @@ - FreeSans.ttf + SourceSansPro-Regular.ttf font/ttf - FreeSerif.ttf + SourceSansPro-It.ttf - application/x-font + font/ttf - Times-Bold.ttf + SourceSansPro-Bold.ttf - application/x-font + font/ttf + + + + SourceSansPro-BoldIt.ttf + + font/ttf + + + + SourceSerifPro-Regular.ttf + + font/ttf + + + + SourceSerifPro-It.ttf + + font/ttf + + + + SourceSerifPro-Bold.ttf + + font/ttf + + + + SourceSerifPro-BoldIt.ttf + + font/ttf @@ -232,11 +269,9 @@ maven-shade-plugin 3.5.3 - true - false - + true + false - *:* @@ -245,18 +280,6 @@ META-INF/*.RSA - - log4j:log4j - - ** - - - - commons-logging:commons-logging - - ** - - @@ -265,15 +288,6 @@ shade - - - - - - - diff --git a/library/src/main/java/org/mustangproject/Allowance.java b/library/src/main/java/org/mustangproject/Allowance.java index df117e2b..e378f767 100644 --- a/library/src/main/java/org/mustangproject/Allowance.java +++ b/library/src/main/java/org/mustangproject/Allowance.java @@ -1,10 +1,16 @@ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + import java.math.BigDecimal; /*** * (absolute) allowances on item and document level */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class Allowance extends Charge { /*** @@ -28,6 +34,7 @@ public class Allowance extends Charge { * @return false since its not supposed to be calculated negatively */ @Override + @JsonIgnore public boolean isCharge() { return false; } diff --git a/library/src/main/java/org/mustangproject/BankDetails.java b/library/src/main/java/org/mustangproject/BankDetails.java index c6edcc86..a16976f3 100644 --- a/library/src/main/java/org/mustangproject/BankDetails.java +++ b/library/src/main/java/org/mustangproject/BankDetails.java @@ -2,11 +2,14 @@ package org.mustangproject; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IZUGFeRDTradeSettlementPayment; /** * provides e.g. the IBAN to transfer money to :-) */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class BankDetails implements IZUGFeRDTradeSettlementPayment { /** * the bank account number @@ -15,15 +18,17 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment { /** * BIC, I believe it's optional */ - protected String BIC=null; + protected String BIC = null; /** * the "name" of the bank account (holder) */ - protected String accountName=null; + protected String accountName = null; + /*** * bean constructor */ - public BankDetails() { } + public BankDetails() { + } /*** * constructor for IBAN only :-) @@ -32,6 +37,7 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment { public BankDetails(String IBAN) { this.IBAN = IBAN; } + /*** * constructor for normal use :-) * @param IBAN the IBAN as string @@ -55,6 +61,7 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment { * identify the IBAN. Of course you will specify your own IBAN in full length but * if you deduct from a customer's account you may e.g. leave out the first or last * digits so that nobody spying on the invoice gets to know the complete number + * * @param IBAN the "IBAN ID", i.e. the IBAN or parts of it * @return fluent setter */ @@ -81,9 +88,10 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment { return this; } - /*** - * getOwn... methods will be removed in the future in favor of Tradeparty (e.g. Sender) class - * */ + + /* + I'd really like to get rid of all those getOwn... methods some time but in this case they are in the interface :-( + */ @Override @Deprecated @JsonIgnore @@ -101,11 +109,12 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment { /** * set Holder + * * @param name account name (usually account holder if != sender) * @return fluent setter */ public BankDetails setAccountName(String name) { - accountName=name; + accountName = name; return this; } @@ -115,5 +124,4 @@ public class BankDetails implements IZUGFeRDTradeSettlementPayment { } - } diff --git a/library/src/main/java/org/mustangproject/CalculatedInvoice.java b/library/src/main/java/org/mustangproject/CalculatedInvoice.java new file mode 100644 index 00000000..194441b1 --- /dev/null +++ b/library/src/main/java/org/mustangproject/CalculatedInvoice.java @@ -0,0 +1,73 @@ +// Copyright (c) 2023 Jochen Stärk, see LICENSE file +package org.mustangproject; + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import org.mustangproject.ZUGFeRD.TransactionCalculator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Serializable; +import java.math.BigDecimal; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class CalculatedInvoice extends Invoice implements Serializable { + + protected BigDecimal lineTotalAmount=null; + protected BigDecimal duePayable=null; + protected BigDecimal grandTotal=null; + protected BigDecimal taxBasis=null; + + public void calculate() { + TransactionCalculator tc=new TransactionCalculator(this); + grandTotal=tc.getGrandTotal(); + lineTotalAmount=tc.getValue(); + duePayable=tc.getDuePayable(); + taxBasis= tc.getTaxBasis(); + } + public BigDecimal getGrandTotal() { + if (grandTotal==null) { + calculate(); + } + return grandTotal; + } + public CalculatedInvoice setGrandTotal(BigDecimal grand) { + grandTotal=grand; + return this; + } + public BigDecimal getTaxBasis() { + if (taxBasis==null) { + calculate(); + } + return taxBasis; + } + public CalculatedInvoice setTaxBasis(BigDecimal basis) { + taxBasis=basis; + return this; + } + + public BigDecimal getDuePayable() { + if (duePayable==null) { + calculate(); + } + return duePayable; + } + public CalculatedInvoice setDuePayable(BigDecimal due) { + duePayable=due; + return this; + } + + public BigDecimal getLineTotalAmount() { + if (lineTotalAmount==null) { + calculate(); + } + return lineTotalAmount; + } + public CalculatedInvoice setLineTotalAmount(BigDecimal total) { + lineTotalAmount=total; + return this; + } + +} diff --git a/library/src/main/java/org/mustangproject/CashDiscount.java b/library/src/main/java/org/mustangproject/CashDiscount.java index c7fb7a03..2151489a 100644 --- a/library/src/main/java/org/mustangproject/CashDiscount.java +++ b/library/src/main/java/org/mustangproject/CashDiscount.java @@ -1,5 +1,7 @@ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IZUGFeRDCashDiscount; import java.math.BigDecimal; @@ -7,6 +9,8 @@ import java.math.BigDecimal; /*** * A class to represent discounts for early payments ("Skonto") */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class CashDiscount implements IZUGFeRDCashDiscount { /*** @@ -31,6 +35,31 @@ public class CashDiscount implements IZUGFeRDCashDiscount { this.days = days; } + /*** + * bean contructor + */ + public CashDiscount() { + + } + + public BigDecimal getPercent() { + return percent; + } + + public CashDiscount setPercent(BigDecimal percent) { + this.percent = percent; + return this; + } + + public Integer getDays() { + return days; + } + + public CashDiscount setDays(Integer days) { + this.days = days; + return this; + } + /*** * @return this particular cash discount as cross industry invoice XML */ diff --git a/library/src/main/java/org/mustangproject/Charge.java b/library/src/main/java/org/mustangproject/Charge.java index a16f5e66..6232611d 100644 --- a/library/src/main/java/org/mustangproject/Charge.java +++ b/library/src/main/java/org/mustangproject/Charge.java @@ -1,5 +1,8 @@ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IAbsoluteValueProvider; import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge; @@ -8,6 +11,8 @@ import java.math.BigDecimal; /*** * Absolute and relative charges for document and item level */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class Charge implements IZUGFeRDAllowanceCharge { /** @@ -151,6 +156,7 @@ public class Charge implements IZUGFeRDAllowanceCharge { * @return true since it is supposed to be calculated negatively */ @Override + @JsonIgnore public boolean isCharge() { return true; } diff --git a/library/src/main/java/org/mustangproject/ClassCode.java b/library/src/main/java/org/mustangproject/ClassCode.java index 8b0a58cc..61fdd20f 100644 --- a/library/src/main/java/org/mustangproject/ClassCode.java +++ b/library/src/main/java/org/mustangproject/ClassCode.java @@ -20,15 +20,19 @@ */ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; /** * A schemed classification for products. The scheme can be anything defined in UNTDID 7143. */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class ClassCode { - private final String listID; - private final String code; + private String listID; + private String code; private String listVersionID; /** @@ -54,6 +58,13 @@ public class ClassCode { this(listID, code, null); } + /*** + * bean constructor + */ + public ClassCode() { + } + + /*** * Set the version for the scheme returned by {@link #getListID()} * @param listVersionID the scheme version diff --git a/library/src/main/java/org/mustangproject/Contact.java b/library/src/main/java/org/mustangproject/Contact.java index f690d0d8..cead6f86 100644 --- a/library/src/main/java/org/mustangproject/Contact.java +++ b/library/src/main/java/org/mustangproject/Contact.java @@ -1,6 +1,7 @@ package org.mustangproject; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -11,6 +12,7 @@ import org.w3c.dom.NodeList; * @see TradeParty */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class Contact implements IZUGFeRDExportableContact { /** diff --git a/library/src/main/java/org/mustangproject/DesignatedProductClassification.java b/library/src/main/java/org/mustangproject/DesignatedProductClassification.java index ac74bf36..ffa35c17 100644 --- a/library/src/main/java/org/mustangproject/DesignatedProductClassification.java +++ b/library/src/main/java/org/mustangproject/DesignatedProductClassification.java @@ -20,14 +20,18 @@ */ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IDesignatedProductClassification; /** * An implementation of {@link IDesignatedProductClassification} for describing a {@link org.mustangproject.Product} * */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class DesignatedProductClassification implements IDesignatedProductClassification { - private final ClassCode classCode; + private ClassCode classCode; private String className; /** @@ -50,6 +54,13 @@ public class DesignatedProductClassification implements IDesignatedProductClassi this(classCode, null); } + /** + * Bean constructor for schemed product descriptor + */ + public DesignatedProductClassification() { + classCode = null;// we need this constructor for jackson, i.e. to be able to JSON + } + @Override public ClassCode getClassCode() { return classCode; diff --git a/library/src/main/java/org/mustangproject/DirectDebit.java b/library/src/main/java/org/mustangproject/DirectDebit.java index 4eef6cb3..86937a0f 100644 --- a/library/src/main/java/org/mustangproject/DirectDebit.java +++ b/library/src/main/java/org/mustangproject/DirectDebit.java @@ -1,20 +1,32 @@ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IZUGFeRDTradeSettlementDebit; /** * provides e.g. the IBAN to transfer money to :-) */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class DirectDebit implements IZUGFeRDTradeSettlementDebit { /** * Debited account identifier (BT-91) */ - protected final String IBAN; + protected String IBAN; /** * Mandate reference identifier (BT-89) */ - protected final String mandate; + protected String mandate; + + /** + * bean constructor + */ + public DirectDebit() { + this.IBAN = ""; + this.mandate = ""; + } /*** * constructor for normal use :-) @@ -35,8 +47,18 @@ public class DirectDebit implements IZUGFeRDTradeSettlementDebit { return this.IBAN; } + public DirectDebit setIBAN(String iBAN) { + this.IBAN = iBAN; + return this; + } + @Override public String getMandate() { return this.mandate; } + + public DirectDebit setMandate(String mandate) { + this.mandate = mandate; + return this; + } } diff --git a/library/src/main/java/org/mustangproject/Exceptions/ArithmetricException.java b/library/src/main/java/org/mustangproject/Exceptions/ArithmetricException.java new file mode 100644 index 00000000..e5b4071d --- /dev/null +++ b/library/src/main/java/org/mustangproject/Exceptions/ArithmetricException.java @@ -0,0 +1,16 @@ +package org.mustangproject.Exceptions; + +import java.text.ParseException; + +/*** + * will be thrown if an invoice cant be reproduced numerically + */ +public class ArithmetricException extends ParseException { + public ArithmetricException() { + this(""); + } + + public ArithmetricException(String details) { + super("Could not reproduce the invoice. " + details, 0); + } +} diff --git a/library/src/main/java/org/mustangproject/Exceptions/StructureException.java b/library/src/main/java/org/mustangproject/Exceptions/StructureException.java new file mode 100644 index 00000000..1859da7a --- /dev/null +++ b/library/src/main/java/org/mustangproject/Exceptions/StructureException.java @@ -0,0 +1,12 @@ +package org.mustangproject.Exceptions; + +import java.text.ParseException; + +/*** + * will be thrown if a invoice cant be read + */ +public class StructureException extends ParseException { + public StructureException(String message, int line) { + super(message, line); + } +} diff --git a/library/src/main/java/org/mustangproject/FileAttachment.java b/library/src/main/java/org/mustangproject/FileAttachment.java index d17aa727..ed1fe39f 100644 --- a/library/src/main/java/org/mustangproject/FileAttachment.java +++ b/library/src/main/java/org/mustangproject/FileAttachment.java @@ -1,5 +1,10 @@ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class FileAttachment { protected String filename; @@ -8,12 +13,20 @@ public class FileAttachment { protected String description; protected byte[] data; + + /*** + * bean contructor + */ + public FileAttachment() { + + } + public FileAttachment(String filename, String mimetype, String relation, byte[] data) { this.filename = filename; this.mimetype = mimetype; this.relation = relation; this.data = data; - description = "Additional file attachment"; + this.description = "Additional file attachment"; } public String getDescription() { @@ -60,8 +73,4 @@ public class FileAttachment { this.data = data; return this; } - - - - } diff --git a/library/src/main/java/org/mustangproject/IncludedNote.java b/library/src/main/java/org/mustangproject/IncludedNote.java index 95536afb..0bcf3133 100644 --- a/library/src/main/java/org/mustangproject/IncludedNote.java +++ b/library/src/main/java/org/mustangproject/IncludedNote.java @@ -1,68 +1,100 @@ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + /** * A grouping of business terms to indicate accounting-relevant free texts including a qualification of these. */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class IncludedNote { - private final String content; - private final SubjectCode subjectCode; + private String content; - private static final String INCLUDE_START = ""; - private static final String INCLUDE_END = ""; - private static final String CONTENT_START = ""; - private static final String CONTENT_END = ""; - private static final String SUBJECT_CODE_START = ""; - private static final String SUBJECT_CODE_END = ""; + private SubjectCode subjectCode; - private IncludedNote(String content, SubjectCode subjectCode) { - this.content = content; - this.subjectCode = subjectCode; - } + private static final String INCLUDE_START = ""; + private static final String INCLUDE_END = ""; + private static final String CONTENT_START = ""; + private static final String CONTENT_END = ""; + private static final String SUBJECT_CODE_START = ""; + private static final String SUBJECT_CODE_END = ""; - public static IncludedNote generalNote(String content) { - return new IncludedNote(content, SubjectCode.AAI); - } - public static IncludedNote regulatoryNote(String content) { - return new IncludedNote(content, SubjectCode.REG); - } - public static IncludedNote legalNote(String content) { - return new IncludedNote(content, SubjectCode.ABL); - } - public static IncludedNote customsNote(String content) { - return new IncludedNote(content, SubjectCode.CUS); - } - public static IncludedNote sellerNote(String content) { - return new IncludedNote(content, SubjectCode.SUR); - } - public static IncludedNote taxNote(String content) { - return new IncludedNote(content, SubjectCode.TXD); - } - public static IncludedNote introductionNote(String content) { - return new IncludedNote(content, SubjectCode.ACY); - } - public static IncludedNote discountBonusNote(String content) { - return new IncludedNote(content, SubjectCode.AAK); - } + public IncludedNote(String content, SubjectCode subjectCode) { + this.content = content; + this.subjectCode = subjectCode; + } - public static IncludedNote unspecifiedNote(String content) { - return new IncludedNote(content, null); - } + /** + * bean constructor + */ + public IncludedNote() { - public String getContent() { - return content; - } + } + + public static IncludedNote generalNote(String content) { + return new IncludedNote(content, SubjectCode.AAI); + } + + public static IncludedNote regulatoryNote(String content) { + return new IncludedNote(content, SubjectCode.REG); + } + + public static IncludedNote legalNote(String content) { + return new IncludedNote(content, SubjectCode.ABL); + } + + public static IncludedNote customsNote(String content) { + return new IncludedNote(content, SubjectCode.CUS); + } + + public static IncludedNote sellerNote(String content) { + return new IncludedNote(content, SubjectCode.SUR); + } + + public static IncludedNote taxNote(String content) { + return new IncludedNote(content, SubjectCode.TXD); + } + + public static IncludedNote introductionNote(String content) { + return new IncludedNote(content, SubjectCode.ACY); + } + + public static IncludedNote discountBonusNote(String content) { + return new IncludedNote(content, SubjectCode.AAK); + } + + public static IncludedNote unspecifiedNote(String content) { + return new IncludedNote(content, null); + } + + public String getContent() { + return content; + } + + public SubjectCode getSubjectCode() { + return subjectCode; + } + + + public IncludedNote setSubjectCode(SubjectCode subjectCode) { + this.subjectCode = subjectCode; + return this; + } + + public IncludedNote setContent(String content) { + this.content = content; + return this; + } + + + public String toCiiXml() { + String result = INCLUDE_START + CONTENT_START + + XMLTools.encodeXML(getContent()) + CONTENT_END; + if (getSubjectCode() != null) { + result += SUBJECT_CODE_START + getSubjectCode() + SUBJECT_CODE_END; + } + return result + INCLUDE_END; + } - public SubjectCode getSubjectCode() { - return subjectCode; - } - - public String toCiiXml(){ - String result = INCLUDE_START + CONTENT_START + - XMLTools.encodeXML(getContent() )+ CONTENT_END; - if (getSubjectCode() != null) { - result += SUBJECT_CODE_START + getSubjectCode() + SUBJECT_CODE_END; - } - return result + INCLUDE_END; - } - } diff --git a/library/src/main/java/org/mustangproject/Invoice.java b/library/src/main/java/org/mustangproject/Invoice.java index 8461e977..04c8b5dc 100644 --- a/library/src/main/java/org/mustangproject/Invoice.java +++ b/library/src/main/java/org/mustangproject/Invoice.java @@ -21,11 +21,9 @@ package org.mustangproject; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; +import java.util.*; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.*; import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; @@ -37,9 +35,10 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; * @see IExportableTransaction if you want to implement an interface instead */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class Invoice implements IExportableTransaction { - protected String documentName = null, documentCode = null, number = null, ownOrganisationFullPlaintextInfo = null, referenceNumber = null, shipToOrganisationID = null, shipToOrganisationName = null, shipToStreet = null, shipToZIP = null, shipToLocation = null, shipToCountry = null, buyerOrderReferencedDocumentID = null, invoiceReferencedDocumentID = null, buyerOrderReferencedDocumentIssueDateTime = null, ownForeignOrganisationID = null, ownOrganisationName = null, currency = null, paymentTermDescription = null; + protected String documentName = null, documentCode = null, number = null, ownOrganisationFullPlaintextInfo = null, referenceNumber = null, shipToOrganisationID = null, shipToOrganisationName = null, shipToStreet = null, shipToZIP = null, shipToLocation = null, shipToCountry = null, buyerOrderReferencedDocumentID = null, buyerOrderReferencedDocumentIssueDateTime = null, ownForeignOrganisationID = null, ownOrganisationName = null, currency = null, paymentTermDescription = null; protected Date issueDate = null, dueDate = null, deliveryDate = null; protected TradeParty sender = null, recipient = null, deliveryAddress = null, payee = null; protected ArrayList cashDiscounts = null; @@ -58,12 +57,18 @@ public class Invoice implements IExportableTransaction { protected ArrayList Allowances = new ArrayList<>(), Charges = new ArrayList<>(), LogisticsServiceCharges = new ArrayList<>(); protected IZUGFeRDPaymentTerms paymentTerms = null; + + protected String invoiceReferencedDocumentID = null; protected Date invoiceReferencedIssueDate; + // New field for storing Invoiced Object Identifier (BG-3) + protected ArrayList invoiceReferencedDocuments = null; + protected String specifiedProcuringProjectID = null; protected String specifiedProcuringProjectName = null; protected String despatchAdviceReferencedDocumentID = null; protected String vatDueDateTypeCode = null; protected String creditorReferenceID; // required when direct debit is used. + private BigDecimal roundingAmount=null; public Invoice() { ZFItems = new ArrayList<>(); @@ -113,6 +118,16 @@ public class Invoice implements IExportableTransaction { } + /*** + * setter in case e.g. jackson tries to map attachments (normal use embedFileInXML) + * @param fileArr Array of FileAttachments + * @return fluent setter + */ + public Invoice setAdditionalReferencedDocuments(FileAttachment[] fileArr) { + xmlEmbeddedFiles = new ArrayList<>(Arrays.asList(fileArr)); + return this; + } + @Override public IZUGFeRDCashDiscount[] getCashDiscounts() { return cashDiscounts.toArray(new IZUGFeRDCashDiscount[0]); @@ -138,6 +153,7 @@ public class Invoice implements IExportableTransaction { */ public Invoice setCorrection(String number) { setInvoiceReferencedDocumentID(number); + addInvoiceReferencedDocument(new ReferencedDocument(number)); documentCode = DocumentCodeTypeConstants.CORRECTEDINVOICE; return this; } @@ -410,6 +426,11 @@ public class Invoice implements IExportableTransaction { return includedNotes; } + public Invoice setNotesWithSubjectCode(List theList) { + includedNotes=theList; + return this; + } + @Override public String getCurrency() { return currency; @@ -465,6 +486,26 @@ public class Invoice implements IExportableTransaction { return sender; } + /*** + * for currency rounding differences to 5ct e.g. in Netherlands ("Rappenrundung") + * @return null if not set, otherwise BigDecimal of Euros + */ + @Override + public BigDecimal getRoundingAmount() { + return roundingAmount; + } + + /*** + * set the cent e.g. to reach the next 5ct mark for currencies in certain countries + * e.g. in the Netherlands ("Rappenrundung") + * @param amount + * @return fluent setter + */ + public Invoice setRoundingAmount(BigDecimal amount) { + roundingAmount=amount; + return this; + } + /*** * sets a named sender contact * @deprecated use setSender @@ -511,6 +552,26 @@ public class Invoice implements IExportableTransaction { return this; } + // Getter for BG-3 + @Override + public ArrayList getInvoiceReferencedDocuments() { + return invoiceReferencedDocuments; + } + + // Setter for BG-3 + public void setInvoiceReferencedDocuments(ArrayList invoiceReferencedDocuments) { + this.invoiceReferencedDocuments = invoiceReferencedDocuments; + } + + // Method to add a single ReferencedDocument for BG-3 + public Invoice addInvoiceReferencedDocument(ReferencedDocument doc) { + if (invoiceReferencedDocuments == null) { + invoiceReferencedDocuments = new ArrayList<>(); + } + invoiceReferencedDocuments.add(doc); + return this; + } + @Override public IZUGFeRDAllowanceCharge[] getZFAllowances() { if (Allowances.isEmpty()) { @@ -520,6 +581,20 @@ public class Invoice implements IExportableTransaction { } } + /*** + * this is wrong and only used from jackson + * @param iza the Array of allowances/charges + * @return fluent setter + */ + public Invoice setZFAllowances(Allowance[] iza) { + Allowances=new ArrayList<>(); + + for (IZUGFeRDAllowanceCharge cz:iza) { + Allowances.add(cz); + } + return this; + } + @Override public IZUGFeRDAllowanceCharge[] getZFCharges() { @@ -530,6 +605,18 @@ public class Invoice implements IExportableTransaction { } } + /*** + * this is wrong and only used from jackson + * @param iza the array of charges + * @return fluent setter + */ + public Invoice setZFCharges(Charge[] iza) { + Charges=new ArrayList<>(); + for (IZUGFeRDAllowanceCharge cz:iza) { + Charges.add(cz); + } + return this; + } @Override public IZUGFeRDAllowanceCharge[] getZFLogisticsServiceCharges() { diff --git a/library/src/main/java/org/mustangproject/Item.java b/library/src/main/java/org/mustangproject/Item.java index 9f568a6d..4641a0e3 100644 --- a/library/src/main/java/org/mustangproject/Item.java +++ b/library/src/main/java/org/mustangproject/Item.java @@ -1,6 +1,7 @@ package org.mustangproject; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IReferencedDocument; import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem; @@ -11,13 +12,18 @@ import org.w3c.dom.NodeList; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; +import java.util.Collection; import java.util.Date; +import java.util.List; +import java.util.HashMap; +import java.util.Map; /*** * describes any invoice line */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class Item implements IZUGFeRDExportableItem { protected BigDecimal price = BigDecimal.ZERO; protected BigDecimal quantity; @@ -35,6 +41,8 @@ public class Item implements IZUGFeRDExportableItem { protected ArrayList additionalReference = null; protected ArrayList Allowances = new ArrayList<>(); protected ArrayList Charges = new ArrayList<>(); + protected List includedNotes = null; + //protected HashMap attributes = new HashMap<>(); /*** * default constructor @@ -62,11 +70,39 @@ public class Item implements IZUGFeRDExportableItem { // ubl //we need: name description unitcode //and we additionally have vat% - setProduct(new Product()); + + // Bharti's homework 20241126:Streams https://www.youtube.com/watch?v=Lf01cBzmuXw + // and Lambdas https://www.youtube.com/watch?v=HCyx31NW8xg + setProduct(new Product(itemMap.getNode("Item").get())); icnm.getAsString("Name").ifPresent(product::setName); + icnm.getAsString("Description").ifPresent(product::setDescription); + + icnm.getAsNodeMap("SellersItemIdentification").ifPresent(SellersItemIdentification -> { + SellersItemIdentification.getAsString("ID").ifPresent(product::setSellerAssignedID); + }); + + icnm.getAsNodeMap("BuyersItemIdentification").ifPresent(BuyersItemIdentification -> { + BuyersItemIdentification.getAsString("ID").ifPresent(product::setBuyerAssignedID); + }); + +// String name = icnm.getAsStringOrNull("Name"); +// String val = icnm.getAsStringOrNull("Value"); +// if (name != null && val != null) { +// if (attributes == null) { +// attributes = new HashMap<>(); +// } +// product.attributes.put(name, val); +// } + //icnm.getNode("AdditionalItemProperty").flatMap(n ->n.getAttributes()).ifPresent(product::setAttributes); + + + icnm.getAsNodeMap("ClassifiedTaxCategory").flatMap(m -> m.getAsBigDecimal("Percent")) .ifPresent(product::setVATPercent); }); + itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(icnm -> { + icnm.getAsString("LineID").ifPresent(this::setId); + }); itemMap.getAsNodeMap("Price").ifPresent(icnm -> { // ubl @@ -81,21 +117,43 @@ public class Item implements IZUGFeRDExportableItem { product.setUnit(icn.getAttributes().getNamedItem("unitCode").getNodeValue()); }); + itemMap.getAllNodes("DocumentReference").map(ReferencedDocument::fromNode) + .forEach(this::addAdditionalReference); + + // ubl + + itemMap.getAsNodeMap("OrderLineReference") + // ubl + .flatMap(bordNodes -> bordNodes.getAsString("LineID")) + .ifPresent(this::addReferencedLineID); + + itemMap.getAsString("ID") + .ifPresent(this::setId); + + + itemMap.getAsString("Note") + .ifPresent(this::addNote); + + + + itemMap.getAsNodeMap("SpecifiedLineTradeAgreement", "SpecifiedSupplyChainTradeAgreement").ifPresent(icnm -> { icnm.getAsNodeMap("BuyerOrderReferencedDocument") .flatMap(bordNodes -> bordNodes.getAsString("LineID")) .ifPresent(this::addReferencedLineID); + icnm.getAsNodeMap("NetPriceProductTradePrice").ifPresent(npptpNodes -> { npptpNodes.getAsBigDecimal("ChargeAmount").ifPresent(this::setPrice); npptpNodes.getAsBigDecimal("BasisQuantity").ifPresent(this::setBasisQuantity); }); - icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode) - .forEach(this::addReferencedDocument); + icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode). + forEach(this::addReferencedDocument); }); - itemMap.getNode("SpecifiedTradeProduct").map(Product::new).ifPresent(this::setProduct); + itemMap.getNode("SpecifiedTradeProduct").map(Product::new).ifPresent(this::setProduct);//CII + itemMap.getNode("SpecifiedTradeProduct").map(Product::new).ifPresent(this::setProduct);//UBL // RequestedQuantity is for Order-X, BilledQuantity for FX and ZF itemMap.getAsNodeMap("SpecifiedLineTradeDelivery", "SpecifiedSupplyChainTradeDelivery") @@ -123,6 +181,37 @@ public class Item implements IZUGFeRDExportableItem { icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference); }); + + itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(adld -> { + List includedNotes = new ArrayList<>(); + adld.getAllNodes("IncludedNote").forEach(item -> { + String subjectCode = ""; + String content = null; + NodeList includedNodeChilds = item.getChildNodes(); + for (int issueDateChildIndex = 0; issueDateChildIndex < includedNodeChilds.getLength(); issueDateChildIndex++) { + if ((includedNodeChilds.item(issueDateChildIndex).getLocalName() != null) + && (includedNodeChilds.item(issueDateChildIndex).getLocalName().equals("Content"))) { + content = XMLTools.trimOrNull(includedNodeChilds.item(issueDateChildIndex)); + } + if ((includedNodeChilds.item(issueDateChildIndex).getLocalName() != null) + && (includedNodeChilds.item(issueDateChildIndex).getLocalName().equals("SubjectCode"))) { + subjectCode = XMLTools.trimOrNull(includedNodeChilds.item(issueDateChildIndex)); + } + } + boolean foundCode = false; + for (SubjectCode code : SubjectCode.values()) { + if (code.toString().equals(subjectCode)) { + includedNotes.add(new IncludedNote(content, code)); + foundCode = true; + break; + } + } + if (!foundCode) { + includedNotes.add(new IncludedNote(content, null)); + } + }); + addNotes(includedNotes); + }); } public Item addReferencedLineID(String s) { @@ -143,6 +232,11 @@ public class Item implements IZUGFeRDExportableItem { return lineTotalAmount; } + public Item setNotesWithSubjectCode(List theList) { + includedNotes=theList; + return this; + } + /** * should only be set by calculator classes or maybe when reading from XML * @@ -258,7 +352,7 @@ public class Item implements IZUGFeRDExportableItem { /*** * Adds a item level addition to the price (will be multiplied by quantity) - * @see org.mustangproject.Charge + * @see Charge * @param izac a relative or absolute charge * @return fluent setter */ @@ -269,7 +363,7 @@ public class Item implements IZUGFeRDExportableItem { /*** * Adds a item level reduction the price (will be multiplied by quantity) - * @see org.mustangproject.Allowance + * @see Allowance * @param izac a relative or absolute allowance * @return fluent setter */ @@ -288,6 +382,26 @@ public class Item implements IZUGFeRDExportableItem { notes = new ArrayList<>(); } notes.add(text); + + addNote(IncludedNote.unspecifiedNote(text)); + + + return this; + } + + /*** + * adds categorized item level freetext fields (includednote) + * @param theNote IncludedNote to add + * @return fluent setter + */ + public Item addNote(IncludedNote theNote) { + + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.add(theNote); + + return this; } @@ -314,7 +428,7 @@ public class Item implements IZUGFeRDExportableItem { /*** - * adds item level references along with their typecodes and issuerassignedIDs (contract ID, cost centre, ...) + * adds item level references along with their typecodes and issuerassignedIDs (contract ID, cost centre, ...) * @param doc the ReferencedDocument to add * @return fluent setter */ @@ -333,8 +447,8 @@ public class Item implements IZUGFeRDExportableItem { } return additionalReference.toArray(new IReferencedDocument[0]); } - - + + /*** * specify a item level delivery period * (apart from the document level delivery period, and the document level @@ -370,4 +484,19 @@ public class Item implements IZUGFeRDExportableItem { return detailedDeliveryPeriodTo; } + public IZUGFeRDExportableItem addNotes(Collection notes) { + if (notes == null) { + return this; + } + if (includedNotes == null) { + includedNotes = new ArrayList<>(); + } + includedNotes.addAll(notes); + return this; + } + + @Override + public List getNotesWithSubjectCode() { + return includedNotes; + } } diff --git a/library/src/main/java/org/mustangproject/LegalOrganisation.java b/library/src/main/java/org/mustangproject/LegalOrganisation.java index 95f61629..705420c2 100644 --- a/library/src/main/java/org/mustangproject/LegalOrganisation.java +++ b/library/src/main/java/org/mustangproject/LegalOrganisation.java @@ -1,6 +1,7 @@ package org.mustangproject; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.*; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -9,6 +10,7 @@ import org.w3c.dom.NodeList; * A organisation, i.e. usually a company */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class LegalOrganisation implements IZUGFeRDLegalOrganisation { protected SchemedID schemedID = null; diff --git a/library/src/main/java/org/mustangproject/Product.java b/library/src/main/java/org/mustangproject/Product.java index 1da0292e..4bbde404 100644 --- a/library/src/main/java/org/mustangproject/Product.java +++ b/library/src/main/java/org/mustangproject/Product.java @@ -1,10 +1,13 @@ package org.mustangproject; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonSetter; import org.mustangproject.ZUGFeRD.IDesignatedProductClassification; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableProduct; import org.mustangproject.util.NodeMap; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import java.math.BigDecimal; import java.util.ArrayList; @@ -17,17 +20,20 @@ import java.util.Map; * describes a product, good or service used in an invoice item line */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) + public class Product implements IZUGFeRDExportableProduct { protected String unit, name, sellerAssignedID, buyerAssignedID; - protected String description=""; - protected String taxExemptionReason=null; - protected String taxCategoryCode=null; + protected String description = ""; + protected String taxExemptionReason = null; + protected String taxCategoryCode = null; protected BigDecimal VATPercent; protected boolean isReverseCharge = false; protected boolean isIntraCommunitySupply = false; protected SchemedID globalId = null; protected String countryOfOrigin = null; protected HashMap attributes = new HashMap<>(); + protected List classifications = new ArrayList<>(); /*** @@ -56,11 +62,13 @@ public class Product implements IZUGFeRDExportableProduct { } }); + nodeMap.getAsString("SellerAssignedID").ifPresent(this::setSellerAssignedID); nodeMap.getAsString("BuyerAssignedID").ifPresent(this::setBuyerAssignedID); nodeMap.getAsString("Name").ifPresent(this::setName); nodeMap.getAsString("Description").ifPresent(this::setDescription); + nodeMap.getAsNodeMap("ApplicableProductCharacteristic").ifPresent(apcNodes -> { String key = apcNodes.getAsStringOrNull("Description"); String value = apcNodes.getAsStringOrNull("Value"); @@ -72,6 +80,26 @@ public class Product implements IZUGFeRDExportableProduct { } }); + + //UBL + nodeMap.getAsNodeMap("AdditionalItemProperty").ifPresent(aipNodes -> { + String name = aipNodes.getAsStringOrNull("Name"); + String val = aipNodes.getAsStringOrNull("Value"); + if (name != null && val != null) { + if (attributes == null) { + attributes = new HashMap<>(); + } + attributes.put(name, val); + } + }); + + nodeMap.getAsNodeMap("CommodityClassification").ifPresent(dpcNodes -> { + String className = dpcNodes.getAsStringOrNull("ClassName"); + dpcNodes.getNode("ItemClassificationCode").map(ClassCode::fromNode).ifPresent(classCode -> + classifications.add(new DesignatedProductClassification(classCode, className))); + }); + + //UBL nodeMap.getAsNodeMap("DesignatedProductClassification").ifPresent(dpcNodes -> { String className = dpcNodes.getAsStringOrNull("ClassName"); dpcNodes.getNode("ClassCode").map(ClassCode::fromNode).ifPresent(classCode -> @@ -112,6 +140,7 @@ public class Product implements IZUGFeRDExportableProduct { return this; } + /*** * * @return e.g. intra-commnunity supply or small business @@ -126,7 +155,7 @@ public class Product implements IZUGFeRDExportableProduct { * @param taxExemptionReasonText String e.g. Kleinunternehmer gemäß §19 UStG https://github.com/ZUGFeRD/mustangproject/issues/463 * @return fluent setter */ - public Product setTaxExemptionReason(String taxExemptionReasonText) { + public Product setTaxExemptionReason(String taxExemptionReasonText) { taxExemptionReason = taxExemptionReasonText; return this; } @@ -148,7 +177,7 @@ public class Product implements IZUGFeRDExportableProduct { * @param code e.g. S (normal tax), Z=zero rated, E (e.g. small business) or K (intrra community supply) see also https://github.com/ZUGFeRD/mustangproject/issues/463 * @return fluent setter */ - public Product setTaxCategoryCode(String code) { + public Product setTaxCategoryCode(String code) { taxCategoryCode = code; return this; } @@ -275,18 +304,22 @@ public class Product implements IZUGFeRDExportableProduct { * @return fluent setter */ public Product setVATPercent(BigDecimal VATPercent) { - this.VATPercent = VATPercent; + if (VATPercent == null) { + this.VATPercent = BigDecimal.ZERO; + } else { + this.VATPercent = VATPercent; + } return this; } @Override public String getCountryOfOrigin() { - return this.countryOfOrigin; + return this.countryOfOrigin; } public Product setCountryOfOrigin(String countryOfOrigin) { - this.countryOfOrigin = countryOfOrigin; - return this; + this.countryOfOrigin = countryOfOrigin; + return this; } @Override @@ -299,16 +332,16 @@ public class Product implements IZUGFeRDExportableProduct { } public Product setAttributes(Map attributes) { - this.attributes.clear(); + this.attributes.clear(); if (attributes != null) { this.attributes.putAll(attributes); } - return this; + return this; } - public Product addAttribute(String name, String value ) { - this.attributes.put(name, value); - return this; + public Product addAttribute(String name, String value) { + this.attributes.put(name, value); + return this; } @Override @@ -334,6 +367,23 @@ public class Product implements IZUGFeRDExportableProduct { return this; } + + /** + * Provide Jackson a hint as to use DesignatedProductClassification for the + * IDesignatedProductClassification product classifications + * + * @param classifications the new set of classifications + * @return fluent setter + */ + @JsonSetter("classifications") + public Product setClassificationsClass(DesignatedProductClassification[] classifications) { + this.classifications.clear(); + if (classifications != null) { + this.classifications.addAll(Arrays.asList(classifications)); + } + return this; + } + /** * Add a {@link IDesignatedProductClassification} classification * diff --git a/library/src/main/java/org/mustangproject/ReferencedDocument.java b/library/src/main/java/org/mustangproject/ReferencedDocument.java index 4d2151ca..7a1c04a0 100644 --- a/library/src/main/java/org/mustangproject/ReferencedDocument.java +++ b/library/src/main/java/org/mustangproject/ReferencedDocument.java @@ -1,25 +1,44 @@ package org.mustangproject; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.Date; + import org.mustangproject.ZUGFeRD.IReferencedDocument; import org.mustangproject.util.NodeMap; import org.w3c.dom.Node; +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class ReferencedDocument implements IReferencedDocument { String issuerAssignedID; String typeCode; String referenceTypeCode; + Date formattedIssueDateTime; public ReferencedDocument(String issuerAssignedID, String typeCode, String referenceTypeCode) { - this.issuerAssignedID = issuerAssignedID; + this(issuerAssignedID); this.typeCode = typeCode; this.referenceTypeCode = referenceTypeCode; } + public ReferencedDocument(String issuerAssignedID, String typeCode, String referenceTypeCode, Date formattedIssueDateTime) { + this(issuerAssignedID, typeCode, referenceTypeCode); + this.formattedIssueDateTime = formattedIssueDateTime; + } + public ReferencedDocument(String issuerAssignedID, String referenceTypeCode) { + this(issuerAssignedID, "916", referenceTypeCode); // additional invoice related document + } + + public ReferencedDocument(String issuerAssingedID, Date formattedIssueDateTime) { + this(issuerAssingedID); + this.formattedIssueDateTime = formattedIssueDateTime; + } + + public ReferencedDocument(String issuerAssignedID) { this.issuerAssignedID = issuerAssignedID; - this.typeCode = "916"; // additional invoice related document - this.referenceTypeCode = referenceTypeCode; } /*** @@ -46,6 +65,15 @@ public class ReferencedDocument implements IReferencedDocument { this.referenceTypeCode = referenceTypeCode; } + /** + * issue date of this line + * + * @param formattedIssueDateTime as Date + */ + public void setFormattedIssueDateTime(Date formattedIssueDateTime) { + this.formattedIssueDateTime = formattedIssueDateTime; + } + @Override public String getIssuerAssignedID() { return issuerAssignedID; @@ -61,13 +89,20 @@ public class ReferencedDocument implements IReferencedDocument { return referenceTypeCode; } + @Override + public Date getFormattedIssueDateTime() + { + return formattedIssueDateTime; + } + public static ReferencedDocument fromNode(Node node) { if (!node.hasChildNodes()) { return null; } NodeMap nodes = new NodeMap(node); - return new ReferencedDocument(nodes.getAsStringOrNull("IssuerAssignedID"), - nodes.getAsStringOrNull("TypeCode"), - nodes.getAsStringOrNull("ReferenceTypeCode")); + return new ReferencedDocument(nodes.getAsStringOrNull("IssuerAssignedID", "ID"), + nodes.getAsStringOrNull("TypeCode", "DocumentTypeCode"), + nodes.getAsStringOrNull("ReferenceTypeCode"), + XMLTools.tryDate(nodes.getAsStringOrNull("FormattedIssueDateTime"))); } } diff --git a/library/src/main/java/org/mustangproject/SchemedID.java b/library/src/main/java/org/mustangproject/SchemedID.java index 9df8a2d9..6cbac0ec 100644 --- a/library/src/main/java/org/mustangproject/SchemedID.java +++ b/library/src/main/java/org/mustangproject/SchemedID.java @@ -1,5 +1,11 @@ package org.mustangproject; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class SchemedID { protected String scheme; protected String id; diff --git a/library/src/main/java/org/mustangproject/SubjectCode.java b/library/src/main/java/org/mustangproject/SubjectCode.java index c58070fd..808c09d4 100644 --- a/library/src/main/java/org/mustangproject/SubjectCode.java +++ b/library/src/main/java/org/mustangproject/SubjectCode.java @@ -36,5 +36,9 @@ public enum SubjectCode { /** * Discount and bonus agreements */ - AAK + AAK, + /** + * Vehicle licence number + */ + ABZ } diff --git a/library/src/main/java/org/mustangproject/TradeParty.java b/library/src/main/java/org/mustangproject/TradeParty.java index e67567e4..73b1ae81 100644 --- a/library/src/main/java/org/mustangproject/TradeParty.java +++ b/library/src/main/java/org/mustangproject/TradeParty.java @@ -2,9 +2,11 @@ package org.mustangproject; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.fasterxml.jackson.annotation.JsonInclude; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTradeParty; import org.mustangproject.ZUGFeRD.IZUGFeRDLegalOrganisation; @@ -15,13 +17,15 @@ import org.w3c.dom.NodeList; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /*** * A organisation, i.e. usually a company */ @JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class TradeParty implements IZUGFeRDExportableTradeParty { - protected String name, zip, street, location, country; + protected String name, zip, street, location, country, taxScheme; protected String taxID = null, vatID = null; protected String ID = null; protected String description = null; @@ -60,6 +64,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } + protected void parseFromUBL(NodeList nodes) { if (nodes.getLength() > 0) { @@ -69,8 +74,34 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { if (currentItemNode.getLocalName() != null) { String currentUBLChild = currentItemNode.getLocalName(); - if (currentUBLChild.equals("Party")) { +// if (currentUBLChild.equals("Delivery")) { +// NodeList delivery = currentItemNode.getChildNodes(); +// for (int deliveryIndex = 0; deliveryIndex < delivery.getLength(); deliveryIndex++) { +// if (delivery.item(deliveryIndex).getLocalName() != null) { +// Node currentNode = delivery.item(deliveryIndex); +// if (currentNode.getLocalName().equals("DeliveryLocation")) { +// NodeList deliveryLocation = currentNode.getChildNodes(); +// for (int deliveryLocationIndex = 0; deliveryLocationIndex < deliveryLocation.getLength(); deliveryLocationIndex++) { +// if (deliveryLocation.item(deliveryLocationIndex).getLocalName() != null) { +// if (deliveryLocation.item(deliveryLocationIndex).getLocalName().equals("ID")) { +// //Node currentNode = partyID.item(partyIDIndex); +// setID(deliveryLocation.item(deliveryLocationIndex).getTextContent()); +// if ((deliveryLocation.item(deliveryLocationIndex).getAttributes() != null && +// (deliveryLocation.item(deliveryLocationIndex).getAttributes().getNamedItem("schemeID") != null)) +// ) { +// SchemedID sID = new SchemedID().setScheme(deliveryLocation.item(deliveryLocationIndex).getAttributes().getNamedItem("schemeID").getTextContent()); +// addGlobalID(sID); +// } +// } +// } +// } +// } +// +// } +// } +// } + if (currentUBLChild.equals("Party")) { NodeList party = currentItemNode.getChildNodes(); for (int partyIndex = 0; partyIndex < party.getLength(); partyIndex++) { if (party.item(partyIndex).getLocalName() != null) { @@ -88,19 +119,102 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } } } + if (party.item(partyIndex).getLocalName().equals("EndpointID")) { + Node currentNode = party.item(partyIndex); + if ((currentNode.getAttributes() != null && + (currentNode.getAttributes().getNamedItem("schemeID") != null)) + && (party.item(partyIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("EM")) + ) { + setEmail(currentNode.getTextContent()); + } + + } + if (currentTopElementName.equals("PartyIdentification")) { + NodeList partyID = party.item(partyIndex).getChildNodes(); + for (int partyIDIndex = 0; partyIDIndex < partyID.getLength(); partyIDIndex++) { + if (partyID.item(partyIDIndex).getLocalName() != null) { + if (partyID.item(partyIDIndex).getLocalName().equals("ID")) { + Node currentNode = partyID.item(partyIDIndex); + if ((currentNode.getAttributes() != null && + (currentNode.getAttributes().getNamedItem("schemeID") != null)) + ) { + SchemedID sID = new SchemedID().setScheme(currentNode.getAttributes().getNamedItem("schemeID").getTextContent()).setId(currentNode.getTextContent()); + addGlobalID(sID); + + } + else { + setID(currentNode.getTextContent()); + } - // UBL only: formally it can have a name as well but BT27 party name *should* be stored in - // so overwrite if one exists - if (currentTopElementName.equals("PartyLegalEntity")) { - NodeList legal = party.item(partyIndex).getChildNodes(); - for (int legalChildIndex = 0; legalChildIndex < legal.getLength(); legalChildIndex++) { - if (legal.item(legalChildIndex).getLocalName() != null) { - if (legal.item(legalChildIndex).getLocalName().equals("RegistrationName")) { - setName(legal.item(legalChildIndex).getTextContent()); } } } } + + if (currentTopElementName.equals("PartyTaxScheme")) { + NodeList partyTaxScheme = party.item(partyIndex).getChildNodes(); + String CompanyId = null; + for (int partyTaxSchemeIndex = 0; partyTaxSchemeIndex < partyTaxScheme.getLength(); partyTaxSchemeIndex++) { + if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName() != null) { + if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("CompanyID")) { + CompanyId = (partyTaxScheme.item(partyTaxSchemeIndex).getTextContent()); + } + if (partyTaxScheme.item(partyTaxSchemeIndex).getLocalName().equals("TaxScheme")) { + NodeList taxSchemechilds = partyTaxScheme.item(partyTaxSchemeIndex).getChildNodes(); + for (int taxSchemechildsIndex = 0; taxSchemechildsIndex < taxSchemechilds.getLength(); taxSchemechildsIndex++) { + if (taxSchemechilds.item(taxSchemechildsIndex).getLocalName() != null) { + if (taxSchemechilds.item(taxSchemechildsIndex).getTextContent().equals("FC") || (taxSchemechilds.item(taxSchemechildsIndex).getTextContent().equals("NOVAT"))) { + setTaxID(CompanyId); + } else { + setVATID(CompanyId); + } + } + } + } + } + + } + } + + + /* + UBL only: formally it can have a name as well but BT27 party name *should* be stored in + so overwrite if one exists + */ + + if (currentTopElementName.equals("PartyLegalEntity")) { + NodeList legal = party.item(partyIndex).getChildNodes(); + LegalOrganisation lo = null; + for (int legalChildIndex = 0; legalChildIndex < legal.getLength(); legalChildIndex++) { + if (legal.item(legalChildIndex).getLocalName() != null) { + + if (legal.item(legalChildIndex).getLocalName().equals("RegistrationName")) { + if (lo == null) { + lo = new LegalOrganisation(); + } + lo.setTradingBusinessName(legal.item(legalChildIndex).getTextContent()); + } + if (legal.item(legalChildIndex).getLocalName().equals("CompanyLegalForm")) { + setDescription(legal.item(legalChildIndex).getTextContent()); + } + if (legal.item(legalChildIndex).getLocalName().equals("CompanyID")) { + if (lo == null) { + lo = new LegalOrganisation(); + } + if (legal.item(legalChildIndex).getAttributes().getNamedItem("schemeID")!=null) { + SchemedID sid = new SchemedID(legal.item(legalChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue(), legal.item(legalChildIndex).getTextContent()); + lo.setSchemedID(sid); + } + } + // we dont have that attribute yet in the legalorganisation: CompanyLegalForm + if (lo != null) { + setLegalOrganisation(lo); + } + + } + } + } + if (currentTopElementName.equals("PostalAddress")) { NodeList postal = party.item(partyIndex).getChildNodes(); @@ -148,8 +262,6 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } } - - } if (postal.item(postalChildIndex).getLocalName().equals("Name")) { setName(postal.item(postalChildIndex).getTextContent()); @@ -167,7 +279,6 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { } } - } if (currentUBLChild.equals("GlobalID")) { @@ -181,56 +292,6 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { NodeList contact = nodes.item(nodeIndex).getChildNodes(); setContact(new Contact(contact)); } - - if (currentUBLChild.equals("PostalTradeAddress")) { - NodeList postal = nodes.item(nodeIndex).getChildNodes(); - for (int postalChildIndex = 0; postalChildIndex < postal.getLength(); postalChildIndex++) { - if (postal.item(postalChildIndex).getLocalName() != null) { - if (postal.item(postalChildIndex).getLocalName().equals("LineOne")) { - setStreet(postal.item(postalChildIndex).getTextContent()); - } - if (postal.item(postalChildIndex).getLocalName().equals("LineTwo")) { - setAdditionalAddress(postal.item(postalChildIndex).getTextContent()); - } - if (postal.item(postalChildIndex).getLocalName().equals("LineThree")) { - setAdditionalAddressExtension(postal.item(postalChildIndex).getTextContent()); - } - if (postal.item(postalChildIndex).getLocalName().equals("CityName")) { - setLocation(postal.item(postalChildIndex).getTextContent()); - } - if (postal.item(postalChildIndex).getLocalName().equals("PostcodeCode")) { - setZIP(postal.item(postalChildIndex).getTextContent()); - } - if (postal.item(postalChildIndex).getLocalName().equals("CountryID")) { - setCountry(postal.item(postalChildIndex).getTextContent()); - } - - } - } - - } - - if (currentUBLChild.equals("SpecifiedTaxRegistration")) { - NodeList taxChilds = nodes.item(nodeIndex).getChildNodes(); - for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) { - if (taxChilds.item(taxChildIndex).getLocalName() != null) { - if ((taxChilds.item(taxChildIndex).getLocalName().equals("ID"))) { - if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID") != null) { - Node firstChild = taxChilds.item(taxChildIndex).getFirstChild(); - if (firstChild != null) { - if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("VA")) { - setVATID(firstChild.getNodeValue()); - } - if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("FC")) { - setTaxID(firstChild.getNodeValue()); - } - } - } - } - } - } - - } } } } @@ -500,6 +561,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { return this; } + /** * (optional) * @@ -511,6 +573,15 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { return this; } + /** + * primarily for invoiceimporter and JSON + * + * @return the list of sepa mandates + */ + public List getDebitDetails() { + return debitDetails; + } + @Override public IZUGFeRDLegalOrganisation getLegalOrganisation() { return legalOrg; @@ -670,6 +741,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty { return contact; } + @JsonIgnore public IZUGFeRDTradeSettlement[] getAsTradeSettlement() { if (bankDetails.isEmpty() && debitDetails.isEmpty()) { return null; diff --git a/library/src/main/java/org/mustangproject/XMLTools.java b/library/src/main/java/org/mustangproject/XMLTools.java index d2daead9..d890c3d1 100644 --- a/library/src/main/java/org/mustangproject/XMLTools.java +++ b/library/src/main/java/org/mustangproject/XMLTools.java @@ -4,9 +4,13 @@ import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.math.RoundingMode; +import java.text.SimpleDateFormat; +import java.util.Date; import org.apache.commons.io.IOUtils; import org.dom4j.io.XMLWriter; +import org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat; +import org.w3c.dom.Node; public class XMLTools extends XMLWriter { @Override @@ -39,10 +43,56 @@ public class XMLTools extends XMLWriter { } + /** + * returns the value of an node + * + * @param node the Node to get the value from + * @return A String or empty String, if no value was found + */ + public static String getNodeValue(Node node) { + if (node != null && node.getFirstChild() != null) { + return node.getFirstChild().getNodeValue(); + } + return ""; + } + + + /** + * tries to convert a String to BigDecimal. + * + * @param nodeValue The value as String + * @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs + */ + public static BigDecimal tryBigDecimal(String nodeValue) { + try { + return new BigDecimal(nodeValue); + } catch (final Exception e) { + try { + return BigDecimal.valueOf(Float.valueOf(nodeValue)); + } catch (final Exception ex) { + return new BigDecimal("0.00"); + } + } + } + + + /** + * tries to convert a Node to a BigDecimal. + * + * @param node The value as String + * @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs + */ + public static BigDecimal tryBigDecimal(Node node) { + final String nodeValue = XMLTools.getNodeValue(node); + if (nodeValue.isEmpty()) { + return null; + } + return XMLTools.tryBigDecimal(nodeValue); + } /*** * formats a number so that at least minDecimals are displayed but at the maximum maxDecimals are there, i.e. * cuts potential 0s off the end until minDecimals - * @param value + * @param value the value to be formatted * @param maxDecimals number of maximal scale * @param minDecimals number of minimal scale * @return value as String with decimals in the specified range @@ -60,7 +110,39 @@ public class XMLTools extends XMLWriter { } - public static String encodeXML(CharSequence s) { + /*** + * returns a util.Date from a 102 String yyyymmdd in a node + * @param node the node + * @return a util.Date, or null, if not parseable + */ + public static Date tryDate(Node node) { + final String nodeValue = XMLTools.getNodeValue(node); + if (nodeValue.isEmpty()) { + return null; + } + return tryDate(nodeValue); + } + + /*** + * returns a util.Date from a 102 String yyyymmdd + * @param toParse the string + * @return a util.Date, or null, if not parseable + */ + public static Date tryDate(String toParse) { + final SimpleDateFormat formatter = ZUGFeRDDateFormat.DATE.getFormatter(); + try { + return formatter.parse(toParse); + } catch (final Exception e) { + return null; + } + } + + /*** + * relplaces some entities like < , > and & with their escaped pendant like &lt; + * @param s the string + * @return the "safe" string + */ + public static String encodeXML(CharSequence s) { if (s == null) { return ""; } @@ -132,4 +214,16 @@ public class XMLTools extends XMLWriter { return IOUtils.toByteArray (fileinput); } + + public static String trimOrNull(Node node) { + if (node != null) { + String textContent = node.getTextContent(); + if (textContent != null) { + return textContent.trim(); + } + } + return null; + } + + } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java index 060216cd..0a013ba3 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IExportableTransaction.java @@ -30,11 +30,13 @@ package org.mustangproject.ZUGFeRD; * */ import java.math.BigDecimal; -import java.util.Date; +import java.util.ArrayList; +import java.util.Date; import java.util.List; import org.mustangproject.FileAttachment; import org.mustangproject.IncludedNote; +import org.mustangproject.ReferencedDocument; import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants; /*** @@ -321,6 +323,16 @@ public interface IExportableTransaction { return false; } + /** + * get the rounding amount + * (only to be usef for NL whose currency requires a rounding to 5ct) + * + * @return the Bigdecimal + */ + default BigDecimal getRoundingAmount() { + return null; + } + /** * get BuyerReference (BT-10) an identifier assigned by the buyer and used * for internal routing. Used for the Leitweg-ID. @@ -415,13 +427,23 @@ public interface IExportableTransaction { * * @return the ID of the document */ + @Deprecated default String getInvoiceReferencedDocumentID() { return null; } + @Deprecated default Date getInvoiceReferencedIssueDate() { return null; } + + /** + * Getter for BG-3 + * @return list of documents + */ + default ArrayList getInvoiceReferencedDocuments() { + return null; + } /** * get the issue timestamp of the BuyerOrderReferencedDocument, which sits in diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IReferencedDocument.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IReferencedDocument.java index 9d46d9b6..92ee2761 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IReferencedDocument.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IReferencedDocument.java @@ -1,5 +1,7 @@ package org.mustangproject.ZUGFeRD; +import java.util.Date; + public interface IReferencedDocument { /*** @@ -20,4 +22,12 @@ public interface IReferencedDocument { */ String getReferenceTypeCode(); + /*** + * + * issue date of this line + * + * @return date of the issue + */ + Date getFormattedIssueDateTime(); + } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java index e5e25cae..45c210ea 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/IZUGFeRDExportableItem.java @@ -28,7 +28,9 @@ package org.mustangproject.ZUGFeRD; import java.math.BigDecimal; import java.util.Date; +import java.util.List; +import org.mustangproject.IncludedNote; import org.mustangproject.Item; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @@ -153,4 +155,21 @@ public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{ return null; } + /*** + * + * @return the line ID + */ + default String getId() { + return null; + } + + /** + * A grouping of business terms to indicate accounting-relevant free texts including a qualification of these. + * + * The information are written to the same xml nodes like {@link #getNotes()} but with explicit subjectCode. + * @return list of the notes + */ + default List getNotesWithSubjectCode() { + return null; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java b/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java index b3a0c177..e319ec73 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/LineCalculator.java @@ -34,16 +34,30 @@ public class LineCalculator { } } - BigDecimal vatPercent = currentItem.getProduct().getVATPercent(); - if (vatPercent == null) + BigDecimal vatPercent = null; + if (currentItem.getProduct()!=null) { + vatPercent = currentItem.getProduct().getVATPercent(); + } + if (vatPercent == null) { vatPercent = BigDecimal.ZERO; + } BigDecimal multiplicator = vatPercent.divide(BigDecimal.valueOf(100)); priceGross = currentItem.getPrice(); // see https://github.com/ZUGFeRD/mustangproject/issues/159 price = priceGross.subtract(allowance).add(charge); - itemTotalNetAmount = currentItem.getQuantity().multiply(getPrice()).divide(currentItem.getBasisQuantity(), 18, RoundingMode.HALF_UP) + + BigDecimal quantity=BigDecimal.ZERO; + if ((currentItem!=null)&&(currentItem.getQuantity()!=null)) { + quantity=currentItem.getQuantity(); + } + + // Division/Zero occurred here. + // Used the setScale only because that's also done in getBasisQuantity + BigDecimal basisQuantity = currentItem.getBasisQuantity().compareTo(BigDecimal.ZERO) == 0 + ? BigDecimal.ONE.setScale(4) + : currentItem.getBasisQuantity(); + itemTotalNetAmount = quantity.multiply(getPrice()).divide(basisQuantity, 18, RoundingMode.HALF_UP) .subtract(allowanceItemTotal).setScale(2, RoundingMode.HALF_UP); itemTotalVATAmount = itemTotalNetAmount.multiply(multiplicator); - } public BigDecimal getPrice() { diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/OXPullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/OXPullProvider.java index 1d2a30e0..7347d422 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/OXPullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/OXPullProvider.java @@ -459,6 +459,19 @@ public class OXPullProvider extends ZUGFeRD2PullProvider { } xml += ""; } + if (trans.getInvoiceReferencedDocuments() != null) { + for (var doc : trans.getInvoiceReferencedDocuments()) { + xml += "" + + "" + + XMLTools.encodeXML(doc.getIssuerAssignedID()) + ""; + if (doc.getFormattedIssueDateTime() != null) { + xml += "" + + DATE.qdtFormat(doc.getFormattedIssueDateTime()) + + ""; + } + xml += ""; + } + } xml += ""; // + " " diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java b/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java index 1e1f757f..9c2b30f3 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/TransactionCalculator.java @@ -4,13 +4,16 @@ import static java.math.BigDecimal.ZERO; import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.Arrays; import java.util.HashMap; +import java.util.Objects; +import java.util.stream.Collectors; import java.util.stream.Stream; /*** * The Transactioncalculator e.g. adds the line totals and applies VAT on whole * invoices - * + * * @see LineCalculator */ public class TransactionCalculator implements IAbsoluteValueProvider { @@ -27,7 +30,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider { /*** * if something had already been paid in advance, this will get it from the * transaction - * + * * @return prepaid amount */ protected BigDecimal getTotalPrepaid() { @@ -41,19 +44,19 @@ public class TransactionCalculator implements IAbsoluteValueProvider { /*** * the invoice total with VAT, allowances and * charges, WITHOUT considering prepaid amount - * + * * @return the invoice total including taxes */ public BigDecimal getGrandTotal() { - final BigDecimal res = getTaxBasis(); + BigDecimal basis = getTaxBasis(); return getVATPercentAmountMap().values().stream().map(VATAmount::getCalculated) - .map(p -> p.setScale(2, RoundingMode.HALF_UP)).reduce(BigDecimal.ZERO, BigDecimal::add).add(res); + .map(p -> p.setScale(2, RoundingMode.HALF_UP)).reduce(BigDecimal.ZERO, BigDecimal::add).add(basis); } /*** * returns total of charges for this tax rate - * + * * @param percent a specific rate, or null for any rate * @return the total amount */ @@ -77,7 +80,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider { /*** * returns a (potentially concatenated) string of charge reasons, or "Charges" * if none are defined - * + * * @param percent a specific rate, or null for any rate * @return the space separated String */ @@ -91,23 +94,20 @@ public class TransactionCalculator implements IAbsoluteValueProvider { } private String getAllowanceChargeReasonForPercent(BigDecimal percent, IZUGFeRDAllowanceCharge[] charges) { - String res = " "; - if ((charges != null) && (charges.length > 0)) { - for (IZUGFeRDAllowanceCharge currentCharge : charges) { - if ((percent == null) || (currentCharge.getTaxPercent().compareTo(percent) == 0) - && currentCharge.getReason() != null) { - res += currentCharge.getReason() + " "; - } - } + if (charges == null) { + return ""; } - res = res.substring(0, res.length() - 1); - return res; + return Arrays.stream(charges) + .filter(currentCharge -> (percent == null || currentCharge.getTaxPercent().compareTo(percent) == 0)) + .map(IZUGFeRDAllowanceCharge::getReason) + .filter(Objects::nonNull) + .collect(Collectors.joining(" ")); } /*** * returns a (potentially concatenated) string of allowance reasons, or * "Allowances", if none are defined - * + * * @param percent a specific rate, or null for any rate * @return the space separated String */ @@ -122,7 +122,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider { /*** * returns total of allowances for this tax rate - * + * * @param percent a specific rate, or null for any rate * @return the total amount */ @@ -134,25 +134,25 @@ public class TransactionCalculator implements IAbsoluteValueProvider { /*** * returns the total net value of all items, without document level * charges/allowances - * + * * @return item sum */ protected BigDecimal getTotal() { BigDecimal dec = Stream.of(trans.getZFItems()).map(LineCalculator::new) - .map(LineCalculator::getItemTotalNetAmount).reduce(ZERO, BigDecimal::add); + .map(LineCalculator::getItemTotalNetAmount).reduce(ZERO, BigDecimal::add); return dec; } /*** * returns the total net value of the invoice, including charges/allowances on * document level - * + * * @return item sum +- charges/allowances */ - protected BigDecimal getTaxBasis() { + public BigDecimal getTaxBasis() { return getTotal().add(getChargesForPercent(null).setScale(2, RoundingMode.HALF_UP)) - .subtract(getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP)) - .setScale(2, RoundingMode.HALF_UP); + .subtract(getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP)) + .setScale(2, RoundingMode.HALF_UP); } /** @@ -167,13 +167,17 @@ public class TransactionCalculator implements IAbsoluteValueProvider { final String vatDueDateTypeCode = trans.getVATDueDateTypeCode(); for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) { - BigDecimal percent = currentItem.getProduct().getVATPercent(); + BigDecimal percent = null; + if (currentItem.getProduct()!=null) + { + percent=currentItem.getProduct().getVATPercent(); + } if (percent != null) { LineCalculator lc = new LineCalculator(currentItem); VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(), - currentItem.getProduct().getTaxCategoryCode(), vatDueDateTypeCode); - String reasonText=currentItem.getProduct().getTaxExemptionReason(); - if (reasonText!=null) { + currentItem.getProduct().getTaxCategoryCode(), vatDueDateTypeCode); + String reasonText = currentItem.getProduct().getTaxExemptionReason(); + if (reasonText != null) { itemVATAmount.setVatExemptionReasonText(reasonText); } VATAmount current = hm.get(percent.stripTrailingZeros()); @@ -193,8 +197,8 @@ public class TransactionCalculator implements IAbsoluteValueProvider { VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros()); if (theAmount == null) { theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO, - currentCharge.getCategoryCode() != null ? currentCharge.getCategoryCode() : "S", - vatDueDateTypeCode); + currentCharge.getCategoryCode() != null ? currentCharge.getCategoryCode() : "S", + vatDueDateTypeCode); } theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(this))); BigDecimal factor = taxPercent.divide(new BigDecimal(100)); @@ -211,8 +215,8 @@ public class TransactionCalculator implements IAbsoluteValueProvider { VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros()); if (theAmount == null) { theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO, - currentAllowance.getCategoryCode() != null ? currentAllowance.getCategoryCode() : "S", - vatDueDateTypeCode); + currentAllowance.getCategoryCode() != null ? currentAllowance.getCategoryCode() : "S", + vatDueDateTypeCode); } theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this))); BigDecimal factor = taxPercent.divide(new BigDecimal(100)); @@ -239,4 +243,11 @@ public class TransactionCalculator implements IAbsoluteValueProvider { return getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP); } + public BigDecimal getDuePayable() { + BigDecimal res = getGrandTotal().subtract(getTotalPrepaid()); + if (trans.getRoundingAmount() != null) { + res = res.add(trans.getRoundingAmount()); + } + return res; + } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ValidationLogVisualizer.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ValidationLogVisualizer.java new file mode 100644 index 00000000..686daa7c --- /dev/null +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ValidationLogVisualizer.java @@ -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)); + } + } +} diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java index 72718b58..caff7b6c 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2PullProvider.java @@ -277,11 +277,11 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { } String reason = ""; - if ((allowance.getReason() != null) && (profile == Profiles.getByName("Extended") || profile == Profiles.getByName("XRechnung"))) { + if ((allowance.getReason() != null) && (profile == Profiles.getByName("Extended") || profile == Profiles.getByName("XRechnung")) || profile == Profiles.getByName("EN16931")) { reason = "" + XMLTools.encodeXML(allowance.getReason()) + ""; } String reasonCode = ""; - if ((allowance.getReasonCode() != null) && (profile == Profiles.getByName("XRechnung"))) { + if (allowance.getReasonCode() != null) { // only in XRechnung profile reasonCode = "" + allowance.getReasonCode() + ""; } @@ -334,7 +334,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { this.trans = trans; this.calc = new TransactionCalculator(trans); - boolean hasDueDate = false; + boolean hasDueDate = trans.getDueDate() != null; final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); String exemptionReason = ""; @@ -401,6 +401,10 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { int lineID = 0; for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) { lineID++; + String lineIDStr = Integer.toString(lineID); + if (currentItem.getId()!=null) { + lineIDStr=currentItem.getId(); + } if (currentItem.getProduct().getTaxExemptionReason() != null) { exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + ""; } @@ -408,7 +412,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) { xml += "" + "" - + "" + lineID + "" + + "" + lineIDStr + "" + buildItemNotes(currentItem) + "" @@ -454,7 +458,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { if (currentItem.getProduct().getClassifications() != null && currentItem.getProduct().getClassifications().length > 0) { for (IDesignatedProductClassification classification : currentItem.getProduct().getClassifications()) { xml += "" - + ""; } + + if (trans.getDueDate() != null) { + xml += "" // $NON-NLS-2$ + + DATE.udtFormat(trans.getDueDate()) + + "";// 20130704 + } if (trans.getTradeSettlement() != null) { for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) { @@ -834,12 +843,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { } } - if (hasDueDate && (trans.getDueDate() != null)) { - xml += "" // $NON-NLS-2$ - + DATE.udtFormat(trans.getDueDate()) - + "";// 20130704 - - } xml += ""; } else { xml += buildPaymentTermsXml(); @@ -857,7 +860,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { final String chargesTotalLine = "" + currencyFormat(calc.getChargesForPercent(null)) + ""; xml += ""; - if (getProfile() != Profiles.getByName("Minimum")) { + if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BASICWL"))) { xml += "" + currencyFormat(calc.getTotal()) + ""; xml += chargesTotalLine + allowanceTotalLine; @@ -866,14 +869,18 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { // // // currencyID=\"EUR\" + "" - + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "" - + "" + currencyFormat(calc.getGrandTotal()) + ""; + + currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + ""; + if (trans.getRoundingAmount() != null) { + xml += "" + currencyFormat(trans.getRoundingAmount()) + ""; + } + + xml += "" + currencyFormat(calc.getGrandTotal()) + ""; // // // currencyID=\"EUR\" if (getProfile() != Profiles.getByName("Minimum")) { xml += "" + currencyFormat(calc.getTotalPrepaid()) + ""; } - xml += "" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "" + xml += "" + currencyFormat(calc.getDuePayable()) + "" + ""; if (trans.getInvoiceReferencedDocumentID() != null) { xml += "" @@ -886,6 +893,19 @@ public class ZUGFeRD2PullProvider implements IXMLProvider { } xml += ""; } + if (trans.getInvoiceReferencedDocuments() != null) { + for (var doc : trans.getInvoiceReferencedDocuments()) { + xml += "" + + "" + + XMLTools.encodeXML(doc.getIssuerAssignedID()) + ""; + if (doc.getFormattedIssueDateTime() != null) { + xml += "" + + DATE.qdtFormat(doc.getFormattedIssueDateTime()) + + ""; + } + xml += ""; + } + } xml += ""; // + "\n" diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromPDFA.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromPDFA.java index 498ae7dc..c3b9299b 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromPDFA.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDExporterFromPDFA.java @@ -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 { diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java index 4016e2a1..6ff0a4b8 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDImporter.java @@ -13,92 +13,34 @@ package org.mustangproject.ZUGFeRD; * @version 1.1.0 * @author jstaerk */ - import java.io.*; -import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; import java.text.SimpleDateFormat; import java.util.*; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; -import org.apache.commons.io.IOUtils; -import org.apache.pdfbox.Loader; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; -import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; -import org.apache.pdfbox.pdmodel.common.PDNameTreeNode; -import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; -import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.mustangproject.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; -public class ZUGFeRDImporter { +public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter { private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDImporter.class); - /** - * if metadata has been found - */ - protected boolean containsMeta = false; - /** - * map filenames of additional XML files to their contents - */ - private final HashMap additionalXMLs = new HashMap<>(); - /** - * map filenames of all embedded files in the respective PDF - */ - private final ArrayList PDFAttachments = new ArrayList<>(); - /** - * Raw XML form of the extracted data - may be directly obtained. - */ - private byte[] rawXML = null; - /** - * XMP metadata - */ - private String xmpString = null; // XMP metadata - /** - * parsed Document - */ - private Document document; - private Integer version; - - - protected ZUGFeRDImporter() { - //constructor for extending classes + public ZUGFeRDImporter() { + super(); } - public ZUGFeRDImporter(String pdfFilename) { - try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) { - extractLowLevel(bis); - } catch (final IOException e) { - LOGGER.error("Failed to extract ZUGFeRD data", e); - throw new ZUGFeRDExportException(e); - } + public ZUGFeRDImporter(String filename) { + super(filename); } - - public ZUGFeRDImporter(InputStream pdfStream) { - try { - extractLowLevel(pdfStream); - } catch (final IOException e) { - LOGGER.error("Failed to extract ZUGFeRD data", e); - throw new ZUGFeRDExportException(e); - } + public ZUGFeRDImporter(InputStream stream) { + super(stream); } @@ -113,169 +55,21 @@ public class ZUGFeRDImporter { - /** - * Extracts a ZUGFeRD invoice from a PDF document represented by an input stream. Errors are reported via exception handling. - * - * @param inStream a inputstream of a pdf file - */ - private void extractLowLevel(InputStream inStream) throws IOException { - BufferedInputStream pdfStream = new BufferedInputStream(inStream); - byte[] pad = new byte[4]; - pdfStream.mark(0); - pdfStream.read(pad); - pdfStream.reset(); - byte[] pdfSignature = {'%', 'P', 'D', 'F'}; - if (Arrays.equals(pad, pdfSignature)) { // we have a pdf - - - try (PDDocument doc = Loader.loadPDF(IOUtils.toByteArray(pdfStream))) { - // PDDocumentInformation info = doc.getDocumentInformation(); - final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); - //start - - if (doc.getDocumentCatalog() == null || doc.getDocumentCatalog().getMetadata() == null) { - LOGGER.info("no-xmlpart"); - return; - } - - final InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata(); - xmpString = convertStreamToString(XMP); - - final PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles(); - if (etn == null) { - return; - } - - final Map efMap = etn.getNames(); - // String filePath = "/tmp/"; - - if (efMap != null) { - extractFiles(efMap); // see - // https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/ - } else { - - final List> kids = etn.getKids(); - if (kids == null) { - return; - } - for (final PDNameTreeNode node : kids) { - final Map namesL = node.getNames(); - extractFiles(namesL); - } - } - } - } else { - // no PDF probably XML - containsMeta = true; - setRawXML(XMLTools.getBytesFromStream(pdfStream)); - - } - } - - - private void extractFiles(Map names) throws IOException { - for (final String alias : names.keySet()) { - - final PDComplexFileSpecification fileSpec = names.get(alias); - final String filename = fileSpec.getFilename(); - /** - * filenames for invoice data (ZUGFeRD v1 and v2, Factur-X) - */ - - final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); - if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml")) || filename.equals("xrechnung.xml") || filename.equals("order-x.xml") || filename.equals("cida.xml")) { - containsMeta = true; - - // String embeddedFilename = filePath + filename; - // File file = new File(filePath + filename); - // System.out.println("Writing " + embeddedFilename); - // ByteArrayOutputStream fileBytes=new - // ByteArrayOutputStream(); - // FileOutputStream fos = new FileOutputStream(file); - - setRawXML(embeddedFile.toByteArray()); - - // fos.write(embeddedFile.getByteArray()); - // fos.close(); - } - if (filename.startsWith("additional_data")) { - additionalXMLs.put(filename, embeddedFile.toByteArray()); - } - PDFAttachments.add(new FileAttachment(filename, embeddedFile.getSubtype(), "Data", embeddedFile.toByteArray())); - } - } - - - protected Document getDocument() { - return document; - } - - - private void setDocument() throws ParserConfigurationException, IOException, SAXException { - final DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); - xmlFact.setNamespaceAware(true); - final DocumentBuilder builder = xmlFact.newDocumentBuilder(); - final ByteArrayInputStream is = new ByteArrayInputStream(rawXML); - /// is.skip(guessBOMSize(is)); - document = builder.parse(is); - } - - - public void setRawXML(byte[] rawXML) throws IOException { - this.containsMeta = true; - this.rawXML = rawXML; - this.version = null; - try { - setDocument(); - } catch (ParserConfigurationException | SAXException e) { - LOGGER.error("Failed to parse XML", e); - throw new ZUGFeRDExportException(e); - } - } - - - protected String extractString(String xpathStr) { - if (!containsMeta) { - throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found."); - } - final String result; - try { - final Document document = getDocument(); - final XPathFactory xpathFact = XPathFactory.newInstance(); - final XPath xpath = xpathFact.newXPath(); - result = xpath.evaluate(xpathStr, document); - } catch (final XPathExpressionException e) { - LOGGER.error("Failed to evaluate XPath", e); - throw new ZUGFeRDExportException(e); - } - return result; - } - - /*** - * Wrapper for protected method extractString - * @param xpathStr the xpath expression to be evaluated - * @return the extracted String for the specific path in the document - */ - public String wExtractString(String xpathStr) { - return extractString(xpathStr); - } - + //////////////////////////////////// /** * @return the reference (purpose) the sender specified for this invoice */ public String getForeignReference() { - String result = extractString("//*[local-name() = 'ApplicableHeaderTradeSettlement']/*[local-name() = 'PaymentReference']"); - if (result == null || result.isEmpty()) { - result = extractString("//*[local-name() = 'ApplicableSupplyChainTradeSettlement']/*[local-name() = 'PaymentReference']"); - } - return result; + + return importedInvoice.getNumber(); } /** * @return the ZUGFeRD Profile */ public String getZUGFeRDProfil() { + String guideline = extractString("//*[local-name() = 'GuidelineSpecifiedDocumentContextParameter']//*[local-name() = 'ID']"); if (guideline.contains("xrechnung")) { return "XRECHNUNG"; @@ -299,21 +93,6 @@ public class ZUGFeRDImporter { } } - /** - * @return the Invoice Currency Code - */ - public String getInvoiceCurrencyCode() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'ApplicableSupplyChainTradeSettlement']//*[local-name() = 'InvoiceCurrencyCode']"); - } else { - return extractString("//*[local-name() = 'ApplicableHeaderTradeSettlement']//*[local-name() = 'InvoiceCurrencyCode']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } /** * @return the IssuerAssigned ID @@ -336,57 +115,6 @@ public class ZUGFeRDImporter { return extractIssuerAssignedID("ContractReferencedDocument"); } - private String extractIssuerAssignedID(String propertyName) { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'ID']"); - } else { - return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'IssuerAssignedID']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } - - /** - * @return the BuyerTradeParty ID - */ - public String getBuyerTradePartyID() { - return extractString("//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'ID']"); - } - - /** - * @return the Issue Date() - */ - public String getIssueDate() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'HeaderExchangedDocument']//*[local-name() = 'IssueDateTime']//*[local-name() = 'DateTimeString']"); - } else { - return extractString("//*[local-name() = 'ExchangedDocument']//*[local-name() = 'IssueDateTime']//*[local-name() = 'DateTimeString']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } - } - - public Date getDetailedDeliveryPeriodFrom() { - final String toParse = extractString( - "//*[local-name() = 'ApplicableHeaderTradeSettlement']" + - "//*[local-name() = 'BillingSpecifiedPeriod']" + - "//*[local-name() = 'StartDateTime']//*[local-name() = 'DateTimeString']"); - return tryDate(toParse); - } - - public Date getDetailedDeliveryPeriodTo() { - final String toParse = extractString( - "//*[local-name() = 'ApplicableHeaderTradeSettlement']" + - "//*[local-name() = 'BillingSpecifiedPeriod']" + - "//*[local-name() = 'EndDateTime']//*[local-name() = 'DateTimeString']"); - return tryDate(toParse); - } /** * @return the TaxBasisTotalAmount @@ -470,7 +198,16 @@ public class ZUGFeRDImporter { * @return the BuyerTradeParty SpecifiedTaxRegistration ID */ public String getBuyertradePartySpecifiedTaxRegistrationID() { - return extractString("//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'SpecifiedTaxRegistration']//*[local-name() = 'ID']"); + String id = null; + if ((importedInvoice.getRecipient()!=null) && (importedInvoice.getRecipient().getLegalOrganisation()!=null)) { + // this *should* be the official result + id = importedInvoice.getRecipient().getLegalOrganisation().getSchemedID().getID(); + } + // but also provide some fallback + if (id == null) { + id = getBuyerTradePartyID(); + } + return id; } @@ -494,14 +231,14 @@ public class ZUGFeRDImporter { * @return the BuyerTradeParty Name */ public String getBuyerTradePartyName() { - return extractString("//*[local-name() = 'BuyerTradeParty']//*[local-name() = 'Name']"); + return importedInvoice.getRecipient().getName(); } /** * @return the BuyerTradeParty Name */ public String getDeliveryTradePartyName() { - return extractString("//*[local-name() = 'ShipToTradeParty']//*[local-name() = 'Name']"); + return importedInvoice.getDeliveryAddress().getName(); } @@ -525,7 +262,7 @@ public class ZUGFeRDImporter { * @return the Payment Terms */ public String getPaymentTerms() { - return extractString("//*[local-name() = 'SpecifiedTradePaymentTerms']//*[local-name() = 'Description']"); + return importedInvoice.getPaymentTermDescription(); } /** @@ -548,16 +285,7 @@ public class ZUGFeRDImporter { * @return the Invoice ID */ public String getInvoiceID() { - try { - if (getVersion() == 1) { - return extractString("//*[local-name() = 'HeaderExchangedDocument']//*[local-name() = 'ID']"); - } else { - return extractString("//*[local-name() = 'ExchangedDocument']//*[local-name() = 'ID']"); - } - } catch (final Exception e) { - // Exception was already logged - return ""; - } + return importedInvoice.getNumber(); } @@ -615,7 +343,18 @@ public class ZUGFeRDImporter { * @return the sender's account IBAN code */ public String getIBAN() { - return extractString("//*[local-name() = 'PayeePartyCreditorFinancialAccount']/*[local-name() = 'IBANID']"); + if ((importedInvoice==null)||(importedInvoice.getTradeSettlement()==null)) { + return null; + } + for (IZUGFeRDTradeSettlement settlement : importedInvoice.getTradeSettlement()) { + if (settlement instanceof IZUGFeRDTradeSettlementDebit) { + return ((IZUGFeRDTradeSettlementDebit) settlement).getIBAN(); + } + if (settlement instanceof IZUGFeRDTradeSettlementPayment) { + return ((IZUGFeRDTradeSettlementPayment) settlement).getOwnIBAN(); + } + } + return null; } @@ -628,14 +367,7 @@ public class ZUGFeRDImporter { * @return the total payable amount */ public String getAmount() { - String result = extractString("//*[local-name() = 'SpecifiedTradeSettlementHeaderMonetarySummation']/*[local-name() = 'DuePayableAmount']"); - if (result == null || result.isEmpty()) { - - /* fx/zf would be SpecifiedTradeSettlementMonetarySummation - * but ox is SpecifiedTradeSettlementHeaderMonetarySummation...*/ - result = extractString("//*[local-name() = 'GrandTotalAmount']"); - } - return result; + return importedInvoice.getGrandTotal().toPlainString(); } @@ -643,7 +375,60 @@ public class ZUGFeRDImporter { * @return when the payment is due */ public String getDueDate() { - return extractString("//*[local-name() = 'SpecifiedTradePaymentTerms']/*[local-name() = 'DueDateDateTime']/*[local-name() = 'DateTimeString']"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + return sdf.format(importedInvoice.getDueDate()); + } + + + //////////////////// + + /** + * @return the Invoice Currency Code + */ + public String getInvoiceCurrencyCode() { + return importedInvoice.getCurrency(); + } + + + private String extractIssuerAssignedID(String propertyName) { + try { + if (getVersion() == 1) { + return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'ID']"); + } else { + return extractString("//*[local-name() = '" + propertyName + "']//*[local-name() = 'IssuerAssignedID']"); + } + } catch (final Exception e) { + // Exception was already logged + return ""; + } + } + + /** + * @return the BuyerTradeParty ID + */ + public String getBuyerTradePartyID() { + String id = importedInvoice.getRecipient().getID(); + if (id == null) { + // provide some fallback + id = importedInvoice.getRecipient().getVATID(); + } + return id; + } + + /** + * @return the Issue Date() + */ + public String getIssueDate() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + return sdf.format(importedInvoice.getIssueDate()); + } + + public Date getDetailedDeliveryPeriodFrom() { + return importedInvoice.getDetailedDeliveryPeriodFrom(); + } + + public Date getDetailedDeliveryPeriodTo() { + return importedInvoice.getDetailedDeliveryPeriodTo(); } @@ -691,28 +476,6 @@ public class ZUGFeRDImporter { } - public EStandard getStandard() throws Exception { - if (!containsMeta) { - throw new Exception("Not yet parsed"); - } - final String head = getUTF8(); - String rootNode = extractString("local-name(/*)"); - if (rootNode.equals("CrossIndustryDocument")) { - return EStandard.zugferd; - } else if (rootNode.equals("Invoice")) { - return EStandard.ubl; - } else if (rootNode.equals("CrossIndustryInvoice")) { - return EStandard.facturx; - } else if (rootNode.equals("SCRDMCCBDACIDAMessageStructure")) { - return EStandard.despatchadvice; - } else if (head.contains(" getLineItemList() { final List nodeList = getLineItemNodes(); final List lineItemList = new ArrayList<>(); @@ -953,7 +681,7 @@ public class ZUGFeRDImporter { if (node != null) { final NodeList tradeAgreementChildren = node.getChildNodes(); node = getNodeByName(tradeAgreementChildren, "ChargeAmount"); - lineItem.setPrice(tryBigDecimal(getNodeValue(node))); + lineItem.setPrice(XMLTools.tryBigDecimal(node)); node = getNodeByName(tradeAgreementChildren, "BasisQuantity"); if (node != null && node.getAttributes() != null) { final Node unitCodeAttribute = node.getAttributes().getNamedItem("unitCode"); @@ -966,49 +694,65 @@ public class ZUGFeRDImporter { node = getNodeByName(nn.getChildNodes(), "GrossPriceProductTradePrice"); if (node != null) { node = getNodeByName(node.getChildNodes(), "ChargeAmount"); - lineItem.setGrossPrice(tryBigDecimal(getNodeValue(node))); + lineItem.setGrossPrice(XMLTools.tryBigDecimal(node)); } break; case "AssociatedDocumentLineDocument": node = getNodeByName(nn.getChildNodes(), "LineID"); - lineItem.setId(getNodeValue(node)); + lineItem.setId(XMLTools.getNodeValue(node)); break; case "SpecifiedTradeProduct": - + node = getNodeByName(nn.getChildNodes(), "GlobalID"); + if (node != null) { + SchemedID globalId = new SchemedID() + .setScheme(node.getAttributes() + .getNamedItem("schemeID").getNodeValue()) + .setId(XMLTools.getNodeValue(node)); + lineItem.getProduct().addGlobalID(globalId); + } node = getNodeByName(nn.getChildNodes(), "SellerAssignedID"); - lineItem.getProduct().setSellerAssignedID(getNodeValue(node)); + lineItem.getProduct().setSellerAssignedID(XMLTools.getNodeValue(node)); node = getNodeByName(nn.getChildNodes(), "BuyerAssignedID"); - lineItem.getProduct().setBuyerAssignedID(getNodeValue(node)); + lineItem.getProduct().setBuyerAssignedID(XMLTools.getNodeValue(node)); node = getNodeByName(nn.getChildNodes(), "Name"); - lineItem.getProduct().setName(getNodeValue(node)); + lineItem.getProduct().setName(XMLTools.getNodeValue(node)); node = getNodeByName(nn.getChildNodes(), "Description"); - lineItem.getProduct().setDescription(getNodeValue(node)); + lineItem.getProduct().setDescription(XMLTools.getNodeValue(node)); break; case "SpecifiedLineTradeDelivery": case "SpecifiedSupplyChainTradeDelivery": node = getNodeByName(nn.getChildNodes(), "BilledQuantity"); - lineItem.setQuantity(tryBigDecimal(getNodeValue(node))); + lineItem.setQuantity(XMLTools.tryBigDecimal(node)); break; case "SpecifiedLineTradeSettlement": node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); if (node != null) { node = getNodeByName(node.getChildNodes(), "RateApplicablePercent"); - lineItem.getProduct().setVATPercent(tryBigDecimal(getNodeValue(node))); + lineItem.getProduct().setVATPercent(XMLTools.tryBigDecimal(node)); } node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); if (node != null) { node = getNodeByName(node.getChildNodes(), "CalculatedAmount"); - lineItem.setTax(tryBigDecimal(getNodeValue(node))); + lineItem.setTax(XMLTools.tryBigDecimal(node)); } + + node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); + if (node != null) { + node = getNodeByName(node.getChildNodes(), "CategoryCode"); + if(node != null){ + lineItem.getProduct().setTaxCategoryCode(XMLTools.getNodeValue(node)); + } + } + node = getNodeByName(nn.getChildNodes(), "BillingSpecifiedPeriod"); if (node != null) { final Node start = getNodeByName(node.getChildNodes(), "StartDateTime"); @@ -1021,13 +765,13 @@ public class ZUGFeRDImporter { if (end != null) { dateTimeEnd = getNodeByName(end.getChildNodes(), "DateTimeString"); } - lineItem.setDetailedDeliveryPeriod(tryDate(dateTimeStart), tryDate(dateTimeEnd)); + lineItem.setDetailedDeliveryPeriod(XMLTools.tryDate(dateTimeStart), XMLTools.tryDate(dateTimeEnd)); } node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementLineMonetarySummation"); if (node != null) { node = getNodeByName(node.getChildNodes(), "LineTotalAmount"); - lineItem.setLineTotalAmount(tryBigDecimal(getNodeValue(node))); + lineItem.setLineTotalAmount(XMLTools.tryBigDecimal(node)); } break; case "SpecifiedSupplyChainTradeSettlement": @@ -1036,19 +780,19 @@ public class ZUGFeRDImporter { node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); if (node != null) { node = getNodeByName(node.getChildNodes(), "ApplicablePercent"); - lineItem.getProduct().setVATPercent(tryBigDecimal(getNodeValue(node))); + lineItem.getProduct().setVATPercent(XMLTools.tryBigDecimal(node)); } node = getNodeByName(nn.getChildNodes(), "ApplicableTradeTax"); if (node != null) { node = getNodeByName(node.getChildNodes(), "CalculatedAmount"); - lineItem.setTax(tryBigDecimal(getNodeValue(node))); + lineItem.setTax(XMLTools.tryBigDecimal(node)); } node = getNodeByName(nn.getChildNodes(), "SpecifiedTradeSettlementMonetarySummation"); if (node != null) { node = getNodeByName(node.getChildNodes(), "LineTotalAmount"); - lineItem.setLineTotalAmount(tryBigDecimal(getNodeValue(node))); + lineItem.setLineTotalAmount(XMLTools.tryBigDecimal(node)); } break; } @@ -1123,51 +867,4 @@ public class ZUGFeRDImporter { } } - /** - * returns the value of an node - * - * @param node the Node to get the value from - * @return A String or empty String, if no value was found - */ - private String getNodeValue(Node node) { - if (node != null && node.getFirstChild() != null) { - return node.getFirstChild().getNodeValue(); - } - return ""; - } - - /** - * tries to convert an String to BigDecimal. - * - * @param nodeValue The value as String - * @return a BigDecimal with the value provides as String or a BigDecimal with value 0.00 if an error occurs - */ - private BigDecimal tryBigDecimal(String nodeValue) { - try { - return new BigDecimal(nodeValue); - } catch (final Exception e) { - try { - return BigDecimal.valueOf(Float.valueOf(nodeValue)); - } catch (final Exception ex) { - return new BigDecimal("0.00"); - } - } - } - - private Date tryDate(Node node) { - final String nodeValue = getNodeValue(node); - if (nodeValue.isEmpty()) { - return null; - } - return tryDate(nodeValue); - } - - private static Date tryDate(String toParse) { - final SimpleDateFormat formatter = ZUGFeRDDateFormat.DATE.getFormatter(); - try { - return formatter.parse(toParse); - } catch (final Exception e) { - return null; - } - } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java index e330853b..aa249cd6 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDInvoiceImporter.java @@ -1,56 +1,282 @@ package org.mustangproject.ZUGFeRD; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigDecimal; -import java.nio.charset.StandardCharsets; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Base64; -import java.util.Date; -import java.util.List; -import java.util.Objects; - -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - +import org.apache.commons.io.IOUtils; +import org.apache.pdfbox.Loader; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; +import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; +import org.apache.pdfbox.pdmodel.common.PDNameTreeNode; +import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; +import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.mustangproject.*; +import org.mustangproject.Exceptions.ArithmetricException; +import org.mustangproject.Exceptions.StructureException; +import org.mustangproject.util.NodeMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.*; +import java.io.*; +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +public class ZUGFeRDInvoiceImporter { -public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDInvoiceImporter.class.getCanonicalName()); // log - private boolean recalcPrice = false; - private boolean ignoreCalculationErrors = false; - private ArrayList fileAttachments=new ArrayList<>(); + /** + * map filenames of additional XML files to their contents + */ + protected final HashMap additionalXMLs = new HashMap<>(); + /** + * map filenames of all embedded files in the respective PDF + */ + protected final ArrayList PDFAttachments = new ArrayList<>(); + /** + * if metadata has been found + */ + protected boolean containsMeta = false; + /** + * Raw XML form of the extracted data - may be directly obtained. + */ + protected byte[] rawXML = null; + /** + * XMP metadata + */ + protected String xmpString = null; // XMP metadata + /** + * parsed Document + */ + protected Document document; + /*** + * automatically parse into importedInvoice + */ + protected boolean parseAutomatically = true; + protected Integer version; + protected CalculatedInvoice importedInvoice = null; + protected boolean recalcPrice = false; + protected boolean ignoreCalculationErrors = false; public ZUGFeRDInvoiceImporter() { - super(); + //constructor for extending classes } - public ZUGFeRDInvoiceImporter(String filename) { - super(filename); + public ZUGFeRDInvoiceImporter(String pdfFilename) { + setPDFFilename(pdfFilename); } - public ZUGFeRDInvoiceImporter(InputStream stream) { - super(stream); + public ZUGFeRDInvoiceImporter(InputStream pdfStream) { + setInputStream(pdfStream); } - public void fromXML(String XML) { - try { - containsMeta = true; - setRawXML(XML.getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); + public void setPDFFilename(String pdfFilename) { + try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) { + extractLowLevel(bis); + } catch (final IOException e) { + LOGGER.error("Failed to extract ZUGFeRD data", e); + throw new ZUGFeRDExportException(e); } } + public void setInputStream(InputStream pdfStream) { + try { + extractLowLevel(pdfStream); + } catch (final IOException e) { + LOGGER.error("Failed to extract ZUGFeRD data", e); + throw new ZUGFeRDExportException(e); + } + } + + /*** + * return the file names of all files embedded into the PDF + * @see ZUGFeRDInvoiceImporter for XML embedded files please use ZUGFeRDInvoiceImporter.getFileAttachmentsXML + * @return a ArrayList of FileAttachments, empty if none + */ + public List getFileAttachmentsPDF() { + return PDFAttachments; + } + + /** + * Extracts a ZUGFeRD invoice from a PDF document represented by an input stream. Errors are reported via exception handling. + * + * @param inStream a inputstream of a pdf file + */ + private void extractLowLevel(InputStream inStream) throws IOException { + BufferedInputStream pdfStream = new BufferedInputStream(inStream); + byte[] pad = new byte[4]; + pdfStream.mark(0); + pdfStream.read(pad); + pdfStream.reset(); + byte[] pdfSignature = {'%', 'P', 'D', 'F'}; + if (Arrays.equals(pad, pdfSignature)) { // we have a pdf + + + try { + PDDocument doc = Loader.loadPDF(IOUtils.toByteArray(pdfStream)); + // PDDocumentInformation info = doc.getDocumentInformation(); + final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); + //start + + if (doc.getDocumentCatalog() == null || doc.getDocumentCatalog().getMetadata() == null) { + LOGGER.info("no-xmlpart"); + return; + } + + final InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata(); + + xmpString = new String(XMLTools.getBytesFromStream(XMP), StandardCharsets.UTF_8); + + final PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles(); + if (etn == null) { + return; + } + + final Map efMap = etn.getNames(); + // String filePath = "/tmp/"; + + if (efMap != null) { + extractFiles(efMap); // see + // https://memorynotfound.com/apache-pdfbox-extract-embedded-file-pdf-document/ + } else { + + final List> kids = etn.getKids(); + if (kids == null) { + return; + } + for (final PDNameTreeNode node : kids) { + final Map namesL = node.getNames(); + extractFiles(namesL); + } + } + } catch (Exception e) { + LOGGER.error("Failed to parse PDF", e); + //ignore otherwise + } + } else { + // no PDF probably XML + containsMeta = true; + setRawXML(XMLTools.getBytesFromStream(pdfStream)); + + } + } + + /*** + * have the item prices be determined from the line total. + * That's a workaround for some invoices which just put 0 as item price + */ + public void doRecalculateItemPricesFromLineTotals() { + recalcPrice = true; + } + + /*** + * do not raise ParseExceptions even if the reproduced invoice total does not match the given value + */ + public void doIgnoreCalculationErrors() { + ignoreCalculationErrors = true; + } + + /*** + * sets th pdf attachments, and if a file is recognized (e.g. a factur-x.xml) triggers processing + * @param names the Hashmap of String, PDComplexFileSpecification + * @throws IOException + */ + private void extractFiles(Map names) throws IOException { + for (final String alias : names.keySet()) { + + final PDComplexFileSpecification fileSpec = names.get(alias); + final String filename = fileSpec.getFilename(); + /** + * filenames for invoice data (ZUGFeRD v1 and v2, Factur-X) + */ + + final PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile(); + if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml")) || filename.equals("xrechnung.xml") || filename.equals("order-x.xml") || filename.equals("cida.xml")) { + containsMeta = true; + + // String embeddedFilename = filePath + filename; + // File file = new File(filePath + filename); + // System.out.println("Writing " + embeddedFilename); + // ByteArrayOutputStream fileBytes=new + // ByteArrayOutputStream(); + // FileOutputStream fos = new FileOutputStream(file); + + setRawXML(embeddedFile.toByteArray()); + + // fos.write(embeddedFile.getByteArray()); + // fos.close(); + } + if (filename.startsWith("additional_data")) { + additionalXMLs.put(filename, embeddedFile.toByteArray()); + } + PDFAttachments.add(new FileAttachment(filename, embeddedFile.getSubtype(), "Data", embeddedFile.toByteArray())); + } + } + + /*** + * set the xml of a CII invoice + * @param rawXML the xml string + * @param doParse automatically parse input for zugferdImporter (not ZUGFeRDInvoiceImporter) + * @throws IOException if parsing xml throws it (unlikely its string based) + */ + public void setRawXML(byte[] rawXML, boolean doParse) throws IOException { + this.containsMeta = true; + this.rawXML = rawXML; + this.version = null; + parseAutomatically = doParse; + + try { + setDocument(); + } catch (ParserConfigurationException | SAXException | ParseException e) { + LOGGER.error("Failed to parse XML", e); + throw new ZUGFeRDExportException(e); + } + + } + + /*** + * set the xml of a CII invoice, simple version + * @param rawXML the cii(?) as a string + * @throws IOException if parsing xml throws it (unlikely its string based) + */ + public void setRawXML(byte[] rawXML) throws IOException { + setRawXML(rawXML, true); + } + + private void setDocument() throws ParserConfigurationException, IOException, SAXException, ParseException { + final DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance(); + xmlFact.setNamespaceAware(true); + final DocumentBuilder builder = xmlFact.newDocumentBuilder(); + final ByteArrayInputStream is = new ByteArrayInputStream(rawXML); + /// is.skip(guessBOMSize(is)); + document = builder.parse(is); + if (parseAutomatically) { + try { + importedInvoice = new CalculatedInvoice(); + extractInto(importedInvoice); + } catch (XPathExpressionException e) { + throw new RuntimeException(e); + } + } + } + + public void setID(String id) { + String ud = id; + } /*** * This will parse a XML into the given invoice object @@ -63,6 +289,8 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { String number = ""; String typeCode = null; + String deliveryPeriodStart = null; + String deliveryPeriodEnd = null; /* * dummywerte sind derzeit noch setDueDate setIssueDate setDeliveryDate * setSender setRecipient setnumber bspw. due date @@ -72,13 +300,135 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { XPath xpath = xpathFact.newXPath(); XPathExpression xpr = xpath.compile("//*[local-name()=\"SellerTradeParty\"]|//*[local-name()=\"AccountingSupplierParty\"]/*"); NodeList SellerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + XPathExpression shipEx = xpath.compile("//*[local-name()=\"ShipToTradeParty\"]"); + NodeList deliveryNodes = (NodeList) shipEx.evaluate(getDocument(), XPathConstants.NODESET); + if (deliveryNodes != null) { + zpp.setDeliveryAddress(new TradeParty(deliveryNodes)); + } + + List includedNotes = new ArrayList<>(); + + //UBL... + XPathExpression UBLNotesEx = xpath.compile("/*[local-name()=\"Invoice\"]/*[local-name()=\"Note\"]"); + NodeList UBLNotesNd = (NodeList) UBLNotesEx.evaluate(getDocument(), XPathConstants.NODESET); + if ((UBLNotesNd != null) && (UBLNotesNd.getLength() > 0)) { + for (int nodeIndex = 0; nodeIndex < UBLNotesNd.getLength(); nodeIndex++) { + includedNotes.add(IncludedNote.generalNote(UBLNotesNd.item(nodeIndex).getTextContent())); + } + zpp.addNotes(includedNotes); + } + + XPathExpression shipExUBL = xpath.compile("//*[local-name()=\"Delivery\"]"); + Node deliveryNode = (Node) shipExUBL.evaluate(getDocument(), XPathConstants.NODE); + + if (deliveryNode != null) { + TradeParty delivery = new TradeParty(); + new NodeMap(deliveryNode).getAsNodeMap("DeliveryLocation").ifPresent( + deliveryLocationNodeMap -> { + + deliveryLocationNodeMap.getNode("ID").ifPresent(s -> { + if (s.getAttributes().getNamedItem("schemeID") != null) { + SchemedID sID = new SchemedID().setScheme(s.getAttributes().getNamedItem("schemeID").getTextContent()).setId(s.getTextContent()); + delivery.addGlobalID(sID); + } + }); + deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { + s.getAsString("StreetName").ifPresent(t -> delivery.setStreet(t)); + }); + deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { + s.getAsString("AdditionalStreetName").ifPresent(t -> delivery.setAdditionalAddress(t)); + }); + deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { + s.getAsString("CityName").ifPresent(t -> delivery.setLocation(t)); + }); + deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { + s.getAsString("PostalZone").ifPresent(t -> delivery.setZIP(t)); + }); + deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { + s.getAsNodeMap("Country").ifPresent(t -> t.getAsString("IdentificationCode").ifPresent(u -> delivery.setCountry(u))); + }); + deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { + s.getAsNodeMap("AddressLine").ifPresent(t -> t.getAsString("Line").ifPresent(u -> delivery.setAdditionalAddressExtension(u))); + }); + deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { + s.getAsString("AdditionalStreetName").ifPresent(t -> delivery.setAdditionalAddress(t)); + }); + deliveryLocationNodeMap.getAsNodeMap("Address").ifPresent(s -> { + s.getAsString("AdditionalStreetName").ifPresent(t -> delivery.setAdditionalAddress(t)); + }); + }); + + + new NodeMap(deliveryNode).getAsNodeMap("DeliveryParty").ifPresent(partyMap -> { + partyMap.getAsNodeMap("PartyName").ifPresent(s -> { + s.getAsString("Name").ifPresent(t -> delivery.setName(t)); + }); + }); + String street, name, additionalStreet, city, postal, countrySubentity, line, country = null; +/* + String idx = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"ID\"]"); + street = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name()=\"Address\"]/*[local-name()=\"StreetName\"]"); + additionalStreet = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]/*[local-name() = \"AdditionalStreetName\"]"); + city = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]/*[local-name() = \"CityName\"]"); + postal = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]/*[local-name() = \"PostalZone\"]"); + countrySubentity = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]/*[local-name() = \"CountrySubentity\"]"); + line = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]//*[local-name() = \"AddressLine\"]/*[local-name() = \"Line\"]"); + country = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"Address\"]//*[local-name() = \"Country\"]/*[local-name() = \"IdentificationCode\"]"); + name = extractString("//*[local-name()=\"DeliveryLocation\"]/*[local-name() = \"DeliveryParty\"]//*[local-name() = \"PartyName\"]/*[local-name() = \"Name\"]"); +*/ + zpp.setDeliveryAddress(delivery); + /* + zpp.setDeliveryAddress(new TradeParty() + .setStreet(street) + .setAdditionalAddress(additionalStreet) + .setLocation(city) + .setZIP(postal) + .setAdditionalAddressExtension(line) + .setCountry(country) + .setName(name) + ); +*/ + + } + xpr = xpath.compile("//*[local-name()=\"BuyerTradeParty\"]|//*[local-name()=\"AccountingCustomerParty\"]/*"); NodeList BuyerNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - xpr = xpath.compile("//*[local-name()=\"PayeeTradeParty\"]|//*[local-name()=\"PayeeParty\"]/*"); + xpr = xpath.compile("//*[local-name()=\"PayeeTradeParty\"]"); NodeList payeeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + // UBL + XPathExpression shipPayee = xpath.compile("//*[local-name()=\"PayeeParty\"]/*"); + NodeList ublPayeeNodes = (NodeList) shipPayee.evaluate(getDocument(), XPathConstants.NODESET); + +// if(ublPayeeNodes != null) { +// TradeParty payee = new TradeParty(); +// NodeMap nodeMap = new NodeMap(ublPayeeNodes).getAsNodeMap("PayeeParty").get(); +// nodeMap.getNode("ID").ifPresent(s -> { +// SchemedID sID = new SchemedID().setScheme(s.getAttributes().getNamedItem("schemeID").getTextContent()).setId(s.getTextContent()); +// payee.addGlobalID(sID); +// }); +// } + //NodeList UBLpayeeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + zpp.setPayee(new TradeParty(ublPayeeNodes)); +// TradeParty payee =new TradeParty(); +// NodeMap payeeID = new NodeMap(UBLpayeeNodes).getAsNodeMap("PartyIdentification").get(); +// if (payeeID !=null) { +// payeeID.getAsString("Name").ifPresent(t->payee.setName(t)); +// } +// if (payeeNodes != null) { +// TradeParty payee =new TradeParty(); +// NodeMap nodeMap = new NodeMap(payeeNodes).getAsNodeMap("PartyIdentification").get(); +// if (nodeMap != null) { +// nodeMap.getNode("ID").ifPresent(s -> { +// SchemedID sID = new SchemedID().setScheme(s.getAttributes().getNamedItem("schemeID").getTextContent()).setId(s.getTextContent()); +// payee.addGlobalID(sID); +// }); +// } +// } + + xpr = xpath.compile("//*[local-name()=\"ExchangedDocument\"]|//*[local-name()=\"HeaderExchangedDocument\"]"); NodeList ExchangedDocumentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); @@ -86,48 +436,134 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { BigDecimal expectedGrandTotal = null; NodeList totalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); if (totalNodes.getLength() > 0) { - expectedGrandTotal = new BigDecimal(totalNodes.item(0).getTextContent()); + expectedGrandTotal = new BigDecimal(XMLTools.trimOrNull(totalNodes.item(0))); + if (zpp instanceof CalculatedInvoice) { + // usually we would re-calculate the invoice to get expectedGrandTotal + // however, for "minimal" invoices or other invoices without lines + // this will not work + ((CalculatedInvoice) zpp).setGrandTotal(expectedGrandTotal); + } } - xpr = xpath.compile("//*[local-name()=\"PrepaidAmount\"]"); + xpr = xpath.compile("//*[local-name()=\"TaxBasisTotalAmount\"]|//*[local-name()=\"TaxExclusiveAmount\"]"); + BigDecimal expectedTaxBasis = null; + NodeList basisNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + if (basisNodes.getLength() > 0) { + expectedTaxBasis = new BigDecimal(XMLTools.trimOrNull(basisNodes.item(0))); + if (zpp instanceof CalculatedInvoice) { + // usually we would re-calculate the invoice to get expectedGrandTotal + // however, for "minimal" invoices or other invoices without lines + // this will not work + ((CalculatedInvoice) zpp).setTaxBasis(expectedTaxBasis); + } + } + + xpr = xpath.compile("//*[local-name()=\"TotalPrepaidAmount\"]|//*[local-name()=\"PrepaidAmount\"]"); NodeList prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); if (prepaidNodes.getLength() > 0) { - zpp.setTotalPrepaidAmount(new BigDecimal(prepaidNodes.item(0).getTextContent())); + zpp.setTotalPrepaidAmount(new BigDecimal(XMLTools.trimOrNull(prepaidNodes.item(0)))); + } + + + xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"LineTotalAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"LineExtensionAmount\"]"); + NodeList lineTotalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + if (lineTotalNodes.getLength() > 0) { + if (zpp instanceof CalculatedInvoice) { + ((CalculatedInvoice) zpp).setLineTotalAmount(new BigDecimal(XMLTools.trimOrNull(lineTotalNodes.item(0)))); + } + } + + xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"DuePayableAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"PayableAmount\"]"); + NodeList lineDueNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + BigDecimal duePayableAmount = null; + if (lineDueNodes.getLength() > 0) { + duePayableAmount = new BigDecimal(XMLTools.trimOrNull(lineDueNodes.item(0))); + if (zpp instanceof CalculatedInvoice) { + ((CalculatedInvoice) zpp).setDuePayable(duePayableAmount); + } } Date issueDate = null; Date dueDate = null; Date deliveryDate = null; String despatchAdviceReferencedDocument = null; - for (int i = 0; i < ExchangedDocumentNodes.getLength(); i++) { - // nodes.item(i).getTextContent())) { + for (int i = 0; i < ExchangedDocumentNodes.getLength(); i++) { Node exchangedDocumentNode = ExchangedDocumentNodes.item(i); NodeList exchangedDocumentChilds = exchangedDocumentNode.getChildNodes(); for (int documentChildIndex = 0; documentChildIndex < exchangedDocumentChilds.getLength(); documentChildIndex++) { Node item = exchangedDocumentChilds.item(documentChildIndex); if ((item.getLocalName() != null) && (item.getLocalName().equals("ID"))) { - number = item.getTextContent(); + number = XMLTools.trimOrNull(item); } if ((item.getLocalName() != null) && (item.getLocalName().equals("TypeCode"))) { - typeCode = item.getTextContent(); + typeCode = XMLTools.trimOrNull(item); } if ((item.getLocalName() != null) && (item.getLocalName().equals("IssueDateTime"))) { NodeList issueDateTimeChilds = item.getChildNodes(); for (int issueDateChildIndex = 0; issueDateChildIndex < issueDateTimeChilds.getLength(); issueDateChildIndex++) { if ((issueDateTimeChilds.item(issueDateChildIndex).getLocalName() != null) && (issueDateTimeChilds.item(issueDateChildIndex).getLocalName().equals("DateTimeString"))) { - issueDate = new SimpleDateFormat("yyyyMMdd").parse(issueDateTimeChilds.item(issueDateChildIndex).getTextContent()); + issueDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(issueDateTimeChilds.item(issueDateChildIndex))); } } } + if ((item.getLocalName() != null) && (item.getLocalName().equals("IncludedNote"))) { + String subjectCode = ""; + String content = null; + NodeList includedNodeChilds = item.getChildNodes(); + for (int issueDateChildIndex = 0; issueDateChildIndex < includedNodeChilds.getLength(); issueDateChildIndex++) { + if ((includedNodeChilds.item(issueDateChildIndex).getLocalName() != null) + && (includedNodeChilds.item(issueDateChildIndex).getLocalName().equals("Content"))) { + content = XMLTools.trimOrNull(includedNodeChilds.item(issueDateChildIndex)); + } + if ((includedNodeChilds.item(issueDateChildIndex).getLocalName() != null) + && (includedNodeChilds.item(issueDateChildIndex).getLocalName().equals("SubjectCode"))) { + subjectCode = XMLTools.trimOrNull(includedNodeChilds.item(issueDateChildIndex)); + } + } + switch (subjectCode) { + case "AAI": + includedNotes.add(IncludedNote.generalNote(content)); + break; + case "REG": + includedNotes.add(IncludedNote.regulatoryNote(content)); + break; + case "ABL": + includedNotes.add(IncludedNote.legalNote(content)); + break; + case "CUS": + includedNotes.add(IncludedNote.customsNote(content)); + break; + case "SUR": + includedNotes.add(IncludedNote.sellerNote(content)); + break; + case "TXD": + includedNotes.add(IncludedNote.taxNote(content)); + break; + case "ACY": + includedNotes.add(IncludedNote.introductionNote(content)); + break; + case "AAK": + includedNotes.add(IncludedNote.discountBonusNote(content)); + break; + default: + includedNotes.add(IncludedNote.unspecifiedNote(content)); + break; + } + } } } + zpp.addNotes(includedNotes); String rootNode = extractString("local-name(/*)"); if (rootNode.equals("Invoice")) { // UBL... number = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"ID\"]").trim(); - issueDate = new SimpleDateFormat("yyyy-MM-dd").parse(extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"IssueDate\"]").trim()); + typeCode = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"InvoiceTypeCode\"]").trim(); + String issueDateStr = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"IssueDate\"]").trim(); + if (issueDateStr.length()>0) { + issueDate = new SimpleDateFormat("yyyy-MM-dd").parse(issueDateStr); + } String dueDt = extractString("//*[local-name()=\"Invoice\"]/*[local-name()=\"DueDate\"]").trim(); if (dueDt.length() > 0) { dueDate = new SimpleDateFormat("yyyy-MM-dd").parse(dueDt); @@ -137,11 +573,11 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { deliveryDate = new SimpleDateFormat("yyyy-MM-dd").parse(deliveryDt); } } - xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeDelivery\"]"); + + xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeDelivery\"]|//*[local-name()=\"Delivery\"]"); NodeList headerTradeDeliveryNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); for (int i = 0; i < headerTradeDeliveryNodes.getLength(); i++) { - // nodes.item(i).getTextContent())) { Node headerTradeDeliveryNode = headerTradeDeliveryNodes.item(i); NodeList headerTradeDeliveryChilds = headerTradeDeliveryNode.getChildNodes(); for (int deliveryChildIndex = 0; deliveryChildIndex < headerTradeDeliveryChilds.getLength(); deliveryChildIndex++) { @@ -155,7 +591,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { for (int occurenceChildIndex = 0; occurenceChildIndex < occurenceChilds.getLength(); occurenceChildIndex++) { if ((occurenceChilds.item(occurenceChildIndex).getLocalName() != null) && (occurenceChilds.item(occurenceChildIndex).getLocalName().equals("DateTimeString"))) { - deliveryDate = new SimpleDateFormat("yyyyMMdd").parse(occurenceChilds.item(occurenceChildIndex).getTextContent()); + deliveryDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(occurenceChilds.item(occurenceChildIndex))); } } } @@ -167,7 +603,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { for (int despatchAdviceChildIndex = 0; despatchAdviceChildIndex < despatchAdviceChilds.getLength(); despatchAdviceChildIndex++) { if (despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName() != null && despatchAdviceChilds.item(despatchAdviceChildIndex).getLocalName().equals("IssuerAssignedID")) { - despatchAdviceReferencedDocument = despatchAdviceChilds.item(despatchAdviceChildIndex).getTextContent(); + despatchAdviceReferencedDocument = XMLTools.trimOrNull(despatchAdviceChilds.item(despatchAdviceChildIndex)); } } } @@ -180,7 +616,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { String buyerOrderIssuerAssignedID = null; String sellerOrderIssuerAssignedID = null; for (int i = 0; i < headerTradeAgreementNodes.getLength(); i++) { - // nodes.item(i).getTextContent())) { + // XMLTools.trimOrNull(nodes.item(i)))) { Node headerTradeAgreementNode = headerTradeAgreementNodes.item(i); NodeList headerTradeAgreementChilds = headerTradeAgreementNode.getChildNodes(); for (int agreementChildIndex = 0; agreementChildIndex < headerTradeAgreementChilds.getLength(); agreementChildIndex++) { @@ -190,7 +626,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { for (int buyerOrderChildIndex = 0; buyerOrderChildIndex < buyerOrderChilds.getLength(); buyerOrderChildIndex++) { if ((buyerOrderChilds.item(buyerOrderChildIndex).getLocalName() != null) && (buyerOrderChilds.item(buyerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) { - buyerOrderIssuerAssignedID = buyerOrderChilds.item(buyerOrderChildIndex).getTextContent(); + buyerOrderIssuerAssignedID = XMLTools.trimOrNull(buyerOrderChilds.item(buyerOrderChildIndex)); } } } @@ -200,7 +636,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { for (int sellerOrderChildIndex = 0; sellerOrderChildIndex < sellerOrderChilds.getLength(); sellerOrderChildIndex++) { if ((sellerOrderChilds.item(sellerOrderChildIndex).getLocalName() != null) && (sellerOrderChilds.item(sellerOrderChildIndex).getLocalName().equals("IssuerAssignedID"))) { - sellerOrderIssuerAssignedID = sellerOrderChilds.item(sellerOrderChildIndex).getTextContent(); + sellerOrderIssuerAssignedID = XMLTools.trimOrNull(sellerOrderChilds.item(sellerOrderChildIndex)); } } } @@ -210,69 +646,118 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { } + String currency = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"InvoiceCurrencyCode\"]|//*[local-name()=\"DocumentCurrencyCode\"]"); + zpp.setCurrency(currency); + + String paymentTermsDescription = extractString("//*[local-name()=\"SpecifiedTradePaymentTerms\"]/*[local-name()=\"Description\"]|//*[local-name()=\"PaymentTerms\"]/*[local-name()=\"Note\"]"); + if ((paymentTermsDescription!=null)&&(!paymentTermsDescription.isEmpty())) { + zpp.setPaymentTermDescription(paymentTermsDescription); + } + + xpr = xpath.compile("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]|//*[local-name()=\"ApplicableSupplyChainTradeSettlement\"]"); NodeList headerTradeSettlementNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); List bankDetails = new ArrayList<>(); + String directDebitMandateID = null; + String IBAN = null, BIC = null; for (int i = 0; i < headerTradeSettlementNodes.getLength(); i++) { - // nodes.item(i).getTextContent())) { + // XMLTools.trimOrNull(nodes.item(i)))) { Node headerTradeSettlementNode = headerTradeSettlementNodes.item(i); + NodeList headerTradeSettlementChilds = headerTradeSettlementNode.getChildNodes(); for (int settlementChildIndex = 0; settlementChildIndex < headerTradeSettlementChilds.getLength(); settlementChildIndex++) { if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradePaymentTerms"))) { NodeList paymentTermChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) { + if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("Description"))) { + zpp.setPaymentTermDescription(paymentTermChilds.item(paymentTermChildIndex).getTextContent()); + } if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DueDateDateTime"))) { NodeList dueDateChilds = paymentTermChilds.item(paymentTermChildIndex).getChildNodes(); for (int dueDateChildIndex = 0; dueDateChildIndex < dueDateChilds.getLength(); dueDateChildIndex++) { if ((dueDateChilds.item(dueDateChildIndex).getLocalName() != null) && (dueDateChilds.item(dueDateChildIndex).getLocalName().equals("DateTimeString"))) { - dueDate = new SimpleDateFormat("yyyyMMdd").parse(dueDateChilds.item(dueDateChildIndex).getTextContent()); + dueDate = new SimpleDateFormat("yyyyMMdd").parse(XMLTools.trimOrNull(dueDateChilds.item(dueDateChildIndex))); } } } + if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DirectDebitMandateID"))) { + directDebitMandateID = paymentTermChilds.item(paymentTermChildIndex).getTextContent(); + } } } if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("SpecifiedTradeSettlementPaymentMeans"))) { NodeList paymentMeansChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); + IBAN = null; + BIC = null; for (int paymentMeansChildIndex = 0; paymentMeansChildIndex < paymentMeansChilds.getLength(); paymentMeansChildIndex++) { - String IBAN = null, BIC = null; - if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeePartyCreditorFinancialAccount"))) { + + if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeePartyCreditorFinancialAccount") || paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayerPartyDebtorFinancialAccount"))) { NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes(); for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) { if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("IBANID"))) {//CII - IBAN = accountChilds.item(accountChildIndex).getTextContent(); + IBAN = XMLTools.trimOrNull(accountChilds.item(accountChildIndex)); } } } - if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeePartyCreditorFinancialInstitution"))) { + if ((paymentMeansChilds.item(paymentMeansChildIndex).getLocalName() != null) && (paymentMeansChilds.item(paymentMeansChildIndex).getLocalName().equals("PayeeSpecifiedCreditorFinancialInstitution"))) { NodeList accountChilds = paymentMeansChilds.item(paymentMeansChildIndex).getChildNodes(); for (int accountChildIndex = 0; accountChildIndex < accountChilds.getLength(); accountChildIndex++) { if ((accountChilds.item(accountChildIndex).getLocalName() != null) && (accountChilds.item(accountChildIndex).getLocalName().equals("BICID"))) {//CII - BIC = accountChilds.item(accountChildIndex).getTextContent(); + BIC = XMLTools.trimOrNull(accountChilds.item(accountChildIndex)); } } } - if (IBAN != null) { - BankDetails bd = new BankDetails(IBAN); - if (BIC != null) { - bd.setBIC(BIC); + + } + if (IBAN != null) { + BankDetails bd = new BankDetails(IBAN); + if (BIC != null) { + bd.setBIC(BIC); + } + bankDetails.add(bd); + } + } + if ((headerTradeSettlementChilds.item(settlementChildIndex).getLocalName() != null) + && (headerTradeSettlementChilds.item(settlementChildIndex).getLocalName().equals("BillingSpecifiedPeriod"))) { + NodeList periodChilds = headerTradeSettlementChilds.item(settlementChildIndex).getChildNodes(); + for (int periodChildIndex = 0; periodChildIndex < periodChilds.getLength(); periodChildIndex++) { + if ((periodChilds.item(periodChildIndex).getLocalName() != null) && (periodChilds.item(periodChildIndex).getLocalName().equals("StartDateTime"))) { + + NodeList startPeriodChilds = periodChilds.item(periodChildIndex).getChildNodes(); + for (int startPeriodIndex = 0; startPeriodIndex < startPeriodChilds.getLength(); startPeriodIndex++) { + if ((startPeriodChilds.item(startPeriodIndex).getLocalName() != null) && (startPeriodChilds.item(startPeriodIndex).getLocalName().equals("DateTimeString"))) {//CII + deliveryPeriodStart = XMLTools.trimOrNull(startPeriodChilds.item(startPeriodIndex)); + } + } + } + if ((periodChilds.item(periodChildIndex).getLocalName() != null) && (periodChilds.item(periodChildIndex).getLocalName().equals("EndDateTime"))) { + NodeList endPeriodChilds = periodChilds.item(periodChildIndex).getChildNodes(); + for (int endPeriodIndex = 0; endPeriodIndex < endPeriodChilds.getLength(); endPeriodIndex++) { + if ((endPeriodChilds.item(endPeriodIndex).getLocalName() != null) && (endPeriodChilds.item(endPeriodIndex).getLocalName().equals("DateTimeString"))) {//CII + deliveryPeriodEnd = XMLTools.trimOrNull(endPeriodChilds.item(endPeriodIndex)); + } } - bankDetails.add(bd); } } } } } + if ((deliveryPeriodStart != null) && (deliveryPeriodEnd != null)) { + zpp.setDetailedDeliveryPeriod(XMLTools.tryDate(deliveryPeriodStart), XMLTools.tryDate(deliveryPeriodEnd)); + } else if (deliveryPeriodStart != null) { + zpp.setDeliveryDate(XMLTools.tryDate(deliveryPeriodStart)); + } xpr = xpath.compile("//*[local-name()=\"PaymentMeans\"]"); //UBL only NodeList paymentMeansNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); for (int i = 0; i < paymentMeansNodes.getLength(); i++) { - // nodes.item(i).getTextContent())) { + // XMLTools.trimOrNull(nodes.item(i)))) { Node paymentMeansNode = paymentMeansNodes.item(i); NodeList paymentMeansChilds = paymentMeansNode.getChildNodes(); for (int meansChildIndex = 0; meansChildIndex < paymentMeansChilds.getLength(); meansChildIndex++) { @@ -281,7 +766,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { NodeList paymentTermChilds = paymentMeansChilds.item(meansChildIndex).getChildNodes(); for (int paymentTermChildIndex = 0; paymentTermChildIndex < paymentTermChilds.getLength(); paymentTermChildIndex++) { if ((paymentTermChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("ID"))) { - String IBAN = paymentTermChilds.item(paymentTermChildIndex).getTextContent(); + IBAN = XMLTools.trimOrNull(paymentTermChilds.item(paymentTermChildIndex)); if (IBAN != null) { BankDetails bd = new BankDetails(IBAN); bankDetails.add(bd); @@ -289,10 +774,29 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { } } } +// if ((paymentMeansChilds.item(paymentTermChildIndex).getLocalName() != null) && (paymentTermChilds.item(paymentTermChildIndex).getLocalName().equals("DirectDebitMandateID"))) { +// directDebitMandateID = paymentTermChilds.item(paymentTermChildIndex).getTextContent(); +// } + if ((paymentMeansChilds.item(meansChildIndex).getLocalName() != null) + && (paymentMeansChilds.item(meansChildIndex).getLocalName().equals("PaymentMandate"))) { + NodeList paymentMandateChilds = paymentMeansChilds.item(meansChildIndex).getChildNodes(); + for (int paymentMandateChildIndex = 0; paymentMandateChildIndex < paymentMandateChilds.getLength(); paymentMandateChildIndex++) { + if ((paymentMandateChilds.item(paymentMandateChildIndex).getLocalName() != null) && (paymentMandateChilds.item(paymentMandateChildIndex).getLocalName().equals("ID"))) { + directDebitMandateID = paymentMandateChilds.item(paymentMandateChildIndex).getTextContent(); + } + } + + } } + } - zpp.setDueDate(dueDate).setDeliveryDate(deliveryDate).setIssueDate(issueDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentCode(typeCode); + zpp.setIssueDate(issueDate).setDueDate(dueDate).setDeliveryDate(deliveryDate).setSender(new TradeParty(SellerNodes)).setRecipient(new TradeParty(BuyerNodes)).setNumber(number).setDocumentCode(typeCode); + + if ((directDebitMandateID != null) && (IBAN != null)) { + DirectDebit d = new DirectDebit(IBAN, directDebitMandateID); + zpp.getSender().addDebitDetails(d); + } bankDetails.forEach(bankDetail -> zpp.getSender().addBankDetails(bankDetail)); @@ -302,28 +806,57 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { if (buyerOrderIssuerAssignedID != null) { zpp.setBuyerOrderReferencedDocumentID(buyerOrderIssuerAssignedID); + } else { + zpp.setBuyerOrderReferencedDocumentID(extractString("//*[local-name()=\"OrderReference\"]/*[local-name()=\"ID\"]")); } if (sellerOrderIssuerAssignedID != null) { zpp.setSellerOrderReferencedDocumentID(sellerOrderIssuerAssignedID); + } else { + zpp.setSellerOrderReferencedDocumentID(extractString("//*[local-name()=\"OrderReference\"]/*[local-name()=\"SalesOrderID\"]")); } if (despatchAdviceReferencedDocument != null) { zpp.setDespatchAdviceReferencedDocumentID(despatchAdviceReferencedDocument); + } else { + zpp.setDespatchAdviceReferencedDocumentID(extractString("//*[local-name()=\"DespatchDocumentReference\"]/*[local-name()=\"ID\"]")); } + zpp.setInvoiceReferencedDocumentID(extractString("//*[local-name()=\"InvoiceReferencedDocument\"]/*[local-name()=\"IssuerAssignedID\"]|//*[local-name()=\"BillingReference\"]/*[local-name()=\"InvoiceDocumentReference\"]/*[local-name()=\"ID\"]")); + xpr = xpath.compile("//*[local-name()=\"InvoiceReferencedDocument\"]"); + NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + + if (nodes.getLength() != 0) { + for (int i = 0; i < nodes.getLength(); i++) { + + Node currentItemNode = nodes.item(i); + ReferencedDocument doc = ReferencedDocument.fromNode(currentItemNode); + if (doc != null + && (!Objects.equals(zpp.getInvoiceReferencedDocumentID(), doc.getIssuerAssignedID()) + || !Objects.equals(zpp.getInvoiceReferencedIssueDate(), doc.getFormattedIssueDateTime()))) + { + zpp.addInvoiceReferencedDocument(doc); + } + } + } + zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]|//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyName\"]").trim()); + String rounding = extractString("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"RoundingAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"Party\"]/*[local-name()=\"PayableRoundingAmount\"]"); + if ((rounding != null) && (!rounding.isEmpty())) { + zpp.setRoundingAmount(new BigDecimal(rounding.trim())); + } + xpr = xpath.compile("//*[local-name()=\"BuyerReference\"]"); String buyerReference = null; - prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); - if (prepaidNodes.getLength() > 0) { - buyerReference = prepaidNodes.item(0).getTextContent(); + lineTotalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + if (lineTotalNodes.getLength() > 0) { + buyerReference = XMLTools.trimOrNull(lineTotalNodes.item(0)); } if (buyerReference != null) { zpp.setReferenceNumber(buyerReference); } xpr = xpath.compile("//*[local-name()=\"IncludedSupplyChainTradeLineItem\"]|//*[local-name()=\"InvoiceLine\"]"); - NodeList nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); + nodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); if (nodes.getLength() != 0) { for (int i = 0; i < nodes.getLength(); i++) { @@ -338,9 +871,9 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { xpr = xpath.compile("//*[local-name()=\"AttachmentBinaryObject\"]|//*[local-name()=\"EmbeddedDocumentBinaryObject\"]"); NodeList attachmentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); for (int i = 0; i < attachmentNodes.getLength(); i++) { - FileAttachment fa=new FileAttachment(attachmentNodes.item(i).getAttributes().getNamedItem("filename").getNodeValue(),attachmentNodes.item(i).getAttributes().getNamedItem("mimeCode").getNodeValue(),"Data", Base64.getDecoder().decode(attachmentNodes.item(i).getTextContent())); - fileAttachments.add(fa); - // filename = "Aufmass.png" mimeCode = "image/png" + FileAttachment fa = new FileAttachment(attachmentNodes.item(i).getAttributes().getNamedItem("filename").getNodeValue(), attachmentNodes.item(i).getAttributes().getNamedItem("mimeCode").getNodeValue(), "Data", Base64.getDecoder().decode(XMLTools.trimOrNull(attachmentNodes.item(i)))); + zpp.embedFileInXML(fa); + // filename = "Aufmass.png" mimeCode = "image/png" //EmbeddedDocumentBinaryObject cbc:EmbeddedDocumentBinaryObject mimeCode="image/png" filename="Aufmass.png" } @@ -348,7 +881,7 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { // be read, // so the invoice remains arithmetically correct // -> parse document level charges+allowances - xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeAllowanceCharge\"]"); + xpr = xpath.compile("//*[local-name()=\"SpecifiedTradeAllowanceCharge\"]|//*[local-name()=\"AllowanceCharge\"]");//CII and UBL NodeList chargeNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); for (int i = 0; i < chargeNodes.getLength(); i++) { NodeList chargeNodeChilds = chargeNodes.item(i).getChildNodes(); @@ -362,25 +895,35 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { if (chargeChildName != null) { if (chargeChildName.equals("ChargeIndicator")) { - NodeList indicatorChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes(); - for (int indicatorChildIndex = 0; indicatorChildIndex < indicatorChilds.getLength(); indicatorChildIndex++) { - if ((indicatorChilds.item(indicatorChildIndex).getLocalName() != null) - && (indicatorChilds.item(indicatorChildIndex).getLocalName().equals("Indicator"))) { - isCharge = indicatorChilds.item(indicatorChildIndex).getTextContent().equalsIgnoreCase("true"); + if (chargeNodeChilds.item(chargeChildIndex).getTextContent().trim().equalsIgnoreCase("false")) { + // UBL + isCharge = false; + } else if (chargeNodeChilds.item(chargeChildIndex).getTextContent().trim().equalsIgnoreCase("true")) { + // still UBL + isCharge = true; + } else { + //CII + NodeList indicatorChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes(); + for (int indicatorChildIndex = 0; indicatorChildIndex < indicatorChilds.getLength(); indicatorChildIndex++) { + if ((indicatorChilds.item(indicatorChildIndex).getLocalName() != null) + && (indicatorChilds.item(indicatorChildIndex).getLocalName().equals("Indicator"))) { + isCharge = XMLTools.trimOrNull(indicatorChilds.item(indicatorChildIndex)).equalsIgnoreCase("true"); + } } } - } else if (chargeChildName.equals("ActualAmount")) { - chargeAmount = chargeNodeChilds.item(chargeChildIndex).getTextContent(); - } else if (chargeChildName.equals("Reason")) { - reason = chargeNodeChilds.item(chargeChildIndex).getTextContent(); - } else if (chargeChildName.equals("ReasonCode")) { - reasonCode = chargeNodeChilds.item(chargeChildIndex).getTextContent(); - } else if (chargeChildName.equals("CategoryTradeTax")) { + + } else if (chargeChildName.equals("ActualAmount") || chargeChildName.equals("Amount")) { + chargeAmount = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); + } else if (chargeChildName.equals("Reason") || chargeChildName.equals("AllowanceChargeReason")) { + reason = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); + } else if (chargeChildName.equals("ReasonCode") || chargeChildName.equals("AllowanceChargeReasonCode")) { + reasonCode = XMLTools.trimOrNull(chargeNodeChilds.item(chargeChildIndex)); + } else if (chargeChildName.equals("CategoryTradeTax") || chargeChildName.equals("TaxCategory")) { NodeList taxChilds = chargeNodeChilds.item(chargeChildIndex).getChildNodes(); for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) { String taxItemName = taxChilds.item(taxChildIndex).getLocalName(); - if ((taxItemName != null) && (taxItemName.equals("RateApplicablePercent") || taxItemName.equals("ApplicablePercent"))) { - taxPercent = taxChilds.item(taxChildIndex).getTextContent(); + if ((taxItemName != null) && (taxItemName.equals("RateApplicablePercent") || taxItemName.equals("ApplicablePercent") || taxItemName.equals("Percent"))) { + taxPercent = XMLTools.trimOrNull(taxChilds.item(taxChildIndex)); } } } @@ -415,35 +958,119 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { } + TransactionCalculator tc = new TransactionCalculator(zpp); - String expectedStringTotalGross = tc.getGrandTotal() - .subtract(Objects.requireNonNullElse(zpp.getTotalPrepaidAmount(), BigDecimal.ZERO)).toPlainString(); + String calculatedPayableTotal = tc.getDuePayable().toPlainString(); EStandard whichType; try { whichType = getStandard(); } catch (Exception e) { - throw new ParseException("Could not find out if it's an invoice, order, or delivery advice", 0); - + throw new StructureException("Could not find out if it's an invoice, order, or delivery advice", 0); } - if ((whichType != EStandard.despatchadvice) - && ((!expectedStringTotalGross.equals(XMLTools.nDigitFormat(expectedGrandTotal, 2))) - && (!ignoreCalculationErrors))) { - throw new ParseException( - "Could not reproduce the invoice, this could mean that it could not be read properly", 0); + if (whichType != EStandard.despatchadvice && !ignoreCalculationErrors) { + // Check calculation if document type allows it and calculation errors should not be ignored + + String payableTotalFromXml = XMLTools.nDigitFormat(Objects.requireNonNullElse(duePayableAmount, expectedGrandTotal), 2); + if (!calculatedPayableTotal.equals(payableTotalFromXml)) { + String moreDetails = ""; + try { + moreDetails = " with tax basis " + tc.getTaxBasis() + " and with positions " + tc.getTotal() + " = " + + Stream.of(tc.trans.getZFItems()) + .map(item -> new LineCalculator(item).getItemTotalNetAmount().toPlainString()) + .collect(Collectors.joining(" + ")); + } catch (Exception ignored) { + } + throw new ArithmetricException("Payable total in XML is " + payableTotalFromXml + ", but calculated total is " + calculatedPayableTotal + moreDetails); + } } } return zpp; } + protected Document getDocument() { + return document; + } + + protected String extractString(String xpathStr) { + if (!containsMeta) { + throw new ZUGFeRDExportException("No suitable data/ZUGFeRD file could be found."); + } + final String result; + try { + final Document document = getDocument(); + final XPathFactory xpathFact = XPathFactory.newInstance(); + final XPath xpath = xpathFact.newXPath(); + result = xpath.evaluate(xpathStr, document); + } catch (final XPathExpressionException e) { + LOGGER.error("Failed to evaluate XPath", e); + throw new ZUGFeRDExportException(e); + } + return result; + } + + public EStandard getStandard() throws Exception { + if (!containsMeta) { + throw new Exception("Not yet parsed"); + } + final String head = getUTF8(); + String rootNode = extractString("local-name(/*)"); + if (rootNode.equals("CrossIndustryDocument")) { + return EStandard.zugferd; + } else if (rootNode.equals("Invoice")) { + return EStandard.ubl; + } else if (rootNode.equals("CreditNote")) { + return EStandard.ubl; + } else if (rootNode.equals("CrossIndustryInvoice")) { + return EStandard.facturx; + } else if (rootNode.equals("SCRDMCCBDACIDAMessageStructure")) { + return EStandard.despatchadvice; + } else if (head.contains(" getFileAttachmentsXML() { - return fileAttachments; + return new ArrayList<>(Arrays.asList(importedInvoice.getAdditionalReferencedDocuments())); } /*** @@ -460,18 +1087,17 @@ public class ZUGFeRDInvoiceImporter extends ZUGFeRDImporter { } - /*** - * have the item prices be determined from the line total. - * That's a workaround for some invoices which just put 0 as item price - */ - public void doRecalculateItemPricesFromLineTotals() { - recalcPrice = true; - } /*** - * do not raise ParseExceptions even if the reproduced invoice total does not match the given value + * sets the XML for the importer to parse + * @param XML the UBL or CII */ - public void doIgnoreCalculationErrors() { - ignoreCalculationErrors = true; + public void fromXML(String XML) { + try { + containsMeta = true; + setRawXML(XML.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); + } } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java index b2e47e3c..9b5c1e73 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java @@ -20,42 +20,9 @@ */ package org.mustangproject.ZUGFeRD; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Templates; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.URIResolver; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import org.apache.fop.apps.FOPException; -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; -import org.apache.fop.apps.FopFactoryBuilder; +import com.helger.commons.io.stream.StreamHelper; +import org.apache.commons.io.IOUtils; +import org.apache.fop.apps.*; import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.configuration.Configuration; import org.apache.fop.configuration.ConfigurationException; @@ -65,12 +32,19 @@ import org.mustangproject.ClasspathResolverURIAdapter; import org.mustangproject.EStandard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import com.helger.commons.io.stream.StreamHelper; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.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; +import java.util.Optional; public class ZUGFeRDVisualizer { @@ -113,7 +87,7 @@ public class ZUGFeRDVisualizer { * @param fis inputstream (will be consumed) * @return (facturx = cii) */ - public EStandard findOutStandardFromRootNode(InputStream fis) { + private EStandard findOutStandardFromRootNode(InputStream fis) { String zf1Signature = "CrossIndustryDocument"; String zf2Signature = "CrossIndustryInvoice"; @@ -144,111 +118,108 @@ public class ZUGFeRDVisualizer { return null; } - public String visualize(String xmlFilename, Language lang) - throws FileNotFoundException, TransformerException, IOException, SAXException, ParserConfigurationException { - - try { - if (mXsltPDFTemplate == null) { - mXsltPDFTemplate = mFactory.newTemplates( - new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/xr-pdf.xsl"))); - } - if (mXsltHTMLTemplate == null) { - mXsltHTMLTemplate = mFactory.newTemplates(new StreamSource( - CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/xrechnung-html." + lang.name().toLowerCase() + ".xsl"))); - } - if (mXsltZF1HTMLTemplate == null) { - mXsltZF1HTMLTemplate = mFactory.newTemplates(new StreamSource( - CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/ZUGFeRD_1p0_c1p0_s1p0.xslt"))); - } - } catch (TransformerConfigurationException ex) { - LOGGER.error("Failed to init XSLT templates", ex); - } - - /** - * * - * http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf - * http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf - * http://countwordsfree.com/xmlviewer - */ + public String visualize(String xmlFilename, Language lang) throws IOException, TransformerException { FileInputStream fis = new FileInputStream(xmlFilename); - String fileContent = ""; - try { - fileContent = new String(Files.readAllBytes(Paths.get(xmlFilename)), StandardCharsets.UTF_8); - } catch (IOException e2) { - LOGGER.error("Failed to read file content", e2); - } + return visualize(fis, lang); + } - ByteArrayOutputStream iaos = new ByteArrayOutputStream(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + public String visualize(InputStream inputXml, Language lang) throws IOException, TransformerException { + initTemplates(lang); - boolean doPostProcessing = false; + String fileContent = new String(IOUtils.toByteArray(inputXml), StandardCharsets.UTF_8); + EStandard thestandard = findOutStandardFromRootNode(new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8))); + ByteArrayOutputStream htmlOutput = new ByteArrayOutputStream(); - fis = new FileInputStream(xmlFilename); // fis wont reset() so re-read from beginning - EStandard thestandard = findOutStandardFromRootNode(fis); - fis = new FileInputStream(xmlFilename); // fis wont reset() so re-read from beginning + ByteArrayInputStream xmlContentStream = new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8)); if (thestandard == EStandard.zugferd) { - applyZF1XSLT(fis, baos); + applyZF1XSLT(xmlContentStream, htmlOutput); + return htmlOutput.toString(StandardCharsets.UTF_8); } else if (thestandard == EStandard.facturx) { //zf2 or fx - applyZF2XSLT(fis, iaos); - doPostProcessing = true; + applyZF2XSLT(xmlContentStream, htmlOutput); } else if (thestandard == EStandard.ubl) { //zf2 or fx - applyUBL2XSLT(fis, iaos); - doPostProcessing = true; + applyUBL2XSLT(xmlContentStream, htmlOutput); } else if (thestandard == EStandard.ubl_creditnote) { //zf2 or fx - applyUBLCreditNote2XSLT(fis, iaos); - doPostProcessing = true; + applyUBLCreditNote2XSLT(xmlContentStream, htmlOutput); } else if (thestandard == EStandard.orderx) { //zf2 or fx - applyCIO2XSLT(fis, iaos); - doPostProcessing = true; + applyCIO2XSLT(xmlContentStream, htmlOutput); } else { throw new IllegalArgumentException("File does not look like CII or UBL"); } - if (doPostProcessing) { - // take the copy of the stream and re-write it to an InputStream - PipedInputStream in = new PipedInputStream(); - PipedOutputStream out; - try { - out = new PipedOutputStream(in); - new Thread(new Runnable() { - public void run() { - try { - // write the original OutputStream to the PipedOutputStream - // note that in order for the below method to work, you need - // to ensure that the data has finished writing to the - // ByteArrayOutputStream - iaos.writeTo(out); - } catch (IOException e) { - LOGGER.error("Failed to write to stream", e); - } finally { - // close the PipedOutputStream here because we're done writing data - // once this thread has completed its run - StreamHelper.close(out); - } - } - }).start(); - applyXSLTToHTML(in, baos); - } catch (IOException e1) { - LOGGER.error("Failed to create HTML", e1); - } - + Optional in = copyStream(htmlOutput); + ByteArrayOutputStream htmlOutStream = new ByteArrayOutputStream(); + if (in.isPresent()) { + applyXSLTToHTML(in.get(), htmlOutStream); } - return baos.toString(StandardCharsets.UTF_8); + return htmlOutStream.toString(StandardCharsets.UTF_8); + } + + /** + * TODO: jstaerk: why not copy with that simple call: new ByteArrayInputStream(byteArrayOutputStream.toByteArray()) ? + */ + private Optional copyStream(ByteArrayOutputStream byteArrayOutputStream) { + // take the copy of the stream and re-write it to an InputStream + PipedInputStream in = new PipedInputStream(); + try { + PipedOutputStream out = new PipedOutputStream(in); + new Thread(() -> { + try { + // write the original OutputStream to the PipedOutputStream + // note that in order for the below method to work, you need + // to ensure that the data has finished writing to the + // ByteArrayOutputStream + byteArrayOutputStream.writeTo(out); + } catch (IOException e) { + LOGGER.error("Failed to write to stream", e); + } finally { + // close the PipedOutputStream here because we're done writing data + // once this thread has completed its run + StreamHelper.close(out); + } + }).start(); + } catch (IOException e1) { + LOGGER.error("Failed to create HTML", e1); + return Optional.empty(); + } + return Optional.of(in); + } + + + private void initTemplates(Language lang) throws TransformerConfigurationException { + if (mXsltXRTemplate == null) { + mXsltXRTemplate = mFactory.newTemplates( + new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/cii-xr.xsl"))); + } + + if (mXsltHTMLTemplate == null) { + mXsltHTMLTemplate = mFactory.newTemplates(new StreamSource( + CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/xrechnung-html." + lang.name().toLowerCase() + ".xsl"))); + } + if (mXsltZF1HTMLTemplate == null) { + mXsltZF1HTMLTemplate = mFactory.newTemplates(new StreamSource( + CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/ZUGFeRD_1p0_c1p0_s1p0.xslt"))); + } } protected String toFOP(String xmlFilename) - throws FileNotFoundException, TransformerException { + throws IOException, TransformerException { FileInputStream fis = new FileInputStream(xmlFilename); EStandard theStandard = findOutStandardFromRootNode(fis); fis = new FileInputStream(xmlFilename);//rewind :-( + return toFOP(fis, theStandard); + } + + protected String toFOP(InputStream is, EStandard theStandard) + throws TransformerException, IOException { + try { if (mXsltPDFTemplate == null) { mXsltPDFTemplate = mFactory.newTemplates( @@ -259,45 +230,22 @@ public class ZUGFeRDVisualizer { } ByteArrayOutputStream iaos = new ByteArrayOutputStream(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); //zf2 or fx if (theStandard == EStandard.facturx) { - applyZF2XSLT(fis, iaos); + applyZF2XSLT(is, iaos); } else if (theStandard == EStandard.ubl) { - applyUBL2XSLT(fis, iaos); + applyUBL2XSLT(is, iaos); } else if (theStandard == EStandard.ubl_creditnote) { - applyUBLCreditNote2XSLT(fis, iaos); + applyUBLCreditNote2XSLT(is, iaos); } - PipedInputStream in = new PipedInputStream(); - PipedOutputStream out; - try { - out = new PipedOutputStream(in); - new Thread(new Runnable() { - public void run() { - try { - // write the original OutputStream to the PipedOutputStream - // note that in order for the below method to work, you need - // to ensure that the data has finished writing to the - // ByteArrayOutputStream - iaos.writeTo(out); - } catch (IOException e) { - LOGGER.error("Failed to write to stream", e); - } finally { - // close the PipedOutputStream here because we're done writing data - // once this thread has completed its run - StreamHelper.close(out); - } - } - }).start(); - applyXSLTToPDF(in, baos); - } catch (IOException e1) { - LOGGER.error("Failed to create PDF", e1); + Optional in = copyStream(iaos); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + if (in.isPresent()) { + applyXSLTToPDF(in.get(), baos); } - - return baos.toString(StandardCharsets.UTF_8); } @@ -313,7 +261,7 @@ public class ZUGFeRDVisualizer { */ try { result = this.toFOP(XMLinputFile.getAbsolutePath()); - } catch (FileNotFoundException | TransformerException e) { + } catch (TransformerException | IOException e) { LOGGER.error("Failed to apply FOP", e); } DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); @@ -367,7 +315,7 @@ public class ZUGFeRDVisualizer { } } - protected void applyZF2XSLT(final InputStream xmlFile, final OutputStream HTMLOutstream) + protected void applyZF2XSLT(final InputStream xmlFile, final OutputStream htmlOutStream) throws TransformerException { if (mXsltXRTemplate == null) { mXsltXRTemplate = mFactory.newTemplates( @@ -376,10 +324,10 @@ public class ZUGFeRDVisualizer { } Transformer transformer = mXsltXRTemplate.newTransformer(); - transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream)); + transformer.transform(new StreamSource(xmlFile), new StreamResult(htmlOutStream)); } - protected void applyCIO2XSLT(final InputStream xmlFile, final OutputStream HTMLOutstream) + protected void applyCIO2XSLT(final InputStream xmlFile, final OutputStream htmlOutstream) throws TransformerException { if (mXsltCIOTemplate == null) { mXsltCIOTemplate = mFactory.newTemplates( @@ -387,10 +335,10 @@ public class ZUGFeRDVisualizer { } Transformer transformer = mXsltCIOTemplate.newTransformer(); - transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream)); + transformer.transform(new StreamSource(xmlFile), new StreamResult(htmlOutstream)); } - protected void applyUBL2XSLT(final InputStream xmlFile, final OutputStream HTMLOutstream) + protected void applyUBL2XSLT(final InputStream xmlFile, final OutputStream htmlOutStream) throws TransformerException { if (mXsltUBLTemplate == null) { mXsltUBLTemplate = mFactory.newTemplates( @@ -398,10 +346,10 @@ public class ZUGFeRDVisualizer { } Transformer transformer = mXsltUBLTemplate.newTransformer(); - transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream)); + transformer.transform(new StreamSource(xmlFile), new StreamResult(htmlOutStream)); } - protected void applyUBLCreditNote2XSLT(final InputStream xmlFile, final OutputStream HTMLOutstream) + protected void applyUBLCreditNote2XSLT(final InputStream xmlFile, final OutputStream htmlOutStream) throws TransformerException { if (mXsltUBLTemplate == null) { mXsltUBLTemplate = mFactory.newTemplates( @@ -409,28 +357,30 @@ public class ZUGFeRDVisualizer { } Transformer transformer = mXsltUBLTemplate.newTransformer(); - transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream)); + transformer.transform(new StreamSource(xmlFile), new StreamResult(htmlOutStream)); } - protected void applyZF1XSLT(final InputStream xmlFile, final OutputStream HTMLOutstream) + protected void applyZF1XSLT(final InputStream xmlFile, final OutputStream htmlOutStream) throws TransformerException { Transformer transformer = mXsltZF1HTMLTemplate.newTransformer(); - transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream)); + transformer.transform(new StreamSource(xmlFile), new StreamResult(htmlOutStream)); } - protected void applyXSLTToHTML(final InputStream xmlFile, final OutputStream HTMLOutstream) - throws TransformerException { + protected void applyXSLTToHTML(final InputStream xmlFile, final OutputStream htmlOutStream) + throws TransformerException, IOException { Transformer transformer = mXsltHTMLTemplate.newTransformer(); - transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream)); + transformer.transform(new StreamSource(xmlFile), new StreamResult(htmlOutStream)); + xmlFile.close(); } protected void applyXSLTToPDF(final InputStream xmlFile, final OutputStream PDFOutstream) - throws TransformerException { + throws TransformerException, IOException { Transformer transformer = mXsltPDFTemplate.newTransformer(); transformer.transform(new StreamSource(xmlFile), new StreamResult(PDFOutstream)); + xmlFile.close(); } private static class ClasspathResourceURIResolver implements URIResolver { @@ -439,7 +389,7 @@ public class ZUGFeRDVisualizer { } @Override - public Source resolve(String href, String base) throws TransformerException { + public Source resolve(String href, String base) { return new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/" + href)); } } diff --git a/library/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java b/library/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java index c400cbbc..c9ecc2a0 100644 --- a/library/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java +++ b/library/src/main/java/org/mustangproject/ZUGFeRD/model/TaxCategoryCodeTypeConstants.java @@ -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 CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT).collect(Collectors.toSet()); + public static final String FREEEXPORT = "G"; + + public static Set CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT, FREEEXPORT).collect(Collectors.toSet()); } diff --git a/library/src/main/java/org/mustangproject/util/NodeMap.java b/library/src/main/java/org/mustangproject/util/NodeMap.java index 46b82a9a..77064d07 100644 --- a/library/src/main/java/org/mustangproject/util/NodeMap.java +++ b/library/src/main/java/org/mustangproject/util/NodeMap.java @@ -106,7 +106,14 @@ public class NodeMap { * @return the text content of the matching node, converted to BigDecimal */ public Optional getAsBigDecimal(String... localNames) { - return getNode(localNames).map(Node::getTextContent).map(s->new BigDecimal(s.trim())); + return getNode(localNames).map(Node::getTextContent).map(s->{ + try { + return new BigDecimal(s.trim()); + } catch (NumberFormatException e) { + return null; + } + + }); } /** diff --git a/library/src/main/resources/fonts/SourceSansPro-Bold.ttf b/library/src/main/resources/fonts/SourceSansPro-Bold.ttf new file mode 100644 index 00000000..a253fdc2 Binary files /dev/null and b/library/src/main/resources/fonts/SourceSansPro-Bold.ttf differ diff --git a/library/src/main/resources/fonts/SourceSansPro-BoldIt.ttf b/library/src/main/resources/fonts/SourceSansPro-BoldIt.ttf new file mode 100644 index 00000000..61505f23 Binary files /dev/null and b/library/src/main/resources/fonts/SourceSansPro-BoldIt.ttf differ diff --git a/library/src/main/resources/fonts/SourceSansPro-It.ttf b/library/src/main/resources/fonts/SourceSansPro-It.ttf new file mode 100644 index 00000000..51e63421 Binary files /dev/null and b/library/src/main/resources/fonts/SourceSansPro-It.ttf differ diff --git a/library/src/main/resources/fonts/SourceSansPro-Regular.ttf b/library/src/main/resources/fonts/SourceSansPro-Regular.ttf new file mode 100644 index 00000000..d9344ce8 Binary files /dev/null and b/library/src/main/resources/fonts/SourceSansPro-Regular.ttf differ diff --git a/library/src/main/resources/fonts/SourceSerifPro-Bold.ttf b/library/src/main/resources/fonts/SourceSerifPro-Bold.ttf new file mode 100644 index 00000000..5814a6a0 Binary files /dev/null and b/library/src/main/resources/fonts/SourceSerifPro-Bold.ttf differ diff --git a/library/src/main/resources/fonts/SourceSerifPro-BoldIt.ttf b/library/src/main/resources/fonts/SourceSerifPro-BoldIt.ttf new file mode 100644 index 00000000..8a23518c Binary files /dev/null and b/library/src/main/resources/fonts/SourceSerifPro-BoldIt.ttf differ diff --git a/library/src/main/resources/fonts/SourceSerifPro-It.ttf b/library/src/main/resources/fonts/SourceSerifPro-It.ttf new file mode 100644 index 00000000..be263bee Binary files /dev/null and b/library/src/main/resources/fonts/SourceSerifPro-It.ttf differ diff --git a/library/src/main/resources/fonts/SourceSerifPro-Regular.ttf b/library/src/main/resources/fonts/SourceSerifPro-Regular.ttf new file mode 100644 index 00000000..0a05b4dc Binary files /dev/null and b/library/src/main/resources/fonts/SourceSerifPro-Regular.ttf differ diff --git a/library/src/main/resources/fop-config.xconf b/library/src/main/resources/fop-config.xconf index cf01edd3..4d93f97e 100644 --- a/library/src/main/resources/fop-config.xconf +++ b/library/src/main/resources/fop-config.xconf @@ -1,37 +1,57 @@ - - - - true - - - true - - - - - - - 96 - - 96 - - - - - - - - - - - - - - - - classpath:AdobeCompat-v2.icc - - - - + + + + true + + + true + + + + + + + 96 + + 96 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + classpath:AdobeCompat-v2.icc + + + diff --git a/library/src/main/resources/stylesheets/cii-xr.xsl b/library/src/main/resources/stylesheets/cii-xr.xsl index a27035b5..f741c903 100644 --- a/library/src/main/resources/stylesheets/cii-xr.xsl +++ b/library/src/main/resources/stylesheets/cii-xr.xsl @@ -1,2544 +1,2650 @@ - - - - - - Author: - KoSIT Bremen (kosit@finanzen.bremen.de) - - Fassung vom: 2020-06-30+02:00 - modifiziert durch Dr. Jan Thiele am: 2021-02-11+01:00 - Überführt eine zur EN 16931 konforme elektronische Rechnung in der konkreten Syntax UNCEFACT.CII.D16B - in eine Instanz gemäß des Schemas für den Namensraum - urn:ce.eu:en16931:2017:xoev-de:kosit:standard:xrechnung-1. - - Das Skript setzt voraus, dass das zu verarbeitende Dokument valide bzgl. des XML Schemas und der - Schematron-Regeln der Quelle ist. Für nicht valide Dokumente ist das Ergebnis nicht definiert. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; - - - - - - - - - - - - - - - - - - - ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #SKONTO# - - TAGE - WOCHEN - - =#PROZENT=# - - - - - - - ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ILLEGAL DATE FORMAT: <para>Mit diesem Datentyp wird ein kalendarisches Datum - abgebildet, wie es in der ISO 8601 Spezifikation <quote>Calendar date complete representation</quote> - beschrieben ist (siehe ISO 8601:2004, Abschnitt 5.2.1.1). Das Datum beinhaltet keine Zeitangabe. Das - konkret zu verwendende Format ist abhängig von der genutzten Syntax.</para> - <para>Der Datentyp basiert auf dem Typ <quote>Date Time. Type</quote>, wie in ISO - 15000-5:2014 Anhang B definiert.</para> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Liefert einen XPath-Pfad, welches $n eindeutig identifiziert. - - - - - - - - - - - Liefert einen XPath-Pfad, welches $n eindeutig identifiziert. - - - - - / - - - [ - - ] - - - - /@ - - - + + + + + + Author: + KoSIT Bremen (kosit@finanzen.bremen.de) + + Fassung vom: 2020-06-30+02:00 + modifiziert durch Dr. Jan Thiele am: 2021-02-11+01:00 + Überführt eine zur EN 16931 konforme elektronische Rechnung in der konkreten Syntax UNCEFACT.CII.D16B + in eine Instanz gemäß des Schemas für den Namensraum + urn:ce.eu:en16931:2017:xoev-de:kosit:standard:xrechnung-1. + + Das Skript setzt voraus, dass das zu verarbeitende Dokument valide bzgl. des XML Schemas und der + Schematron-Regeln der Quelle ist. Für nicht valide Dokumente ist das Ergebnis nicht definiert. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ; + + + + + + + + + + + + + + + + + + + ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #SKONTO# + + TAGE + WOCHEN + + =#PROZENT=# + + + + + + + ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ILLEGAL DATE FORMAT: <para>Mit diesem Datentyp wird ein kalendarisches Datum + abgebildet, wie es in der ISO 8601 Spezifikation <quote>Calendar date complete representation</quote> + beschrieben ist (siehe ISO 8601:2004, Abschnitt 5.2.1.1). Das Datum beinhaltet keine Zeitangabe. Das + konkret zu verwendende Format ist abhängig von der genutzten Syntax.</para> + <para>Der Datentyp basiert auf dem Typ <quote>Date Time. Type</quote>, wie in ISO + 15000-5:2014 Anhang B definiert.</para> + + + + + + + + + + + + ILLEGAL DATE FORMAT: <para>Mit diesem Datentyp wird ein kalendarisches Datum + abgebildet, wie es in der ISO 8601 Spezifikation <quote>Calendar date complete representation</quote> + beschrieben ist (siehe ISO 8601:2004, Abschnitt 5.2.1.1). Das Datum beinhaltet keine Zeitangabe. Das + konkret zu verwendende Format ist abhängig von der genutzten Syntax.</para> + <para>Der Datentyp basiert auf dem Typ <quote>Date Time. Type</quote>, wie in ISO + 15000-5:2014 Anhang B definiert.</para> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Liefert einen XPath-Pfad, welches $n eindeutig identifiziert. + + + + + + + + + + + Liefert einen XPath-Pfad, welches $n eindeutig identifiziert. + + + + + / + + + [ + + ] + + + + /@ + + + diff --git a/library/src/main/resources/stylesheets/result-pdf.xsl b/library/src/main/resources/stylesheets/result-pdf.xsl new file mode 100644 index 00000000..9ffe8e1e --- /dev/null +++ b/library/src/main/resources/stylesheets/result-pdf.xsl @@ -0,0 +1,243 @@ + + + + + + + + + + + + green + + + red + + + + + green + + + red + + + + + Das ZUGFeRD-PDF ist valide. + + + Das ZUGFeRD-PDF ist nicht valide. + + + + + Es wird empfohlen, das Dokument anzunehmen und weiterzuverarbeiten. + + + Es wird empfohlen, das Dokument zurückzuweisen. + + + + + + + + + + + + + Prüfbericht + + + + + + + + + + + + + Referenz: + + + + + + + + + + Zeitpunkt der Prüfung: + + + + + + + + + + Erkannter Dokumenttyp: + + + + + + + + + Validierungsergebnisse im Detail: + + + + + + + + + Type + + + Code + + + Schwere + + + Text + + + + + + + + + + + + Es gibt weder Hinweise noch Fehler. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + red + Fehler + + + Hinweis + + + + + + + + red + + + + + + + + + + red + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/src/main/resources/stylesheets/xr-pdf.xsl b/library/src/main/resources/stylesheets/xr-pdf.xsl index 153dba41..406e4044 100644 --- a/library/src/main/resources/stylesheets/xr-pdf.xsl +++ b/library/src/main/resources/stylesheets/xr-pdf.xsl @@ -64,7 +64,7 @@ - + - - SourceSerifPro - SourceSerifPro - - - - - - - - - - - 9pt - 12pt - 3 - true - de - - - - - 18pt - - false - all - - - - - 18pt - - bold - 4mm - false - all - always - - - - - 0.5pt solid - 2.5pt - all - 4mm - always - - - - - 9pt - - bold - 0.5pt solid - 4pt 6pt - always - 0 - - - - - 10pt - - bold - 1mm - 2mm - 2mm - all - always - - - - - 2mm - 3mm - 0.5pt dotted - #999999 - always - - - - #eeeeee - 28 - - - 7pt - 10pt - 1mm - 1mm - 2mm - 1mm - - - - 9pt - 10pt - - 1mm - 1mm - 2mm - 2mm - always - - - - - 9pt - left - 0.2mm - 0.2mm - 0mm - 1mm - 0mm - always - - - - 9pt - left - 0.2mm - 0.2mm - 0mm - 1mm - 0mm - always - - - - 9pt - right - 0.2mm - 0.2mm - 0mm - 0mm - 0mm - always - - - - 9pt - left - 0.4mm - 0.2mm - 0mm - 1mm - 0.1pt solid #999999 - always - - - - 9pt - left - 0.4mm - 0.2mm - 0mm - 1mm - 0.1pt solid #999999 - always - - - - 9pt - bold - right - 0.4mm - 0.2mm - 0mm - 0mm - 0.1pt solid #999999 - always - - - - - 10mm - - - - 2mm - always - all - - - - 2mm - - - - - 2pt - 2pt - 100% - fixed - 2mm - - - - bold - - - - - - - - - 80% - italic - - - - 2pt - 2pt - 100% - fixed - 80% - italic - - - \ No newline at end of file + + + + + + SourceSansPro + SourceSerifPro + + + + + + + + + + + 9pt + 12pt + 3 + true + de + + + + + 18pt + + false + all + + + + + 18pt + + bold + 4mm + false + all + always + + + + + 0.5pt solid + 2.5pt + all + 4mm + always + + + + + 9pt + + bold + 0.5pt solid + 4pt 6pt + always + 0 + + + + + 10pt + + bold + 1mm + 2mm + 2mm + all + always + + + + + 2mm + 3mm + 0.5pt dotted + #999999 + always + + + + #eeeeee + 28 + + + 7pt + 10pt + 1mm + 1mm + 2mm + 1mm + + + + 9pt + 10pt + + 1mm + 1mm + 2mm + 2mm + always + + + + + 9pt + left + 0.2mm + 0.2mm + 0mm + 1mm + 0mm + always + + + + 9pt + left + 0.2mm + 0.2mm + 0mm + 1mm + 0mm + always + + + + 9pt + right + 0.2mm + 0.2mm + 0mm + 0mm + 0mm + always + + + + 9pt + left + 0.4mm + 0.2mm + 0mm + 1mm + 0.1pt solid #999999 + always + + + + 9pt + left + 0.4mm + 0.2mm + 0mm + 1mm + 0.1pt solid #999999 + always + + + + 9pt + bold + right + 0.4mm + 0.2mm + 0mm + 0mm + 0.1pt solid #999999 + always + + + + + 10mm + + + + 2mm + always + all + + + + 2mm + + + + + 2pt + 2pt + 100% + fixed + 2mm + + + + bold + + + + + + + + + 80% + italic + + + + 2pt + 2pt + 100% + fixed + 80% + italic + + + diff --git a/library/src/main/resources/stylesheets/xrechnung-html.de.xsl b/library/src/main/resources/stylesheets/xrechnung-html.de.xsl index 9f3afab9..e2a2e930 100644 --- a/library/src/main/resources/stylesheets/xrechnung-html.de.xsl +++ b/library/src/main/resources/stylesheets/xrechnung-html.de.xsl @@ -1,2512 +1,229 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <xsl:value-of select="$i18n.title"/> - - - - -
- -
-
-
- - - - - -
-
- - - -
- - - -
-
-
-
- - - -
- - - -
-
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
-
- - -
-
- -
-
- - -
-
- -
-
- -
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-

:

-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-

:

- -
-
-
-
-
- - -
-
-
:
-
-
-
-
:
-
-
-
-
- - - -
-
-
-
-
-
-
netto
-
-
-
-
-
netto
-
-
-
-
-
netto
-
-
-
-
-
netto
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
brutto
-
-
-
-
-
brutto
-
-
-
-
-
brutto
-
-
-
-
-
brutto
-
-
-
-
-
-
- - - -
-
-
-
-
-
:
-
-
-
-
-
-
netto
-
-
-
-
-
-
%
-
-
-
-
-
-
-
- -
-
:
-
:
-
-
-
-
- - - -
-
-
-
-
-
:
-
-
-
-
-
-
netto
-
-
-
-
-
-
%
-
-
-
-
netto
-
-
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
:
-
-
-
-
-
-
netto
-
-
-
-
-
-
%
-
-
-
-
netto
-
-
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
- - - -
-
-
-
-
-
-
:
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
- -
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
- -
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-

:

-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
%
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
%
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
- -
-
-
-
-
-
-
-
%
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-

:

- -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-
-
- -
- - -
-
-
-
-
- - -
-
-
-
-
- - - -
-
-
-
- -
- -
-
-
-
- -
- -
-
-
-
- -
- -
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
- -
-
-
-
-
- - - -
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
- - - -
-
-
:
-
-
-
-
:
-
-
-
-
- - - -
-
-
-
-
- -
-
-
-
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
- -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/src/main/resources/stylesheets/xrechnung-html.en.xsl b/library/src/main/resources/stylesheets/xrechnung-html.en.xsl index 7fcecea5..c989a430 100644 --- a/library/src/main/resources/stylesheets/xrechnung-html.en.xsl +++ b/library/src/main/resources/stylesheets/xrechnung-html.en.xsl @@ -1,2516 +1,229 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <xsl:value-of select="$i18n.title"/> - - - - -
- -
-
-
- - - - - -
-
- - - -
- - - -
-
-
-
- - - -
- - - -
-
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
-
- - -
-
- -
-
- - -
-
- -
-
- -
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-

:

-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-

:

- -
-
-
-
-
- - -
-
-
:
-
-
-
-
:
-
-
-
-
- - - -
-
-
-
-
-
-
netto
-
-
-
-
-
netto
-
-
-
-
-
netto
-
-
-
-
-
netto
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
brutto
-
-
-
-
-
brutto
-
-
-
-
-
brutto
-
-
-
-
-
brutto
-
-
-
-
-
-
- - - -
-
-
-
-
-
:
-
-
-
-
-
-
netto
-
-
-
-
-
-
%
-
-
-
-
-
-
-
- -
-
:
-
:
-
-
-
-
- - - -
-
-
-
-
-
:
-
-
-
-
-
-
netto
-
-
-
-
-
-
%
-
-
-
-
netto
-
-
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
:
-
-
-
-
-
-
netto
-
-
-
-
-
-
%
-
-
-
-
netto
-
-
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
- - - -
-
-
-
-
-
-
:
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
- -
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
- -
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-

:

-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
%
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
%
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
- -
-
-
-
-
-
-
-
%
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-

:

- -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-
-
- -
- - -
-
-
-
-
- - -
-
-
-
-
- - - -
-
-
-
- -
- -
-
-
-
- -
- -
-
-
-
- -
- -
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
- -
-
-
-
-
- - - -
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
- - - -
-
-
:
-
-
-
-
:
-
-
-
-
- - - -
-
-
-
-
- -
-
-
-
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
- -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/src/main/resources/stylesheets/xrechnung-html.fr.xsl b/library/src/main/resources/stylesheets/xrechnung-html.fr.xsl index 486827b9..5be83bab 100644 --- a/library/src/main/resources/stylesheets/xrechnung-html.fr.xsl +++ b/library/src/main/resources/stylesheets/xrechnung-html.fr.xsl @@ -1,2514 +1,229 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <xsl:value-of select="$i18n.title"/> - - - - -
- -
-
-
- - - - - -
-
- - - -
- - - -
-
-
-
- - - -
- - - -
-
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
-
- - -
-
- -
-
- - -
-
- -
-
- -
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-

:

-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-

:

- -
-
-
-
-
- - -
-
-
:
-
-
-
-
:
-
-
-
-
- - - -
-
-
-
-
-
-
netto
-
-
-
-
-
netto
-
-
-
-
-
netto
-
-
-
-
-
netto
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
brutto
-
-
-
-
-
brutto
-
-
-
-
-
brutto
-
-
-
-
-
brutto
-
-
-
-
-
-
- - - -
-
-
-
-
-
:
-
-
-
-
-
-
netto
-
-
-
-
-
-
%
-
-
-
-
-
-
-
- -
-
:
-
:
-
-
-
-
- - - -
-
-
-
-
-
:
-
-
-
-
-
-
netto
-
-
-
-
-
-
%
-
-
-
-
netto
-
-
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
:
-
-
-
-
-
-
netto
-
-
-
-
-
-
%
-
-
-
-
netto
-
-
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
- - - -
-
-
-
-
-
-
:
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
- -
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
- -
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-

:

-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
%
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
%
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
- -
-
-
-
-
-
-
-
%
-
-
-
-
-
-
-
-
:
-
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-

:

- -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
-
-
-
-
- -
- - -
-
-
-
-
- - -
-
-
-
-
- - - -
-
-
-
- -
- -
-
-
-
- -
- -
-
-
-
- -
- -
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
-
- - - -
-
-
-
-
-
- -
-
-
-
-
- - - -
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
- - - -
-
-
:
-
-
-
-
:
-
-
-
-
- - - -
-
-
-
-
- -
-
-
-
-
- - - -
-
-
-
-
-
-
:
-
-
-
-
:
-
-
-
-
:
-
-
-
-
- -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/src/main/resources/stylesheets/xrechnung-html.univ.xsl b/library/src/main/resources/stylesheets/xrechnung-html.univ.xsl new file mode 100644 index 00000000..92689837 --- /dev/null +++ b/library/src/main/resources/stylesheets/xrechnung-html.univ.xsl @@ -0,0 +1,2355 @@ + + + + + + + + + + + + + + <xsl:value-of select="$i18n.title"/> + + + + +
+ +
+
+
+ + + + + +
+
+ + + +
+ + + +
+
+
+
+ + + +
+ + + +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+
+
+ + + +
+ +
+
+
+ + + +
+ +
+
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+
+
+

:

+
+
+
:
+
+
+
+
:
+
+
+
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+

:

+ +
+
+
+
+
+ + +
+
+
:
+
+
+
+
:
+
+
+
+
+ + + +
+
+
+
+
+
+
netto
+
+
+
+
+
netto
+
+
+
+
+
netto
+
+
+
+
+
netto
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
brutto
+
+
+
+
+
brutto
+
+
+
+
+
brutto
+
+
+
+
+
brutto
+
+
+
+
+
+
+ + + +
+
+
+
+
+
:
+
+
+
+
+
+
netto
+
+
+
+
+
+
%
+
+
+
+
+
+
+
+ +
+
:
+
:
+
+
+
+
+ + + +
+
+
+
+
+
:
+
+
+
+
+
+
netto
+
+
+
+
+
+
%
+
+
+
+
netto
+
+
+
+
+
+
+
+
+
+
:
+
:
+
+
+
+
+
+ + + +
+
+
+
+
+
:
+
+
+
+
+
+
netto
+
+
+
+
+
+
%
+
+
+
+
netto
+
+
+
+
+
+
+
+
+
+
:
+
:
+
+
+
+
+
+ + + +
+
+
+
+
+
:
+
+
+
+
+
+
netto
+
+
+
+
+
+
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
:
+
+ + + +
+
+
+
+
+
+
:
+
+ + + +
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+ +
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+ +
+
+ + + +
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+

:

+
+
:
+
+
+
+
:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
%
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
%
+
+
+
+
+
+
+
+
:
+
:
+
+
+
+
+
+ +
+
+
+
+
+
+
+
%
+
+
+
+
+
+
+
+
:
+
:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+

:

+ +
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + +
+
+
+
+
+ + + +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+ + + +
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+ + +
+
+
+
:
+
+ + +
+
+
+
:
+
+ + +
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+
+ + + +
+
+
+
+
+
+ +
+
+
+
+
+ + + +
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+ + + +
+
+
:
+
+
+
+
:
+
+
+
+
+ + + +
+
+
+
+
+ +
+
+
+
+
+ + + +
+
+
+
+
+
+
:
+
+
+
+
:
+
+
+
+
:
+
+
+
+
+ +
diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java index 03cc04c8..746e7cbb 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/DeSerializationTest.java @@ -21,18 +21,29 @@ */ package org.mustangproject.ZUGFeRD; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import junit.framework.TestCase; +import org.junit.Assert; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; import org.mustangproject.*; +import org.mustangproject.ZUGFeRD.model.EventTimeCodeTypeConstants; +import javax.xml.xpath.XPathExpressionException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Date; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class DeSerializationTest extends TestCase { +public class DeSerializationTest extends ResourceCase { public void testJackson() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); @@ -49,4 +60,736 @@ public class DeSerializationTest extends TestCase { assertEquals("info@company.com", fromJSON.getSender().getUriUniversalCommunicationID()); } + + public void testInvoiceLine() throws JsonProcessingException { + File inputCII = getResourceAsFile("factur-x.xml"); + boolean hasExceptions = false; + + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + try { + zii.fromXML(new String(Files.readAllBytes(inputCII.toPath()), StandardCharsets.UTF_8)); + + } catch (IOException e) { + hasExceptions = true; + } + + CalculatedInvoice ci = new CalculatedInvoice(); + try { + zii.extractInto(ci); + } catch (XPathExpressionException e) { + hasExceptions = true; + } catch (ParseException e) { + hasExceptions = true; + } + ObjectMapper mapper = new ObjectMapper(); + String jsonArray = mapper.writeValueAsString(ci); + assertFalse(hasExceptions); + assertTrue(jsonArray.contains("lineTotalAmount")); + + } + + public void testAllowanceRead() throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + + // [{"stringValue":"a","intValue":1,"booleanValue":true}, + // {"stringValue":"bc","intValue":3,"booleanValue":false}] + + Invoice fromJSON = mapper.readValue("{\n" + + " \"documentCode\": \"380\",\n" + + " \"number\": \"471102\",\n" + + " \"ownOrganisationName\": \"Lieferant GmbH\",\n" + + " \"currency\": \"EUR\",\n" + + " \"issueDate\": \"2018-03-03T23:00:00.000+00:00\",\n" + + " \"deliveryDate\": \"2018-03-03T23:00:00.000+00:00\",\n" + + " \"sender\": {\n" + + " \"name\": \"Lieferant GmbH\",\n" + + " \"zip\": \"80333\",\n" + + " \"street\": \"Lieferantenstraße 20\",\n" + + " \"location\": \"München\",\n" + + " \"country\": \"DE\",\n" + + " \"taxID\": \"201/113/40209\",\n" + + " \"vatID\": \"DE123456789\",\n" + + " \"vatid\": \"DE123456789\"\n" + + " },\n" + + " \"recipient\": {\n" + + " \"name\": \"Kunden AG Mitte\",\n" + + " \"zip\": \"69876\",\n" + + " \"street\": \"Kundenstraße 15\",\n" + + " \"location\": \"Frankfurt\",\n" + + " \"country\": \"DE\"\n" + + " },\n" + + " \"grandTotal\": 234.43,\n" + + " \"zfitems\": [\n" + + " {\n" + + " \"price\": 9.9,\n" + + " \"quantity\": 20,\n" + + " \"tax\": null,\n" + + " \"grossPrice\": null,\n" + + " \"lineTotalAmount\": null,\n" + + " \"basisQuantity\": 1,\n" + + " \"detailedDeliveryPeriodFrom\": null,\n" + + " \"detailedDeliveryPeriodTo\": null,\n" + + " \"id\": null,\n" + + " \"product\": {\n" + + " \"unit\": \"H87\",\n" + + " \"name\": \"Trennblätter A4\",\n" + + " \"taxCategoryCode\": \"S\",\n" + + " \"attributes\": null,\n" + + " \"vatpercent\": 19\n" + + " },\n" + + " \"value\": 9.9\n" + + " }\n" + + " ],\n" + + " \"tradeSettlement\": null,\n" + + " \"ownTaxID\": \"201/113/40209\",\n" + + " \"ownVATID\": \"DE123456789\",\n" + + " \"ownStreet\": \"Lieferantenstraße 20\",\n" + + " \"ownZIP\": \"80333\",\n" + + " \"ownLocation\": \"München\",\n" + + " \"ownCountry\": \"DE\",\n" + + " \"zfallowances\": [\n" + + " {\n" + + " \"totalAmount\": 1,\n" + + " \"taxPercent\": 19,\n" + + " \"reason\": \"Sondernachlass\",\n" + + " \"reasonCode\": null,\n" + + " \"categoryCode\": \"S\",\n" + + " \"charge\": false\n" + + " }\n" + + " ]\n" + + "}", Invoice.class); + TransactionCalculator tc = new TransactionCalculator(fromJSON); + assertEquals(tc.getGrandTotal(), new BigDecimal("234.43")); + assertEquals(fromJSON.getNumber(), fromJSON.getNumber()); + assertEquals(fromJSON.getZFItems().length, fromJSON.getZFItems().length); + + } + + public void testDeserializedFiles() { + File inputUBL = getResourceAsFile("XRECHNUNG_Elektron.ubl.xml"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + zii.doIgnoreCalculationErrors(); + Invoice i = new Invoice(); + String exText = null; + + try { + zii.fromXML(new String(Files.readAllBytes(inputUBL.toPath()), StandardCharsets.UTF_8)); + ObjectMapper mapper = new ObjectMapper(); + zii.extractInto(i); + String json = mapper.writeValueAsString(i); + Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); + + assertEquals("181301674", i.getNumber()); + assertEquals(newInvoiceFromJSON.getNumber(), i.getNumber()); + assertEquals(newInvoiceFromJSON.getAdditionalReferencedDocuments()[0].getFilename(), i.getAdditionalReferencedDocuments()[0].getFilename()); + assertEquals(newInvoiceFromJSON.getAdditionalReferencedDocuments().length, 2); + + + } catch (IOException e) { + exText = e.getMessage(); + } catch (XPathExpressionException e) { + exText = e.getMessage(); + } catch (ParseException e) { + exText = e.getMessage(); + } + assertNull(exText); + + } + + public void testFileSerialization() { + + String base64 = "b25ldHdvdGhyZWU="; + String json = "{\n" + + " \"additionalReferencedDocuments\": [\n" + + " {\n" + + " \"data\": \"" + base64 + "\",\n" + + " \"description\": \"Additional file attachment\",\n" + + " \"filename\": \"text.txt\",\n" + + " \"mimetype\": \"text/plain\",\n" + + " \"relation\": \"Data\"\n" + + " }\n" + + "],\n" + + "\n" + + " \"number\": \"471102\",\n" + + " \"currency\": \"EUR\",\n" + + " \"issueDate\": \"2018-03-04T00:00:00.000+01:00\",\n" + + " \"dueDate\": \"2018-03-04T00:00:00.000+01:00\",\n" + + " \"deliveryDate\": \"2018-03-04T00:00:00.000+01:00\",\n" + + " \"sender\": {\n" + + " \"name\": \"Lieferant GmbH\",\n" + + " \"zip\": \"80333\",\n" + + " \"street\": \"Lieferantenstraße 20\",\n" + + " \"location\": \"München\",\n" + + " \"country\": \"DE\",\n" + + " \"taxID\": \"201/113/40209\",\n" + + " \"vatID\": \"DE123456789\",\n" + + " \"globalID\": \"4000001123452\",\n" + + " \"globalIDScheme\": \"0088\"\n" + + " },\n" + + " \"recipient\": {\n" + + " \"name\": \"Kunden AG Mitte\",\n" + + " \"zip\": \"69876\",\n" + + " \"street\": \"Kundenstraße 15\",\n" + + " \"location\": \"Frankfurt\",\n" + + " \"country\": \"DE\"\n" + + " },\n" + + " \"zfitems\": [\n" + + " {\n" + + " \"price\": 9.9,\n" + + " \"quantity\": 20,\n" + + " \"product\": {\n" + + " \"unit\": \"H87\",\n" + + " \"name\": \"Trennblätter A4\",\n" + + " \"description\": \"\",\n" + + " \"vatpercent\": 19,\n" + + " \"taxCategoryCode\": \"S\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"price\": 5.5,\n" + + " \"quantity\": 50,\n" + + " \"product\": {\n" + + " \"unit\": \"H87\",\n" + + " \"name\": \"Joghurt Banane\",\n" + + " \"description\": \"\",\n" + + " \"vatpercent\": 7,\n" + + " \"taxCategoryCode\": \"S\"\n" + + " }\n" + + " }\n" + + " ]\n" + + "}\n"; + + ObjectMapper mapper = new ObjectMapper(); + + try { + Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); + ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); + zf2p.setProfile(Profiles.getByName("XRechnung")); + zf2p.generateXML(newInvoiceFromJSON); + String theXML = new String(zf2p.getXML()); + assertTrue(theXML.contains("20180304")); + assertTrue(theXML.contains(base64)); + + } catch (Exception e) { + fail("No exception expected"); + } + + } + + + public void testFull300Roundtrip() { + File inputCII = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml"); + + Invoice i = new Invoice(); + String exText = null; + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + zii.doIgnoreCalculationErrors(); + try { + zii.fromXML(new String(Files.readAllBytes(inputCII.toPath()), StandardCharsets.UTF_8)); + ObjectMapper mapper = new ObjectMapper(); + zii.extractInto(i); + String json = mapper.writeValueAsString(i); + Invoice newInvoiceFromJSON = mapper.readValue(json, Invoice.class); + + assertEquals("Test_EeISI_100", i.getNumber()); + assertEquals(newInvoiceFromJSON.getNumber(), i.getNumber()); + + } catch (IOException e) { + exText = e.getMessage(); + } catch (XPathExpressionException e) { + exText = e.getMessage(); + } catch (ParseException e) { + exText = e.getMessage(); + } + assertNull(exText); + + + } + + public void testIssuerAssignedIDRoundtrip() { + String occurrenceFrom = "20201001"; + String occurrenceTo = "20201005"; + String contractID = "376zreurzu0983"; + + String orgID = "0009845"; + String orgname = "Test company"; + String number = "123"; + String priceStr = "1.00"; + String taxID = "9990815"; + BigDecimal price = new BigDecimal(priceStr); + Invoice newInvoiceFromJSON = null; + boolean hasExceptions = false; + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + try { + SchemedID gtin = new SchemedID("0160", "2001015001325"); + SchemedID gln = new SchemedID("0088", "4304171000002"); + Invoice i = new Invoice().setCurrency("CHF").addNote("document level 1/2").addNote("document level 2/2").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()) + .setSellerOrderReferencedDocumentID("9384").setBuyerOrderReferencedDocumentID("28934") + .setDetailedDeliveryPeriod(new SimpleDateFormat("yyyyMMdd").parse(occurrenceFrom), new SimpleDateFormat("yyyyMMdd").parse(occurrenceTo)) + .setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID(taxID).setEmail("sender@test.org").setID(orgID).addVATID("DE0815")) + .setDeliveryAddress(new TradeParty("just the other side of the street", "teststr.12a", "55232", "Entenhausen", "DE").addVATID("DE47110")) + .setContractReferencedDocument(contractID) + .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addGlobalID(gln).setEmail("recipient@test.org").addVATID("DE4711") + .setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE").setFax("++49555123456")).setAdditionalAddress("Hinterhaus 3")) + .addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(16)).addGlobalID(gtin).setSellerAssignedID("4711"), price, new BigDecimal(1.0)).setId("a123").addReferencedLineID("xxx").addNote("item level 1/1").addAllowance(new Allowance(new BigDecimal(0.02)).setReason("item discount").setTaxPercent(new BigDecimal(16))).setDetailedDeliveryPeriod(sdf.parse("2020-01-13"), sdf.parse("2020-01-15"))) + .addCharge(new Charge(new BigDecimal(0.5)).setReason("quick delivery charge").setTaxPercent(new BigDecimal(16))) + .addAllowance(new Allowance(new BigDecimal(0.2)).setReason("discount").setTaxPercent(new BigDecimal(16))) + .addCashDiscount(new CashDiscount(new BigDecimal(2), 14)) + .setDeliveryDate(sdf.parse("2020-11-02")).setNumber(number).setVATDueDateTypeCode(EventTimeCodeTypeConstants.PAYMENT_DATE); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(i); + newInvoiceFromJSON = mapper.readValue(json, Invoice.class); + } catch (ParseException e) { + hasExceptions = true; + } catch (JsonProcessingException e) { + hasExceptions = true; + } + assertEquals(newInvoiceFromJSON.getBuyerOrderReferencedDocumentID(), "28934"); + assertFalse(hasExceptions); + + + } + + public void testDueDateRoundtrip() throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + + // [{"stringValue":"a","intValue":1,"booleanValue":true}, + // {"stringValue":"bc","intValue":3,"booleanValue":false}] + + Invoice fromJSON = mapper.readValue("{\n" + + " \"number\": \"RE - 228\",\n" + + " \"currency\": \"EUR\",\n" + + " \"issueDate\": \"2024-10-24\",\n" + + " \"dueDate\": \"2024-10-26\",\n" + + " \"deliveryDate\": \"2024-10-25\",\n" + + " \"sender\": {\n" + + " \"name\": \"Amazing Company\",\n" + + " \"zip\": \"10000\",\n" + + " \"street\": \"Straße der Kosmonauten 20\",\n" + + " \"location\": \"Berlin\",\n" + + " \"country\": \"DE\",\n" + + " \"taxID\": \"201/113/40209\",\n" + + " \"vatID\": \"DE123456789\",\n" + + " \"globalID\": \"4000001123452\",\n" + + " \"globalIDScheme\": \"0088\"\n" + + " },\n" + + " \"recipient\": {\n" + + " \"name\": \"Amazing Company\",\n" + + " \"zip\": \"1000\",\n" + + " \"street\": \"Straße der Kosmonauten 10\",\n" + + " \"location\": \"Berlin\",\n" + + " \"taxID\": \"201/113/40209\",\n" + + " \"vatID\": \"DE123456789\",\n" + + " \"country\": \"DE\"\n" + + " },\n" + + " \"zfitems\": [\n" + + " {\n" + + " \"price\": 99.9,\n" + + " \"quantity\": 10,\n" + + " \"product\": {\n" + + " \"unit\": \"H87\",\n" + + " \"name\": \"Amazing Archives\",\n" + + " \"description\": \"123\",\n" + + " \"vatpercent\": \"19\",\n" + + " \"taxCategoryCode\": \"3\"\n" + + " }\n" + + " }\n" + + " ]\n" + + "}\n", Invoice.class); + ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); + zf2p.setProfile(Profiles.getByName("XRechnung")); + zf2p.generateXML(fromJSON); + String theXML = new String(zf2p.getXML()); + assertTrue(theXML.contains("20241026")); + + } + + + public void testDirectDebit() throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + + // [{"stringValue":"a","intValue":1,"booleanValue":true}, + // {"stringValue":"bc","intValue":3,"booleanValue":false}] + + boolean exceptions = false; + String theXML = ""; + try { + Invoice fromJSON = mapper.readValue("\n" + + "\t{\n" + + "\t\t\"documentCode\": \"380\",\n" + + "\t\t\"number\": \"F20220031\",\n" + + "\t\t\"referenceNumber\": \"SERVEXEC\",\n" + + "\t\t\"buyerOrderReferencedDocumentID\": \"PO201925478\",\n" + + "\t\t\"ownOrganisationName\": \"LE FOURNISSEUR\",\n" + + "\t\t\"currency\": \"EUR\",\n" + + "\t\t\"issueDate\": \"2022-01-30T23:00:00.000+00:00\",\n" + + "\t\t\"dueDate\": \"2022-03-01T23:00:00.000+00:00\",\n" + + "\t\t\"deliveryDate\": \"2022-01-27T23:00:00.000+00:00\",\n" + + "\t\t\"sender\": {\n" + + "\t\t\"name\": \"LE FOURNISSEUR\",\n" + + "\t\t\t\"zip\": \"75018\",\n" + + "\t\t\t\"street\": \"35 rue d'ici\",\n" + + "\t\t\t\"location\": \"PARIS\",\n" + + "\t\t\t\"country\": \"FR\",\n" + + "\t\t\t\"vatID\": \"FR11123456782\",\n" + + "\t\t\t\"additionalAddress\": \"Seller line 2\",\n" + + "\t\t\t\"additionalAddressExtension\": \"Seller line 3\",\n" + + "\t\t\t\"bankDetails\": [\n" + + "\t\t{\n" + + "\t\t\t\"accountName\": null,\n" + + "\t\t\t\"iban\": \"FR20 1254 2547 2569 8542 5874 698\",\n" + + "\t\t\t\"bic\": \"BIC_MONCOMPTE\"\n" + + "\t\t}\n" + + " ],\n" + + "\t\t\"debitDetails\": [\n" + + "\t\t{\n" + + "\t\t\t\"mandate\": \"MANDATE PT\",\n" + + "\t\t\t\"iban\": \"FR20 1254 2547 2569 8542 5874 698\"\n" + + "\t\t}\n" + + " ],\n" + + "\t\t\"contact\": {\n" + + "\t\t\t\"name\": \"M. CONTACT\",\n" + + "\t\t\t\t\"phone\": \"01 02 03 54 87\",\n" + + "\t\t\t\t\"email\": \"seller@seller.com\",\n" + + "\t\t\t\t\"zip\": null,\n" + + "\t\t\t\t\"street\": null,\n" + + "\t\t\t\t\"location\": null,\n" + + "\t\t\t\t\"country\": null,\n" + + "\t\t\t\t\"fax\": null,\n" + + "\t\t\t\t\"vatid\": null,\n" + + "\t\t\t\t\"id\": null,\n" + + "\t\t\t\t\"additionalAddress\": null\n" + + "\t\t},\n" + + "\t\t\"email\": \"moi@seller.com\",\n" + + "\t\t\t\"vatid\": \"FR11123456782\",\n" + + "\t\t\t\"id\": \"123\",\n" + + "\t\t\t\"legalOrganisation\": {\n" + + "\t\t\t\"schemedID\": null,\n" + + "\t\t\t\t\"tradingBusinessName\": \"SELLER TRADE NAME\"\n" + + "\t\t},\n" + + "\t\t\"globalID\": \"587451236587\",\n" + + "\t\t\t\"globalIDScheme\": \"0088\"\n" + + "\t},\n" + + "\t\t\"recipient\": {\n" + + "\t\t\"name\": \"LE CLIENT\",\n" + + "\t\t\t\"zip\": \"06000\",\n" + + "\t\t\t\"street\": \"MON ADRESSE LIGNE 1\",\n" + + "\t\t\t\"location\": \"MA VILLE\",\n" + + "\t\t\t\"country\": \"FR\",\n" + + "\t\t\t\"vatID\": \"FR 05 987 654 321\",\n" + + "\t\t\t\"additionalAddress\": \"Buyer line 2\",\n" + + "\t\t\t\"additionalAddressExtension\": \"Buyer line 3\",\n" + + "\t\t\t\"contact\": {\n" + + "\t\t\t\"name\": \"Buyer contact name\",\n" + + "\t\t\t\t\"phone\": \"01 01 25 45 87\",\n" + + "\t\t\t\t\"email\": \"buyer@buyer.com\",\n" + + "\t\t\t\t\"zip\": null,\n" + + "\t\t\t\t\"street\": null,\n" + + "\t\t\t\t\"location\": null,\n" + + "\t\t\t\t\"country\": null,\n" + + "\t\t\t\t\"fax\": null,\n" + + "\t\t\t\t\"vatid\": null,\n" + + "\t\t\t\t\"id\": null,\n" + + "\t\t\t\t\"additionalAddress\": null\n" + + "\t\t},\n" + + "\t\t\"email\": \"me@buyer.com\",\n" + + "\t\t\t\"vatid\": \"FR 05 987 654 321\",\n" + + "\t\t\t\"legalOrganisation\": {\n" + + "\t\t\t\"schemedID\": null,\n" + + "\t\t\t\t\"tradingBusinessName\": null\n" + + "\t\t},\n" + + "\t\t\"globalID\": \"3654789851\",\n" + + "\t\t\t\"globalIDScheme\": \"0088\"\n" + + "\t},\n" + + "\t\t\"deliveryAddress\": {\n" + + "\t\t\"name\": \"DEL Name\",\n" + + "\t\t\t\"zip\": \"06000\",\n" + + "\t\t\t\"street\": \"DEL ADRESSE LIGNE 1\",\n" + + "\t\t\t\"location\": \"NICE\",\n" + + "\t\t\t\"country\": \"FR\",\n" + + "\t\t\t\"additionalAddress\": \"DEL line 2\",\n" + + "\t\t\t\"id\": \"PRIVATE_ID_DEL\"\n" + + "\t},\n" + + "\t\t\"payee\": {\n" + + "\t\t\"name\": \"PAYEE NAME\",\n" + + "\t\t\t\"legalOrganisation\": {\n" + + "\t\t\t\"schemedID\": null,\n" + + "\t\t\t\t\"tradingBusinessName\": null\n" + + "\t\t},\n" + + "\t\t\"globalID\": \"587451236586\",\n" + + "\t\t\t\"globalIDScheme\": \"0088\"\n" + + "\t},\n" + + "\t\t\"sellerOrderReferencedDocumentID\": \"SALES REF 2547\",\n" + + "\t\t\"despatchAdviceReferencedDocumentID\": \"DESPADV002\",\n" + + "\t\t\"grandTotal\": 107.82,\n" + + "\t\t\"detailedDeliveryPeriodFrom\": \"2021-12-31T23:00:00.000+00:00\",\n" + + "\t\t\"detailedDeliveryPeriodTo\": \"2022-12-30T23:00:00.000+00:00\",\n" + + "\t\t\"notesWithSubjectCode\": [\n" + + "\t\t{\n" + + "\t\t\t\"content\": \"FOURNISSEUR F SARL au capital de 50 000 EUR\",\n" + + "\t\t\t\"subjectCode\": \"REG\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"content\": \"RCS MAVILLE 123 456 782\",\n" + + "\t\t\t\"subjectCode\": \"ABL\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"content\": \"35 ma rue a moi, code postal Ville Pays – contact@masociete.fr - www.masociete.fr – N° TVA : FR32 123 456 789\",\n" + + "\t\t\t\"subjectCode\": \"AAI\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"content\": \"Tout retard de paiement engendre une pénalité exigible à compter de la date d'échéance, calculée sur la base de trois fois le taux d'intérêt légal.\",\n" + + "\t\t\t\"subjectCode\": null\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"content\": \"Indemnité forfaitaire pour frais de recouvrement en cas de retard de paiement : 40 €.\",\n" + + "\t\t\t\"subjectCode\": null\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"content\": \"Les réglements reçus avant la date d'échéance ne donneront pas lieu à escompte.\",\n" + + "\t\t\t\"subjectCode\": null\n" + + "\t\t}\n" + + " ],\n" + + "\t\t\"zfallowances\": [\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"REMISE VOLUME\",\n" + + "\t\t\t\"reasonCode\": \"71\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"REMISE VOLUME\",\n" + + "\t\t\t\"reasonCode\": \"71\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"REMISE VOLUME\",\n" + + "\t\t\t\"reasonCode\": \"71\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": null,\n" + + "\t\t\t\"reasonCode\": \"100\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 2,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"REMISE VOLUME\",\n" + + "\t\t\t\"reasonCode\": \"71\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"REMISE VOLUME\",\n" + + "\t\t\t\"reasonCode\": \"71\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"REMISE VOLUME\",\n" + + "\t\t\t\"reasonCode\": \"71\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": null,\n" + + "\t\t\t\"reasonCode\": \"100\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1.4,\n" + + "\t\t\t\"taxPercent\": 20,\n" + + "\t\t\t\"reason\": \"REMISE COMMERCIALE\",\n" + + "\t\t\t\"reasonCode\": \"100\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1.2,\n" + + "\t\t\t\"taxPercent\": 10,\n" + + "\t\t\t\"reason\": \"REMISE COMMERCIALE\",\n" + + "\t\t\t\"reasonCode\": \"100\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t}\n" + + " ],\n" + + "\t\t\"zfcharges\": [\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"FRAIS PALETTE\",\n" + + "\t\t\t\"reasonCode\": null,\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"FRAIS PALETTE\",\n" + + "\t\t\t\"reasonCode\": null,\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"FRAIS PALETTE\",\n" + + "\t\t\t\"reasonCode\": null,\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"FRAIS PALETTE\",\n" + + "\t\t\t\"reasonCode\": null,\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": null,\n" + + "\t\t\t\"reasonCode\": \"ADL\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"FRAIS PALETTE\",\n" + + "\t\t\t\"reasonCode\": null,\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 1,\n" + + "\t\t\t\"taxPercent\": null,\n" + + "\t\t\t\"reason\": \"FRAIS PALETTE\",\n" + + "\t\t\t\"reasonCode\": null,\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 2.8,\n" + + "\t\t\t\"taxPercent\": 20,\n" + + "\t\t\t\"reason\": \"FRAIS DEPLACEMENT\",\n" + + "\t\t\t\"reasonCode\": \"FC\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"percent\": null,\n" + + "\t\t\t\"totalAmount\": 0.6,\n" + + "\t\t\t\"taxPercent\": 10,\n" + + "\t\t\t\"reason\": \"FRAIS DEPLACEMENT\",\n" + + "\t\t\t\"reasonCode\": \"ADR\",\n" + + "\t\t\t\"categoryCode\": \"S\"\n" + + "\t\t}\n" + + " ],\n" + + "\t\t\"tradeSettlement\": [\n" + + "\t\t{\n" + + "\t\t\t\"accountName\": null,\n" + + "\t\t\t\"iban\": \"FR20 1254 2547 2569 8542 5874 698\",\n" + + "\t\t\t\"bic\": \"BIC_MONCOMPTE\"\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"mandate\": \"MANDATE PT\",\n" + + "\t\t\t\"iban\": \"FR20 1254 2547 2569 8542 5874 698\"\n" + + "\t\t}\n" + + " ],\n" + + "\t\t\"zfitems\": [\n" + + "\t\t{\n" + + "\t\t\t\"price\": 60,\n" + + "\t\t\t\"quantity\": 1,\n" + + "\t\t\t\"basisQuantity\": 1,\n" + + "\t\t\t\"product\": {\n" + + "\t\t\t\"unit\": \"C62\",\n" + + "\t\t\t\t\"name\": \"REMBOURSEMENT AFFRANCHISSEMENT\",\n" + + "\t\t\t\t\"description\": \"Description\",\n" + + "\t\t\t\t\"taxCategoryCode\": \"Z\",\n" + + "\t\t\t\t\"vatpercent\": 0,\n" + + "\t\t\t\t\"reverseCharge\": false,\n" + + "\t\t\t\t\"intraCommunitySupply\": false,\n" + + "\t\t\t\t\"globalID\": \"598785412598745\",\n" + + "\t\t\t\t\"globalIDScheme\": \"0160\"\n" + + "\t\t},\n" + + "\t\t\t\"buyerOrderReferencedDocumentLineID\": \"1\",\n" + + "\t\t\t\"value\": 60\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"price\": 30,\n" + + "\t\t\t\"quantity\": 3,\n" + + "\t\t\t\"basisQuantity\": 3,\n" + + "\t\t\t\"product\": {\n" + + "\t\t\t\"unit\": \"C62\",\n" + + "\t\t\t\t\"name\": \"FOURNITURES DIVERSES\",\n" + + "\t\t\t\t\"description\": \"Description\",\n" + + "\t\t\t\t\"taxCategoryCode\": \"S\",\n" + + "\t\t\t\t\"vatpercent\": 20,\n" + + "\t\t\t\t\"reverseCharge\": false,\n" + + "\t\t\t\t\"intraCommunitySupply\": false\n" + + "\t\t},\n" + + "\t\t\t\"buyerOrderReferencedDocumentLineID\": \"3\",\n" + + "\t\t\t\"value\": 30\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"price\": 12,\n" + + "\t\t\t\"quantity\": 1,\n" + + "\t\t\t\"basisQuantity\": 1,\n" + + "\t\t\t\"product\": {\n" + + "\t\t\t\"unit\": \"C62\",\n" + + "\t\t\t\t\"name\": \"APPEL\",\n" + + "\t\t\t\t\"description\": \"Description\",\n" + + "\t\t\t\t\"taxCategoryCode\": \"S\",\n" + + "\t\t\t\t\"vatpercent\": 10,\n" + + "\t\t\t\t\"reverseCharge\": false,\n" + + "\t\t\t\t\"intraCommunitySupply\": false\n" + + "\t\t},\n" + + "\t\t\t\"buyerOrderReferencedDocumentLineID\": \"2\",\n" + + "\t\t\t\"value\": 12\n" + + "\t\t}\n" + + " ],\n" + + "\t\t\"ownStreet\": \"35 rue d'ici\",\n" + + "\t\t\"ownCountry\": \"FR\",\n" + + "\t\t\"ownZIP\": \"75018\",\n" + + "\t\t\"ownLocation\": \"PARIS\",\n" + + "\t\t\"ownVATID\": \"FR11123456782\",\n" + + "\t\t\"valid\": false\n" + + "\t}\n", Invoice.class); + ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider(); + zf2p.setProfile(Profiles.getByName("XRechnung")); + zf2p.generateXML(fromJSON); + theXML = new String(zf2p.getXML()); + } catch (Exception e) { + exceptions = true; + } + assertTrue(theXML.contains("pour frais de recouvrement en cas de retard de paiement")); + assertFalse(exceptions); + + } + + } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java index 3a767c97..b7fbede6 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/MustangReaderWriterTest.java @@ -214,8 +214,10 @@ public class MustangReaderWriterTest extends MustangReaderTestCase { public void testForeignImport() { InputStream inputStream = this.getClass().getResourceAsStream("/zugferd_invoice.pdf"); - ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); - + ZUGFeRDImporter zi = new ZUGFeRDImporter(); + zi.doRecalculateItemPricesFromLineTotals(); + zi.doIgnoreCalculationErrors(); + zi.setInputStream(inputStream); // Reading ZUGFeRD String amount = zi.getAmount(); diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ProfilesMinimumBasicWLTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ProfilesMinimumBasicWLTest.java index 045f3c8f..abe0821e 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ProfilesMinimumBasicWLTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ProfilesMinimumBasicWLTest.java @@ -137,7 +137,7 @@ public class ProfilesMinimumBasicWLTest extends TestCase { ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_PDF_FX_MINIMUM_INV); // Reading ZUGFeRD - assertEquals("145.37",zi.getAmount()); + assertEquals("146.37",zi.getAmount()); // assertEquals(zi.getBIC(), ownBIC); // assertEquals(zi.getIBAN(), ownIBAN); assertEquals(ownOrgName, zi.getHolder()); diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/VisualizationTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/VisualizationTest.java index 416eed72..88c4fccf 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/VisualizationTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/VisualizationTest.java @@ -1,230 +1,171 @@ - -/** ********************************************************************** - * - * Copyright 2019 Jochen Staerk - * - * Use is subject to license terms. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - * - *********************************************************************** */ -package org.mustangproject.ZUGFeRD; - -import org.apache.commons.io.IOUtils; -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.*; -import java.io.*; -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",""); - - File expectedResult=getResourceAsFile("factur-x-vis.fr.html"); - expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r","").replace("\n",""); - // 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(" ","").replace("\t",""); - - 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(" ","").replace("\t",""); - // 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",""); - - File expectedResult=getResourceAsFile("factur-x-vis-ubl.en.html"); - expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r","").replace("\n",""); - // 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"); - } - } - -} +/** + * ********************************************************************* + *

+ * Copyright 2019 Jochen Staerk + *

+ * Use is subject to license terms. + *

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

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

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

+ * ********************************************************************** + */ +package org.mustangproject.ZUGFeRD; + +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; +import org.mustangproject.ZUGFeRD.ZUGFeRDVisualizer.Language; +import org.mustangproject.util.ByteArraySearcher; + +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() { + this.runZUGFeRDVisualization("factur-x.xml", "factur-x-vis.fr.html", Language.FR); + } + + public void testCIIVisualizationExtended() { + this.runZUGFeRDVisualization("factur-x-extended.xml", "factur-x-vis-extended.de.html", Language.DE); + } + + public void testUBLCreditNoteVisualizationBasic() { + this.runZUGFeRDVisualization("ubl-creditnote.xml", "factur-x-vis-ubl-creditnote.en.html", Language.EN); + } + + public void testUBLVisualizationBasic() { + this.runZUGFeRDVisualization("ubl/01.01a-INVOICE.ubl.xml", "factur-x-vis-ubl.en.html", Language.EN); + } + + private void runZUGFeRDVisualization(String inputFilename, String resultFileName, Language lang) { + File CIIinputFile = getResourceAsFile(inputFilename); + + String expected = null; + String result = null; + try { + ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer(); + result = zvi.visualize(CIIinputFile.getAbsolutePath(), lang); + Files.write(Paths.get("./target/testout-" + resultFileName), result.getBytes(StandardCharsets.UTF_8)); + + File expectedResult = getResourceAsFile(resultFileName); + expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8) + ; + + } 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()); + } + + + assertNotNull(result); + /* remove file endings so that tests can also pass after checking + out from git with arbitrary options (which may include CSRF changes) + */ + assertEquals(expected.replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", ""), result.replace("\r", "") + .replace("\n", "") + .replace("\t", "") + .replace(" ", "")); + } + + 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"); + } + } + +} diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java index 075ab794..3efa4ccf 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/XRTest.java @@ -129,19 +129,18 @@ public class XRTest extends TestCase { Invoice readInvoice = new Invoice(); ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); try { - - zii.setRawXML(zf2p.getXML()); + zii.setRawXML(zf2p.getXML(), false); zii.extractInto(readInvoice); } catch (ParseException | XPathExpressionException xp) { - fail("Exception not expected"); + fail("ParseException not expected"); } catch (IOException e) { - throw new RuntimeException(e); + fail("IOException not expected"); } - List attachedFiles=zii.getFileAttachmentsXML(); + FileAttachment[] attachedFiles=readInvoice.getAdditionalReferencedDocuments(); assertNotNull(attachedFiles); - assertEquals(attachedFiles.size(), 1); + assertEquals(attachedFiles.length, 1); - assertTrue(Arrays.equals(attachedFiles.get(0).getData(), b)); + assertTrue(Arrays.equals(attachedFiles[0].getData(), b)); } diff --git a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java index be949c34..b8012b57 100644 --- a/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java +++ b/library/src/test/java/org/mustangproject/ZUGFeRD/ZF2PushTest.java @@ -22,6 +22,7 @@ package org.mustangproject.ZUGFeRD; import java.io.ByteArrayInputStream; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; @@ -29,6 +30,7 @@ import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; import org.mustangproject.*; import org.junit.FixMethodOrder; @@ -61,9 +63,9 @@ public class ZF2PushTest extends TestCase { final String TARGET_REVERSECHARGEPDF = "./target/testout-ZF2PushReverseCharge.pdf"; public void testPushExport() { - /*** - * This writes to a filename like an official sample, please consider when changing (probably better not?) - */ + /*** + * This writes to a filename like an official sample, please consider when changing (probably better not?) + */ // the writing part String orgname = "Bei Spiel GmbH"; String number = "RE-20201121/508"; @@ -88,6 +90,7 @@ public class ZF2PushTest extends TestCase { .addItem(new Item(new Product("Design (hours)", "Of a sample invoice", "HUR", new BigDecimal(7)), price, new BigDecimal(1.0))) .addItem(new Item(new Product("Ballons", "various colors, ~2000ml", "H87", new BigDecimal(19)), new BigDecimal("0.79"), new BigDecimal(400.0))) .addItem(new Item(new Product("Hot air „heiße Luft“ (litres)", "", "LTR", new BigDecimal(19)), new BigDecimal("0.025"), new BigDecimal(800.0))) + .setRoundingAmount(new BigDecimal("1")) ); ze.export(TARGET_PDF); @@ -95,6 +98,15 @@ public class ZF2PushTest extends TestCase { fail("Exception should not be raised"); } + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF); + Invoice i = new Invoice(); + try { + zii.extractInto(i); + } catch (XPathExpressionException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); + } // now check the contents (like MustangReaderTest) @@ -128,6 +140,7 @@ public class ZF2PushTest extends TestCase { String senderDescription = "Kleinunternehmer"; String taxID = "9990815"; + String theNote="oh lala"; BigDecimal price = new BigDecimal(priceStr); try { InputStream SOURCE_PDF = this.getClass().getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf"); @@ -145,7 +158,7 @@ public class ZF2PushTest extends TestCase { .setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711") .setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))) .setNumber(number) - .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(0)).setTaxExemptionReason("Kleinunternehmer gemäß §19 UStG").setTaxCategoryCode("E"), price, new BigDecimal(1.0))) + .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(0)).setTaxExemptionReason("Kleinunternehmer gemäß §19 UStG").setTaxCategoryCode("E"), price, new BigDecimal(1.0)).addNote(theNote)) ); String theXML = new String(ze.getProvider().getXML()); assertTrue(theXML.contains(" * Copyright 2019 Jochen Staerk - * + *

* Use is subject to license terms. - * + *

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

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

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

+ * ********************************************************************** + */ package org.mustangproject.ZUGFeRD; import java.io.IOException; @@ -99,9 +101,9 @@ public class ZF2Test extends MustangReaderTestCase { public IZUGFeRDExportableItem[] getZFItems() { final Item[] allItems = new Item[3]; final Product designProduct = new Product("", "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung", "HUR", - new BigDecimal("7.000000")); + new BigDecimal("7.000000")); final Product balloonProduct = new Product("", "Bestellerweiterung für E&F Umbau", "C62", - new BigDecimal("19.000000"));// test for issue 103 + new BigDecimal("19.000000"));// test for issue 103 final Product airProduct = new Product("", "Heiße Luft pro Liter", "LTR", new BigDecimal("19.000000")); allItems[0] = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct); @@ -166,12 +168,12 @@ public class ZF2Test extends MustangReaderTestCase { // the writing part try (InputStream SOURCE_PDF = this.getClass() - .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"); + .getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505PDFA3.pdf"); ZUGFeRDExporterFromA3 ze = new ZUGFeRDExporterFromA3().setProducer("My Application") - .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("EN16931") - .load(SOURCE_PDF)) { - + .setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile("EN16931") + .load(SOURCE_PDF)) { + ze.setTransaction(this); final String theXML = new String(ze.getProvider().getXML()); assertTrue(theXML.contains(" @@ -21,11 +20,19 @@ */ package org.mustangproject.ZUGFeRD; -import org.mustangproject.FileAttachment; -import org.mustangproject.Invoice; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.apache.commons.codec.binary.StringUtils; +import org.junit.jupiter.api.Test; +import org.mustangproject.*; import javax.xml.xpath.XPathExpressionException; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -33,6 +40,10 @@ import java.nio.file.Paths; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; /*** @@ -65,6 +76,7 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase { assertEquals("LTR", invoice.getZFItems()[2].getProduct().getUnit()); assertEquals("7.00", invoice.getZFItems()[0].getProduct().getVATPercent().toString()); assertEquals("RE-20170509/505", invoice.getNumber()); + assertEquals("Zahlbar ohne Abzug bis zum 30.05.2017", invoice.getPaymentTermDescription()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); assertEquals("2017-05-09", sdf.format(invoice.getIssueDate())); @@ -113,8 +125,10 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase { // Reading ZUGFeRD assertEquals("Bei Spiel GmbH", invoice.getOwnOrganisationName()); assertEquals(3, invoice.getZFItems().length); + assertEquals(invoice.getZFItems()[0].getNotesWithSubjectCode().get(0).getContent(),"Something"); + assertEquals(invoice.getZFItems()[0].getNotesWithSubjectCode().size(),1); assertEquals("400", invoice.getZFItems()[1].getQuantity().toString()); - + assertEquals("Zahlbar ohne Abzug bis zum 30.05.2017", invoice.getPaymentTermDescription()); assertEquals("AB321", invoice.getReferenceNumber()); assertEquals("160", invoice.getZFItems()[0].getPrice().toString()); assertEquals("Heiße Luft pro Liter", invoice.getZFItems()[2].getProduct().getName()); @@ -270,12 +284,16 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase { public void testXRImport() { boolean hasExceptions = false; - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + ZUGFeRDImporter zii = new ZUGFeRDImporter(); + + int version=-1; try { zii.fromXML(new String(Files.readAllBytes(Paths.get("./target/testout-XR-Edge.xml")), StandardCharsets.UTF_8)); - + version=zii.getVersion(); } catch (IOException e) { hasExceptions = true; + } catch (Exception e) { + throw new RuntimeException(e); } Invoice invoice = null; @@ -285,28 +303,43 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase { hasExceptions = true; } assertFalse(hasExceptions); + + + TransactionCalculator tc = new TransactionCalculator(invoice); assertEquals(new BigDecimal("1.00"), tc.getGrandTotal()); + assertEquals(version,2); + assertTrue(new BigDecimal("1").compareTo(invoice.getZFItems()[0].getQuantity()) == 0); + LineCalculator lc=new LineCalculator(invoice.getZFItems()[0]); + assertTrue(new BigDecimal("1").compareTo(lc.getItemTotalNetAmount()) == 0); + + assertTrue(invoice.getTradeSettlement().length == 1); + assertTrue(invoice.getTradeSettlement()[0] instanceof IZUGFeRDTradeSettlementPayment); + IZUGFeRDTradeSettlementPayment paym = (IZUGFeRDTradeSettlementPayment) invoice.getTradeSettlement()[0]; + assertEquals("DE12500105170648489890", paym.getOwnIBAN()); + assertEquals("COBADEFXXX", paym.getOwnBIC()); + + assertTrue(invoice.getPayee() != null); assertEquals("VR Factoring GmbH", invoice.getPayee().getName()); } /** * testing if other files embedded in pdf additionally to the invoice can be read correctly - * */ + */ public void testDetach() { boolean hasExceptions = false; - byte[] fileA=null; - byte[] fileB=null; + byte[] fileA = null; + byte[] fileB = null; ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter("./target/testout-ZF2PushAttachments.pdf"); - for (FileAttachment fa:zii.getFileAttachmentsPDF()) { + for (FileAttachment fa : zii.getFileAttachmentsPDF()) { if (fa.getFilename().equals("one.pdf")) { - fileA=fa.getData(); + fileA = fa.getData(); } else if (fa.getFilename().equals("two.pdf")) { - fileB=fa.getData(); + fileB = fa.getData(); } } byte[] b = {12, 13}; // the sample data that was used to write the files @@ -318,36 +351,127 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase { } -/* - public void testEEISI_300_cii_Import() { - boolean hasExceptions = false; - File input = getResourceAsFile("not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel2.ubl.xml"); - - - ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(); + public void testImportDebit() { + File CIIinputFile = getResourceAsFile("cii/minimalDebit.xml"); try { - zii.fromXML(new String(Files.readAllBytes(input.toPath()), StandardCharsets.UTF_8)); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile)); + Invoice i = zii.extractInvoice(); + + assertEquals("DE21860000000086001055", i.getSender().getBankDetails().get(0).getIBAN()); + ObjectMapper mapper = new ObjectMapper(); + + String jsonArray = mapper.writeValueAsString(i); + + // assertEquals("",jsonArray); } catch (IOException e) { - hasExceptions = true; + fail("IOException not expected"); + } catch (XPathExpressionException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); } - Invoice invoice = null; - try { - invoice = zii.extractInvoice(); - assertEquals("Seller contact point",invoice.getSender().getName()); - /* - Seller contact point - +41 345 654455 - seller@contact.de);* - } catch (XPathExpressionException | ParseException e) { - hasExceptions = true; - } - assertFalse(hasExceptions); - TransactionCalculator tc = new TransactionCalculator(invoice); - assertEquals(new BigDecimal("205.00"), tc.getGrandTotal()); } -*/ + public void testImportMinimum() { + File CIIinputFile = getResourceAsFile("cii/facturFrMinimum.xml"); + try { + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(CIIinputFile)); + + + CalculatedInvoice i = new CalculatedInvoice(); + zii.extractInto(i); + assertEquals("671.15", i.getGrandTotal().toString()); + + } catch (IOException e) { + fail("IOException not expected"); + } catch (XPathExpressionException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); + } + + + } + + + @Test + public void testImportPrepaid() throws XPathExpressionException, ParseException { + InputStream inputStream = this.getClass() + .getResourceAsStream("/EN16931_1_Teilrechnung.pdf"); + ZUGFeRDInvoiceImporter importer = new ZUGFeRDInvoiceImporter(); + importer.doIgnoreCalculationErrors(); + importer.setInputStream(inputStream); + + CalculatedInvoice invoice = new CalculatedInvoice(); + importer.extractInto(invoice); + + boolean isBD=invoice.getTotalPrepaidAmount() instanceof BigDecimal; + assertTrue(isBD); + BigDecimal expectedPrepaid=new BigDecimal(50); + BigDecimal expectedLineTotal=new BigDecimal("180.76"); + BigDecimal expectedDue=new BigDecimal("147.65"); + if (isBD) { + BigDecimal amread=invoice.getTotalPrepaidAmount(); + BigDecimal importedLineTotal=invoice.getLineTotalAmount(); + BigDecimal importedDuePayable=invoice.getDuePayable(); + assertTrue(amread.compareTo(expectedPrepaid) == 0); + assertTrue(importedLineTotal.compareTo(expectedLineTotal) == 0); + assertTrue(importedDuePayable.compareTo(expectedDue) == 0); + } + + } + + + @Test + public void testImportIncludedNotes() throws XPathExpressionException, ParseException { + InputStream inputStream = this.getClass() + .getResourceAsStream("/EN16931_Einfach.pdf"); + ZUGFeRDInvoiceImporter importer = new ZUGFeRDInvoiceImporter(inputStream); + Invoice invoice = importer.extractInvoice(); + List notesWithSubjectCode = invoice.getNotesWithSubjectCode(); + assertThat(notesWithSubjectCode).hasSize(2); + assertThat(notesWithSubjectCode.get(0).getSubjectCode()).isNull(); + assertThat(notesWithSubjectCode.get(0).getContent()).isEqualTo("Rechnung gemäß Bestellung vom 01.11.2024."); + assertThat(notesWithSubjectCode.get(1).getSubjectCode()).isEqualTo(SubjectCode.REG); + assertThat(notesWithSubjectCode.get(1).getContent()).isEqualTo("Lieferant GmbH\t\t\t\t\n" + + "Lieferantenstraße 20\t\t\t\t\n" + + "80333 München\t\t\t\t\n" + + "Deutschland\t\t\t\t\n" + + "Geschäftsführer: Hans Muster\n" + + "Handelsregisternummer: H A 123"); + + } + + @Test + public void testImportPositionIncludedNotes() throws FileNotFoundException, XPathExpressionException, ParseException { + File inputFile = getResourceAsFile("ZTESTZUGFERD_1_INVDSS_012015738820PDF-1.pdf"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile)); + + Invoice invoice = zii.extractInvoice(); + assertEquals(1, invoice.getZFItems().length); + assertEquals(8, invoice.getZFItems()[0].getNotesWithSubjectCode().size()); + assertEquals("FB-LE 9999", invoice.getZFItems()[0].getNotesWithSubjectCode().stream().filter(note -> note.getSubjectCode().equals(SubjectCode.ABZ)).findFirst().get().getContent()); + } + + @Test + public void testImportXRechnungPositionNote() throws FileNotFoundException, XPathExpressionException, ParseException { + File inputFile = getResourceAsFile("TESTXRECHNUNG_INVDSS_012015776085.XML"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile)); + + Invoice invoice = zii.extractInvoice(); + assertEquals(1, invoice.getZFItems().length); + assertFalse(invoice.getZFItems()[0].getNotes() == null); + assertEquals(1, invoice.getZFItems()[0].getNotes().length); + } + + @Test + public void testImportXRechnungWithoutCalculationErrors() throws FileNotFoundException, XPathExpressionException, ParseException { + File inputFile = getResourceAsFile("cii/02.03a-INVOICE_uncefact.xml"); + ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(new FileInputStream(inputFile)); + + assertEquals("0", zii.importedInvoice.getDuePayable().toPlainString()); + } } diff --git a/library/src/test/resources/EN16931_1_Teilrechnung.pdf b/library/src/test/resources/EN16931_1_Teilrechnung.pdf new file mode 100644 index 00000000..0bc3ea77 Binary files /dev/null and b/library/src/test/resources/EN16931_1_Teilrechnung.pdf differ diff --git a/library/src/test/resources/EN16931_Einfach.pdf b/library/src/test/resources/EN16931_Einfach.pdf new file mode 100755 index 00000000..802b7282 Binary files /dev/null and b/library/src/test/resources/EN16931_Einfach.pdf differ diff --git a/library/src/test/resources/TESTXRECHNUNG_INVDSS_012015776085.XML b/library/src/test/resources/TESTXRECHNUNG_INVDSS_012015776085.XML new file mode 100644 index 00000000..1541326d --- /dev/null +++ b/library/src/test/resources/TESTXRECHNUNG_INVDSS_012015776085.XML @@ -0,0 +1,157 @@ + + urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 + urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 + 2015776085 + 2024-11-01 + 380 + #AAI# Wenn bereits bezahlt, nur zu den Akten legen. Für Verzug und Verzugszinsen gelten die Bestimmungen der §§ 286 - 288 BGB. Der Schuldner einer Entgeltforderung kommt spätestens in Verzug, wenn er nicht innerhalb von 30 Tagen nach Fälligkeit und Zugang einer Rechnung oder gleichwertigen Zahlungsaufstellung leistet. Die Lieferung von Waren und Fahrzeugen erfolgt unter Eigentumsvorbehalt. + #PAI# Rechnungsbetrag zahlbar ohne Abzug sofort nach Erhalt der Rechnung. + EUR + 02-ZZ987654-99 + + 2024-11-01 + 2024-11-30 + + + N/A + + + 63435555 + + + + DE238574172 + + Alphabet Fuhrparkmanagement GmbH + + + Lilienthalallee 26 + München + 80786 + + DE + + + + DE238574172 + + VAT + + + + Alphabet Fuhrparkmanagement GmbH + HRB 181098 + + + Yildiz Tolga + +49899-- + Tolga.Yildiz@alphabet.de + + + + + + N/A + + 00987654 + + + Muster GmbH + + + Musterweg 1 + Kiel + 24105 + + DE + + + + Muster GmbH + + + Mustermann Max + + + + + 2024-11-30 + + 00987654 + + Musterweg 1 + Kiel + 24105 + + DE + + + + + + Muster GmbH + + + + + 30 + + DE34700700100156919301 + Alphabet Fuhrparkmanagement GmbH + + DEUTDEMMXXX + + + + + Rechnungsbetrag zahlbar ohne Abzug sofort nach Erhalt der Rechnung. + + + 161.69 + + 851.00 + 161.69 + + S + 19.00 + + VAT + + + + + + 851.00 + 851.00 + 1012.69 + 1012.69 + + + 1 + #AAI# Finanzrate vom 01.11.2024 bis 30.11.2024 #ABZ/Kennzeichen#SH-9 18E #AKG/Fahrgestellnummer#WBY51EJ080CR55555 #BA/Kilometerstand#0 #AKV/LeasingNr#63435555 + 1.00 + 851.00 + + 2024-11-01 + 2024-11-30 + + + FL-Rate + FL-Rate + + 90101 + + + S + 19.00 + + VAT + + + + + 851.00 + 1.00 + + + diff --git a/library/src/test/resources/ZTESTZUGFERD_1_INVDSS_012015738820PDF-1.pdf b/library/src/test/resources/ZTESTZUGFERD_1_INVDSS_012015738820PDF-1.pdf new file mode 100644 index 00000000..7b220689 Binary files /dev/null and b/library/src/test/resources/ZTESTZUGFERD_1_INVDSS_012015738820PDF-1.pdf differ diff --git a/library/src/test/resources/cii/02.03a-INVOICE_uncefact.xml b/library/src/test/resources/cii/02.03a-INVOICE_uncefact.xml new file mode 100644 index 00000000..b605c668 --- /dev/null +++ b/library/src/test/resources/cii/02.03a-INVOICE_uncefact.xml @@ -0,0 +1,309 @@ + + + + + urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 + + + urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 + + + + 1234567 + 380 + + 20180413 + + + Invoice Note Description + AAC + + + + + + 1 + + Die letzte Lieferung im Rahmen des abgerechneten Abonnements erfolgt in 12/2016 Lieferung erfolgt / erfolgte direkt vom Verlag + + + + 1034 + Beratung + Anforderungmanagement + + 0721-880X + + + + + 6171175.1 + + + 143.75 + + + + 33 + + + + VAT + S + 19 + + + + 20160101 + + + 20161231 + + + + 4743.75 + + + + + + 2 + + + Beratung + + + + 143.75 + + + + 42 + + + + VAT + S + 19 + + + 6037.5 + + + + + 90000000-03083-72 + + 987654321 + [Seller name] + Amtsgericht […], Geschäftsführer: […], Sitz der Gesellschaft […], Aufsichtsratvorsitzender: […] + + 123456789 + [Seller trading name] + + + Tim Tester + + 012 3456789 + + + tim.tester@test.com + + + + 12345 + [Seller address line 1] + [Seller address line 2] + [Seller city] + DE + + + rechnungsausgang@test.com + + + ATU123456789 + + + 123/456/789 + + + + 138 + [Buyer name] + + 90000000-03083-72 + + + Tina Tester + + 0800 123456 + + + tester@test.de + + + + 98765 + [Buyer address line 1] + [Buyer address line 2] + [Buyer address line 3] + [Buyer city] + DE + + + rechnungseingang@test.de + + + DE12345ABC + + + + [Seller tax representative name] + + DE + + + DE124567 + + + + ABC123456789 + + + 65002278 + + + 0000000752 + + + 01_15_Anhang_01.pdf + 916 + Aufschlüsselung der einzelnen Leistungspositionen + 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DQowMDAwMDAwMDEwIDY1NTM1IGYNCjAwMDAwMDAwMTcgMDAwMDAgbg0KMDAwMDAwMDEyNSAwMDAwMCBuDQowMDAwMDAwMTgxIDAwMDAwIG4NCjAwMDAwMDA0NTEgMDAwMDAgbg0KMDAwMDAwMDczOCAwMDAwMCBuDQowMDAwMDAwOTA2IDAwMDAwIG4NCjAwMDAwMDExNDUgMDAwMDAgbg0KMDAwMDAwMTE5OCAwMDAwMCBuDQowMDAwMDAxMjUxIDAwMDAwIG4NCjAwMDAwMDAwMTEgNjU1MzUgZg0KMDAwMDAwMDAxMiA2NTUzNSBmDQowMDAwMDAwMDEzIDY1NTM1IGYNCjAwMDAwMDAwMTQgNjU1MzUgZg0KMDAwMDAwMDAxNSA2NTUzNSBmDQowMDAwMDAwMDE2IDY1NTM1IGYNCjAwMDAwMDAwMDAgNjU1MzUgZg0KMDAwMDAwMTg2NCAwMDAwMCBuDQowMDAwMDAyMzQ1IDAwMDAwIG4NCjAwMDAxNDkxMTMgMDAwMDAgbg0KdHJhaWxlcg0KPDwvU2l6ZSAyMC9Sb290IDEgMCBSL0luZm8gOSAwIFIvSURbPDVEMjQ1NTY4ODNFQ0FBNDFCMDM0N0E2RjAzMjFBNDBDPjw1RDI0NTU2ODgzRUNBQTQxQjAzNDdBNkYwMzIxQTQwQz5dID4+DQpzdGFydHhyZWYNCjE0OTM5MA0KJSVFT0YNCnhyZWYNCjAgMA0KdHJhaWxlcg0KPDwvU2l6ZSAyMC9Sb290IDEgMCBSL0luZm8gOSAwIFIvSURbPDVEMjQ1NTY4ODNFQ0FBNDFCMDM0N0E2RjAzMjFBNDBDPjw1RDI0NTU2ODgzRUNBQTQxQjAzNDdBNkYwMzIxQTQwQz5dIC9QcmV2IDE0OTM5MC9YUmVmU3RtIDE0OTExMz4+DQpzdGFydHhyZWYNCjE0OTk0Nw0KJSVFT0Y= + + + ANG987654321 + 50 + + + PR12345678 + Project reference + + + + + 68 + [Deliver to party name] + + 98765 + [Deliver to street] + 4. OG + [Deliver to city] + DE + Bayern + + + + + 20180413 + + + + + Deb. 12345 / Fact. 9876543 + GBP + EUR + + 74 + [Payee name] + + + 58 + + DE75512108001245126199 + [Payment account name] + + + [BIC] + + + + 2048.44 + VAT + 10781.25 + S + + 20180413 + + 19 + + + 0 + VAT + 0 + E + VATEX-EU-132-1A + 0 + + + + 20160101 + + + 20161231 + + + + + true + + 0 + 0 + 0 + TAC + Testing + + VAT + E + 0 + + + + + false + + 0 + 0 + 0 + 102 + Fixed long term + + VAT + E + 0 + + + + Bitte überweisen Sie bis zum 24.01.2015 auf das unten aufgeführte Konto. + + 20180413 + + + + 10781.25 + 0 + 0 + 10781.25 + 2048.44 + 2048.44 + 0 + 12829.69 + 12829.69 + 0 + + + + diff --git a/library/src/test/resources/cii/facturFrMinimum.xml b/library/src/test/resources/cii/facturFrMinimum.xml new file mode 100644 index 00000000..dacf0d03 --- /dev/null +++ b/library/src/test/resources/cii/facturFrMinimum.xml @@ -0,0 +1,56 @@ + + + + + urn:factur-x.eu:1p0:minimum + + + + FA-2017-0010 + 380 + + 20171113 + + + + + + Au bon moulin + + 99999999800010 + + + FR + + + FR11999999998 + + + + Ma jolie boutique + + 78787878400035 + + + FR + + + FR19787878784 + + + + PO445 + + + + + EUR + + 624.90 + 46.25 + 671.15 + 470.15 + + + + diff --git a/library/src/test/resources/cii/minimalDebit.xml b/library/src/test/resources/cii/minimalDebit.xml new file mode 100644 index 00000000..f714e0c9 --- /dev/null +++ b/library/src/test/resources/cii/minimalDebit.xml @@ -0,0 +1,143 @@ + + + + + + urn:cen.eu:en16931:2017 + + + + 471102 + 380 + + 20180304 + + + + + + 1 + + + Trennblätter A4 + + + + 9.9000 + 1.0000 + + + + 20.0000 + + + + VAT + S + 19.00 + + + 198.00 + + + + + + 2 + + + Joghurt Banane + + + + 5.5000 + 1.0000 + + + + 50.0000 + + + + VAT + S + 7.00 + + + 275.00 + + + + + + Lieferant GmbH + + 80333 + Lieferantenstraße 20 + München + DE + + + DE123456789 + + + 201/113/40209 + + + + Kunden AG Mitte + + 69876 + Kundenstraße 15 + Frankfurt + DE + + + + + + + 20180304 + + + + + DE98ZZZ09999999999 + EUR + + 59 + + DE21860000000086001055 + + + 19.25 + VAT + 275.00 + S + 7.00 + + + 37.62 + VAT + 198.00 + S + 19.00 + + + Der Betrag in Höhe von EUR 529,87 wird am 20.03.2018 von Ihrem Konto per SEPA-Lastschrift eingezogen. + + REF A-123 + + + 473.00 + 0.00 + 0.00 + 473.00 + 56.87 + 529.87 + 0.00 + 529.87 + + + + \ No newline at end of file diff --git a/library/src/test/resources/factur-x-extended.xml b/library/src/test/resources/factur-x-extended.xml new file mode 100644 index 00000000..a7c5fb27 --- /dev/null +++ b/library/src/test/resources/factur-x-extended.xml @@ -0,0 +1,430 @@ + + + + + + + + + + true + + + urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended + + + + KR87654321012 + KOSTENRECHNUNG + 380 + + 20241115 + + + ST3 + Es bestehen Rabatt- oder Bonusvereinbarungen. + AAK + + + EEV + Der Verkäufer bleibt Eigentümer der Waren bis zur vollständigen Erfüllung der Kaufpreisforderung. + AAJ + + + MUSTERLIEFERANT GMBH +BAHNHOFSTRASSE 99 +99199 MUSTERHAUSEN +Geschäftsführung: +Max Mustermann +USt-IdNr: DE123456789 +Telefon: +49 932 431 0 +www.musterlieferant.de +HRB Nr. 372876 +Amtsgericht Musterstadt +GLN 4304171000002 + + REG + + + + + + 1 + + + 4123456000014 + WA997 + Wirkarbeit HT + + Zählpunkt + DE0001346484600000000000000100038 + + + + + 0.0520 + + + 0.0520 + + + + 1000.0000 + + + + VAT + S + 19.00 + + + 52.00 + + + + + + 2 + + + 4123456000021 + ÖST250 + Ökosteuer Lieferant + + + + 0.0205 + + + 0.0205 + + + + 1000.0000 + + + + VAT + S + 19.00 + + + 20.50 + + + + + + 3 + + + 4260331811362 + Kommissionierer 1250032 D. Muster + Besteller: Hr. Mayer, Personalnr. 4488 + + + + 15.0000 + + + false + + 4.50 + Artikelrabatt 1 + + + + 10.5000 + + + + 27.5000 + + + + VAT + S + 19.00 + + + 288.75 + + + + + + 4 + + + 2001015001325 + FB05 + FALTENBEUTEL 16x6x28 CM + + + + 0.0105 + + + 0.0105 + + + + 3500.0000 + + + + VAT + S + 19.00 + + + 36.75 + + + + + + 5 + + + 4123456000038 + KOP05 + Kopierpapier A4 + Zählerstand von-bis: 543210 - 544420 + + Zähler-Nr. + MG-X79318 + + + + + 0.0100 + + + 0.0100 + + + + 1210.0000 + + + + VAT + S + 19.00 + + + 12.10 + + + + + + 549910 + 4333741000005 + MUSTERLIEFERANT GMBH + + + +49 932 431 500 + + + max.mustermann@musterlieferant.de + + + + 99199 + BAHNHOFSTRASSE 99 + MUSTERHAUSEN + DE + + + 201/113/40209 + + + + 339420 + 4304171000002 + MUSTER-KUNDE GMBH + + 40235 + KUNDENWEG 88 + DUESSELDORF + DE + + + + A777123 + 130 + + + + + 4304171088093 + MUSTER-MARKT + + 7322 + + + 31157 + HAUPTSTRASSE 44 + SARSTEDT + DE + + + + + 20241030 + + + + L87654321012 + + 20241031 + + + + + EUR + + 339420 + 4304171000002 + MUSTER-KUNDE GMBH + + 40235 + KUNDENWEG 88 + DUESSELDORF + DE + + + + 76.67 + VAT + 403.55 + 410.10 + -6.55 + S + 19.00 + + + + false + + 410.10 + 21.55 + Sonderrabatt + + VAT + S + 19.00 + + + + Transportkosten: Frachbetrag + 15.00 + + VAT + S + 19.00 + + + + Skontovereinbarung: 2% bei Zahlung innerhalb 10 Tagen nach Rechnungsdatum + + 10 + 2.00 + + + + 410.10 + 15.00 + 21.55 + 403.55 + 76.67 + 480.22 + 0.00 + 480.22 + + + + diff --git a/library/src/test/resources/factur-x-vis-extended.de.html b/library/src/test/resources/factur-x-vis-extended.de.html new file mode 100644 index 00000000..ed5a147d --- /dev/null +++ b/library/src/test/resources/factur-x-vis-extended.de.html @@ -0,0 +1,2422 @@ + + + + + XRechnung + + + + +

+ +
+
+
+
+
Wir übernehmen keine Haftung für die Richtigkeit der Daten.
+
+
+
+
Informationen zum Käufer
+
+
+
Leitweg-ID:
+
+
+
+
Name:
+
MUSTER-KUNDE GMBH
+
+
+
Straße / Haus-Nr.:
+
KUNDENWEG 88
+
+
+
Postfach:
+
+
+
+
Adresszusatz:
+
+
+
+
PLZ:
+
40235
+
+
+
Ort:
+
DUESSELDORF
+
+
+
Bundesland:
+
+
+
+
Land:
+
DE (Deutschland)
+
+
+
Kennung / Kunden-Nr.:
+
4304171000002
+
+
+
Schema der Kennung:
+
0088 (EAN + Location Code) +
+
+
+
Name:
+
+
+
+
Telefon:
+
+
+
+
E-Mail-Adresse:
+
+
+
+
+
+
+
Informationen zum Verkäufer
+
+
+
+
+
+
+
Firmenname:
+
MUSTERLIEFERANT GMBH
+
+
+
Straße / Haus-Nr.:
+
BAHNHOFSTRASSE 99
+
+
+
Postfach:
+
+
+
+
Adresszusatz:
+
+
+
+
PLZ:
+
99199
+
+
+
Ort:
+
MUSTERHAUSEN
+
+
+
Bundesland:
+
+
+
+
Ländercode:
+
DE (Deutschland)
+
+
+
Kennung:
+
4333741000005
+
+
+
Schema der Kennung:
+
0088 (EAN + Location Code) +
+
+
+
Name:
+
+
+
+
Telefon:
+
+49 932 431 500
+
+
+
E-Mail-Adresse:
+
max.mustermann@musterlieferant.de +
+
+
+
+
+
+
+
+
+
Rechnungsdaten
+
+
+
+
+
Rechnungsnummer:
+
KR87654321012
+
+
+
Rechnungsdatum:
+
15.11.2024
+
+
+
Rechnungsart:
+
380 (Commercial invoice)
+
+
+
Währung
+
EUR (Euro)
+
+
+

Abrechnungszeitraum:

+
+
+
von:
+
+
+
+
bis:
+
+
+
+
+
+
+
+
+
Projektnummer:
+
+
+
+
Vertragsnummer:
+
+
+
+
Bestellnummer:
+
+
+
+
Auftragsnummer:
+
+
+
+

Vorausgegangene Rechnungen:

+
+
+
+
+
+
+
+
+
Gesamtbeträge der Rechnung
+
+
+
Summe aller Positionen
+
netto
+
410,10
+
+
+
Summe Nachlässe
+
netto
+
21,55
+
+
+
Summe Zuschläge
+
netto
+
+ 15,00 +
+
+
+
Gesamtsumme
+
netto
+
403,55
+
+
+
Summe Umsatzsteuer
+
+
+
+
+
Summe Umsatzsteuer in + Abrechnungswährung +
+
+
+ 76,67 +
+
+
+
Gesamtsumme
+
brutto
+
480,22
+
+
+
Gezahlter Betrag
+
brutto
+
0,00
+
+
+
Rundungsbetrag
+
brutto
+
+
+
+
Fälliger Betrag
+
brutto
+
480,22 +
+
+
+
+
+
+
+
+
+
Aufschlüsselung der Umsatzsteuer auf Ebene der + Rechnung +
+
+
+
Umsatzsteuerkategorie: S (Standard rate) +
+
+
+
+
+
Gesamtsumme
+
netto
+
403,55
+
+
+
Umsatzsteuersatz
+
+
19.00%
+
+
+
Umsatzsteuerbetrag
+
+
76,67
+
+
+
+
Befreiungsgrund:
+
Kennung für den Befreiungsgrund: +
+
+
+
+
+
+
+
+
Nachlass auf Ebene der Rechnung
+
+
+
Umsatzsteuerkategorie des Nachlasses: S (Standard rate)
+
+
+
+
+
Grundbetrag
+
netto
+
410,10
+
+
+
Prozentsatz
+
+
%
+
+
+
Nachlass
+
netto
+
21,55
+
+
+
Umsatzsteuersatz des Nachlasses
+
+
19.00
+
+
+
+
Grund für den Nachlass: Sonderrabatt +
+
Document level allowance reason code:
+
+
+
+
+
+
+
+
+
Versandkosten
+
+
+
Umsatzsteuerkategorie der Versandkosten: S (Standard rate)
+
+
+
+
+
Betrag
+
netto
+
15,00
+
+
+
Umsatzsteuersatz der Versandkosten
+
+
19.00
+
+
+
+
Versandkostenbeschreibung: Transportkosten: Frachbetrag +
+
+
+
+
+
+
+
+
+
Zahlungsdaten
+
+
+
Skonto; weitere Zahlungsbed.:
+
#SKONTO# TAGE =10#PROZENT=2.00# + Skontovereinbarung: 2% bei Zahlung innerhalb 10 Tagen nach Rechnungsdatum +
+
+
+
Fälligkeitsdatum:
+
+
+
+
Code für das Zahlungsmittel:
+
+
+
+
Zahlungsmittel:
+
+
+
+
Verwendungszweck:
+
+
+
+
+
+
Karteninformation
+
+
+
Kartennummer:
+
+
+
+
Karteninhaber:
+
+
+
+
+
+
+
+
+
+
Lastschrift
+
+
+
Mandatsreferenznr.:
+
+
+
+
IBAN:
+
+
+
+
Gläubiger-ID:
+
+
+
+
+
+
Überweisung
+
+
+
+
+
+
+
Bemerkung zur Rechnung
+
+
+
Betreff:
+
AAK (Price conditions)
+
+
+
Bemerkung:
+
Es bestehen Rabatt- oder + Bonusvereinbarungen. +
+
+
+
+
+
Bemerkung zur Rechnung
+
+
+
Betreff:
+
AAJ (Additional conditions of + sale/purchase) +
+
+
+
Bemerkung:
+
Der Verkäufer bleibt Eigentümer der + Waren bis zur vollständigen Erfüllung der Kaufpreisforderung. +
+
+
+
+
+
Bemerkung zur Rechnung
+
+
+
Betreff:
+
REG (Regulatory information)
+
+
+
Bemerkung:
+
MUSTERLIEFERANT GMBH BAHNHOFSTRASSE + 99 99199 MUSTERHAUSEN Geschäftsführung: Max Mustermann USt-IdNr: DE123456789 + Telefon: +49 932 431 0 www.musterlieferant.de HRB Nr. 372876 Amtsgericht Musterstadt + GLN 4304171000002 +
+
+
+
+
+
+
+
+
Wir übernehmen keine Haftung für die Richtigkeit der Daten.
+
+
+
+
Position1
+
+
+
Freitext:
+
+
+
+
Objektkennung:
+
+
+
+
Schema der Objektkennung:
+
+
+
+
Nummer der Auftragsposition:
+
+
+
+
Kontierungshinweis /Kostenstelle:
+
+
+

Abrechnungszeitraum:

+
+
von:
+
+
+
+
bis:
+
+
+
+
+
+
Preiseinzelheiten
+
+
+
Menge
+
1000.0000
+
+
+
Einheit
+
KWH (kilowatt hour)
+
+
+
Preis pro Einheit (netto)
+
0,05
+
+
+
Gesamtpreis (netto)
+
52,00
+
+
+
+
+
Rabatt (netto):
+
+
+
+
Listenpreis (netto):
+
0,05
+
+
+
Anzahl der Einheit:
+
+
+
+
Code der Maßeinheit:
+
+
+
+
Umsatzsteuer:
+
S (Standard rate)
+
+
+
Umsatzsteuersatz in %:
+
19%
+
+
+
+
+
+
+
+
+
Nachlässe auf Ebene der + Rechnungsposition +
+
+
+
Zuschläge auf Ebene der + Rechnungsposition +
+
+
+
+
+
+
+
Artikelinformationen
+
+
+
+
+
+
Bezeichnung:
+
Wirkarbeit HT +
+
+
+
Beschreibung:
+
+
+
+
Artikelnummer:
+
WA997
+
+
+
Kunden-Material-Nr.:
+
+
+

Eigenschaften des Artikels:

+
+
Zählpunkt
+
+ DE0001346484600000000000000100038 +
+
+
+
+
+
+
+
+
Artikelkennung (EAN):
+
4123456000014
+
+
+
Schema der Artikelkennung:
+
+ 0088 (EAN Location Code) +
+
+
+
Code der Artikelklassifizierung:
+
+
+
+
Kennung zur Bildung des Schemas:
+
+
+
+
Version zur Bildung des Schemas:
+
+
+
+
Code des Herkunftslandes:
+
+
+
+
+
+
+
+
+
+
+
+
+
Position2
+
+
+
Freitext:
+
+
+
+
Objektkennung:
+
+
+
+
Schema der Objektkennung:
+
+
+
+
Nummer der Auftragsposition:
+
+
+
+
Kontierungshinweis /Kostenstelle:
+
+
+

Abrechnungszeitraum:

+
+
von:
+
+
+
+
bis:
+
+
+
+
+
+
Preiseinzelheiten
+
+
+
Menge
+
1000.0000
+
+
+
Einheit
+
KWH (kilowatt hour)
+
+
+
Preis pro Einheit (netto)
+
0,02
+
+
+
Gesamtpreis (netto)
+
20,50
+
+
+
+
+
Rabatt (netto):
+
+
+
+
Listenpreis (netto):
+
0,02
+
+
+
Anzahl der Einheit:
+
+
+
+
Code der Maßeinheit:
+
+
+
+
Umsatzsteuer:
+
S (Standard rate)
+
+
+
Umsatzsteuersatz in %:
+
19%
+
+
+
+
+
+
+
+
+
Nachlässe auf Ebene der + Rechnungsposition +
+
+
+
Zuschläge auf Ebene der + Rechnungsposition +
+
+
+
+
+
+
+
Artikelinformationen
+
+
+
+
+
+
Bezeichnung:
+
Ökosteuer + Lieferant +
+
+
+
Beschreibung:
+
+
+
+
Artikelnummer:
+
ÖST250
+
+
+
Kunden-Material-Nr.:
+
+
+

Eigenschaften des Artikels:

+
+
+
+
+
+
Artikelkennung (EAN):
+
4123456000021
+
+
+
Schema der Artikelkennung:
+
+ 0088 (EAN Location Code) +
+
+
+
Code der Artikelklassifizierung:
+
+
+
+
Kennung zur Bildung des Schemas:
+
+
+
+
Version zur Bildung des Schemas:
+
+
+
+
Code des Herkunftslandes:
+
+
+
+
+
+
+
+
+
+
+
+
+
Position3
+
+
+
Freitext:
+
+
+
+
Objektkennung:
+
+
+
+
Schema der Objektkennung:
+
+
+
+
Nummer der Auftragsposition:
+
+
+
+
Kontierungshinweis /Kostenstelle:
+
+
+

Abrechnungszeitraum:

+
+
von:
+
+
+
+
bis:
+
+
+
+
+
+
Preiseinzelheiten
+
+
+
Menge
+
27.5000
+
+
+
Einheit
+
HUR (hour)
+
+
+
Preis pro Einheit (netto)
+
10,50
+
+
+
Gesamtpreis (netto)
+
288,75
+
+
+
+
+
Rabatt (netto):
+
4,50
+
+
+
Listenpreis (netto):
+
15,00
+
+
+
Anzahl der Einheit:
+
+
+
+
Code der Maßeinheit:
+
+
+
+
Umsatzsteuer:
+
S (Standard rate)
+
+
+
Umsatzsteuersatz in %:
+
19%
+
+
+
+
+
+
+
+
+
Nachlässe auf Ebene der + Rechnungsposition +
+
+
+
Zuschläge auf Ebene der + Rechnungsposition +
+
+
+
+
+
+
+
Artikelinformationen
+
+
+
+
+
+
Bezeichnung:
+
Kommissionierer + 1250032 D. Muster +
+
+
+
Beschreibung:
+
Besteller: Hr. Mayer, + Personalnr. 4488 +
+
+
+
Artikelnummer:
+
+
+
+
Kunden-Material-Nr.:
+
+
+

Eigenschaften des Artikels:

+
+
+
+
+
+
Artikelkennung (EAN):
+
4260331811362
+
+
+
Schema der Artikelkennung:
+
+ 0088 (EAN Location Code) +
+
+
+
Code der Artikelklassifizierung:
+
+
+
+
Kennung zur Bildung des Schemas:
+
+
+
+
Version zur Bildung des Schemas:
+
+
+
+
Code des Herkunftslandes:
+
+
+
+
+
+
+
+
+
+
+
+
+
Position4
+
+
+
Freitext:
+
+
+
+
Objektkennung:
+
+
+
+
Schema der Objektkennung:
+
+
+
+
Nummer der Auftragsposition:
+
+
+
+
Kontierungshinweis /Kostenstelle:
+
+
+

Abrechnungszeitraum:

+
+
von:
+
+
+
+
bis:
+
+
+
+
+
+
Preiseinzelheiten
+
+
+
Menge
+
3500.0000
+
+
+
Einheit
+
H87 (piece)
+
+
+
Preis pro Einheit (netto)
+
0,01
+
+
+
Gesamtpreis (netto)
+
36,75
+
+
+
+
+
Rabatt (netto):
+
+
+
+
Listenpreis (netto):
+
0,01
+
+
+
Anzahl der Einheit:
+
+
+
+
Code der Maßeinheit:
+
+
+
+
Umsatzsteuer:
+
S (Standard rate)
+
+
+
Umsatzsteuersatz in %:
+
19%
+
+
+
+
+
+
+
+
+
Nachlässe auf Ebene der + Rechnungsposition +
+
+
+
Zuschläge auf Ebene der + Rechnungsposition +
+
+
+
+
+
+
+
Artikelinformationen
+
+
+
+
+
+
Bezeichnung:
+
FALTENBEUTEL + 16x6x28 CM +
+
+
+
Beschreibung:
+
+
+
+
Artikelnummer:
+
FB05
+
+
+
Kunden-Material-Nr.:
+
+
+

Eigenschaften des Artikels:

+
+
+
+
+
+
Artikelkennung (EAN):
+
2001015001325
+
+
+
Schema der Artikelkennung:
+
+ 0088 (EAN Location Code) +
+
+
+
Code der Artikelklassifizierung:
+
+
+
+
Kennung zur Bildung des Schemas:
+
+
+
+
Version zur Bildung des Schemas:
+
+
+
+
Code des Herkunftslandes:
+
+
+
+
+
+
+
+
+
+
+
+
+
Position5
+
+
+
Freitext:
+
+
+
+
Objektkennung:
+
+
+
+
Schema der Objektkennung:
+
+
+
+
Nummer der Auftragsposition:
+
+
+
+
Kontierungshinweis /Kostenstelle:
+
+
+

Abrechnungszeitraum:

+
+
von:
+
+
+
+
bis:
+
+
+
+
+
+
Preiseinzelheiten
+
+
+
Menge
+
1210.0000
+
+
+
Einheit
+
H87 (piece)
+
+
+
Preis pro Einheit (netto)
+
0,01
+
+
+
Gesamtpreis (netto)
+
12,10
+
+
+
+
+
Rabatt (netto):
+
+
+
+
Listenpreis (netto):
+
0,01
+
+
+
Anzahl der Einheit:
+
+
+
+
Code der Maßeinheit:
+
+
+
+
Umsatzsteuer:
+
S (Standard rate)
+
+
+
Umsatzsteuersatz in %:
+
19%
+
+
+
+
+
+
+
+
+
Nachlässe auf Ebene der + Rechnungsposition +
+
+
+
Zuschläge auf Ebene der + Rechnungsposition +
+
+
+
+
+
+
+
Artikelinformationen
+
+
+
+
+
+
Bezeichnung:
+
Kopierpapier A4 +
+
+
+
Beschreibung:
+
Zählerstand von-bis: + 543210 - 544420 +
+
+
+
Artikelnummer:
+
KOP05
+
+
+
Kunden-Material-Nr.:
+
+
+

Eigenschaften des Artikels:

+
+
Zähler-Nr.
+
MG-X79318
+
+
+
+
+
+
+
+
Artikelkennung (EAN):
+
4123456000038
+
+
+
Schema der Artikelkennung:
+
+ 0088 (EAN Location Code) +
+
+
+
Code der Artikelklassifizierung:
+
+
+
+
Kennung zur Bildung des Schemas:
+
+
+
+
Version zur Bildung des Schemas:
+
+
+
+
Code des Herkunftslandes:
+
+
+
+
+
+
+
+
+
+
+
+
Wir übernehmen keine Haftung für die Richtigkeit der Daten.
+
+
+
+
Informationen zum Verkäufer
+
+
+
Abweichender Handelsname:
+
+
+
+
Bundesland:
+
+
+
+
Elektronische Adresse:
+
+
+
+
Schema der elektronischen Adresse:
+
+
+
+
Register-/Registriernummer:
+
+
+
+
Umsatzsteuer-ID:
+
+
+
+
Steuernummer:
+
201/113/40209
+
+
+
Schema der Steuernummer:
+
+
+
+
Weitere rechtliche Informationen:
+
+
+
+
Code der Umsatzsteuerwährung:
+
+
+
+
+
+
+
+
+
+
+
Informationen zum Käufer
+
+
+
Abweichender Handelsname:
+
+
+
+
Bundesland:
+
+
+
+
Elektronische Adresse:
+
+
+
+
Schema der elektronischen Adresse:
+
+
+
+
Register-/Registriernummer:
+
+
+
+
Schema der Register-/Registriernummer:
+
+
+
+
Umsatzsteuer-ID:
+
+
+
+
Abrechnungsdatum der Umsatzsteuer:
+
+
+
+
Code des Umsatzsteuer-Abrechnungsdatums:
+
+
+
+
Kontierungsinformation / Kostenstelle:
+
+
+
+
+
+
+
Lieferinformationen
+
+
+
Kennung des Lieferorts:
+
4304171088093
+
+
+
Schema der Kennung:
+
0088
+
+
+
Lieferdatum:
+
30.10.2024
+
+
+
Name des Empfängers:
+
MUSTER-MARKT
+
+
+
Straße / Haus-Nr.:
+
HAUPTSTRASSE 44
+
+
+
Postfach:
+
+
+
+
Adresszusatz:
+
+
+
+
PLZ:
+
31157
+
+
+
Ort:
+
SARSTEDT
+
+
+
Bundesland:
+
+
+
+
Land:
+
DE (Deutschland)
+
+
+
+
+
+
+
+
+
Vertragsdaten
+
+
+
Vergabenummer:
+
+
+
+
Kennung der Empfangsbestätigung:
+
+
+
+
Kennung der Versandanzeige:
+
+
+
+
Kennung des Lieferscheins:
+
L87654321012 vom 31.10.2024
+
+
+
Prozesskennung:
+
+
+
+
Spezifikationskennung:
+
+ urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended +
+
+
+
Objektkennung:
+
A777123
+
+
+
Schema der Objektkennung:
+
+
+
+
+
+
+
+
+
+
Wir übernehmen keine Haftung für die Richtigkeit der Daten.
+
+
+
+
Rechnungsbegründende Unterlagen
+
+
+
+
+
+
+
+
+
Bearbeitungshistorie
+
+
+
+
+
+
+ + + diff --git a/library/src/test/resources/factur-x-vis-ubl-creditnote.en.html b/library/src/test/resources/factur-x-vis-ubl-creditnote.en.html index f5855ab2..4c63e9c9 100644 --- a/library/src/test/resources/factur-x-vis-ubl-creditnote.en.html +++ b/library/src/test/resources/factur-x-vis-ubl-creditnote.en.html @@ -1555,7 +1555,7 @@
Description:
Processor: Intel Core 2 Duo SU9400 LV (1.4GHz). RAM: - 3MB. Screen 1440x900
+ 3MB. Screen 1440x900
Part number:
@@ -2354,6 +2354,10 @@
Dispatch note ID:
+
+
Delivery note ID:
+
+
Process ID:
@@ -2625,4 +2629,4 @@ function downloadData (element_id) { }); // - \ No newline at end of file + diff --git a/library/src/test/resources/factur-x-vis-ubl.en.html b/library/src/test/resources/factur-x-vis-ubl.en.html index 7f80320c..4a394f1c 100644 --- a/library/src/test/resources/factur-x-vis-ubl.en.html +++ b/library/src/test/resources/factur-x-vis-ubl.en.html @@ -1219,8 +1219,6 @@
-
-
@@ -1754,6 +1752,10 @@
Dispatch note ID:
+
+
Delivery note ID:
+
+
Process ID:
@@ -1946,4 +1948,4 @@ function downloadData (element_id) { }); // - \ No newline at end of file + diff --git a/library/src/test/resources/factur-x-vis.fr.html b/library/src/test/resources/factur-x-vis.fr.html index 76efd248..e22b12ef 100644 --- a/library/src/test/resources/factur-x-vis.fr.html +++ b/library/src/test/resources/factur-x-vis.fr.html @@ -1250,8 +1250,6 @@
-
-
@@ -1926,6 +1924,10 @@
Identifiant du bordereau d'expédition:
+
+
Identifiant du bon de livraison:
+
+
Identifiant processus:
@@ -2118,4 +2120,4 @@ function downloadData (element_id) { }); // - \ No newline at end of file + diff --git a/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml b/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml index 9f8d1044..8b5bb189 100644 --- a/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml +++ b/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.cii.xml @@ -1,411 +1,411 @@ - - - BT-23 Business Process Type - - - urn:cen.eu:en16931:2017 - - - - Test_EeISI_100 - 380 - - 20181112 - - - invoice note text - #AAA# - - - invoice note text 2 - #AAA# - - - - - - 1a - - Invoice line note - - - - Item standar identifier - Item seller's identifier - Item buyer's identifier - Item name - Item description - - Color - Red - - - Size - L - - - Item classification identifier0 - - - IT - - - - - 12345 - - - 11.00 - 1.00 - - - false - - 1.00 - - - - 10.00 - 1.00 - - - - 10.00 - - - - VAT - S - 5.00 - - - + + + BT-23 Business Process Type + + + urn:cen.eu:en16931:2017 + + + + Test_EeISI_100 + 380 + 20181112 - - - 20181130 - - - - - false - - 1.00 - 1000.00 - 10.00 - 55 - Invoice line allowance reason - - - - true - - 1.00 - 1000.00 - 10.00 - AAA - Invoice line charge reason - - - 1000.00 - - - Line object identifier - 130 - - - - 6789 - - - - - - 1b - - - Item name 2 - - - - 10.00 - - - - 10.00 - - - - VAT - E - 0.00 - - - 1000.00 - - - - - 123 - - Seller identifier 1 - Seller identifier 2 - Seller name - Seller additional legal information - - Seller legal identifier - Seller trading name - - - Seller contact point - - +41 345 654455 - - - seller@contact.de - - - - 12345 - Seller address line 1 - Seller address line 2 - Seller address line 3 - Seller city - DE - Seller country subdivision - - - Seller electronic address - - - DE12345677 - - - DE49294093 - - - - Buyer identifier - Buyer name - - Buyer legal registration identifier - Buyer trading name - - - Buyer contact point - - +353 2948584 - - - buyer@contact.ie - - - - 34562 - Buyer address line 1 - Buyer address line 2 - Buyer address line 3 - Buyer city - IE - Buyer country subdivision - - - Buyer electronic address - - - IE394838894 - - - - Tax representative name - - 23455 - Tax representative address line 1 - Tax representative address line 2 - Tax representative address line 3 - Tax representative city - DE - Tax representative country subdivision - - - DE3949053 - - - - def - - - abc - - - 789 - - - Supporting document ref - External document location - 916 - Supporting document descr - ZGVmYXVsdA== - - - rst - 130 - 0090 - - - 456 - Project reference - - - - - deliver location identifier - Deliver to party name - - 98765 - Deliver to address line 1 - Deliver to address line 2 - Deliver to address line 3 - Deliver to city - IE - Deliver to country subdivision - - - - - 20181204 - - - - lmn - - - ghi - - - - Bank assigned creditor identifier - Remittance information - NOK - EUR - - Payee identifier - Payee name - - Payee legal registration identifier - - - - 4 - SEPA - - 1234 - Payment card holder name - - - Debited account identifier - - - IT1212341234123412 - Payment account name - - - BSCTCH22 - - - IT1212341234123413 - Payment account name 2 - - - BSCTCH22 - - - - 50.00 - VAT - 1000.00 - S - 29 - 5.00 - - - 0.00 - VAT - Exemtion reason text - 1000.00 - E - Exemption reason code - 29 - 0.00 - - - - 20181112 - - - 20181130 - - - - - false - - 1.00 - 1000.00 - 10.00 - 55 - Doc allowance reason text - - VAT - S - 5.00 - - - - - true - - 1.00 - 1000.00 - 10.00 - AAA - Doc charge reason text - - VAT - S - 5.00 - - - - total amount - - 20181130 - - Mandate reference identifier - - - 2000.00 - 10.00 - 10.00 - 2000.00 - 50.00 - 46.00 - 0.00 - 2050.00 - 0.00 - 2050.00 - - - abc123 - - 20181004 - - - - uvz - - - + + + invoice note text + #AAA# + + + invoice note text 2 + #AAA# + + + + + + 1a + + Invoice line note + + + + Item standar identifier + Item seller's identifier + Item buyer's identifier + Item name + Item description + + Color + Red + + + Size + L + + + Item classification identifier0 + + + IT + + + + + 12345 + + + 11.00 + 1.00 + + + false + + 1.00 + + + + 10.00 + 1.00 + + + + 10.00 + + + + VAT + S + 5.00 + + + + 20181112 + + + 20181130 + + + + + false + + 1.00 + 1000.00 + 10.00 + 55 + Invoice line allowance reason + + + + true + + 1.00 + 1000.00 + 10.00 + AAA + Invoice line charge reason + + + 1000.00 + + + Line object identifier + 130 + + + + 6789 + + + + + + 1b + + + Item name 2 + + + + 10.00 + + + + 10.00 + + + + VAT + E + 0.00 + + + 1000.00 + + + + + 123 + + Seller identifier 1 + Seller identifier 2 + Seller name + Seller additional legal information + + Seller legal identifier + Seller trading name + + + Seller contact point + + +41 345 654455 + + + seller@contact.de + + + + 12345 + Seller address line 1 + Seller address line 2 + Seller address line 3 + Seller city + DE + Seller country subdivision + + + Seller electronic address + + + DE12345677 + + + DE49294093 + + + + Buyer identifier + Buyer name + + Buyer legal registration identifier + Buyer trading name + + + Buyer contact point + + +353 2948584 + + + buyer@contact.ie + + + + 34562 + Buyer address line 1 + Buyer address line 2 + Buyer address line 3 + Buyer city + IE + Buyer country subdivision + + + Buyer electronic address + + + IE394838894 + + + + Tax representative name + + 23455 + Tax representative address line 1 + Tax representative address line 2 + Tax representative address line 3 + Tax representative city + DE + Tax representative country subdivision + + + DE3949053 + + + + def + + + abc + + + 789 + + + Supporting document ref + External document location + 916 + Supporting document descr + ZGVmYXVsdA== + + + rst + 130 + 0090 + + + 456 + Project reference + + + + + deliver location identifier + Deliver to party name + + 98765 + Deliver to address line 1 + Deliver to address line 2 + Deliver to address line 3 + Deliver to city + IE + Deliver to country subdivision + + + + + 20181204 + + + + lmn + + + ghi + + + + Bank assigned creditor identifier + Remittance information + NOK + EUR + + Payee identifier + Payee name + + Payee legal registration identifier + + + + 4 + SEPA + + 1234 + Payment card holder name + + + Debited account identifier + + + IT1212341234123412 + Payment account name + + + BSCTCH22 + + + IT1212341234123413 + Payment account name 2 + + + BSCTCH22 + + + + 50.00 + VAT + 1000.00 + S + 29 + 5.00 + + + 0.00 + VAT + Exemtion reason text + 1000.00 + E + Exemption reason code + 29 + 0.00 + + + + 20181112 + + + 20181130 + + + + + false + + 1.00 + 1000.00 + 10.00 + 55 + Doc allowance reason text + + VAT + S + 5.00 + + + + + true + + 1.00 + 1000.00 + 10.00 + AAA + Doc charge reason text + + VAT + S + 5.00 + + + + total amount + + 20181130 + + Mandate reference identifier + + + 2000.00 + 10.00 + 10.00 + 2000.00 + 50.00 + 46.00 + 0.00 + 2050.00 + 0.00 + 2050.00 + + + abc123 + + 20181004 + + + + uvz + + + diff --git a/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.ubl.xml b/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.ubl.xml index a314773a..6e850cc1 100644 --- a/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.ubl.xml +++ b/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel.ubl.xml @@ -1,404 +1,401 @@ - urn:cen.eu:en16931:2017 - BT-23 Business Process Type - Test_EeISI_100 - 2018-11-12 - 2018-11-30 - 380 - ##AAA##invoice note text - ##AAA##invoice note text 2 - EUR - NOK - uvz - 123 - - 2018-11-12 - 2018-11-30 - 35 - - - abc - def - - - - abc123 - 2018-10-04 - - - - lmn - - - ghi - - - opq - - - 789 - - - rst - 130 - - - Supporting document ref - Supporting document descr - - ZGVmYXVsdA== - - External document location - - - - - 456 - - - - Seller electronic address - - Seller identifier 1 - - - Seller identifier 2 - - - Bank assigned creditor identifier - - - Seller trading name - - - Seller address line 1 - Seller address line 2 - Seller city - 12345 - Seller country subdivision - - Seller address line 3 - - - DE - - - - DE12345677 - - VAT - - - - DE49294093 - - NOVAT - - - - Seller name - Seller legal identifier - Seller additional legal information - - - Seller contact point - +41 345 654455 - seller@contact.de - - - - - - Buyer electronic address - - 0190:Buyer identifier - - - Buyer trading name - - - Buyer address line 1 - Buyer address line 2 - Buyer city - 34562 - Buyer country subdivision - - Buyer address line 3 - - - IE - - - - IE394838894 - - VAT - - - - Buyer name - Buyer legal registration identifier - - - Buyer contact point - +353 2948584 - buyer@contact.ie - - - - - - Payee identifier - - - Payee name - - - Payee legal registration identifier - - - - - Tax representative name - - - Tax representative address line 1 - Tax representative address line 2 - Tax representative city - 23455 - Tax representative country subdivision - - Tax representative address line 3 - - - DE - - - - DE3949053 - - VAT - - - - - 2018-12-04 - - deliver location identifier - - Deliver to address line 1 - Deliver to address line 2 - Deliver to city - 98765 - Deliver to country subdivision - - Deliver to address line 3 - - - IE - - - - - - Deliver to party name - - - - - 4 - Remittance information - - 1234 - mandatory network id - Payment card holder name - - - IT1212341234123412 - Payment account name - - BSCTCH22 - - - - IT1212341234123413 - Payment account name 2 - - BSCTCH22 - - - - Mandate reference identifier - - Debited account identifier - - - - - total amount - - - false - 55 - Doc allowance reason text - 1.0000 - 10.00 - 1000.00 - - S - 5.00 - - VAT - - - - - true - AAA - Doc charge reason text - 1.0000 - 10.00 - 1000.00 - - S - 5.00 - - VAT - - - - - 46.00 - - - 50.00 - - 1000.00 - 50.00 - - S - 5.00 - - VAT - - - - - 1000.00 - 0.00 - - E - 0.00 - Exemption reason code - Exemtion reason text - - VAT - - - - - - 2000.00 - 2000.00 - 2050.00 - 10.00 - 10.00 - 2050.00 - - - 1a - Invoice line note - 10.00000000 - 1000.00 - 6789 + urn:cen.eu:en16931:2017 + BT-23 Business Process Type + Test_EeISI_100 + 2018-11-12 + 2018-11-30 + 380 + ##AAA##invoice note text + ##AAA##invoice note text 2 + EUR + NOK + uvz + 123 - 2018-11-12 - 2018-11-30 + 2018-11-12 + 2018-11-30 + 35 - - 12345 - - - Line object identifier - 130 - + + abc + def + + + + abc123 + 2018-10-04 + + + + lmn + + + ghi + + + opq + + + 789 + + + rst + 130 + + + Supporting document ref + Supporting document descr + + ZGVmYXVsdA== + + External document location + + + + + 456 + + + + Seller electronic address + + Seller identifier 1 + + + Seller identifier 2 + + + Seller trading name + + + Seller address line 1 + Seller address line 2 + Seller city + 12345 + Seller country subdivision + + Seller address line 3 + + + DE + + + + DE12345677 + + VAT + + + + DE49294093 + + NOVAT + + + + Seller name + Seller legal identifier + Seller additional legal information + + + Seller contact point + +41 345 654455 + seller@contact.de + + + + + + Buyer electronic address + + 0190:Buyer identifier + + + Buyer trading name + + + Buyer address line 1 + Buyer address line 2 + Buyer city + 34562 + Buyer country subdivision + + Buyer address line 3 + + + IE + + + + IE394838894 + + VAT + + + + Buyer name + Buyer legal registration identifier + + + Buyer contact point + +353 2948584 + buyer@contact.ie + + + + + + Payee identifier + + + Payee name + + + Payee legal registration identifier + + + + + Tax representative name + + + Tax representative address line 1 + Tax representative address line 2 + Tax representative city + 23455 + Tax representative country subdivision + + Tax representative address line 3 + + + DE + + + + DE3949053 + + VAT + + + + + 2018-12-04 + + deliver location identifier + + Deliver to address line 1 + Deliver to address line 2 + Deliver to city + 98765 + Deliver to country subdivision + + Deliver to address line 3 + + + IE + + + + + + Deliver to party name + + + + + 4 + Remittance information + + 1234 + mandatory network id + Payment card holder name + + + IT1212341234123412 + Payment account name + + BSCTCH22 + + + + IT1212341234123413 + Payment account name 2 + + BSCTCH22 + + + + Mandate reference identifier + + Debited account identifier + + + + + total amount + - false - 55 - Invoice line allowance reason - 1 - 10 - 1000 - - - true - AAA - Invoice line charge reason - 1 - 10 - 1000 - - - Item description - Item name - - Item buyer's identifier - - - Item seller's identifier - - - Item standar identifier - - - IT - - - Item classification identifier0 - - - S - 5.00 - - VAT - - - - Color - Red - - - Size - L - - - - 10.00 - 1.00 - false - 1 - 11 - - - - - 1b - 10.00000000 - 1000.00 - - Item name 2 - - E - 0.00 - - VAT - - - - - 10.00 - - + 55 + Doc allowance reason text + 1.0000 + 10.00 + 1000.00 + + S + 5.00 + + VAT + + + + + true + AAA + Doc charge reason text + 1.0000 + 10.00 + 1000.00 + + S + 5.00 + + VAT + + + + + 46.00 + + + 50.00 + + 1000.00 + 50.00 + + S + 5.00 + + VAT + + + + + 1000.00 + 0.00 + + E + 0.00 + Exemption reason code + Exemtion reason text + + VAT + + + + + + 2000.00 + 2000.00 + 2050.00 + 10.00 + 10.00 + 2050.00 + + + 1a + Invoice line note + 10.00000000 + 1000.00 + 6789 + + 2018-11-12 + 2018-11-30 + + + 12345 + + + Line object identifier + 130 + + + false + 55 + Invoice line allowance reason + 1 + 10 + 1000 + + + true + AAA + Invoice line charge reason + 1 + 10 + 1000 + + + Item description + Item name + + Item buyer's identifier + + + Item seller's identifier + + + Item standar identifier + + + IT + + + Item classification identifier0 + + + S + 5.00 + + VAT + + + + Color + Red + + + Size + L + + + + 10.00 + 1.00 + + false + 1 + 11 + + + + + 1b + 10.00000000 + 1000.00 + + Item name 2 + + E + 0.00 + + VAT + + + + + 10.00 + + diff --git a/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel2.ubl.xml b/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel2.ubl.xml deleted file mode 100644 index 7e71103c..00000000 --- a/library/src/test/resources/not_validating_full_invoice_based_onTest_EeISI_300_CENfullmodel2.ubl.xml +++ /dev/null @@ -1,349 +0,0 @@ - - - urn:cen.eu:en16931:2017 - BT-23 Business Process Type - Test_EeISI_100 - 2018-11-12 - 2018-11-30 - 380 - ##AAA##invoice note text - ##AAA##invoice note text 2 - EUR - NOK - uvz - 123 - - 2018-11-12 - 2018-11-30 - 35 - - - abc - def - - - - abc123 - 2018-10-04 - - - - lmn - - - ghi - - - opq - - - 789 - - - rst - 130 - - - Supporting document ref - Supporting document descr - - ZGVmYXVsdA== - - External document location - - - - - 456 - - - - Seller electronic address - - Seller identifier 1 - - - Seller identifier 2 - - - Bank assigned creditor identifier - - - Seller trading name - - - Seller address line 1 - Seller address line 2 - Seller city - 12345 - Seller country subdivision - - Seller address line 3 - - - DE - - - - DE12345677 - - VAT - - - - DE49294093 - - NOVAT - - - - Seller name - Seller legal identifier - Seller additional legal information - - - Seller contact point - +41 345 654455 - seller@contact.de - - - - - - Buyer electronic address - - 0190:Buyer identifier - - - Buyer trading name - - - Buyer address line 1 - Buyer address line 2 - Buyer city - 34562 - Buyer country subdivision - - Buyer address line 3 - - - IE - - - - IE394838894 - - VAT - - - - Buyer name - Buyer legal registration identifier - - - Buyer contact point - +353 2948584 - buyer@contact.ie - - - - - - Payee identifier - - - Payee name - - - Payee legal registration identifier - - - - - Tax representative name - - - Tax representative address line 1 - Tax representative address line 2 - Tax representative city - 23455 - Tax representative country subdivision - - Tax representative address line 3 - - - DE - - - - DE3949053 - - VAT - - - - - 2018-12-04 - - deliver location identifier - - Deliver to address line 1 - Deliver to address line 2 - Deliver to city - 98765 - Deliver to country subdivision - - Deliver to address line 3 - - - IE - - - - - - Deliver to party name - - - - - 4 - Remittance information - - 1234 - mandatory network id - Payment card holder name - - - IT1212341234123412 - Payment account name - - BSCTCH22 - - - - IT1212341234123413 - Payment account name 2 - - BSCTCH22 - - - - Mandate reference identifier - - Debited account identifier - - - - - total amount - - - 50.00 - - 1000.00 - 50.00 - - S - 5.00 - - VAT - - - - - 1000.00 - 0.00 - - E - 0.00 - Exemption reason code - Exemtion reason text - - VAT - - - - - - 200.00 - 200.00 - 205.00 - 205.00 - - - 1a - Invoice line note - 10.00000000 - 1000.00 - 6789 - - 2018-11-12 - 2018-11-30 - - - 12345 - - - Line object identifier - 130 - - - Item description - Item name - - Item buyer's identifier - - - Item seller's identifier - - - Item standar identifier - - - IT - - - Item classification identifier0 - - - S - 5.00 - - VAT - - - - Color - Red - - - Size - L - - - - 10.00 - 1.00 - - - - - 1b - 10.00000000 - 100.00 - - Item name 2 - - E - 0.00 - - VAT - - - - - 10.00 - - - diff --git a/library/src/test/resources/testout-ZF2new.ubl.xml b/library/src/test/resources/testout-ZF2new.ubl.xml index 9be2f765..c1cd3bc5 100644 --- a/library/src/test/resources/testout-ZF2new.ubl.xml +++ b/library/src/test/resources/testout-ZF2new.ubl.xml @@ -123,6 +123,7 @@ 1 + Something 1 160 @@ -178,4 +179,4 @@ 1 - \ No newline at end of file + diff --git a/pom.xml b/pom.xml index 1752f94e..9dade18f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,8 +3,7 @@ 4.0.0 org.mustangproject core - 2.15.0-SNAPSHOT - pom + 2.15.3-SNAPSHOT pom Mustang diff --git a/validator/pom.xml b/validator/pom.xml index ec333d9e..67d7ca94 100644 --- a/validator/pom.xml +++ b/validator/pom.xml @@ -3,7 +3,7 @@ org.mustangproject core - 2.15.0-SNAPSHOT + 2.15.3-SNAPSHOT 4.0.0 org.mustangproject @@ -11,7 +11,7 @@ Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung) jar - 2.15.0-SNAPSHOT + 2.15.3-SNAPSHOT @@ -38,12 +38,18 @@ ${project.groupId} library - 2.15.0-SNAPSHOT + 2.15.3-SNAPSHOT org.dom4j dom4j 2.1.4 + + + * + * + + commons-io @@ -54,7 +60,6 @@ org.apache.pdfbox pdfbox 3.0.2 - test jakarta.xml.bind @@ -225,10 +230,10 @@ - ${basedir}/src/main/resources/xslt/ZF_230/ + src/main/resources/xslt/ZF_232/ - ${basedir}/src/main/resources/schematron/ZF_230/ + ${basedir}/src/main/resources/schematron/ZF_232/ **/*.xml diff --git a/validator/src/main/java/org/mustangproject/validator/PDFValidator.java b/validator/src/main/java/org/mustangproject/validator/PDFValidator.java index da719f9b..15a4108a 100644 --- a/validator/src/main/java/org/mustangproject/validator/PDFValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/PDFValidator.java @@ -52,7 +52,7 @@ public class PDFValidator extends Validator { } private static final Logger LOGGER = LoggerFactory.getLogger(PDFValidator.class.getCanonicalName()); // log output - private static final PDFAFlavour[] PDF_A_3_FLAVOURS = {PDFAFlavour.PDFA_3_A, PDFAFlavour.PDFA_3_A, PDFAFlavour.PDFA_3_A}; + private static final PDFAFlavour[] PDF_A_3_FLAVOURS = {PDFAFlavour.PDFA_3_A, PDFAFlavour.PDFA_3_B, PDFAFlavour.PDFA_3_U}; private String pdfFilename; @@ -122,7 +122,9 @@ public class PDFValidator extends Validator { } // step 2 validate XMP - final ZUGFeRDImporter zi = new ZUGFeRDImporter(inputStream); + final ZUGFeRDImporter zi = new ZUGFeRDImporter(); + zi.doIgnoreCalculationErrors();//of course the calculation will still be schematron checked + zi.setInputStream(inputStream); final String xmp = zi.getXMP(); final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -239,7 +241,8 @@ public class PDFValidator extends Validator { boolean versionValid = false; for (int i = 0; i < nodes.getLength(); i++) { - final String[] valueArray = {"1.0", "2p0", "1.2", "2.0", "2.1"}; //1.2, 2.0 and 2.1 are for xrechnung 1.2, 2p0 can be ZF 2.0, 2.1, 2.1.1 + final String[] valueArray = {"1.0", "1p0", "2p0", "1.2", "2.0", "2.1", "2.2", "2.3", "3.0"}; //1.2, 2.0, 2.1, 2.2, 2.3 and 3.0 are for xrechnung 1.2, 2p0 can be ZF 2.0, 2.1, 2.1.1 + if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) { versionValid = true; } // e.g. 1.0 @@ -263,6 +266,8 @@ public class PDFValidator extends Validator { final byte[] konikSignature = "Konik".getBytes(StandardCharsets.UTF_8); final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes(StandardCharsets.UTF_8); final byte[] ghostscriptSignature = "%%Invocation:".getBytes(StandardCharsets.UTF_8); + final byte[] cibpdfbrewerSignature = "CIB pdf brewer".getBytes(StandardCharsets.UTF_8); + final byte[] lexofficeSignature = "lexoffice".getBytes(StandardCharsets.UTF_8); if (ByteArraySearcher.contains(fileContents, symtraxSignature)) { Signature = "Symtrax"; @@ -278,6 +283,10 @@ public class PDFValidator extends Validator { Signature = "pdfMachine"; } else if (ByteArraySearcher.contains(fileContents, ghostscriptSignature)) { Signature = "Ghostscript"; + } else if (ByteArraySearcher.contains(fileContents, cibpdfbrewerSignature)) { + Signature = "CIB pdf brewer"; + } else if (ByteArraySearcher.contains(fileContents, lexofficeSignature)) { + Signature = "Lexware office"; } context.setSignature(Signature); @@ -297,8 +306,10 @@ public class PDFValidator extends Validator { if (!processorResult.getValidationResult().isCompliant()) { context.setInvalid(); } + + PDFAFlavour pdfaFlavourFromValidationResult = processorResult.getValidationResult().getPDFAFlavour(); if (Arrays.stream(PDF_A_3_FLAVOURS) - .anyMatch(pdfaFlavour -> processorResult.getValidationResult().getPDFAFlavour().equals(pdfaFlavour))) { + .noneMatch(pdfaFlavourFromValidationResult::equals)) { context.addResultItem( new ValidationResultItem(ESeverity.error, "Not a PDF/A-3").setSection(23).setPart(EPart.pdf)); diff --git a/validator/src/main/java/org/mustangproject/validator/ValidationContext.java b/validator/src/main/java/org/mustangproject/validator/ValidationContext.java index a74c9f1c..73b95f2e 100644 --- a/validator/src/main/java/org/mustangproject/validator/ValidationContext.java +++ b/validator/src/main/java/org/mustangproject/validator/ValidationContext.java @@ -135,6 +135,22 @@ public class ValidationContext { return String.join(",", errorcodes); } + /*** + * + * @return the unique error IDs as comma separated string + */ + public String getCSVIDResult() { + final ArrayList errorIDs = new ArrayList<>(); + for (final ValidationResultItem validationResultItem : results) { + if (!validationResultItem.getID().isEmpty()) { + final String errorID=validationResultItem.getID(); + errorIDs.add(errorID); + + } + } + return String.join(",", errorIDs); + } + public void setInvalid() { isValid = false; } diff --git a/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java b/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java index d5a9b244..b0d6b5a1 100644 --- a/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java +++ b/validator/src/main/java/org/mustangproject/validator/ValidationResultItem.java @@ -12,6 +12,7 @@ public class ValidationResultItem { protected String message, location=null; protected int section =-1; + protected String id =""; // e.g. "FX-SCH-A-000026" private ESeverity severity=ESeverity.error; @@ -103,6 +104,15 @@ public class ValidationResultItem { return severity; } + public ValidationResultItem setID(String id) { + this.id=id; + return this; + } + + public String getID() { + return id; + } + public int getSection() { return section; } diff --git a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java index abe94216..77061ab9 100644 --- a/validator/src/main/java/org/mustangproject/validator/XMLValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/XMLValidator.java @@ -1,4 +1,5 @@ package org.mustangproject.validator; + import java.io.IOException; import java.io.PrintWriter; import java.io.StringReader; @@ -69,15 +70,13 @@ public class XMLValidator extends Validator { final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9) .setPart(EPart.fx); try (final StringWriter sw = new StringWriter(); - final PrintWriter pw = new PrintWriter(sw)) - { - e.printStackTrace(pw); - vri.setStacktrace(sw.toString()); - context.addResultItem(vri); + final PrintWriter pw = new PrintWriter(sw)) { + e.printStackTrace(pw); + vri.setStacktrace(sw.toString()); + context.addResultItem(vri); + } catch (IOException ex) { + throw new UncheckedIOException(ex); } - catch (IOException ex) { - throw new UncheckedIOException (ex); - } } } @@ -125,9 +124,9 @@ public class XMLValidator extends Validator { if (zfXML.isEmpty()) { final ValidationResultItem res = new ValidationResultItem(ESeverity.exception, - "XML data not found in " + filename - + ": did you specify a pdf or xml file and does the xml file contain an embedded XML file?") - .setSection(3); + "XML data not found in " + filename + + ": did you specify a pdf or xml file and does the xml file contain an embedded XML file?") + .setSection(3); context.addResultItem(res); } else { @@ -170,7 +169,7 @@ public class XMLValidator extends Validator { // Create XPath object final XPath xpath = xpathFactory.newXPath(); final XPathExpression expr = xpath.compile( - "(//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/*[local-name()=\"ID\"])/text()|//*[local-name()=\"CustomizationID\"]/text()"); + "(//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/*[local-name()=\"ID\"])/text()|//*[local-name()=\"CustomizationID\"]/text()"); // evaluate expression result on XML document ndList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); @@ -190,8 +189,8 @@ public class XMLValidator extends Validator { boolean isEN16931 = false; boolean isExtended = false; boolean isXRechnung = false; - String currentZFVersionDir = "ZF_230"; - int mainSchematronSectionErrorTypeCode=4; + String currentZFVersionDir = "ZF_232"; + int mainSchematronSectionErrorTypeCode = 4; String xsltFilename = null; // urn:ferd:CrossIndustryDocument:invoice:1p0:extended, // urn:ferd:CrossIndustryDocument:invoice:1p0:comfort, @@ -224,7 +223,7 @@ public class XMLValidator extends Validator { isBasic = false;// basicwl also contains the string basic... } isEN16931 = matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931") - || matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017"); + || matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017"); isExtended = context.getProfile().contains("extended"); isXRechnung = context.getProfile().contains("xrechnung"); @@ -269,16 +268,16 @@ public class XMLValidator extends Validator { // saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s // tcdl2.0.tsdtf.sch iso_svrl.xsl - } else if (root.getLocalName().equalsIgnoreCase("Invoice")) { + } else if (root.getLocalName().equalsIgnoreCase("Invoice") || root.getLocalName().equalsIgnoreCase("CreditNote")) { context.setGeneration("2"); context.setFormat("UBL"); isXRechnung = context.getProfile().contains("xrechnung"); // UBL LOGGER.debug("UBL"); - validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-Invoice-2.1.xsd", 18, EPart.fx); + validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-" + root.getLocalName() + "-2.1.xsd", 18, EPart.fx); xsltFilename = "/xslt/en16931schematron/EN16931-UBL-validation.xslt"; - mainSchematronSectionErrorTypeCode=24; + mainSchematronSectionErrorTypeCode = 24; if (isXRechnung) { validateSchematron(zfXML, xsltFilename, 24, ESeverity.error); @@ -287,14 +286,14 @@ public class XMLValidator extends Validator { XRechnung is a EN16931 subset so the validation vis a vis FACTUR-X_EN16931.xslt=schematron also has to pass * */ //validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_211/EN16931/FACTUR-X_EN16931.xsd", 18, EPart.fx); - String xrVersion=context.getProfile().substring(context.getProfile().length()-3).replace(".",""); - if (!xrVersion.equals("12")&&!xrVersion.equals("20")&&!xrVersion.equals("21")&&!xrVersion.equals("22")&&!xrVersion.equals("23")&&!xrVersion.equals("30")) { + String xrVersion = context.getProfile().substring(context.getProfile().length() - 3).replace(".", ""); + if (!xrVersion.equals("12") && !xrVersion.equals("20") && !xrVersion.equals("21") && !xrVersion.equals("22") && !xrVersion.equals("23") && !xrVersion.equals("30")) { throw new Exception("Unsupported XR version"); } - LOGGER.debug("is XRechnung v"+xrVersion); - xsltFilename = "/xslt/XR_"+xrVersion+"/XRechnung-UBL-validation.xslt"; + LOGGER.debug("is XRechnung v" + xrVersion); + xsltFilename = "/xslt/XR_" + xrVersion + "/XRechnung-UBL-validation.xslt"; XrechnungSeverity = ESeverity.error; - mainSchematronSectionErrorTypeCode=27; + mainSchematronSectionErrorTypeCode = 27; } @@ -302,58 +301,58 @@ public class XMLValidator extends Validator { context.setGeneration("1"); // if ((!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { + && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) + && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type") - .setSection(25).setPart(EPart.fx)); + .setSection(25).setPart(EPart.fx)); } validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_10/ZUGFeRD1p0.xsd", 18, EPart.fx); xsltFilename = "/xslt/ZUGFeRD_1p0.xslt"; } else { // unknown document root context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Unsupported root element") - .setSection(3).setPart(EPart.fx)); + .setSection(3).setPart(EPart.fx)); } if (context.getFormat().equals("CII")) { if (context.getGeneration().equals("2")) { if ((!matchesURI(context.getProfile(), "urn:factur-x.eu:1p0:minimum")) - && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:minimum")) - && (!matchesURI(context.getProfile(), "urn:factur-x.eu:1p0:basicwl")) - && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:basicwl")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:basic")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")) - && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended"))) { + && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:minimum")) + && (!matchesURI(context.getProfile(), "urn:factur-x.eu:1p0:basicwl")) + && (!matchesURI(context.getProfile(), "urn:zugferd.de:2p0:basicwl")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:basic")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")) + && (!matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended"))) { context.addResultItem( - new ValidationResultItem(ESeverity.error, "Unsupported profile type " + context.getProfile()) - .setSection(25).setPart(EPart.fx)); + new ValidationResultItem(ESeverity.error, "Unsupported profile type " + context.getProfile()) + .setSection(25).setPart(EPart.fx)); } } else /** v1 */ { if (isOrderX) { //order-x 1.0 if ((!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:comfort")) - && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:extended"))) { + && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:comfort")) + && (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:extended"))) { //zf 1.0 context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type") - .setSection(25).setPart(EPart.fx)); + .setSection(25).setPart(EPart.fx)); } } else if ((!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:basic")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) - && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { + && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort")) + && (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) { //zf 1.0 context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type") - .setSection(25).setPart(EPart.fx)); + .setSection(25).setPart(EPart.fx)); } } } - if (xsltFilename!=null) { + if (xsltFilename != null) { // main schematron validation validateSchematron(zfXML, xsltFilename, mainSchematronSectionErrorTypeCode, ESeverity.error); @@ -362,7 +361,7 @@ public class XMLValidator extends Validator { if (context.getFormat().equals("CII")) { if (context.getGeneration().equals("2") - && (isBasic || isEN16931 || isXRechnung)) { + && (isBasic || isEN16931 || isXRechnung)) { //additionally validate against CEN validateSchematron(zfXML, "/xslt/en16931schematron/EN16931-CII-validation.xslt", 24, ESeverity.error); if (!disableNotices || XrechnungSeverity != ESeverity.notice) { @@ -376,7 +375,7 @@ public class XMLValidator extends Validator { throw er; } catch (final Exception e) { final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(22) - .setPart(EPart.fx); + .setPart(EPart.fx); final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); @@ -388,8 +387,8 @@ public class XMLValidator extends Validator { final long endTime = Calendar.getInstance().getTimeInMillis(); context.addCustomXML("" + ((context.getGeneration() != null) ? context.getGeneration() : "invalid") - + "" + ((context.getProfile() != null) ? context.getProfile() : "invalid") + - "" + firedRules + "" + failedRules + "" + "" + (endTime - startXMLTime) + ""); + + "" + ((context.getProfile() != null) ? context.getProfile() : "invalid") + + "" + firedRules + "" + failedRules + "" + "" + (endTime - startXMLTime) + ""); } @@ -419,10 +418,10 @@ public class XMLValidator extends Validator { * @param xml the xml to be checked * @param xsltFilename the filename of the intermediate XSLT file * @param section the error type code, if one arises - * @param severity how serious a error should be treated - may only be notice + * @param defaultSeverity how serious a error should be treated - may only be notice * @throws IrrecoverableValidationError if anything happened that prevents further checks */ - public void validateSchematron(String xml, String xsltFilename, int section, ESeverity severity) throws IrrecoverableValidationError { + public void validateSchematron(String xml, String xsltFilename, int section, ESeverity defaultSeverity) throws IrrecoverableValidationError { ISchematronResource aResSCH = null; aResSCH = SchematronResourceXSLT.fromClassPath(xsltFilename); @@ -434,7 +433,7 @@ public class XMLValidator extends Validator { final SchematronOutputType sout; try { sout = aResSCH - .applySchematronValidationToSVRL(new StreamSource(new StringReader(xml))); + .applySchematronValidationToSVRL(new StreamSource(new StringReader(xml))); } catch (final Exception e) { throw new IrrecoverableValidationError(e.getMessage()); } @@ -448,6 +447,7 @@ public class XMLValidator extends Validator { String thisFailText = ""; String thisFailID = ""; + String thisFailIDStr = ""; String thisFailTest = ""; String thisFailLocation = ""; if (failedAsserts.getLength() > 0) { @@ -456,7 +456,8 @@ public class XMLValidator extends Validator { //nodes.item(i).getTextContent())) { Node currentFailNode = failedAsserts.item(nodeIndex); if (currentFailNode.getAttributes().getNamedItem("id") != null) { - thisFailID = " [ID " + currentFailNode.getAttributes().getNamedItem("id").getNodeValue() + "]"; + thisFailID = currentFailNode.getAttributes().getNamedItem("id").getNodeValue(); + thisFailIDStr = " [ID " + thisFailID + "]"; } if (currentFailNode.getAttributes().getNamedItem("test") != null) { thisFailTest = currentFailNode.getAttributes().getNamedItem("test").getNodeValue(); @@ -465,6 +466,17 @@ public class XMLValidator extends Validator { thisFailLocation = currentFailNode.getAttributes().getNamedItem("location").getNodeValue(); } + ESeverity severity; + if (defaultSeverity == ESeverity.notice) { + severity = defaultSeverity; + } else if (currentFailNode.getAttributes().getNamedItem("flag") != null + && currentFailNode.getAttributes().getNamedItem("flag").getNodeValue().equals("warning")) { + // the XR issues warnings with flag=warning + severity = ESeverity.warning; + } else { + severity = ESeverity.error; + } + NodeList failChilds = currentFailNode.getChildNodes(); for (int failChildIndex = 0; failChildIndex < failChilds.getLength(); failChildIndex++) { if (failChilds.item(failChildIndex).getLocalName() != null) { @@ -479,9 +491,9 @@ public class XMLValidator extends Validator { LOGGER.info("FailedAssert ", thisFailText); - context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailID + " from " + xsltFilename + ")") - .setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section) - .setPart(EPart.fx)); + context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailIDStr + " from " + xsltFilename + ")") + .setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section).setID(thisFailID) + .setPart(EPart.fx)); failedRules++; } @@ -512,7 +524,7 @@ public class XMLValidator extends Validator { if (firedRules == 0) { context.addResultItem(new ValidationResultItem(ESeverity.error, "No rules matched, XML to minimal?").setSection(26) - .setPart(EPart.fx)); + .setPart(EPart.fx)); } // for (String currentString : sout.getText()) { diff --git a/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java b/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java index edd9a73d..d21317b1 100644 --- a/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java +++ b/validator/src/main/java/org/mustangproject/validator/ZUGFeRDValidator.java @@ -318,7 +318,7 @@ public class ZUGFeRDValidator { LOGGER.info("Parsed PDF:" + pdfResult + " XML:" + (xmlValidity ? "valid" : "invalid") + " Signature:" + Signature + " Checksum:" + sha1Checksum + " Profile:" + context.getProfile() + " Version:" + context.getGeneration() + " Took:" + duration + "ms Errors:[" + context.getCSVResult() - + "] " + toBeAppended); + + "] ErrorIDs: [" + context.getCSVIDResult() + "]" + toBeAppended); wasCompletelyValid = ((pdfValidity) && (xmlValidity)); return sw.toString(); } diff --git a/validator/src/main/resources/schema/ZF_230/BASIC-WL/FACTUR-X_BASIC-WL.xsd b/validator/src/main/resources/schema/ZF_232/BASIC-WL/FACTUR-X_BASIC-WL.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/BASIC-WL/FACTUR-X_BASIC-WL.xsd rename to validator/src/main/resources/schema/ZF_232/BASIC-WL/FACTUR-X_BASIC-WL.xsd diff --git a/validator/src/main/resources/schema/ZF_230/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schema/ZF_230/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd b/validator/src/main/resources/schema/ZF_232/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd similarity index 98% rename from validator/src/main/resources/schema/ZF_230/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd rename to validator/src/main/resources/schema/ZF_232/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd index 89d8a099..f6345542 100644 --- a/validator/src/main/resources/schema/ZF_230/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +++ b/validator/src/main/resources/schema/ZF_232/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd @@ -5,8 +5,8 @@ xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" targetNamespace="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" elementFormDefault="qualified"> - - + + diff --git a/validator/src/main/resources/schema/ZF_230/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/BASIC-WL/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schema/ZF_230/BASIC/FACTUR-X_BASIC.xsd b/validator/src/main/resources/schema/ZF_232/BASIC/FACTUR-X_BASIC.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/BASIC/FACTUR-X_BASIC.xsd rename to validator/src/main/resources/schema/ZF_232/BASIC/FACTUR-X_BASIC.xsd diff --git a/validator/src/main/resources/schema/ZF_230/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schema/ZF_230/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd b/validator/src/main/resources/schema/ZF_232/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd similarity index 99% rename from validator/src/main/resources/schema/ZF_230/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd rename to validator/src/main/resources/schema/ZF_232/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd index 35458e59..517d0fb0 100644 --- a/validator/src/main/resources/schema/ZF_230/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +++ b/validator/src/main/resources/schema/ZF_232/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd @@ -5,8 +5,8 @@ xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" targetNamespace="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" elementFormDefault="qualified"> - - + + diff --git a/validator/src/main/resources/schema/ZF_230/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/BASIC/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schema/ZF_230/EN16931/FACTUR-X_EN16931.xsd b/validator/src/main/resources/schema/ZF_232/EN16931/FACTUR-X_EN16931.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/EN16931/FACTUR-X_EN16931.xsd rename to validator/src/main/resources/schema/ZF_232/EN16931/FACTUR-X_EN16931.xsd diff --git a/validator/src/main/resources/schema/ZF_230/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schema/ZF_230/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd b/validator/src/main/resources/schema/ZF_232/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd similarity index 99% rename from validator/src/main/resources/schema/ZF_230/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd rename to validator/src/main/resources/schema/ZF_232/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd index 62bcf3dd..b9dfd083 100644 --- a/validator/src/main/resources/schema/ZF_230/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +++ b/validator/src/main/resources/schema/ZF_232/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd @@ -5,8 +5,8 @@ xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" targetNamespace="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" elementFormDefault="qualified"> - - + + diff --git a/validator/src/main/resources/schema/ZF_230/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/EN16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schema/ZF_230/EXTENDED/FACTUR-X_EXTENDED.xsd b/validator/src/main/resources/schema/ZF_232/EXTENDED/FACTUR-X_EXTENDED.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/EXTENDED/FACTUR-X_EXTENDED.xsd rename to validator/src/main/resources/schema/ZF_232/EXTENDED/FACTUR-X_EXTENDED.xsd diff --git a/validator/src/main/resources/schema/ZF_230/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schema/ZF_230/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd b/validator/src/main/resources/schema/ZF_232/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd similarity index 99% rename from validator/src/main/resources/schema/ZF_230/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd rename to validator/src/main/resources/schema/ZF_232/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd index 7e42a4f8..80ee1129 100644 --- a/validator/src/main/resources/schema/ZF_230/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +++ b/validator/src/main/resources/schema/ZF_232/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd @@ -5,8 +5,8 @@ xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" targetNamespace="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" elementFormDefault="qualified"> - - + + diff --git a/validator/src/main/resources/schema/ZF_230/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/EXTENDED/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schema/ZF_230/MINIMUM/FACTUR-X_MINIMUM.xsd b/validator/src/main/resources/schema/ZF_232/MINIMUM/FACTUR-X_MINIMUM.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/MINIMUM/FACTUR-X_MINIMUM.xsd rename to validator/src/main/resources/schema/ZF_232/MINIMUM/FACTUR-X_MINIMUM.xsd diff --git a/validator/src/main/resources/schema/ZF_230/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schema/ZF_230/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd b/validator/src/main/resources/schema/ZF_232/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd similarity index 97% rename from validator/src/main/resources/schema/ZF_230/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd rename to validator/src/main/resources/schema/ZF_232/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd index 8fad95ed..389563bd 100644 --- a/validator/src/main/resources/schema/ZF_230/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +++ b/validator/src/main/resources/schema/ZF_232/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd @@ -5,8 +5,8 @@ xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" targetNamespace="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" elementFormDefault="qualified"> - - + + diff --git a/validator/src/main/resources/schema/ZF_230/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd b/validator/src/main/resources/schema/ZF_232/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd similarity index 100% rename from validator/src/main/resources/schema/ZF_230/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd rename to validator/src/main/resources/schema/ZF_232/MINIMUM/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC-WL.sch b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC-WL.sch similarity index 99% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC-WL.sch rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC-WL.sch index 9a08c305..29de139b 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC-WL.sch +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC-WL.sch @@ -1,5 +1,5 @@ - Schema for Factur-X; 1.0.07; Accounting, BASIC without Lines + Schema for Factur-X; 1.07.2; Accounting, BASIC without Lines @@ -164,7 +164,7 @@ [BR-AG-03]-An Invoice that contains a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-06]-In a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" the Document level allowance VAT rate (BT-96) shall be 0 (zero) or greater than zero. @@ -236,7 +236,7 @@ [BR-AG-04]-An Invoice that contains a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-07]-In a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" the Document level charge VAT rate (BT-103) shall be 0 (zero) or greater than zero. @@ -322,12 +322,16 @@ [BR-CO-27]-Either the IBAN or a Proprietary ID (BT-84) shall be used. + + + + [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. + + [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. - - [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC-WL_codedb.xml b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC-WL_codedb.xml similarity index 98% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC-WL_codedb.xml rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC-WL_codedb.xml index cc567d65..b5fef2d7 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC-WL_codedb.xml +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC-WL_codedb.xml @@ -2,6 +2,7 @@ + @@ -692,6 +693,14 @@ + + + + + + + + @@ -919,6 +928,14 @@ + + + + + + + + @@ -1189,6 +1206,7 @@ + @@ -1220,6 +1238,7 @@ + @@ -1336,7 +1355,6 @@ - @@ -1429,6 +1447,7 @@ + @@ -1453,6 +1472,7 @@ + @@ -1588,6 +1608,8 @@ + + @@ -1603,6 +1625,7 @@ + @@ -1884,7 +1907,6 @@ - @@ -1977,6 +1999,7 @@ + @@ -2001,6 +2024,7 @@ + @@ -2065,7 +2089,6 @@ - @@ -2158,6 +2181,7 @@ + @@ -2182,6 +2206,7 @@ + diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC.sch b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC.sch similarity index 99% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC.sch rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC.sch index dfaefe8b..9a8304eb 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC.sch +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC.sch @@ -1,5 +1,5 @@ - Schema for Factur-X; 1.0.07; EN16931-COMPLIANT-BASIC + Schema for Factur-X; 1.07.2; EN16931-COMPLIANT-BASIC @@ -118,7 +118,7 @@ [BR-65]-The Item classification identifier (BT-158) shall have a Scheme identifier. [BR-CO-04]-Each Invoice line (BG-25) shall be categorized with an Invoiced item VAT category code (BT-151). - + [BR-DEC-23]-The allowed maximum number of decimals for the Invoice line net amount (BT-131) is 2. @@ -246,7 +246,7 @@ [BR-AG-03]-An Invoice that contains a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-06]-In a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" the Document level allowance VAT rate (BT-96) shall be 0 (zero) or greater than zero. @@ -318,7 +318,7 @@ [BR-AG-04]-An Invoice that contains a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-07]-In a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" the Document level charge VAT rate (BT-103) shall be 0 (zero) or greater than zero. @@ -406,12 +406,16 @@ [BR-CO-27]-Either the IBAN or a Proprietary ID (BT-84) shall be used. + + + + [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. + + [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. - - [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. @@ -546,7 +550,7 @@ [BR-AG-02]-An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-05]-In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" the Invoiced item VAT rate (BT-152) shall be 0 (zero) or greater than zero. diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC_codedb.xml b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC_codedb.xml similarity index 99% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC_codedb.xml rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC_codedb.xml index ce1fdffe..d8154cdc 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC_codedb.xml +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_BASIC_codedb.xml @@ -2,6 +2,7 @@ + @@ -692,6 +693,14 @@ + + + + + + + + @@ -3298,6 +3307,14 @@ + + + + + + + + @@ -3525,6 +3542,14 @@ + + + + + + + + @@ -3795,6 +3820,7 @@ + @@ -3826,6 +3852,7 @@ + @@ -3942,7 +3969,6 @@ - @@ -4035,6 +4061,7 @@ + @@ -4059,6 +4086,7 @@ + @@ -4180,6 +4208,8 @@ + + @@ -4195,6 +4225,7 @@ + @@ -4476,7 +4507,6 @@ - @@ -4569,6 +4599,7 @@ + @@ -4593,6 +4624,7 @@ + @@ -4657,7 +4689,6 @@ - @@ -4750,6 +4781,7 @@ + @@ -4774,6 +4806,7 @@ + diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_EN16931.sch b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_EN16931.sch similarity index 99% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_EN16931.sch rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_EN16931.sch index 179768be..86eefe5a 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_EN16931.sch +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_EN16931.sch @@ -1,5 +1,5 @@ - Schema for Factur-X; 1.0.07; EN16931-COMPLIANT (FULLY) + Schema for Factur-X; 1.07.2; EN16931-COMPLIANT (FULLY) @@ -130,7 +130,7 @@ [BR-65]-The Item classification identifier (BT-158) shall have a Scheme identifier. [BR-CO-04]-Each Invoice line (BG-25) shall be categorized with an Invoiced item VAT category code (BT-151). - + [BR-DEC-23]-The allowed maximum number of decimals for the Invoice line net amount (BT-131) is 2. @@ -258,7 +258,7 @@ [BR-AG-03]-An Invoice that contains a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-06]-In a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" the Document level allowance VAT rate (BT-96) shall be 0 (zero) or greater than zero. @@ -330,7 +330,7 @@ [BR-AG-04]-An Invoice that contains a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-07]-In a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" the Document level charge VAT rate (BT-103) shall be 0 (zero) or greater than zero. @@ -418,12 +418,16 @@ [BR-CO-27]-Either the IBAN or a Proprietary ID (BT-84) shall be used. + + + + [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. + + [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. - - [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. @@ -558,7 +562,7 @@ [BR-AG-02]-An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-05]-In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" the Invoiced item VAT rate (BT-152) shall be 0 (zero) or greater than zero. diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_EN16931_codedb.xml b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_EN16931_codedb.xml similarity index 99% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_EN16931_codedb.xml rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_EN16931_codedb.xml index d0ad2b33..ae1b08a2 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_EN16931_codedb.xml +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_EN16931_codedb.xml @@ -692,6 +692,14 @@ + + + + + + + + @@ -4561,6 +4569,14 @@ + + + + + + + + @@ -4788,6 +4804,14 @@ + + + + + + + + @@ -4805,6 +4829,7 @@ + @@ -4836,6 +4861,7 @@ + @@ -4969,7 +4995,6 @@ - @@ -5062,6 +5087,7 @@ + @@ -5086,6 +5112,7 @@ + @@ -5207,6 +5234,8 @@ + + @@ -5222,6 +5251,7 @@ + @@ -5506,7 +5536,6 @@ - @@ -5599,6 +5628,7 @@ + @@ -5623,6 +5653,7 @@ + @@ -5687,7 +5718,6 @@ - @@ -5780,6 +5810,7 @@ + @@ -5804,6 +5835,7 @@ + diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_EXTENDED.sch b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_EXTENDED.sch similarity index 98% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_EXTENDED.sch rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_EXTENDED.sch index c17c0359..75f84b54 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_EXTENDED.sch +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_EXTENDED.sch @@ -1,5 +1,5 @@ - Schema for Factur-X; 1.0.07; EN16931-CONFORMANT-EXTENDED + Schema for Factur-X; 1.07.2; EN16931-CONFORMANT-EXTENDED @@ -102,6 +102,12 @@ [BR-54]-Each Item attribute (BG-32) shall contain an Item attribute name (BT-160) and an Item attribute value (BT-161). + + + + [BR-FXEXT-04]-To ensure automated processing of the article attributes without bilateral reconciliation, only values from the code list UNTDED 6313+Factur-X-Extension should be used. + + @@ -138,7 +144,7 @@ [BR-65]-The Item classification identifier (BT-158) shall have a Scheme identifier. [BR-CO-04]-Each Invoice line (BG-25) shall be categorized with an Invoiced item VAT category code (BT-151). - + [BR-DEC-23]-The allowed maximum number of decimals for the Invoice line net amount (BT-131) is 2. @@ -272,7 +278,7 @@ [BR-AG-03]-An Invoice that contains a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-06]-In a Document level allowance (BG-20) where the Document level allowance VAT category code (BT-95) is "IPSI" the Document level allowance VAT rate (BT-96) shall be 0 (zero) or greater than zero. @@ -342,7 +348,7 @@ [BR-AG-04]-An Invoice that contains a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller Tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-07]-In a Document level charge (BG-21) where the Document level charge VAT category code (BT-102) is "IPSI" the Document level charge VAT rate (BT-103) shall be 0 (zero) or greater than zero. @@ -380,9 +386,9 @@ [BR-14]-An Invoice shall have the Invoice total amount with VAT (BT-112). [BR-15]-An Invoice shall have the Amount due for payment (BT-115). - + [BR-FXEXT-CO-11]-Absolute Value of (Sum of allowances on document level (BT-107) - Σ Document level allowance amounts (BT-92))<= 0,01 * Number of Document level allowance amounts (BT-92). - + [BR-FXEXT-CO-12]-Absolute Value of (Sum of charges on document level (BT-108) - Σ Document level charge amounts (BT-99) - Σ Logistics Service fee amounts (BT-x-272))<= 0,01 * (Number of Document level charge amounts (BT-99) + Number of Logistics Service fee amounts (BT-X-272)). [BR-FXEXT-CO-13]-Absolute Value of (Invoice total amount without VAT (BT-109) - ∑ Invoice line net amounts (BT-131) + Σ Document level allowance amounts (BT-92) - Σ Document level charge amounts (BT-99)) <= 0,01 * (Number of line net amounts (BT-131) + Number of Document level allowance amounts (BT-92) + Number of Document level charge amounts (BT-99)). @@ -428,12 +434,16 @@ [BR-CO-27]-Either the IBAN or a Proprietary ID (BT-84) shall be used. + + + + [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. + + [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. - - [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. @@ -560,7 +570,7 @@ [BR-AG-02]-An Invoice that contains an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" shall contain the Seller VAT Identifier (BT-31), the Seller tax registration identifier (BT-32) and/or the Seller tax representative VAT identifier (BT-63). - + [BR-AG-05]-In an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is "IPSI" the Invoiced item VAT rate (BT-152) shall be 0 (zero) or greater than zero. @@ -1131,8 +1141,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -1165,8 +1175,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -1371,8 +1381,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -1405,8 +1415,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -1548,8 +1558,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -1582,8 +1592,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -1796,8 +1806,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -1830,8 +1840,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -2036,8 +2046,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -2070,8 +2080,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -2278,8 +2288,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -2312,8 +2322,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -2462,8 +2472,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -2496,8 +2506,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -2849,6 +2859,13 @@ Element 'ram:ModeCode' must occur exactly 1 times. + + + + + Value of 'ram:ModeCode' is not allowed. + + @@ -2938,8 +2955,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -2972,8 +2989,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -3115,8 +3132,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -3149,8 +3166,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -3292,8 +3309,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -3326,8 +3343,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -3435,8 +3452,8 @@ - - + + Value of 'ram:DueDateTypeCode' is not allowed. @@ -3473,8 +3490,8 @@ - - + + Value of '@format' is not allowed. @@ -3531,8 +3548,8 @@ - - + + Value of 'ram:InvoiceCurrencyCode' is not allowed. @@ -3589,8 +3606,8 @@ - - + + Value of 'ram:TypeCode' is not allowed. @@ -3691,8 +3708,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -3725,8 +3742,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -3870,8 +3887,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -3904,8 +3921,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -4049,8 +4066,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -4083,8 +4100,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -4228,8 +4245,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -4262,8 +4279,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -4324,8 +4341,8 @@ - - + + Value of 'ram:TypeCode' is not allowed. @@ -4480,8 +4497,8 @@ - - + + Value of 'ram:TypeCode' is not allowed. @@ -4692,8 +4709,8 @@ - - + + Value of 'ram:ReasonCode' is not allowed. @@ -4798,8 +4815,8 @@ - - + + Value of 'ram:ReasonCode' is not allowed. @@ -4987,8 +5004,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -5021,8 +5038,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -5149,8 +5166,8 @@ - - + + Value of '@currencyID' is not allowed. @@ -5162,8 +5179,8 @@ - - + + Value of '@currencyID' is not allowed. @@ -5239,8 +5256,8 @@ - - + + Value of 'ram:TypeCode' is not allowed. @@ -5259,22 +5276,22 @@ - - + + Value of 'ram:SourceCurrencyCode' is not allowed. - - + + Value of 'ram:TargetCurrencyCode' is not allowed. - - + + Value of 'ram:TaxCurrencyCode' is not allowed. @@ -6273,8 +6290,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -6435,8 +6452,8 @@ - - + + Value of 'ram:CountryID' is not allowed. @@ -6915,13 +6932,6 @@ Element 'ram:Value' must occur exactly 1 times. - - - - - Value of 'ram:TypeCode' is not allowed. - - @@ -6960,8 +6970,8 @@ - - + + Value of '@listID' is not allowed. @@ -7010,6 +7020,13 @@ Attribute '@schemeID' is required in this context. + + + + + Value of '@schemeID' is not allowed. + + @@ -7073,8 +7090,8 @@ - - + + Value of 'ram:ID' is not allowed. diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_EXTENDED_codedb.xml b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_EXTENDED_codedb.xml similarity index 95% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_EXTENDED_codedb.xml rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_EXTENDED_codedb.xml index c1e94944..62d10ca4 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_EXTENDED_codedb.xml +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_EXTENDED_codedb.xml @@ -2,6 +2,7 @@ + @@ -818,302 +819,16 @@ + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1299,7 +1014,7 @@ - + @@ -1552,6 +1267,241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4804,6 +4754,8 @@ + + @@ -4819,6 +4771,7 @@ + @@ -5058,6 +5011,14 @@ + + + + + + + + @@ -5285,6 +5246,14 @@ + + + + + + + + @@ -5302,6 +5271,7 @@ + @@ -5333,6 +5303,7 @@ + @@ -5728,6 +5699,18 @@ + + + + + + + + + + + + @@ -5789,7 +5772,6 @@ - @@ -5882,6 +5864,7 @@ + @@ -5906,9 +5889,10 @@ + - + @@ -5994,15 +5978,15 @@ - + - + - + @@ -6023,7 +6007,7 @@ - + @@ -6203,187 +6187,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6446,7 +6249,6 @@ - @@ -6539,6 +6341,7 @@ + @@ -6563,9 +6366,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6622,7 +6608,7 @@ - + @@ -6631,7 +6617,7 @@ - + diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_MINIMUM.sch b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_MINIMUM.sch similarity index 99% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_MINIMUM.sch rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_MINIMUM.sch index 82fde99f..dd86da5b 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_MINIMUM.sch +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_MINIMUM.sch @@ -1,5 +1,5 @@ - Schema for Factur-X; 1.0.07; Accounting, MINIMUM + Schema for Factur-X; 1.07.2; Accounting, MINIMUM diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_MINIMUM_codedb.xml b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_MINIMUM_codedb.xml similarity index 98% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_MINIMUM_codedb.xml rename to validator/src/main/resources/schematron/ZF_232/FACTUR-X_MINIMUM_codedb.xml index 74a7b49c..c07e49f4 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_MINIMUM_codedb.xml +++ b/validator/src/main/resources/schematron/ZF_232/FACTUR-X_MINIMUM_codedb.xml @@ -2,6 +2,7 @@ + @@ -289,6 +290,14 @@ + + + + + + + + @@ -605,7 +614,6 @@ - @@ -698,6 +706,7 @@ + @@ -722,6 +731,7 @@ + @@ -786,7 +796,6 @@ - @@ -879,6 +888,7 @@ + @@ -903,6 +913,7 @@ + diff --git a/validator/src/main/resources/xslt/XR_22/XRechnung-CII-validation.xslt b/validator/src/main/resources/xslt/XR_22/XRechnung-CII-validation.xslt index 58c2e721..a9d2063b 100644 --- a/validator/src/main/resources/xslt/XR_22/XRechnung-CII-validation.xslt +++ b/validator/src/main/resources/xslt/XR_22/XRechnung-CII-validation.xslt @@ -211,7 +211,7 @@ - + @@ -344,7 +344,7 @@ - + @@ -365,7 +365,7 @@ - + @@ -386,7 +386,7 @@ - + @@ -422,7 +422,7 @@ - + @@ -503,7 +503,7 @@ - + @@ -539,7 +539,7 @@ - + @@ -575,7 +575,7 @@ - + @@ -626,7 +626,7 @@ - + @@ -662,7 +662,7 @@ - + @@ -713,7 +713,7 @@ - + @@ -734,11 +734,11 @@ - + - + @@ -764,7 +764,7 @@ - + @@ -787,7 +787,7 @@ - + @@ -810,7 +810,7 @@ - + @@ -833,7 +833,7 @@ - + @@ -856,10 +856,10 @@ - + - + diff --git a/validator/src/main/resources/xslt/XR_23/XRechnung-CII-validation.xslt b/validator/src/main/resources/xslt/XR_23/XRechnung-CII-validation.xslt index 9732db99..4306177e 100644 --- a/validator/src/main/resources/xslt/XR_23/XRechnung-CII-validation.xslt +++ b/validator/src/main/resources/xslt/XR_23/XRechnung-CII-validation.xslt @@ -214,7 +214,7 @@ - + @@ -396,7 +396,7 @@ - + @@ -417,7 +417,7 @@ - + @@ -438,7 +438,7 @@ - + @@ -474,7 +474,7 @@ - + @@ -555,7 +555,7 @@ - + @@ -591,7 +591,7 @@ - + @@ -627,7 +627,7 @@ - + @@ -678,7 +678,7 @@ - + @@ -714,7 +714,7 @@ - + @@ -765,7 +765,7 @@ - + @@ -786,11 +786,11 @@ - + - + @@ -816,7 +816,7 @@ - + @@ -839,7 +839,7 @@ - + @@ -862,7 +862,7 @@ - + @@ -885,7 +885,7 @@ - + @@ -908,10 +908,10 @@ - + - + diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC-WL.xslt b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC-WL.xslt similarity index 97% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC-WL.xslt rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC-WL.xslt index 931cc737..36484a84 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC-WL.xslt +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC-WL.xslt @@ -153,7 +153,7 @@ - +     @@ -1522,11 +1522,18 @@ + + + + + + + -Schema for Factur-X; 1.0.07; Accounting, BASIC without Lines +Schema for Factur-X; 1.07.2; Accounting, BASIC without Lines @@ -2450,9 +2457,9 @@ - + - + FX-SCH-A-000092 @@ -2837,9 +2844,9 @@ - + - + FX-SCH-A-000110 @@ -3373,23 +3380,8 @@ - - - - - - - - - FX-SCH-A-000133 - - - - - [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. - - - + + @@ -3416,7 +3408,35 @@ - + + + + + + + + + FX-SCH-A-000133 + + + + + [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. + + + + + + + + + + + + + + + @@ -3433,18 +3453,18 @@ - + - - - + + + - + @@ -3476,18 +3496,18 @@ - + - - - + + + - + @@ -3519,18 +3539,18 @@ - + - - - + + + - + @@ -3562,18 +3582,18 @@ - + - - - + + + - + @@ -3635,18 +3655,18 @@ - + - - - + + + - + @@ -3678,18 +3698,18 @@ - + - - - + + + - + @@ -3721,18 +3741,18 @@ - + - - - + + + - + @@ -3809,18 +3829,18 @@ - + - - - + + + - + @@ -4032,18 +4052,18 @@ - + - - - + + + - + @@ -4075,18 +4095,18 @@ - + - - - + + + - + @@ -4099,18 +4119,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -4142,18 +4162,18 @@ - + - - - + + + - + @@ -4171,18 +4191,18 @@ - + - - - + + + - + @@ -4199,18 +4219,18 @@ - + - - - + + + - + @@ -4228,18 +4248,18 @@ - + - - - + + + - + @@ -4257,18 +4277,18 @@ - + - - - + + + - + @@ -4300,18 +4320,18 @@ - + - - - + + + - + @@ -4328,18 +4348,18 @@ - + - - - + + + - + @@ -4352,18 +4372,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -4380,18 +4400,18 @@ - + - - - + + + - + @@ -4409,18 +4429,18 @@ - + - - - + + + - + @@ -4433,18 +4453,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -4476,18 +4496,18 @@ - + - - - + + + - + @@ -4504,30 +4524,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. - - @@ -4539,8 +4535,8 @@ - - + + @@ -4549,7 +4545,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -4563,7 +4559,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -4655,18 +4675,18 @@ - + - - - + + + - + @@ -4683,18 +4703,18 @@ - + - - - + + + - + @@ -4712,18 +4732,18 @@ - + - - - + + + - + @@ -4736,18 +4756,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -4779,18 +4799,18 @@ - + - - - + + + - + @@ -4808,18 +4828,18 @@ - + - - - + + + - + @@ -4837,18 +4857,18 @@ - + - - - + + + - + @@ -4861,18 +4881,18 @@ Element 'ram:TradingBusinessName' is marked as not used in the given context. - + - - - + + + - + @@ -4889,18 +4909,18 @@ - + - - - + + + - + @@ -4917,18 +4937,18 @@ - + - - - + + + - + @@ -4946,18 +4966,18 @@ - + - - - + + + - + @@ -4974,18 +4994,18 @@ - + - - - + + + - + @@ -5002,18 +5022,18 @@ - + - - - + + + - + @@ -5031,18 +5051,18 @@ - + - - - + + + - + @@ -5059,30 +5079,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. - - @@ -5094,8 +5090,8 @@ - - + + @@ -5104,7 +5100,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -5118,7 +5114,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -5165,30 +5185,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:GlobalID' is marked as not used in the given context. - - @@ -5200,8 +5196,8 @@ - - + + @@ -5210,7 +5206,7 @@ - Element 'ram:ID' is marked as not used in the given context. + Element 'ram:GlobalID' is marked as not used in the given context. @@ -5224,7 +5220,31 @@ - + + + + + + + + + + + Element 'ram:ID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -5256,18 +5276,18 @@ - + - - - + + + - + @@ -5285,18 +5305,18 @@ - + - - - + + + - + @@ -5309,18 +5329,18 @@ Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. - + - - - + + + - + @@ -5337,18 +5357,18 @@ - + - - - + + + - + @@ -5365,18 +5385,18 @@ - + - - - + + + - + @@ -5394,18 +5414,18 @@ - + - - - + + + - + @@ -5418,18 +5438,18 @@ Element 'ram:URIUniversalCommunication' is marked as not used in the given context. - + - - - + + + - + @@ -5506,18 +5526,18 @@ - + - - - + + + - + @@ -5534,18 +5554,18 @@ - + - - - + + + - + @@ -5563,18 +5583,18 @@ - + - - - + + + - + @@ -5587,18 +5607,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -5630,18 +5650,18 @@ - + - - - + + + - + @@ -5659,18 +5679,18 @@ - + - - - + + + - + @@ -5688,18 +5708,18 @@ - + - - - + + + - + @@ -5712,18 +5732,18 @@ Element variant 'ram:SpecifiedTaxRegistration[ not(ram:ID/@schemeID="VA") and not(ram:ID/@schemeID="FC")]' is marked as not used in the given context. - + - - - + + + - + @@ -5740,18 +5760,18 @@ - + - - - + + + - + @@ -5768,18 +5788,18 @@ - + - - - + + + - + @@ -5796,18 +5816,18 @@ - + - - - + + + - + @@ -5824,18 +5844,18 @@ - + - - - + + + - + @@ -5852,18 +5872,18 @@ - + - - - + + + - + @@ -5880,18 +5900,18 @@ - + - - - + + + - + @@ -5909,18 +5929,18 @@ - + - - - + + + - + @@ -5937,18 +5957,18 @@ - + - - - + + + - + @@ -5965,18 +5985,18 @@ - + - - - + + + - + @@ -5993,18 +6013,18 @@ - + - - - + + + - + @@ -6022,18 +6042,18 @@ - + - - - + + + - + @@ -6050,30 +6070,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. - - @@ -6085,8 +6081,8 @@ - - + + @@ -6095,7 +6091,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -6109,7 +6105,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -6141,18 +6161,18 @@ - + - - - + + + - + @@ -6169,18 +6189,18 @@ - + - - - + + + - + @@ -6198,18 +6218,18 @@ - + - - - + + + - + @@ -6222,18 +6242,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -6265,18 +6285,18 @@ - + - - - + + + - + @@ -6294,30 +6314,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. - - @@ -6329,8 +6325,8 @@ - - + + @@ -6339,7 +6335,7 @@ - Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. + Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. @@ -6353,8 +6349,8 @@ - - + + @@ -6363,7 +6359,7 @@ - Element 'ram:URIUniversalCommunication' is marked as not used in the given context. + Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. @@ -6377,7 +6373,31 @@ - + + + + + + + + + + + Element 'ram:URIUniversalCommunication' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -6469,18 +6489,18 @@ - + - - - + + + - + @@ -6542,30 +6562,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -6577,8 +6573,8 @@ - - + + @@ -6601,7 +6597,31 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -6619,18 +6639,18 @@ - + - - - + + + - + @@ -6648,18 +6668,18 @@ - + - - - + + + - + @@ -6677,18 +6697,18 @@ - + - - - + + + - + @@ -6706,18 +6726,18 @@ - + - - - + + + - + @@ -6734,18 +6754,18 @@ - + - - - + + + - + @@ -6763,18 +6783,18 @@ - + - - - + + + - + @@ -6791,18 +6811,18 @@ - + - - - + + + - + @@ -6820,18 +6840,18 @@ - + - - - + + + - + @@ -6844,18 +6864,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -6873,18 +6893,18 @@ - + - - - + + + - + @@ -6916,18 +6936,18 @@ - + - - - + + + - + @@ -6944,18 +6964,18 @@ - + - - - + + + - + @@ -6973,18 +6993,18 @@ - + - - - + + + - + @@ -6997,18 +7017,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -7055,18 +7075,18 @@ - + - - - + + + - + @@ -7083,18 +7103,18 @@ - + - - - + + + - + @@ -7112,30 +7132,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -7147,8 +7143,8 @@ - - + + @@ -7157,7 +7153,7 @@ - Element 'ram:PostalTradeAddress' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -7171,7 +7167,31 @@ - + + + + + + + + + + + Element 'ram:PostalTradeAddress' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -7189,30 +7209,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:TradingBusinessName' is marked as not used in the given context. - - @@ -7224,8 +7220,8 @@ - - + + @@ -7234,7 +7230,7 @@ - Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. + Element 'ram:TradingBusinessName' is marked as not used in the given context. @@ -7248,8 +7244,8 @@ - - + + @@ -7258,7 +7254,7 @@ - Element 'ram:URIUniversalCommunication' is marked as not used in the given context. + Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. @@ -7272,8 +7268,8 @@ - - + + @@ -7282,7 +7278,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:URIUniversalCommunication' is marked as not used in the given context. @@ -7296,8 +7292,8 @@ - - + + @@ -7306,7 +7302,7 @@ - Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -7320,7 +7316,31 @@ - + + + + + + + + + + + Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -7367,30 +7387,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -7402,8 +7398,8 @@ - - + + @@ -7426,7 +7422,31 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -7458,30 +7478,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisAmount' is marked as not used in the given context. - - @@ -7493,8 +7489,8 @@ - - + + @@ -7503,7 +7499,7 @@ - Element 'ram:CalculatedAmount' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -7517,7 +7513,31 @@ - + + + + + + + + + + + Element 'ram:CalculatedAmount' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -7535,30 +7555,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - @@ -7570,8 +7566,8 @@ - - + + @@ -7580,7 +7576,7 @@ - Element 'ram:ExemptionReason' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -7594,8 +7590,8 @@ - - + + @@ -7604,7 +7600,7 @@ - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -7618,7 +7614,31 @@ - + + + + + + + + + + + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -7636,18 +7656,18 @@ - + - - - + + + - + @@ -7665,18 +7685,18 @@ - + - - - + + + - + @@ -7723,30 +7743,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -7758,8 +7754,8 @@ - - + + @@ -7782,7 +7778,31 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -7814,30 +7834,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisAmount' is marked as not used in the given context. - - @@ -7849,8 +7845,8 @@ - - + + @@ -7859,7 +7855,7 @@ - Element 'ram:CalculatedAmount' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -7873,7 +7869,31 @@ - + + + + + + + + + + + Element 'ram:CalculatedAmount' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -7891,30 +7911,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - @@ -7926,8 +7922,8 @@ - - + + @@ -7936,7 +7932,7 @@ - Element 'ram:ExemptionReason' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -7950,8 +7946,8 @@ - - + + @@ -7960,7 +7956,7 @@ - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -7974,7 +7970,31 @@ - + + + + + + + + + + + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -7992,18 +8012,18 @@ - + - - - + + + - + @@ -8021,18 +8041,18 @@ - + - - - + + + - + @@ -8064,18 +8084,18 @@ - + - - - + + + - + @@ -8088,18 +8108,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -8116,18 +8136,18 @@ - + - - - + + + - + @@ -8145,18 +8165,18 @@ - + - - - + + + - + @@ -8293,30 +8313,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -8328,8 +8324,8 @@ - - + + @@ -8352,8 +8348,8 @@ - - + + @@ -8376,8 +8372,8 @@ - - + + @@ -8400,8 +8396,8 @@ - - + + @@ -8424,8 +8420,8 @@ - - + + @@ -8448,8 +8444,8 @@ - - + + @@ -8458,7 +8454,7 @@ - Element variant 'ram:TaxTotalAmount[ not(@currencyID=../../ram:InvoiceCurrencyCode) and not(@currencyID=../../ram:TaxCurrencyCode)]' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -8472,7 +8468,31 @@ - + + + + + + + + + + + Element variant 'ram:TaxTotalAmount[ not(@currencyID=../../ram:InvoiceCurrencyCode) and not(@currencyID=../../ram:TaxCurrencyCode)]' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -8490,18 +8510,18 @@ - + - - - + + + - + @@ -8518,18 +8538,18 @@ - + - - - + + + - + @@ -8547,18 +8567,18 @@ - + - - - + + + - + @@ -8575,18 +8595,18 @@ - + - - - + + + - + @@ -8599,18 +8619,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -8642,30 +8662,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -8677,8 +8673,8 @@ - - + + @@ -8701,7 +8697,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -8718,18 +8738,18 @@ - + - - - + + + - + @@ -8742,18 +8762,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -8771,18 +8791,18 @@ - + - - - + + + - + @@ -8800,10 +8820,10 @@ - + - - - + + + diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC-WL_codedb.xml b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC-WL_codedb.xml similarity index 98% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC-WL_codedb.xml rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC-WL_codedb.xml index cc567d65..b5fef2d7 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC-WL_codedb.xml +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC-WL_codedb.xml @@ -2,6 +2,7 @@ + @@ -692,6 +693,14 @@ + + + + + + + + @@ -919,6 +928,14 @@ + + + + + + + + @@ -1189,6 +1206,7 @@ + @@ -1220,6 +1238,7 @@ + @@ -1336,7 +1355,6 @@ - @@ -1429,6 +1447,7 @@ + @@ -1453,6 +1472,7 @@ + @@ -1588,6 +1608,8 @@ + + @@ -1603,6 +1625,7 @@ + @@ -1884,7 +1907,6 @@ - @@ -1977,6 +1999,7 @@ + @@ -2001,6 +2024,7 @@ + @@ -2065,7 +2089,6 @@ - @@ -2158,6 +2181,7 @@ + @@ -2182,6 +2206,7 @@ + diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC.xslt b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC.xslt similarity index 97% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC.xslt rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC.xslt index 0d4386e3..e7f52bfa 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_BASIC.xslt +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC.xslt @@ -153,7 +153,7 @@ - +     @@ -2019,11 +2019,18 @@ + + + + + + + -Schema for Factur-X; 1.0.07; EN16931-COMPLIANT-BASIC +Schema for Factur-X; 1.07.2; EN16931-COMPLIANT-BASIC @@ -2755,9 +2762,9 @@ - + - + FX-SCH-A-000211 @@ -3460,9 +3467,9 @@ - + - + FX-SCH-A-000092 @@ -3847,9 +3854,9 @@ - + - + FX-SCH-A-000110 @@ -4398,23 +4405,8 @@ - - - - - - - - - FX-SCH-A-000133 - - - - - [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. - - - + + @@ -4441,7 +4433,35 @@ - + + + + + + + + + FX-SCH-A-000133 + + + + + [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. + + + + + + + + + + + + + + + @@ -4458,18 +4478,18 @@ - + - - - + + + - + @@ -4516,18 +4536,18 @@ - + - - - + + + - + @@ -4574,18 +4594,18 @@ - + - - - + + + - + @@ -4632,18 +4652,18 @@ - + - - - + + + - + @@ -4720,18 +4740,18 @@ - + - - - + + + - + @@ -4778,18 +4798,18 @@ - + - - - + + + - + @@ -4836,18 +4856,18 @@ - + - - - + + + - + @@ -4954,18 +4974,18 @@ - + - - - + + + - + @@ -4997,18 +5017,18 @@ - + - - - + + + - + @@ -5040,18 +5060,18 @@ - + - - - + + + - + @@ -5083,18 +5103,18 @@ - + - - - + + + - + @@ -5126,18 +5146,18 @@ - + - - - + + + - + @@ -5169,18 +5189,18 @@ - + - - - + + + - + @@ -5200,9 +5220,9 @@ - + - + FX-SCH-A-000246 @@ -5212,18 +5232,18 @@ - + - - - + + + - + @@ -5255,18 +5275,18 @@ - + - - - + + + - + @@ -5298,18 +5318,18 @@ - + - - - + + + - + @@ -5341,18 +5361,18 @@ - + - - - + + + - + @@ -5744,18 +5764,18 @@ - + - - - + + + - + @@ -5787,18 +5807,18 @@ - + - - - + + + - + @@ -5811,18 +5831,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -5854,18 +5874,18 @@ - + - - - + + + - + @@ -5883,18 +5903,18 @@ - + - - - + + + - + @@ -5911,18 +5931,18 @@ - + - - - + + + - + @@ -5940,18 +5960,18 @@ - + - - - + + + - + @@ -5969,18 +5989,18 @@ - + - - - + + + - + @@ -6012,18 +6032,18 @@ - + - - - + + + - + @@ -6040,18 +6060,18 @@ - + - - - + + + - + @@ -6064,18 +6084,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -6092,18 +6112,18 @@ - + - - - + + + - + @@ -6121,18 +6141,18 @@ - + - - - + + + - + @@ -6145,18 +6165,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -6173,18 +6193,18 @@ - + - - - + + + - + @@ -6216,18 +6236,18 @@ - + - - - + + + - + @@ -6244,30 +6264,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. - - @@ -6279,8 +6275,8 @@ - - + + @@ -6289,7 +6285,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -6303,7 +6299,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -6395,18 +6415,18 @@ - + - - - + + + - + @@ -6423,18 +6443,18 @@ - + - - - + + + - + @@ -6452,18 +6472,18 @@ - + - - - + + + - + @@ -6476,18 +6496,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -6519,18 +6539,18 @@ - + - - - + + + - + @@ -6548,18 +6568,18 @@ - + - - - + + + - + @@ -6577,18 +6597,18 @@ - + - - - + + + - + @@ -6601,18 +6621,18 @@ Element 'ram:TradingBusinessName' is marked as not used in the given context. - + - - - + + + - + @@ -6629,18 +6649,18 @@ - + - - - + + + - + @@ -6657,18 +6677,18 @@ - + - - - + + + - + @@ -6686,18 +6706,18 @@ - + - - - + + + - + @@ -6714,18 +6734,18 @@ - + - - - + + + - + @@ -6742,18 +6762,18 @@ - + - - - + + + - + @@ -6771,18 +6791,18 @@ - + - - - + + + - + @@ -6799,30 +6819,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. - - @@ -6834,8 +6830,8 @@ - - + + @@ -6844,7 +6840,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -6858,7 +6854,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -6905,30 +6925,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:GlobalID' is marked as not used in the given context. - - @@ -6940,8 +6936,8 @@ - - + + @@ -6950,7 +6946,7 @@ - Element 'ram:ID' is marked as not used in the given context. + Element 'ram:GlobalID' is marked as not used in the given context. @@ -6964,7 +6960,31 @@ - + + + + + + + + + + + Element 'ram:ID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -6996,18 +7016,18 @@ - + - - - + + + - + @@ -7025,18 +7045,18 @@ - + - - - + + + - + @@ -7049,18 +7069,18 @@ Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. - + - - - + + + - + @@ -7077,18 +7097,18 @@ - + - - - + + + - + @@ -7105,18 +7125,18 @@ - + - - - + + + - + @@ -7134,18 +7154,18 @@ - + - - - + + + - + @@ -7158,18 +7178,18 @@ Element 'ram:URIUniversalCommunication' is marked as not used in the given context. - + - - - + + + - + @@ -7246,18 +7266,18 @@ - + - - - + + + - + @@ -7274,18 +7294,18 @@ - + - - - + + + - + @@ -7303,18 +7323,18 @@ - + - - - + + + - + @@ -7327,18 +7347,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -7370,18 +7390,18 @@ - + - - - + + + - + @@ -7399,18 +7419,18 @@ - + - - - + + + - + @@ -7428,18 +7448,18 @@ - + - - - + + + - + @@ -7452,18 +7472,18 @@ Element variant 'ram:SpecifiedTaxRegistration[ not(ram:ID/@schemeID="VA") and not(ram:ID/@schemeID="FC")]' is marked as not used in the given context. - + - - - + + + - + @@ -7480,18 +7500,18 @@ - + - - - + + + - + @@ -7508,18 +7528,18 @@ - + - - - + + + - + @@ -7536,18 +7556,18 @@ - + - - - + + + - + @@ -7564,18 +7584,18 @@ - + - - - + + + - + @@ -7592,18 +7612,18 @@ - + - - - + + + - + @@ -7620,18 +7640,18 @@ - + - - - + + + - + @@ -7649,18 +7669,18 @@ - + - - - + + + - + @@ -7677,18 +7697,18 @@ - + - - - + + + - + @@ -7705,18 +7725,18 @@ - + - - - + + + - + @@ -7733,18 +7753,18 @@ - + - - - + + + - + @@ -7762,18 +7782,18 @@ - + - - - + + + - + @@ -7790,30 +7810,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. - - @@ -7825,8 +7821,8 @@ - - + + @@ -7835,7 +7831,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -7849,7 +7845,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -7881,18 +7901,18 @@ - + - - - + + + - + @@ -7909,18 +7929,18 @@ - + - - - + + + - + @@ -7938,18 +7958,18 @@ - + - - - + + + - + @@ -7962,18 +7982,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -8005,18 +8025,18 @@ - + - - - + + + - + @@ -8034,30 +8054,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. - - @@ -8069,8 +8065,8 @@ - - + + @@ -8079,7 +8075,7 @@ - Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. + Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. @@ -8093,8 +8089,8 @@ - - + + @@ -8103,7 +8099,7 @@ - Element 'ram:URIUniversalCommunication' is marked as not used in the given context. + Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. @@ -8117,7 +8113,31 @@ - + + + + + + + + + + + Element 'ram:URIUniversalCommunication' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -8209,18 +8229,18 @@ - + - - - + + + - + @@ -8282,30 +8302,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -8317,8 +8313,8 @@ - - + + @@ -8341,7 +8337,31 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -8359,18 +8379,18 @@ - + - - - + + + - + @@ -8388,18 +8408,18 @@ - + - - - + + + - + @@ -8417,18 +8437,18 @@ - + - - - + + + - + @@ -8446,18 +8466,18 @@ - + - - - + + + - + @@ -8474,18 +8494,18 @@ - + - - - + + + - + @@ -8503,18 +8523,18 @@ - + - - - + + + - + @@ -8531,18 +8551,18 @@ - + - - - + + + - + @@ -8560,18 +8580,18 @@ - + - - - + + + - + @@ -8584,18 +8604,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -8613,18 +8633,18 @@ - + - - - + + + - + @@ -8656,18 +8676,18 @@ - + - - - + + + - + @@ -8684,18 +8704,18 @@ - + - - - + + + - + @@ -8713,18 +8733,18 @@ - + - - - + + + - + @@ -8737,18 +8757,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -8795,18 +8815,18 @@ - + - - - + + + - + @@ -8823,18 +8843,18 @@ - + - - - + + + - + @@ -8852,30 +8872,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -8887,8 +8883,8 @@ - - + + @@ -8897,7 +8893,7 @@ - Element 'ram:PostalTradeAddress' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -8911,7 +8907,31 @@ - + + + + + + + + + + + Element 'ram:PostalTradeAddress' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -8929,30 +8949,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:TradingBusinessName' is marked as not used in the given context. - - @@ -8964,8 +8960,8 @@ - - + + @@ -8974,7 +8970,7 @@ - Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. + Element 'ram:TradingBusinessName' is marked as not used in the given context. @@ -8988,8 +8984,8 @@ - - + + @@ -8998,7 +8994,7 @@ - Element 'ram:URIUniversalCommunication' is marked as not used in the given context. + Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. @@ -9012,8 +9008,8 @@ - - + + @@ -9022,7 +9018,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:URIUniversalCommunication' is marked as not used in the given context. @@ -9036,8 +9032,8 @@ - - + + @@ -9046,7 +9042,7 @@ - Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -9060,7 +9056,31 @@ - + + + + + + + + + + + Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -9107,30 +9127,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -9142,8 +9138,8 @@ - - + + @@ -9166,7 +9162,31 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -9198,30 +9218,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisAmount' is marked as not used in the given context. - - @@ -9233,8 +9229,8 @@ - - + + @@ -9243,7 +9239,7 @@ - Element 'ram:CalculatedAmount' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -9257,7 +9253,31 @@ - + + + + + + + + + + + Element 'ram:CalculatedAmount' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -9275,30 +9295,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - @@ -9310,8 +9306,8 @@ - - + + @@ -9320,7 +9316,7 @@ - Element 'ram:ExemptionReason' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -9334,8 +9330,8 @@ - - + + @@ -9344,7 +9340,7 @@ - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -9358,7 +9354,31 @@ - + + + + + + + + + + + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -9376,18 +9396,18 @@ - + - - - + + + - + @@ -9405,18 +9425,18 @@ - + - - - + + + - + @@ -9463,30 +9483,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -9498,8 +9494,8 @@ - - + + @@ -9522,7 +9518,31 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -9554,30 +9574,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisAmount' is marked as not used in the given context. - - @@ -9589,8 +9585,8 @@ - - + + @@ -9599,7 +9595,7 @@ - Element 'ram:CalculatedAmount' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -9613,7 +9609,31 @@ - + + + + + + + + + + + Element 'ram:CalculatedAmount' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -9631,30 +9651,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - @@ -9666,8 +9662,8 @@ - - + + @@ -9676,7 +9672,7 @@ - Element 'ram:ExemptionReason' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -9690,8 +9686,8 @@ - - + + @@ -9700,7 +9696,7 @@ - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -9714,7 +9710,31 @@ - + + + + + + + + + + + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -9732,18 +9752,18 @@ - + - - - + + + - + @@ -9761,18 +9781,18 @@ - + - - - + + + - + @@ -9804,18 +9824,18 @@ - + - - - + + + - + @@ -9828,18 +9848,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -9856,18 +9876,18 @@ - + - - - + + + - + @@ -9885,18 +9905,18 @@ - + - - - + + + - + @@ -10033,30 +10053,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -10068,8 +10064,8 @@ - - + + @@ -10092,8 +10088,8 @@ - - + + @@ -10116,8 +10112,8 @@ - - + + @@ -10140,8 +10136,8 @@ - - + + @@ -10164,8 +10160,8 @@ - - + + @@ -10188,8 +10184,8 @@ - - + + @@ -10198,7 +10194,7 @@ - Element variant 'ram:TaxTotalAmount[ not(@currencyID=../../ram:InvoiceCurrencyCode) and not(@currencyID=../../ram:TaxCurrencyCode)]' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -10212,7 +10208,31 @@ - + + + + + + + + + + + Element variant 'ram:TaxTotalAmount[ not(@currencyID=../../ram:InvoiceCurrencyCode) and not(@currencyID=../../ram:TaxCurrencyCode)]' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -10230,18 +10250,18 @@ - + - - - + + + - + @@ -10258,18 +10278,18 @@ - + - - - + + + - + @@ -10287,18 +10307,18 @@ - + - - - + + + - + @@ -10315,18 +10335,18 @@ - + - - - + + + - + @@ -10339,18 +10359,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -10382,30 +10402,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -10417,8 +10413,8 @@ - - + + @@ -10441,7 +10437,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -10458,18 +10478,18 @@ - + - - - + + + - + @@ -10482,18 +10502,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -10511,18 +10531,18 @@ - + - - - + + + - + @@ -10540,18 +10560,18 @@ - + - - - + + + - + @@ -10613,18 +10633,18 @@ - + - - - + + + - + @@ -10656,18 +10676,18 @@ - + - - - + + + - + @@ -10684,30 +10704,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:SubjectCode' is marked as not used in the given context. - - @@ -10719,8 +10715,8 @@ - - + + @@ -10729,7 +10725,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:SubjectCode' is marked as not used in the given context. @@ -10743,7 +10739,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -10760,18 +10780,18 @@ - + - - - + + + - + @@ -10803,18 +10823,18 @@ - + - - - + + + - + @@ -10827,18 +10847,18 @@ Element variant 'ram:AppliedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. - + - - - + + + - + @@ -10870,30 +10890,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -10905,8 +10901,8 @@ - - + + @@ -10915,7 +10911,7 @@ - Element 'ram:BasisAmount' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -10929,8 +10925,8 @@ - - + + @@ -10939,7 +10935,7 @@ - Element 'ram:CalculationPercent' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -10953,8 +10949,8 @@ - - + + @@ -10963,7 +10959,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Element 'ram:CalculationPercent' is marked as not used in the given context. @@ -10977,8 +10973,8 @@ - - + + @@ -10987,7 +10983,7 @@ - Element 'ram:Reason' is marked as not used in the given context. + Element 'ram:CategoryTradeTax' is marked as not used in the given context. @@ -11001,8 +10997,8 @@ - - + + @@ -11011,7 +11007,7 @@ - Element 'ram:ReasonCode' is marked as not used in the given context. + Element 'ram:Reason' is marked as not used in the given context. @@ -11025,7 +11021,31 @@ - + + + + + + + + + + + Element 'ram:ReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -11043,18 +11063,18 @@ - + - - - + + + - + @@ -11067,18 +11087,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -11095,18 +11115,18 @@ - + - - - + + + - + @@ -11119,18 +11139,18 @@ Element 'ram:AppliedTradeAllowanceCharge' is marked as not used in the given context. - + - - - + + + - + @@ -11148,18 +11168,18 @@ - + - - - + + + - + @@ -11172,18 +11192,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -11200,18 +11220,18 @@ - + - - - + + + - + @@ -11228,18 +11248,18 @@ - + - - - + + + - + @@ -11257,18 +11277,18 @@ - + - - - + + + - + @@ -11300,18 +11320,18 @@ - + - - - + + + - + @@ -11343,30 +11363,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisAmount' is marked as not used in the given context. - - @@ -11378,8 +11374,8 @@ - - + + @@ -11388,7 +11384,7 @@ - Element 'ram:CalculatedAmount' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -11402,7 +11398,31 @@ - + + + + + + + + + + + Element 'ram:CalculatedAmount' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -11420,30 +11440,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - @@ -11455,8 +11451,8 @@ - - + + @@ -11465,7 +11461,7 @@ - Element 'ram:ExemptionReason' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -11479,8 +11475,8 @@ - - + + @@ -11489,7 +11485,7 @@ - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -11503,7 +11499,31 @@ - + + + + + + + + + + + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -11521,18 +11541,18 @@ - + - - - + + + - + @@ -11549,18 +11569,18 @@ - + - - - + + + - + @@ -11578,18 +11598,18 @@ - + - - - + + + - + @@ -11606,18 +11626,18 @@ - + - - - + + + - + @@ -11635,18 +11655,18 @@ - + - - - + + + - + @@ -11659,18 +11679,18 @@ Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. - + - - - + + + - + @@ -11702,30 +11722,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -11737,8 +11733,8 @@ - - + + @@ -11747,7 +11743,7 @@ - Element 'ram:BasisAmount' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -11761,8 +11757,8 @@ - - + + @@ -11771,7 +11767,7 @@ - Element 'ram:CalculationPercent' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -11785,8 +11781,8 @@ - - + + @@ -11795,7 +11791,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Element 'ram:CalculationPercent' is marked as not used in the given context. @@ -11809,7 +11805,31 @@ - + + + + + + + + + + + Element 'ram:CategoryTradeTax' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -11827,18 +11847,18 @@ - + - - - + + + - + @@ -11870,30 +11890,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -11905,8 +11901,8 @@ - - + + @@ -11915,7 +11911,7 @@ - Element 'ram:BasisAmount' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -11929,8 +11925,8 @@ - - + + @@ -11939,7 +11935,7 @@ - Element 'ram:CalculationPercent' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -11953,8 +11949,8 @@ - - + + @@ -11963,7 +11959,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Element 'ram:CalculationPercent' is marked as not used in the given context. @@ -11977,7 +11973,31 @@ - + + + + + + + + + + + Element 'ram:CategoryTradeTax' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -11995,18 +12015,18 @@ - + - - - + + + - + @@ -12023,18 +12043,18 @@ - + - - - + + + - + @@ -12047,18 +12067,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -12075,18 +12095,18 @@ - + - - - + + + - + @@ -12103,18 +12123,18 @@ - + - - - + + + - + @@ -12132,10 +12152,10 @@ - + - - - + + + diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC_codedb.xml b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC_codedb.xml similarity index 99% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC_codedb.xml rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC_codedb.xml index ce1fdffe..d8154cdc 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_BASIC_codedb.xml +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_BASIC_codedb.xml @@ -2,6 +2,7 @@ + @@ -692,6 +693,14 @@ + + + + + + + + @@ -3298,6 +3307,14 @@ + + + + + + + + @@ -3525,6 +3542,14 @@ + + + + + + + + @@ -3795,6 +3820,7 @@ + @@ -3826,6 +3852,7 @@ + @@ -3942,7 +3969,6 @@ - @@ -4035,6 +4061,7 @@ + @@ -4059,6 +4086,7 @@ + @@ -4180,6 +4208,8 @@ + + @@ -4195,6 +4225,7 @@ + @@ -4476,7 +4507,6 @@ - @@ -4569,6 +4599,7 @@ + @@ -4593,6 +4624,7 @@ + @@ -4657,7 +4689,6 @@ - @@ -4750,6 +4781,7 @@ + @@ -4774,6 +4806,7 @@ + diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_EN16931.xslt b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_EN16931.xslt similarity index 97% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_EN16931.xslt rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_EN16931.xslt index b03d1084..5709d20e 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_EN16931.xslt +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_EN16931.xslt @@ -153,7 +153,7 @@ - +     @@ -2971,11 +2971,18 @@ + + + + + + + -Schema for Factur-X; 1.0.07; EN16931-COMPLIANT (FULLY) +Schema for Factur-X; 1.07.2; EN16931-COMPLIANT (FULLY) @@ -3763,9 +3770,9 @@ - + - + FX-SCH-A-000211 @@ -4468,9 +4475,9 @@ - + - + FX-SCH-A-000092 @@ -4855,9 +4862,9 @@ - + - + FX-SCH-A-000110 @@ -5406,23 +5413,8 @@ - - - - - - - - - FX-SCH-A-000133 - - - - - [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. - - - + + @@ -5449,7 +5441,35 @@ - + + + + + + + + + FX-SCH-A-000133 + + + + + [BR-50]-A Payment account identifier (BT-84) shall be present if Credit transfer (BG-16) information is provided in the Invoice. + + + + + + + + + + + + + + + @@ -5466,18 +5486,18 @@ - + - - - + + + - + @@ -5524,18 +5544,18 @@ - + - - - + + + - + @@ -5582,18 +5602,18 @@ - + - - - + + + - + @@ -5640,18 +5660,18 @@ - + - - - + + + - + @@ -5728,18 +5748,18 @@ - + - - - + + + - + @@ -5786,18 +5806,18 @@ - + - - - + + + - + @@ -5844,18 +5864,18 @@ - + - - - + + + - + @@ -5962,18 +5982,18 @@ - + - - - + + + - + @@ -6005,18 +6025,18 @@ - + - - - + + + - + @@ -6048,18 +6068,18 @@ - + - - - + + + - + @@ -6091,18 +6111,18 @@ - + - - - + + + - + @@ -6134,18 +6154,18 @@ - + - - - + + + - + @@ -6177,18 +6197,18 @@ - + - - - + + + - + @@ -6208,9 +6228,9 @@ - + - + FX-SCH-A-000246 @@ -6220,18 +6240,18 @@ - + - - - + + + - + @@ -6263,18 +6283,18 @@ - + - - - + + + - + @@ -6306,18 +6326,18 @@ - + - - - + + + - + @@ -6349,18 +6369,18 @@ - + - - - + + + - + @@ -6752,18 +6772,18 @@ - + - - - + + + - + @@ -6795,18 +6815,18 @@ - + - - - + + + - + @@ -6819,18 +6839,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -6862,18 +6882,18 @@ - + - - - + + + - + @@ -6891,30 +6911,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - @@ -6926,8 +6922,8 @@ - - + + @@ -6936,7 +6932,7 @@ - Attribute @listVersionID' marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -6950,7 +6946,31 @@ - + + + + + + + + + + + Attribute @listVersionID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -6967,18 +6987,18 @@ - + - - - + + + - + @@ -6996,18 +7016,18 @@ - + - - - + + + - + @@ -7025,18 +7045,18 @@ - + - - - + + + - + @@ -7068,18 +7088,18 @@ - + - - - + + + - + @@ -7096,18 +7116,18 @@ - + - - - + + + - + @@ -7120,18 +7140,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -7148,18 +7168,18 @@ - + - - - + + + - + @@ -7177,18 +7197,18 @@ - + - - - + + + - + @@ -7201,18 +7221,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -7229,18 +7249,18 @@ - + - - - + + + - + @@ -7272,18 +7292,18 @@ - + - - - + + + - + @@ -7296,18 +7316,18 @@ Element variant 'ram:AdditionalReferencedDocument[ not(ram:TypeCode="916") and not(ram:TypeCode="50") and not(ram:TypeCode="130")]' is marked as not used in the given context. - + - - - + + + - + @@ -7339,30 +7359,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -7374,8 +7370,8 @@ - - + + @@ -7384,7 +7380,7 @@ - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -7398,8 +7394,8 @@ - - + + @@ -7408,7 +7404,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -7422,8 +7418,8 @@ - - + + @@ -7432,7 +7428,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -7446,8 +7442,8 @@ - - + + @@ -7456,7 +7452,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -7470,7 +7466,31 @@ - + + + + + + + + + + + Element 'ram:Name' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -7488,18 +7508,18 @@ - + - - - + + + - + @@ -7517,18 +7537,18 @@ - + - - - + + + - + @@ -7541,18 +7561,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -7584,30 +7604,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -7619,8 +7615,8 @@ - - + + @@ -7629,7 +7625,7 @@ - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -7643,8 +7639,8 @@ - - + + @@ -7653,7 +7649,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -7667,8 +7663,8 @@ - - + + @@ -7677,7 +7673,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -7691,8 +7687,8 @@ - - + + @@ -7701,7 +7697,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -7715,8 +7711,8 @@ - - + + @@ -7725,7 +7721,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -7739,7 +7735,31 @@ - + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -7757,18 +7777,18 @@ - + - - - + + + - + @@ -7781,18 +7801,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -7854,18 +7874,18 @@ - + - - - + + + - + @@ -7897,18 +7917,18 @@ - + - - - + + + - + @@ -7926,30 +7946,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. - - @@ -7961,8 +7957,8 @@ - - + + @@ -7971,7 +7967,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -7985,8 +7981,8 @@ - - + + @@ -7995,7 +7991,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -8009,8 +8005,8 @@ - - + + @@ -8019,7 +8015,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -8033,7 +8029,31 @@ - + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -8051,18 +8071,18 @@ - + - - - + + + - + @@ -8075,18 +8095,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -8103,30 +8123,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -8138,8 +8134,8 @@ - - + + @@ -8148,7 +8144,7 @@ - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -8162,8 +8158,8 @@ - - + + @@ -8172,7 +8168,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -8186,8 +8182,8 @@ - - + + @@ -8196,7 +8192,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -8210,8 +8206,8 @@ - - + + @@ -8220,7 +8216,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -8234,8 +8230,8 @@ - - + + @@ -8244,7 +8240,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -8258,8 +8254,8 @@ - - + + @@ -8268,7 +8264,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -8282,8 +8278,8 @@ - - + + @@ -8292,7 +8288,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:TypeCode' is marked as not used in the given context. @@ -8306,7 +8302,31 @@ - + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -8413,18 +8433,18 @@ - + - - - + + + - + @@ -8441,30 +8461,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -8476,8 +8472,8 @@ - - + + @@ -8486,7 +8482,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:CompleteNumber' is marked as not used in the given context. @@ -8500,7 +8496,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -8517,30 +8537,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:URIID' is marked as not used in the given context. - - @@ -8552,8 +8548,8 @@ - - + + @@ -8562,7 +8558,7 @@ - Element 'ram:Description' is marked as not used in the given context. + Element 'ram:URIID' is marked as not used in the given context. @@ -8576,7 +8572,31 @@ - + + + + + + + + + + + Element 'ram:Description' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -8593,18 +8613,18 @@ - + - - - + + + - + @@ -8622,18 +8642,18 @@ - + - - - + + + - + @@ -8646,18 +8666,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -8689,18 +8709,18 @@ - + - - - + + + - + @@ -8718,30 +8738,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - @@ -8753,8 +8749,8 @@ - - + + @@ -8763,7 +8759,7 @@ - Attribute @listVersionID' marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -8777,7 +8773,31 @@ - + + + + + + + + + + + Attribute @listVersionID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -8795,18 +8815,18 @@ - + - - - + + + - + @@ -8823,18 +8843,18 @@ - + - - - + + + - + @@ -8851,18 +8871,18 @@ - + - - - + + + - + @@ -8880,18 +8900,18 @@ - + - - - + + + - + @@ -8908,18 +8928,18 @@ - + - - - + + + - + @@ -8932,18 +8952,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -8960,18 +8980,18 @@ - + - - - + + + - + @@ -8989,18 +9009,18 @@ - + - - - + + + - + @@ -9017,30 +9037,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -9052,8 +9048,8 @@ - - + + @@ -9062,7 +9058,7 @@ - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -9076,8 +9072,8 @@ - - + + @@ -9086,7 +9082,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -9100,8 +9096,8 @@ - - + + @@ -9110,7 +9106,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -9124,8 +9120,8 @@ - - + + @@ -9134,7 +9130,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -9148,8 +9144,8 @@ - - + + @@ -9158,7 +9154,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -9172,8 +9168,8 @@ - - + + @@ -9182,7 +9178,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -9196,8 +9192,8 @@ - - + + @@ -9206,7 +9202,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:TypeCode' is marked as not used in the given context. @@ -9220,7 +9216,31 @@ - + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -9237,30 +9257,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -9272,8 +9268,8 @@ - - + + @@ -9282,7 +9278,7 @@ - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -9296,8 +9292,8 @@ - - + + @@ -9306,7 +9302,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -9320,8 +9316,8 @@ - - + + @@ -9330,7 +9326,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -9344,8 +9340,8 @@ - - + + @@ -9354,7 +9350,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -9368,8 +9364,8 @@ - - + + @@ -9378,7 +9374,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -9392,8 +9388,8 @@ - - + + @@ -9402,7 +9398,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -9416,8 +9412,8 @@ - - + + @@ -9426,7 +9422,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:TypeCode' is marked as not used in the given context. @@ -9440,7 +9436,31 @@ - + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -9487,30 +9507,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DefinedTradeContact' is marked as not used in the given context. - - @@ -9522,8 +9518,8 @@ - - + + @@ -9532,7 +9528,7 @@ - Element 'ram:Description' is marked as not used in the given context. + Element 'ram:DefinedTradeContact' is marked as not used in the given context. @@ -9546,8 +9542,8 @@ - - + + @@ -9556,7 +9552,7 @@ - Element 'ram:GlobalID' is marked as not used in the given context. + Element 'ram:Description' is marked as not used in the given context. @@ -9570,8 +9566,8 @@ - - + + @@ -9580,7 +9576,7 @@ - Element 'ram:ID' is marked as not used in the given context. + Element 'ram:GlobalID' is marked as not used in the given context. @@ -9594,7 +9590,31 @@ - + + + + + + + + + + + Element 'ram:ID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -9626,18 +9646,18 @@ - + - - - + + + - + @@ -9655,30 +9675,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - @@ -9690,8 +9686,8 @@ - - + + @@ -9700,7 +9696,7 @@ - Attribute @listVersionID' marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -9714,8 +9710,8 @@ - - + + @@ -9724,7 +9720,7 @@ - Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. + Attribute @listVersionID' marked as not used in the given context. @@ -9738,7 +9734,31 @@ - + + + + + + + + + + + Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -9755,18 +9775,18 @@ - + - - - + + + - + @@ -9783,18 +9803,18 @@ - + - - - + + + - + @@ -9812,18 +9832,18 @@ - + - - - + + + - + @@ -9836,18 +9856,18 @@ Element 'ram:URIUniversalCommunication' is marked as not used in the given context. - + - - - + + + - + @@ -9954,18 +9974,18 @@ - + - - - + + + - + @@ -9982,30 +10002,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -10017,8 +10013,8 @@ - - + + @@ -10027,7 +10023,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:CompleteNumber' is marked as not used in the given context. @@ -10041,7 +10037,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -10058,18 +10078,18 @@ - + - - - + + + - + @@ -10082,18 +10102,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -10110,18 +10130,18 @@ - + - - - + + + - + @@ -10139,18 +10159,18 @@ - + - - - + + + - + @@ -10163,18 +10183,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -10206,18 +10226,18 @@ - + - - - + + + - + @@ -10235,30 +10255,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - @@ -10270,8 +10266,8 @@ - - + + @@ -10280,7 +10276,7 @@ - Attribute @listVersionID' marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -10294,7 +10290,31 @@ - + + + + + + + + + + + Attribute @listVersionID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -10312,18 +10332,18 @@ - + - - - + + + - + @@ -10336,18 +10356,18 @@ Element variant 'ram:SpecifiedTaxRegistration[ not(ram:ID/@schemeID="VA") and not(ram:ID/@schemeID="FC")]' is marked as not used in the given context. - + - - - + + + - + @@ -10364,18 +10384,18 @@ - + - - - + + + - + @@ -10392,18 +10412,18 @@ - + - - - + + + - + @@ -10420,18 +10440,18 @@ - + - - - + + + - + @@ -10448,18 +10468,18 @@ - + - - - + + + - + @@ -10476,18 +10496,18 @@ - + - - - + + + - + @@ -10500,18 +10520,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -10528,18 +10548,18 @@ - + - - - + + + - + @@ -10557,18 +10577,18 @@ - + - - - + + + - + @@ -10581,18 +10601,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -10609,18 +10629,18 @@ - + - - - + + + - + @@ -10637,18 +10657,18 @@ - + - - - + + + - + @@ -10665,18 +10685,18 @@ - + - - - + + + - + @@ -10694,18 +10714,18 @@ - + - - - + + + - + @@ -10722,30 +10742,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -10757,8 +10753,8 @@ - - + + @@ -10767,7 +10763,7 @@ - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -10781,8 +10777,8 @@ - - + + @@ -10791,7 +10787,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -10805,8 +10801,8 @@ - - + + @@ -10815,7 +10811,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -10829,8 +10825,8 @@ - - + + @@ -10839,7 +10835,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -10853,8 +10849,8 @@ - - + + @@ -10863,7 +10859,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -10877,8 +10873,8 @@ - - + + @@ -10887,7 +10883,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -10901,8 +10897,8 @@ - - + + @@ -10911,7 +10907,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:TypeCode' is marked as not used in the given context. @@ -10925,7 +10921,31 @@ - + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -10942,30 +10962,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -10977,8 +10973,8 @@ - - + + @@ -10987,7 +10983,7 @@ - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -11001,8 +10997,8 @@ - - + + @@ -11011,7 +11007,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -11025,8 +11021,8 @@ - - + + @@ -11035,7 +11031,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -11049,8 +11045,8 @@ - - + + @@ -11059,7 +11055,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -11073,8 +11069,8 @@ - - + + @@ -11083,7 +11079,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -11097,8 +11093,8 @@ - - + + @@ -11107,7 +11103,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -11121,8 +11117,8 @@ - - + + @@ -11131,7 +11127,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:TypeCode' is marked as not used in the given context. @@ -11145,7 +11141,31 @@ - + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -11177,30 +11197,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DefinedTradeContact' is marked as not used in the given context. - - @@ -11212,8 +11208,8 @@ - - + + @@ -11222,7 +11218,7 @@ - Element 'ram:Description' is marked as not used in the given context. + Element 'ram:DefinedTradeContact' is marked as not used in the given context. @@ -11236,7 +11232,31 @@ - + + + + + + + + + + + Element 'ram:Description' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -11253,18 +11273,18 @@ - + - - - + + + - + @@ -11282,18 +11302,18 @@ - + - - - + + + - + @@ -11306,18 +11326,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -11349,18 +11369,18 @@ - + - - - + + + - + @@ -11378,30 +11398,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - @@ -11413,8 +11409,8 @@ - - + + @@ -11423,7 +11419,7 @@ - Attribute @listVersionID' marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -11437,8 +11433,8 @@ - - + + @@ -11447,7 +11443,7 @@ - Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. + Attribute @listVersionID' marked as not used in the given context. @@ -11461,8 +11457,8 @@ - - + + @@ -11471,7 +11467,7 @@ - Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. + Element 'ram:SpecifiedLegalOrganization' is marked as not used in the given context. @@ -11485,8 +11481,8 @@ - - + + @@ -11495,7 +11491,7 @@ - Element 'ram:URIUniversalCommunication' is marked as not used in the given context. + Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. @@ -11509,7 +11505,31 @@ - + + + + + + + + + + + Element 'ram:URIUniversalCommunication' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -11601,18 +11621,18 @@ - + - - - + + + - + @@ -11674,30 +11694,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -11709,8 +11705,8 @@ - - + + @@ -11733,7 +11729,31 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -11751,18 +11771,18 @@ - + - - - + + + - + @@ -11780,18 +11800,18 @@ - + - - - + + + - + @@ -11809,30 +11829,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - @@ -11844,8 +11840,8 @@ - - + + @@ -11854,7 +11850,7 @@ - Attribute @listVersionID' marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -11868,7 +11864,31 @@ - + + + + + + + + + + + Attribute @listVersionID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -11885,18 +11905,18 @@ - + - - - + + + - + @@ -11914,18 +11934,18 @@ - + - - - + + + - + @@ -11943,18 +11963,18 @@ - + - - - + + + - + @@ -11971,18 +11991,18 @@ - + - - - + + + - + @@ -12000,18 +12020,18 @@ - + - - - + + + - + @@ -12028,18 +12048,18 @@ - + - - - + + + - + @@ -12057,18 +12077,18 @@ - + - - - + + + - + @@ -12081,18 +12101,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -12110,18 +12130,18 @@ - + - - - + + + - + @@ -12153,18 +12173,18 @@ - + - - - + + + - + @@ -12177,18 +12197,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -12205,18 +12225,18 @@ - + - - - + + + - + @@ -12234,30 +12254,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -12269,8 +12265,8 @@ - - + + @@ -12279,7 +12275,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -12293,8 +12289,8 @@ - - + + @@ -12303,7 +12299,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -12317,8 +12313,8 @@ - - + + @@ -12327,7 +12323,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -12341,8 +12337,8 @@ - - + + @@ -12351,7 +12347,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -12365,8 +12361,8 @@ - - + + @@ -12375,7 +12371,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:TypeCode' is marked as not used in the given context. @@ -12389,7 +12385,31 @@ - + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -12436,30 +12456,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DefinedTradeContact' is marked as not used in the given context. - - @@ -12471,8 +12467,8 @@ - - + + @@ -12481,7 +12477,7 @@ - Element 'ram:Description' is marked as not used in the given context. + Element 'ram:DefinedTradeContact' is marked as not used in the given context. @@ -12495,7 +12491,31 @@ - + + + + + + + + + + + Element 'ram:Description' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -12512,18 +12532,18 @@ - + - - - + + + - + @@ -12541,30 +12561,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -12576,8 +12572,8 @@ - - + + @@ -12586,7 +12582,7 @@ - Element 'ram:PostalTradeAddress' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -12600,7 +12596,31 @@ - + + + + + + + + + + + Element 'ram:PostalTradeAddress' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -12618,30 +12638,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:TradingBusinessName' is marked as not used in the given context. - - @@ -12653,8 +12649,8 @@ - - + + @@ -12663,7 +12659,7 @@ - Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. + Element 'ram:TradingBusinessName' is marked as not used in the given context. @@ -12677,8 +12673,8 @@ - - + + @@ -12687,7 +12683,7 @@ - Element 'ram:URIUniversalCommunication' is marked as not used in the given context. + Element 'ram:SpecifiedTaxRegistration' is marked as not used in the given context. @@ -12701,8 +12697,8 @@ - - + + @@ -12711,7 +12707,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:URIUniversalCommunication' is marked as not used in the given context. @@ -12725,8 +12721,8 @@ - - + + @@ -12735,7 +12731,7 @@ - Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -12749,7 +12745,31 @@ - + + + + + + + + + + + Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -12796,30 +12816,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -12831,8 +12827,8 @@ - - + + @@ -12855,7 +12851,31 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -12887,30 +12907,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisAmount' is marked as not used in the given context. - - @@ -12922,8 +12918,8 @@ - - + + @@ -12932,7 +12928,7 @@ - Element 'ram:CalculatedAmount' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -12946,7 +12942,31 @@ - + + + + + + + + + + + Element 'ram:CalculatedAmount' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -12964,30 +12984,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - @@ -12999,8 +12995,8 @@ - - + + @@ -13009,7 +13005,7 @@ - Element 'ram:ExemptionReason' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -13023,8 +13019,8 @@ - - + + @@ -13033,7 +13029,7 @@ - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -13047,8 +13043,8 @@ - - + + @@ -13057,7 +13053,7 @@ - Element 'ram:TaxPointDate' is marked as not used in the given context. + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. @@ -13071,7 +13067,31 @@ - + + + + + + + + + + + Element 'ram:TaxPointDate' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -13089,18 +13109,18 @@ - + - - - + + + - + @@ -13118,18 +13138,18 @@ - + - - - + + + - + @@ -13176,30 +13196,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -13211,8 +13207,8 @@ - - + + @@ -13235,7 +13231,31 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -13267,30 +13287,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisAmount' is marked as not used in the given context. - - @@ -13302,8 +13298,8 @@ - - + + @@ -13312,7 +13308,7 @@ - Element 'ram:CalculatedAmount' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -13326,7 +13322,31 @@ - + + + + + + + + + + + Element 'ram:CalculatedAmount' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -13344,30 +13364,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - @@ -13379,8 +13375,8 @@ - - + + @@ -13389,7 +13385,7 @@ - Element 'ram:ExemptionReason' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -13403,8 +13399,8 @@ - - + + @@ -13413,7 +13409,7 @@ - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -13427,8 +13423,8 @@ - - + + @@ -13437,7 +13433,7 @@ - Element 'ram:TaxPointDate' is marked as not used in the given context. + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. @@ -13451,7 +13447,31 @@ - + + + + + + + + + + + Element 'ram:TaxPointDate' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -13469,18 +13489,18 @@ - + - - - + + + - + @@ -13498,18 +13518,18 @@ - + - - - + + + - + @@ -13541,18 +13561,18 @@ - + - - - + + + - + @@ -13565,18 +13585,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -13593,18 +13613,18 @@ - + - - - + + + - + @@ -13622,18 +13642,18 @@ - + - - - + + + - + @@ -13785,30 +13805,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -13820,8 +13816,8 @@ - - + + @@ -13844,8 +13840,8 @@ - - + + @@ -13868,8 +13864,8 @@ - - + + @@ -13892,8 +13888,8 @@ - - + + @@ -13916,8 +13912,8 @@ - - + + @@ -13940,8 +13936,8 @@ - - + + @@ -13964,8 +13960,8 @@ - - + + @@ -13974,7 +13970,7 @@ - Element variant 'ram:TaxTotalAmount[ not(@currencyID=../../ram:InvoiceCurrencyCode) and not(@currencyID=../../ram:TaxCurrencyCode)]' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -13988,7 +13984,31 @@ - + + + + + + + + + + + Element variant 'ram:TaxTotalAmount[ not(@currencyID=../../ram:InvoiceCurrencyCode) and not(@currencyID=../../ram:TaxCurrencyCode)]' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -14006,18 +14026,18 @@ - + - - - + + + - + @@ -14034,18 +14054,18 @@ - + - - - + + + - + @@ -14063,18 +14083,18 @@ - + - - - + + + - + @@ -14091,18 +14111,18 @@ - + - - - + + + - + @@ -14115,18 +14135,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -14173,18 +14193,18 @@ - + - - - + + + - + @@ -14201,30 +14221,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -14236,8 +14232,8 @@ - - + + @@ -14260,8 +14256,8 @@ - - + + @@ -14284,7 +14280,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -14301,18 +14321,18 @@ - + - - - + + + - + @@ -14325,18 +14345,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -14353,18 +14373,18 @@ - + - - - + + + - + @@ -14377,18 +14397,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -14406,18 +14426,18 @@ - + - - - + + + - + @@ -14435,18 +14455,18 @@ - + - - - + + + - + @@ -14508,18 +14528,18 @@ - + - - - + + + - + @@ -14551,18 +14571,18 @@ - + - - - + + + - + @@ -14579,30 +14599,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:SubjectCode' is marked as not used in the given context. - - @@ -14614,8 +14610,8 @@ - - + + @@ -14624,7 +14620,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:SubjectCode' is marked as not used in the given context. @@ -14638,7 +14634,31 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -14655,30 +14675,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -14690,8 +14686,8 @@ - - + + @@ -14700,7 +14696,7 @@ - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -14714,8 +14710,8 @@ - - + + @@ -14724,7 +14720,7 @@ - Element 'ram:IssuerAssignedID' is marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -14738,8 +14734,8 @@ - - + + @@ -14748,7 +14744,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:IssuerAssignedID' is marked as not used in the given context. @@ -14762,8 +14758,8 @@ - - + + @@ -14772,7 +14768,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -14786,8 +14782,8 @@ - - + + @@ -14796,7 +14792,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -14810,8 +14806,8 @@ - - + + @@ -14820,7 +14816,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -14834,8 +14830,8 @@ - - + + @@ -14844,7 +14840,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:TypeCode' is marked as not used in the given context. @@ -14858,7 +14854,31 @@ - + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -14890,18 +14910,18 @@ - + - - - + + + - + @@ -14914,18 +14934,18 @@ Element variant 'ram:AppliedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. - + - - - + + + - + @@ -14957,30 +14977,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -14992,8 +14988,8 @@ - - + + @@ -15002,7 +14998,7 @@ - Element 'ram:BasisAmount' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -15016,8 +15012,8 @@ - - + + @@ -15026,7 +15022,7 @@ - Element 'ram:CalculationPercent' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -15040,8 +15036,8 @@ - - + + @@ -15050,7 +15046,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Element 'ram:CalculationPercent' is marked as not used in the given context. @@ -15064,8 +15060,8 @@ - - + + @@ -15074,7 +15070,7 @@ - Element 'ram:Reason' is marked as not used in the given context. + Element 'ram:CategoryTradeTax' is marked as not used in the given context. @@ -15088,8 +15084,8 @@ - - + + @@ -15098,7 +15094,7 @@ - Element 'ram:ReasonCode' is marked as not used in the given context. + Element 'ram:Reason' is marked as not used in the given context. @@ -15112,7 +15108,31 @@ - + + + + + + + + + + + Element 'ram:ReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -15130,18 +15150,18 @@ - + - - - + + + - + @@ -15154,18 +15174,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -15182,18 +15202,18 @@ - + - - - + + + - + @@ -15206,18 +15226,18 @@ Element 'ram:AppliedTradeAllowanceCharge' is marked as not used in the given context. - + - - - + + + - + @@ -15235,18 +15255,18 @@ - + - - - + + + - + @@ -15259,18 +15279,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -15287,18 +15307,18 @@ - + - - - + + + - + @@ -15315,18 +15335,18 @@ - + - - - + + + - + @@ -15344,18 +15364,18 @@ - + - - - + + + - + @@ -15417,18 +15437,18 @@ - + - - - + + + - + @@ -15460,30 +15480,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -15495,8 +15491,8 @@ - - + + @@ -15505,7 +15501,7 @@ - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -15519,8 +15515,8 @@ - - + + @@ -15529,7 +15525,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -15543,8 +15539,8 @@ - - + + @@ -15553,7 +15549,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -15567,8 +15563,8 @@ - - + + @@ -15577,7 +15573,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -15591,7 +15587,31 @@ - + + + + + + + + + + + Element 'ram:Name' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -15609,18 +15629,18 @@ - + - - - + + + - + @@ -15638,18 +15658,18 @@ - + - - - + + + - + @@ -15662,18 +15682,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -15705,30 +15725,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisAmount' is marked as not used in the given context. - - @@ -15740,8 +15736,8 @@ - - + + @@ -15750,7 +15746,7 @@ - Element 'ram:CalculatedAmount' is marked as not used in the given context. + Element 'ram:BasisAmount' is marked as not used in the given context. @@ -15764,7 +15760,31 @@ - + + + + + + + + + + + Element 'ram:CalculatedAmount' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -15782,30 +15802,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - @@ -15817,8 +15813,8 @@ - - + + @@ -15827,7 +15823,7 @@ - Element 'ram:ExemptionReason' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -15841,8 +15837,8 @@ - - + + @@ -15851,7 +15847,7 @@ - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -15865,8 +15861,8 @@ - - + + @@ -15875,7 +15871,7 @@ - Element 'ram:TaxPointDate' is marked as not used in the given context. + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. @@ -15889,7 +15885,31 @@ - + + + + + + + + + + + Element 'ram:TaxPointDate' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -15907,18 +15927,18 @@ - + - - - + + + - + @@ -15935,18 +15955,18 @@ - + - - - + + + - + @@ -15964,18 +15984,18 @@ - + - - - + + + - + @@ -15992,18 +16012,18 @@ - + - - - + + + - + @@ -16021,30 +16041,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -16056,8 +16052,8 @@ - - + + @@ -16066,7 +16062,7 @@ - Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -16080,7 +16076,31 @@ - + + + + + + + + + + + Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -16112,30 +16132,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -16147,8 +16143,8 @@ - - + + @@ -16171,8 +16167,8 @@ - - + + @@ -16181,7 +16177,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -16195,7 +16191,31 @@ - + + + + + + + + + + + Element 'ram:CategoryTradeTax' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -16213,18 +16233,18 @@ - + - - - + + + - + @@ -16256,30 +16276,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -16291,8 +16287,8 @@ - - + + @@ -16315,8 +16311,8 @@ - - + + @@ -16325,7 +16321,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -16339,7 +16335,31 @@ - + + + + + + + + + + + Element 'ram:CategoryTradeTax' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -16357,18 +16377,18 @@ - + - - - + + + - + @@ -16385,18 +16405,18 @@ - + - - - + + + - + @@ -16409,18 +16429,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -16452,18 +16472,18 @@ - + - - - + + + - + @@ -16495,18 +16515,18 @@ - + - - - + + + - + @@ -16519,18 +16539,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -16547,18 +16567,18 @@ - + - - - + + + - + @@ -16576,18 +16596,18 @@ - + - - - + + + - + @@ -16604,18 +16624,18 @@ - + - - - + + + - + @@ -16633,18 +16653,18 @@ - + - - - + + + - + @@ -16661,18 +16681,18 @@ - + - - - + + + - + @@ -16690,18 +16710,18 @@ - + - - - + + + - + @@ -16714,10 +16734,10 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_EN16931_codedb.xml b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_EN16931_codedb.xml similarity index 99% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_EN16931_codedb.xml rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_EN16931_codedb.xml index d0ad2b33..ae1b08a2 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_EN16931_codedb.xml +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_EN16931_codedb.xml @@ -692,6 +692,14 @@ + + + + + + + + @@ -4561,6 +4569,14 @@ + + + + + + + + @@ -4788,6 +4804,14 @@ + + + + + + + + @@ -4805,6 +4829,7 @@ + @@ -4836,6 +4861,7 @@ + @@ -4969,7 +4995,6 @@ - @@ -5062,6 +5087,7 @@ + @@ -5086,6 +5112,7 @@ + @@ -5207,6 +5234,8 @@ + + @@ -5222,6 +5251,7 @@ + @@ -5506,7 +5536,6 @@ - @@ -5599,6 +5628,7 @@ + @@ -5623,6 +5653,7 @@ + @@ -5687,7 +5718,6 @@ - @@ -5780,6 +5810,7 @@ + @@ -5804,6 +5835,7 @@ + diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_EXTENDED.xslt b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_EXTENDED.xslt similarity index 96% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_EXTENDED.xslt rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_EXTENDED.xslt index b317bcb5..c3b9ce37 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_EXTENDED.xslt +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_EXTENDED.xslt @@ -153,7 +153,7 @@ - +     @@ -7472,11 +7472,32 @@ + + + + + + + + + + + + + + + + + + + + + -Schema for Factur-X; 1.0.07; EN16931-CONFORMANT-EXTENDED +Schema for Factur-X; 1.07.2; EN16931-CONFORMANT-EXTENDED @@ -8064,7 +8085,36 @@ - + + + + + + + + + FX-SCH-A-000345 + warning + + + + + [BR-FXEXT-04]-To ensure automated processing of the article attributes without bilateral reconciliation, only values from the code list UNTDED 6313+Factur-X-Extension should be used. + + + + + + + + + + + + + + + @@ -8081,18 +8131,18 @@ - + - - - + + + - + @@ -8109,18 +8159,18 @@ - + - - - + + + - + @@ -8290,9 +8340,9 @@ - + - + FX-SCH-A-000211 @@ -8302,18 +8352,18 @@ - + - - - + + + - + @@ -8330,18 +8380,18 @@ - + - - - + + + - + @@ -8403,18 +8453,18 @@ - + - - - + + + - + @@ -8431,18 +8481,18 @@ - + - - - + + + - + @@ -8474,18 +8524,18 @@ - + - - - + + + - + @@ -8502,18 +8552,18 @@ - + - - - + + + - + @@ -8590,18 +8640,18 @@ - + - - - + + + - + @@ -8693,18 +8743,18 @@ - + - - - + + + - + @@ -8721,18 +8771,18 @@ - + - - - + + + - + @@ -8749,18 +8799,18 @@ - + - - - + + + - + @@ -8777,18 +8827,18 @@ - + - - - + + + - + @@ -8820,18 +8870,18 @@ - + - - - + + + - + @@ -8863,18 +8913,18 @@ - + - - - + + + - + @@ -8906,18 +8956,18 @@ - + - - - + + + - + @@ -8949,18 +8999,18 @@ - + - - - + + + - + @@ -8992,18 +9042,18 @@ - + - - - + + + - + @@ -9023,9 +9073,9 @@ - + - + FX-SCH-A-000092 @@ -9035,18 +9085,18 @@ - + - - - + + + - + @@ -9063,18 +9113,18 @@ - + - - - + + + - + @@ -9106,18 +9156,18 @@ - + - - - + + + - + @@ -9149,18 +9199,18 @@ - + - - - + + + - + @@ -9192,18 +9242,18 @@ - + - - - + + + - + @@ -9235,18 +9285,18 @@ - + - - - + + + - + @@ -9278,18 +9328,18 @@ - + - - - + + + - + @@ -9321,18 +9371,18 @@ - + - - - + + + - + @@ -9364,18 +9414,18 @@ - + - - - + + + - + @@ -9395,9 +9445,9 @@ - + - + FX-SCH-A-000110 @@ -9407,18 +9457,18 @@ - + - - - + + + - + @@ -9435,18 +9485,18 @@ - + - - - + + + - + @@ -9478,18 +9528,18 @@ - + - - - + + + - + @@ -9521,18 +9571,18 @@ - + - - - + + + - + @@ -9612,9 +9662,9 @@ - + - + FX-SCH-A-000304 @@ -9627,9 +9677,9 @@ - + - + FX-SCH-A-000305 @@ -9849,18 +9899,18 @@ - + - - - + + + - + @@ -9877,18 +9927,18 @@ - + - - - + + + - + @@ -9920,18 +9970,46 @@ - + - - - + + + - + + + + + + + + + FX-SCH-A-000134 + + + + + [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. + + + + + + + + + + + + + + + @@ -9948,33 +10026,18 @@ - - - - - - - FX-SCH-A-000134 - - - - - [BR-61]-If the Payment means type code (BT-81) means SEPA credit transfer, Local credit transfer or Non-SEPA international credit transfer, the Payment account identifier (BT-84) shall be present. - - - - + - - - + + + - + @@ -9991,18 +10054,18 @@ - + - - - + + + - + @@ -10049,18 +10112,18 @@ - + - - - + + + - + @@ -10107,18 +10170,18 @@ - + - - - + + + - + @@ -10165,18 +10228,18 @@ - + - - - + + + - + @@ -10253,18 +10316,18 @@ - + - - - + + + - + @@ -10311,18 +10374,18 @@ - + - - - + + + - + @@ -10369,18 +10432,18 @@ - + - - - + + + - + @@ -10427,18 +10490,18 @@ - + - - - + + + - + @@ -10470,18 +10533,18 @@ - + - - - + + + - + @@ -10513,18 +10576,18 @@ - + - - - + + + - + @@ -10556,18 +10619,18 @@ - + - - - + + + - + @@ -10599,18 +10662,18 @@ - + - - - + + + - + @@ -10642,18 +10705,18 @@ - + - - - + + + - + @@ -10673,9 +10736,9 @@ - + - + FX-SCH-A-000246 @@ -10685,18 +10748,18 @@ - + - - - + + + - + @@ -10713,18 +10776,18 @@ - + - - - + + + - + @@ -10756,18 +10819,18 @@ - + - - - + + + - + @@ -10799,18 +10862,18 @@ - + - - - + + + - + @@ -11202,18 +11265,18 @@ - + - - - + + + - + @@ -11275,18 +11338,18 @@ - + - - - + + + - + @@ -11303,18 +11366,18 @@ - + - - - + + + - + @@ -11331,18 +11394,18 @@ - + - - - + + + - + @@ -11360,54 +11423,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Description' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:EndDateTime' is marked as not used in the given context. - - @@ -11419,8 +11434,8 @@ - - + + @@ -11429,7 +11444,7 @@ - Element 'ram:StartDateTime' is marked as not used in the given context. + Element 'ram:Description' is marked as not used in the given context. @@ -11443,8 +11458,8 @@ - - + + @@ -11453,7 +11468,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:EndDateTime' is marked as not used in the given context. @@ -11467,7 +11482,55 @@ - + + + + + + + + + + + Element 'ram:StartDateTime' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -11499,18 +11562,18 @@ - + - - - + + + - + @@ -11523,18 +11586,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -11547,18 +11610,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -11576,18 +11639,18 @@ - + - - - + + + - + @@ -11600,18 +11663,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -11624,18 +11687,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -11652,18 +11715,18 @@ - + - - - + + + - + @@ -11680,18 +11743,18 @@ - + - - - + + + - + @@ -11709,18 +11772,18 @@ - + - - - + + + - + @@ -11733,18 +11796,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -11762,18 +11825,18 @@ - + - - - + + + - + @@ -11805,58 +11868,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000019 - - - - - Element 'ram:ID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -11868,8 +11879,8 @@ - - + + @@ -11896,7 +11907,59 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000019 + + + + + Element 'ram:ID' must occur exactly 1 times. + + + + + + + + + + + + + + + @@ -11914,18 +11977,18 @@ - + - - - + + + - + @@ -11938,18 +12001,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -11966,18 +12029,18 @@ - + - - - + + + - + @@ -12009,18 +12072,18 @@ - + - - - + + + - + @@ -12033,18 +12096,18 @@ Element variant 'ram:AdditionalReferencedDocument[ not(ram:TypeCode="916") and not(ram:TypeCode="50") and not(ram:TypeCode="130")]' is marked as not used in the given context. - + - - - + + + - + @@ -12076,18 +12139,18 @@ - + - - - + + + - + @@ -12100,18 +12163,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -12128,18 +12191,18 @@ - + - - - + + + - + @@ -12157,54 +12220,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -12216,8 +12231,8 @@ - - + + @@ -12226,7 +12241,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -12240,7 +12255,55 @@ - + + + + + + + + + + + Element 'ram:LineID' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:Name' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -12258,18 +12321,18 @@ - + - - - + + + - + @@ -12287,18 +12350,18 @@ - + - - - + + + - + @@ -12311,18 +12374,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -12354,18 +12417,18 @@ - + - - - + + + - + @@ -12378,18 +12441,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -12406,18 +12469,18 @@ - + - - - + + + - + @@ -12435,54 +12498,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -12494,8 +12509,8 @@ - - + + @@ -12504,7 +12519,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -12518,8 +12533,8 @@ - - + + @@ -12528,7 +12543,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -12542,7 +12557,55 @@ - + + + + + + + + + + + Element 'ram:Name' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -12560,18 +12623,18 @@ - + - - - + + + - + @@ -12584,18 +12647,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -12657,18 +12720,18 @@ - + - - - + + + - + @@ -12700,18 +12763,18 @@ - + - - - + + + - + @@ -12729,18 +12792,18 @@ - + - - - + + + - + @@ -12757,18 +12820,18 @@ - + - - - + + + - + @@ -12786,54 +12849,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -12845,8 +12860,8 @@ - - + + @@ -12855,7 +12870,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -12869,7 +12884,55 @@ - + + + + + + + + + + + Element 'ram:LineID' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -12887,18 +12950,18 @@ - + - - - + + + - + @@ -12911,18 +12974,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -12939,18 +13002,18 @@ - + - - - + + + - + @@ -12968,18 +13031,18 @@ - + - - - + + + - + @@ -13056,18 +13119,18 @@ - + - - - + + + - + @@ -13084,18 +13147,18 @@ - + - - - + + + - + @@ -13108,58 +13171,6 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000289 - - - - - Element 'ram:CompleteNumber' must occur exactly 1 times. - - - @@ -13171,8 +13182,8 @@ - - + + @@ -13181,7 +13192,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -13195,8 +13206,8 @@ - - + + @@ -13223,8 +13234,8 @@ - - + + @@ -13247,7 +13258,59 @@ - + + + + + + + + + FX-SCH-A-000289 + + + + + Element 'ram:CompleteNumber' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -13260,18 +13323,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -13288,18 +13351,18 @@ - + - - - + + + - + @@ -13317,18 +13380,18 @@ - + - - - + + + - + @@ -13341,18 +13404,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -13384,26 +13447,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -13413,18 +13476,18 @@ - + - - - + + + - + @@ -13437,18 +13500,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -13461,18 +13524,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -13490,18 +13553,18 @@ - + - - - + + + - + @@ -13533,26 +13596,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -13562,18 +13625,18 @@ - + - - - + + + - + @@ -13586,18 +13649,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -13610,18 +13673,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -13638,18 +13701,18 @@ - + - - - + + + - + @@ -13666,18 +13729,18 @@ - + - - - + + + - + @@ -13694,18 +13757,18 @@ - + - - - + + + - + @@ -13718,18 +13781,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -13746,18 +13809,18 @@ - + - - - + + + - + @@ -13775,18 +13838,18 @@ - + - - - + + + - + @@ -13803,18 +13866,18 @@ - + - - - + + + - + @@ -13827,18 +13890,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -13855,18 +13918,18 @@ - + - - - + + + - + @@ -13884,54 +13947,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -13943,8 +13958,8 @@ - - + + @@ -13953,7 +13968,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -13967,8 +13982,8 @@ - - + + @@ -13977,7 +13992,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -13991,8 +14006,8 @@ - - + + @@ -14001,7 +14016,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -14015,8 +14030,8 @@ - - + + @@ -14025,7 +14040,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -14039,7 +14054,55 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -14116,18 +14179,18 @@ - + - - - + + + - + @@ -14144,18 +14207,18 @@ - + - - - + + + - + @@ -14168,58 +14231,6 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000289 - - - - - Element 'ram:CompleteNumber' must occur exactly 1 times. - - - @@ -14231,8 +14242,8 @@ - - + + @@ -14241,7 +14252,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -14255,8 +14266,8 @@ - - + + @@ -14283,8 +14294,8 @@ - - + + @@ -14307,7 +14318,59 @@ - + + + + + + + + + FX-SCH-A-000289 + + + + + Element 'ram:CompleteNumber' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -14320,18 +14383,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -14348,18 +14411,18 @@ - + - - - + + + - + @@ -14377,18 +14440,18 @@ - + - - - + + + - + @@ -14401,18 +14464,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -14444,26 +14507,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -14473,18 +14536,18 @@ - + - - - + + + - + @@ -14497,18 +14560,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -14521,18 +14584,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -14550,18 +14613,18 @@ - + - - - + + + - + @@ -14593,26 +14656,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -14622,18 +14685,18 @@ - + - - - + + + - + @@ -14646,18 +14709,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -14670,18 +14733,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -14698,18 +14761,18 @@ - + - - - + + + - + @@ -14726,18 +14789,18 @@ - + - - - + + + - + @@ -14754,18 +14817,18 @@ - + - - - + + + - + @@ -14778,18 +14841,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -14806,18 +14869,18 @@ - + - - - + + + - + @@ -14835,18 +14898,18 @@ - + - - - + + + - + @@ -14953,18 +15016,18 @@ - + - - - + + + - + @@ -14981,18 +15044,18 @@ - + - - - + + + - + @@ -15005,58 +15068,6 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000289 - - - - - Element 'ram:CompleteNumber' must occur exactly 1 times. - - - @@ -15068,8 +15079,8 @@ - - + + @@ -15078,7 +15089,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -15092,8 +15103,8 @@ - - + + @@ -15120,8 +15131,8 @@ - - + + @@ -15144,7 +15155,59 @@ - + + + + + + + + + FX-SCH-A-000289 + + + + + Element 'ram:CompleteNumber' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -15161,18 +15224,18 @@ - + - - - + + + - + @@ -15190,18 +15253,18 @@ - + - - - + + + - + @@ -15214,18 +15277,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -15257,26 +15320,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -15286,18 +15349,18 @@ - + - - - + + + - + @@ -15310,18 +15373,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -15334,18 +15397,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -15363,18 +15426,18 @@ - + - - - + + + - + @@ -15406,26 +15469,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -15435,18 +15498,18 @@ - + - - - + + + - + @@ -15459,18 +15522,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -15483,18 +15546,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -15511,18 +15574,18 @@ - + - - - + + + - + @@ -15539,18 +15602,18 @@ - + - - - + + + - + @@ -15568,18 +15631,18 @@ - + - - - + + + - + @@ -15596,18 +15659,18 @@ - + - - - + + + - + @@ -15620,18 +15683,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -15648,18 +15711,18 @@ - + - - - + + + - + @@ -15677,18 +15740,18 @@ - + - - - + + + - + @@ -15705,18 +15768,18 @@ - + - - - + + + - + @@ -15729,18 +15792,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -15757,18 +15820,18 @@ - + - - - + + + - + @@ -15786,54 +15849,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -15845,8 +15860,8 @@ - - + + @@ -15855,7 +15870,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -15869,7 +15884,55 @@ - + + + + + + + + + + + Element 'ram:LineID' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:Name' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -15887,18 +15950,18 @@ - + - - - + + + - + @@ -15911,18 +15974,18 @@ Element 'ram:TypeCode' is marked as not used in the given context. - + - - - + + + - + @@ -15935,18 +15998,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -16023,18 +16086,18 @@ - + - - - + + + - + @@ -16051,18 +16114,18 @@ - + - - - + + + - + @@ -16075,58 +16138,6 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000289 - - - - - Element 'ram:CompleteNumber' must occur exactly 1 times. - - - @@ -16138,8 +16149,8 @@ - - + + @@ -16148,7 +16159,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -16162,8 +16173,8 @@ - - + + @@ -16190,8 +16201,8 @@ - - + + @@ -16214,7 +16225,59 @@ - + + + + + + + + + FX-SCH-A-000289 + + + + + Element 'ram:CompleteNumber' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -16227,18 +16290,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -16255,18 +16318,18 @@ - + - - - + + + - + @@ -16284,18 +16347,18 @@ - + - - - + + + - + @@ -16308,18 +16371,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -16351,26 +16414,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -16380,18 +16443,18 @@ - + - - - + + + - + @@ -16404,18 +16467,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -16428,18 +16491,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -16457,18 +16520,18 @@ - + - - - + + + - + @@ -16500,26 +16563,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -16529,18 +16592,18 @@ - + - - - + + + - + @@ -16553,18 +16616,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -16577,18 +16640,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -16605,18 +16668,18 @@ - + - - - + + + - + @@ -16633,18 +16696,18 @@ - + - - - + + + - + @@ -16661,18 +16724,18 @@ - + - - - + + + - + @@ -16685,18 +16748,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -16713,18 +16776,18 @@ - + - - - + + + - + @@ -16742,18 +16805,18 @@ - + - - - + + + - + @@ -16770,18 +16833,18 @@ - + - - - + + + - + @@ -16794,18 +16857,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -16822,18 +16885,18 @@ - + - - - + + + - + @@ -16851,54 +16914,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -16910,8 +16925,8 @@ - - + + @@ -16920,7 +16935,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -16934,8 +16949,8 @@ - - + + @@ -16944,7 +16959,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -16958,8 +16973,8 @@ - - + + @@ -16968,7 +16983,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -16982,8 +16997,8 @@ - - + + @@ -16992,7 +17007,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -17006,7 +17021,55 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -17083,18 +17146,18 @@ - + - - - + + + - + @@ -17111,18 +17174,18 @@ - + - - - + + + - + @@ -17135,58 +17198,6 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000289 - - - - - Element 'ram:CompleteNumber' must occur exactly 1 times. - - - @@ -17198,8 +17209,8 @@ - - + + @@ -17208,7 +17219,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -17222,8 +17233,8 @@ - - + + @@ -17250,8 +17261,8 @@ - - + + @@ -17274,7 +17285,59 @@ - + + + + + + + + + FX-SCH-A-000289 + + + + + Element 'ram:CompleteNumber' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -17287,18 +17350,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -17315,18 +17378,18 @@ - + - - - + + + - + @@ -17344,18 +17407,18 @@ - + - - - + + + - + @@ -17368,18 +17431,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -17411,26 +17474,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -17440,18 +17503,18 @@ - + - - - + + + - + @@ -17464,18 +17527,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -17488,18 +17551,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -17517,18 +17580,18 @@ - + - - - + + + - + @@ -17560,26 +17623,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -17589,18 +17652,18 @@ - + - - - + + + - + @@ -17613,18 +17676,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -17637,18 +17700,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -17665,18 +17728,18 @@ - + - - - + + + - + @@ -17693,18 +17756,18 @@ - + - - - + + + - + @@ -17721,18 +17784,18 @@ - + - - - + + + - + @@ -17745,18 +17808,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -17773,18 +17836,18 @@ - + - - - + + + - + @@ -17802,18 +17865,18 @@ - + - - - + + + - + @@ -17830,18 +17893,18 @@ - + - - - + + + - + @@ -17854,18 +17917,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -17882,18 +17945,18 @@ - + - - - + + + - + @@ -17911,54 +17974,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -17970,8 +17985,8 @@ - - + + @@ -17980,7 +17995,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -17994,8 +18009,8 @@ - - + + @@ -18004,7 +18019,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -18018,8 +18033,8 @@ - - + + @@ -18028,7 +18043,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -18042,8 +18057,8 @@ - - + + @@ -18052,7 +18067,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -18066,7 +18081,55 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -18158,18 +18221,18 @@ - + - - - + + + - + @@ -18186,18 +18249,18 @@ - + - - - + + + - + @@ -18210,58 +18273,6 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000289 - - - - - Element 'ram:CompleteNumber' must occur exactly 1 times. - - - @@ -18273,8 +18284,8 @@ - - + + @@ -18283,7 +18294,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -18297,8 +18308,8 @@ - - + + @@ -18325,8 +18336,8 @@ - - + + @@ -18349,7 +18360,59 @@ - + + + + + + + + + FX-SCH-A-000289 + + + + + Element 'ram:CompleteNumber' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -18362,18 +18425,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -18390,18 +18453,18 @@ - + - - - + + + - + @@ -18419,18 +18482,18 @@ - + - - - + + + - + @@ -18443,18 +18506,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -18486,26 +18549,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -18515,18 +18578,18 @@ - + - - - + + + - + @@ -18539,18 +18602,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -18563,18 +18626,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -18592,18 +18655,18 @@ - + - - - + + + - + @@ -18635,26 +18698,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -18664,18 +18727,18 @@ - + - - - + + + - + @@ -18688,18 +18751,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -18712,18 +18775,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -18740,18 +18803,18 @@ - + - - - + + + - + @@ -18768,18 +18831,18 @@ - + - - - + + + - + @@ -18797,18 +18860,18 @@ - + - - - + + + - + @@ -18825,18 +18888,18 @@ - + - - - + + + - + @@ -18849,18 +18912,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -18877,18 +18940,18 @@ - + - - - + + + - + @@ -18906,18 +18969,18 @@ - + - - - + + + - + @@ -19024,18 +19087,18 @@ - + - - - + + + - + @@ -19052,18 +19115,18 @@ - + - - - + + + - + @@ -19076,58 +19139,6 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000289 - - - - - Element 'ram:CompleteNumber' must occur exactly 1 times. - - - @@ -19139,8 +19150,8 @@ - - + + @@ -19149,7 +19160,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -19163,8 +19174,8 @@ - - + + @@ -19191,8 +19202,8 @@ - - + + @@ -19215,7 +19226,59 @@ - + + + + + + + + + FX-SCH-A-000289 + + + + + Element 'ram:CompleteNumber' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -19232,18 +19295,18 @@ - + - - - + + + - + @@ -19261,18 +19324,18 @@ - + - - - + + + - + @@ -19285,18 +19348,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -19328,26 +19391,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -19357,18 +19420,18 @@ - + - - - + + + - + @@ -19381,18 +19444,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -19405,18 +19468,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -19434,18 +19497,18 @@ - + - - - + + + - + @@ -19477,59 +19540,6 @@ - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000036 - - - - - Value of 'ram:CountryID' is not allowed. - - - - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - @@ -19541,19 +19551,24 @@ - - + + + - - - - - - - - Attribute @listVersionID' marked as not used in the given context. - - + + + + + + FX-SCH-A-000036 + + + + + Value of 'ram:CountryID' is not allowed. + + + @@ -19565,8 +19580,8 @@ - - + + @@ -19575,7 +19590,7 @@ - Element variant 'ram:SpecifiedTaxRegistration[ not(ram:ID/@schemeID="VA") and not(ram:ID/@schemeID="FC")]' is marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -19589,23 +19604,19 @@ - - + + - - - - - - FX-SCH-A-000019 - - - - - Element 'ram:ID' must occur exactly 1 times. - - - + + + + + + + + Attribute @listVersionID' marked as not used in the given context. + + @@ -19617,23 +19628,19 @@ - - + + - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - + + + + + + + + Element variant 'ram:SpecifiedTaxRegistration[ not(ram:ID/@schemeID="VA") and not(ram:ID/@schemeID="FC")]' is marked as not used in the given context. + + @@ -19645,8 +19652,8 @@ - - + + @@ -19673,8 +19680,8 @@ - - + + @@ -19701,7 +19708,63 @@ - + + + + + + + + + FX-SCH-A-000019 + + + + + Element 'ram:ID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -19718,18 +19781,18 @@ - + - - - + + + - + @@ -19742,18 +19805,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -19770,18 +19833,18 @@ - + - - - + + + - + @@ -19799,18 +19862,18 @@ - + - - - + + + - + @@ -19823,18 +19886,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -19851,18 +19914,18 @@ - + - - - + + + - + @@ -19875,18 +19938,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -19903,18 +19966,18 @@ - + - - - + + + - + @@ -19932,54 +19995,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -19991,8 +20006,8 @@ - - + + @@ -20001,7 +20016,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -20015,8 +20030,8 @@ - - + + @@ -20025,7 +20040,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -20039,8 +20054,8 @@ - - + + @@ -20049,7 +20064,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -20063,8 +20078,8 @@ - - + + @@ -20073,7 +20088,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -20087,7 +20102,55 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -20104,18 +20167,18 @@ - + - - - + + + - + @@ -20132,18 +20195,18 @@ - + - - - + + + - + @@ -20160,18 +20223,18 @@ - + - - - + + + - + @@ -20189,18 +20252,18 @@ - + - - - + + + - + @@ -20217,18 +20280,18 @@ - + - - - + + + - + @@ -20241,18 +20304,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -20269,18 +20332,18 @@ - + - - - + + + - + @@ -20298,54 +20361,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -20357,8 +20372,8 @@ - - + + @@ -20367,7 +20382,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -20381,8 +20396,8 @@ - - + + @@ -20391,7 +20406,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -20405,8 +20420,8 @@ - - + + @@ -20415,7 +20430,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -20429,8 +20444,8 @@ - - + + @@ -20439,7 +20454,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -20453,7 +20468,55 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -20470,18 +20533,18 @@ - + - - - + + + - + @@ -20494,18 +20557,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -20522,18 +20585,18 @@ - + - - - + + + - + @@ -20551,54 +20614,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -20610,8 +20625,8 @@ - - + + @@ -20620,7 +20635,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -20634,8 +20649,8 @@ - - + + @@ -20644,7 +20659,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -20658,8 +20673,8 @@ - - + + @@ -20668,7 +20683,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -20682,8 +20697,8 @@ - - + + @@ -20692,7 +20707,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -20706,7 +20721,55 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -20723,18 +20786,18 @@ - + - - - + + + - + @@ -20747,18 +20810,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -20775,18 +20838,18 @@ - + - - - + + + - + @@ -20804,54 +20867,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - @@ -20863,8 +20878,8 @@ - - + + @@ -20873,7 +20888,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -20887,8 +20902,8 @@ - - + + @@ -20897,7 +20912,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Element 'ram:LineID' is marked as not used in the given context. @@ -20911,8 +20926,8 @@ - - + + @@ -20921,7 +20936,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -20935,8 +20950,8 @@ - - + + @@ -20945,7 +20960,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -20959,7 +20974,55 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -20976,18 +21039,47 @@ - + - - - + + + - + + + + + + + + + + FX-SCH-A-000346 + + + + + Value of 'ram:ModeCode' is not allowed. + + + + + + + + + + + + + + + @@ -21049,18 +21141,18 @@ - + - - - + + + - + @@ -21077,18 +21169,18 @@ - + - - - + + + - + @@ -21101,18 +21193,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -21125,18 +21217,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -21153,18 +21245,18 @@ - + - - - + + + - + @@ -21177,18 +21269,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -21205,18 +21297,18 @@ - + - - - + + + - + @@ -21229,18 +21321,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -21253,18 +21345,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -21281,18 +21373,18 @@ - + - - - + + + - + @@ -21310,18 +21402,18 @@ - + - - - + + + - + @@ -21334,18 +21426,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -21377,26 +21469,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -21406,18 +21498,18 @@ - + - - - + + + - + @@ -21430,18 +21522,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -21454,18 +21546,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -21483,18 +21575,18 @@ - + - - - + + + - + @@ -21526,26 +21618,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -21555,18 +21647,18 @@ - + - - - + + + - + @@ -21579,18 +21671,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -21603,18 +21695,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -21631,86 +21723,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -21722,8 +21734,8 @@ - - + + @@ -21750,7 +21762,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -21768,18 +21860,18 @@ - + - - - + + + - + @@ -21841,18 +21933,18 @@ - + - - - + + + - + @@ -21869,18 +21961,18 @@ - + - - - + + + - + @@ -21893,18 +21985,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -21917,18 +22009,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -21945,18 +22037,18 @@ - + - - - + + + - + @@ -21969,18 +22061,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -21997,18 +22089,18 @@ - + - - - + + + - + @@ -22021,18 +22113,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -22045,18 +22137,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -22073,18 +22165,18 @@ - + - - - + + + - + @@ -22102,18 +22194,18 @@ - + - - - + + + - + @@ -22126,18 +22218,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -22169,26 +22261,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -22198,18 +22290,18 @@ - + - - - + + + - + @@ -22222,18 +22314,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -22246,18 +22338,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -22275,18 +22367,18 @@ - + - - - + + + - + @@ -22318,26 +22410,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -22347,18 +22439,18 @@ - + - - - + + + - + @@ -22371,18 +22463,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -22395,18 +22487,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -22423,86 +22515,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -22514,8 +22526,8 @@ - - + + @@ -22542,7 +22554,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -22560,18 +22652,18 @@ - + - - - + + + - + @@ -22633,18 +22725,18 @@ - + - - - + + + - + @@ -22661,18 +22753,18 @@ - + - - - + + + - + @@ -22685,18 +22777,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -22709,18 +22801,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -22737,18 +22829,18 @@ - + - - - + + + - + @@ -22761,18 +22853,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -22789,18 +22881,18 @@ - + - - - + + + - + @@ -22813,18 +22905,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -22837,18 +22929,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -22865,18 +22957,18 @@ - + - - - + + + - + @@ -22894,18 +22986,18 @@ - + - - - + + + - + @@ -22918,18 +23010,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -22961,26 +23053,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -22990,18 +23082,18 @@ - + - - - + + + - + @@ -23014,18 +23106,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -23038,18 +23130,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -23067,18 +23159,18 @@ - + - - - + + + - + @@ -23110,26 +23202,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -23139,18 +23231,18 @@ - + - - - + + + - + @@ -23163,18 +23255,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -23187,18 +23279,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -23215,86 +23307,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -23306,8 +23318,8 @@ - - + + @@ -23334,7 +23346,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -23352,18 +23444,18 @@ - + - - - + + + - + @@ -23425,18 +23517,18 @@ - + - - - + + + - + @@ -23528,18 +23620,18 @@ - + - - - + + + - + @@ -23552,18 +23644,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -23576,18 +23668,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -23600,18 +23692,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -23629,26 +23721,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000180 @@ -23658,18 +23750,18 @@ - + - - - + + + - + @@ -23687,18 +23779,18 @@ - + - - - + + + - + @@ -23711,18 +23803,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -23735,18 +23827,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -23759,18 +23851,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -23787,26 +23879,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000022 @@ -23816,18 +23908,18 @@ - + - - - + + + - + @@ -23845,18 +23937,18 @@ - + - - - + + + - + @@ -23873,18 +23965,18 @@ - + - - - + + + - + @@ -23897,18 +23989,18 @@ Element 'ram:CompleteDateTime' is marked as not used in the given context. - + - - - + + + - + @@ -23925,18 +24017,18 @@ - + - - - + + + - + @@ -23954,18 +24046,18 @@ - + - - - + + + - + @@ -23982,18 +24074,18 @@ - + - - - + + + - + @@ -24011,18 +24103,18 @@ - + - - - + + + - + @@ -24035,26 +24127,26 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + - + - + - + FX-SCH-A-000040 @@ -24064,18 +24156,18 @@ - + - - - + + + - + @@ -24107,18 +24199,18 @@ - + - - - + + + - + @@ -24131,18 +24223,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -24159,18 +24251,18 @@ - + - - - + + + - + @@ -24188,78 +24280,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -24271,8 +24291,8 @@ - - + + @@ -24281,7 +24301,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -24295,24 +24315,19 @@ - - - + + - - - - - - FX-SCH-A-000023 - - - - - Value of 'ram:TypeCode' is not allowed. - - - + + + + + + + + Element 'ram:LineID' is marked as not used in the given context. + + @@ -24324,8 +24339,8 @@ - - + + @@ -24334,7 +24349,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -24348,7 +24363,84 @@ - + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000023 + + + + + Value of 'ram:TypeCode' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -24425,18 +24517,18 @@ - + - - - + + + - + @@ -24453,18 +24545,18 @@ - + - - - + + + - + @@ -24477,18 +24569,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -24501,18 +24593,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -24529,18 +24621,18 @@ - + - - - + + + - + @@ -24553,18 +24645,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -24581,18 +24673,18 @@ - + - - - + + + - + @@ -24605,18 +24697,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -24629,18 +24721,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -24657,18 +24749,18 @@ - + - - - + + + - + @@ -24686,18 +24778,18 @@ - + - - - + + + - + @@ -24710,18 +24802,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -24753,26 +24845,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -24782,18 +24874,18 @@ - + - - - + + + - + @@ -24806,18 +24898,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -24830,18 +24922,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -24859,18 +24951,18 @@ - + - - - + + + - + @@ -24902,26 +24994,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -24931,18 +25023,18 @@ - + - - - + + + - + @@ -24955,18 +25047,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -24979,18 +25071,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -25007,86 +25099,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -25098,8 +25110,8 @@ - - + + @@ -25126,7 +25138,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -25144,18 +25236,18 @@ - + - - - + + + - + @@ -25232,18 +25324,18 @@ - + - - - + + + - + @@ -25260,18 +25352,18 @@ - + - - - + + + - + @@ -25284,18 +25376,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -25308,18 +25400,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -25336,18 +25428,18 @@ - + - - - + + + - + @@ -25360,18 +25452,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -25388,18 +25480,18 @@ - + - - - + + + - + @@ -25412,18 +25504,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -25436,18 +25528,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -25464,18 +25556,18 @@ - + - - - + + + - + @@ -25493,18 +25585,18 @@ - + - - - + + + - + @@ -25517,18 +25609,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -25560,26 +25652,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -25589,18 +25681,18 @@ - + - - - + + + - + @@ -25613,18 +25705,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -25637,18 +25729,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -25666,18 +25758,18 @@ - + - - - + + + - + @@ -25709,26 +25801,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -25738,18 +25830,18 @@ - + - - - + + + - + @@ -25762,18 +25854,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -25786,18 +25878,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -25814,86 +25906,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -25905,8 +25917,8 @@ - - + + @@ -25933,7 +25945,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -25951,18 +26043,18 @@ - + - - - + + + - + @@ -26039,18 +26131,18 @@ - + - - - + + + - + @@ -26067,18 +26159,18 @@ - + - - - + + + - + @@ -26091,18 +26183,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -26115,18 +26207,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -26143,18 +26235,18 @@ - + - - - + + + - + @@ -26167,18 +26259,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -26195,18 +26287,18 @@ - + - - - + + + - + @@ -26219,18 +26311,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -26243,18 +26335,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -26271,18 +26363,18 @@ - + - - - + + + - + @@ -26300,18 +26392,18 @@ - + - - - + + + - + @@ -26324,18 +26416,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -26367,26 +26459,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -26396,18 +26488,18 @@ - + - - - + + + - + @@ -26420,18 +26512,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -26444,18 +26536,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -26473,18 +26565,18 @@ - + - - - + + + - + @@ -26516,26 +26608,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -26545,18 +26637,18 @@ - + - - - + + + - + @@ -26569,18 +26661,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -26593,18 +26685,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -26621,86 +26713,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -26712,8 +26724,8 @@ - - + + @@ -26740,7 +26752,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -26758,18 +26850,18 @@ - + - - - + + + - + @@ -26846,18 +26938,18 @@ - + - - - + + + - + @@ -26874,18 +26966,18 @@ - + - - - + + + - + @@ -26898,18 +26990,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -26922,18 +27014,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -26950,18 +27042,18 @@ - + - - - + + + - + @@ -26974,18 +27066,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -27002,18 +27094,18 @@ - + - - - + + + - + @@ -27026,18 +27118,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -27050,18 +27142,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -27078,18 +27170,18 @@ - + - - - + + + - + @@ -27107,18 +27199,18 @@ - + - - - + + + - + @@ -27131,18 +27223,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -27174,26 +27266,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -27203,18 +27295,18 @@ - + - - - + + + - + @@ -27227,18 +27319,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -27251,18 +27343,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -27280,18 +27372,18 @@ - + - - - + + + - + @@ -27323,26 +27415,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -27352,18 +27444,18 @@ - + - - - + + + - + @@ -27376,18 +27468,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -27400,18 +27492,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -27428,86 +27520,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -27519,8 +27531,8 @@ - - + + @@ -27547,7 +27559,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -27565,18 +27657,18 @@ - + - - - + + + - + @@ -27589,26 +27681,26 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + - + - + - + FX-SCH-A-000023 @@ -27618,18 +27710,18 @@ - + - - - + + + - + @@ -27661,18 +27753,18 @@ - + - - - + + + - + @@ -27689,18 +27781,18 @@ - + - - - + + + - + @@ -27718,18 +27810,18 @@ - + - - - + + + - + @@ -27776,18 +27868,18 @@ - + - - - + + + - + @@ -27800,18 +27892,18 @@ Element 'ram:AllowanceChargeBasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -27824,18 +27916,18 @@ Element 'ram:BasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -27848,18 +27940,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -27877,18 +27969,18 @@ - + - - - + + + - + @@ -27901,18 +27993,18 @@ Element 'ram:DueDateTypeCode' is marked as not used in the given context. - + - - - + + + - + @@ -27930,78 +28022,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @listVersionID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. - - @@ -28013,8 +28033,8 @@ - - + + @@ -28023,7 +28043,7 @@ - Element 'ram:TaxPointDate' is marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -28037,7 +28057,79 @@ - + + + + + + + + + + + Attribute @listVersionID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TaxPointDate' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -28055,18 +28147,18 @@ - + - - - + + + - + @@ -28083,18 +28175,18 @@ - + - - - + + + - + @@ -28107,18 +28199,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -28135,18 +28227,18 @@ - + - - - + + + - + @@ -28164,78 +28256,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineID' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -28247,8 +28267,8 @@ - - + + @@ -28257,7 +28277,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -28271,24 +28291,19 @@ - - - + + - - - - - - FX-SCH-A-000023 - - - - - Value of 'ram:TypeCode' is not allowed. - - - + + + + + + + + Element 'ram:LineID' is marked as not used in the given context. + + @@ -28300,8 +28315,8 @@ - - + + @@ -28310,7 +28325,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -28324,8 +28339,8 @@ - - + + @@ -28334,7 +28349,7 @@ - Attribute @currencyID' marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -28348,7 +28363,84 @@ - + + + + + + + + + + FX-SCH-A-000023 + + + + + Value of 'ram:TypeCode' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -28395,18 +28487,18 @@ - + - - - + + + - + @@ -28419,18 +28511,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -28477,18 +28569,18 @@ - + - - - + + + - + @@ -28501,18 +28593,18 @@ Element 'ram:AllowanceChargeBasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -28525,18 +28617,18 @@ Element 'ram:BasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -28549,18 +28641,18 @@ Element 'ram:CalculatedAmount' is marked as not used in the given context. - + - - - + + + - + @@ -28578,78 +28670,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:ExemptionReason' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. - - @@ -28661,8 +28681,8 @@ - - + + @@ -28671,7 +28691,7 @@ - Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -28685,8 +28705,8 @@ - - + + @@ -28695,7 +28715,7 @@ - Element 'ram:TaxPointDate' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -28709,7 +28729,79 @@ - + + + + + + + + + + + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TaxPointDate' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -28727,18 +28819,18 @@ - + - - - + + + - + @@ -28751,18 +28843,18 @@ Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. - + - - - + + + - + @@ -28809,18 +28901,18 @@ - + - - - + + + - + @@ -28833,18 +28925,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -28857,18 +28949,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -28886,18 +28978,18 @@ - + - - - + + + - + @@ -28929,18 +29021,18 @@ - + - - - + + + - + @@ -28953,18 +29045,18 @@ Element 'ram:AllowanceChargeBasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -28977,18 +29069,18 @@ Element 'ram:BasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -29001,18 +29093,18 @@ Element 'ram:CalculatedAmount' is marked as not used in the given context. - + - - - + + + - + @@ -29030,78 +29122,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:ExemptionReason' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. - - @@ -29113,8 +29133,8 @@ - - + + @@ -29123,7 +29143,7 @@ - Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -29137,8 +29157,8 @@ - - + + @@ -29147,7 +29167,7 @@ - Element 'ram:TaxPointDate' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -29161,7 +29181,79 @@ - + + + + + + + + + + + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TaxPointDate' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -29179,26 +29271,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000186 @@ -29208,18 +29300,18 @@ - + - - - + + + - + @@ -29266,18 +29358,18 @@ - + - - - + + + - + @@ -29290,18 +29382,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -29314,18 +29406,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -29343,18 +29435,18 @@ - + - - - + + + - + @@ -29386,18 +29478,18 @@ - + - - - + + + - + @@ -29410,18 +29502,18 @@ Element 'ram:AllowanceChargeBasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -29434,18 +29526,18 @@ Element 'ram:BasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -29458,18 +29550,18 @@ Element 'ram:CalculatedAmount' is marked as not used in the given context. - + - - - + + + - + @@ -29487,78 +29579,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:DueDateTypeCode' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:ExemptionReason' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:ExemptionReasonCode' is marked as not used in the given context. - - @@ -29570,8 +29590,8 @@ - - + + @@ -29580,7 +29600,7 @@ - Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. + Element 'ram:DueDateTypeCode' is marked as not used in the given context. @@ -29594,8 +29614,8 @@ - - + + @@ -29604,7 +29624,7 @@ - Element 'ram:TaxPointDate' is marked as not used in the given context. + Element 'ram:ExemptionReason' is marked as not used in the given context. @@ -29618,7 +29638,79 @@ - + + + + + + + + + + + Element 'ram:ExemptionReasonCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TaxPointDate' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -29636,26 +29728,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000186 @@ -29665,18 +29757,18 @@ - + - - - + + + - + @@ -29738,18 +29830,18 @@ - + - - - + + + - + @@ -29762,87 +29854,6 @@ Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000021 - - - - - Attribute '@format' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000022 - - - - - Value of '@format' is not allowed. - - - @@ -29854,8 +29865,8 @@ - - + + @@ -29878,7 +29889,88 @@ - + + + + + + + + + FX-SCH-A-000021 + + + + + Attribute '@format' is required in this context. + + + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000022 + + + + + Value of '@format' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -29891,18 +29983,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -29919,18 +30011,18 @@ - + - - - + + + - + @@ -29948,18 +30040,18 @@ - + - - - + + + - + @@ -29976,18 +30068,18 @@ - + - - - + + + - + @@ -30000,18 +30092,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -30028,18 +30120,18 @@ - + - - - + + + - + @@ -30057,18 +30149,18 @@ - + - - - + + + - + @@ -30081,18 +30173,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -30169,18 +30261,18 @@ - + - - - + + + - + @@ -30197,18 +30289,18 @@ - + - - - + + + - + @@ -30221,18 +30313,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -30245,18 +30337,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -30273,18 +30365,18 @@ - + - - - + + + - + @@ -30297,18 +30389,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -30325,18 +30417,18 @@ - + - - - + + + - + @@ -30349,18 +30441,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -30373,18 +30465,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -30401,18 +30493,18 @@ - + - - - + + + - + @@ -30430,18 +30522,18 @@ - + - - - + + + - + @@ -30454,18 +30546,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -30497,26 +30589,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -30526,18 +30618,18 @@ - + - - - + + + - + @@ -30550,18 +30642,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -30574,18 +30666,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -30603,18 +30695,18 @@ - + - - - + + + - + @@ -30646,26 +30738,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -30675,18 +30767,18 @@ - + - - - + + + - + @@ -30699,18 +30791,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -30723,18 +30815,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -30751,86 +30843,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -30842,8 +30854,8 @@ - - + + @@ -30870,7 +30882,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -30888,18 +30980,18 @@ - + - - - + + + - + @@ -31051,78 +31143,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -31134,8 +31154,8 @@ - - + + @@ -31158,8 +31178,8 @@ - - + + @@ -31182,8 +31202,8 @@ - - + + @@ -31206,8 +31226,8 @@ - - + + @@ -31230,8 +31250,8 @@ - - + + @@ -31240,7 +31260,7 @@ - Element variant 'ram:TaxTotalAmount[ not(@currencyID=../../ram:InvoiceCurrencyCode) and not(@currencyID=../../ram:TaxCurrencyCode)]' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -31254,24 +31274,19 @@ - - - + + - - - - - - FX-SCH-A-000045 - - - - - Value of '@currencyID' is not allowed. - - - + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + @@ -31283,23 +31298,19 @@ - - + + - - - - - - FX-SCH-A-000046 - - - - - Attribute '@currencyID' is required in this context. - - - + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + @@ -31311,8 +31322,32 @@ - - + + + + + + + + + + + Element variant 'ram:TaxTotalAmount[ not(@currencyID=../../ram:InvoiceCurrencyCode) and not(@currencyID=../../ram:TaxCurrencyCode)]' is marked as not used in the given context. + + + + + + + + + + + + + + + @@ -31329,18 +31364,75 @@ - + - - - + + + - + + + + + + + + + FX-SCH-A-000046 + + + + + Attribute '@currencyID' is required in this context. + + + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000045 + + + + + Value of '@currencyID' is not allowed. + + + + + + + + + + + + + + + @@ -31357,18 +31449,18 @@ - + - - - + + + - + @@ -31381,18 +31473,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -31439,18 +31531,18 @@ - + - - - + + + - + @@ -31467,18 +31559,18 @@ - + - - - + + + - + @@ -31491,82 +31583,6 @@ Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000292 - - - - - Element 'ram:BICID' must occur exactly 1 times. - - - @@ -31578,8 +31594,8 @@ - - + + @@ -31602,7 +31618,83 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000292 + + + + + Element 'ram:BICID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -31619,18 +31711,18 @@ - + - - - + + + - + @@ -31643,26 +31735,26 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + - + - + - + FX-SCH-A-000023 @@ -31672,18 +31764,18 @@ - + - - - + + + - + @@ -31700,18 +31792,18 @@ - + - - - + + + - + @@ -31729,93 +31821,6 @@ - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000332 - - - - - Value of 'ram:SourceCurrencyCode' is not allowed. - - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000333 - - - - - Value of 'ram:TargetCurrencyCode' is not allowed. - - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000196 - - - - - Value of 'ram:TaxCurrencyCode' is not allowed. - - - @@ -31827,7 +31832,94 @@ - + + + + + + + + + + FX-SCH-A-000332 + + + + + Value of 'ram:SourceCurrencyCode' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000333 + + + + + Value of 'ram:TargetCurrencyCode' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000196 + + + + + Value of 'ram:TaxCurrencyCode' is not allowed. + + + + + + + + + + + + + + + @@ -31889,18 +31981,18 @@ - + - - - + + + - + @@ -31917,18 +32009,18 @@ - + - - - + + + - + @@ -31960,83 +32052,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @listVersionID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000162 - - - - - Value of 'ram:SubjectCode' is not allowed. - - - @@ -32048,8 +32063,8 @@ - - + + @@ -32072,8 +32087,8 @@ - - + + @@ -32096,7 +32111,84 @@ - + + + + + + + + + + FX-SCH-A-000162 + + + + + Value of 'ram:SubjectCode' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + Attribute @listID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Attribute @listVersionID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -32109,18 +32201,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -32138,18 +32230,18 @@ - + - - - + + + - + @@ -32167,18 +32259,18 @@ - + - - - + + + - + @@ -32191,18 +32283,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -32215,18 +32307,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -32239,18 +32331,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -32267,18 +32359,18 @@ - + - - - + + + - + @@ -32340,18 +32432,18 @@ - + - - - + + + - + @@ -32383,18 +32475,18 @@ - + - - - + + + - + @@ -32412,18 +32504,18 @@ - + - - - + + + - + @@ -32440,18 +32532,18 @@ - + - - - + + + - + @@ -32469,18 +32561,18 @@ - + - - - + + + - + @@ -32493,88 +32585,6 @@ Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000282 - - - - - Value of 'ram:ReferenceTypeCode' is not allowed. - - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000023 - - - - - Value of 'ram:TypeCode' is not allowed. - - - @@ -32586,8 +32596,8 @@ - - + + @@ -32610,7 +32620,89 @@ - + + + + + + + + + + FX-SCH-A-000282 + + + + + Value of 'ram:ReferenceTypeCode' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000023 + + + + + Value of 'ram:TypeCode' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -32623,18 +32715,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -32651,18 +32743,18 @@ - + - - - + + + - + @@ -32680,78 +32772,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -32763,8 +32783,8 @@ - - + + @@ -32773,7 +32793,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -32787,8 +32807,8 @@ - - + + @@ -32797,7 +32817,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -32811,8 +32831,8 @@ - - + + @@ -32821,7 +32841,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -32835,8 +32855,8 @@ - - + + @@ -32845,7 +32865,7 @@ - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -32859,7 +32879,79 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -32876,18 +32968,18 @@ - + - - - + + + - + @@ -32905,78 +32997,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -32988,8 +33008,8 @@ - - + + @@ -32998,7 +33018,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -33012,8 +33032,8 @@ - - + + @@ -33022,7 +33042,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -33036,8 +33056,8 @@ - - + + @@ -33046,7 +33066,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -33060,7 +33080,79 @@ - + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -33077,18 +33169,18 @@ - + - - - + + + - + @@ -33101,18 +33193,18 @@ Element variant 'ram:AppliedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. - + - - - + + + - + @@ -33144,78 +33236,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisQuantity' is marked as not used in the given context. - - @@ -33227,8 +33247,8 @@ - - + + @@ -33237,7 +33257,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -33251,7 +33271,79 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:BasisQuantity' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CategoryTradeTax' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -33269,18 +33361,18 @@ - + - - - + + + - + @@ -33293,18 +33385,18 @@ Element 'ram:SequenceNumeric' is marked as not used in the given context. - + - - - + + + - + @@ -33336,78 +33428,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisQuantity' is marked as not used in the given context. - - @@ -33419,8 +33439,8 @@ - - + + @@ -33429,7 +33449,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -33443,7 +33463,79 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:BasisQuantity' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CategoryTradeTax' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -33461,18 +33553,18 @@ - + - - - + + + - + @@ -33485,18 +33577,18 @@ Element 'ram:SequenceNumeric' is marked as not used in the given context. - + - - - + + + - + @@ -33514,18 +33606,18 @@ - + - - - + + + - + @@ -33538,18 +33630,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -33562,18 +33654,18 @@ Element 'ram:IncludedTradeTax' is marked as not used in the given context. - + - - - + + + - + @@ -33605,18 +33697,18 @@ - + - - - + + + - + @@ -33629,18 +33721,18 @@ Element 'ram:AppliedTradeAllowanceCharge' is marked as not used in the given context. - + - - - + + + - + @@ -33658,18 +33750,18 @@ - + - - - + + + - + @@ -33682,18 +33774,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -33755,18 +33847,18 @@ - + - - - + + + - + @@ -33779,18 +33871,18 @@ Element 'ram:AllowanceChargeBasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -33803,18 +33895,18 @@ Element 'ram:BasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -33827,18 +33919,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -33856,18 +33948,18 @@ - + - - - + + + - + @@ -33880,18 +33972,18 @@ Element 'ram:DueDateTypeCode' is marked as not used in the given context. - + - - - + + + - + @@ -33909,78 +34001,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @listVersionID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. - - @@ -33992,8 +34012,8 @@ - - + + @@ -34002,7 +34022,7 @@ - Element 'ram:TaxPointDate' is marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -34016,7 +34036,79 @@ - + + + + + + + + + + + Attribute @listVersionID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TaxPointDate' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -34034,18 +34126,18 @@ - + - - - + + + - + @@ -34058,18 +34150,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -34086,18 +34178,18 @@ - + - - - + + + - + @@ -34115,78 +34207,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -34198,8 +34218,8 @@ - - + + @@ -34208,7 +34228,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -34222,8 +34242,8 @@ - - + + @@ -34232,7 +34252,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -34246,8 +34266,8 @@ - - + + @@ -34256,7 +34276,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -34270,8 +34290,8 @@ - - + + @@ -34280,7 +34300,7 @@ - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -34294,7 +34314,79 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -34311,18 +34403,18 @@ - + - - - + + + - + @@ -34340,78 +34432,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -34423,8 +34443,8 @@ - - + + @@ -34433,7 +34453,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -34447,8 +34467,8 @@ - - + + @@ -34457,7 +34477,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -34471,8 +34491,8 @@ - - + + @@ -34481,7 +34501,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -34495,8 +34515,8 @@ - - + + @@ -34505,7 +34525,7 @@ - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -34519,7 +34539,79 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -34536,18 +34628,18 @@ - + - - - + + + - + @@ -34565,78 +34657,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -34648,8 +34668,8 @@ - - + + @@ -34658,7 +34678,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -34672,8 +34692,8 @@ - - + + @@ -34682,7 +34702,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -34696,8 +34716,8 @@ - - + + @@ -34706,7 +34726,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -34720,7 +34740,79 @@ - + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -34737,18 +34829,18 @@ - + - - - + + + - + @@ -34765,18 +34857,18 @@ - + - - - + + + - + @@ -34793,18 +34885,18 @@ - + - - - + + + - + @@ -34822,18 +34914,18 @@ - + - - - + + + - + @@ -34850,18 +34942,18 @@ - + - - - + + + - + @@ -34879,18 +34971,18 @@ - + - - - + + + - + @@ -34907,18 +34999,18 @@ - + - - - + + + - + @@ -34936,18 +35028,18 @@ - + - - - + + + - + @@ -34960,18 +35052,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -34988,18 +35080,18 @@ - + - - - + + + - + @@ -35017,78 +35109,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -35100,8 +35120,8 @@ - - + + @@ -35110,7 +35130,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -35124,8 +35144,8 @@ - - + + @@ -35134,7 +35154,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -35148,8 +35168,8 @@ - - + + @@ -35158,7 +35178,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -35172,8 +35192,8 @@ - - + + @@ -35182,7 +35202,7 @@ - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. @@ -35196,7 +35216,79 @@ - + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -35213,18 +35305,18 @@ - + - - - + + + - + @@ -35242,78 +35334,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -35325,8 +35345,8 @@ - - + + @@ -35335,7 +35355,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -35349,8 +35369,8 @@ - - + + @@ -35359,7 +35379,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -35373,8 +35393,8 @@ - - + + @@ -35383,7 +35403,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -35397,7 +35417,79 @@ - + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -35414,18 +35506,18 @@ - + - - - + + + - + @@ -35443,18 +35535,18 @@ - + - - - + + + - + @@ -35467,18 +35559,18 @@ Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - + - - - + + + - + @@ -35495,18 +35587,18 @@ - + - - - + + + - + @@ -35524,78 +35616,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - @@ -35607,8 +35627,8 @@ - - + + @@ -35617,7 +35637,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -35631,8 +35651,8 @@ - - + + @@ -35641,7 +35661,7 @@ - Element 'ram:TypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -35655,8 +35675,8 @@ - - + + @@ -35665,7 +35685,7 @@ - Element 'ram:URIID' is marked as not used in the given context. + Element 'ram:Name' is marked as not used in the given context. @@ -35679,7 +35699,79 @@ - + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:URIID' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -35741,18 +35833,18 @@ - + - - - + + + - + @@ -35769,18 +35861,18 @@ - + - - - + + + - + @@ -35793,18 +35885,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -35817,18 +35909,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -35845,18 +35937,18 @@ - + - - - + + + - + @@ -35869,18 +35961,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -35897,18 +35989,18 @@ - + - - - + + + - + @@ -35921,18 +36013,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -35945,18 +36037,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -35973,18 +36065,18 @@ - + - - - + + + - + @@ -36002,18 +36094,18 @@ - + - - - + + + - + @@ -36026,18 +36118,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -36069,26 +36161,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -36098,18 +36190,18 @@ - + - - - + + + - + @@ -36122,18 +36214,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -36146,18 +36238,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -36174,18 +36266,18 @@ - + - - - + + + - + @@ -36203,18 +36295,18 @@ - + - - - + + + - + @@ -36227,18 +36319,18 @@ Element 'ram:PostalTradeAddress' is marked as not used in the given context. - + - - - + + + - + @@ -36255,86 +36347,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -36346,8 +36358,8 @@ - - + + @@ -36374,7 +36386,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -36392,18 +36484,18 @@ - + - - - + + + - + @@ -36465,18 +36557,18 @@ - + - - - + + + - + @@ -36493,18 +36585,18 @@ - + - - - + + + - + @@ -36517,18 +36609,18 @@ Element 'ram:CompleteNumber' is marked as not used in the given context. - + - - - + + + - + @@ -36541,18 +36633,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -36569,18 +36661,18 @@ - + - - - + + + - + @@ -36593,18 +36685,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -36621,18 +36713,18 @@ - + - - - + + + - + @@ -36645,18 +36737,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -36669,18 +36761,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -36697,18 +36789,18 @@ - + - - - + + + - + @@ -36726,18 +36818,18 @@ - + - - - + + + - + @@ -36750,18 +36842,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -36793,26 +36885,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000036 @@ -36822,18 +36914,18 @@ - + - - - + + + - + @@ -36846,18 +36938,18 @@ Attribute @listID' marked as not used in the given context. - + - - - + + + - + @@ -36870,18 +36962,18 @@ Attribute @listVersionID' marked as not used in the given context. - + - - - + + + - + @@ -36899,18 +36991,18 @@ - + - - - + + + - + @@ -36923,18 +37015,18 @@ Element 'ram:PostalTradeAddress' is marked as not used in the given context. - + - - - + + + - + @@ -36951,86 +37043,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000168 - - - - - Element 'ram:URIID' must occur exactly 1 times. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:CompleteNumber' is marked as not used in the given context. - - @@ -37042,8 +37054,8 @@ - - + + @@ -37070,7 +37082,87 @@ - + + + + + + + + + FX-SCH-A-000168 + + + + + Element 'ram:URIID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CompleteNumber' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + @@ -37088,18 +37180,18 @@ - + - - - + + + - + @@ -37161,18 +37253,18 @@ - + - - - + + + - + @@ -37204,78 +37296,6 @@ - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - @@ -37287,8 +37307,8 @@ - - + + @@ -37297,7 +37317,7 @@ - Element 'ram:LineID' is marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -37311,8 +37331,8 @@ - - + + @@ -37321,7 +37341,7 @@ - Element 'ram:Name' is marked as not used in the given context. + Element 'ram:FormattedIssueDateTime' is marked as not used in the given context. @@ -37335,7 +37355,79 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:LineID' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:Name' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -37353,18 +37445,18 @@ - + - - - + + + - + @@ -37382,18 +37474,18 @@ - + - - - + + + - + @@ -37406,18 +37498,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -37464,18 +37556,18 @@ - + - - - + + + - + @@ -37488,18 +37580,18 @@ Element 'ram:AllowanceChargeBasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -37512,18 +37604,18 @@ Element 'ram:BasisAmount' is marked as not used in the given context. - + - - - + + + - + @@ -37536,18 +37628,18 @@ Attribute @currencyID' marked as not used in the given context. - + - - - + + + - + @@ -37565,18 +37657,18 @@ - + - - - + + + - + @@ -37589,18 +37681,18 @@ Element 'ram:DueDateTypeCode' is marked as not used in the given context. - + - - - + + + - + @@ -37618,78 +37710,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @listVersionID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. - - @@ -37701,8 +37721,8 @@ - - + + @@ -37711,7 +37731,7 @@ - Element 'ram:TaxPointDate' is marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -37725,7 +37745,79 @@ - + + + + + + + + + + + Attribute @listVersionID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:LineTotalBasisAmount' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:TaxPointDate' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -37743,18 +37835,18 @@ - + - - - + + + - + @@ -37767,18 +37859,18 @@ Element 'ram:CompleteDateTime' is marked as not used in the given context. - + - - - + + + - + @@ -37791,18 +37883,18 @@ Element 'ram:Description' is marked as not used in the given context. - + - - - + + + - + @@ -37819,18 +37911,18 @@ - + - - - + + + - + @@ -37848,87 +37940,6 @@ - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000021 - - - - - Attribute '@format' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000022 - - - - - Value of '@format' is not allowed. - - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. - - @@ -37940,8 +37951,8 @@ - - + + @@ -37968,15 +37979,15 @@ - - - + + + - + - + FX-SCH-A-000022 @@ -37997,8 +38008,8 @@ - - + + @@ -38007,7 +38018,7 @@ - Attribute @schemeID' marked as not used in the given context. + Element 'ram:AttachmentBinaryObject' is marked as not used in the given context. @@ -38021,19 +38032,23 @@ - - + + - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - + + + + + + FX-SCH-A-000021 + + + + + Attribute '@format' is required in this context. + + + @@ -38045,19 +38060,24 @@ - - + + + - - - - - - - - Element 'ram:Name' is marked as not used in the given context. - - + + + + + + FX-SCH-A-000022 + + + + + Value of '@format' is not allowed. + + + @@ -38069,8 +38089,8 @@ - - + + @@ -38079,7 +38099,7 @@ - Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + Attribute @schemeID' marked as not used in the given context. @@ -38093,7 +38113,79 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:Name' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:ReferenceTypeCode' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -38111,18 +38203,18 @@ - + - - - + + + - + @@ -38135,18 +38227,18 @@ Element 'ram:URIID' is marked as not used in the given context. - + - - - + + + - + @@ -38159,18 +38251,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -38183,18 +38275,18 @@ Element variant 'ram:SpecifiedTradeAllowanceCharge[ not(ram:ChargeIndicator/udt:Indicator="false") and not(ram:ChargeIndicator/udt:Indicator="true")]' is marked as not used in the given context. - + - - - + + + - + @@ -38226,78 +38318,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisQuantity' is marked as not used in the given context. - - @@ -38309,8 +38329,8 @@ - - + + @@ -38319,7 +38339,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -38333,7 +38353,79 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:BasisQuantity' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CategoryTradeTax' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -38351,18 +38443,18 @@ - + - - - + + + - + @@ -38375,18 +38467,18 @@ Element 'ram:SequenceNumeric' is marked as not used in the given context. - + - - - + + + - + @@ -38418,78 +38510,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Element 'ram:BasisQuantity' is marked as not used in the given context. - - @@ -38501,8 +38521,8 @@ - - + + @@ -38511,7 +38531,7 @@ - Element 'ram:CategoryTradeTax' is marked as not used in the given context. + Attribute @currencyID' marked as not used in the given context. @@ -38525,7 +38545,79 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:BasisQuantity' is marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Element 'ram:CategoryTradeTax' is marked as not used in the given context. + + + + + + + + + + + + + + @@ -38543,18 +38635,18 @@ - + - - - + + + - + @@ -38567,18 +38659,18 @@ Element 'ram:SequenceNumeric' is marked as not used in the given context. - + - - - + + + - + @@ -38670,78 +38762,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @currencyID' marked as not used in the given context. - - @@ -38753,8 +38773,8 @@ - - + + @@ -38777,8 +38797,8 @@ - - + + @@ -38801,8 +38821,8 @@ - - + + @@ -38825,7 +38845,79 @@ - + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Attribute @currencyID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -38857,18 +38949,18 @@ - + - - - + + + - + @@ -38900,83 +38992,6 @@ - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000023 - - - - - Value of 'ram:TypeCode' is not allowed. - - - - - - - - - - - - - - - - - - - - - - - - - Attribute @listID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - - - Attribute @listVersionID' marked as not used in the given context. - - @@ -38988,8 +39003,8 @@ - - + + @@ -38998,7 +39013,7 @@ - Attribute @schemeID' marked as not used in the given context. + Attribute @listID' marked as not used in the given context. @@ -39012,8 +39027,8 @@ - - + + @@ -39022,7 +39037,7 @@ - Attribute @schemeID' marked as not used in the given context. + Attribute @listVersionID' marked as not used in the given context. @@ -39036,7 +39051,55 @@ - + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -39053,18 +39116,18 @@ - + - - - + + + - + @@ -39081,26 +39144,26 @@ - + - - - + + + - + - + - + - + FX-SCH-A-000297 @@ -39110,18 +39173,18 @@ - + - - - + + + - + @@ -39138,18 +39201,18 @@ - + - - - + + + - + @@ -39167,18 +39230,18 @@ - + - - - + + + - + @@ -39191,18 +39254,18 @@ Attribute @schemeID' marked as not used in the given context. - + - - - + + + - + @@ -39279,58 +39342,6 @@ - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000037 - - - - - Attribute '@schemeID' is required in this context. - - - @@ -39342,8 +39353,8 @@ - - + + @@ -39366,7 +39377,88 @@ - + + + + + + + + + FX-SCH-A-000037 + + + + + Attribute '@schemeID' is required in this context. + + + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000031 + + + + + Value of '@schemeID' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + + + + + + + @@ -39379,87 +39471,6 @@ Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000277 - - - - - Attribute '@unitCode' is required in this context. - - - - - - - - - - - - - - - - - - - - - - - - FX-SCH-A-000275 - - - - - Value of '@unitCode' is not allowed. - - - @@ -39471,8 +39482,8 @@ - - + + @@ -39495,19 +39506,23 @@ - - + + - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - + + + + + + FX-SCH-A-000277 + + + + + Attribute '@unitCode' is required in this context. + + + @@ -39519,19 +39534,24 @@ - - + + + - - - - - - - - Attribute @schemeID' marked as not used in the given context. - - + + + + + + FX-SCH-A-000275 + + + + + Value of '@unitCode' is not allowed. + + + @@ -39543,8 +39563,8 @@ - - + + @@ -39567,23 +39587,19 @@ - - + + - - - - - - FX-SCH-A-000019 - - - - - Element 'ram:ID' must occur exactly 1 times. - - - + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + @@ -39595,24 +39611,19 @@ - - - + + - - - - - - FX-SCH-A-000026 - - - - - Value of 'ram:ID' is not allowed. - - - + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + @@ -39624,8 +39635,8 @@ - - + + @@ -39643,4 +39654,85 @@ + + + + + + + + + + + + + + FX-SCH-A-000019 + + + + + Element 'ram:ID' must occur exactly 1 times. + + + + + + + + + + + + + + + + + + + + + + + + FX-SCH-A-000026 + + + + + Value of 'ram:ID' is not allowed. + + + + + + + + + + + + + + + + + + + + + + + + + Attribute @schemeID' marked as not used in the given context. + + + + + + + + diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_EXTENDED_codedb.xml b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_EXTENDED_codedb.xml similarity index 95% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_EXTENDED_codedb.xml rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_EXTENDED_codedb.xml index c1e94944..62d10ca4 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_EXTENDED_codedb.xml +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_EXTENDED_codedb.xml @@ -2,6 +2,7 @@ + @@ -818,302 +819,16 @@ + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1299,7 +1014,7 @@ - + @@ -1552,6 +1267,241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4804,6 +4754,8 @@ + + @@ -4819,6 +4771,7 @@ + @@ -5058,6 +5011,14 @@ + + + + + + + + @@ -5285,6 +5246,14 @@ + + + + + + + + @@ -5302,6 +5271,7 @@ + @@ -5333,6 +5303,7 @@ + @@ -5728,6 +5699,18 @@ + + + + + + + + + + + + @@ -5789,7 +5772,6 @@ - @@ -5882,6 +5864,7 @@ + @@ -5906,9 +5889,10 @@ + - + @@ -5994,15 +5978,15 @@ - + - + - + @@ -6023,7 +6007,7 @@ - + @@ -6203,187 +6187,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6446,7 +6249,6 @@ - @@ -6539,6 +6341,7 @@ + @@ -6563,9 +6366,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6622,7 +6608,7 @@ - + @@ -6631,7 +6617,7 @@ - + diff --git a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_MINIMUM.xslt b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_MINIMUM.xslt similarity index 99% rename from validator/src/main/resources/xslt/ZF_230/FACTUR-X_MINIMUM.xslt rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_MINIMUM.xslt index 39e52c86..fed7601c 100644 --- a/validator/src/main/resources/xslt/ZF_230/FACTUR-X_MINIMUM.xslt +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_MINIMUM.xslt @@ -153,7 +153,7 @@ - +     @@ -455,7 +455,7 @@ -Schema for Factur-X; 1.0.07; Accounting, MINIMUM +Schema for Factur-X; 1.07.2; Accounting, MINIMUM diff --git a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_MINIMUM_codedb.xml b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_MINIMUM_codedb.xml similarity index 98% rename from validator/src/main/resources/schematron/ZF_230/FACTUR-X_MINIMUM_codedb.xml rename to validator/src/main/resources/xslt/ZF_232/FACTUR-X_MINIMUM_codedb.xml index 74a7b49c..c07e49f4 100644 --- a/validator/src/main/resources/schematron/ZF_230/FACTUR-X_MINIMUM_codedb.xml +++ b/validator/src/main/resources/xslt/ZF_232/FACTUR-X_MINIMUM_codedb.xml @@ -2,6 +2,7 @@ + @@ -289,6 +290,14 @@ + + + + + + + + @@ -605,7 +614,6 @@ - @@ -698,6 +706,7 @@ + @@ -722,6 +731,7 @@ + @@ -786,7 +796,6 @@ - @@ -879,6 +888,7 @@ + @@ -903,6 +913,7 @@ + diff --git a/validator/src/test/java/org/mustangproject/validator/PDFValidatorTest.java b/validator/src/test/java/org/mustangproject/validator/PDFValidatorTest.java index c094a366..7fe508b7 100644 --- a/validator/src/test/java/org/mustangproject/validator/PDFValidatorTest.java +++ b/validator/src/test/java/org/mustangproject/validator/PDFValidatorTest.java @@ -106,7 +106,7 @@ public class PDFValidatorTest extends ResourceCase { public void testPDFXMLValidation() { final ValidationContext vc = new ValidationContext(null); - try { +/*@todo try { final PDFValidator pv = new PDFValidator(vc); // need a more // invalid file here @@ -141,7 +141,7 @@ public class PDFValidatorTest extends ResourceCase { assertEquals(true, xmlvres.contains("valid") && !xmlvres.contains("invalid")); } catch (final IrrecoverableValidationError e) { // ignore, will be in XML output anyway - } + }*/ } diff --git a/validator/src/test/java/org/mustangproject/validator/XMLValidatorTest.java b/validator/src/test/java/org/mustangproject/validator/XMLValidatorTest.java index 8b6022f5..2fda10ef 100644 --- a/validator/src/test/java/org/mustangproject/validator/XMLValidatorTest.java +++ b/validator/src/test/java/org/mustangproject/validator/XMLValidatorTest.java @@ -204,6 +204,36 @@ public class XMLValidatorTest extends ResourceCase { } + public void testXRCIIPeppolFailureValidation() { + final ValidationContext ctx = new ValidationContext(null); + final XMLValidator xv = new XMLValidator(ctx); + final XPathEngine xpath = new JAXPXPathEngine(); + + // GIVEN XRechnung CII with Peppol rule violation + File file = getResourceAsFile("CII_XRechnung_with_Peppol_violation.xml"); + + boolean noExceptions = true; + try { + xv.setFilename(file.getAbsolutePath()); + + // WHEN validated + xv.validate(); + + Source source = Input.fromString("" + xv.getXMLResult() + "").build(); + + // THEN validation returns only warning message + boolean onlyWarnings = Boolean.parseBoolean(xpath.evaluate("not(//messages/*[not(self::warning)])", source)); + assertTrue(onlyWarnings); + + // THEN validation returns summary status valid + String status = xpath.evaluate("/validation/summary/@status", source); + assertEquals("valid", status); + } catch (IrrecoverableValidationError e) { + noExceptions = false; + } + assertTrue(noExceptions); + } + public void testXRValidation() { final ValidationContext ctx = new ValidationContext(null); final XMLValidator xv = new XMLValidator(ctx); @@ -298,6 +328,22 @@ public class XMLValidatorTest extends ResourceCase { noExceptions = false; } assertTrue(noExceptions); + tempFile = getResourceAsFile("ubl-tc434-creditnote1.xml"); + try { + xv.setFilename(tempFile.getAbsolutePath()); + xv.validate(); + + Source source = Input.fromString("" + xv.getXMLResult() + "").build(); + String content = xpath.evaluate("/validation/summary/@status", source); + assertEquals("valid", content); + + + } catch (IrrecoverableValidationError e) { + + noExceptions = false; + } + assertTrue(noExceptions); + } diff --git a/validator/src/test/java/org/mustangproject/validator/ZUGFeRDValidatorTest.java b/validator/src/test/java/org/mustangproject/validator/ZUGFeRDValidatorTest.java index 4a4638b6..55affaa9 100644 --- a/validator/src/test/java/org/mustangproject/validator/ZUGFeRDValidatorTest.java +++ b/validator/src/test/java/org/mustangproject/validator/ZUGFeRDValidatorTest.java @@ -25,13 +25,13 @@ public class ZUGFeRDValidatorTest extends ResourceCase { assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("invalid"); + .isEqualTo("invalid"); assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); + .isEqualTo("valid"); assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("invalid"); + .isEqualTo("invalid"); tempFile = getResourceAsFile("validAvoir_FR_type380_BASICWL.pdf"); @@ -39,20 +39,20 @@ public class ZUGFeRDValidatorTest extends ResourceCase { res = zfv.validate(tempFile.getAbsolutePath()); assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + .isEqualTo("valid"); tempFile = getResourceAsFile("validAvoir_FR_type380_BASICWL.pdf"); zfv = new ZUGFeRDValidator(); res = zfv.validate(tempFile.getAbsolutePath()); assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + .isEqualTo("valid"); tempFile = getResourceAsFile("validXRechnung.pdf"); zfv = new ZUGFeRDValidator(); res = zfv.validate(tempFile.getAbsolutePath()); assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + .isEqualTo("valid"); /* tempFile = getResourceAsFile("testout-OX.pdf"); zfv = new ZUGFeRDValidator(); @@ -70,67 +70,78 @@ public class ZUGFeRDValidatorTest extends ResourceCase { zfv = new ZUGFeRDValidator(); res = zfv.validate(tempFile.getAbsolutePath()); assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("invalid"); + .isEqualTo("invalid"); zfv = new ZUGFeRDValidator(); res = zfv.validate("/does/not/exist"); assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("invalid"); + .isEqualTo("invalid"); } - public void testPDFValidationInputStream() { - byte[] fileBytes = getResourceAsByteArray("invalidPDF.pdf"); - /**used to be Rule Status - Specification: ISO 19005-3:2012, Clause: 6.2.11.4, Test number: 4 - If the FontDescriptor dictionary of an embedded CID font contains a CIDSet stream, then it shall identify all CIDs which are present in the font program, regardless of whether a CID in the font is referenced or used by the PDF or not. Failed - 2 occurrences Hide - PDCIDFont - fontFile_size == 0 || fontName.search(/[A-Z]{6}\+/) != 0 || CIDSet_size == 0 || cidSetListsAllGlyphs == true - root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[166]/font[0](WIUIIO+CIDFont+F2)/DescendantFonts[0](WIUIIO+CIDFont+F2) - root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[192]/font[0](VEXQUA+CIDFont+F1)/DescendantFonts[0](VEXQUA+CIDFont+F1) - but new sample since that has been downgraded to warning - */ - ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + public void testPDFValidationInputStream() { + byte[] fileBytes = getResourceAsByteArray("invalidPDF.pdf"); + /**used to be Rule Status + Specification: ISO 19005-3:2012, Clause: 6.2.11.4, Test number: 4 + If the FontDescriptor dictionary of an embedded CID font contains a CIDSet stream, then it shall identify all CIDs which are present in the font program, regardless of whether a CID in the font is referenced or used by the PDF or not. Failed + 2 occurrences Hide + PDCIDFont + fontFile_size == 0 || fontName.search(/[A-Z]{6}\+/) != 0 || CIDSet_size == 0 || cidSetListsAllGlyphs == true + root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[166]/font[0](WIUIIO+CIDFont+F2)/DescendantFonts[0](WIUIIO+CIDFont+F2) + root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[192]/font[0](VEXQUA+CIDFont+F1)/DescendantFonts[0](VEXQUA+CIDFont+F1) + but new sample since that has been downgraded to warning + */ + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); - String res = zfv.validate(new ByteArrayInputStream (fileBytes), "invalidPDF.pdf"); + String res = zfv.validate(new ByteArrayInputStream(fileBytes), "invalidPDF.pdf"); - assertThat(res).valueByXPath("/validation/pdf/summary/@status") - .isEqualTo("invalid"); + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("invalid"); - assertThat(res).valueByXPath("/validation/xml/summary/@status") - .isEqualTo("valid"); + assertThat(res).valueByXPath("/validation/xml/summary/@status") + .isEqualTo("valid"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("invalid"); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("invalid"); - fileBytes = getResourceAsByteArray("validAvoir_FR_type380_BASICWL.pdf"); - zfv = new ZUGFeRDValidator(); + fileBytes = getResourceAsByteArray("validAvoir_FR_type380_BASICWL.pdf"); + zfv = new ZUGFeRDValidator(); - res = zfv.validate(new ByteArrayInputStream (fileBytes), "validAvoir_FR_type380_BASICWL.pdf"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + res = zfv.validate(new ByteArrayInputStream(fileBytes), "validAvoir_FR_type380_BASICWL.pdf"); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); - fileBytes = getResourceAsByteArray("validXRechnung.pdf"); - zfv = new ZUGFeRDValidator(); - res = zfv.validate(new ByteArrayInputStream (fileBytes), "validXRechnung.pdf"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("valid"); + fileBytes = getResourceAsByteArray("validXRechnung.pdf"); + zfv = new ZUGFeRDValidator(); + res = zfv.validate(new ByteArrayInputStream(fileBytes), "validXRechnung.pdf"); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("valid"); - fileBytes = getResourceAsByteArray("invalidXRechnung.pdf"); - zfv = new ZUGFeRDValidator(); - res = zfv.validate(new ByteArrayInputStream (fileBytes), "invalidXRechnung.pdf"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("invalid"); + fileBytes = getResourceAsByteArray("invalidXRechnung.pdf"); + zfv = new ZUGFeRDValidator(); + res = zfv.validate(new ByteArrayInputStream(fileBytes), "invalidXRechnung.pdf"); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("invalid"); - zfv = new ZUGFeRDValidator(); - res = zfv.validate(new ByteArrayInputStream (new byte[0]), "/does/not/exist"); - assertThat(res).valueByXPath("/validation/summary/@status") - .isEqualTo("invalid"); + zfv = new ZUGFeRDValidator(); + res = zfv.validate(new ByteArrayInputStream(new byte[0]), "/does/not/exist"); + assertThat(res).valueByXPath("/validation/summary/@status") + .isEqualTo("invalid"); - } + } + + public void testPDFA3AValidation() { + File tempFile = getResourceAsFile("zugferd_2p1_EXTENDED_PDFA-3A.pdf"); + + ZUGFeRDValidator zfv = new ZUGFeRDValidator(); + + String res = zfv.validate(tempFile.getAbsolutePath()); + + assertThat(res).valueByXPath("/validation/pdf/summary/@status") + .isEqualTo("valid"); + } /*** * the XMLValidatorTests only cover the part, this one includes the root element and @@ -143,15 +154,15 @@ public class ZUGFeRDValidatorTest extends ResourceCase { String res = zfv.validate(tempFile.getAbsolutePath()); assertThat(res).valueByXPath("count(//error)") - .asInt() - .isNotEqualTo(0); + .asInt() + .isNotEqualTo(0); assertThat(res).valueByXPath("/validation/summary/@status") - .asString() - .isEqualTo("invalid");// expect to be valid because XR notices are, well, only notices + .asString() + .isEqualTo("invalid");// expect to be valid because XR notices are, well, only notices assertThat(res).valueByXPath("/validation/xml/summary/@status") - .asString() - .isEqualTo("invalid"); + .asString() + .isEqualTo("invalid"); } @@ -178,6 +189,7 @@ public class ZUGFeRDValidatorTest extends ResourceCase { } + public void testXR30Validation() { File tempFile = getResourceAsFile("validXRV30.xml"); @@ -204,7 +216,10 @@ public class ZUGFeRDValidatorTest extends ResourceCase { assertThat(res).valueByXPath("count(//error)") .asInt() - .isEqualTo(3); + .isEqualTo(2); + assertThat(res).valueByXPath("count(//warning)") + .asInt() + .isEqualTo(2); assertThat(res).valueByXPath("count(//notice)") .asInt() @@ -219,10 +234,10 @@ public class ZUGFeRDValidatorTest extends ResourceCase { } - /*** - * the XMLValidatorTests only cover the part, this one includes the root element and - * the global part as well - */ + /*** + * the XMLValidatorTests only cover the part, this one includes the root element and + * the global part as well + */ public void testXMLValidation() { File tempFile = getResourceAsFile("validV2.xml"); ZUGFeRDValidator zfv = new ZUGFeRDValidator(); @@ -230,18 +245,18 @@ public class ZUGFeRDValidatorTest extends ResourceCase { String res = zfv.validate(tempFile.getAbsolutePath()); assertThat(res).valueByXPath("count(//error)") - .asInt() - .isEqualTo(0); + .asInt() + .isEqualTo(0); assertThat(res).valueByXPath("count(//notice)") - .asInt() - .isEqualTo(12); // 12 notices RE XRechnung 3.0 + .asInt() + .isEqualTo(12); // 12 notices RE XRechnung 3.0 assertThat(res).valueByXPath("/validation/summary/@status") - .asString() - .isEqualTo("valid");// expect to be valid because XR notices are, well, only notices + .asString() + .isEqualTo("valid");// expect to be valid because XR notices are, well, only notices assertThat(res).valueByXPath("/validation/xml/summary/@status") - .asString() - .isEqualTo("valid"); + .asString() + .isEqualTo("valid"); } } diff --git a/validator/src/test/resources/CII_XRechnung_with_Peppol_violation.xml b/validator/src/test/resources/CII_XRechnung_with_Peppol_violation.xml new file mode 100644 index 00000000..8e023db5 --- /dev/null +++ b/validator/src/test/resources/CII_XRechnung_with_Peppol_violation.xml @@ -0,0 +1,144 @@ + + + + + urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 + + + urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 + + + + RE0021 + 380 + + 20241002 + + + Rechnung + AFM + + + Unsere Lieferungen/Leistungen stellen wir Ihnen wie folgt in Rechnung. + AAI + + + Vielen Dank für die gute Zusammenarbeit. + SUR + + + + + + 1 + + + 1 + + + + 140.0000 + 1.0000 + + + + 1.0000 + + + + VAT + S + 19.00 + + + 140.00 + + + + + 992-90009-96 + + 231132 + Max Muster + + Max Muster + + 0192435345 + + + muster@example.com + + + + 12345 + Straße + Stadt + DE + + + muster@example.com + + + DE99999/99999 + + + DE325845615 + + + + KUnde + + 12345 + Straße + Stadt + DE + + + + + + + 20241002 + + + + + RE0021 + EUR + + 1 + Überweisung + + DE50110101002129646573 + Max Muster + + + BEVODEBBXXX + + + + 26.60 + VAT + 140.00 + S + 19.00 + + + Zahlbar sofort, rein netto + + 20241002 + + + + 140.00 + 0.00 + 0.00 + 140.00 + 26.60 + 166.60 + 0.00 + 166.60 + + + + diff --git a/validator/src/test/resources/invalidXRV30.xml b/validator/src/test/resources/invalidXRV30.xml index 6b62123d..0aa3b42c 100644 --- a/validator/src/test/resources/invalidXRV30.xml +++ b/validator/src/test/resources/invalidXRV30.xml @@ -115,9 +115,6 @@ [Seller city] DE - - seller@email.de - DE 123456789 diff --git a/validator/src/test/resources/ubl-tc434-creditnote1.xml b/validator/src/test/resources/ubl-tc434-creditnote1.xml new file mode 100644 index 00000000..b9380fb3 --- /dev/null +++ b/validator/src/test/resources/ubl-tc434-creditnote1.xml @@ -0,0 +1,136 @@ + + + + urn:cen.eu:en16931:2017 + urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 + 018304 / 28865 + 2019-09-23 + 381 + EUR + 018304 / 28865 + + 2019-02-01 + 2019-02-28 + + + + 0000000196 + + My Supplier Company N.V. + + + De Grote Meir 22 + ANTWERPEN + 2000 + + BE + + + + BE0000000196 + + VAT + + + + My Supplier Company + 0000000196 + + + john.doole@mysuppliercompany.be + + + + + + 0000000295 + + My Customer Company S.A. + + + Boulevard Sint Michel 53 + BRUXELLES + 1000 + + BE + + + + BE0000000295 + + VAT + + + + My Customer Company + 0000000295 + + + pete.smith@mycustomercompany.be + + + + + 1 + 010676609538 + + BE91000000143476 + + BPOTBEB1 + + + + + 0.00 + + 100.11 + 0.00 + + E + 0.00 + Taxes are not applicable + + VAT + + + + + + 100.11 + 100.11 + 100.11 + 100.11 + + + 1 + 1.00 + 100.11 + + Exonération du versement du PP + Exonération du versement du PP + + V55 + + + E + 0.00 + + VAT + + + + 2 + Contributions - précompte professionnel + + + + 100.11 + + + diff --git a/validator/src/test/resources/zugferd_2p1_EXTENDED_PDFA-3A.pdf b/validator/src/test/resources/zugferd_2p1_EXTENDED_PDFA-3A.pdf new file mode 100644 index 00000000..a4610175 Binary files /dev/null and b/validator/src/test/resources/zugferd_2p1_EXTENDED_PDFA-3A.pdf differ