Merge pull request #892 from danielluckas-rse/code-quality-enhancements

Enhance code quality
This commit is contained in:
Jochen Staerk
2025-07-25 09:34:43 +02:00
committed by GitHub
15 changed files with 227 additions and 236 deletions

View File

@@ -371,17 +371,17 @@ public class Main {
boolean optionsRecognized = false;
String action = "";
Boolean disableFileLogging = false;
boolean disableFileLogging = false;
try {
cmd = parser.parse(options, args);
// Retrieve all options
action = cmd.getOptionValue("action");
String directoryName = cmd.getOptionValue("directory");
Boolean filesFromStdIn = cmd.hasOption("listfromstdin");//((Number)cmdLine.getParsedOptionValue("integer-option")).intValue();
Boolean ignoreFileExt = cmd.hasOption("ignorefileextension");
Boolean noAttachments = cmd.hasOption("no-additional-attachments");
Boolean helpRequested = cmd.hasOption("help") || ((action != null) && (action.equals("help")));
boolean filesFromStdIn = cmd.hasOption("listfromstdin");//((Number)cmdLine.getParsedOptionValue("integer-option")).intValue();
boolean ignoreFileExt = cmd.hasOption("ignorefileextension");
boolean noAttachments = cmd.hasOption("no-additional-attachments");
boolean helpRequested = cmd.hasOption("help") || ((action != null) && (action.equals("help")));
disableFileLogging = cmd.hasOption("disable-file-logging");
String sourceName = cmd.getOptionValue("source");
@@ -389,8 +389,8 @@ public class Main {
String outName = cmd.getOptionValue("out");
String format = cmd.getOptionValue("format");
String lang = cmd.getOptionValue("language");
Boolean noNotices = cmd.hasOption("no-notices");
Boolean LogAsPDF = cmd.hasOption("log-as-pdf");
boolean noNotices = cmd.hasOption("no-notices");
boolean LogAsPDF = cmd.hasOption("log-as-pdf");
String zugferdVersion = cmd.getOptionValue("version");
String zugferdProfile = cmd.getOptionValue("profile");

View File

@@ -68,7 +68,7 @@ public class ValidatorFileWalker
thisResultString = "invalid";
allValid = false;
}
LOGGER.info(String.format("\n@%s Testing file %d: %s (%s) ", dateFormat.format(date), fileCount++, thisResultString, file));
LOGGER.info("\n@{} Testing file {}: {} ({}) ", dateFormat.format(date), fileCount++, thisResultString, file);
}
}
}
@@ -79,7 +79,7 @@ public class ValidatorFileWalker
@Override
public FileVisitResult postVisitDirectory(Path dir,
IOException exc) {
LOGGER.info(String.format("\nDirectory: %s \n", dir));
LOGGER.info("\nDirectory: {} \n", dir);
return FileVisitResult.CONTINUE;
}

View File

@@ -591,11 +591,7 @@ public class Invoice implements IExportableTransaction {
* @return fluent setter
*/
public Invoice setZFAllowances(Allowance[] iza) {
Allowances=new ArrayList<>();
for (IZUGFeRDAllowanceCharge cz:iza) {
Allowances.add(cz);
}
Allowances=new ArrayList<>(Arrays.asList(iza));
return this;
}
@@ -616,9 +612,7 @@ public class Invoice implements IExportableTransaction {
*/
public Invoice setZFCharges(Charge[] iza) {
Charges=new ArrayList<>();
for (IZUGFeRDAllowanceCharge cz:iza) {
Charges.add(cz);
}
Charges.addAll(Arrays.asList(iza));
return this;
}

View File

@@ -78,20 +78,21 @@ public class Item implements IZUGFeRDExportableItem {
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("SellersItemIdentification")
.flatMap(SellersItemIdentification -> SellersItemIdentification.getAsString("ID"))
.ifPresent(product::setSellerAssignedID);
icnm.getAsNodeMap("BuyersItemIdentification").ifPresent(BuyersItemIdentification -> {
BuyersItemIdentification.getAsString("ID").ifPresent(product::setBuyerAssignedID);
});
icnm.getAsNodeMap("BuyersItemIdentification")
.flatMap(BuyersItemIdentification -> BuyersItemIdentification.getAsString("ID"))
.ifPresent(product::setBuyerAssignedID);
icnm.getAsNodeMap("ClassifiedTaxCategory").flatMap(m -> m.getAsBigDecimal("Percent"))
icnm.getAsNodeMap("ClassifiedTaxCategory")
.flatMap(m -> m.getAsBigDecimal("Percent"))
.ifPresent(product::setVATPercent);
});
itemMap.getAsNodeMap("AssociatedDocumentLineDocument").ifPresent(icnm -> {
icnm.getAsString("LineID").ifPresent(this::setId);
});
itemMap.getAsNodeMap("AssociatedDocumentLineDocument")
.flatMap(icnm -> icnm.getAsString("LineID"))
.ifPresent(this::setId);
itemMap.getAsNodeMap("Price").ifPresent(icnm -> {
// ubl
@@ -181,7 +182,7 @@ public class Item implements IZUGFeRDExportableItem {
}
if (amountString != null) {
izac.setTotalAmount(new BigDecimal(amountString));
if (percentString!=null&&(percentString!="0")) {
if (percentString!=null&&(!percentString.equals("0"))) {
izac.setTotalAmount(new BigDecimal(amountString).divide(getQuantity()));
}
}
@@ -211,11 +212,11 @@ public class Item implements IZUGFeRDExportableItem {
icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference);
icnm.getAsString("ReceivableSpecifiedTradeAccountingAccount").ifPresent(s -> this.accountingReference = s == null ? null : s.trim());
icnm.getAsString("ReceivableSpecifiedTradeAccountingAccount").ifPresent(s -> this.accountingReference = s.trim());
icnm.getAsNodeMap("BillingSpecifiedPeriod").ifPresent(periodNode -> {
Date start = periodNode.getAsNodeMap("StartDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(dts -> XMLTools.tryDate(dts)).orElse(null);
Date end = periodNode.getAsNodeMap("EndDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(dts -> XMLTools.tryDate(dts)).orElse(null);
Date start = periodNode.getAsNodeMap("StartDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(XMLTools::tryDate).orElse(null);
Date end = periodNode.getAsNodeMap("EndDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(XMLTools::tryDate).orElse(null);
setDetailedDeliveryPeriod(start, end);
});
});
@@ -428,9 +429,7 @@ public class Item implements IZUGFeRDExportableItem {
public void setItemAllowances(ArrayList<Allowance> theAllowances) {
if (theAllowances != null) {
Allowances.clear();
for (Allowance theAllowance : theAllowances) {
Allowances.add(theAllowance);
}
Allowances.addAll(theAllowances);
}
}
@@ -440,9 +439,7 @@ public class Item implements IZUGFeRDExportableItem {
public void setItemCharges(ArrayList<Charge> theCharges) {
if (theCharges != null) {
Charges.clear();
for (Charge theCharge : theCharges) {
Charges.add(theCharge);
}
Charges.addAll(theCharges);
}
}

View File

@@ -772,7 +772,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
if (bankDetails.isEmpty() && debitDetails.isEmpty()) {
return null;
}
List<IZUGFeRDTradeSettlement> tradeSettlements = Stream.concat(bankDetails.stream(), debitDetails.stream()).map(IZUGFeRDTradeSettlement.class::cast).collect(Collectors.toList());
List<IZUGFeRDTradeSettlement> tradeSettlements = Stream.concat(bankDetails.stream(), debitDetails.stream()).collect(Collectors.toList());
IZUGFeRDTradeSettlement[] result = new IZUGFeRDTradeSettlement[tradeSettlements.size()];
for (int i = 0; i < tradeSettlements.size(); i++) {

View File

@@ -97,12 +97,12 @@ public class DAPullProvider extends ZUGFeRD2PullProvider {
+ XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "</ram:BuyerAssignedID>";
}
String allowanceChargeStr = "";
if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) {
if (currentItem.getItemAllowances() != null) {
for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) {
allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem);
}
}
if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) {
if (currentItem.getItemCharges() != null) {
for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) {
allowanceChargeStr += getAllowanceChargeStr(charge, currentItem);

View File

@@ -22,7 +22,7 @@ public class LineCalculator {
public LineCalculator(IZUGFeRDExportableItem currentItem) {
if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) {
if (currentItem.getItemAllowances() != null) {
for (IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) {
BigDecimal factor=BigDecimal.ONE;
BigDecimal singleAllowance=allowance.getTotalAmount(currentItem);
@@ -35,7 +35,7 @@ public class LineCalculator {
}
}
if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) {
if (currentItem.getItemCharges() != null) {
for (IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) {
BigDecimal factor=BigDecimal.ONE;
BigDecimal singleCharge=charge.getTotalAmount(currentItem);
@@ -47,7 +47,7 @@ public class LineCalculator {
}
}
if (currentItem.getItemTotalAllowances() != null && currentItem.getItemTotalAllowances().length > 0) {
if (currentItem.getItemTotalAllowances() != null) {
for (final IZUGFeRDAllowanceCharge itemTotalAllowance : currentItem.getItemTotalAllowances()) {
addAllowanceItemTotal(itemTotalAllowance.getTotalAmount(currentItem));
}

View File

@@ -57,7 +57,7 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
paymentTermsDescription = XMLTools.encodeXML(trans.getPaymentTermDescription());
}
if ((paymentTermsDescription == null) && (trans.getDocumentCode() != CORRECTEDINVOICE)/* && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)*/) {
if (paymentTermsDescription == null && !CORRECTEDINVOICE.equals(trans.getDocumentCode())/* && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)*/) {
paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate());
}
@@ -125,12 +125,12 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
+ XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "</ram:BuyerAssignedID>";
}
String allowanceChargeStr = "";
if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) {
if (currentItem.getItemAllowances() != null) {
for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) {
allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem);
}
}
if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) {
if (currentItem.getItemCharges() != null) {
for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) {
allowanceChargeStr += getAllowanceChargeStr(charge, currentItem);
@@ -313,8 +313,9 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) {
if (payment != null) {
hasDueDate = true;
// xml += payment.getSettlementXML();
}
break;
// xml += payment.getSettlementXML();
}
}
}
if (trans.getTradeSettlement() != null) {

View File

@@ -89,7 +89,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
private BigDecimal sumAllowanceCharge(BigDecimal percent, IZUGFeRDAllowanceCharge[] charges) {
BigDecimal res = BigDecimal.ZERO;
if ((charges != null) && (charges.length > 0)) {
if (charges != null) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) {
if ((percent == null) || (currentCharge.getTaxPercent().compareTo(percent) == 0)) {
res = res.add(currentCharge.getTotalAmount(this));
@@ -212,7 +212,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges();
if ((charges != null) && (charges.length > 0)) {
if (charges != null) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) {
BigDecimal taxPercent = currentCharge.getTaxPercent();
if (taxPercent != null) {
@@ -230,7 +230,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
}
IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances();
if ((allowances != null) && (allowances.length > 0)) {
if (allowances != null) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
BigDecimal taxPercent = currentAllowance.getTaxPercent();
if (taxPercent != null) {
@@ -286,8 +286,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
final IZUGFeRDAllowanceCharge[] charges = this.trans.getZFCharges();
if (charges != null && charges.length > 0)
{
if (charges != null) {
for (final IZUGFeRDAllowanceCharge currentCharge : charges)
{
final BigDecimal taxPercent = currentCharge.getTaxPercent();
@@ -310,8 +309,7 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
}
final IZUGFeRDAllowanceCharge[] allowances = this.trans.getZFAllowances();
if (allowances != null && allowances.length > 0)
{
if (allowances != null) {
for (final IZUGFeRDAllowanceCharge currentAllowance : allowances)
{
final BigDecimal taxPercent = currentAllowance.getTaxPercent();

View File

@@ -360,7 +360,10 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
}
paymentTermsDescription += discount.getAsXRechnung();
}
} else if ((paymentTermsDescription == null) && (trans.getDocumentCode() != DocumentCodeTypeConstants.CORRECTEDINVOICE) && (trans.getDocumentCode() != DocumentCodeTypeConstants.CREDITNOTE)) {
} else if (paymentTermsDescription == null
&& !DocumentCodeTypeConstants.CORRECTEDINVOICE.equals(trans.getDocumentCode())
&& !DocumentCodeTypeConstants.CREDITNOTE.equals(trans.getDocumentCode())
) {
if (trans.getDueDate() != null) {
paymentTermsDescription = "Please remit until " + germanDateFormat.format(trans.getDueDate());
}
@@ -434,12 +437,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
+ XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "</ram:BuyerAssignedID>";
}
String allowanceChargeStr = "";
if (currentItem.getProduct().getAllowances() != null && currentItem.getProduct().getAllowances().length > 0) {
if (currentItem.getProduct().getAllowances() != null) {
for (final IZUGFeRDAllowanceCharge allowance : currentItem.getProduct().getAllowances()) {
allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem);
}
}
if (currentItem.getProduct().getCharges() != null && currentItem.getProduct().getCharges().length > 0) {
if (currentItem.getProduct().getCharges() != null) {
for (final IZUGFeRDAllowanceCharge charge : currentItem.getProduct().getCharges()) {
allowanceChargeStr += getAllowanceChargeStr(charge, currentItem);
@@ -447,24 +450,24 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
}
String itemTotalAllowanceChargeStr = "";
if (currentItem.getAllowances() != null && currentItem.getAllowances().length > 0) {
if (currentItem.getAllowances() != null) {
for (final IZUGFeRDAllowanceCharge itemTotalAllowance : currentItem.getAllowances()) {
itemTotalAllowanceChargeStr += getItemTotalAllowanceChargeStr(itemTotalAllowance, currentItem);
}
}
if (currentItem.getCharges() != null && currentItem.getCharges().length > 0) {
if (currentItem.getCharges() != null) {
for (final IZUGFeRDAllowanceCharge itemTotalCharges : currentItem.getCharges()) {
itemTotalAllowanceChargeStr += getItemTotalAllowanceChargeStr(itemTotalCharges, currentItem);
}
}
xml += "<ram:Name>" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "</ram:Name>";
if (currentItem.getProduct().getDescription() != null && currentItem.getProduct().getDescription().length() > 0) {
if (currentItem.getProduct().getDescription() != null) {
xml += "<ram:Description>" +
XMLTools.encodeXML(currentItem.getProduct().getDescription()) +
"</ram:Description>";
}
if (currentItem.getProduct().getClassifications() != null && currentItem.getProduct().getClassifications().length > 0) {
if (currentItem.getProduct().getClassifications() != null) {
for (IDesignatedProductClassification classification : currentItem.getProduct().getClassifications()) {
xml += "<ram:DesignatedProductClassification>"
+ "<ram:ClassCode listID=\"" + XMLTools.encodeXML(classification.getClassCode().getListID()) + "\"";
@@ -718,7 +721,9 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
}
}
}
if ((trans.getDocumentCode() == DocumentCodeTypeConstants.CORRECTEDINVOICE) || (trans.getDocumentCode() == DocumentCodeTypeConstants.CREDITNOTE)) {
if (DocumentCodeTypeConstants.CORRECTEDINVOICE.equals(trans.getDocumentCode())
|| DocumentCodeTypeConstants.CREDITNOTE.equals(trans.getDocumentCode())
) {
hasDueDate = false;
}
@@ -882,7 +887,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
} else {
xml += buildPaymentTermsXml();
}
if ((profile == Profiles.getByName("Extended")) && (trans.getCashDiscounts() != null) && (trans.getCashDiscounts().length > 0)) {
if (profile == Profiles.getByName("Extended") && trans.getCashDiscounts() != null) {
for (IZUGFeRDCashDiscount discount : trans.getCashDiscounts()
) {
xml += discount.getAsCII();

View File

@@ -564,10 +564,9 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
// iterate over all pdf pages
for (Object object : doc.getPages()) {
if (object instanceof PDPage) {
for (PDPage page : doc.getPages()) {
if (page != null) {
PDPage page = (PDPage) object;
PDResources res = page.getResources();
// Check for fonts in PDXObjects:

View File

@@ -212,7 +212,16 @@ public class ZUGFeRDInvoiceImporter {
*/
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")) {
Set<String> validFilenames = Set.of(
"ZUGFeRD-invoice.xml",
"zugferd-invoice.xml",
"factur-x.xml",
"xrechnung.xml",
"order-x.xml",
"cida.xml"
);
if (validFilenames.contains(filename)) {
containsMeta = true;
// String embeddedFilename = filePath + filename;
@@ -359,39 +368,31 @@ public class ZUGFeRDInvoiceImporter {
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));
});
Optional<NodeMap> addressNodeMapp = deliveryLocationNodeMap.getAsNodeMap("Address");
addressNodeMapp.flatMap(s -> s.getAsString("StreetName"))
.ifPresent(delivery::setStreet);
addressNodeMapp.flatMap(s -> s.getAsString("AdditionalStreetName"))
.ifPresent(delivery::setAdditionalAddress);
addressNodeMapp.flatMap(s -> s.getAsString("CityName"))
.ifPresent(delivery::setLocation);
addressNodeMapp.flatMap(s -> s.getAsString("PostalZone"))
.ifPresent(delivery::setZIP);
addressNodeMapp.flatMap(s -> s.getAsNodeMap("Country")).flatMap(t -> t.getAsString("IdentificationCode"))
.ifPresent(delivery::setCountry);
addressNodeMapp.flatMap(s -> s.getAsNodeMap("AddressLine")).flatMap(t -> t.getAsString("Line"))
.ifPresent(delivery::setAdditionalAddressExtension);
addressNodeMapp.flatMap(s -> s.getAsString("AdditionalStreetName"))
.ifPresent(delivery::setAdditionalAddress);
addressNodeMapp.flatMap(s -> s.getAsString("AdditionalStreetName"))
.ifPresent(delivery::setAdditionalAddress);
});
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;
new NodeMap(deliveryNode).getAsNodeMap("DeliveryParty")
.flatMap(partyMap -> partyMap.getAsNodeMap("PartyName"))
.flatMap(s -> s.getAsString("Name"))
.ifPresent(delivery::setName);
zpp.setDeliveryAddress(delivery);
}
@@ -430,7 +431,7 @@ public class ZUGFeRDInvoiceImporter {
xpr = xpath.compile("//*[local-name()=\"ExchangedDocument\"]|//*[local-name()=\"HeaderExchangedDocument\"]");
NodeList ExchangedDocumentNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
xpr = xpath.compile("//*[local-name()=\"GrandTotalAmount\"]|//*[local-name()=\"TaxInclusiveAmount\"]");
BigDecimal expectedGrandTotal = null;
NodeList totalNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
@@ -578,11 +579,11 @@ public class ZUGFeRDInvoiceImporter {
}
String creditorReferenceID = extractString("//*[local-name()=\"ApplicableHeaderTradeSettlement\"]/*[local-name()=\"CreditorReferenceID\"]").trim();//BT-90
if ((creditorReferenceID == null)||(creditorReferenceID.length()==0)) {
if (creditorReferenceID == null || creditorReferenceID.isEmpty()) {
//maybe it's there in UBL?
creditorReferenceID = extractString("//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyIdentification\"]/*[local-name()=\"ID\"]").trim();
}
if ((creditorReferenceID != null)&&(creditorReferenceID.length()>0)) {
if (creditorReferenceID != null && !creditorReferenceID.isEmpty()) {
zpp.setCreditorReferenceID(creditorReferenceID);
}

View File

@@ -12,7 +12,6 @@ import java.util.Calendar;
import java.util.EnumSet;
import java.util.HashMap;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -130,136 +129,137 @@ public class PDFValidator extends Validator {
final Document docXMP;
if (xmp == null || xmp.length() == 0) {
if (xmp == null || xmp.isEmpty()) {
context.addResultItem(new ValidationResultItem(ESeverity.error, "Invalid XMP Metadata not found")
.setSection(17).setPart(EPart.pdf));
}
else
/*
* checking for sth like <zf:ConformanceLevel>EXTENDED</zf:ConformanceLevel>
* <zf:DocumentType>INVOICE</zf:DocumentType>
* <zf:DocumentFileName>ZUGFeRD-invoice.xml</zf:DocumentFileName>
* <zf:Version>1.0</zf:Version>
*/
try {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
factory.setXIncludeAware(false);
else {
/*
* checking for sth like <zf:ConformanceLevel>EXTENDED</zf:ConformanceLevel>
* <zf:DocumentType>INVOICE</zf:DocumentType>
* <zf:DocumentFileName>ZUGFeRD-invoice.xml</zf:DocumentFileName>
* <zf:Version>1.0</zf:Version>
*/
try {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
factory.setXIncludeAware(false);
final DocumentBuilder builder = factory.newDocumentBuilder();
final InputSource is = new InputSource(new StringReader(xmp));
docXMP = builder.parse(is);
final DocumentBuilder builder = factory.newDocumentBuilder();
final InputSource is = new InputSource(new StringReader(xmp));
docXMP = builder.parse(is);
final XPathFactory xpathFactory = XPathFactory.newInstance();
final XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object XPath xpath = xpathFactory.newXPath(); XPathExpression
// Create XPath object XPath xpath = xpathFactory.newXPath(); XPathExpression
final XPath xpath = xpathFactory.newXPath();
// xpath.compile("//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/[local-name()=\"ID\"]");
// evaluate expression result on XML document ndList = (NodeList)
final XPath xpath = xpathFactory.newXPath();
// xpath.compile("//*[local-name()=\"GuidelineSpecifiedDocumentContextParameter\"]/[local-name()=\"ID\"]");
// evaluate expression result on XML document ndList = (NodeList)
// get the first element
XPathExpression xpr = xpath.compile(
"//*[local-name()=\"ConformanceLevel\"]|//*[local-name()=\"Description\"]/@ConformanceLevel");
NodeList nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET);
// get the first element
XPathExpression xpr = xpath.compile(
"//*[local-name()=\"ConformanceLevel\"]|//*[local-name()=\"Description\"]/@ConformanceLevel");
NodeList nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET);
if (nodes.getLength() == 0) {
context.addResultItem(
new ValidationResultItem(ESeverity.error, "XMP Metadata: ConformanceLevel not found")
.setSection(11).setPart(EPart.pdf));
}
boolean conformanceLevelValid = false;
for (int i = 0; i < nodes.getLength(); i++) {
final String[] valueArray = {"BASIC WL", "BASIC", "MINIMUM", "EN 16931", "COMFORT", "CIUS", "EXTENDED", "XRECHNUNG"};
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
conformanceLevelValid = true;
}
}
if (!conformanceLevelValid) {
context.addResultItem(new ValidationResultItem(
ESeverity.error,
"XMP Metadata: ConformanceLevel contains invalid value"
).setSection(12).setPart(EPart.pdf));
}
xpr = xpath.compile("//*[local-name()=\"DocumentType\"]|//*[local-name()=\"Description\"]/@DocumentType");
nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET);
if (nodes.getLength() == 0) {
context.addResultItem(new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentType not found")
.setSection(13).setPart(EPart.pdf));
}
boolean documentTypeValid = false;
for (int i = 0; i < nodes.getLength(); i++) {
if (nodes.item(i).getTextContent().equals("INVOICE") || nodes.item(i).getTextContent().equals("ORDER")
|| nodes.item(i).getTextContent().equals("ORDER_RESPONSE") || nodes.item(i).getTextContent()
.equals("ORDER_CHANGE")) {
documentTypeValid = true;
}
}
if (!documentTypeValid) {
context.addResultItem(
new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentType invalid")
.setSection(14).setPart(EPart.pdf));
}
xpr = xpath.compile(
"//*[local-name()=\"DocumentFileName\"]|//*[local-name()=\"Description\"]/@DocumentFileName");
nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET);
if (nodes.getLength() == 0) {
context.addResultItem(
new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentFileName not found")
.setSection(21).setPart(EPart.pdf));
}
boolean documentFilenameValid = false;
for (int i = 0; i < nodes.getLength(); i++) {
final String[] valueArray = {"factur-x.xml", "ZUGFeRD-invoice.xml", "zugferd-invoice.xml", "xrechnung.xml", "order-x.xml"};
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
documentFilenameValid = true;
if (nodes.getLength() == 0) {
context.addResultItem(
new ValidationResultItem(ESeverity.error, "XMP Metadata: ConformanceLevel not found")
.setSection(11).setPart(EPart.pdf));
}
// e.g. ZUGFeRD-invoice.xml
}
if (!documentFilenameValid) {
boolean conformanceLevelValid = false;
for (int i = 0; i < nodes.getLength(); i++) {
context.addResultItem(new ValidationResultItem(
ESeverity.error,
"XMP Metadata: DocumentFileName contains invalid value"
).setSection(19).setPart(EPart.pdf));
}
xpr = xpath.compile("//*[local-name()=\"Version\"]|//*[local-name()=\"Description\"]/@Version");
nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET);
final String[] valueArray = {"BASIC WL", "BASIC", "MINIMUM", "EN 16931", "COMFORT", "CIUS", "EXTENDED", "XRECHNUNG"};
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
conformanceLevelValid = true;
}
}
if (!conformanceLevelValid) {
context.addResultItem(new ValidationResultItem(
ESeverity.error,
"XMP Metadata: ConformanceLevel contains invalid value"
).setSection(12).setPart(EPart.pdf));
// get all child nodes
// NodeList nodes = element.getChildNodes();
// expr.evaluate(docXMP, XPathConstants.NODESET);
// print the text content of each child
if (nodes.getLength() == 0) {
context.addResultItem(new ValidationResultItem(ESeverity.error, "XMP Metadata: Version not found")
.setSection(15).setPart(EPart.pdf));
}
}
xpr = xpath.compile("//*[local-name()=\"DocumentType\"]|//*[local-name()=\"Description\"]/@DocumentType");
nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET);
boolean versionValid = false;
for (int i = 0; i < nodes.getLength(); i++) {
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 (nodes.getLength() == 0) {
context.addResultItem(new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentType not found")
.setSection(13).setPart(EPart.pdf));
}
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
versionValid = true;
} // e.g. 1.0
}
if (!versionValid) {
context.addResultItem(
new ValidationResultItem(ESeverity.error, "XMP Metadata: Version contains invalid value")
.setSection(16).setPart(EPart.pdf));
boolean documentTypeValid = false;
for (int i = 0; i < nodes.getLength(); i++) {
if (nodes.item(i).getTextContent().equals("INVOICE") || nodes.item(i).getTextContent().equals("ORDER")
|| nodes.item(i).getTextContent().equals("ORDER_RESPONSE") || nodes.item(i).getTextContent()
.equals("ORDER_CHANGE")) {
documentTypeValid = true;
}
}
if (!documentTypeValid) {
context.addResultItem(
new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentType invalid")
.setSection(14).setPart(EPart.pdf));
}
xpr = xpath.compile(
"//*[local-name()=\"DocumentFileName\"]|//*[local-name()=\"Description\"]/@DocumentFileName");
nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET);
if (nodes.getLength() == 0) {
context.addResultItem(
new ValidationResultItem(ESeverity.error, "XMP Metadata: DocumentFileName not found")
.setSection(21).setPart(EPart.pdf));
}
boolean documentFilenameValid = false;
for (int i = 0; i < nodes.getLength(); i++) {
final String[] valueArray = {"factur-x.xml", "ZUGFeRD-invoice.xml", "zugferd-invoice.xml", "xrechnung.xml", "order-x.xml"};
if (stringArrayContains(valueArray, nodes.item(i).getTextContent())) {
documentFilenameValid = true;
}
// e.g. ZUGFeRD-invoice.xml
}
if (!documentFilenameValid) {
context.addResultItem(new ValidationResultItem(
ESeverity.error,
"XMP Metadata: DocumentFileName contains invalid value"
).setSection(19).setPart(EPart.pdf));
}
xpr = xpath.compile("//*[local-name()=\"Version\"]|//*[local-name()=\"Description\"]/@Version");
nodes = (NodeList) xpr.evaluate(docXMP, XPathConstants.NODESET);
// get all child nodes
// NodeList nodes = element.getChildNodes();
// expr.evaluate(docXMP, XPathConstants.NODESET);
// print the text content of each child
if (nodes.getLength() == 0) {
context.addResultItem(new ValidationResultItem(ESeverity.error, "XMP Metadata: Version not found")
.setSection(15).setPart(EPart.pdf));
}
boolean versionValid = false;
for (int i = 0; i < nodes.getLength(); i++) {
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
}
if (!versionValid) {
context.addResultItem(
new ValidationResultItem(ESeverity.error, "XMP Metadata: Version contains invalid value")
.setSection(16).setPart(EPart.pdf));
}
} catch (final SAXException | IOException | ParserConfigurationException | XPathExpressionException e) {
LOGGER.error(e.getMessage(), e);
}
} catch (final SAXException | IOException | ParserConfigurationException | XPathExpressionException e) {
LOGGER.error(e.getMessage(), e);
}
zfXML = zi.getUTF8();
@@ -306,7 +306,7 @@ public class PDFValidator extends Validator {
final HashMap<String, byte[]> additionalData = zi.getAdditionalData();
for (final String filename : additionalData.keySet()) {
// validating xml in byte[] additionalData.get(filename)
LOGGER.info("validating additionalData " + filename);
LOGGER.info("validating additionalData {}", filename);
validateSchema(additionalData.get(filename), "ad/basic/additional_data_base_schema.xsd", 2, EPart.pdf);
}

View File

@@ -32,13 +32,13 @@ public class ValidationContext {
}
if (logger != null) {
if ((vr.getSeverity() == ESeverity.fatal) || (vr.getSeverity() == ESeverity.exception)) {
logger.error("Fatal Error " + vr.getSection() + ": " + vr.getMessage());
logger.error("Fatal Error {}: {}", vr.getSection(), vr.getMessage());
} else if ((vr.getSeverity() == ESeverity.error)) {
logger.error("Error " + vr.getSection() + ": " + vr.getMessage());
logger.error("Error {}: {}", vr.getSection(), vr.getMessage());
} else if (vr.getSeverity() == ESeverity.warning) {
logger.warn("Warning " + vr.getSection() + ": " + vr.getMessage());
logger.warn("Warning {}: {}", vr.getSection(), vr.getMessage());
} else if (vr.getSeverity() == ESeverity.notice) {
logger.info("Notice " + vr.getSection() + ": " + vr.getMessage());
logger.info("Notice {}: {}", vr.getSection(), vr.getMessage());
}
}
@@ -106,20 +106,17 @@ public class ValidationContext {
}
public String getXMLResult() {
String res = getCustomXML();
if (results.size() > 0) {
res += "<messages>";
StringBuilder res = new StringBuilder(getCustomXML());
if (results != null && !results.isEmpty()) {
res.append("<messages>");
for (final ValidationResultItem validationResultItem : results) {
// xml and pdf are handled in their respective sections
res.append(validationResultItem.getXMLOnce()).append("\n");
}
res.append("</messages>");
}
for (final ValidationResultItem validationResultItem : results) {
// xml and pdf are handled in their respective sections
res += validationResultItem.getXMLOnce() + "\n";
}
if (results.size() > 0) {
res += "</messages>";
}
res += "<summary status=\"" + (isValid ? "valid" : "invalid") + "\"/>";
return res;
res.append("<summary status=\"").append(isValid ? "valid" : "invalid").append("\"/>");
return res.toString();
}
/***

View File

@@ -22,7 +22,6 @@ import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.mustangproject.CalculatedInvoice;
import org.mustangproject.Exceptions.ArithmetricException;
import org.mustangproject.XMLTools;
import org.mustangproject.ZUGFeRD.ZUGFeRDInvoiceImporter;
import org.slf4j.Logger;
@@ -304,7 +303,7 @@ public class XMLValidator extends Validator {
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);
LOGGER.debug("is XRechnung v{}", xrVersion);
xsltFilename = "/xslt/XR_" + xrVersion + "/XRechnung-UBL-validation.xslt";
XrechnungSeverity = ESeverity.error;
mainSchematronSectionErrorTypeCode = 27;
@@ -528,7 +527,7 @@ public class XMLValidator extends Validator {
}
}
LOGGER.info("FailedAssert ", thisFailText);
LOGGER.info("FailedAssert {}", thisFailText);
context.addResultItem(new ValidationResultItem(severity, thisFailText + thisFailIDStr + " from " + xsltFilename + ")")
.setLocation(thisFailLocation).setCriterion(thisFailTest).setSection(section).setID(thisFailID)