org.mustangproject.ZUGFeRD.ZUGFeRD1PullProvider Maven / Gradle / Ivy
Show all versions of library Show documentation
/**
* *********************************************************************
*
* 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 static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE;
import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.mustangproject.XMLTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider {
private static final Logger LOGGER = LoggerFactory.getLogger (ZUGFeRD1PullProvider.class);
//// MAIN CLASS
protected byte[] zugferdData;
private String paymentTermsDescription;
protected Profile profile = Profiles.getByName("COMFORT", 1);
/**
* enables the flag to indicate a test invoice in the XML structure
*/
@Override
public void setTest() {
}
@Override
protected String vatFormat(BigDecimal value) {
return XMLTools.nDigitFormat(value, 2);
}
@Override
protected String currencyFormat(BigDecimal value) {
return XMLTools.nDigitFormat(value, 2);
}
@Override
protected String priceFormat(BigDecimal value) {
return XMLTools.nDigitFormat(value, 4);
}
@Override
protected String quantityFormat(BigDecimal value) {
return XMLTools.nDigitFormat(value, 4);
}
@Override
public Profile getProfile() {
return profile;
}
@Override
public byte[] getXML() {
byte[] res = zugferdData;
final StringWriter sw = new StringWriter();
Document document = null;
try {
document = DocumentHelper.parseText(new String(zugferdData));
} catch (final DocumentException e1) {
LOGGER.error ("Failed to parse ZUGFeRD data", e1);
}
try {
final OutputFormat format = OutputFormat.createPrettyPrint();
format.setTrimText(false);
final XMLWriter writer = new XMLWriter(sw, format);
writer.write(document);
res = sw.toString().getBytes(StandardCharsets.UTF_8);
} catch (final IOException e) {
LOGGER.error ("Failed to write ZUGFeRD data", e);
}
return res;
}
@Override
public void generateXML(IExportableTransaction trans) {
this.trans = trans;
this.calc = new TransactionCalculator(trans);
boolean hasDueDate = false;
final SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
String exemptionReason = "";
if (trans.getPaymentTermDescription() != null) {
paymentTermsDescription = trans.getPaymentTermDescription();
}
if (paymentTermsDescription == null) {
paymentTermsDescription = "Zahlbar ohne Abzug bis " + germanDateFormat.format(trans.getDueDate());
}
String senderReg = "";
if (trans.getOwnOrganisationFullPlaintextInfo() != null) {
senderReg = ""
+ XMLTools.encodeXML(trans.getOwnOrganisationFullPlaintextInfo()) + " "
+ "REG ";
}
String rebateAgreement = "";
if (trans.rebateAgreementExists()) {
rebateAgreement = ""
+ "Es bestehen Rabatt- und Bonusvereinbarungen. "
+ "AAK ";
}
String subjectNote = "";
if (trans.getSubjectNote() != null) {
subjectNote = ""
+ XMLTools.encodeXML(trans.getSubjectNote()) + " "
+ " ";
}
String typecode = "380";
if (trans.getDocumentCode() != null) {
typecode = trans.getDocumentCode();
}
String xml = ""
+ ""
+ ""
+ ""
// + "
// "+testBooleanStr+" "
//
+ ""
+ "" + getProfile().getID() + " "
+ " "
+ " "
+ ""
+ "" + XMLTools.encodeXML(trans.getNumber()) + " "
+ "RECHNUNG "
+ "" + typecode + " "
+ ""
+ DATE.udtFormat(trans.getIssueDate()) + " " // date
// format
// was
// 20130605
+ subjectNote
+ rebateAgreement
+ senderReg
+ " "
+ "";
xml += "";
if (trans.getReferenceNumber() != null) {
xml += "" + XMLTools.encodeXML(trans.getReferenceNumber()) + " ";
}
xml += "";
xml += getTradePartyAsXML(trans.getSender(), true, false);
xml += " "
+ "";
// + " GE2020211 "
// + " 4000001987658 "
xml += getTradePartyAsXML(trans.getRecipient(), false, false);
if ((trans.getOwnVATID() != null) && (trans.getOwnOrganisationName() != null)) {
xml += ""
+ XMLTools.encodeXML(trans.getOwnVATID()) + " "
+ " ";
}
xml += " ";
if (trans.getSellerOrderReferencedDocumentID() != null) {
xml += ""
+ ""
+ XMLTools.encodeXML(trans.getSellerOrderReferencedDocumentID()) + " "
+ " ";
}
if (trans.getBuyerOrderReferencedDocumentID() != null) {
xml += ""
+ ""
+ XMLTools.encodeXML(trans.getBuyerOrderReferencedDocumentID()) + " "
+ " ";
}
xml += " "
+ "";
if (this.trans.getDeliveryAddress() != null) {
xml += "" +
getTradePartyAsXML(this.trans.getDeliveryAddress(), false, true) +
" ";
}
xml += ""
+ "";
if (trans.getDeliveryDate() != null) {
xml += DATE.udtFormat(trans.getDeliveryDate());
} else {
throw new IllegalStateException("No delivery date provided");
}
xml += " ";
xml += " "
/*
* + "" +
* "20130603 " +
* "2013-51112 " +
* " "
*/
+ " "
+ "" + XMLTools.encodeXML(trans.getNumber()) + " "
+ "" + trans.getCurrency() + " ";
if (trans.getTradeSettlementPayment() != null) {
for (final IZUGFeRDTradeSettlementPayment payment : trans.getTradeSettlementPayment()) {
if (payment != null) {
hasDueDate = true;
xml += payment.getSettlementXML();
}
}
}
if (trans.getTradeSettlement() != null) {
for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) {
if (payment != null) {
if (payment instanceof IZUGFeRDTradeSettlementPayment) {
hasDueDate = true;
}
xml += payment.getSettlementXML();
}
}
}
final HashMap VATPercentAmountMap = calc.getVATPercentAmountMap();
for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
if (amount != null) {
final String amountCategoryCode = amount.getCategoryCode();
final String amountDueDateTypeCode = amount.getDueDateTypeCode();
final boolean displayExemptionReason = CATEGORY_CODES_WITH_EXEMPTION_REASON.contains(amountCategoryCode);
xml += ""
+ "" + currencyFormat(amount.getCalculated())
+ " " //currencyID=\"EUR\"
+ "VAT "
+ (displayExemptionReason ? exemptionReason : "")
+ "" + currencyFormat(amount.getBasis()) + " " // currencyID=\"EUR\"
+ "" + amount.getCategoryCode() + " "
+ (amountDueDateTypeCode != null ? "" + amountDueDateTypeCode + " " : "")
+ "" + vatFormat(currentTaxPercent)
+ " ";
}
}
if (trans.getPaymentTerms() == null) {
xml += ""
+ "" + paymentTermsDescription + " ";
if (trans.getTradeSettlement() != null) {
for (final IZUGFeRDTradeSettlement payment : trans.getTradeSettlement()) {
if ((payment != null) && (payment instanceof IZUGFeRDTradeSettlementDebit)) {
xml += payment.getPaymentXML();
}
}
}
if (hasDueDate && (trans.getDueDate() != null)) {
xml += "" // $NON-NLS-2$
+ DATE.udtFormat(trans.getDueDate())
+ " ";// 20130704
}
xml += " ";
} else {
xml += buildPaymentTermsXml();
}
xml += ""
+ "" + currencyFormat(calc.getTotal()) + " "
// currencyID=\"EUR\"
+ ""
+ currencyFormat(calc.getChargeTotal()) + " " // currencyID=\"EUR\"
+ ""
+ currencyFormat(calc.getAllowanceTotal()) + " " //
// currencyID=\"EUR\"
// + " 5.80 "
// + " 14.73 "
+ ""
+ currencyFormat(calc.getTaxBasis()) + " "
// //
// currencyID=\"EUR\"
+ ""
+ currencyFormat(calc.getGrandTotal().subtract(calc.getTaxBasis())) + " "
+ "" + currencyFormat(calc.getGrandTotal()) + " "
// //
// currencyID=\"EUR\"
+ "" + currencyFormat(calc.getTotalPrepaid()) + " "
+ "" + currencyFormat(calc.getGrandTotal().subtract(calc.getTotalPrepaid())) + " "
// //
// currencyID=\"EUR\"
+ " "
+ " ";
int lineID = 0;
for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
lineID++;
if (currentItem.getProduct().getTaxExemptionReason() != null) {
exemptionReason = "" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + " ";
}
final LineCalculator lc = new LineCalculator(currentItem);
xml += "" +
""
+ "" + lineID + " "
+ " "
+ ""
+ ""
+ "" + priceFormat(lc.getPriceGross())
+ " "
+ "" + quantityFormat(currentItem.getBasisQuantity()) + " "
// + " "
// + " false "
// + " 0.6667 "
// + " Rabatt "
// + " "
+ " "
+ ""
+ "" + priceFormat(currentItem.getPrice())
+ " "
+ "" + quantityFormat(currentItem.getBasisQuantity()) + " "
+ " "
+ " "
+ ""
+ ""
+ quantityFormat(currentItem.getQuantity()) + " "
+ " "
+ ""
+ ""
+ "VAT "
+ exemptionReason
+ "" + currentItem.getProduct().getTaxCategoryCode() + " "
+ ""
+ vatFormat(currentItem.getProduct().getVATPercent()) + " "
+ " "
+ ""
+ "" + currencyFormat(lc.getItemTotalNetAmount())
+ " "
+ " ";
if (currentItem.getAdditionalReferences() != null) {
xml += "" + currentItem.getAdditionalReferences()[0].getIssuerAssignedID() + " 130 ";
} else if (currentItem.getAdditionalReferencedDocumentID() != null) {
xml += "" + currentItem.getAdditionalReferencedDocumentID() + " 130 ";
}
xml += " "
+ "";
// + " 4012345001235 "
if (currentItem.getProduct().getSellerAssignedID() != null) {
xml += ""
+ XMLTools.encodeXML(currentItem.getProduct().getSellerAssignedID()) + " ";
}
if (currentItem.getProduct().getBuyerAssignedID() != null) {
xml += ""
+ XMLTools.encodeXML(currentItem.getProduct().getBuyerAssignedID()) + " ";
}
xml += "" + XMLTools.encodeXML(currentItem.getProduct().getName()) + " "
+ "" + XMLTools.encodeXML(currentItem.getProduct().getDescription())
+ " "
+ " "
+ " ";
}
// + " \n"
// + " \n"
// + " \n"
// + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr.
// 2013-51112 in Rechnung zu stellen: \n"
// + " \n"
// + " \n"
// + " \n";
xml += " "
+ " ";
final byte[] zugferdRaw;
zugferdRaw = xml.getBytes(StandardCharsets.UTF_8);
zugferdData = XMLTools.removeBOM(zugferdRaw);
}
@Override
public void setProfile(Profile p) {
profile = p;
}
private String buildPaymentTermsXml() {
String paymentTermsXml = "";
final IZUGFeRDPaymentTerms paymentTerms = trans.getPaymentTerms();
final IZUGFeRDPaymentDiscountTerms discountTerms = paymentTerms.getDiscountTerms();
final Date dueDate = paymentTerms.getDueDate();
if (dueDate != null && discountTerms != null && discountTerms.getBaseDate() != null) {
throw new IllegalStateException(
"if paymentTerms.dueDate is specified, paymentTerms.discountTerms.baseDate has not to be specified");
}
paymentTermsXml += "" + paymentTerms.getDescription() + " ";
if (dueDate != null) {
paymentTermsXml += "";
paymentTermsXml += DATE.udtFormat(dueDate);
paymentTermsXml += " ";
}
if (discountTerms != null) {
paymentTermsXml += "";
final String currency = trans.getCurrency();
final String basisAmount = currencyFormat(calc.getGrandTotal());
paymentTermsXml += "" + basisAmount + " ";
paymentTermsXml += "" + discountTerms.getCalculationPercentage().toString()
+ " ";
if (discountTerms.getBaseDate() != null) {
final Date baseDate = discountTerms.getBaseDate();
paymentTermsXml += "";
paymentTermsXml += DATE.udtFormat(baseDate);
paymentTermsXml += " ";
paymentTermsXml += ""
+ discountTerms.getBasePeriodMeasure() + " ";
}
paymentTermsXml += " ";
}
paymentTermsXml += " ";
return paymentTermsXml;
}
}