konik-io / konik

A library to create, read and validate ZUGFeRD compliant invoices. Available for Java and .NET
https://konik.io
Other
46 stars 18 forks source link

Basic Profile is not valid according to ZUV #89

Closed jlkDE closed 4 years ago

jlkDE commented 4 years ago

Hi,

when validating a Basic invoice with ZUV by ZUGFeRD Community, the same validation error as mentioned by #75 is shown.

2020-07-23-095353

this is the validation report:

<?xml version="1.0"?>
<!--?xml version="1.0" encoding="UTF-8"?-->
<validation filename="out.pdf" datetime="2020-07-23 09:37:34">
  <pdf>
    <report>
      <buildinformation>
        <releasedetails id="core" version="1.14.105" builddate="2019-10-24T22:54:00+02:00"/>
        <releasedetails id="validation-model" version="1.14.105" builddate="2019-10-24T22:59:00+02:00"/>
      </buildinformation>
      <jobs>
        <job>
          <item size="23138">
            <name>/var/www/zugferd_community/zugferd_checker/uploads/out.pdf</name>
          </item>
          <validationreport profilename="PDF/A-3B validation profile" statement="PDF file is compliant with Validation Profile requirements." iscompliant="true">
            <details passedrules="123" failedrules="0" passedchecks="499" failedchecks="0"/>
          </validationreport>
          <duration start="1595489854660" finish="1595489855968">00:00:01.308</duration>
        </job>
      </jobs>
      <batchsummary totaljobs="1" failedtoparse="0" encrypted="0">
        <validationreports compliant="1" noncompliant="0" failedjobs="0">1</validationreports>
        <featurereports failedjobs="0">0</featurereports>
        <repairreports failedjobs="0">0</repairreports>
        <duration start="1595489854451" finish="1595489856012">00:00:01.561</duration>
      </batchsummary>
    </report>
    <info>
      <signature>Konik</signature>
      <duration unit="ms">2214</duration>
    </info>
    <summary status="valid"/>
  </pdf>
  <xml>
    <info>
      <version>1</version>
      <profile>urn:ferd:CrossIndustryDocument:invoice:1p0:basic</profile>
      <validator version="0.9.1-SNAPSHOT"/>
      <rules>
        <fired>56</fired>
        <failed>2</failed>
      </rules>
      <duration unit="ms">10760</duration>
    </info>
    <messages>
      <error type="4" location="/*[local-name()='CrossIndustryDocument']/*[local-name()='SpecifiedSupplyChainTradeTransaction']/*[local-name()='IncludedSupplyChainTradeLineItem'][1]" criterion="count(ram:AssociatedDocumentLineDocument)=1">Element 'ram:AssociatedDocumentLineDocument' must occur exactly 1 times.</error>
      <error type="4" location="/*[local-name()='CrossIndustryDocument']/*[local-name()='SpecifiedSupplyChainTradeTransaction']/*[local-name()='IncludedSupplyChainTradeLineItem'][2]" criterion="count(ram:AssociatedDocumentLineDocument)=1">Element 'ram:AssociatedDocumentLineDocument' must occur exactly 1 times.</error>
    </messages>
    <summary status="invalid"/>
  </xml>
  <messages/>
  <summary status="invalid"/>
</validation>

this is my ZUGFeRD-xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rsm:CrossIndustryDocument xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:12" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:15" xmlns:rsm="urn:ferd:CrossIndustryDocument:invoice:1p0">
  <rsm:SpecifiedExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:ferd:CrossIndustryDocument:invoice:1p0:basic</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:SpecifiedExchangedDocumentContext>
  <rsm:HeaderExchangedDocument>
    <ram:ID>invoice-1</ram:ID>
    <ram:Name>Rechnung</ram:Name>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20200721</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:HeaderExchangedDocument>
  <rsm:SpecifiedSupplyChainTradeTransaction>
    <ram:ApplicableSupplyChainTradeAgreement>
      <ram:SellerTradeParty>
        <ram:Name>TestTrader</ram:Name>
        <ram:PostalTradeAddress>
          <ram:PostcodeCode>12345</ram:PostcodeCode>
          <ram:LineOne>TraderStreet</ram:LineOne>
          <ram:CityName>TraderCity</ram:CityName>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration>
          <ram:ID schemeID="FC">DE123456789</ram:ID>
        </ram:SpecifiedTaxRegistration>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:Name>TestCustomer</ram:Name>
        <ram:PostalTradeAddress>
          <ram:PostcodeCode>54321</ram:PostcodeCode>
          <ram:LineOne>CustomerStreet</ram:LineOne>
          <ram:CityName>CustomerCity</ram:CityName>
          <ram:CountryID>DE</ram:CountryID>
        </ram:PostalTradeAddress>
        <ram:SpecifiedTaxRegistration>
          <ram:ID schemeID="FC">DE987654321</ram:ID>
        </ram:SpecifiedTaxRegistration>
      </ram:BuyerTradeParty>
    </ram:ApplicableSupplyChainTradeAgreement>
    <ram:ApplicableSupplyChainTradeDelivery>
      <ram:ActualDeliverySupplyChainEvent>
        <ram:OccurrenceDateTime>
          <udt:DateTimeString format="102">20200804</udt:DateTimeString>
        </ram:OccurrenceDateTime>
      </ram:ActualDeliverySupplyChainEvent>
    </ram:ApplicableSupplyChainTradeDelivery>
    <ram:ApplicableSupplyChainTradeSettlement>
      <ram:PaymentReference>invoice-1</ram:PaymentReference>
      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
      <ram:SpecifiedTradeSettlementPaymentMeans>
        <ram:PayerPartyDebtorFinancialAccount>
          <ram:IBANID>DE01234..</ram:IBANID>
        </ram:PayerPartyDebtorFinancialAccount>
        <ram:PayerSpecifiedDebtorFinancialInstitution>
          <ram:BICID>GENO...</ram:BICID>
        </ram:PayerSpecifiedDebtorFinancialInstitution>
      </ram:SpecifiedTradeSettlementPaymentMeans>
      <ram:ApplicableTradeTax>
        <ram:CalculatedAmount currencyID="EUR">0.00</ram:CalculatedAmount>
        <ram:TypeCode>VAT</ram:TypeCode>
        <ram:BasisAmount currencyID="EUR">1200.00</ram:BasisAmount>
        <ram:ApplicablePercent>0.00</ram:ApplicablePercent>
      </ram:ApplicableTradeTax>
      <ram:ApplicableTradeTax>
        <ram:CalculatedAmount currencyID="EUR">41.61</ram:CalculatedAmount>
        <ram:TypeCode>VAT</ram:TypeCode>
        <ram:BasisAmount currencyID="EUR">219.00</ram:BasisAmount>
        <ram:ApplicablePercent>19.00</ram:ApplicablePercent>
      </ram:ApplicableTradeTax>
      <ram:SpecifiedTradeSettlementMonetarySummation>
        <ram:LineTotalAmount currencyID="EUR">1419.00</ram:LineTotalAmount>
        <ram:ChargeTotalAmount currencyID="EUR">0.00</ram:ChargeTotalAmount>
        <ram:AllowanceTotalAmount currencyID="EUR">0.00</ram:AllowanceTotalAmount>
        <ram:TaxBasisTotalAmount currencyID="EUR">1419.00</ram:TaxBasisTotalAmount>
        <ram:TaxTotalAmount currencyID="EUR">41.61</ram:TaxTotalAmount>
        <ram:GrandTotalAmount currencyID="EUR">1460.61</ram:GrandTotalAmount>
        <ram:TotalPrepaidAmount currencyID="EUR">0.00</ram:TotalPrepaidAmount>
        <ram:DuePayableAmount currencyID="EUR">1460.61</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementMonetarySummation>
    </ram:ApplicableSupplyChainTradeSettlement>
    <ram:IncludedSupplyChainTradeLineItem>
      <ram:SpecifiedSupplyChainTradeAgreement>
        <ram:NetPriceProductTradePrice>
          <ram:ChargeAmount currencyID="EUR">73.0000</ram:ChargeAmount>
        </ram:NetPriceProductTradePrice>
      </ram:SpecifiedSupplyChainTradeAgreement>
      <ram:SpecifiedSupplyChainTradeDelivery>
        <ram:BilledQuantity unitCode="C62">3.0000</ram:BilledQuantity>
      </ram:SpecifiedSupplyChainTradeDelivery>
      <ram:SpecifiedSupplyChainTradeSettlement>
        <ram:ApplicableTradeTax>
          <ram:TypeCode>VAT</ram:TypeCode>
          <ram:ApplicablePercent>19.00</ram:ApplicablePercent>
        </ram:ApplicableTradeTax>
        <ram:SpecifiedTradeSettlementMonetarySummation>
          <ram:LineTotalAmount currencyID="EUR">219.00</ram:LineTotalAmount>
          <ram:TotalAllowanceChargeAmount currencyID="EUR">0.00</ram:TotalAllowanceChargeAmount>
        </ram:SpecifiedTradeSettlementMonetarySummation>
      </ram:SpecifiedSupplyChainTradeSettlement>
      <ram:SpecifiedTradeProduct>
        <ram:Name>Artikel 1</ram:Name>
      </ram:SpecifiedTradeProduct>
    </ram:IncludedSupplyChainTradeLineItem>
    <ram:IncludedSupplyChainTradeLineItem>
      <ram:SpecifiedSupplyChainTradeAgreement>
        <ram:NetPriceProductTradePrice>
          <ram:ChargeAmount currencyID="EUR">1200.0000</ram:ChargeAmount>
        </ram:NetPriceProductTradePrice>
      </ram:SpecifiedSupplyChainTradeAgreement>
      <ram:SpecifiedSupplyChainTradeDelivery>
        <ram:BilledQuantity unitCode="C62">1.0000</ram:BilledQuantity>
      </ram:SpecifiedSupplyChainTradeDelivery>
      <ram:SpecifiedSupplyChainTradeSettlement>
        <ram:ApplicableTradeTax>
          <ram:TypeCode>VAT</ram:TypeCode>
          <ram:ApplicablePercent>0.00</ram:ApplicablePercent>
        </ram:ApplicableTradeTax>
        <ram:SpecifiedTradeSettlementMonetarySummation>
          <ram:LineTotalAmount currencyID="EUR">1200.00</ram:LineTotalAmount>
          <ram:TotalAllowanceChargeAmount currencyID="EUR">0.00</ram:TotalAllowanceChargeAmount>
        </ram:SpecifiedTradeSettlementMonetarySummation>
      </ram:SpecifiedSupplyChainTradeSettlement>
      <ram:SpecifiedTradeProduct>
        <ram:Name>Artikel 2</ram:Name>
      </ram:SpecifiedTradeProduct>
    </ram:IncludedSupplyChainTradeLineItem>
  </rsm:SpecifiedSupplyChainTradeTransaction>
</rsm:CrossIndustryDocument>

and this is my Code for invoice generation:

    /**
     * Creates Invoice based on Container data
     *
     * @param input data specified as InvoiceContainer
     * @return generated Invoice
     */
    private Invoice createInvoice(final InvoiceContainer input) {

        final Invoice invoice = new Invoice(BASIC);
        invoice.setHeader(new Header().setInvoiceNumber(input.getId()).setCode(_380).setIssued(new ZfDateDay(input.getInvoiceDate())).setName("Rechnung"));

        final EconomicUnit trader = input.getTrader();
        final EconomicUnit customer = input.getCustomer();

        final Trade trade = new Trade();
        trade.setAgreement(new Agreement()
                .setSeller(new TradeParty().setName(trader.getName())
                        .setAddress(new Address(String.valueOf(trader.getZipCode()), trader.getStreet(), trader.getCity(), DE))
                        .addTaxRegistrations(new TaxRegistration(trader.getUstId(), FC)))
                .setBuyer(new TradeParty().setName(customer.getName())
                        .setAddress(new Address(String.valueOf(customer.getZipCode()), customer.getStreet(), customer.getCity(), DE))
                        .addTaxRegistrations(new TaxRegistration(customer.getUstId(), FC))));

        trade.setDelivery(new Delivery(new ZfDateDay(input.getDueDate())));

        for (final Article article : input.getArticles()) {
            final ItemTax itemTax = new ItemTax();
            itemTax.setPercentage(BigDecimal.valueOf(article.getTax()));
            itemTax.setType(TaxCode.VAT);

            trade.addItem(new Item().setProduct(new Product().setName(article.getDescription()))
                    .setAgreement(new SpecifiedAgreement()
                            .setNetPrice(new Price(new Amount(article.getPrice(), EUR))))
                    .setSettlement(new SpecifiedSettlement().addTradeTax(itemTax))
                    .setDelivery(new SpecifiedDelivery(new Quantity(article.getQuantity(), UNIT))));
        }

        trade.setSettlement(new Settlement().setPaymentReference(input.getId()).setCurrency(EUR)
                .addPaymentMeans(new PaymentMeans().setPayerAccount(new DebtorFinancialAccount("DE01234.."))
                        .setPayerInstitution(new FinancialInstitution("GENO..."))));

        invoice.setTrade(trade);

        return new InvoiceCalculator(invoice).complete();
    }
Vad1mo commented 4 years ago

The validation is not correct, see spec page 101 and 108 https://konik.io/ZUGFeRD-Spezifikation/Das-ZUGFeRD-Format_1p0_technische_Dokumentation.pdf

AssociatedDocumentLineDocument should not exist in Basic Profile exactly the oposite to the error message. Even in Comfort and Extended AssociatedDocumentLineDocument is optional. image image image

REf: image