use XMLUnit
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -88,6 +88,12 @@
|
|||||||
<version>5.0.4</version>
|
<version>5.0.4</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xmlunit</groupId>
|
||||||
|
<artifactId>xmlunit-core</artifactId>
|
||||||
|
<version>2.6.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<!-- For Toecount -->
|
<!-- For Toecount -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sanityinc</groupId>
|
<groupId>com.sanityinc</groupId>
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import org.junit.BeforeClass;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.xmlunit.builder.DiffBuilder;
|
||||||
|
import org.xmlunit.diff.Diff;
|
||||||
|
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -28,10 +30,11 @@ import java.io.IOException;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every ZUGFeRD 1.0 XML file from <code>src/test/resources/migration/input</code>
|
* Every ZUGFeRD 1.0 XML file from <code>src/test/resources/migration/input</code>
|
||||||
@@ -69,9 +72,8 @@ public class VersionMigrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void addFilesFromFolder(final File folder, Collection<Object[]> testSuiteData) {
|
private static void addFilesFromFolder(final File folder, Collection<Object[]> testSuiteData) {
|
||||||
String filePath = null;
|
|
||||||
for (final File fileEntry : folder.listFiles()) {
|
for (final File fileEntry : folder.listFiles()) {
|
||||||
filePath = fileEntry.getAbsolutePath();
|
String filePath = fileEntry.getAbsolutePath();
|
||||||
if (fileEntry.isDirectory()) {
|
if (fileEntry.isDirectory()) {
|
||||||
LOG.log(Level.INFO, "*** testDirectory:{0}", filePath);
|
LOG.log(Level.INFO, "*** testDirectory:{0}", filePath);
|
||||||
addFilesFromFolder(fileEntry, testSuiteData);
|
addFilesFromFolder(fileEntry, testSuiteData);
|
||||||
@@ -100,20 +102,8 @@ public class VersionMigrationTest {
|
|||||||
// we need to save the string and reload it otherwise two bytes are missing (likely EOF related)
|
// we need to save the string and reload it otherwise two bytes are missing (likely EOF related)
|
||||||
String outXML = ResourceUtilities.readFile(StandardCharsets.UTF_8, OUTPUT_DIR + newName);
|
String outXML = ResourceUtilities.readFile(StandardCharsets.UTF_8, OUTPUT_DIR + newName);
|
||||||
String refXML = ResourceUtilities.readFile(StandardCharsets.UTF_8, REFERENCE_DIR + newName);
|
String refXML = ResourceUtilities.readFile(StandardCharsets.UTF_8, REFERENCE_DIR + newName);
|
||||||
int t = outXML.length();
|
Diff myDiff = DiffBuilder.compare(refXML).withTest(outXML).checkForSimilar().ignoreComments().ignoreWhitespace().build();
|
||||||
int r = refXML.length();
|
assertFalse(myDiff.toString(), myDiff.hasDifferences());
|
||||||
if (t != r || !(outXML.equals(refXML))) {
|
|
||||||
LOG.info("There are differences between:"
|
|
||||||
+ "\nZUGFeRD 2.0 Test Output @ " + OUTPUT_DIR + newName
|
|
||||||
+ "\nZUGFeRD 2.0 Test Reference @ " + REFERENCE_DIR + newName);
|
|
||||||
LOG.info("\n\nFile sizes:\n "
|
|
||||||
+ "\nZUGFeRD 2.0 Test Output character count: " + t
|
|
||||||
+ "\nZUGFeRD 2.0 Test Refer. character count: " + r);
|
|
||||||
findLineDiffs(outXML, refXML);
|
|
||||||
Assert.fail("Version update failed, as test result and reference are different!");
|
|
||||||
} else {
|
|
||||||
LOG.log(Level.INFO, "\n*** Tested successfull migration from ZUGFeRD 1.0 to 2.0: '" + newName + "'' ***\n", OUTPUT_DIR);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
LOG.log(Level.INFO, "\n*** Migrated from ZUGFeRD 1.0 to 2.0 invoice: '" + newName + "'' ***\n", OUTPUT_DIR);
|
LOG.log(Level.INFO, "\n*** Migrated from ZUGFeRD 1.0 to 2.0 invoice: '" + newName + "'' ***\n", OUTPUT_DIR);
|
||||||
}
|
}
|
||||||
@@ -123,22 +113,4 @@ public class VersionMigrationTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void findLineDiffs(String outXML, String refXML) {
|
|
||||||
Scanner outScanner = new Scanner(outXML);
|
|
||||||
Scanner refScanner = new Scanner(refXML);
|
|
||||||
String outLine = null;
|
|
||||||
String refLine = null;
|
|
||||||
while (outScanner.hasNextLine() && refScanner.hasNextLine()) {
|
|
||||||
outLine = outScanner.nextLine();
|
|
||||||
refLine = refScanner.nextLine();
|
|
||||||
if (!outLine.equals(refLine)) {
|
|
||||||
LOG.info("First line difference between reference and output file:" +
|
|
||||||
"\nRefLine: " + refLine +
|
|
||||||
"\nOutLine: " + outLine + "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
refScanner.close();
|
|
||||||
outScanner.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,9 @@
|
|||||||
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
|
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
|
||||||
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
|
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
|
||||||
xmlns:qdt="urn:un:unece:uncefact:data:Standard:QualifiedDataType:100"
|
xmlns:qdt="urn:un:unece:uncefact:data:Standard:QualifiedDataType:100"
|
||||||
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"><!--
|
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
|
||||||
Migrated by Mustangproject XSLT
|
<!--Migrated by Mustangproject XSLT-->
|
||||||
--><rsm:ExchangedDocumentContext>
|
<rsm:ExchangedDocumentContext>
|
||||||
<ram:TestIndicator>
|
<ram:TestIndicator>
|
||||||
<udt:Indicator>false</udt:Indicator>
|
<udt:Indicator>false</udt:Indicator>
|
||||||
</ram:TestIndicator>
|
</ram:TestIndicator>
|
||||||
@@ -28,7 +28,7 @@ Migrated by Mustangproject XSLT
|
|||||||
<ram:ID>urn:ferd:CrossIndustryDocument:invoice:1p0:extended</ram:ID>
|
<ram:ID>urn:ferd:CrossIndustryDocument:invoice:1p0:extended</ram:ID>
|
||||||
</ram:GuidelineSpecifiedDocumentContextParameter>
|
</ram:GuidelineSpecifiedDocumentContextParameter>
|
||||||
</rsm:ExchangedDocumentContext>
|
</rsm:ExchangedDocumentContext>
|
||||||
<rsm:ExchangedDocument xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
|
<rsm:ExchangedDocument xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
|
||||||
<ram:ID>RE-20170509/505</ram:ID>
|
<ram:ID>RE-20170509/505</ram:ID>
|
||||||
<ram:Name>RECHNUNG</ram:Name>
|
<ram:Name>RECHNUNG</ram:Name>
|
||||||
<ram:TypeCode>380</ram:TypeCode>
|
<ram:TypeCode>380</ram:TypeCode>
|
||||||
@@ -36,16 +36,16 @@ Migrated by Mustangproject XSLT
|
|||||||
<udt:DateTimeString format="102">20170509</udt:DateTimeString>
|
<udt:DateTimeString format="102">20170509</udt:DateTimeString>
|
||||||
</ram:IssueDateTime>
|
</ram:IssueDateTime>
|
||||||
</rsm:ExchangedDocument>
|
</rsm:ExchangedDocument>
|
||||||
<rsm:SupplyChainTradeTransaction xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
|
<rsm:SupplyChainTradeTransaction xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">
|
||||||
<ram:IncludedSupplyChainTradeLineItem>
|
<ram:IncludedSupplyChainTradeLineItem>
|
||||||
<ram:AssociatedDocumentLineDocument>
|
<ram:AssociatedDocumentLineDocument>
|
||||||
<ram:LineID>1</ram:LineID>
|
<ram:LineID>1</ram:LineID>
|
||||||
</ram:AssociatedDocumentLineDocument>
|
</ram:AssociatedDocumentLineDocument>
|
||||||
<ram:SpecifiedTradeProduct>
|
<ram:SpecifiedTradeProduct>
|
||||||
<ram:Name>Künstlerische Gestaltung (Stunde): Einer Beispielrechnung</ram:Name>
|
<ram:Name>Künstlerische Gestaltung (Stunde): Einer Beispielrechnung</ram:Name>
|
||||||
<ram:Description/>
|
<ram:Description/>
|
||||||
</ram:SpecifiedTradeProduct>
|
</ram:SpecifiedTradeProduct>
|
||||||
<ram:SpecifiedLineTradeAgreement>
|
<ram:SpecifiedLineTradeAgreement>
|
||||||
<ram:GrossPriceProductTradePrice>
|
<ram:GrossPriceProductTradePrice>
|
||||||
<ram:ChargeAmount currencyID="EUR">160.0000</ram:ChargeAmount>
|
<ram:ChargeAmount currencyID="EUR">160.0000</ram:ChargeAmount>
|
||||||
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
|
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
|
||||||
@@ -55,10 +55,10 @@ Migrated by Mustangproject XSLT
|
|||||||
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
|
<ram:BasisQuantity unitCode="HUR">1.0000</ram:BasisQuantity>
|
||||||
</ram:NetPriceProductTradePrice>
|
</ram:NetPriceProductTradePrice>
|
||||||
</ram:SpecifiedLineTradeAgreement>
|
</ram:SpecifiedLineTradeAgreement>
|
||||||
<ram:SpecifiedLineTradeDelivery>
|
<ram:SpecifiedLineTradeDelivery>
|
||||||
<ram:BilledQuantity unitCode="HUR">1.0000</ram:BilledQuantity>
|
<ram:BilledQuantity unitCode="HUR">1.0000</ram:BilledQuantity>
|
||||||
</ram:SpecifiedLineTradeDelivery>
|
</ram:SpecifiedLineTradeDelivery>
|
||||||
<ram:SpecifiedLineTradeSettlement>
|
<ram:SpecifiedLineTradeSettlement>
|
||||||
<ram:ApplicableTradeTax>
|
<ram:ApplicableTradeTax>
|
||||||
<ram:TypeCode>VAT</ram:TypeCode>
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
<ram:CategoryCode>S</ram:CategoryCode>
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
@@ -68,16 +68,16 @@ Migrated by Mustangproject XSLT
|
|||||||
<ram:LineTotalAmount currencyID="EUR">160.00</ram:LineTotalAmount>
|
<ram:LineTotalAmount currencyID="EUR">160.00</ram:LineTotalAmount>
|
||||||
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
</ram:SpecifiedLineTradeSettlement>
|
</ram:SpecifiedLineTradeSettlement>
|
||||||
</ram:IncludedSupplyChainTradeLineItem>
|
</ram:IncludedSupplyChainTradeLineItem>
|
||||||
<ram:IncludedSupplyChainTradeLineItem>
|
<ram:IncludedSupplyChainTradeLineItem>
|
||||||
<ram:AssociatedDocumentLineDocument>
|
<ram:AssociatedDocumentLineDocument>
|
||||||
<ram:LineID>2</ram:LineID>
|
<ram:LineID>2</ram:LineID>
|
||||||
</ram:AssociatedDocumentLineDocument>
|
</ram:AssociatedDocumentLineDocument>
|
||||||
<ram:SpecifiedTradeProduct>
|
<ram:SpecifiedTradeProduct>
|
||||||
<ram:Name>Luftballon: Bunt, ca. 500ml</ram:Name>
|
<ram:Name>Luftballon: Bunt, ca. 500ml</ram:Name>
|
||||||
<ram:Description/>
|
<ram:Description/>
|
||||||
</ram:SpecifiedTradeProduct>
|
</ram:SpecifiedTradeProduct>
|
||||||
<ram:SpecifiedLineTradeAgreement>
|
<ram:SpecifiedLineTradeAgreement>
|
||||||
<ram:GrossPriceProductTradePrice>
|
<ram:GrossPriceProductTradePrice>
|
||||||
<ram:ChargeAmount currencyID="EUR">0.7900</ram:ChargeAmount>
|
<ram:ChargeAmount currencyID="EUR">0.7900</ram:ChargeAmount>
|
||||||
<ram:BasisQuantity unitCode="C62">1.0000</ram:BasisQuantity>
|
<ram:BasisQuantity unitCode="C62">1.0000</ram:BasisQuantity>
|
||||||
@@ -87,10 +87,10 @@ Migrated by Mustangproject XSLT
|
|||||||
<ram:BasisQuantity unitCode="C62">1.0000</ram:BasisQuantity>
|
<ram:BasisQuantity unitCode="C62">1.0000</ram:BasisQuantity>
|
||||||
</ram:NetPriceProductTradePrice>
|
</ram:NetPriceProductTradePrice>
|
||||||
</ram:SpecifiedLineTradeAgreement>
|
</ram:SpecifiedLineTradeAgreement>
|
||||||
<ram:SpecifiedLineTradeDelivery>
|
<ram:SpecifiedLineTradeDelivery>
|
||||||
<ram:BilledQuantity unitCode="C62">400.0000</ram:BilledQuantity>
|
<ram:BilledQuantity unitCode="C62">400.0000</ram:BilledQuantity>
|
||||||
</ram:SpecifiedLineTradeDelivery>
|
</ram:SpecifiedLineTradeDelivery>
|
||||||
<ram:SpecifiedLineTradeSettlement>
|
<ram:SpecifiedLineTradeSettlement>
|
||||||
<ram:ApplicableTradeTax>
|
<ram:ApplicableTradeTax>
|
||||||
<ram:TypeCode>VAT</ram:TypeCode>
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
<ram:CategoryCode>S</ram:CategoryCode>
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
@@ -100,16 +100,16 @@ Migrated by Mustangproject XSLT
|
|||||||
<ram:LineTotalAmount currencyID="EUR">316.00</ram:LineTotalAmount>
|
<ram:LineTotalAmount currencyID="EUR">316.00</ram:LineTotalAmount>
|
||||||
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
</ram:SpecifiedLineTradeSettlement>
|
</ram:SpecifiedLineTradeSettlement>
|
||||||
</ram:IncludedSupplyChainTradeLineItem>
|
</ram:IncludedSupplyChainTradeLineItem>
|
||||||
<ram:IncludedSupplyChainTradeLineItem>
|
<ram:IncludedSupplyChainTradeLineItem>
|
||||||
<ram:AssociatedDocumentLineDocument>
|
<ram:AssociatedDocumentLineDocument>
|
||||||
<ram:LineID>3</ram:LineID>
|
<ram:LineID>3</ram:LineID>
|
||||||
</ram:AssociatedDocumentLineDocument>
|
</ram:AssociatedDocumentLineDocument>
|
||||||
<ram:SpecifiedTradeProduct>
|
<ram:SpecifiedTradeProduct>
|
||||||
<ram:Name>Heiße Luft pro Liter</ram:Name>
|
<ram:Name>Heiße Luft pro Liter</ram:Name>
|
||||||
<ram:Description/>
|
<ram:Description/>
|
||||||
</ram:SpecifiedTradeProduct>
|
</ram:SpecifiedTradeProduct>
|
||||||
<ram:SpecifiedLineTradeAgreement>
|
<ram:SpecifiedLineTradeAgreement>
|
||||||
<ram:GrossPriceProductTradePrice>
|
<ram:GrossPriceProductTradePrice>
|
||||||
<ram:ChargeAmount currencyID="EUR">0.1000</ram:ChargeAmount>
|
<ram:ChargeAmount currencyID="EUR">0.1000</ram:ChargeAmount>
|
||||||
<ram:BasisQuantity unitCode="LTR">1.0000</ram:BasisQuantity>
|
<ram:BasisQuantity unitCode="LTR">1.0000</ram:BasisQuantity>
|
||||||
@@ -119,10 +119,10 @@ Migrated by Mustangproject XSLT
|
|||||||
<ram:BasisQuantity unitCode="LTR">1.0000</ram:BasisQuantity>
|
<ram:BasisQuantity unitCode="LTR">1.0000</ram:BasisQuantity>
|
||||||
</ram:NetPriceProductTradePrice>
|
</ram:NetPriceProductTradePrice>
|
||||||
</ram:SpecifiedLineTradeAgreement>
|
</ram:SpecifiedLineTradeAgreement>
|
||||||
<ram:SpecifiedLineTradeDelivery>
|
<ram:SpecifiedLineTradeDelivery>
|
||||||
<ram:BilledQuantity unitCode="LTR">200.0000</ram:BilledQuantity>
|
<ram:BilledQuantity unitCode="LTR">200.0000</ram:BilledQuantity>
|
||||||
</ram:SpecifiedLineTradeDelivery>
|
</ram:SpecifiedLineTradeDelivery>
|
||||||
<ram:SpecifiedLineTradeSettlement>
|
<ram:SpecifiedLineTradeSettlement>
|
||||||
<ram:ApplicableTradeTax>
|
<ram:ApplicableTradeTax>
|
||||||
<ram:TypeCode>VAT</ram:TypeCode>
|
<ram:TypeCode>VAT</ram:TypeCode>
|
||||||
<ram:CategoryCode>S</ram:CategoryCode>
|
<ram:CategoryCode>S</ram:CategoryCode>
|
||||||
@@ -132,8 +132,8 @@ Migrated by Mustangproject XSLT
|
|||||||
<ram:LineTotalAmount currencyID="EUR">20.00</ram:LineTotalAmount>
|
<ram:LineTotalAmount currencyID="EUR">20.00</ram:LineTotalAmount>
|
||||||
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
</ram:SpecifiedTradeSettlementLineMonetarySummation>
|
||||||
</ram:SpecifiedLineTradeSettlement>
|
</ram:SpecifiedLineTradeSettlement>
|
||||||
</ram:IncludedSupplyChainTradeLineItem>
|
</ram:IncludedSupplyChainTradeLineItem>
|
||||||
<ram:ApplicableHeaderTradeAgreement>
|
<ram:ApplicableHeaderTradeAgreement>
|
||||||
<ram:SellerTradeParty>
|
<ram:SellerTradeParty>
|
||||||
<ram:Name>Bei Spiel GmbH</ram:Name>
|
<ram:Name>Bei Spiel GmbH</ram:Name>
|
||||||
<ram:PostalTradeAddress>
|
<ram:PostalTradeAddress>
|
||||||
@@ -162,14 +162,14 @@ Migrated by Mustangproject XSLT
|
|||||||
</ram:SpecifiedTaxRegistration>
|
</ram:SpecifiedTaxRegistration>
|
||||||
</ram:BuyerTradeParty>
|
</ram:BuyerTradeParty>
|
||||||
</ram:ApplicableHeaderTradeAgreement>
|
</ram:ApplicableHeaderTradeAgreement>
|
||||||
<ram:ApplicableHeaderTradeDelivery>
|
<ram:ApplicableHeaderTradeDelivery>
|
||||||
<ram:ActualDeliverySupplyChainEvent>
|
<ram:ActualDeliverySupplyChainEvent>
|
||||||
<ram:OccurrenceDateTime>
|
<ram:OccurrenceDateTime>
|
||||||
<udt:DateTimeString format="102">20170507</udt:DateTimeString>
|
<udt:DateTimeString format="102">20170507</udt:DateTimeString>
|
||||||
</ram:OccurrenceDateTime>
|
</ram:OccurrenceDateTime>
|
||||||
</ram:ActualDeliverySupplyChainEvent>
|
</ram:ActualDeliverySupplyChainEvent>
|
||||||
</ram:ApplicableHeaderTradeDelivery>
|
</ram:ApplicableHeaderTradeDelivery>
|
||||||
<ram:ApplicableHeaderTradeSettlement>
|
<ram:ApplicableHeaderTradeSettlement>
|
||||||
<ram:PaymentReference>RE-20170509/505</ram:PaymentReference>
|
<ram:PaymentReference>RE-20170509/505</ram:PaymentReference>
|
||||||
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
|
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
|
||||||
<ram:SpecifiedTradeSettlementPaymentMeans>
|
<ram:SpecifiedTradeSettlementPaymentMeans>
|
||||||
@@ -215,6 +215,6 @@ Migrated by Mustangproject XSLT
|
|||||||
<ram:DuePayableAmount currencyID="EUR">571.04</ram:DuePayableAmount>
|
<ram:DuePayableAmount currencyID="EUR">571.04</ram:DuePayableAmount>
|
||||||
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
|
||||||
</ram:ApplicableHeaderTradeSettlement>
|
</ram:ApplicableHeaderTradeSettlement>
|
||||||
</rsm:SupplyChainTradeTransaction>
|
</rsm:SupplyChainTradeTransaction>
|
||||||
</rsm:CrossIndustryInvoice>
|
</rsm:CrossIndustryInvoice>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user