Merge pull request #901 from danielluckas-rse/code-quality-enhancements-part-2
Enhance code quality - part 2
This commit is contained in:
@@ -218,7 +218,7 @@ public class Main {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.error(e.getMessage(), e);
|
LOGGER.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
if (!selectedAnswer.equals("Y") && !selectedAnswer.equals("y")) {
|
if (!"Y".equalsIgnoreCase(selectedAnswer)) {
|
||||||
System.err.println("Aborted by user");
|
System.err.println("Aborted by user");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
@@ -653,9 +653,9 @@ public class Main {
|
|||||||
|
|
||||||
if (zfProfile == null) {
|
if (zfProfile == null) {
|
||||||
try {
|
try {
|
||||||
if ((format.equals("zf") && (zfIntVersion == 1)) || (format.equals("ox"))) {
|
if ((("zf".equals(format)) && (zfIntVersion == 1)) || ("ox".equals(format))) {
|
||||||
zfProfile = getStringFromUser("Profile (b)asic, (c)omfort or ex(t)ended", "t", "B|b|C|c|T|t");
|
zfProfile = getStringFromUser("Profile (b)asic, (c)omfort or ex(t)ended", "t", "B|b|C|c|T|t");
|
||||||
} else if ((format.equals("da"))) {
|
} else if (("da".equals(format))) {
|
||||||
zfProfile = getStringFromUser("Profile (p)ilot", "p", "P|p");
|
zfProfile = getStringFromUser("Profile (p)ilot", "p", "P|p");
|
||||||
} else {
|
} else {
|
||||||
zfProfile = getStringFromUser(
|
zfProfile = getStringFromUser(
|
||||||
@@ -676,20 +676,20 @@ public class Main {
|
|||||||
ensureFileExists(xmlName);
|
ensureFileExists(xmlName);
|
||||||
ensureFileNotExists(outName);
|
ensureFileNotExists(outName);
|
||||||
|
|
||||||
if ((format.equals("fx")) && (zfIntVersion > 1)) {
|
if ((("fx".equals(format))) && (zfIntVersion > 1)) {
|
||||||
throw new Exception("Factur-X is only available in version 1 (roughly corresponding to ZF2)");
|
throw new Exception("Factur-X is only available in version 1 (roughly corresponding to ZF2)");
|
||||||
}
|
}
|
||||||
|
|
||||||
EStandard standard = EStandard.facturx;
|
EStandard standard = EStandard.facturx;
|
||||||
if (format.equals("zf")) {
|
if ("zf".equals(format)) {
|
||||||
standard = EStandard.zugferd;
|
standard = EStandard.zugferd;
|
||||||
}
|
}
|
||||||
if (format.equals("da")) {
|
if ("da".equals(format)) {
|
||||||
standard = EStandard.despatchadvice;
|
standard = EStandard.despatchadvice;
|
||||||
|
|
||||||
zfConformanceLevelProfile = Profiles.getByName(standard, "PILOT", 1);
|
zfConformanceLevelProfile = Profiles.getByName(standard, "PILOT", 1);
|
||||||
} else if (((format.equals("zf")) && (zfIntVersion == 1)) || (format.equals("ox"))) {
|
} else if (((("zf".equals(format))) && (zfIntVersion == 1)) || ("ox".equals(format))) {
|
||||||
if (format.equals("ox")) {
|
if ("ox".equals(format)) {
|
||||||
standard = EStandard.orderx;
|
standard = EStandard.orderx;
|
||||||
}
|
}
|
||||||
if (zfProfile.equals("b")) {
|
if (zfProfile.equals("b")) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
|||||||
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact;
|
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* a named contact person in an organisation
|
* a named contact person in an organisation
|
||||||
@@ -111,50 +112,52 @@ public class Contact implements IZUGFeRDExportableContact {
|
|||||||
for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) {
|
for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) {
|
||||||
//nodes.item(i).getTextContent())) {
|
//nodes.item(i).getTextContent())) {
|
||||||
Node currentItemNode = nodes.item(nodeIndex);
|
Node currentItemNode = nodes.item(nodeIndex);
|
||||||
if (currentItemNode.getLocalName() != null) {
|
String localName = currentItemNode.getLocalName();
|
||||||
|
if (localName != null) {
|
||||||
|
|
||||||
if (currentItemNode.getLocalName().equals("PersonName")/*CII*/||currentItemNode.getLocalName().equals("Name")/*UBL*/) {
|
Set<String> nameElements = Set.of("PersonName"/*CII*/, "Name"/*UBL*/);
|
||||||
if (currentItemNode.getFirstChild()!=null) {
|
if (localName != null && nameElements.contains(localName)
|
||||||
|
&& currentItemNode.getFirstChild()!=null) {
|
||||||
setName(currentItemNode.getFirstChild().getNodeValue());
|
setName(currentItemNode.getFirstChild().getNodeValue());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (currentItemNode.getLocalName().equals("TelephoneUniversalCommunication")) { /*CII*/
|
if (localName.equals("TelephoneUniversalCommunication")) { /*CII*/
|
||||||
NodeList tel = currentItemNode.getChildNodes();
|
NodeList tel = currentItemNode.getChildNodes();
|
||||||
for (int telChildIndex = 0; telChildIndex < tel.getLength(); telChildIndex++) {
|
for (int telChildIndex = 0; telChildIndex < tel.getLength(); telChildIndex++) {
|
||||||
if (tel.item(telChildIndex).getLocalName() != null) {
|
String telLocalName = tel.item(telChildIndex).getLocalName();
|
||||||
if (tel.item(telChildIndex).getLocalName().equals("CompleteNumber")) {
|
if (telLocalName != null && telLocalName.equals("CompleteNumber")) {
|
||||||
setPhone(tel.item(telChildIndex).getTextContent());
|
setPhone(tel.item(telChildIndex).getTextContent());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (currentItemNode.getLocalName().equals("Telephone")) { /* UBL */
|
} else if (localName.equals("Telephone")) { /* UBL */
|
||||||
setPhone(currentItemNode.getTextContent());
|
setPhone(currentItemNode.getTextContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
// CII: only for Extended profile
|
// CII: only for Extended profile
|
||||||
if (currentItemNode.getLocalName().equals("FaxUniversalCommunication")) { /* CII */
|
if (localName.equals("FaxUniversalCommunication")) { /* CII */
|
||||||
NodeList fax = currentItemNode.getChildNodes();
|
NodeList fax = currentItemNode.getChildNodes();
|
||||||
for (int faxChildIndex = 0; faxChildIndex < fax.getLength(); faxChildIndex++) {
|
for (int faxChildIndex = 0; faxChildIndex < fax.getLength(); faxChildIndex++) {
|
||||||
if (fax.item(faxChildIndex).getLocalName() != null) {
|
String faxLocalName = fax.item(faxChildIndex).getLocalName();
|
||||||
if (fax.item(faxChildIndex).getLocalName().equals("CompleteNumber")) {
|
if (faxLocalName != null && faxLocalName.equals("CompleteNumber")) {
|
||||||
setFax(fax.item(faxChildIndex).getTextContent());
|
setFax(fax.item(faxChildIndex).getTextContent());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (currentItemNode.getLocalName().equals("Telefax")) { /* UBL */
|
} else if (localName.equals("Telefax")) { /* UBL */
|
||||||
setFax(currentItemNode.getTextContent());
|
setFax(currentItemNode.getTextContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentItemNode.getLocalName().equals("EmailURIUniversalCommunication")) { /* CII */
|
if (localName.equals("EmailURIUniversalCommunication")) { /* CII */
|
||||||
NodeList email = currentItemNode.getChildNodes();
|
NodeList email = currentItemNode.getChildNodes();
|
||||||
for (int emailChildIndex = 0; emailChildIndex < email.getLength(); emailChildIndex++) {
|
for (int emailChildIndex = 0; emailChildIndex < email.getLength(); emailChildIndex++) {
|
||||||
if (email.item(emailChildIndex).getLocalName() != null) {
|
String emailLocalName = email.item(emailChildIndex).getLocalName();
|
||||||
if (email.item(emailChildIndex).getLocalName().equals("URIID")) {
|
if (emailLocalName != null && emailLocalName.equals("URIID")) {
|
||||||
setEMail(email.item(emailChildIndex).getTextContent());
|
setEMail(email.item(emailChildIndex).getTextContent());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (currentItemNode.getLocalName().equals("ElectronicMail")) { /* UBL */
|
} else if (localName.equals("ElectronicMail")) { /* UBL */
|
||||||
setEMail(currentItemNode.getTextContent());
|
setEMail(currentItemNode.getTextContent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package org.mustangproject;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -163,7 +163,9 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
|
|||||||
NodeList taxSchemechilds = partyTaxScheme.item(partyTaxSchemeIndex).getChildNodes();
|
NodeList taxSchemechilds = partyTaxScheme.item(partyTaxSchemeIndex).getChildNodes();
|
||||||
for (int taxSchemechildsIndex = 0; taxSchemechildsIndex < taxSchemechilds.getLength(); taxSchemechildsIndex++) {
|
for (int taxSchemechildsIndex = 0; taxSchemechildsIndex < taxSchemechilds.getLength(); taxSchemechildsIndex++) {
|
||||||
if (taxSchemechilds.item(taxSchemechildsIndex).getLocalName() != null) {
|
if (taxSchemechilds.item(taxSchemechildsIndex).getLocalName() != null) {
|
||||||
if (taxSchemechilds.item(taxSchemechildsIndex).getTextContent().equals("FC") || (taxSchemechilds.item(taxSchemechildsIndex).getTextContent().equals("NOVAT"))) {
|
Set<String> taxSchemeTypes = Set.of("FC", "NOVAT");
|
||||||
|
String textContent = taxSchemechilds.item(taxSchemechildsIndex).getTextContent();
|
||||||
|
if (textContent != null && taxSchemeTypes.contains(textContent)) {
|
||||||
setTaxID(CompanyId);
|
setTaxID(CompanyId);
|
||||||
} else {
|
} else {
|
||||||
setVATID(CompanyId);
|
setVATID(CompanyId);
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ public class Profile {
|
|||||||
* @return the XMP name string of the profile
|
* @return the XMP name string of the profile
|
||||||
*/
|
*/
|
||||||
public String getXMPName() {
|
public String getXMPName() {
|
||||||
if (name.equals("BASICWL")) {
|
if ("BASICWL".equals(name)) {
|
||||||
return "BASIC WL";
|
return "BASIC WL";
|
||||||
} else if (name.equals("EN16931")) {
|
} else if ("EN16931".equals(name)) {
|
||||||
return "EN 16931";
|
return "EN 16931";
|
||||||
} else {
|
} else {
|
||||||
return name;
|
return name;
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ import java.util.Arrays;
|
|||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
@@ -719,9 +719,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (DocumentCodeTypeConstants.CORRECTEDINVOICE.equals(trans.getDocumentCode())
|
if (trans.getDocumentCode() != null
|
||||||
|| DocumentCodeTypeConstants.CREDITNOTE.equals(trans.getDocumentCode())
|
&& Set.of(DocumentCodeTypeConstants.CORRECTEDINVOICE, DocumentCodeTypeConstants.CREDITNOTE).contains(trans.getDocumentCode())) {
|
||||||
) {
|
|
||||||
hasDueDate = false;
|
hasDueDate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
|
|||||||
* @return the filename of the file to be embedded
|
* @return the filename of the file to be embedded
|
||||||
*/
|
*/
|
||||||
public String getFilenameForVersion(int ver, Profile profile) {
|
public String getFilenameForVersion(int ver, Profile profile) {
|
||||||
if (profile.getName().equals("XRECHNUNG")) {
|
if ("XRECHNUNG".equals(profile.getName())) {
|
||||||
return "xrechnung.xml";
|
return "xrechnung.xml";
|
||||||
}
|
}
|
||||||
if (isFacturX) {
|
if (isFacturX) {
|
||||||
|
|||||||
@@ -606,7 +606,7 @@ public class ZUGFeRDInvoiceImporter {
|
|||||||
}
|
}
|
||||||
zpp.addNotes(includedNotes);
|
zpp.addNotes(includedNotes);
|
||||||
String rootNode = extractString("local-name(/*)");
|
String rootNode = extractString("local-name(/*)");
|
||||||
if (rootNode.equals("Invoice") || rootNode.equals("CreditNote")) {
|
if (rootNode != null && Set.of("Invoice", "CreditNote").contains(rootNode)) {
|
||||||
// UBL...
|
// UBL...
|
||||||
// //*[local-name()="Invoice" or local-name()="CreditNote"]
|
// //*[local-name()="Invoice" or local-name()="CreditNote"]
|
||||||
number = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"ID\"]").trim();
|
number = extractString("/*[local-name()=\"Invoice\" or local-name()=\"CreditNote\"]/*[local-name()=\"ID\"]").trim();
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import java.util.Arrays;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
@@ -41,6 +42,7 @@ import org.verapdf.processor.TaskType;
|
|||||||
import org.verapdf.processor.plugins.PluginsCollectionConfig;
|
import org.verapdf.processor.plugins.PluginsCollectionConfig;
|
||||||
import org.verapdf.processor.reports.ItemDetails;
|
import org.verapdf.processor.reports.ItemDetails;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
@@ -194,9 +196,9 @@ public class PDFValidator extends Validator {
|
|||||||
|
|
||||||
boolean documentTypeValid = false;
|
boolean documentTypeValid = false;
|
||||||
for (int i = 0; i < nodes.getLength(); i++) {
|
for (int i = 0; i < nodes.getLength(); i++) {
|
||||||
if (nodes.item(i).getTextContent().equals("INVOICE") || nodes.item(i).getTextContent().equals("ORDER")
|
Node item = nodes.item(i);
|
||||||
|| nodes.item(i).getTextContent().equals("ORDER_RESPONSE") || nodes.item(i).getTextContent()
|
String textContent = item.getTextContent();
|
||||||
.equals("ORDER_CHANGE")) {
|
if (textContent != null && Set.of("INVOICE", "ORDER", "ORDER_RESPONSE", "ORDER_CHANGE").contains(textContent)) {
|
||||||
documentTypeValid = true;
|
documentTypeValid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.xml.XMLConstants;
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
@@ -103,7 +104,7 @@ public class XMLValidator extends Validator {
|
|||||||
* @return true if semantically identical
|
* @return true if semantically identical
|
||||||
*/
|
*/
|
||||||
public static boolean matchesURI(String uri1, String uri2) {
|
public static boolean matchesURI(String uri1, String uri2) {
|
||||||
return (uri1.equals(uri2) || uri1.startsWith(uri2 + "#"));
|
return (uri1 != null && (uri2 != null && (uri1.equals(uri2) || uri1.startsWith(uri2 + "#"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -217,29 +218,35 @@ public class XMLValidator extends Validator {
|
|||||||
|
|
||||||
// urn:cen.eu:en16931:2017
|
// urn:cen.eu:en16931:2017
|
||||||
// urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:basic
|
// urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:basic
|
||||||
if (root.getLocalName().equalsIgnoreCase("SCRDMCCBDACIOMessageStructure")) {
|
String rootLocalName = root.getLocalName();
|
||||||
|
String contextProfile = context.getProfile();
|
||||||
|
if ("SCRDMCCBDACIOMessageStructure".equalsIgnoreCase(rootLocalName)) {
|
||||||
context.setGeneration("1");
|
context.setGeneration("1");
|
||||||
isOrderX = true;
|
isOrderX = true;
|
||||||
isBasic = context.getProfile().contains("basic");
|
isBasic = contextProfile.contains("basic");
|
||||||
isEN16931 = context.getProfile().contains("comfort");
|
isEN16931 = contextProfile.contains("comfort");
|
||||||
isExtended = context.getProfile().contains("extended");
|
isExtended = contextProfile.contains("extended");
|
||||||
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B.xsd", 99, EPart.ox);
|
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B.xsd", 99, EPart.ox);
|
||||||
xsltFilename = "/xslt/OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B_COMFORT.xslt";
|
xsltFilename = "/xslt/OX_10/comfort/SCRDMCCBDACIOMessageStructure_100pD20B_COMFORT.xslt";
|
||||||
|
|
||||||
} else if (root.getLocalName().equalsIgnoreCase("CrossIndustryInvoice")) { // ZUGFeRD 2.0 or Factur-X
|
} else if (root.getLocalName().equalsIgnoreCase("CrossIndustryInvoice")) { // ZUGFeRD 2.0 or Factur-X
|
||||||
context.setGeneration("2");
|
context.setGeneration("2");
|
||||||
|
|
||||||
isMiniumum = context.getProfile().contains("minimum");
|
isMiniumum = contextProfile.contains("minimum");
|
||||||
isBasic = context.getProfile().contains("basic");
|
isBasic = contextProfile.contains("basic");
|
||||||
isBasicWithoutLines = context.getProfile().contains("basicwl");
|
isBasicWithoutLines = contextProfile.contains("basicwl");
|
||||||
if (isBasicWithoutLines) {
|
if (isBasicWithoutLines) {
|
||||||
isBasic = false;// basicwl also contains the string basic...
|
isBasic = false;// basicwl also contains the string basic...
|
||||||
}
|
}
|
||||||
isEN16931 = matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931")
|
isEN16931 = Set.of(
|
||||||
|| matchesURI(context.getProfile(), "urn:cen.eu:en16931:2017");
|
"urn:cen.eu:en16931:2017:compliant:factur-x.eu:1p0:en16931",
|
||||||
|
"urn:cen.eu:en16931:2017"
|
||||||
|
)
|
||||||
|
.stream()
|
||||||
|
.anyMatch(profile -> matchesURI(contextProfile, profile));
|
||||||
|
|
||||||
isExtended = context.getProfile().contains("extended");
|
isExtended = contextProfile.contains("extended");
|
||||||
isXRechnung = context.getProfile().contains("xrechnung");
|
isXRechnung = contextProfile.contains("xrechnung");
|
||||||
|
|
||||||
if ((isExtended) || (isXRechnung)) {
|
if ((isExtended) || (isXRechnung)) {
|
||||||
isEN16931 = false;// the uri for extended is urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended and thus contains en16931...
|
isEN16931 = false;// the uri for extended is urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended and thus contains en16931...
|
||||||
@@ -281,13 +288,13 @@ public class XMLValidator extends Validator {
|
|||||||
// saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s
|
// saxon java net.sf.saxon.Transform -o tcdl2.0.tsdtf.sch.tmp.xsl -s
|
||||||
// tcdl2.0.tsdtf.sch iso_svrl.xsl
|
// tcdl2.0.tsdtf.sch iso_svrl.xsl
|
||||||
|
|
||||||
} else if (root.getLocalName().equalsIgnoreCase("Invoice") || root.getLocalName().equalsIgnoreCase("CreditNote")) {
|
} else if ("Invoice".equalsIgnoreCase(rootLocalName) || rootLocalName.equalsIgnoreCase("CreditNote")) {
|
||||||
context.setGeneration("2");
|
context.setGeneration("2");
|
||||||
context.setFormat("UBL");
|
context.setFormat("UBL");
|
||||||
isXRechnung = context.getProfile().contains("xrechnung");
|
isXRechnung = contextProfile.contains("xrechnung");
|
||||||
// UBL
|
// UBL
|
||||||
LOGGER.debug("UBL");
|
LOGGER.debug("UBL");
|
||||||
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-" + root.getLocalName() + "-2.1.xsd", 18, EPart.fx);
|
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "UBL_21/maindoc/UBL-" + rootLocalName + "-2.1.xsd", 18, EPart.fx);
|
||||||
xsltFilename = "/xslt/en16931schematron/EN16931-UBL-validation.xslt";
|
xsltFilename = "/xslt/en16931schematron/EN16931-UBL-validation.xslt";
|
||||||
|
|
||||||
mainSchematronSectionErrorTypeCode = 24;
|
mainSchematronSectionErrorTypeCode = 24;
|
||||||
@@ -299,8 +306,10 @@ 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
|
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);
|
//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(".", "");
|
String xrVersion = contextProfile.substring(contextProfile.length() - 3).replace(".", "");
|
||||||
if (!xrVersion.equals("12") && !xrVersion.equals("20") && !xrVersion.equals("21") && !xrVersion.equals("22") && !xrVersion.equals("23") && !xrVersion.equals("30")) {
|
|
||||||
|
Set<String> supportedVersions = Set.of("12", "20", "21", "22", "23", "30");
|
||||||
|
if (!supportedVersions.contains(xrVersion)) {
|
||||||
throw new Exception("Unsupported XR version");
|
throw new Exception("Unsupported XR version");
|
||||||
}
|
}
|
||||||
LOGGER.debug("is XRechnung v{}", xrVersion);
|
LOGGER.debug("is XRechnung v{}", xrVersion);
|
||||||
@@ -310,14 +319,16 @@ public class XMLValidator extends Validator {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (root.getLocalName().equalsIgnoreCase("CrossIndustryDocument")) { // ZUGFeRD 1.0
|
} else if ("CrossIndustryDocument".equalsIgnoreCase(rootLocalName)) { // ZUGFeRD 1.0
|
||||||
context.setGeneration("1");
|
context.setGeneration("1");
|
||||||
//
|
//
|
||||||
if ((!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:basic"))
|
Set<String> validZF1Profiles = Set.of(
|
||||||
&& (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:comfort"))
|
"urn:ferd:CrossIndustryDocument:invoice:1p0:basic",
|
||||||
&& (!matchesURI(context.getProfile(), "urn:ferd:CrossIndustryDocument:invoice:1p0:extended"))) {
|
"urn:ferd:CrossIndustryDocument:invoice:1p0:comfort",
|
||||||
context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type")
|
"urn:ferd:CrossIndustryDocument:invoice:1p0:extended"
|
||||||
.setSection(25).setPart(EPart.fx));
|
);
|
||||||
|
if (validZF1Profiles.stream().noneMatch(profile -> matchesURI(contextProfile, profile))) {
|
||||||
|
addUnsupportedProfileResultItem();
|
||||||
}
|
}
|
||||||
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_10/ZUGFeRD1p0.xsd", 18, EPart.fx);
|
validateSchema(zfXML.getBytes(StandardCharsets.UTF_8), "ZF_10/ZUGFeRD1p0.xsd", 18, EPart.fx);
|
||||||
|
|
||||||
@@ -326,41 +337,41 @@ public class XMLValidator extends Validator {
|
|||||||
context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Unsupported root element")
|
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 ("CII".equals(context.getFormat())) {
|
||||||
|
|
||||||
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"))) {
|
|
||||||
context.addResultItem(
|
|
||||||
new ValidationResultItem(ESeverity.error, "Unsupported profile type " + context.getProfile())
|
|
||||||
.setSection(25).setPart(EPart.fx));
|
|
||||||
|
|
||||||
|
if ("2".equals(context.getGeneration())) {
|
||||||
|
Set<String> validZF2Profiles = Set.of(
|
||||||
|
"urn:factur-x.eu:1p0:minimum",
|
||||||
|
"urn:zugferd.de:2p0:minimum",
|
||||||
|
"urn:factur-x.eu:1p0:basicwl",
|
||||||
|
"urn:zugferd.de:2p0:basicwl",
|
||||||
|
"urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic",
|
||||||
|
"urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:basic",
|
||||||
|
"urn:cen.eu:en16931:2017",
|
||||||
|
"urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended",
|
||||||
|
"urn:cen.eu:en16931:2017#conformant#urn:zugferd.de:2p0:extended"
|
||||||
|
);
|
||||||
|
if (validZF2Profiles.stream().noneMatch(profile -> matchesURI(contextProfile, profile))) {
|
||||||
|
addUnsupportedProfileResultItem();
|
||||||
}
|
}
|
||||||
} else /** v1 */ {
|
} else /** v1 */ {
|
||||||
if (isOrderX) {
|
if (isOrderX) {
|
||||||
//order-x 1.0
|
//order-x 1.0
|
||||||
if ((!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:basic"))
|
if(Set.of(
|
||||||
&& (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:comfort"))
|
"urn:order-x.eu:1p0:basic",
|
||||||
&& (!matchesURI(context.getProfile(), "urn:order-x.eu:1p0:extended"))) {
|
"urn:order-x.eu:1p0:comfort",
|
||||||
//zf 1.0
|
"urn:order-x.eu:1p0:extended"
|
||||||
context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type")
|
).stream().noneMatch(profile -> matchesURI(contextProfile, profile))) {
|
||||||
.setSection(25).setPart(EPart.fx));
|
addUnsupportedProfileResultItem();
|
||||||
|
|
||||||
}
|
}
|
||||||
} 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"))) {
|
|
||||||
//zf 1.0
|
|
||||||
context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type")
|
|
||||||
.setSection(25).setPart(EPart.fx));
|
|
||||||
|
|
||||||
|
} else if (Set.of(
|
||||||
|
"urn:ferd:CrossIndustryDocument:invoice:1p0:basic",
|
||||||
|
"urn:ferd:CrossIndustryDocument:invoice:1p0:comfort",
|
||||||
|
"urn:ferd:CrossIndustryDocument:invoice:1p0:extended"
|
||||||
|
).stream().noneMatch(profile -> matchesURI(contextProfile, profile))) {
|
||||||
|
//zf 1.0
|
||||||
|
addUnsupportedProfileResultItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,7 +382,7 @@ public class XMLValidator extends Validator {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.getFormat().equals("CII") && (context.getGeneration().equals("2"))) {
|
if ("CII".equals(context.getFormat()) && ("2".equals(context.getGeneration()))) {
|
||||||
|
|
||||||
if (isXRechnung) {
|
if (isXRechnung) {
|
||||||
//additionally validate against CEN, the CEN rules are part of the ZF Schematron anyway
|
//additionally validate against CEN, the CEN rules are part of the ZF Schematron anyway
|
||||||
@@ -402,10 +413,30 @@ public class XMLValidator extends Validator {
|
|||||||
}
|
}
|
||||||
final long endTime = Calendar.getInstance().getTimeInMillis();
|
final long endTime = Calendar.getInstance().getTimeInMillis();
|
||||||
|
|
||||||
context.addCustomXML("<info><version>" + ((context.getGeneration() != null) ? context.getGeneration() : "invalid")
|
context.addCustomXML(getInfoXml(endTime, startXMLTime));
|
||||||
+ "</version><profile>" + ((context.getProfile() != null) ? context.getProfile() : "invalid") +
|
}
|
||||||
"</profile><validator version=\"" + XMLValidator.class.getPackage().getImplementationVersion() + "\"></validator><rules><fired>" + firedRules + "</fired><failed>" + failedRules + "</failed></rules>" + "<duration unit=\"ms\">" + (endTime - startXMLTime) + "</duration></info>");
|
|
||||||
|
|
||||||
|
private void addUnsupportedProfileResultItem() throws IrrecoverableValidationError {
|
||||||
|
context.addResultItem(new ValidationResultItem(ESeverity.error, "Unsupported profile type " + context.getProfile())
|
||||||
|
.setSection(25).setPart(EPart.fx));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getInfoXml(long endTime, long startXMLTime) {
|
||||||
|
String generation = context.getGeneration() != null ? context.getGeneration() : "invalid";
|
||||||
|
String profile = context.getProfile() != null ? context.getProfile() : "invalid";
|
||||||
|
String validatorVersion = XMLValidator.class.getPackage().getImplementationVersion();
|
||||||
|
long duration = endTime - startXMLTime;
|
||||||
|
|
||||||
|
return String.format(
|
||||||
|
"<info>" +
|
||||||
|
"<version>%s</version>" +
|
||||||
|
"<profile>%s</profile>" +
|
||||||
|
"<validator version=\"%s\"></validator>" +
|
||||||
|
"<rules><fired>%d</fired><failed>%d</failed></rules>" +
|
||||||
|
"<duration unit=\"ms\">%d</duration>" +
|
||||||
|
"</info>",
|
||||||
|
generation, profile, validatorVersion, firedRules, failedRules, duration
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkArithmetics(ValidationContext context) {
|
private void checkArithmetics(ValidationContext context) {
|
||||||
@@ -508,7 +539,7 @@ public class XMLValidator extends Validator {
|
|||||||
if (defaultSeverity == ESeverity.notice) {
|
if (defaultSeverity == ESeverity.notice) {
|
||||||
severity = defaultSeverity;
|
severity = defaultSeverity;
|
||||||
} else if (currentFailNode.getAttributes().getNamedItem("flag") != null
|
} else if (currentFailNode.getAttributes().getNamedItem("flag") != null
|
||||||
&& currentFailNode.getAttributes().getNamedItem("flag").getNodeValue().equals("warning")) {
|
&& "warning".equals(currentFailNode.getAttributes().getNamedItem("flag").getNodeValue())) {
|
||||||
// the XR issues warnings with flag=warning
|
// the XR issues warnings with flag=warning
|
||||||
severity = ESeverity.warning;
|
severity = ESeverity.warning;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user