Merge pull request #786 from Shorty1o1/master
Fix Invoices with Category Code "O"
This commit is contained in:
@@ -135,7 +135,7 @@ public class VATAmount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public VATAmount add(VATAmount v) {
|
public VATAmount add(VATAmount v) {
|
||||||
return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated()), this.categoryCode, this.dueDateTypeCode).setVatExemptionReasonText(v.getVatExemptionReasonText());
|
return new VATAmount(basis.add(v.getBasis()), calculated.add(v.getCalculated()), this.categoryCode, this.dueDateTypeCode).setVatExemptionReasonText(v.getVatExemptionReasonText() != null ? v.getVatExemptionReasonText(): this.vatExemptionReasonText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VATAmount subtract(VATAmount v) {
|
public VATAmount subtract(VATAmount v) {
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import org.mustangproject.IncludedNote;
|
|||||||
import org.mustangproject.ReferencedDocument;
|
import org.mustangproject.ReferencedDocument;
|
||||||
import org.mustangproject.XMLTools;
|
import org.mustangproject.XMLTools;
|
||||||
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
|
import org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants;
|
||||||
|
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -152,12 +153,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
if (profile == Profiles.getByName("Minimum")) {
|
if (profile == Profiles.getByName("Minimum")) {
|
||||||
xml += "<ram:ID>" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + "</ram:ID>";
|
xml += "<ram:ID>" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + "</ram:ID>";
|
||||||
} else {
|
} else {
|
||||||
String schemeAttribute="";
|
String schemeAttribute = "";
|
||||||
if ((party.getLegalOrganisation().getSchemedID().getScheme()!=null)&&(party.getLegalOrganisation().getSchemedID().getScheme().length()>0)) {
|
if ((party.getLegalOrganisation().getSchemedID().getScheme() != null) && (party.getLegalOrganisation().getSchemedID().getScheme().length() > 0)) {
|
||||||
schemeAttribute="schemeID=\"" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getScheme())+"\"";
|
schemeAttribute = "schemeID=\"" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getScheme()) + "\"";
|
||||||
|
|
||||||
}
|
}
|
||||||
xml += "<ram:ID "+schemeAttribute+">" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + "</ram:ID>";
|
xml += "<ram:ID " + schemeAttribute + ">" + XMLTools.encodeXML(party.getLegalOrganisation().getSchemedID().getID()) + "</ram:ID>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (party.getLegalOrganisation().getTradingBusinessName() != null) {
|
if (party.getLegalOrganisation().getTradingBusinessName() != null) {
|
||||||
@@ -395,20 +396,20 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
+ "</rsm:ExchangedDocumentContext>"
|
+ "</rsm:ExchangedDocumentContext>"
|
||||||
+ "<rsm:ExchangedDocument>"
|
+ "<rsm:ExchangedDocument>"
|
||||||
+ "<ram:ID>" + XMLTools.encodeXML(trans.getNumber()) + "</ram:ID>";
|
+ "<ram:ID>" + XMLTools.encodeXML(trans.getNumber()) + "</ram:ID>";
|
||||||
if (profile == Profiles.getByName("Extended") && trans.getDocumentName() != null) {
|
if (profile == Profiles.getByName("Extended") && trans.getDocumentName() != null) {
|
||||||
xml += "<ram:Name>" + XMLTools.encodeXML(trans.getDocumentName()) + "</ram:Name>";
|
xml += "<ram:Name>" + XMLTools.encodeXML(trans.getDocumentName()) + "</ram:Name>";
|
||||||
}
|
}
|
||||||
xml += "<ram:TypeCode>" + typecode + "</ram:TypeCode>"
|
xml += "<ram:TypeCode>" + typecode + "</ram:TypeCode>"
|
||||||
+ "<ram:IssueDateTime>" + DATE.udtFormat(trans.getIssueDate()) + "</ram:IssueDateTime>" // date
|
+ "<ram:IssueDateTime>" + DATE.udtFormat(trans.getIssueDate()) + "</ram:IssueDateTime>" // date
|
||||||
+ buildNotes(trans)
|
+ buildNotes(trans)
|
||||||
+ "</rsm:ExchangedDocument>"
|
+ "</rsm:ExchangedDocument>"
|
||||||
+ "<rsm:SupplyChainTradeTransaction>";
|
+ "<rsm:SupplyChainTradeTransaction>";
|
||||||
int lineID = 0;
|
int lineID = 0;
|
||||||
for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
|
for (final IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
|
||||||
lineID++;
|
lineID++;
|
||||||
String lineIDStr = Integer.toString(lineID);
|
String lineIDStr = Integer.toString(lineID);
|
||||||
if (currentItem.getId()!=null) {
|
if (currentItem.getId() != null) {
|
||||||
lineIDStr=currentItem.getId();
|
lineIDStr = currentItem.getId();
|
||||||
}
|
}
|
||||||
final LineCalculator lc = new LineCalculator(currentItem);
|
final LineCalculator lc = new LineCalculator(currentItem);
|
||||||
if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) {
|
if ((getProfile() != Profiles.getByName("Minimum")) && (getProfile() != Profiles.getByName("BasicWL"))) {
|
||||||
@@ -531,15 +532,16 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
+ "<ram:SpecifiedLineTradeSettlement>"
|
+ "<ram:SpecifiedLineTradeSettlement>"
|
||||||
+ "<ram:ApplicableTradeTax>"
|
+ "<ram:ApplicableTradeTax>"
|
||||||
+ "<ram:TypeCode>VAT</ram:TypeCode>";
|
+ "<ram:TypeCode>VAT</ram:TypeCode>";
|
||||||
|
|
||||||
if (currentItem.getProduct().getTaxExemptionReason() != null) {
|
if (currentItem.getProduct().getTaxExemptionReason() != null) {
|
||||||
xml += "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>";
|
xml += "<ram:ExemptionReason>" + XMLTools.encodeXML(currentItem.getProduct().getTaxExemptionReason()) + "</ram:ExemptionReason>";
|
||||||
}
|
}
|
||||||
|
xml += "<ram:CategoryCode>" + currentItem.getProduct().getTaxCategoryCode() + "</ram:CategoryCode>";
|
||||||
xml += "<ram:CategoryCode>" + currentItem.getProduct().getTaxCategoryCode() + "</ram:CategoryCode>"
|
if (!currentItem.getProduct().getTaxCategoryCode().equals(TaxCategoryCodeTypeConstants.UNTAXEDSERVICE)) {
|
||||||
+ "<ram:RateApplicablePercent>"
|
xml += "<ram:RateApplicablePercent>"
|
||||||
+ vatFormat(currentItem.getProduct().getVATPercent()) + "</ram:RateApplicablePercent>"
|
+ vatFormat(currentItem.getProduct().getVATPercent()) + "</ram:RateApplicablePercent>";
|
||||||
+ "</ram:ApplicableTradeTax>";
|
}
|
||||||
|
xml += "</ram:ApplicableTradeTax>";
|
||||||
|
|
||||||
if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) {
|
if ((currentItem.getDetailedDeliveryPeriodFrom() != null) || (currentItem.getDetailedDeliveryPeriodTo() != null)) {
|
||||||
xml += "<ram:BillingSpecifiedPeriod>";
|
xml += "<ram:BillingSpecifiedPeriod>";
|
||||||
if (currentItem.getDetailedDeliveryPeriodFrom() != null) {
|
if (currentItem.getDetailedDeliveryPeriodFrom() != null) {
|
||||||
@@ -725,9 +727,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
+ exemptionReasonTextXML
|
+ exemptionReasonTextXML
|
||||||
+ "<ram:BasisAmount>" + currencyFormat(amount.getBasis()) + "</ram:BasisAmount>" // currencyID=\"EUR\"
|
+ "<ram:BasisAmount>" + currencyFormat(amount.getBasis()) + "</ram:BasisAmount>" // currencyID=\"EUR\"
|
||||||
+ "<ram:CategoryCode>" + amountCategoryCode + "</ram:CategoryCode>"
|
+ "<ram:CategoryCode>" + amountCategoryCode + "</ram:CategoryCode>"
|
||||||
+ (amountDueDateTypeCode != null ? "<ram:DueDateTypeCode>" + amountDueDateTypeCode + "</ram:DueDateTypeCode>" : "")
|
+ (amountDueDateTypeCode != null ? "<ram:DueDateTypeCode>" + amountDueDateTypeCode + "</ram:DueDateTypeCode>" : "");
|
||||||
+ "<ram:RateApplicablePercent>"
|
if (!amountCategoryCode.equals(TaxCategoryCodeTypeConstants.UNTAXEDSERVICE)) {
|
||||||
+ vatFormat(currentTaxPercent) + "</ram:RateApplicablePercent></ram:ApplicableTradeTax>";
|
xml += "<ram:RateApplicablePercent>"
|
||||||
|
+ vatFormat(currentTaxPercent) + "</ram:RateApplicablePercent>";
|
||||||
|
}
|
||||||
|
xml += "</ram:ApplicableTradeTax>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -743,7 +748,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) {
|
if ((trans.getZFCharges() != null) && (trans.getZFCharges().length > 0)) {
|
||||||
if ((profile == Profiles.getByName("XRechnung")) || (profile == Profiles.getByName("EN16931")) || (profile == Profiles.getByName("EXTENDED"))) {
|
if ((profile == Profiles.getByName("XRechnung")) || (profile == Profiles.getByName("EN16931")) || (profile == Profiles.getByName("EXTENDED"))) {
|
||||||
for (IZUGFeRDAllowanceCharge charge : trans.getZFCharges()) {
|
for (IZUGFeRDAllowanceCharge charge : trans.getZFCharges()) {
|
||||||
xml += "<ram:SpecifiedTradeAllowanceCharge>" +
|
xml += "<ram:SpecifiedTradeAllowanceCharge>" +
|
||||||
"<ram:ChargeIndicator>" +
|
"<ram:ChargeIndicator>" +
|
||||||
@@ -759,7 +764,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
xml += "<ram:CategoryTradeTax>" +
|
xml += "<ram:CategoryTradeTax>" +
|
||||||
"<ram:TypeCode>VAT</ram:TypeCode>" +
|
"<ram:TypeCode>VAT</ram:TypeCode>" +
|
||||||
"<ram:CategoryCode>" + charge.getCategoryCode() + "</ram:CategoryCode>";
|
"<ram:CategoryCode>" + charge.getCategoryCode() + "</ram:CategoryCode>";
|
||||||
if (charge.getTaxPercent() != null) {
|
if (charge.getTaxPercent() != null && !charge.getCategoryCode().equals(TaxCategoryCodeTypeConstants.UNTAXEDSERVICE)) {
|
||||||
xml += "<ram:RateApplicablePercent>" + vatFormat(charge.getTaxPercent()) + "</ram:RateApplicablePercent>";
|
xml += "<ram:RateApplicablePercent>" + vatFormat(charge.getTaxPercent()) + "</ram:RateApplicablePercent>";
|
||||||
}
|
}
|
||||||
xml += "</ram:CategoryTradeTax>" +
|
xml += "</ram:CategoryTradeTax>" +
|
||||||
@@ -834,7 +839,7 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
if (paymentTermsDescription != null) {
|
if (paymentTermsDescription != null) {
|
||||||
xml += "<ram:Description>" + paymentTermsDescription + "</ram:Description>";
|
xml += "<ram:Description>" + paymentTermsDescription + "</ram:Description>";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trans.getDueDate() != null) {
|
if (trans.getDueDate() != null) {
|
||||||
xml += "<ram:DueDateDateTime>" // $NON-NLS-2$
|
xml += "<ram:DueDateDateTime>" // $NON-NLS-2$
|
||||||
+ DATE.udtFormat(trans.getDueDate())
|
+ DATE.udtFormat(trans.getDueDate())
|
||||||
@@ -902,12 +907,12 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
|
|||||||
if (trans.getInvoiceReferencedDocuments() != null) {
|
if (trans.getInvoiceReferencedDocuments() != null) {
|
||||||
for (ReferencedDocument doc : trans.getInvoiceReferencedDocuments()) {
|
for (ReferencedDocument doc : trans.getInvoiceReferencedDocuments()) {
|
||||||
xml += "<ram:InvoiceReferencedDocument>"
|
xml += "<ram:InvoiceReferencedDocument>"
|
||||||
+ "<ram:IssuerAssignedID>"
|
+ "<ram:IssuerAssignedID>"
|
||||||
+ XMLTools.encodeXML(doc.getIssuerAssignedID()) + "</ram:IssuerAssignedID>";
|
+ XMLTools.encodeXML(doc.getIssuerAssignedID()) + "</ram:IssuerAssignedID>";
|
||||||
if (doc.getFormattedIssueDateTime() != null) {
|
if (doc.getFormattedIssueDateTime() != null) {
|
||||||
xml += "<ram:FormattedIssueDateTime>"
|
xml += "<ram:FormattedIssueDateTime>"
|
||||||
+ DATE.qdtFormat(doc.getFormattedIssueDateTime())
|
+ DATE.qdtFormat(doc.getFormattedIssueDateTime())
|
||||||
+ "</ram:FormattedIssueDateTime>";
|
+ "</ram:FormattedIssueDateTime>";
|
||||||
}
|
}
|
||||||
xml += "</ram:InvoiceReferencedDocument>";
|
xml += "</ram:InvoiceReferencedDocument>";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
/** **********************************************************************
|
/**
|
||||||
*
|
* *********************************************************************
|
||||||
|
* <p>
|
||||||
* Copyright 2018 Jochen Staerk
|
* Copyright 2018 Jochen Staerk
|
||||||
*
|
* <p>
|
||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*
|
* <p>
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
* 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
|
* 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.
|
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
*
|
* <p>
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
*
|
* <p>
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
* <p>
|
||||||
*********************************************************************** */
|
* **********************************************************************
|
||||||
|
*/
|
||||||
package org.mustangproject.ZUGFeRD.model;
|
package org.mustangproject.ZUGFeRD.model;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -31,5 +33,5 @@ public class TaxCategoryCodeTypeConstants {
|
|||||||
public static final String INTRACOMMUNITY = "K";
|
public static final String INTRACOMMUNITY = "K";
|
||||||
public static final String FREEEXPORT = "G";
|
public static final String FREEEXPORT = "G";
|
||||||
|
|
||||||
public static Set<String> CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT, FREEEXPORT).collect(Collectors.toSet());
|
public static Set<String> CATEGORY_CODES_WITH_EXEMPTION_REASON = Stream.of(INTRACOMMUNITY, REVERSECHARGE, TAXEXEMPT, FREEEXPORT, UNTAXEDSERVICE).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import junit.framework.TestCase;
|
|||||||
import org.mustangproject.*;
|
import org.mustangproject.*;
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
|
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants;
|
||||||
|
|
||||||
|
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
@@ -52,8 +53,8 @@ public class XRTest extends TestCase {
|
|||||||
TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE");
|
TradeParty recipient = new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE");
|
||||||
recipient.setEmail("quack@ducktown.org");
|
recipient.setEmail("quack@ducktown.org");
|
||||||
Invoice i = createInvoice(recipient);
|
Invoice i = createInvoice(recipient);
|
||||||
String legalOrgID="aCustomSellerLegalOrgId";
|
String legalOrgID = "aCustomSellerLegalOrgId";
|
||||||
String sellerID="aSellerTradePartyID";
|
String sellerID = "aSellerTradePartyID";
|
||||||
i.getSender().setLegalOrganisation(new LegalOrganisation(legalOrgID));
|
i.getSender().setLegalOrganisation(new LegalOrganisation(legalOrgID));
|
||||||
i.getSender().setID(sellerID);
|
i.getSender().setID(sellerID);
|
||||||
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
|
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
|
||||||
@@ -61,8 +62,8 @@ public class XRTest extends TestCase {
|
|||||||
zf2p.generateXML(i);
|
zf2p.generateXML(i);
|
||||||
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
|
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
|
||||||
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
|
||||||
assertTrue(theXML.contains("<ram:ID>"+sellerID+"</ram:ID>"));// must be possible without scheme #
|
assertTrue(theXML.contains("<ram:ID>" + sellerID + "</ram:ID>"));// must be possible without scheme #
|
||||||
assertTrue(theXML.contains("<ram:ID>"+legalOrgID+"</ram:ID>"));// must be possible without scheme #
|
assertTrue(theXML.contains("<ram:ID>" + legalOrgID + "</ram:ID>"));// must be possible without scheme #
|
||||||
assertThat(theXML).valueByXPath("count(//*[local-name()='IncludedSupplyChainTradeLineItem'])")
|
assertThat(theXML).valueByXPath("count(//*[local-name()='IncludedSupplyChainTradeLineItem'])")
|
||||||
.asInt()
|
.asInt()
|
||||||
.isEqualTo(1); //2 errors are OK because there is a known bug
|
.isEqualTo(1); //2 errors are OK because there is a known bug
|
||||||
@@ -81,6 +82,7 @@ public class XRTest extends TestCase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testXREdgeExport() {
|
public void testXREdgeExport() {
|
||||||
|
|
||||||
// the writing part
|
// the writing part
|
||||||
@@ -100,7 +102,7 @@ public class XRTest extends TestCase {
|
|||||||
.setReferenceNumber("991-01484-64")//leitweg-id
|
.setReferenceNumber("991-01484-64")//leitweg-id
|
||||||
// not using any VAT, this is also a test of zero-rated goods:
|
// not using any VAT, this is also a test of zero-rated goods:
|
||||||
.setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO).setTaxExemptionReason("Kleinunternehmer"), amount, new BigDecimal(1.0)))
|
.setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", BigDecimal.ZERO).setTaxExemptionReason("Kleinunternehmer"), amount, new BigDecimal(1.0)))
|
||||||
.setPayee( new TradeParty().setName("VR Factoring GmbH").setID("DE813838785").setLegalOrganisation(new LegalOrganisation("391200LDDFJDMIPPMZ54", "0199")))
|
.setPayee(new TradeParty().setName("VR Factoring GmbH").setID("DE813838785").setLegalOrganisation(new LegalOrganisation("391200LDDFJDMIPPMZ54", "0199")))
|
||||||
.embedFileInXML(fe1);
|
.embedFileInXML(fe1);
|
||||||
|
|
||||||
|
|
||||||
@@ -140,9 +142,9 @@ public class XRTest extends TestCase {
|
|||||||
fail("ParseException not expected");
|
fail("ParseException not expected");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
fail("IOException not expected");
|
fail("IOException not expected");
|
||||||
}
|
}
|
||||||
FileAttachment[] attachedFiles=readInvoice.getAdditionalReferencedDocuments();
|
FileAttachment[] attachedFiles = readInvoice.getAdditionalReferencedDocuments();
|
||||||
assertNotNull(attachedFiles);
|
assertNotNull(attachedFiles);
|
||||||
assertEquals(attachedFiles.length, 1);
|
assertEquals(attachedFiles.length, 1);
|
||||||
|
|
||||||
assertTrue(Arrays.equals(attachedFiles[0].getData(), b));
|
assertTrue(Arrays.equals(attachedFiles[0].getData(), b));
|
||||||
@@ -205,10 +207,40 @@ public class XRTest extends TestCase {
|
|||||||
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
|
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
|
||||||
assertThat(theXML).valueByXPath("count(//*[local-name()='ExemptionReason'])")
|
assertThat(theXML).valueByXPath("count(//*[local-name()='ExemptionReason'])")
|
||||||
.asInt()
|
.asInt()
|
||||||
.isEqualTo(1);
|
.isEqualTo(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testApplicablePercentInUntaxedService() {
|
||||||
|
|
||||||
|
// the writing part
|
||||||
|
TradeParty recipient = new TradeParty("Franz Müller", null, "55232", "Entenhausen", "DE");
|
||||||
|
String orgname = "Test company";
|
||||||
|
String number = "123";
|
||||||
|
String amountStr = "1.00";
|
||||||
|
BigDecimal amount = new BigDecimal(amountStr);
|
||||||
|
var i = new Invoice().setDueDate(new java.util.Date()).setIssueDate(new java.util.Date()).setDeliveryDate(new java.util.Date())
|
||||||
|
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("DE4711").addVATID("DE0815").setEmail("info@example.org").setContact(new org.mustangproject.Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new org.mustangproject.BankDetails("DE12500105170648489890", "COBADEFXXX")))
|
||||||
|
.setRecipient(recipient)
|
||||||
|
.setReferenceNumber("991-01484-64")//leitweg-id
|
||||||
|
// not using any VAT, this is also a test of zero-rated goods:
|
||||||
|
.setNumber(number).addItem(new org.mustangproject.Item(new org.mustangproject.Product("Testprodukt", "", "C62", java.math.BigDecimal.ZERO).setTaxCategoryCode(TaxCategoryCodeTypeConstants.UNTAXEDSERVICE).setTaxExemptionReason("Expemtion reason"), amount, new java.math.BigDecimal(1.0)));
|
||||||
|
|
||||||
|
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
|
||||||
|
zf2p.setProfile(Profiles.getByName("XRechnung"));
|
||||||
|
zf2p.generateXML(i);
|
||||||
|
String theXML = new String(zf2p.getXML(), StandardCharsets.UTF_8);
|
||||||
|
// Untaxed services don't have the field RateApplicablePercent, since it would be always 0. An error is thrown on validation, if 0 is set.
|
||||||
|
assertThat(theXML).valueByXPath("count(//*[local-name()='RateApplicablePercent'])")
|
||||||
|
.asInt()
|
||||||
|
.isEqualTo(0);
|
||||||
|
|
||||||
|
//Exemption reason needs to be set if TaxCategoryCode == "O", reason should be at the product and in the ApplicableTradeTax
|
||||||
|
assertThat(theXML).valueByXPath("count(//*[local-name()='ExemptionReason'])")
|
||||||
|
.asInt()
|
||||||
|
.isEqualTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
private org.mustangproject.Invoice createInvoice(TradeParty recipient) {
|
private org.mustangproject.Invoice createInvoice(TradeParty recipient) {
|
||||||
String orgname = "Test company";
|
String orgname = "Test company";
|
||||||
String number = "123";
|
String number = "123";
|
||||||
|
|||||||
Reference in New Issue
Block a user