Merge branch 'master' of github.com:ZUGFeRD/mustangproject
This commit is contained in:
@@ -307,12 +307,13 @@ public class Main {
|
|||||||
// Plain Java
|
// Plain Java
|
||||||
// based on https://mkyong.com/java/how-to-convert-inputstream-to-string-in-java/
|
// based on https://mkyong.com/java/how-to-convert-inputstream-to-string-in-java/
|
||||||
private static String convertInputStreamToString(InputStream is) {
|
private static String convertInputStreamToString(InputStream is) {
|
||||||
int DEFAULT_BUFFER_SIZE = 8192;
|
try (InputStream inputStream = is) {
|
||||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
int DEFAULT_BUFFER_SIZE = 8192;
|
||||||
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
|
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||||
int length;
|
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||||
try {
|
int length;
|
||||||
while ((length = is.read(buffer)) != -1) {
|
|
||||||
|
while ((length = inputStream.read(buffer)) != -1) {
|
||||||
result.write(buffer, 0, length);
|
result.write(buffer, 0, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,11 +321,10 @@ public class Main {
|
|||||||
return result.toString(StandardCharsets.UTF_8.name());
|
return result.toString(StandardCharsets.UTF_8.name());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
// Java 10
|
||||||
|
// return result.toString(StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
// Java 10
|
|
||||||
// return result.toString(StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|||||||
@@ -158,7 +158,6 @@ public class Invoice implements IExportableTransaction {
|
|||||||
*/
|
*/
|
||||||
public Invoice setCorrection(String number) {
|
public Invoice setCorrection(String number) {
|
||||||
setInvoiceReferencedDocumentID(number);
|
setInvoiceReferencedDocumentID(number);
|
||||||
addInvoiceReferencedDocument(new ReferencedDocument(number));
|
|
||||||
documentCode = DocumentCodeTypeConstants.CORRECTEDINVOICE;
|
documentCode = DocumentCodeTypeConstants.CORRECTEDINVOICE;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public class Item implements IZUGFeRDExportableItem {
|
|||||||
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<>();
|
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<>();
|
||||||
protected ArrayList<IZUGFeRDAllowanceCharge> Charges = new ArrayList<>();
|
protected ArrayList<IZUGFeRDAllowanceCharge> Charges = new ArrayList<>();
|
||||||
protected List<IncludedNote> includedNotes = null;
|
protected List<IncludedNote> includedNotes = null;
|
||||||
|
protected String accountingReference;
|
||||||
//protected HashMap<String, String> attributes = new HashMap<>();
|
//protected HashMap<String, String> attributes = new HashMap<>();
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -214,6 +215,8 @@ public class Item implements IZUGFeRDExportableItem {
|
|||||||
|
|
||||||
icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference);
|
icnm.getAllNodes("AdditionalReferencedDocument").map(ReferencedDocument::fromNode).forEach(this::addAdditionalReference);
|
||||||
|
|
||||||
|
icnm.getAsString("ReceivableSpecifiedTradeAccountingAccount").ifPresent(s -> this.accountingReference = s == null ? null : s.trim());
|
||||||
|
|
||||||
icnm.getAsNodeMap("BillingSpecifiedPeriod").ifPresent(periodNode -> {
|
icnm.getAsNodeMap("BillingSpecifiedPeriod").ifPresent(periodNode -> {
|
||||||
Date start = periodNode.getAsNodeMap("StartDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(dts -> XMLTools.tryDate(dts)).orElse(null);
|
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 end = periodNode.getAsNodeMap("EndDateTime").flatMap(dateTimeNode -> dateTimeNode.getNode("DateTimeString")).map(dts -> XMLTools.tryDate(dts)).orElse(null);
|
||||||
@@ -561,4 +564,9 @@ public class Item implements IZUGFeRDExportableItem {
|
|||||||
public List<IncludedNote> getNotesWithSubjectCode() {
|
public List<IncludedNote> getNotesWithSubjectCode() {
|
||||||
return includedNotes;
|
return includedNotes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccountingReference() {
|
||||||
|
return accountingReference;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,8 @@ public class XMLTools extends XMLWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] getBytesFromStream(InputStream fileinput) throws IOException {
|
public static byte[] getBytesFromStream(InputStream fileinput) throws IOException {
|
||||||
return IOUtils.toByteArray (fileinput);
|
// Stream closing responsibility is with the caller
|
||||||
|
return IOUtils.toByteArray(fileinput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -172,4 +172,8 @@ public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
|
|||||||
default List<IncludedNote> getNotesWithSubjectCode() {
|
default List<IncludedNote> getNotesWithSubjectCode() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default String getAccountingReference() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.mustangproject.EStandard;
|
import org.mustangproject.EStandard;
|
||||||
import org.mustangproject.FileAttachment;
|
import org.mustangproject.FileAttachment;
|
||||||
|
import org.mustangproject.ReferencedDocument;
|
||||||
import org.mustangproject.XMLTools;
|
import org.mustangproject.XMLTools;
|
||||||
|
|
||||||
public class OXPullProvider extends ZUGFeRD2PullProvider {
|
public class OXPullProvider extends ZUGFeRD2PullProvider {
|
||||||
@@ -460,7 +461,7 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
|
|||||||
xml += "</ram:InvoiceReferencedDocument>";
|
xml += "</ram:InvoiceReferencedDocument>";
|
||||||
}
|
}
|
||||||
if (trans.getInvoiceReferencedDocuments() != null) {
|
if (trans.getInvoiceReferencedDocuments() != null) {
|
||||||
for (var doc : trans.getInvoiceReferencedDocuments()) {
|
for (ReferencedDocument doc : trans.getInvoiceReferencedDocuments()) {
|
||||||
xml += "<ram:InvoiceReferencedDocument>"
|
xml += "<ram:InvoiceReferencedDocument>"
|
||||||
+ "<ram:IssuerAssignedID>"
|
+ "<ram:IssuerAssignedID>"
|
||||||
+ XMLTools.encodeXML(doc.getIssuerAssignedID()) + "</ram:IssuerAssignedID>";
|
+ XMLTools.encodeXML(doc.getIssuerAssignedID()) + "</ram:IssuerAssignedID>";
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ import org.apache.pdfbox.preflight.parser.PreflightParser;
|
|||||||
|
|
||||||
import jakarta.activation.DataSource;
|
import jakarta.activation.DataSource;
|
||||||
|
|
||||||
// Copied from PDFBox preflight 2.0.x
|
// Copied from PDFBox preflight 2.0.x
|
||||||
final class ByteArrayDataSource implements DataSource
|
final class ByteArrayDataSource implements DataSource
|
||||||
{
|
{
|
||||||
private ByteArrayOutputStream data;
|
private ByteArrayOutputStream data;
|
||||||
private String type = null;
|
private String type = null;
|
||||||
private String name = null;
|
private String name = null;
|
||||||
|
|
||||||
public ByteArrayDataSource (InputStream is) throws IOException
|
public ByteArrayDataSource (final InputStream is) throws IOException
|
||||||
{
|
{
|
||||||
data = new ByteArrayOutputStream ();
|
data = new ByteArrayOutputStream ();
|
||||||
IOUtils.copy (is, data);
|
IOUtils.copy (is, data);
|
||||||
@@ -36,7 +36,7 @@ final class ByteArrayDataSource implements DataSource
|
|||||||
* @param type
|
* @param type
|
||||||
* the type to set
|
* the type to set
|
||||||
*/
|
*/
|
||||||
public void setType (String type)
|
public void setType (final String type)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ final class ByteArrayDataSource implements DataSource
|
|||||||
* @param name
|
* @param name
|
||||||
* the name to set
|
* the name to set
|
||||||
*/
|
*/
|
||||||
public void setName (String name)
|
public void setName (final String name)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
@@ -70,12 +70,13 @@ final class ByteArrayDataSource implements DataSource
|
|||||||
// Try to create an API similar to the 2.x one
|
// Try to create an API similar to the 2.x one
|
||||||
final class PreflightParserHelper
|
final class PreflightParserHelper
|
||||||
{
|
{
|
||||||
private static File createTmpFile (InputStream input) throws IOException
|
private static File createTmpFile (final InputStream input) throws IOException
|
||||||
{
|
{
|
||||||
FileOutputStream fos = null;
|
FileOutputStream fos = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File tmpFile = File.createTempFile ("mustang-pdf", ".pdf");
|
final File tmpFile = File.createTempFile ("mustang-pdf", ".pdf");
|
||||||
|
tmpFile.deleteOnExit ();
|
||||||
fos = new FileOutputStream (tmpFile);
|
fos = new FileOutputStream (tmpFile);
|
||||||
IOUtils.copy (input, fos);
|
IOUtils.copy (input, fos);
|
||||||
return tmpFile;
|
return tmpFile;
|
||||||
@@ -87,7 +88,7 @@ final class PreflightParserHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PreflightParser createPreflightParser (DataSource dataSource) throws IOException
|
public static PreflightParser createPreflightParser (final DataSource dataSource) throws IOException
|
||||||
{
|
{
|
||||||
return new PreflightParser (createTmpFile (dataSource.getInputStream ()));
|
return new PreflightParser (createTmpFile (dataSource.getInputStream ()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import org.dom4j.io.OutputFormat;
|
|||||||
import org.dom4j.io.XMLWriter;
|
import org.dom4j.io.XMLWriter;
|
||||||
import org.mustangproject.FileAttachment;
|
import org.mustangproject.FileAttachment;
|
||||||
import org.mustangproject.IncludedNote;
|
import org.mustangproject.IncludedNote;
|
||||||
|
import org.mustangproject.ReferencedDocument;
|
||||||
import org.mustangproject.XMLTools;
|
import org.mustangproject.XMLTools;
|
||||||
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
|
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -139,7 +140,9 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
xml += "<ram:GlobalID schemeID=\"" + XMLTools.encodeXML(party.getGlobalIDScheme()) + "\">"
|
xml += "<ram:GlobalID schemeID=\"" + XMLTools.encodeXML(party.getGlobalIDScheme()) + "\">"
|
||||||
+ XMLTools.encodeXML(party.getGlobalID()) + "</ram:GlobalID>";
|
+ XMLTools.encodeXML(party.getGlobalID()) + "</ram:GlobalID>";
|
||||||
}
|
}
|
||||||
xml += "<ram:Name>" + XMLTools.encodeXML(party.getName()) + "</ram:Name>";
|
if (party.getName() != null && !party.getName().isEmpty()) {
|
||||||
|
xml += "<ram:Name>" + XMLTools.encodeXML(party.getName()) + "</ram:Name>";
|
||||||
|
}
|
||||||
if (party.getDescription() != null) {
|
if (party.getDescription() != null) {
|
||||||
xml += "<ram:Description>" + XMLTools.encodeXML(party.getDescription()) + "</ram:Description>";
|
xml += "<ram:Description>" + XMLTools.encodeXML(party.getDescription()) + "</ram:Description>";
|
||||||
}
|
}
|
||||||
@@ -342,8 +345,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
boolean hasDueDate = trans.getDueDate() != null;
|
boolean hasDueDate = trans.getDueDate() != null;
|
||||||
final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
|
final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
|
||||||
|
|
||||||
String exemptionReason = "";
|
|
||||||
|
|
||||||
if (trans.getPaymentTermDescription() != null) {
|
if (trans.getPaymentTermDescription() != null) {
|
||||||
paymentTermsDescription = XMLTools.encodeXML(trans.getPaymentTermDescription());
|
paymentTermsDescription = XMLTools.encodeXML(trans.getPaymentTermDescription());
|
||||||
}
|
}
|
||||||
@@ -409,9 +410,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
if (currentItem.getId()!=null) {
|
if (currentItem.getId()!=null) {
|
||||||
lineIDStr=currentItem.getId();
|
lineIDStr=currentItem.getId();
|
||||||
}
|
}
|
||||||
if (currentItem.getProduct().getTaxExemptionReason() != null) {
|
|
||||||
exemptionReason = "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>";
|
|
||||||
}
|
|
||||||
final LineCalculator lc = new LineCalculator(currentItem);
|
final LineCalculator lc = new LineCalculator(currentItem);
|
||||||
if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) {
|
if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) {
|
||||||
xml += "<ram:IncludedSupplyChainTradeLineItem>" +
|
xml += "<ram:IncludedSupplyChainTradeLineItem>" +
|
||||||
@@ -454,7 +452,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
xml += "<ram:Name>" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "</ram:Name>";
|
xml += "<ram:Name>" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "</ram:Name>";
|
||||||
if (currentItem.getProduct().getDescription().length() > 0) {
|
if (currentItem.getProduct().getDescription() != null && currentItem.getProduct().getDescription().length() > 0) {
|
||||||
xml += "<ram:Description>" +
|
xml += "<ram:Description>" +
|
||||||
XMLTools.encodeXML(currentItem.getProduct().getDescription()) +
|
XMLTools.encodeXML(currentItem.getProduct().getDescription()) +
|
||||||
"</ram:Description>";
|
"</ram:Description>";
|
||||||
@@ -462,7 +460,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
if (currentItem.getProduct().getClassifications() != null && currentItem.getProduct().getClassifications().length > 0) {
|
if (currentItem.getProduct().getClassifications() != null && currentItem.getProduct().getClassifications().length > 0) {
|
||||||
for (IDesignatedProductClassification classification : currentItem.getProduct().getClassifications()) {
|
for (IDesignatedProductClassification classification : currentItem.getProduct().getClassifications()) {
|
||||||
xml += "<ram:DesignatedProductClassification>"
|
xml += "<ram:DesignatedProductClassification>"
|
||||||
+ "<ram:ClassCode listId=\"" + XMLTools.encodeXML(classification.getClassCode().getListID()) + "\"";
|
+ "<ram:ClassCode listID=\"" + XMLTools.encodeXML(classification.getClassCode().getListID()) + "\"";
|
||||||
if (classification.getClassCode().getListVersionID() != null) {
|
if (classification.getClassCode().getListVersionID() != null) {
|
||||||
xml += " listVersionID=\"" + XMLTools.encodeXML(classification.getClassCode().getListVersionID()) + "\"";
|
xml += " listVersionID=\"" + XMLTools.encodeXML(classification.getClassCode().getListVersionID()) + "\"";
|
||||||
}
|
}
|
||||||
@@ -532,9 +530,13 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
+ "</ram:SpecifiedLineTradeDelivery>"
|
+ "</ram:SpecifiedLineTradeDelivery>"
|
||||||
+ "<ram:SpecifiedLineTradeSettlement>"
|
+ "<ram:SpecifiedLineTradeSettlement>"
|
||||||
+ "<ram:ApplicableTradeTax>"
|
+ "<ram:ApplicableTradeTax>"
|
||||||
+ "<ram:TypeCode>VAT</ram:TypeCode>"
|
+ "<ram:TypeCode>VAT</ram:TypeCode>";
|
||||||
+ exemptionReason
|
|
||||||
+ "<ram:CategoryCode>" + currentItem.getProduct().getTaxCategoryCode() + "</ram:CategoryCode>"
|
if (currentItem.getProduct().getTaxExemptionReason() != null) {
|
||||||
|
xml += "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>";
|
||||||
|
}
|
||||||
|
|
||||||
|
xml += "<ram:CategoryCode>" + currentItem.getProduct().getTaxCategoryCode() + "</ram:CategoryCode>"
|
||||||
+ "<ram:RateApplicablePercent>"
|
+ "<ram:RateApplicablePercent>"
|
||||||
+ vatFormat(currentItem.getProduct().getVATPercent()) + "</ram:RateApplicablePercent>"
|
+ vatFormat(currentItem.getProduct().getVATPercent()) + "</ram:RateApplicablePercent>"
|
||||||
+ "</ram:ApplicableTradeTax>";
|
+ "</ram:ApplicableTradeTax>";
|
||||||
@@ -898,7 +900,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
xml += "</ram:InvoiceReferencedDocument>";
|
xml += "</ram:InvoiceReferencedDocument>";
|
||||||
}
|
}
|
||||||
if (trans.getInvoiceReferencedDocuments() != null) {
|
if (trans.getInvoiceReferencedDocuments() != null) {
|
||||||
for (var doc : trans.getInvoiceReferencedDocuments()) {
|
for (ReferencedDocument doc : trans.getInvoiceReferencedDocuments()) {
|
||||||
xml += "<ram:InvoiceReferencedDocument>"
|
xml += "<ram:InvoiceReferencedDocument>"
|
||||||
+ "<ram:IssuerAssignedID>"
|
+ "<ram:IssuerAssignedID>"
|
||||||
+ XMLTools.encodeXML(doc.getIssuerAssignedID()) + "</ram:IssuerAssignedID>";
|
+ XMLTools.encodeXML(doc.getIssuerAssignedID()) + "</ram:IssuerAssignedID>";
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import org.apache.pdfbox.pdmodel.font.PDCIDFontType2;
|
|||||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||||
import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
|
import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
|
||||||
import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
||||||
|
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
|
import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
|
||||||
import org.apache.xmpbox.XMPMetadata;
|
import org.apache.xmpbox.XMPMetadata;
|
||||||
import org.apache.xmpbox.schema.AdobePDFSchema;
|
import org.apache.xmpbox.schema.AdobePDFSchema;
|
||||||
@@ -559,6 +560,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
|
|||||||
// https://github.com/ZUGFeRD/mustangproject/issues/249
|
// https://github.com/ZUGFeRD/mustangproject/issues/249
|
||||||
|
|
||||||
COSName cidSet = COSName.getPDFName("CIDSet");
|
COSName cidSet = COSName.getPDFName("CIDSet");
|
||||||
|
COSName resources = COSName.getPDFName("Resources");
|
||||||
|
|
||||||
// iterate over all pdf pages
|
// iterate over all pdf pages
|
||||||
|
|
||||||
@@ -567,29 +569,45 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
|
|||||||
|
|
||||||
PDPage page = (PDPage) object;
|
PDPage page = (PDPage) object;
|
||||||
PDResources res = page.getResources();
|
PDResources res = page.getResources();
|
||||||
for (COSName fontName : res.getFontNames()) {
|
|
||||||
try {
|
|
||||||
PDFont pdFont = res.getFont(fontName);
|
|
||||||
if (pdFont instanceof PDType0Font) {
|
|
||||||
PDType0Font typedFont = (PDType0Font) pdFont;
|
|
||||||
|
|
||||||
if (typedFont.getDescendantFont() instanceof PDCIDFontType2) {
|
// Check for fonts in PDXObjects:
|
||||||
@SuppressWarnings("unused")
|
for (COSName xObjectName : res.getXObjectNames()) {
|
||||||
PDCIDFontType2 f = (PDCIDFontType2) typedFont.getDescendantFont();
|
PDXObject xObject = res.getXObject(xObjectName);
|
||||||
PDFontDescriptor fontDescriptor = pdFont.getFontDescriptor();
|
COSDictionary d = xObject.getCOSObject().getCOSDictionary(resources);
|
||||||
|
if (d != null) {
|
||||||
fontDescriptor.getCOSObject().removeItem(cidSet);
|
PDResources xr = new PDResources(d);
|
||||||
}
|
removeCIDSetFromPDResources(cidSet, xr);
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
// do stuff with the font
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for fonts in document-resources:
|
||||||
|
removeCIDSetFromPDResources(cidSet, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeCIDSetFromPDResources(COSName cidSet, PDResources res) throws IOException {
|
||||||
|
for (COSName fontName : res.getFontNames()) {
|
||||||
|
try {
|
||||||
|
PDFont pdFont = res.getFont(fontName);
|
||||||
|
if (pdFont instanceof PDType0Font) {
|
||||||
|
PDType0Font typedFont = (PDType0Font) pdFont;
|
||||||
|
|
||||||
|
if (typedFont.getDescendantFont() instanceof PDCIDFontType2) {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
PDCIDFontType2 f = (PDCIDFontType2) typedFont.getDescendantFont();
|
||||||
|
PDFontDescriptor fontDescriptor = pdFont.getFontDescriptor();
|
||||||
|
|
||||||
|
fontDescriptor.getCOSObject().removeItem(cidSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
// do stuff with the font
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void prepareDocument() throws IOException {
|
protected void prepareDocument() throws IOException {
|
||||||
|
|
||||||
PDDocumentCatalog cat = doc.getDocumentCatalog();
|
PDDocumentCatalog cat = doc.getDocumentCatalog();
|
||||||
|
|||||||
@@ -90,9 +90,10 @@ public class ZUGFeRDExporterFromPDFA implements IZUGFeRDExporter {
|
|||||||
|
|
||||||
protected byte[] inputstreamToByteArray(InputStream fileInputStream) throws IOException {
|
protected byte[] inputstreamToByteArray(InputStream fileInputStream) throws IOException {
|
||||||
byte[] bytes = new byte[fileInputStream.available()];
|
byte[] bytes = new byte[fileInputStream.available()];
|
||||||
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
|
try (DataInputStream dataInputStream = new DataInputStream(fileInputStream)) {
|
||||||
dataInputStream.readFully(bytes);
|
dataInputStream.readFully(bytes);
|
||||||
return bytes;
|
return bytes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|||||||
@@ -138,9 +138,9 @@ public class ZUGFeRDInvoiceImporter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata();
|
try (final InputStream XMP = doc.getDocumentCatalog().getMetadata().exportXMPMetadata()) {
|
||||||
|
xmpString = new String(XMLTools.getBytesFromStream(XMP), StandardCharsets.UTF_8);
|
||||||
xmpString = new String(XMLTools.getBytesFromStream(XMP), StandardCharsets.UTF_8);
|
}
|
||||||
|
|
||||||
final PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles();
|
final PDEmbeddedFilesNameTreeNode etn = names.getEmbeddedFiles();
|
||||||
if (etn == null) {
|
if (etn == null) {
|
||||||
@@ -260,12 +260,23 @@ public class ZUGFeRDInvoiceImporter {
|
|||||||
|
|
||||||
private void setDocument() throws ParserConfigurationException, IOException, SAXException, ParseException {
|
private void setDocument() throws ParserConfigurationException, IOException, SAXException, ParseException {
|
||||||
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
dbf.setNamespaceAware(true);
|
//REDHAT
|
||||||
dbf.setExpandEntityReferences(false);
|
//https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
|
||||||
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
dbf.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
||||||
|
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
|
||||||
|
|
||||||
|
//OWASP
|
||||||
|
//https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||||
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||||
|
// Disable external DTDs as well
|
||||||
|
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||||
|
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
|
||||||
|
dbf.setXIncludeAware(false);
|
||||||
|
dbf.setExpandEntityReferences(false);
|
||||||
|
dbf.setNamespaceAware(true);
|
||||||
final DocumentBuilder builder = dbf.newDocumentBuilder();
|
final DocumentBuilder builder = dbf.newDocumentBuilder();
|
||||||
final ByteArrayInputStream is = new ByteArrayInputStream(rawXML);
|
final ByteArrayInputStream is = new ByteArrayInputStream(rawXML);
|
||||||
/// is.skip(guessBOMSize(is));
|
/// is.skip(guessBOMSize(is));
|
||||||
|
|||||||
@@ -102,12 +102,23 @@ public class ZUGFeRDVisualizer {
|
|||||||
String cioSignature = "SCRDMCCBDACIOMessageStructure";
|
String cioSignature = "SCRDMCCBDACIOMessageStructure";
|
||||||
|
|
||||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
dbf.setNamespaceAware(true);
|
//REDHAT
|
||||||
dbf.setExpandEntityReferences(false);
|
//https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
|
||||||
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
dbf.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
||||||
|
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
|
||||||
|
|
||||||
|
//OWASP
|
||||||
|
//https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||||
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||||
|
// Disable external DTDs as well
|
||||||
|
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||||
|
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
|
||||||
|
dbf.setXIncludeAware(false);
|
||||||
|
dbf.setExpandEntityReferences(false);
|
||||||
|
dbf.setNamespaceAware(true);
|
||||||
try {
|
try {
|
||||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||||
Document doc = db.parse(new InputSource(fis));
|
Document doc = db.parse(new InputSource(fis));
|
||||||
@@ -131,8 +142,9 @@ public class ZUGFeRDVisualizer {
|
|||||||
|
|
||||||
public String visualize(String xmlFilename, Language lang)
|
public String visualize(String xmlFilename, Language lang)
|
||||||
throws IOException, TransformerException, ParserConfigurationException {
|
throws IOException, TransformerException, ParserConfigurationException {
|
||||||
FileInputStream fis = new FileInputStream(xmlFilename);
|
try (FileInputStream fis = new FileInputStream(xmlFilename)) {
|
||||||
return visualize(fis, lang);
|
return visualize(fis, lang);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String visualize(InputStream inputXml, Language lang)
|
public String visualize(InputStream inputXml, Language lang)
|
||||||
@@ -222,12 +234,14 @@ public class ZUGFeRDVisualizer {
|
|||||||
|
|
||||||
protected String toFOP(String xmlFilename)
|
protected String toFOP(String xmlFilename)
|
||||||
throws IOException, TransformerException, ParserConfigurationException {
|
throws IOException, TransformerException, ParserConfigurationException {
|
||||||
|
EStandard theStandard;
|
||||||
FileInputStream fis = new FileInputStream(xmlFilename);
|
try (FileInputStream fis = new FileInputStream(xmlFilename)) {
|
||||||
EStandard theStandard = findOutStandardFromRootNode(fis);
|
theStandard = findOutStandardFromRootNode(fis);
|
||||||
fis = new FileInputStream(xmlFilename);//rewind :-(
|
}
|
||||||
|
|
||||||
return toFOP(fis, theStandard);
|
try (FileInputStream fis = new FileInputStream(xmlFilename)) {
|
||||||
|
return toFOP(fis, theStandard);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String toFOP(InputStream is, EStandard theStandard)
|
protected String toFOP(InputStream is, EStandard theStandard)
|
||||||
|
|||||||
@@ -398,7 +398,7 @@
|
|||||||
<nummer>BT-64</nummer>
|
<nummer>BT-64</nummer>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:when test="$identifier = 'xr:Tax_representative_address_line_2'">
|
<xsl:when test="$identifier = 'xr:Tax_representative_address_line_2'">
|
||||||
<label>Postfach</label>
|
<label>Adresszusatz</label>
|
||||||
<nummer>BT-65</nummer>
|
<nummer>BT-65</nummer>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:when test="$identifier = 'xr:Tax_representative_address_line_3'">
|
<xsl:when test="$identifier = 'xr:Tax_representative_address_line_3'">
|
||||||
@@ -486,7 +486,7 @@
|
|||||||
<nummer>BT-75</nummer>
|
<nummer>BT-75</nummer>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:when test="$identifier = 'xr:Deliver_to_address_line_2'">
|
<xsl:when test="$identifier = 'xr:Deliver_to_address_line_2'">
|
||||||
<label>Postfach</label>
|
<label>Adresszusatz</label>
|
||||||
<nummer>BT-76</nummer>
|
<nummer>BT-76</nummer>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:when test="$identifier = 'xr:Deliver_to_address_line_3'">
|
<xsl:when test="$identifier = 'xr:Deliver_to_address_line_3'">
|
||||||
|
|||||||
@@ -1193,7 +1193,7 @@ function downloadData (element_id) {
|
|||||||
<div id="BT-50" title="BT-50" class="boxdaten wert"><xsl:value-of select="xr:BUYER_POSTAL_ADDRESS/xr:Buyer_address_line_1"/></div>
|
<div id="BT-50" title="BT-50" class="boxdaten wert"><xsl:value-of select="xr:BUYER_POSTAL_ADDRESS/xr:Buyer_address_line_1"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach (BT-51):</div>
|
<div class="boxdaten legende">Adresszusatz (BT-51):</div>
|
||||||
<div id="BT-51" title="BT-51" class="boxdaten wert"><xsl:value-of select="xr:BUYER_POSTAL_ADDRESS/xr:Buyer_address_line_2"/></div>
|
<div id="BT-51" title="BT-51" class="boxdaten wert"><xsl:value-of select="xr:BUYER_POSTAL_ADDRESS/xr:Buyer_address_line_2"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
@@ -1258,7 +1258,7 @@ function downloadData (element_id) {
|
|||||||
<div id="BT-35" title="BT-35" class="boxdaten wert"><xsl:value-of select="xr:SELLER_POSTAL_ADDRESS/xr:Seller_address_line_1"/></div>
|
<div id="BT-35" title="BT-35" class="boxdaten wert"><xsl:value-of select="xr:SELLER_POSTAL_ADDRESS/xr:Seller_address_line_1"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach (BT-36):</div>
|
<div class="boxdaten legende">Adresszusatz (BT-36):</div>
|
||||||
<div id="BT-36" title="BT-36" class="boxdaten wert"><xsl:value-of select="xr:SELLER_POSTAL_ADDRESS/xr:Seller_address_line_2"/></div>
|
<div id="BT-36" title="BT-36" class="boxdaten wert"><xsl:value-of select="xr:SELLER_POSTAL_ADDRESS/xr:Seller_address_line_2"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
@@ -1998,7 +1998,7 @@ function downloadData (element_id) {
|
|||||||
<div id="BT-64" title="BT-64" class="boxdaten wert"><xsl:value-of select="xr:SELLER_TAX_REPRESENTATIVE_POSTAL_ADDRESS/xr:Tax_representative_address_line_1"/></div>
|
<div id="BT-64" title="BT-64" class="boxdaten wert"><xsl:value-of select="xr:SELLER_TAX_REPRESENTATIVE_POSTAL_ADDRESS/xr:Tax_representative_address_line_1"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach (BT-65):</div>
|
<div class="boxdaten legende">Adresszusatz (BT-65):</div>
|
||||||
<div id="BT-65" title="BT-65" class="boxdaten wert"><xsl:value-of select="xr:SELLER_TAX_REPRESENTATIVE_POSTAL_ADDRESS/xr:Tax_representative_address_line_2"/></div>
|
<div id="BT-65" title="BT-65" class="boxdaten wert"><xsl:value-of select="xr:SELLER_TAX_REPRESENTATIVE_POSTAL_ADDRESS/xr:Tax_representative_address_line_2"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
@@ -2111,7 +2111,7 @@ function downloadData (element_id) {
|
|||||||
<div id="BT-75" title="BT-75" class="boxdaten wert"><xsl:value-of select="xr:DELIVER_TO_ADDRESS/xr:Deliver_to_address_line_1"/></div>
|
<div id="BT-75" title="BT-75" class="boxdaten wert"><xsl:value-of select="xr:DELIVER_TO_ADDRESS/xr:Deliver_to_address_line_1"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach (BT-76):</div>
|
<div class="boxdaten legende">Adresszusatz (BT-76):</div>
|
||||||
<div id="BT-76" title="BT-76" class="boxdaten wert"><xsl:value-of select="xr:DELIVER_TO_ADDRESS/xr:Deliver_to_address_line_2"/></div>
|
<div id="BT-76" title="BT-76" class="boxdaten wert"><xsl:value-of select="xr:DELIVER_TO_ADDRESS/xr:Deliver_to_address_line_2"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<xsl:variable name="i18n.recipientInfo" select="'Informationen zum Käufer'"/>
|
<xsl:variable name="i18n.recipientInfo" select="'Informationen zum Käufer'"/>
|
||||||
<xsl:variable name="i18n.dateOf" select="' vom '"/>
|
<xsl:variable name="i18n.dateOf" select="' vom '"/>
|
||||||
<xsl:variable name="i18n.bt50" select="'Straße / Haus-Nr.'"/>
|
<xsl:variable name="i18n.bt50" select="'Straße / Haus-Nr.'"/>
|
||||||
<xsl:variable name="i18n.bt51" select="'Postfach'"/>
|
<xsl:variable name="i18n.bt51" select="'Adresszusatz'"/>
|
||||||
<xsl:variable name="i18n.bt163" select="'Adresszusatz'"/>
|
<xsl:variable name="i18n.bt163" select="'Adresszusatz'"/>
|
||||||
<xsl:variable name="i18n.bt53" select="'PLZ'"/>
|
<xsl:variable name="i18n.bt53" select="'PLZ'"/>
|
||||||
<xsl:variable name="i18n.bt52" select="'Ort'"/>
|
<xsl:variable name="i18n.bt52" select="'Ort'"/>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<xsl:variable name="i18n.bt58" select="'E-Mail-Adresse'"/>
|
<xsl:variable name="i18n.bt58" select="'E-Mail-Adresse'"/>
|
||||||
<xsl:variable name="i18n.bt27" select="'Firmenname'"/>
|
<xsl:variable name="i18n.bt27" select="'Firmenname'"/>
|
||||||
<xsl:variable name="i18n.bt35" select="'Straße / Haus-Nr.'"/>
|
<xsl:variable name="i18n.bt35" select="'Straße / Haus-Nr.'"/>
|
||||||
<xsl:variable name="i18n.bt36" select="'Postfach'"/>
|
<xsl:variable name="i18n.bt36" select="'Adresszusatz'"/>
|
||||||
<xsl:variable name="i18n.bt162" select="'Adresszusatz'"/>
|
<xsl:variable name="i18n.bt162" select="'Adresszusatz'"/>
|
||||||
<xsl:variable name="i18n.bt38" select="'PLZ'"/>
|
<xsl:variable name="i18n.bt38" select="'PLZ'"/>
|
||||||
<xsl:variable name="i18n.bt37" select="'Ort'"/>
|
<xsl:variable name="i18n.bt37" select="'Ort'"/>
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
<xsl:variable name="i18n.bg11" select="'Steuervertreter des Verkäufers'"/>
|
<xsl:variable name="i18n.bg11" select="'Steuervertreter des Verkäufers'"/>
|
||||||
<xsl:variable name="i18n.bt62" select="'Name'"/>
|
<xsl:variable name="i18n.bt62" select="'Name'"/>
|
||||||
<xsl:variable name="i18n.bt64" select="'Straße / Hausnummer'"/>
|
<xsl:variable name="i18n.bt64" select="'Straße / Hausnummer'"/>
|
||||||
<xsl:variable name="i18n.bt65" select="'Postfach'"/>
|
<xsl:variable name="i18n.bt65" select="'Adresszusatz'"/>
|
||||||
<xsl:variable name="i18n.bt164" select="'Adresszusatz'"/>
|
<xsl:variable name="i18n.bt164" select="'Adresszusatz'"/>
|
||||||
<xsl:variable name="i18n.bt67" select="'PLZ'"/>
|
<xsl:variable name="i18n.bt67" select="'PLZ'"/>
|
||||||
<xsl:variable name="i18n.bt66" select="'Ort'"/>
|
<xsl:variable name="i18n.bt66" select="'Ort'"/>
|
||||||
@@ -189,7 +189,7 @@
|
|||||||
<xsl:variable name="i18n.bt72" select="'Lieferdatum'"/>
|
<xsl:variable name="i18n.bt72" select="'Lieferdatum'"/>
|
||||||
<xsl:variable name="i18n.bt70" select="'Name des Empfängers'"/>
|
<xsl:variable name="i18n.bt70" select="'Name des Empfängers'"/>
|
||||||
<xsl:variable name="i18n.bt75" select="'Straße / Haus-Nr.'"/>
|
<xsl:variable name="i18n.bt75" select="'Straße / Haus-Nr.'"/>
|
||||||
<xsl:variable name="i18n.bt76" select="'Postfach'"/>
|
<xsl:variable name="i18n.bt76" select="'Adresszusatz'"/>
|
||||||
<xsl:variable name="i18n.bt165" select="'Adresszusatz'"/>
|
<xsl:variable name="i18n.bt165" select="'Adresszusatz'"/>
|
||||||
<xsl:variable name="i18n.bt78" select="'PLZ'"/>
|
<xsl:variable name="i18n.bt78" select="'PLZ'"/>
|
||||||
<xsl:variable name="i18n.bt77" select="'Ort'"/>
|
<xsl:variable name="i18n.bt77" select="'Ort'"/>
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
<div title="BT-50" class="boxdaten wert"><xsl:value-of select="xr:BUYER_POSTAL_ADDRESS/xr:Buyer_address_line_1"/></div>
|
<div title="BT-50" class="boxdaten wert"><xsl:value-of select="xr:BUYER_POSTAL_ADDRESS/xr:Buyer_address_line_1"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach:</div>
|
<div class="boxdaten legende">Adresszusatz:</div>
|
||||||
<div title="BT-51" class="boxdaten wert"><xsl:value-of select="xr:BUYER_POSTAL_ADDRESS/xr:Buyer_address_line_2"/></div>
|
<div title="BT-51" class="boxdaten wert"><xsl:value-of select="xr:BUYER_POSTAL_ADDRESS/xr:Buyer_address_line_2"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
<div title="BT-35" class="boxdaten wert"><xsl:value-of select="xr:SELLER_POSTAL_ADDRESS/xr:Seller_address_line_1"/></div>
|
<div title="BT-35" class="boxdaten wert"><xsl:value-of select="xr:SELLER_POSTAL_ADDRESS/xr:Seller_address_line_1"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach:</div>
|
<div class="boxdaten legende">Adresszusatz:</div>
|
||||||
<div title="BT-36" class="boxdaten wert"><xsl:value-of select="xr:SELLER_POSTAL_ADDRESS/xr:Seller_address_line_2"/></div>
|
<div title="BT-36" class="boxdaten wert"><xsl:value-of select="xr:SELLER_POSTAL_ADDRESS/xr:Seller_address_line_2"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
@@ -892,7 +892,7 @@
|
|||||||
<div title="BT-64" class="boxdaten wert"><xsl:value-of select="xr:SELLER_TAX_REPRESENTATIVE_POSTAL_ADDRESS/xr:Tax_representative_address_line_1"/></div>
|
<div title="BT-64" class="boxdaten wert"><xsl:value-of select="xr:SELLER_TAX_REPRESENTATIVE_POSTAL_ADDRESS/xr:Tax_representative_address_line_1"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach:</div>
|
<div class="boxdaten legende">Adresszusatz:</div>
|
||||||
<div title="BT-65" class="boxdaten wert"><xsl:value-of select="xr:SELLER_TAX_REPRESENTATIVE_POSTAL_ADDRESS/xr:Tax_representative_address_line_2"/></div>
|
<div title="BT-65" class="boxdaten wert"><xsl:value-of select="xr:SELLER_TAX_REPRESENTATIVE_POSTAL_ADDRESS/xr:Tax_representative_address_line_2"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
@@ -998,7 +998,7 @@
|
|||||||
<div title="BT-75" class="boxdaten wert"><xsl:value-of select="xr:DELIVER_TO_ADDRESS/xr:Deliver_to_address_line_1"/></div>
|
<div title="BT-75" class="boxdaten wert"><xsl:value-of select="xr:DELIVER_TO_ADDRESS/xr:Deliver_to_address_line_1"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach:</div>
|
<div class="boxdaten legende">Adresszusatz:</div>
|
||||||
<div title="BT-76" class="boxdaten wert"><xsl:value-of select="xr:DELIVER_TO_ADDRESS/xr:Deliver_to_address_line_2"/></div>
|
<div title="BT-76" class="boxdaten wert"><xsl:value-of select="xr:DELIVER_TO_ADDRESS/xr:Deliver_to_address_line_2"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
|
|||||||
@@ -178,6 +178,36 @@ public class XRTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testTaxExemptionReasonIssue() {
|
||||||
|
String orgname = "Test company";
|
||||||
|
String number = "123";
|
||||||
|
String amountStr = "1.00";
|
||||||
|
BigDecimal amount = new BigDecimal(amountStr);
|
||||||
|
byte[] b = {12, 13};
|
||||||
|
|
||||||
|
Invoice i = new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
|
||||||
|
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").setEmail("sender@example.com").addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890", "COBADEFXXX").setAccountName("kontoInhaber")))
|
||||||
|
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").setEmail("recipient@sample.org"))
|
||||||
|
.setReferenceNumber("991-01484-64")//leitweg-id
|
||||||
|
// not using any VAT, this is also a test of zero-rated goods:
|
||||||
|
.setNumber(number)
|
||||||
|
.addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO).setTaxCategoryCode("E").setTaxExemptionReason("Kleinunternehmer"), amount, new BigDecimal(1.0)))
|
||||||
|
.addItem(new Item(new Product("Testprodukt2", "", "C62", BigDecimal.ZERO).setTaxCategoryCode("S"), amount, new BigDecimal(1.0)))
|
||||||
|
.setPayee( new TradeParty().setName("VR Factoring GmbH").setID("DE813838785").setLegalOrganisation(new LegalOrganisation("391200LDDFJDMIPPMZ54", "0199")));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
|
||||||
|
|
||||||
|
zf2p.setProfile(Profiles.getByName("XRechnung"));
|
||||||
|
zf2p.generateXML(i);
|
||||||
|
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
|
||||||
|
assertThat(theXML).valueByXPath("count(//*[local-name()='ExemptionReason'])")
|
||||||
|
.asInt()
|
||||||
|
.isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private org.mustangproject.Invoice createInvoice(TradeParty recipient) {
|
private org.mustangproject.Invoice createInvoice(TradeParty recipient) {
|
||||||
String orgname = "Test company";
|
String orgname = "Test company";
|
||||||
|
|||||||
@@ -585,4 +585,16 @@ public class ZF2ZInvoiceImporterTest extends ResourceCase {
|
|||||||
|
|
||||||
assertEquals("0", zii.importedInvoice.getDuePayable().toPlainString());
|
assertEquals("0", zii.importedInvoice.getDuePayable().toPlainString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws FileNotFoundException, XPathExpressionException, ParseException {
|
||||||
|
File inputFile = getResourceAsFile("ORDER-X_EX01_ORDER_FULL_DATA-COMFORTorder-x.xml");
|
||||||
|
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter();
|
||||||
|
zii.doIgnoreCalculationErrors();
|
||||||
|
zii.setInputStream(new FileInputStream(inputFile));
|
||||||
|
|
||||||
|
Invoice invoice = zii.extractInvoice();
|
||||||
|
assertEquals(3, invoice.getZFItems().length);
|
||||||
|
assertEquals("BUYER_ACCOUNTING_REF", invoice.getZFItems()[0].getAccountingReference());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -762,7 +762,7 @@
|
|||||||
<div id="BT-50" title="BT-50" class="boxdaten wert">KUNDENWEG 88</div>
|
<div id="BT-50" title="BT-50" class="boxdaten wert">KUNDENWEG 88</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach:</div>
|
<div class="boxdaten legende">Adresszusatz:</div>
|
||||||
<div id="BT-51" title="BT-51" class="boxdaten wert"></div>
|
<div id="BT-51" title="BT-51" class="boxdaten wert"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
@@ -826,7 +826,7 @@
|
|||||||
<div id="BT-35" title="BT-35" class="boxdaten wert">BAHNHOFSTRASSE 99</div>
|
<div id="BT-35" title="BT-35" class="boxdaten wert">BAHNHOFSTRASSE 99</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach:</div>
|
<div class="boxdaten legende">Adresszusatz:</div>
|
||||||
<div id="BT-36" title="BT-36" class="boxdaten wert"></div>
|
<div id="BT-36" title="BT-36" class="boxdaten wert"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
@@ -2203,7 +2203,7 @@
|
|||||||
<div id="BT-75" title="BT-75" class="boxdaten wert">HAUPTSTRASSE 44</div>
|
<div id="BT-75" title="BT-75" class="boxdaten wert">HAUPTSTRASSE 44</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
<div class="boxdaten legende">Postfach:</div>
|
<div class="boxdaten legende">Adresszusatz:</div>
|
||||||
<div id="BT-76" title="BT-76" class="boxdaten wert"></div>
|
<div id="BT-76" title="BT-76" class="boxdaten wert"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxzeile">
|
<div class="boxzeile">
|
||||||
|
|||||||
@@ -150,13 +150,23 @@ public class XMLValidator extends Validator {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
dbf.setNamespaceAware(true); // otherwise we can not act namespace independently, i.e. use
|
//REDHAT
|
||||||
// document.getElementsByTagNameNS("*",...
|
//https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
|
||||||
dbf.setExpandEntityReferences(false);
|
dbf.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
||||||
|
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
|
||||||
|
|
||||||
|
//OWASP
|
||||||
|
//https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||||
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||||
|
// Disable external DTDs as well
|
||||||
|
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||||
|
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
|
||||||
|
dbf.setXIncludeAware(false);
|
||||||
|
dbf.setExpandEntityReferences(false);
|
||||||
|
dbf.setNamespaceAware(true);
|
||||||
|
|
||||||
final DocumentBuilder db = dbf.newDocumentBuilder();
|
final DocumentBuilder db = dbf.newDocumentBuilder();
|
||||||
final InputSource is = new InputSource(new StringReader(zfXML));
|
final InputSource is = new InputSource(new StringReader(zfXML));
|
||||||
|
|||||||
@@ -143,12 +143,23 @@ public class ZUGFeRDValidator {
|
|||||||
String xmlAsString = null;
|
String xmlAsString = null;
|
||||||
try {
|
try {
|
||||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
dbf.setNamespaceAware(true);
|
//REDHAT
|
||||||
dbf.setExpandEntityReferences(false);
|
//https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
|
||||||
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
dbf.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
||||||
|
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
|
||||||
|
|
||||||
|
//OWASP
|
||||||
|
//https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||||
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||||
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||||
|
// Disable external DTDs as well
|
||||||
|
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||||
|
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
|
||||||
|
dbf.setXIncludeAware(false);
|
||||||
|
dbf.setExpandEntityReferences(false);
|
||||||
|
dbf.setNamespaceAware(true);
|
||||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||||
|
|
||||||
content = XMLTools.removeBOM(content);
|
content = XMLTools.removeBOM(content);
|
||||||
@@ -301,6 +312,7 @@ public class ZUGFeRDValidator {
|
|||||||
XMLWriter writer = new XMLWriter(sw, format);
|
XMLWriter writer = new XMLWriter(sw, format);
|
||||||
try {
|
try {
|
||||||
writer.write(document);
|
writer.write(document);
|
||||||
|
writer.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error(e.getMessage());
|
LOGGER.error(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user