ZUGFeRD Version 1 importieren

This commit is contained in:
Stefan Schmaltz
2022-10-10 16:59:29 +02:00
parent 7183cefe47
commit 5c0a3134ac
3 changed files with 73 additions and 42 deletions

View File

@@ -5,11 +5,16 @@ import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.mustangproject.ZUGFeRD.*;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableTradeParty;
import org.mustangproject.ZUGFeRD.IZUGFeRDLegalOrganisation;
import org.mustangproject.ZUGFeRD.IZUGFeRDTradeSettlement;
import org.mustangproject.ZUGFeRD.IZUGFeRDTradeSettlementDebit;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/***
* A organisation, i.e. usually a company
*/
@@ -136,11 +141,17 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
if (taxChilds.item(taxChildIndex).getLocalName() != null) {
if ((taxChilds.item(taxChildIndex).getLocalName().equals("ID"))) {
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID") != null) {
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("VA")) {
setVATID(taxChilds.item(taxChildIndex).getFirstChild().getNodeValue());
}
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("FC")) {
setTaxID(taxChilds.item(taxChildIndex).getFirstChild().getNodeValue());
Node firstChild = taxChilds.item(taxChildIndex).getFirstChild();
if (firstChild != null)
{
if (taxChilds.item(taxChildIndex).getAttributes()
.getNamedItem("schemeID").getNodeValue().equals("VA")) {
setVATID(firstChild.getNodeValue());
}
if (taxChilds.item(taxChildIndex).getAttributes()
.getNamedItem("schemeID").getNodeValue().equals("FC")) {
setTaxID(firstChild.getNodeValue());
}
}
}
}

View File

@@ -8,7 +8,9 @@ import java.util.HashMap;
import java.util.stream.Stream;
/***
* The Transactioncalculator e.g. adds the line totals and applies VAT on whole invoices
* The Transactioncalculator e.g. adds the line totals and applies VAT on whole
* invoices
*
* @see LineCalculator
*/
public class TransactionCalculator implements IAbsoluteValueProvider {
@@ -23,7 +25,9 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
/***
* if something had already been paid in advance, this will get it from the transaction
* if something had already been paid in advance, this will get it from the
* transaction
*
* @return prepaid amount
*/
protected BigDecimal getTotalPrepaid() {
@@ -35,20 +39,21 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
/***
* the invoice total with VAT, corrected by prepaid amount, allowances and charges
* the invoice total with VAT, corrected by prepaid amount, allowances and
* charges
*
* @return the invoice total including taxes
*/
public BigDecimal getGrandTotal() {
final BigDecimal res = getTaxBasis();
return getVATPercentAmountMap().values().stream()
.map(VATAmount::getCalculated)
.map(p -> p.setScale(2, RoundingMode.HALF_UP))
.reduce(BigDecimal.ZERO, BigDecimal::add).add(res);
return getVATPercentAmountMap().values().stream().map(VATAmount::getCalculated)
.map(p -> p.setScale(2, RoundingMode.HALF_UP)).reduce(BigDecimal.ZERO, BigDecimal::add).add(res);
}
/***
* returns total of charges for this tax rate
*
* @param percent a specific rate, or null for any rate
* @return the total amount
*/
@@ -70,7 +75,9 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
/***
* returns a (potentially concatenated) string of charge reasons, or "Charges" if none are defined
* returns a (potentially concatenated) string of charge reasons, or "Charges"
* if none are defined
*
* @param percent a specific rate, or null for any rate
* @return the space separated String
*/
@@ -98,7 +105,9 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
/***
* returns a (potentially concatenated) string of allowance reasons, or "Allowances", if none are defined
* returns a (potentially concatenated) string of allowance reasons, or
* "Allowances", if none are defined
*
* @param percent a specific rate, or null for any rate
* @return the space separated String
*/
@@ -111,9 +120,9 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
return res;
}
/***
* returns total of allowances for this tax rate
*
* @param percent a specific rate, or null for any rate
* @return the total amount
*/
@@ -123,24 +132,27 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
/***
* returns the total net value of all items, without document level charges/allowances
* returns the total net value of all items, without document level
* charges/allowances
*
* @return item sum
*/
protected BigDecimal getTotal() {
BigDecimal dec = Stream.of(trans.getZFItems())
.map(LineCalculator::new)
.map(LineCalculator::getItemTotalNetAmount)
.reduce(ZERO, BigDecimal::add);
BigDecimal dec = Stream.of(trans.getZFItems()).map(LineCalculator::new)
.map(LineCalculator::getItemTotalNetAmount).reduce(ZERO, BigDecimal::add);
return dec;
}
/***
* returns the total net value of the invoice, including charges/allowances on document
* level
* returns the total net value of the invoice, including charges/allowances on
* document level
*
* @return item sum +- charges/allowances
*/
protected BigDecimal getTaxBasis() {
return getTotal().add(getChargesForPercent(null).setScale(2, RoundingMode.HALF_UP)).subtract(getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP)).setScale(2, RoundingMode.HALF_UP);
return getTotal().add(getChargesForPercent(null).setScale(2, RoundingMode.HALF_UP))
.subtract(getAllowancesForPercent(null).setScale(2, RoundingMode.HALF_UP))
.setScale(2, RoundingMode.HALF_UP);
}
/**
@@ -166,41 +178,43 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
}
}
IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges();
if ((charges != null) && (charges.length > 0)) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) {
VATAmount theAmount = hm.get(currentCharge.getTaxPercent().stripTrailingZeros());
if (theAmount == null) {
theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO,
currentCharge.getCategoryCode() != null ? currentCharge.getCategoryCode() : "S");
BigDecimal taxPercent = currentCharge.getTaxPercent();
if (taxPercent != null) {
VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros());
if (theAmount == null) {
theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO,
currentCharge.getCategoryCode() != null ? currentCharge.getCategoryCode() : "S");
}
theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(this)));
BigDecimal factor = taxPercent.divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(taxPercent.stripTrailingZeros(), theAmount);
}
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().stripTrailingZeros(), theAmount);
}
}
IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances();
if ((allowances != null) && (allowances.length > 0)) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
VATAmount theAmount = hm.get(currentAllowance.getTaxPercent().stripTrailingZeros());
BigDecimal taxPercent = currentAllowance.getTaxPercent();
VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros());
if (theAmount == null) {
theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO,
currentAllowance.getCategoryCode() != null ? currentAllowance.getCategoryCode() : "S");
}
theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this)));
BigDecimal factor = currentAllowance.getTaxPercent().divide(new BigDecimal(100));
BigDecimal factor = taxPercent.divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(currentAllowance.getTaxPercent().stripTrailingZeros(), theAmount);
hm.put(taxPercent.stripTrailingZeros(), theAmount);
}
}
return hm;
}
@Override
public BigDecimal getValue() {
return getTotal();

View File

@@ -63,7 +63,7 @@ public class ZUGFeRDImporter {
/**
* map filenames of additional XML files to their contents
*/
private HashMap<String, byte[]> additionalXMLs = new HashMap<>();
private final HashMap<String, byte[]> additionalXMLs = new HashMap<>();
/**
* Raw XML form of the extracted data - may be directly obtained.
*/
@@ -658,7 +658,9 @@ public class ZUGFeRDImporter {
}
if (getUTF8().contains("<rsm:CrossIndustryDocument")) {
return EStandard.zugferd;
} else if (getUTF8().contains("<rsm:CrossIndustryInvoice")) {
} else if (getUTF8().contains("<CrossIndustryDocument")) {
return EStandard.zugferd;
} else if (getUTF8().contains("<urn:rsm:CrossIndustryInvoice")) {
return EStandard.facturx;
} else if (getUTF8().contains("<SCRDMCCBDACIDAMessageStructure")) {
return EStandard.despatchadvice;
@@ -673,9 +675,13 @@ public class ZUGFeRDImporter {
if (!containsMeta) {
throw new Exception("Not yet parsed");
}
if (getUTF8().contains("<rsm:CrossIndustryDocument")||getUTF8().contains("<SCRDMCCBDACIDAMessageStructure")||getUTF8().contains("<rsm:SCRDMCCBDACIOMessageStructure")) {
String head = getUTF8();
if (head.contains("<rsm:CrossIndustryDocument") //
|| head.contains("<CrossIndustryDocument") //
|| head.contains("<SCRDMCCBDACIDAMessageStructure") //
|| head.contains("<rsm:SCRDMCCBDACIOMessageStructure")) { //
return 1;
} else if (getUTF8().contains("<rsm:CrossIndustryInvoice")) {
} else if (head.contains("<rsm:CrossIndustryInvoice")) {
return 2;
}
throw new Exception("ZUGFeRD version could not be determined");