attempts on supporting netherlands' Euro
This commit is contained in:
@@ -66,6 +66,7 @@ public class Invoice implements IExportableTransaction {
|
|||||||
protected String despatchAdviceReferencedDocumentID = null;
|
protected String despatchAdviceReferencedDocumentID = null;
|
||||||
protected String vatDueDateTypeCode = null;
|
protected String vatDueDateTypeCode = null;
|
||||||
protected String creditorReferenceID; // required when direct debit is used.
|
protected String creditorReferenceID; // required when direct debit is used.
|
||||||
|
private BigDecimal roundingAmount=null;
|
||||||
|
|
||||||
public Invoice() {
|
public Invoice() {
|
||||||
ZFItems = new ArrayList<>();
|
ZFItems = new ArrayList<>();
|
||||||
@@ -467,6 +468,24 @@ public class Invoice implements IExportableTransaction {
|
|||||||
return sender;
|
return sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* for currency rounding differences to 5ct e.g. in Netherlands ("Rappenrundung")
|
||||||
|
* @return null if not set, otherwise BigDecimal of Euros
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public BigDecimal getRoundingAmount() {
|
||||||
|
return roundingAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* for currency rounding differences to 5ct e.g. in Netherlands ("Rappenrundung")
|
||||||
|
* @return fluent setter
|
||||||
|
*/
|
||||||
|
public Invoice setRoundingAmount(BigDecimal amount) {
|
||||||
|
roundingAmount=amount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* sets a named sender contact
|
* sets a named sender contact
|
||||||
* @deprecated use setSender
|
* @deprecated use setSender
|
||||||
|
|||||||
@@ -321,6 +321,15 @@ public interface IExportableTransaction {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* supplier identification assigned by the costumer
|
||||||
|
*
|
||||||
|
* @return the sender's identification
|
||||||
|
*/
|
||||||
|
default BigDecimal getRoundingAmount() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get reference document number typically used for Invoice Corrections Will be
|
* get reference document number typically used for Invoice Corrections Will be
|
||||||
* added as IncludedNote in comfort profile
|
* added as IncludedNote in comfort profile
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
|
|||||||
*/
|
*/
|
||||||
public BigDecimal getGrandTotal() {
|
public BigDecimal getGrandTotal() {
|
||||||
|
|
||||||
final BigDecimal res = getTaxBasis();
|
BigDecimal basis = getTaxBasis();
|
||||||
return getVATPercentAmountMap().values().stream().map(VATAmount::getCalculated)
|
return getVATPercentAmountMap().values().stream().map(VATAmount::getCalculated)
|
||||||
.map(p -> p.setScale(2, RoundingMode.HALF_UP)).reduce(BigDecimal.ZERO, BigDecimal::add).add(res);
|
.map(p -> p.setScale(2, RoundingMode.HALF_UP)).reduce(BigDecimal.ZERO, BigDecimal::add).add(basis);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -172,8 +172,8 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
|
|||||||
LineCalculator lc = new LineCalculator(currentItem);
|
LineCalculator lc = new LineCalculator(currentItem);
|
||||||
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(),
|
VATAmount itemVATAmount = new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount(),
|
||||||
currentItem.getProduct().getTaxCategoryCode(), vatDueDateTypeCode);
|
currentItem.getProduct().getTaxCategoryCode(), vatDueDateTypeCode);
|
||||||
String reasonText=currentItem.getProduct().getTaxExemptionReason();
|
String reasonText = currentItem.getProduct().getTaxExemptionReason();
|
||||||
if (reasonText!=null) {
|
if (reasonText != null) {
|
||||||
itemVATAmount.setVatExemptionReasonText(reasonText);
|
itemVATAmount.setVatExemptionReasonText(reasonText);
|
||||||
}
|
}
|
||||||
VATAmount current = hm.get(percent.stripTrailingZeros());
|
VATAmount current = hm.get(percent.stripTrailingZeros());
|
||||||
@@ -239,4 +239,11 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
|
|||||||
return getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP);
|
return getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal getDuePayable() {
|
||||||
|
BigDecimal res = getGrandTotal().subtract(getTotalPrepaid());
|
||||||
|
if (trans.getRoundingAmount() != null) {
|
||||||
|
res = res.add(trans.getRoundingAmount());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
this.trans = trans;
|
this.trans = trans;
|
||||||
this.calc = new TransactionCalculator(trans);
|
this.calc = new TransactionCalculator(trans);
|
||||||
|
|
||||||
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 = "";
|
String exemptionReason = "";
|
||||||
@@ -856,7 +856,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
final String chargesTotalLine = "<ram:ChargeTotalAmount>" + currencyFormat(calc.getChargesForPercent(null)) + "</ram:ChargeTotalAmount>";
|
final String chargesTotalLine = "<ram:ChargeTotalAmount>" + currencyFormat(calc.getChargesForPercent(null)) + "</ram:ChargeTotalAmount>";
|
||||||
|
|
||||||
xml += "<ram:SpecifiedTradeSettlementHeaderMonetarySummation>";
|
xml += "<ram:SpecifiedTradeSettlementHeaderMonetarySummation>";
|
||||||
if (getProfile() != Profiles.getByName("Minimum")) {
|
if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BASICWL"))) {
|
||||||
xml += "<ram:LineTotalAmount>" + currencyFormat(calc.getTotal()) + "</ram:LineTotalAmount>";
|
xml += "<ram:LineTotalAmount>" + currencyFormat(calc.getTotal()) + "</ram:LineTotalAmount>";
|
||||||
xml += chargesTotalLine
|
xml += chargesTotalLine
|
||||||
+ allowanceTotalLine;
|
+ allowanceTotalLine;
|
||||||
@@ -865,14 +865,18 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
// //
|
// //
|
||||||
// currencyID=\"EUR\"
|
// currencyID=\"EUR\"
|
||||||
+ "<ram:TaxTotalAmount currencyID=\"" + trans.getCurrency() + "\">"
|
+ "<ram:TaxTotalAmount currencyID=\"" + trans.getCurrency() + "\">"
|
||||||
+ currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "</ram:TaxTotalAmount>"
|
+ currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + "</ram:TaxTotalAmount>";
|
||||||
+ "<ram:GrandTotalAmount>" + currencyFormat(calc.getGrandTotal()) + "</ram:GrandTotalAmount>";
|
if (trans.getRoundingAmount() != null) {
|
||||||
|
xml += "<ram:RoundingAmount>" + currencyFormat(trans.getRoundingAmount()) + "</ram:RoundingAmount>";
|
||||||
|
}
|
||||||
|
|
||||||
|
xml += "<ram:GrandTotalAmount>" + currencyFormat(calc.getGrandTotal()) + "</ram:GrandTotalAmount>";
|
||||||
// //
|
// //
|
||||||
// currencyID=\"EUR\"
|
// currencyID=\"EUR\"
|
||||||
if (getProfile() != Profiles.getByName("Minimum")) {
|
if (getProfile() != Profiles.getByName("Minimum")) {
|
||||||
xml += "<ram:TotalPrepaidAmount>" + currencyFormat(calc.getTotalPrepaid()) + "</ram:TotalPrepaidAmount>";
|
xml += "<ram:TotalPrepaidAmount>" + currencyFormat(calc.getTotalPrepaid()) + "</ram:TotalPrepaidAmount>";
|
||||||
}
|
}
|
||||||
xml += "<ram:DuePayableAmount>" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + "</ram:DuePayableAmount>"
|
xml += "<ram:DuePayableAmount>" + currencyFormat(calc.getDuePayable()) + "</ram:DuePayableAmount>"
|
||||||
+ "</ram:SpecifiedTradeSettlementHeaderMonetarySummation>";
|
+ "</ram:SpecifiedTradeSettlementHeaderMonetarySummation>";
|
||||||
if (trans.getInvoiceReferencedDocumentID() != null) {
|
if (trans.getInvoiceReferencedDocumentID() != null) {
|
||||||
xml += "<ram:InvoiceReferencedDocument>"
|
xml += "<ram:InvoiceReferencedDocument>"
|
||||||
|
|||||||
@@ -621,6 +621,11 @@ public class ZUGFeRDInvoiceImporter {
|
|||||||
|
|
||||||
zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]|//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyName\"]").trim());
|
zpp.setOwnOrganisationName(extractString("//*[local-name()=\"SellerTradeParty\"]/*[local-name()=\"Name\"]|//*[local-name()=\"AccountingSupplierParty\"]/*[local-name()=\"Party\"]/*[local-name()=\"PartyName\"]").trim());
|
||||||
|
|
||||||
|
String rounding=extractString("//*[local-name()=\"SpecifiedTradeSettlementHeaderMonetarySummation\"]/*[local-name()=\"RoundingAmount\"]|//*[local-name()=\"LegalMonetaryTotal\"]/*[local-name()=\"Party\"]/*[local-name()=\"PayableRoundingAmount\"]");
|
||||||
|
if ((rounding!=null)&&(!rounding.isEmpty())) {
|
||||||
|
zpp.setRoundingAmount(new BigDecimal(rounding.trim()));
|
||||||
|
}
|
||||||
|
|
||||||
xpr = xpath.compile("//*[local-name()=\"BuyerReference\"]");
|
xpr = xpath.compile("//*[local-name()=\"BuyerReference\"]");
|
||||||
String buyerReference = null;
|
String buyerReference = null;
|
||||||
prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
prepaidNodes = (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ public class ZF2PushTest extends TestCase {
|
|||||||
.addItem(new Item(new Product("Design (hours)", "Of a sample invoice", "HUR", new BigDecimal(7)), price, new BigDecimal(1.0)))
|
.addItem(new Item(new Product("Design (hours)", "Of a sample invoice", "HUR", new BigDecimal(7)), price, new BigDecimal(1.0)))
|
||||||
.addItem(new Item(new Product("Ballons", "various colors, ~2000ml", "H87", new BigDecimal(19)), new BigDecimal("0.79"), new BigDecimal(400.0)))
|
.addItem(new Item(new Product("Ballons", "various colors, ~2000ml", "H87", new BigDecimal(19)), new BigDecimal("0.79"), new BigDecimal(400.0)))
|
||||||
.addItem(new Item(new Product("Hot air „heiße Luft“ (litres)", "", "LTR", new BigDecimal(19)), new BigDecimal("0.025"), new BigDecimal(800.0)))
|
.addItem(new Item(new Product("Hot air „heiße Luft“ (litres)", "", "LTR", new BigDecimal(19)), new BigDecimal("0.025"), new BigDecimal(800.0)))
|
||||||
|
.setRoundingAmount(new BigDecimal("1"))
|
||||||
);
|
);
|
||||||
|
|
||||||
ze.export(TARGET_PDF);
|
ze.export(TARGET_PDF);
|
||||||
@@ -95,6 +96,15 @@ public class ZF2PushTest extends TestCase {
|
|||||||
fail("Exception should not be raised");
|
fail("Exception should not be raised");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZUGFeRDInvoiceImporter zii=new ZUGFeRDInvoiceImporter(TARGET_PDF);
|
||||||
|
Invoice i=new Invoice();
|
||||||
|
try {
|
||||||
|
zii.extractInto(i);
|
||||||
|
} catch (XPathExpressionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// now check the contents (like MustangReaderTest)
|
// now check the contents (like MustangReaderTest)
|
||||||
|
|||||||
Reference in New Issue
Block a user