ZUGFeRD Version 1 importieren
This commit is contained in:
@@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user