support item level allowances
This commit is contained in:
@@ -594,9 +594,9 @@ public class Main {
|
||||
System.out.println("ZUGFeRD XML source set to " + sourceName);
|
||||
}
|
||||
if (outName == null) {
|
||||
outName = getFilenameFromUser("ZUGFeRD 2.0 HTML target", "factur-x.html", "html", false, true);
|
||||
outName = getFilenameFromUser("HTML target file", "factur-x.html", "html", false, true);
|
||||
} else {
|
||||
System.out.println("ZUGFeRD 1.0 XML source set to " + outName);
|
||||
System.out.println("HTML target set to " + outName);
|
||||
}
|
||||
|
||||
// Verify params
|
||||
|
||||
@@ -36,7 +36,8 @@ larger) and a commandline application using the latter
|
||||
library.
|
||||
|
||||
The validator component embeds VeraPDF, a open-source
|
||||
PDF/A-validator, via maven dependency and uses ph-schematron
|
||||
PDF/A-validator, via maven dependency and uses standard java
|
||||
checks against schema and ph-schematron for checks against the schematron
|
||||
to validate the XML part of the invoices.
|
||||
|
||||

|
||||
|
||||
@@ -13,4 +13,9 @@ public class Allowance extends Charge implements IZUGFeRDAllowanceCharge {
|
||||
super(totalAmount, taxPercent, reason, categoryCode);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCharge() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,11 @@ public class Charge implements IZUGFeRDAllowanceCharge {
|
||||
return taxPercent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCharge() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public Charge setCategoryCode(String categoryCode) {
|
||||
this.categoryCode = categoryCode;
|
||||
|
||||
@@ -34,4 +34,5 @@ public interface IZUGFeRDAllowanceCharge {
|
||||
return TaxCategoryCodeTypeConstants.STANDARDRATE;
|
||||
}
|
||||
|
||||
public boolean isCharge();
|
||||
}
|
||||
|
||||
@@ -4,19 +4,34 @@ import java.math.BigDecimal;
|
||||
|
||||
public class LineCalc {
|
||||
private BigDecimal totalGross;
|
||||
private BigDecimal price;
|
||||
private BigDecimal priceGross;
|
||||
private BigDecimal itemTotalNetAmount;
|
||||
private BigDecimal itemTotalVATAmount;
|
||||
private BigDecimal allowance=new BigDecimal(0);
|
||||
|
||||
public LineCalc(IZUGFeRDExportableItem currentItem) {
|
||||
|
||||
if (currentItem.getItemAllowances()!=null && currentItem.getItemAllowances().length>0) {
|
||||
for (IZUGFeRDAllowanceCharge allowance:currentItem.getItemAllowances()) {
|
||||
addAllowance(allowance.getTotalAmount());
|
||||
}
|
||||
}
|
||||
BigDecimal multiplicator = currentItem.getProduct().getVATPercent().divide(new BigDecimal(100))
|
||||
.add(new BigDecimal(1));
|
||||
priceGross = currentItem.getPrice(); // see https://github.com/ZUGFeRD/mustangproject/issues/159
|
||||
totalGross = currentItem.getQuantity().multiply(currentItem.getPrice()).divide(currentItem.getBasisQuantity())
|
||||
price = priceGross.subtract(allowance);
|
||||
totalGross = currentItem.getQuantity().multiply(getPrice()).divide(currentItem.getBasisQuantity())
|
||||
.multiply(multiplicator);
|
||||
itemTotalNetAmount = currentItem.getQuantity().multiply(currentItem.getPrice()).divide(currentItem.getBasisQuantity())
|
||||
itemTotalNetAmount = currentItem.getQuantity().multiply(getPrice()).divide(currentItem.getBasisQuantity())
|
||||
.setScale(2, BigDecimal.ROUND_HALF_UP);
|
||||
itemTotalVATAmount = totalGross.subtract(itemTotalNetAmount);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public BigDecimal getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public BigDecimal getItemTotalNetAmount() {
|
||||
@@ -28,12 +43,16 @@ public class LineCalc {
|
||||
}
|
||||
|
||||
public BigDecimal getItemTotalGrossAmount() {
|
||||
return itemTotalVATAmount;
|
||||
return itemTotalNetAmount;
|
||||
}
|
||||
|
||||
public BigDecimal getPriceGross() {
|
||||
return priceGross;
|
||||
}
|
||||
public void addAllowance(BigDecimal b) {
|
||||
allowance=b;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.dom4j.DocumentException;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.io.OutputFormat;
|
||||
import org.dom4j.io.XMLWriter;
|
||||
import org.mustangproject.Charge;
|
||||
import org.mustangproject.XMLTools;
|
||||
|
||||
public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
|
||||
@@ -121,7 +122,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
|
||||
BigDecimal res = new BigDecimal(0);
|
||||
for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
|
||||
LineCalc lc = new LineCalc(currentItem);
|
||||
res = res.add(lc.getItemTotalNetAmount());
|
||||
res = res.add(lc.getItemTotalGrossAmount());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -286,6 +287,19 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
|
||||
xml = xml + " <ram:BuyerAssignedID>"
|
||||
+ XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + "</ram:BuyerAssignedID>\n";
|
||||
}
|
||||
|
||||
String allowanceStr=" <ram:BasisQuantity unitCode=\"" + XMLTools.encodeXML(currentItem.getProduct().getUnit())
|
||||
+ "\">" + quantityFormat(currentItem.getBasisQuantity()) +"</ram:BasisQuantity>\n";
|
||||
if (currentItem.getItemAllowances()!=null && currentItem.getItemAllowances().length>0) {
|
||||
for (IZUGFeRDAllowanceCharge allowance:currentItem.getItemAllowances()) {
|
||||
if (allowance.isCharge()) {
|
||||
throw new RuntimeException("Item level charges are not yet implemented");
|
||||
} else {
|
||||
allowanceStr= "<ram:AppliedTradeAllowanceCharge><ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator><ram:ActualAmount>"+priceFormat(allowance.getTotalAmount())+"</ram:ActualAmount></ram:AppliedTradeAllowanceCharge>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xml = xml + " <ram:Name>" + XMLTools.encodeXML(currentItem.getProduct().getName()) + "</ram:Name>\n" //$NON-NLS-2$
|
||||
+ " <ram:Description>" + XMLTools.encodeXML(currentItem.getProduct().getDescription())
|
||||
+ "</ram:Description>\n"
|
||||
@@ -295,8 +309,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
|
||||
+ " <ram:GrossPriceProductTradePrice>\n"
|
||||
+ " <ram:ChargeAmount>" + priceFormat(lc.getPriceGross())
|
||||
+ "</ram:ChargeAmount>\n" //currencyID=\"EUR\"
|
||||
+ " <ram:BasisQuantity unitCode=\"" + XMLTools.encodeXML(currentItem.getProduct().getUnit())
|
||||
+ "\">" + quantityFormat(currentItem.getBasisQuantity()) +"</ram:BasisQuantity>\n"
|
||||
+ allowanceStr
|
||||
// + " <AppliedTradeAllowanceCharge>\n"
|
||||
// + " <ChargeIndicator>false</ChargeIndicator>\n"
|
||||
// + " <ActualAmount currencyID=\"EUR\">0.6667</ActualAmount>\n"
|
||||
@@ -304,7 +317,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
|
||||
// + " </AppliedTradeAllowanceCharge>\n"
|
||||
+ " </ram:GrossPriceProductTradePrice>\n"
|
||||
+ " <ram:NetPriceProductTradePrice>\n"
|
||||
+ " <ram:ChargeAmount>" + priceFormat(currentItem.getPrice())
|
||||
+ " <ram:ChargeAmount>" + priceFormat(lc.getPrice())
|
||||
+ "</ram:ChargeAmount>\n" // currencyID=\"EUR\"
|
||||
+ " <ram:BasisQuantity unitCode=\"" + XMLTools.encodeXML(currentItem.getProduct().getUnit())
|
||||
+ "\">" + quantityFormat(currentItem.getBasisQuantity()) +"</ram:BasisQuantity>\n"
|
||||
|
||||
@@ -24,6 +24,7 @@ public class IZUGFeRDAllowanceChargeImpl implements IZUGFeRDAllowanceCharge {
|
||||
private BigDecimal totalAmount;
|
||||
private String reason;
|
||||
private BigDecimal taxPercent;
|
||||
boolean isCharge=true;
|
||||
|
||||
@Override
|
||||
public BigDecimal getTotalAmount() {
|
||||
@@ -40,6 +41,16 @@ public class IZUGFeRDAllowanceChargeImpl implements IZUGFeRDAllowanceCharge {
|
||||
return taxPercent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCharge() {
|
||||
return isCharge;
|
||||
}
|
||||
|
||||
public IZUGFeRDAllowanceChargeImpl setAllowance() {
|
||||
isCharge = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IZUGFeRDAllowanceChargeImpl setTotalAmount(BigDecimal totalAmount) {
|
||||
this.totalAmount = totalAmount;
|
||||
return this;
|
||||
|
||||
@@ -136,9 +136,9 @@ public class ZF2PushTest extends TestCase {
|
||||
.load(SOURCE_PDF)) {
|
||||
|
||||
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname,"teststr", "55232","teststadt","DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addCharge(new Charge(new BigDecimal(0.1),new BigDecimal(0), "","K")))
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance(new BigDecimal(0.07),new BigDecimal(0), "","K")))
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance(new BigDecimal(0.07),new BigDecimal(0), "","K")).addCharge(new Charge(new BigDecimal(0.1),new BigDecimal(0), "","K")))
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance(new BigDecimal(0.1),new BigDecimal(0), "","K")))
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)))
|
||||
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)))
|
||||
|
||||
);
|
||||
String theXML = new String(ze.getProvider().getXML());
|
||||
@@ -154,7 +154,7 @@ public class ZF2PushTest extends TestCase {
|
||||
assertTrue(zi.getUTF8().contains("EUR"));
|
||||
|
||||
// Reading ZUGFeRD
|
||||
assertEquals("10.71", zi.getAmount());
|
||||
assertEquals("10.59", zi.getAmount());
|
||||
assertEquals(zi.getHolder(), orgname);
|
||||
assertEquals(zi.getForeignReference(), number);
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user