Merge pull request #137 from Koizumi85/master

deliveryDate in different date formats (#136)
This commit is contained in:
Jochen Staerk
2019-10-15 17:06:13 +02:00
committed by GitHub
11 changed files with 254 additions and 19 deletions

View File

@@ -79,12 +79,12 @@
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>org.apache.pdfbox</groupId>
<artifactId>preflight</artifactId> <artifactId>preflight</artifactId>
<version>[2.0.15,)</version> <version>[2.0.15,2.0.17]</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId> <artifactId>pdfbox</artifactId>
<version>[2.0.15,)</version> <version>[2.0.15,2.0.17]</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>

View File

@@ -0,0 +1,13 @@
package org.mustangproject.ZUGFeRD;
import java.util.Date;
public interface IZUGFeRDDate {
Date getDate();
default ZUGFeRDDateFormat getFormat() {
return ZUGFeRDDateFormat.DATE;
}
}

View File

@@ -124,4 +124,13 @@ public interface IZUGFeRDExportableContact {
return null; return null;
} }
/**
* returns additional address information which is display in xml tag "LineTwo"
*
* @return additional address information
*/
default String getAdditionalAddress() {
return null;
}
} }

View File

@@ -131,6 +131,7 @@ public interface IZUGFeRDExportableTransaction {
* @deprecated use getTradeSettlement * @deprecated use getTradeSettlement
* @return an array of IZUGFeRDTradeSettlementPayment * @return an array of IZUGFeRDTradeSettlementPayment
*/ */
@Deprecated
default IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment() { default IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment() {
return null; return null;
} }
@@ -231,6 +232,16 @@ public interface IZUGFeRDExportableTransaction {
*/ */
Date getDeliveryDate(); Date getDeliveryDate();
/**
* get delivery date in more specific form. If this and getDeliveryDate() are
* specified, this value will be taken
*
* @return instance holding date and format
*/
default IZUGFeRDDate getZFDeliveryDate() {
return null;
}
/** /**
* get main invoice currency used on the invoice * get main invoice currency used on the invoice

View File

@@ -24,6 +24,7 @@ import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -78,6 +79,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
private ZUGFeRDConformanceLevel level; private ZUGFeRDConformanceLevel level;
private String paymentTermsDescription; private String paymentTermsDescription;
@Override
public void setProfile(ZUGFeRDConformanceLevel level) { public void setProfile(ZUGFeRDConformanceLevel level) {
this.level = level; this.level = level;
} }
@@ -85,6 +87,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
/** /**
* enables the flag to indicate a test invoice in the XML structure * enables the flag to indicate a test invoice in the XML structure
*/ */
@Override
public void setTest() { public void setTest() {
} }
@@ -203,6 +206,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
return hm; return hm;
} }
@Override
public String getProfile() { public String getProfile() {
// return "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_1.2"; // return "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_1.2";
return "urn:cen.eu:en16931:2017"; return "urn:cen.eu:en16931:2017";
@@ -390,8 +394,11 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
// + " </DefinedTradeContact>\n" // + " </DefinedTradeContact>\n"
+ " <ram:PostalTradeAddress>\n" //$NON-NLS-1$ + " <ram:PostalTradeAddress>\n" //$NON-NLS-1$
+ " <ram:PostcodeCode>" + XMLTools.encodeXML(trans.getRecipient().getZIP()) + "</ram:PostcodeCode>\n" //$NON-NLS-1$ //$NON-NLS-2$ + " <ram:PostcodeCode>" + XMLTools.encodeXML(trans.getRecipient().getZIP()) + "</ram:PostcodeCode>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:LineOne>" + XMLTools.encodeXML(trans.getRecipient().getStreet()) + "</ram:LineOne>\n" //$NON-NLS-1$ //$NON-NLS-2$ + " <ram:LineOne>" + XMLTools.encodeXML(trans.getRecipient().getStreet()) + "</ram:LineOne>\n"; //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:CityName>" + XMLTools.encodeXML(trans.getRecipient().getLocation()) + "</ram:CityName>\n" //$NON-NLS-1$ //$NON-NLS-2$ if (trans.getRecipient().getAdditionalAddress() != null) {
xml += " <ram:LineTwo>" + XMLTools.encodeXML(trans.getRecipient().getAdditionalAddress()) + "</ram:LineTwo>\n"; //$NON-NLS-1$ //$NON-NLS-2$
}
xml += " <ram:CityName>" + XMLTools.encodeXML(trans.getRecipient().getLocation()) + "</ram:CityName>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " <ram:CountryID>" + XMLTools.encodeXML(trans.getRecipient().getCountry()) + "</ram:CountryID>\n" //$NON-NLS-1$ //$NON-NLS-2$ + " <ram:CountryID>" + XMLTools.encodeXML(trans.getRecipient().getCountry()) + "</ram:CountryID>\n" //$NON-NLS-1$ //$NON-NLS-2$
+ " </ram:PostalTradeAddress>\n"; //$NON-NLS-1$ + " </ram:PostalTradeAddress>\n"; //$NON-NLS-1$
if (trans.getRecipient().getVATID() != null) { if (trans.getRecipient().getVATID() != null) {
@@ -406,8 +413,20 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
// + " </BuyerOrderReferencedDocument>\n" // + " </BuyerOrderReferencedDocument>\n"
+ " </ram:ApplicableHeaderTradeAgreement>\n" //$NON-NLS-1$ + " </ram:ApplicableHeaderTradeAgreement>\n" //$NON-NLS-1$
+ " <ram:ApplicableHeaderTradeDelivery>\n" + " <ram:ActualDeliverySupplyChainEvent>\n" + " <ram:ApplicableHeaderTradeDelivery>\n" + " <ram:ActualDeliverySupplyChainEvent>\n"
+ " <ram:OccurrenceDateTime><udt:DateTimeString format=\"102\">" + " <ram:OccurrenceDateTime>";
+ zugferdDateFormat.format(trans.getDeliveryDate()) + "</udt:DateTimeString></ram:OccurrenceDateTime>\n"
if (trans.getZFDeliveryDate() != null) {
ZUGFeRDDateFormat dateFormat = trans.getZFDeliveryDate().getFormat();
Date date = trans.getZFDeliveryDate().getDate();
xml += "<udt:DateTimeString format=\"" + dateFormat.getDateTimeType() + "\">"
+ dateFormat.getFormatter().format(date) + "</udt:DateTimeString>";
} else if (trans.getDeliveryDate() != null) {
xml += "<udt:DateTimeString format=\"102\">" + zugferdDateFormat.format(trans.getDeliveryDate())
+ "</udt:DateTimeString>";
} else {
throw new IllegalStateException("No delivery date provided");
}
xml += "</ram:OccurrenceDateTime>\n"
+ " </ram:ActualDeliverySupplyChainEvent>\n" + " </ram:ActualDeliverySupplyChainEvent>\n"
/* /*
* + " <DeliveryNoteReferencedDocument>\n" + * + " <DeliveryNoteReferencedDocument>\n" +

View File

@@ -0,0 +1,28 @@
package org.mustangproject.ZUGFeRD;
import java.text.SimpleDateFormat;
import org.mustangproject.ZUGFeRD.model.DateTimeTypeConstants;
public enum ZUGFeRDDateFormat {
MONTH_OF_YEAR(DateTimeTypeConstants.MONTH, new SimpleDateFormat("yyyyMM")),
WEEK_OF_YEAR(DateTimeTypeConstants.WEEK, new SimpleDateFormat("yyyyww")),
DATE(DateTimeTypeConstants.DATE, new SimpleDateFormat("yyyyMMdd"));
private String dateTimeType;
private SimpleDateFormat formatter;
private ZUGFeRDDateFormat(String dateTimeType, SimpleDateFormat formatter) {
this.dateTimeType = dateTimeType;
this.formatter = formatter;
}
public String getDateTimeType() {
return dateTimeType;
}
public SimpleDateFormat getFormatter() {
return formatter;
}
}

View File

@@ -248,6 +248,12 @@ class ZUGFeRDTransactionModelConverter {
buyerAddress.setValue(trans.getRecipient().getStreet()); buyerAddress.setValue(trans.getRecipient().getStreet());
buyerAddressType.setLineOne(buyerAddress); buyerAddressType.setLineOne(buyerAddress);
if (trans.getRecipient().getAdditionalAddress() != null) {
TextType buyerAdditionalAddress = xmlFactory.createTextType();
buyerAdditionalAddress.setValue(trans.getRecipient().getAdditionalAddress());
buyerAddressType.setLineTwo(buyerAdditionalAddress);
}
CodeType buyerPostcode = xmlFactory.createCodeType(); CodeType buyerPostcode = xmlFactory.createCodeType();
buyerPostcode.setValue(trans.getRecipient().getZIP()); buyerPostcode.setValue(trans.getRecipient().getZIP());
buyerAddressType.getPostcodeCode().add(buyerPostcode); buyerAddressType.getPostcodeCode().add(buyerPostcode);
@@ -385,9 +391,18 @@ class ZUGFeRDTransactionModelConverter {
DateTimeType deliveryDate = xmlFactory.createDateTimeType(); DateTimeType deliveryDate = xmlFactory.createDateTimeType();
DateTimeType.DateTimeString deliveryDateString = xmlFactory DateTimeType.DateTimeString deliveryDateString = xmlFactory
.createDateTimeTypeDateTimeString(); .createDateTimeTypeDateTimeString();
IZUGFeRDDate zfDeliveryDate = trans.getZFDeliveryDate();
if (zfDeliveryDate != null) {
ZUGFeRDDateFormat deliveryDateFormat = zfDeliveryDate.getFormat();
deliveryDateString.setFormat(deliveryDateFormat.getDateTimeType());
deliveryDateString.setValue(
deliveryDateFormat.getFormatter().format(zfDeliveryDate.getDate()));
} else if (trans.getDeliveryDate() != null) {
deliveryDateString.setFormat(DateTimeTypeConstants.DATE); deliveryDateString.setFormat(DateTimeTypeConstants.DATE);
deliveryDateString.setValue(zugferdDateFormat.format(trans deliveryDateString.setValue(zugferdDateFormat.format(trans.getDeliveryDate()));
.getDeliveryDate())); } else {
throw new IllegalStateException("No delivery date provided");
}
deliveryDate.setDateTimeString(deliveryDateString); deliveryDate.setDateTimeString(deliveryDateString);
deliveryEvent.getOccurrenceDateTime().add(deliveryDate); deliveryEvent.getOccurrenceDateTime().add(deliveryDate);
tradeDelivery.getActualDeliverySupplyChainEvent().add(deliveryEvent); tradeDelivery.getActualDeliverySupplyChainEvent().add(deliveryEvent);

View File

@@ -0,0 +1,30 @@
package org.mustangproject.ZUGFeRD;
import java.util.Date;
public class IZUGFeRDDateImpl implements IZUGFeRDDate {
private Date date;
private ZUGFeRDDateFormat format = ZUGFeRDDateFormat.DATE;
public IZUGFeRDDateImpl setDate(Date date) {
this.date = date;
return this;
}
public IZUGFeRDDateImpl setFormat(ZUGFeRDDateFormat format) {
this.format = format;
return this;
}
@Override
public Date getDate() {
return date;
}
@Override
public ZUGFeRDDateFormat getFormat() {
return format;
}
}

View File

@@ -32,6 +32,7 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
private IZUGFeRDExportableItem[] zFItems; private IZUGFeRDExportableItem[] zFItems;
private IZUGFeRDExportableContact recipient; private IZUGFeRDExportableContact recipient;
private IZUGFeRDTradeSettlementPayment[] settlementPayments; private IZUGFeRDTradeSettlementPayment[] settlementPayments;
private IZUGFeRDDate zfDeliveryDate;
private String ownTaxID; private String ownTaxID;
private String ownVATID; private String ownVATID;
private String ownOrganisationName; private String ownOrganisationName;
@@ -149,6 +150,11 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
return referenceNumber; return referenceNumber;
} }
@Override
public IZUGFeRDDate getZFDeliveryDate() {
return zfDeliveryDate;
}
public IZUGFeRDExportableTransactionImpl setNumber(String number) { public IZUGFeRDExportableTransactionImpl setNumber(String number) {
this.number = number; this.number = number;
return this; return this;
@@ -234,6 +240,11 @@ public class IZUGFeRDExportableTransactionImpl implements IZUGFeRDExportableTran
return this; return this;
} }
public IZUGFeRDExportableTransactionImpl setZfDeliveryDate(IZUGFeRDDate zfDeliveryDate) {
this.zfDeliveryDate = zfDeliveryDate;
return this;
}
public IZUGFeRDExportableTransactionImpl setCurrency(String currency) { public IZUGFeRDExportableTransactionImpl setCurrency(String currency) {
this.currency = currency; this.currency = currency;
return this; return this;

View File

@@ -19,11 +19,6 @@
*********************************************************************** */ *********************************************************************** */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -33,6 +28,12 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import junit.framework.Test;
import junit.framework.TestSuite;
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ZF2EdgeTest extends MustangReaderTestCase implements IZUGFeRDExportableTransaction { public class ZF2EdgeTest extends MustangReaderTestCase implements IZUGFeRDExportableTransaction {
final String TARGET_PDF = "./target/testout-ZF2newEdge.pdf"; final String TARGET_PDF = "./target/testout-ZF2newEdge.pdf";
@@ -286,7 +287,6 @@ public class ZF2EdgeTest extends MustangReaderTestCase implements IZUGFeRDExport
try { try {
assertEquals(zi.getVersion(), 2); assertEquals(zi.getVersion(), 2);
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -18,14 +18,15 @@
*********************************************************************** */ *********************************************************************** */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.junit.Test;
import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType;
import javax.xml.bind.JAXBElement;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import javax.xml.bind.JAXBElement;
import org.junit.Test;
import org.mustangproject.ZUGFeRD.model.CrossIndustryDocumentType;
public class ZUGFeRDTransactionModelConverterTest { public class ZUGFeRDTransactionModelConverterTest {
@Test @Test
public void convertToModel_convertsMinimalTransactionToValidXml() throws Exception { public void convertToModel_convertsMinimalTransactionToValidXml() throws Exception {
@@ -66,9 +67,107 @@ public class ZUGFeRDTransactionModelConverterTest {
ZUGFeRDXMLAssert.assertValidZugferd(actual); ZUGFeRDXMLAssert.assertValidZugferd(actual);
} }
@Test
public void convertToModel_convertsWithDateFormatToValidXml() throws Exception {
// setup
IZUGFeRDExportableTransaction transaction = new IZUGFeRDExportableTransactionImpl()
.setIssueDate(createDate(2000, 1, 1))
.setZfDeliveryDate(createZfDate(2000, 1, 2, ZUGFeRDDateFormat.DATE)).setDueDate(createDate(2000, 1, 3))
.setNumber("num")
.setRecipient(new IZUGFeRDExportableContactImpl().setName("recipient name")
.setStreet("recipient street").setLocation("recipient city").setCountry("recipient country"))
.setOwnOrganisationName("own org").setOwnStreet("own street").setOwnCountry("own country")
.setOwnLocation("own city")
.setTradeSettlementPayment(new IZUGFeRDTradeSettlementPaymentImpl().setOwnBankName("own bank"))
.setZFItems(new IZUGFeRDExportableItemImpl()
.setProduct(new IZUGFeRDExportableProductImpl().setVatPercent(new BigDecimal("1.19"))
.setName("product name").setDescription("product description").setUnit("product unit"))
.setQuantity(BigDecimal.ONE).setPrice(BigDecimal.TEN));
// execution
final JAXBElement<CrossIndustryDocumentType> actual = new ZUGFeRDTransactionModelConverter(transaction)
.convertToModel();
// evaluation
ZUGFeRDXMLAssert.assertValidZugferd(actual);
}
@Test
public void convertToModel_convertsWithWeekFormatToValidXml() throws Exception {
// setup
IZUGFeRDExportableTransaction transaction = new IZUGFeRDExportableTransactionImpl()
.setIssueDate(createDate(2000, 1, 1))
.setZfDeliveryDate(createZfDate(2000, 1, 2, ZUGFeRDDateFormat.WEEK_OF_YEAR))
.setDueDate(createDate(2000, 1, 3)).setNumber("num")
.setRecipient(new IZUGFeRDExportableContactImpl().setName("recipient name")
.setStreet("recipient street").setLocation("recipient city").setCountry("recipient country"))
.setOwnOrganisationName("own org").setOwnStreet("own street").setOwnCountry("own country")
.setOwnLocation("own city")
.setTradeSettlementPayment(new IZUGFeRDTradeSettlementPaymentImpl().setOwnBankName("own bank"))
.setZFItems(new IZUGFeRDExportableItemImpl()
.setProduct(new IZUGFeRDExportableProductImpl().setVatPercent(new BigDecimal("1.19"))
.setName("product name").setDescription("product description").setUnit("product unit"))
.setQuantity(BigDecimal.ONE).setPrice(BigDecimal.TEN));
// execution
final JAXBElement<CrossIndustryDocumentType> actual = new ZUGFeRDTransactionModelConverter(transaction)
.convertToModel();
// evaluation
ZUGFeRDXMLAssert.assertValidZugferd(actual);
}
@Test
public void convertToModel_convertsWithMonthFormatToValidXml() throws Exception {
// setup
IZUGFeRDExportableTransaction transaction = new IZUGFeRDExportableTransactionImpl()
.setIssueDate(createDate(2000, 1, 1))
.setZfDeliveryDate(createZfDate(2000, 1, 2, ZUGFeRDDateFormat.MONTH_OF_YEAR))
.setDueDate(createDate(2000, 1, 3))
.setNumber("num")
.setRecipient(new IZUGFeRDExportableContactImpl()
.setName("recipient name")
.setStreet("recipient street")
.setLocation("recipient city")
.setCountry("recipient country")
)
.setOwnOrganisationName("own org")
.setOwnStreet("own street")
.setOwnCountry("own country")
.setOwnLocation("own city")
.setTradeSettlementPayment(new IZUGFeRDTradeSettlementPaymentImpl().setOwnBankName("own bank"))
.setZFItems(
new IZUGFeRDExportableItemImpl()
.setProduct(new IZUGFeRDExportableProductImpl()
.setVatPercent(new BigDecimal("1.19"))
.setName("product name")
.setDescription("product description")
.setUnit("product unit")
)
.setQuantity(BigDecimal.ONE)
.setPrice(BigDecimal.TEN)
);
// execution
final JAXBElement<CrossIndustryDocumentType> actual =
new ZUGFeRDTransactionModelConverter(transaction).convertToModel();
// evaluation
ZUGFeRDXMLAssert.assertValidZugferd(actual);
}
private static Date createDate(int year, int month, int day) { private static Date createDate(int year, int month, int day) {
final GregorianCalendar calendar = new GregorianCalendar(); final GregorianCalendar calendar = new GregorianCalendar();
calendar.set(year, month - 1, day); calendar.set(year, month - 1, day);
return calendar.getTime(); return calendar.getTime();
} }
private static IZUGFeRDDate createZfDate(int year, int month, int day, ZUGFeRDDateFormat format) {
final GregorianCalendar calendar = new GregorianCalendar();
calendar.set(year, month - 1, day);
IZUGFeRDDateImpl date = new IZUGFeRDDateImpl();
date.setDate(calendar.getTime());
date.setFormat(format);
return date;
}
} }