Merge pull request #459 from Frgetg/issues/458-multiple-payment-details

Issue #458 Allow Multiple payment details for invoice
This commit is contained in:
Jochen Staerk
2025-04-22 11:10:22 +02:00
committed by GitHub
6 changed files with 171 additions and 103 deletions

View File

@@ -56,7 +56,7 @@ public class Invoice implements IExportableTransaction {
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<>(),
Charges = new ArrayList<>(), LogisticsServiceCharges = new ArrayList<>();
protected IZUGFeRDPaymentTerms paymentTerms = null;
protected ArrayList<IZUGFeRDPaymentTerms> paymentTerms = new ArrayList<>();
protected String invoiceReferencedDocumentID = null;
protected Date invoiceReferencedIssueDate;
@@ -646,15 +646,43 @@ public class Invoice implements IExportableTransaction {
@Override
public IZUGFeRDPaymentTerms getPaymentTerms() {
return paymentTerms;
if (!paymentTerms.isEmpty()) {
return paymentTerms.get(0);
}
return null;
}
public Invoice setPaymentTerms(IZUGFeRDPaymentTerms paymentTerms) {
this.paymentTerms = paymentTerms;
public Invoice setPaymentTerms(IZUGFeRDPaymentTerms paymentTerm) {
if (paymentTerms.isEmpty()) {
paymentTerms.add(paymentTerm);
}
else {
paymentTerms.set(0, paymentTerm);
}
return this;
}
@Override
public IZUGFeRDPaymentTerms[] getExtendedPaymentTerms() {
return paymentTerms.toArray(new IZUGFeRDPaymentTerms[0]);
}
public Invoice setExtendedPaymentTerms(IZUGFeRDPaymentTerms[] paymentTerms) {
this.paymentTerms.clear();
this.paymentTerms.addAll(Arrays.asList(paymentTerms));
return this;
}
/**
* Set multiple payment terms when using the EXTENDED profile.
* @return
*/
public Invoice addPaymentTerms(IZUGFeRDPaymentTerms paymentTerm) {
paymentTerms.add(paymentTerm);
return this;
}
public String getPaymentReference() {
return paymentReference;
}

View File

@@ -305,8 +305,7 @@ public interface IExportableTransaction {
}
/**
* get payment terms. if set, getPaymentTermDescription() and getDueDate() are
* ignored
* get payment terms. if set, getPaymentTermDescription() and getDueDate() are ignored
*
* @return the IZUGFeRDPaymentTerms of the invoice
*/
@@ -318,6 +317,14 @@ public interface IExportableTransaction {
return null;
}
/**
* Get payment terms for the EXTENDED profile (multiple terms are allowed)
* @return
*/
default IZUGFeRDPaymentTerms[] getExtendedPaymentTerms() {
return new IZUGFeRDPaymentTerms[0];
}
/**
* returns if a rebate agreements exists
*

View File

@@ -506,15 +506,21 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
private String buildPaymentTermsXml() {
final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms();
if (paymentTerms == null) {
final IZUGFeRDPaymentTerms[] paymentTerms = trans.getExtendedPaymentTerms();
String paymentTermsXml = "";
if (paymentTerms == null || paymentTerms.length == 0) {
return "";
}
String paymentTermsXml = "<ram:SpecifiedTradePaymentTerms>";
final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms();
paymentTermsXml += "<ram:Description>" + paymentTerms.getDescription() + "</ram:Description>";
if (discountTerms != null) {
for (IZUGFeRDPaymentTerms pt : paymentTerms)
{
paymentTermsXml += "<ram:SpecifiedTradePaymentTerms>";
final IZUGFeRDPaymentDiscountTerms discountTerms = pt.getDiscountTerms();
paymentTermsXml += "<ram:Description>" + pt.getDescription() + "</ram:Description>";
if (discountTerms != null)
{
paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>";
final String currency = trans.getCurrency();
final String basisAmount = currencyFormat(calc.getGrandTotal());
@@ -522,7 +528,8 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString()
+ "</ram:CalculationPercent>";
if (discountTerms.getBaseDate() != null) {
if (discountTerms.getBaseDate() != null)
{
final Date baseDate = discountTerms.getBaseDate();
paymentTermsXml += "<ram:BasisDateTime>";
paymentTermsXml += DATE.udtFormat(baseDate);
@@ -536,6 +543,7 @@ public class OXPullProvider extends ZUGFeRD2PullProvider {
}
paymentTermsXml += "</ram:SpecifiedTradePaymentTerms>";
}
return paymentTermsXml;
}

View File

@@ -433,23 +433,34 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider {
}
private String buildPaymentTermsXml() {
String paymentTermsXml = "<ram:SpecifiedTradePaymentTerms>";
final IZUGFeRDPaymentTerms[] paymentTerms = trans.getExtendedPaymentTerms();
final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms();
final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms();
final Date dueDate = paymentTerms.getDueDate();
if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) {
String paymentTermsXml = "";
if (paymentTerms == null || paymentTerms.length == 0) {
return paymentTermsXml;
}
for (IZUGFeRDPaymentTerms pt : paymentTerms)
{
paymentTermsXml += "<ram:SpecifiedTradePaymentTerms>";
final IZUGFeRDPaymentDiscountTerms discountTerms = pt.getDiscountTerms();
final Date dueDate = pt.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:Description>" + pt.getDescription() + "</ram:Description>";
if (dueDate != null)
{
paymentTermsXml += "<ram:DueDateDateTime>";
paymentTermsXml += DATE.udtFormat(dueDate);
paymentTermsXml += "</ram:DueDateDateTime>";
}
if (discountTerms != null) {
if (discountTerms != null)
{
paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>";
final String currency = trans.getCurrency();
final String basisAmount = currencyFormat(calc.getGrandTotal());
@@ -457,7 +468,8 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider {
paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString()
+ "</ram:CalculationPercent>";
if (discountTerms.getBaseDate() != null) {
if (discountTerms.getBaseDate() != null)
{
final Date baseDate = discountTerms.getBaseDate();
paymentTermsXml += "<ram:BasisDateTime>";
paymentTermsXml += DATE.udtFormat(baseDate);
@@ -471,6 +483,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider {
}
paymentTermsXml += "</ram:SpecifiedTradePaymentTerms>";
}
return paymentTermsXml;
}

View File

@@ -969,35 +969,47 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
}
private String buildPaymentTermsXml() {
final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms();
if (paymentTerms == null) {
final IZUGFeRDPaymentTerms[] paymentTerms = trans.getExtendedPaymentTerms();
String paymentTermsXml = "";
if (paymentTerms == null || paymentTerms.length == 0) {
return "";
}
String paymentTermsXml = "<ram:SpecifiedTradePaymentTerms>";
final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms();
final Date dueDate = paymentTerms.getDueDate();
if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) {
for (IZUGFeRDPaymentTerms pt : paymentTerms)
{
paymentTermsXml += "<ram:SpecifiedTradePaymentTerms>";
final IZUGFeRDPaymentDiscountTerms discountTerms = pt.getDiscountTerms();
final Date dueDate = pt.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>";
paymentTermsXml += "<ram:Description>" + pt.getDescription() + "</ram:Description>";
if (dueDate != null) {
if (dueDate != null)
{
paymentTermsXml += "<ram:DueDateDateTime>";
paymentTermsXml += DATE.udtFormat(dueDate);
paymentTermsXml += "</ram:DueDateDateTime>";
}
if (trans.getTradeSettlement() != null) {
for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) {
if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) {
if (trans.getTradeSettlement() != null)
{
for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement())
{
if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit))
{
paymentTermsXml += payment.getPaymentXML();
}
}
}
if (discountTerms != null) {
if (discountTerms != null)
{
paymentTermsXml += "<ram:ApplicableTradePaymentDiscountTerms>";
final String currency = trans.getCurrency();
final String basisAmount = currencyFormat(calc.getGrandTotal());
@@ -1005,7 +1017,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
paymentTermsXml += "<ram:CalculationPercent>" + discountTerms.getCalculationPercentage().toString()
+ "</ram:CalculationPercent>";
if (discountTerms.getBaseDate() != null) {
if (discountTerms.getBaseDate() != null)
{
final Date baseDate = discountTerms.getBaseDate();
paymentTermsXml += "<ram:BasisDateTime>";
paymentTermsXml += DATE.udtFormat(baseDate);
@@ -1019,6 +1032,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
}
paymentTermsXml += "</ram:SpecifiedTradePaymentTerms>";
}
return paymentTermsXml;
}

View File

@@ -240,13 +240,11 @@ public class ZF2EdgeTest extends MustangReaderTestCase {
e.printStackTrace();
}
return
new PaymentTerms(
return new PaymentTerms(
"14 Tage 2% Skonto, 30 Tage rein netto",
due,// fälligkeitsdatum
paymentDiscountTerms //PaymentDiscountTerms
);
}
@Override