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.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.mustangproject.ZUGFeRD.IZUGFeRDExportableContact;
import org.mustangproject.ZUGFeRD.*; 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.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/*** /***
* A organisation, i.e. usually a company * 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() != null) {
if ((taxChilds.item(taxChildIndex).getLocalName().equals("ID"))) { if ((taxChilds.item(taxChildIndex).getLocalName().equals("ID"))) {
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID") != null) { if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID") != null) {
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("VA")) { Node firstChild = taxChilds.item(taxChildIndex).getFirstChild();
setVATID(taxChilds.item(taxChildIndex).getFirstChild().getNodeValue()); 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());
} }
if (taxChilds.item(taxChildIndex).getAttributes().getNamedItem("schemeID").getNodeValue().equals("FC")) {
setTaxID(taxChilds.item(taxChildIndex).getFirstChild().getNodeValue());
} }
} }
} }

View File

@@ -8,7 +8,9 @@ import java.util.HashMap;
import java.util.stream.Stream; 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 * @see LineCalculator
*/ */
public class TransactionCalculator implements IAbsoluteValueProvider { 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 * @return prepaid amount
*/ */
protected BigDecimal getTotalPrepaid() { 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 * @return the invoice total including taxes
*/ */
public BigDecimal getGrandTotal() { public BigDecimal getGrandTotal() {
final BigDecimal res = getTaxBasis(); final BigDecimal res = getTaxBasis();
return getVATPercentAmountMap().values().stream() return getVATPercentAmountMap().values().stream().map(VATAmount::getCalculated)
.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(res);
} }
/*** /***
* returns total of charges for this tax rate * returns total of charges for this tax rate
*
* @param percent a specific rate, or null for any rate * @param percent a specific rate, or null for any rate
* @return the total amount * @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 * @param percent a specific rate, or null for any rate
* @return the space separated String * @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 * @param percent a specific rate, or null for any rate
* @return the space separated String * @return the space separated String
*/ */
@@ -111,9 +120,9 @@ public class TransactionCalculator implements IAbsoluteValueProvider {
return res; return res;
} }
/*** /***
* returns total of allowances for this tax rate * returns total of allowances for this tax rate
*
* @param percent a specific rate, or null for any rate * @param percent a specific rate, or null for any rate
* @return the total amount * @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 * @return item sum
*/ */
protected BigDecimal getTotal() { protected BigDecimal getTotal() {
BigDecimal dec = Stream.of(trans.getZFItems()) BigDecimal dec = Stream.of(trans.getZFItems()).map(LineCalculator::new)
.map(LineCalculator::new) .map(LineCalculator::getItemTotalNetAmount).reduce(ZERO, BigDecimal::add);
.map(LineCalculator::getItemTotalNetAmount)
.reduce(ZERO, BigDecimal::add);
return dec; return dec;
} }
/*** /***
* returns the total net value of the invoice, including charges/allowances on document * returns the total net value of the invoice, including charges/allowances on
* level * document level
*
* @return item sum +- charges/allowances * @return item sum +- charges/allowances
*/ */
protected BigDecimal getTaxBasis() { 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(); IZUGFeRDAllowanceCharge[] charges = trans.getZFCharges();
if ((charges != null) && (charges.length > 0)) { if ((charges != null) && (charges.length > 0)) {
for (IZUGFeRDAllowanceCharge currentCharge : charges) { for (IZUGFeRDAllowanceCharge currentCharge : charges) {
VATAmount theAmount = hm.get(currentCharge.getTaxPercent().stripTrailingZeros()); BigDecimal taxPercent = currentCharge.getTaxPercent();
if (taxPercent != null) {
VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros());
if (theAmount == null) { if (theAmount == null) {
theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO, theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO,
currentCharge.getCategoryCode() != null ? currentCharge.getCategoryCode() : "S"); currentCharge.getCategoryCode() != null ? currentCharge.getCategoryCode() : "S");
} }
theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(this))); theAmount.setBasis(theAmount.getBasis().add(currentCharge.getTotalAmount(this)));
BigDecimal factor = currentCharge.getTaxPercent().divide(new BigDecimal(100)); BigDecimal factor = taxPercent.divide(new BigDecimal(100));
theAmount.setCalculated(theAmount.getBasis().multiply(factor)); theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(currentCharge.getTaxPercent().stripTrailingZeros(), theAmount); hm.put(taxPercent.stripTrailingZeros(), theAmount);
}
} }
} }
IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances(); IZUGFeRDAllowanceCharge[] allowances = trans.getZFAllowances();
if ((allowances != null) && (allowances.length > 0)) { if ((allowances != null) && (allowances.length > 0)) {
for (IZUGFeRDAllowanceCharge currentAllowance : allowances) { for (IZUGFeRDAllowanceCharge currentAllowance : allowances) {
VATAmount theAmount = hm.get(currentAllowance.getTaxPercent().stripTrailingZeros()); BigDecimal taxPercent = currentAllowance.getTaxPercent();
VATAmount theAmount = hm.get(taxPercent.stripTrailingZeros());
if (theAmount == null) { if (theAmount == null) {
theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO, theAmount = new VATAmount(BigDecimal.ZERO, BigDecimal.ZERO,
currentAllowance.getCategoryCode() != null ? currentAllowance.getCategoryCode() : "S"); currentAllowance.getCategoryCode() != null ? currentAllowance.getCategoryCode() : "S");
} }
theAmount.setBasis(theAmount.getBasis().subtract(currentAllowance.getTotalAmount(this))); 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)); theAmount.setCalculated(theAmount.getBasis().multiply(factor));
hm.put(currentAllowance.getTaxPercent().stripTrailingZeros(), theAmount); hm.put(taxPercent.stripTrailingZeros(), theAmount);
} }
} }
return hm; return hm;
} }
@Override @Override
public BigDecimal getValue() { public BigDecimal getValue() {
return getTotal(); return getTotal();

View File

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