Relative charges/allowances on document level

This commit is contained in:
Jochen Stärk
2020-10-08 14:51:33 +02:00
parent 66fd7b4316
commit 44c6509504
11 changed files with 131 additions and 41 deletions

View File

@@ -6,6 +6,7 @@
- removed jaxb
- pushprovider
- new xrechnung profile
- visualization? zugferdvisualizer?
- german bank account numbers can no longer be specified (dropped in favor of IBAN and BIC)
- factory for xrechnung
- complete or discard read into push provider
@@ -15,7 +16,7 @@
- getSellerTradePartyAddress (PR #157 ) thanks to aberndt-hub
- switched from eclipse to IntelliJ
- added ph-schematron-maven-plugin so that xrechnung xslt can be generated
- remove migration
- removed migration feature (XSLT upgrade of ZF1)
- be able to recursively validate directories
- be able to ignore input pdf errors with -i
- be able to recursively scan directories using validateExpectValid/validateExpectInvalid
@@ -34,29 +35,30 @@ switch
- release notes
- new tradeparty class, Contact getOwnContact superseded by TradeParty getSender
- new invoicecorrection class
- order-x read support
- order-x xml read support
- automated tests zuv/verapdf validate created library test files
- trans.getTradeSettlementPayment() removed in favor of trans.getTradeSettlement()
- commandline option for no notices
- new features
- additional docs,
- contract id,
- delivery period,
- corrected invoices,
- contacts also for recipients
### 2.0 still todo
- dont show empty tax number field
- be able to specify iban via tradeparty object
- verapdf as prevalidation?
- visualization? zugferdvisualizer?
- new sample invoice
- prompt for source file for validation has to be pdf
- be able to disable "source pdf set to timeout"
- *visualizer to work with Extended profile
- *visualizer tests
- *validator not to XR error on ZF files (only notices)
- *from A3 does not seem tow ork see mustangreaderwriteredgetest:testedgeexport
- xmp errors may not show correctly in log
- switch for no log and no notices
- confirm correct generation from pdf/a3 files zf2edgetest
- *correctiontest exports zf1+zf2?
- *USt 0% wird aus invoice-klasse noch nicht sauber abgefangen
- new features additional docs, contract id, periods, corrected invoices, discounts, occurrence dates and periods
- absolute and relative allowances and charges on item and document level,
- finalize invoiceimporter
Alpha2 2020-09-15
Alpha1 2020-08-06

View File

@@ -1,5 +1,6 @@
package org.mustangproject;
import org.mustangproject.ZUGFeRD.IAbsoluteValueProvider;
import org.mustangproject.ZUGFeRD.IExportableTransaction;
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem;
@@ -55,27 +56,16 @@ public class Charge implements IZUGFeRDAllowanceCharge {
@Override
public BigDecimal getTotalAmount(IZUGFeRDExportableItem currentItem) {
public BigDecimal getTotalAmount(IAbsoluteValueProvider currentItem) {
if (totalAmount!=null) {
return totalAmount;
} else if (percent!=null) {
return currentItem.getPrice().multiply(getPercent().divide(new BigDecimal(100)));
return currentItem.getValue().multiply(getPercent().divide(new BigDecimal(100)));
} else {
throw new RuntimeException("Either totalAmount or percent must be set");
}
}
@Override
public BigDecimal getTotalAmount(IExportableTransaction currentTrans) {
// if (totalAmount!=null) {
return totalAmount;
// } else //if (percent!=null) {
// to be implemented return currentItem.get().multiply(getPercent().divide(new BigDecimal(100)));
//} else {
// throw new RuntimeException("Either totalAmount or percent must be set");
// }
}
public BigDecimal getPercent() {
return percent;

View File

@@ -0,0 +1,27 @@
/** **********************************************************************
*
* Copyright 2018 Jochen Staerk
*
* Use is subject to license terms.
*
* 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.
*
* 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.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
import java.math.BigDecimal;
public interface IAbsoluteValueProvider {
public BigDecimal getValue();
}

View File

@@ -24,8 +24,7 @@ import java.math.BigDecimal;
*/
public interface IZUGFeRDAllowanceCharge {
BigDecimal getTotalAmount(IZUGFeRDExportableItem currentItem);
BigDecimal getTotalAmount(IExportableTransaction trans);
BigDecimal getTotalAmount(IAbsoluteValueProvider trans);
String getReason();

View File

@@ -30,7 +30,7 @@ import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants;
import java.math.BigDecimal;
public interface IZUGFeRDExportableItem {
public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
IZUGFeRDExportableProduct getProduct();
@@ -46,6 +46,10 @@ public interface IZUGFeRDExportableItem {
*/
BigDecimal getPrice();
@Override
default BigDecimal getValue() {
return getPrice();
}
/**
* how many get billed
*

View File

@@ -38,7 +38,7 @@ import org.dom4j.io.XMLWriter;
import org.mustangproject.Invoice;
import org.mustangproject.XMLTools;
public class ZUGFeRD2PullProvider implements IXMLProvider {
public class ZUGFeRD2PullProvider implements IXMLProvider, IAbsoluteValueProvider {
//// MAIN CLASS
protected SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd");
@@ -96,7 +96,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
return res;
}
//move
private BigDecimal getTotalPrepaid() {
if (trans.getTotalPrepaidAmount() == null) {
return new BigDecimal(0);
@@ -121,7 +121,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges();
if ((charges != null) && (charges.length > 0)) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) {
res = res.add(currentCharge.getTotalAmount(trans));
res = res.add(currentCharge.getTotalAmount(this));
}
}
return res;
@@ -132,7 +132,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances();
if ((allowances != null) && (allowances.length > 0)) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
res = res.add(currentAllowance.getTotalAmount(trans));
res = res.add(currentAllowance.getTotalAmount(this));
}
}
return res;
@@ -183,7 +183,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
if (theAmount == null) {
theAmount = new VATAmount(new BigDecimal(0), new BigDecimal(0), "S");
}
theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(trans)));
theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(this)));
BigDecimal factor = currentCharge.getTaxPercent().divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(currentCharge.getTaxPercent(), theAmount);
@@ -196,7 +196,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
if (theAmount == null) {
theAmount = new VATAmount(new BigDecimal(0), new BigDecimal(0), "S");
}
theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(trans)));
theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this)));
BigDecimal factor = currentAllowance.getTaxPercent().divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor));
@@ -207,7 +207,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
return hm;
}
@Override
public Profile getProfile() {
return profile;
@@ -701,4 +700,8 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
return paymentTermsXml;
}
@Override
public BigDecimal getValue() {
return getTotal();
}
}

View File

@@ -27,12 +27,7 @@ public class IZUGFeRDAllowanceChargeImpl implements IZUGFeRDAllowanceCharge {
boolean isCharge=true;
@Override
public BigDecimal getTotalAmount(IZUGFeRDExportableItem currentItem) {
return totalAmount;
}
@Override
public BigDecimal getTotalAmount(IExportableTransaction currentTransaction) {
public BigDecimal getTotalAmount(IAbsoluteValueProvider currentItem) {
return totalAmount;
}

View File

@@ -39,6 +39,7 @@ public class ZF2PushTest extends TestCase {
final String TARGET_CORRECTIONPDF = "./target/testout-ZF2PushCorrection.pdf";
final String TARGET_ITEMCHARGESALLOWANCESPDF = "./target/testout-ZF2PushItemChargesAllowances.pdf";
final String TARGET_CHARGESALLOWANCESPDF = "./target/testout-ZF2PushChargesAllowances.pdf";
final String TARGET_RELATIVECHARGESALLOWANCESPDF = "./target/testout-ZF2PushRelativeChargesAllowances.pdf";
final String TARGET_ATTACHMENTSPDF = "./target/testout-ZF2PushAttachments.pdf";
public void testPushExport() {
@@ -233,6 +234,51 @@ public class ZF2PushTest extends TestCase {
}
}
public void testRelativeChargesAllowancesExport() {
String orgname = "Test company";
String number = "123";
String amountStr = "3.00";
BigDecimal amount = new BigDecimal(amountStr);
try (InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");
ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1().setProducer("My Application")
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("en16931")).ignorePDFAErrors()
.load(SOURCE_PDF)) {
ze.setTransaction(new Invoice().setCurrency("CHF").setDueDate(new Date()).setOccurrenceDate(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)))
.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)))
.addAllowance(new Allowance().setPercent(new BigDecimal(50 )).setTaxPercent(new BigDecimal(19)))
);
String theXML = new String(ze.getProvider().getXML());
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
ze.export(TARGET_RELATIVECHARGESALLOWANCESPDF);
} catch (IOException e) {
fail("IOException should not be raised in testEdgeExport");
}
// now check the contents (like MustangReaderTest)
ZUGFeRDImporter zi = new ZUGFeRDImporter(TARGET_RELATIVECHARGESALLOWANCESPDF);
assertFalse(zi.getUTF8().contains("EUR"));
// Reading ZUGFeRD
assertEquals("5.36", zi.getAmount());
assertEquals(zi.getHolder(), orgname);
assertEquals(zi.getForeignReference(), number);
try {
assertEquals(zi.getVersion(), 2);
} catch (Exception e) {
e.printStackTrace();
}
}

View File

@@ -80,6 +80,25 @@ public class LibraryTest extends ResourceCase {
}
public void testLibraryPushRelativeAllowances() {
File tempFile = new File("../library/target/testout-ZF2PushRelativeChargesAllowances.pdf");
assertTrue(tempFile.exists());
ZUGFeRDValidator zfv = new ZUGFeRDValidator();
String res = zfv.validate(tempFile.getAbsolutePath());
assertThat(res).valueByXPath("/validation/pdf/summary/@status")
.isEqualTo("valid");
assertThat(res).valueByXPath("/validation/xml/summary/@status")
.isEqualTo("valid");
assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("valid");
}
public void testLibraryPushAllowances() {
File tempFile = new File("../library/target/testout-ZF2PushChargesAllowances.pdf");
assertTrue(tempFile.exists());

View File

@@ -64,6 +64,11 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid");
zfv = new ZUGFeRDValidator();
res = zfv.validate("/does/not/exist");
assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid");
}
/***