deliveradvice corrections

This commit is contained in:
jstaerk
2022-05-03 20:51:52 +02:00
parent ef24a7f95d
commit 7078c4adf8
8 changed files with 437 additions and 19 deletions

View File

@@ -1,3 +1,6 @@
- upgraded en16931 validation to 1.3.8
- Be able to embed Cross Industry Delivery Advice
- update xr to v. 2.2
2.5.0
=======
2022-04-07

View File

@@ -580,7 +580,7 @@ public class Main {
if (format == null) {
try {
format = getStringFromUser("Format (fx=Factur-X, zf=ZUGFeRD, ox=Order-X)", "zf", "fx|zf|ox|dx");
format = getStringFromUser("Format (fx=Factur-X, zf=ZUGFeRD, ox=Order-X, da=Cross Industry Despatch Advice)", "zf", "fx|zf|ox|da");
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
@@ -603,7 +603,7 @@ public class Main {
try {
if ((format.equals("zf") && (zfIntVersion == 1)) || (format.equals("ox") )) {
zfProfile = getStringFromUser("Profile (b)asic, (c)omfort or ex(t)ended", "t", "B|b|C|c|T|t");
} else if ( (format.equals("dx"))) {
} else if ( (format.equals("da"))) {
zfProfile = getStringFromUser("Profile (p)ilot", "p", "P|p");
} else {
zfProfile = getStringFromUser(
@@ -630,8 +630,8 @@ public class Main {
}
EStandard standard=EStandard.facturx;
if (format.equals("dx")) {
standard=EStandard.deliverx;
if (format.equals("da")) {
standard=EStandard.deliveradvice;
zfConformanceLevelProfile = Profiles.getByName(standard, "PILOT", 1);
}
@@ -682,7 +682,7 @@ public class Main {
((OXExporterFromA1)ze).ignorePDFAErrors();
}
} else if (format.equals("dx")) {
} else if (format.equals("da")) {
ze = new DXExporterFromA1().setProducer("Mustang-cli")
.setZUGFeRDVersion(zfIntVersion)
.setCreator(System.getProperty("user.name")).setProfile(zfConformanceLevelProfile);

View File

@@ -1,6 +1,6 @@
package org.mustangproject;
public enum EStandard {
facturx, orderx, deliverx, zugferd, cii, ubl
facturx, orderx, deliveradvice, zugferd, cii, ubl
}

View File

@@ -0,0 +1,358 @@
/**
* *********************************************************************
* <p>
* Copyright 2018 Jochen Staerk
* <p>
* Use is subject to license terms.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* <p>
* See the License for the specific language governing permissions and
* limitations under the License.
* <p>
* **********************************************************************
*/
package org.mustangproject.ZUGFeRD;
import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE;
import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE;
import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.mustangproject.*;
public class DAPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider {
protected IExportableTransaction trans;
private String paymentTermsDescription;
protected Profile profile = Profiles.getByName(EStandard.deliveradvice,"pilot", 1);
@Override
public void generateXML(IExportableTransaction trans) {
this.trans = trans;
boolean hasDueDate = false;
final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
final String exemptionReason = "";
String senderReg = "";
if (trans.getOwnOrganisationFullPlaintextInfo() != null) {
senderReg = "<ram:IncludedNote><ram:Content>"
+ XMLTools.encodeXML(trans.getOwnOrganisationFullPlaintextInfo()) + "</ram:Content>"
+ "<ram:SubjectCode>REG</ram:SubjectCode></ram:IncludedNote>";
}
String subjectNote = "";
if (trans.getSubjectNote() != null) {
subjectNote = "<ram:IncludedNote><ram:Content>"
+ XMLTools.encodeXML(trans.getSubjectNote()) + "</ram:Content>"
+ "</ram:IncludedNote>";
}
final String typecode = "220";
/*if (trans.getDocumentCode() != null) {
typecode = trans.getDocumentCode();
}*/
String notes = "";
if (trans.getNotes() != null) {
for (final String currentNote : trans.getNotes()) {
notes += "<ram:IncludedNote><ram:Content>" + XMLTools.encodeXML(currentNote) + "</ram:Content></ram:IncludedNote>";
}
}
String testBooleanStr="true";
String xml = "<SCRDMCCBDACIDAMessageStructure\n" +
" xmlns:udt=\"urn:un:unece:uncefact:data:standard:UnqualifiedDataType:25\"\n" +
" xmlns:ram=\"urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:101\"\n" +
" xmlns:px=\"urn:un:unece:uncefact:data:standard:SCRDMCCBDACIDAMessageStructure:1\">\n"
// + "
// xsi:schemaLocation=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100
// ../Schema/ZUGFeRD1p0.xsd\""
+ "<px:ExchangedDocumentContext>"
// + "
+" <ram:TestIndicator><udt:Indicator>"+testBooleanStr+"</udt:Indicator></ram:TestIndicator>\n"
//
+ "<ram:BusinessProcessSpecifiedDocumentContextParameter>"
+ "<ram:ID>" + getProfile().getID() + "</ram:ID>"
+ "</ram:BusinessProcessSpecifiedDocumentContextParameter>"
+ "</px:ExchangedDocumentContext>"
+ "<px:ExchangedDocument>"
+ "<ram:ID>" + XMLTools.encodeXML(trans.getNumber()) + "</ram:ID>"
// + " <ram:Name>RECHNUNG</ram:Name>"
// + "<ram:TypeCode>380</ram:TypeCode>"
+ "<ram:TypeCode>" + typecode + "</ram:TypeCode>"
+ "<ram:IssueDateTime>"
+ DATE.udtFormat(trans.getIssueDate()) + "</ram:IssueDateTime>" // date
+ notes
+ subjectNote
+ senderReg
+ "</px:ExchangedDocument>"
+ "<px:SupplyChainTradeTransaction>";
int lineID = 0;
for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
lineID++;
if (currentItem.getProduct().getTaxExemptionReason() != null) {
// exemptionReason = "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>";
}
notes = "";
if (currentItem.getNotes() != null) {
for (final String currentNote : currentItem.getNotes()) {
notes = notes + "<ram:IncludedNote><ram:Content>" + XMLTools.encodeXML(currentNote) + "</ram:Content></ram:IncludedNote>";
}
}
final LineCalculator lc = new LineCalculator(currentItem);
xml += "<ram:IncludedSupplyChainTradeLineItem>" +
"<ram:AssociatedDocumentLineDocument>"
+ "<ram:LineID>" + lineID + "</ram:LineID>"
+ notes
+ "</ram:AssociatedDocumentLineDocument>"
+ "<ram:SpecifiedTradeProduct>";
// + " <GlobalID schemeID=\"0160\">4012345001235</GlobalID>"
if (currentItem.getProduct().getSellerAssignedID() != null) {
xml += "<ram:SellerAssignedID>"
+ XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + "</ram:SellerAssignedID>";
}
if (currentItem.getProduct().getBuyerAssignedID() != null) {
xml += "<ram:BuyerAssignedID>"
+ XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "</ram:BuyerAssignedID>";
}
String allowanceChargeStr = "";
if (currentItem.getItemAllowances() != null && currentItem.getItemAllowances().length > 0) {
for (final IZUGFeRDAllowanceCharge allowance : currentItem.getItemAllowances()) {
allowanceChargeStr += getAllowanceChargeStr(allowance, currentItem);
}
}
if (currentItem.getItemCharges() != null && currentItem.getItemCharges().length > 0) {
for (final IZUGFeRDAllowanceCharge charge : currentItem.getItemCharges()) {
allowanceChargeStr += getAllowanceChargeStr(charge, currentItem);
}
}
xml += "<ram:Name>" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "</ram:Name>"
+ "<ram:Description>" + XMLTools.encodeXML(currentItem.getProduct().getDescription())
+ "</ram:Description>"
+ "</ram:SpecifiedTradeProduct>"
+ "<ram:SpecifiedLineTradeDelivery>"
+ "<ram:DespatchedQuantity unitCode=\"" + XMLTools.encodeXML(currentItem.getProduct().getUnit()) + "\">"
+ quantityFormat(currentItem.getQuantity()) + "</ram:DespatchedQuantity>"
+ "</ram:SpecifiedLineTradeDelivery>"
+ "<ram:SpecifiedLineTradeSettlement>";
if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) {
xml += "<ram:BillingSpecifiedPeriod>";
if (currentItem.getDetailedDeliveryPeriodFrom() != null) {
xml += "<ram:StartDateTime>" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodFrom()) + "</ram:StartDateTime>";
}
if (currentItem.getDetailedDeliveryPeriodTo() != null) {
xml += "<ram:EndDateTime>" + DATE.udtFormat(currentItem.getDetailedDeliveryPeriodTo()) + "</ram:EndDateTime>";
}
xml += "</ram:BillingSpecifiedPeriod>";
}
xml += "<ram:SpecifiedTradeSettlementLineMonetarySummation>"
+ "<ram:LineTotalAmount>" + currencyFormat(lc.getItemTotalNetAmount())
+ "</ram:LineTotalAmount>" // currencyID=\"EUR\"
+ "</ram:SpecifiedTradeSettlementLineMonetarySummation>";
/* if (currentItem.getAdditionalReferencedDocumentID() != null) {
xml += "<ram:AdditionalReferencedDocument><ram:IssuerAssignedID>" + currentItem.getAdditionalReferencedDocumentID() + "</ram:IssuerAssignedID><ram:TypeCode>130</ram:TypeCode></ram:AdditionalReferencedDocument>";
}*/
xml += "</ram:SpecifiedLineTradeSettlement>"
+ "</ram:IncludedSupplyChainTradeLineItem>";
}
xml += "<ram:ApplicableHeaderTradeAgreement>";
if (trans.getReferenceNumber() != null) {
xml += "<ram:BuyerReference>" + XMLTools.encodeXML(trans.getReferenceNumber()) + "</ram:BuyerReference>";
}
xml += "<ram:SellerTradeParty>"
+ getTradePartyAsXML(trans.getSender(), true, false)
+ "</ram:SellerTradeParty>"
+ "<ram:BuyerTradeParty>";
// + " <ID>GE2020211</ID>"
// + " <GlobalID schemeID=\"0088\">4000001987658</GlobalID>"
xml += getTradePartyAsXML(trans.getRecipient(), false, false);
xml += "</ram:BuyerTradeParty>";
if (trans.getSellerOrderReferencedDocumentID() != null) {
xml += "<ram:SellerOrderReferencedDocument>"
+ "<ram:IssuerAssignedID>"
+ XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + "</ram:IssuerAssignedID>"
+ "</ram:SellerOrderReferencedDocument>";
}
if (trans.getBuyerOrderReferencedDocumentID() != null) {
xml += "<ram:BuyerOrderReferencedDocument>"
+ "<ram:IssuerAssignedID>"
+ XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + "</ram:IssuerAssignedID>"
+ "</ram:BuyerOrderReferencedDocument>";
}
if (trans.getContractReferencedDocument() != null) {
xml += "<ram:ContractReferencedDocument>"
+ "<ram:IssuerAssignedID>"
+ XMLTools.encodeXML(trans.getContractReferencedDocument()) + "</ram:IssuerAssignedID>"
+ "</ram:ContractReferencedDocument>";
}
// Additional Documents of XRechnung (Rechnungsbegruendende Unterlagen - BG-24 XRechnung)
if (trans.getAdditionalReferencedDocuments() != null) {
for (final FileAttachment f : trans.getAdditionalReferencedDocuments()) {
final String documentContent = new String(Base64.getEncoder().encodeToString(f.getData()));
xml += "<ram:AdditionalReferencedDocument>"
+ "<ram:IssuerAssignedID>" + f.getFilename() + "</ram:IssuerAssignedID>"
+ "<ram:TypeCode>916</ram:TypeCode>"
+ "<ram:Name>" + f.getDescription() + "</ram:Name>"
+ "<ram:AttachmentBinaryObject mimeCode=\"" + f.getMimetype() + "\"\n"
+ "filename=\"" + f.getFilename() + "\">" + documentContent + "</ram:AttachmentBinaryObject>"
+ "</ram:AdditionalReferencedDocument>";
}
}
if (trans.getSpecifiedProcuringProjectID() != null) {
xml += "<ram:SpecifiedProcuringProject>"
+ "<ram:ID>"
+ XMLTools.encodeXML(trans.getSpecifiedProcuringProjectID()) + "</ram:ID>";
if (trans.getSpecifiedProcuringProjectName() != null) {
xml += "<ram:Name >" + XMLTools.encodeXML(trans.getSpecifiedProcuringProjectName()) + "</ram:Name>";
}
xml += "</ram:SpecifiedProcuringProject>";
}
xml += "</ram:ApplicableHeaderTradeAgreement>"
+ "<ram:ApplicableHeaderTradeDelivery>";
if (this.trans.getDeliveryAddress() != null) {
xml += "<ram:ShipToTradeParty>" +
getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) +
"</ram:ShipToTradeParty>";
}
xml += " <ram:ActualDespatchSupplyChainEvent>\n" +
" <ram:OccurrenceDateTime>\n" +
" <udt:DateTimeString\n" +
" format=\"102\">"+ DATE.udtFormat(trans.getDeliveryDate() )+"</udt:DateTimeString>\n" +
" </ram:OccurrenceDateTime>\n" +
" </ram:ActualDespatchSupplyChainEvent>";
/*
xml += "<ram:ActualDeliverySupplyChainEvent>"
+ "<ram:OccurrenceDateTime>";
if (trans.getDeliveryDate() != null) {
xml += DATE.udtFormat(trans.getDeliveryDate());
} else {
throw new IllegalStateException("No delivery date provided");
}
xml += "</ram:OccurrenceDateTime>\n";
xml += "</ram:ActualDeliverySupplyChainEvent>\n"
*/
/*
* + "<DeliveryNoteReferencedDocument>\n" +
* "<IssueDateTime format=\"102\">20130603</IssueDateTime>\n" +
* "<ID>2013-51112</ID>\n" +
* "</DeliveryNoteReferencedDocument>\n"
*/
xml+= "</ram:ApplicableHeaderTradeDelivery>\n";
// + " <IncludedSupplyChainTradeLineItem>"
// + " <AssociatedDocumentLineDocument>"
// + " <IncludedNote>"
// + " <Content>Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr.
// 2013-51112 in Rechnung zu stellen:</Content>\n"
// + " </IncludedNote>\n"
// + " </AssociatedDocumentLineDocument>\n"
// + " </IncludedSupplyChainTradeLineItem>\n";
xml += "</px:SupplyChainTradeTransaction>"
+ "</SCRDMCCBDACIDAMessageStructure>";
final byte[] zugferdRaw;
try {
zugferdRaw = xml.getBytes("UTF-8");
zugferdData = XMLTools.removeBOM(zugferdRaw);
} catch (final UnsupportedEncodingException e) {
Logger.getLogger(OXPullProvider.class.getName()).log(Level.SEVERE, null, e);
}
}
@Override
public void setProfile(Profile p) {
profile = p;
}
@Override
public Profile getProfile() {
return profile;
}
private String buildPaymentTermsXml() {
final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms();
if (paymentTerms == null) {
return "";
}
String paymentTermsXml = "<ram:SpecifiedTradePaymentTerms>";
final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms();
final Date dueDate = paymentTerms.getDueDate();
if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) {
throw new IllegalStateException(
"if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified");
}
paymentTermsXml += "<ram:Description>" + paymentTerms.getDescription() + "</ram:Description>";
if (dueDate != null) {
paymentTermsXml += "<ram:DueDateDateTime>";
paymentTermsXml += DATE.udtFormat(dueDate);
paymentTermsXml += "</ram:DueDateDateTime>";
}
if (discountTerms != null) {
paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>";
final String currency = trans.getCurrency();
final String basisAmount = currencyFormat(calc.getGrandTotal());
paymentTermsXml += "<ram:BasisAmount currencyID=\"" + currency + "\">" + basisAmount + "</ram:BasisAmount>";
paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString()
+ "</ram:CalculationPercent>";
if (discountTerms.getBaseDate() != null) {
final Date baseDate = discountTerms.getBaseDate();
paymentTermsXml += "<ram:BasisDateTime>";
paymentTermsXml += DATE.udtFormat(baseDate);
paymentTermsXml += "</ram:BasisDateTime>";
paymentTermsXml += "<ram:BasisPeriodMeasure unitCode=\"" + discountTerms.getBasePeriodUnitCode() + "\">"
+ discountTerms.getBasePeriodMeasure() + "</ram:BasisPeriodMeasure>";
}
paymentTermsXml += "</ram:ApplicableTradePaymentDiscountTerms>";
}
paymentTermsXml += "</ram:SpecifiedTradePaymentTerms>";
return paymentTermsXml;
}
}

View File

@@ -105,7 +105,7 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* OrderX document type. As of version 1.0 it may be
* ORDER, ORDER_RESPONSE, or ORDER_CHANGE
*/
protected String deliverXDocumentType = "DESPATCHADVICE";
protected String despatchAdviceDocumentType = "DESPATCHADVICE";
private HashMap<String, byte[]> additionalXMLs = new HashMap<String, byte[]>();
@@ -404,7 +404,7 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*/
public DXExporterFromA3 setDocumentType(String DocumentType)
{
this.deliverXDocumentType = DocumentType;
this.despatchAdviceDocumentType = DocumentType;
return this;
}
@@ -428,7 +428,7 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, 1, true, xmlProvider.getProfile(),
"urn:facturx:pdfa:CrossIndustryDocument:despatchadvice:1p0#", "fx",
"cida.xml");
zf.setType(this.deliverXDocumentType);
zf.setType(this.despatchAdviceDocumentType);
metadata.addSchema(zf);
// also add the schema extensions...
@@ -679,7 +679,7 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
@Override
public DXExporterFromA3 setZUGFeRDVersion(int version) {
OXPullProvider z2p = new OXPullProvider();
DAPullProvider z2p = new DAPullProvider();
setXMLProvider(z2p);
return this;
}

View File

@@ -33,7 +33,7 @@ public class Profiles {
{"BASIC", new Profile("BASIC", "urn:cen.eu:en16931:2017#compliant#urn:factur-x.eu:1p0:basic")},
{"EN16931", new Profile("EN16931", "urn:cen.eu:en16931:2017")},
{"EXTENDED", new Profile("EXTENDED", "urn:cen.eu:en16931:2017#conformant#urn:factur-x.eu:1p0:extended")},
{"XRECHNUNG", new Profile("XRECHNUNG", "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.1")}
{"XRECHNUNG", new Profile("XRECHNUNG", "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.2")}
}).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1]));
static Map<String, Profile> zf1Map = Stream.of(new Object[][]{
@@ -51,7 +51,7 @@ public class Profiles {
}).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1]));
static Map<String, Profile> dx1Map = Stream.of(new Object[][]{
{"PILOT", new Profile("PILOT", "urn:facturx:pdfa:CrossIndustryDocument:despatchadvice:1p0#")}
{"PILOT", new Profile("PILOT", "urn:awv-net.de:CIDA:1.0:pilot")}
}).collect(Collectors.toMap(data -> (String) data[0], data -> (Profile) data[1]));
@@ -63,7 +63,7 @@ public class Profiles {
throw new RuntimeException("Profile not found");
}
return result;
} else if (standard == EStandard.deliverx) {
} else if (standard == EStandard.deliveradvice) {
Profile result = null;
result = dx1Map.get(name.toUpperCase());
if (result == null) {

View File

@@ -23,9 +23,13 @@ import junit.framework.Test;
import junit.framework.TestSuite;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.EStandard;
import org.mustangproject.Invoice;
import org.mustangproject.TradeParty;
import javax.xml.xpath.XPathExpressionException;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
@@ -38,6 +42,8 @@ import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import static org.xmlunit.assertj.XmlAssert.assertThat;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class DXTest extends MustangReaderTestCase implements IExportableTransaction {
final String TARGET_PDF = "./target/testout-DX.pdf";
@@ -201,7 +207,7 @@ public class DXTest extends MustangReaderTestCase implements IExportableTransact
// 103
EdgeProduct airProduct = new EdgeProduct("", "Heiße Luft pro Liter", "LTR");
Item design=new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct);
Item design = new Item(new BigDecimal("160"), new BigDecimal("1"), designProduct);
design.setAddReference("1825");
allItems[0] = design;
allItems[1] = new Item(new BigDecimal("0.79"), new BigDecimal("400"), balloonProduct);
@@ -292,7 +298,7 @@ public class DXTest extends MustangReaderTestCase implements IExportableTransact
assertEquals(zi.getHolder(), getOwnOrganisationName());
ZUGFeRDInvoiceImporter zii = new ZUGFeRDInvoiceImporter(TARGET_PDF);
try {
Invoice i=zii.extractInvoice();
Invoice i = zii.extractInvoice();
assertEquals(new BigDecimal("400.0000"), i.getZFItems()[1].getQuantity());
/* getting the Quantity is more difficult than usual because in OrderX it's
@@ -311,4 +317,55 @@ public class DXTest extends MustangReaderTestCase implements IExportableTransact
}
public void testDAGeneration() {
// the writing part
TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE");
Invoice i = createDA(recipient);
DAPullProvider zf2p = new DAPullProvider();
zf2p.setProfile(Profiles.getByName(EStandard.deliveradvice,"Pilot",1));
zf2p.generateXML(i);
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(TARGET_XML));
writer.write(theXML);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
assertTrue(theXML.contains("<SCRDMCCBDACIDAMessageStructure"));
assertThat(theXML).valueByXPath("count(//*[local-name()='IncludedSupplyChainTradeLineItem'])")
.asInt()
.isEqualTo(2); //we have two items
assertThat(theXML).valueByXPath("//*[local-name()='ActualDespatchSupplyChainEvent']/*[local-name()='OccurrenceDateTime']/*[local-name()='DateTimeString']")
.asString()
.isEqualToIgnoringWhitespace("20210426");
}
private Invoice createDA(TradeParty recipient) {
String orgname = "Test company";
String number = "123";
String amountStr = "23.00";
BigDecimal amount = new BigDecimal(amountStr);
SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
try {
return new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
.setSender(new TradeParty(orgname,"teststr","55232","teststadt","DE").addTaxID("DE4711").addVATID("DE0815").setContact(new org.mustangproject.Contact("Hans Test","+49123456789","test@example.org")).addBankDetails(new org.mustangproject.BankDetails("DE12500105170648489890","COBADEFXXX")))
.setRecipient(recipient)
.setDeliveryDate(germanDateFormat.parse("26.04.2021"))
.setReferenceNumber("991-01484-64")//leitweg-id
// not using any VAT, this is also a test of zero-rated goods:
.setNumber(number)
.addItem(new org.mustangproject.Item(new org.mustangproject.Product("Testprodukt", "", "P75", BigDecimal.ZERO), amount, new BigDecimal(1.0))).addItem(new org.mustangproject.Item(new org.mustangproject.Product("Testprodukt", "", "P85", BigDecimal.ZERO), amount, new BigDecimal(1.0)));
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
}

View File

@@ -177,7 +177,7 @@ public class XMLValidator extends Validator {
context.setProfile(booking.getNodeValue());
}
boolean isOrderX = false;
boolean isDeliverX = false;
boolean isDespatchAdvice = false;
boolean isMiniumum = false;
boolean isBasic = false;
boolean isBasicWithoutLines = false;