ZUGFeRD 2.2-2.4 import for Dynamics 365 for Finance

ZUGFeRD 2.2-2.4 import for Dynamics 365 for Finance

ZUGFeRD (Zentraler User Guide des Forums elektronische Rechnung Deutschland) is an e-invoicing format combining a human-readable PDF/A-3 and an embedded XML file using the CII (Cross-Industry Invoice) syntax. The CII syntax may also be used in the xRechnung, which is a pure XML version of the German e-Invoice. From 2025, the ability to receive and process electronic invoices becomes mandatory for B2B transactions in Germany.

Microsoft’s current solution in Dynamics 365 for Finance provides support specifically for the UBL (Universal Business Language) format of the xRechnung: Import vendor electronic invoices – Finance | Dynamics 365 | Microsoft Learn. It enables the import of vendor invoices received in this format, mapping them as pending vendor invoices in D365. The invoice may be uploaded directly into the system or placed in a SharePoint folder for unattended processing.

We are happy to announce the release of the CII (Cross-Industry Invoice) dialect of the xRechnung / ZUGFeRD electronic invoice. This solution is implemented via Electronic Reporting (ER) configurations, which means it does not require any customisations and can be easily installed across all active versions of D365. It sits on top of the standard Invoice model v280, Vendor Invoice Mapping to Destination v280.46, side by side with the configuration Vendor Invoice Import v280.7 v280.9 (state: Jan. 2025).

The functionality aligns with the standard Microsoft UBL import, utilizing the key data elements for processing and ensuring PO matching:

  • Header: Invoice ID, Invoice date, Due date, Vendor ID, Currency code, PO number, a header-level note and header attachments (in XML embedded MIME documents).
  • Lines: Line number, Item ID, Quantity, Sales unit of measure, Sales price, Discount (percentage discounts are converted to absolute values as the XML schema doesn’t support percentages), Price unit, Name, Description, and Line amount (excluding VAT).

The solution supports the ZUGFeRD 2.1, ZUGFeRD 2.2, 2.3.x or ZUGFeRD 2.4 / Factur-X 1.0x with the profile EN16931 (also known as the “COMFORT” profile), XRECHNUNG profile or the EXTENDED profile. All three meet the tax law requirements and must be accepted by e-invoice recipients.

In contrary, ZUGFeRD 1.0 (easily recognised by the <rsm:CrossIndustryDocument> root node instead of the proper <rsm:CrossIndustryInvoice>) is no longer permitted in Germany when it comes to complying with the current legal requirements for electronic invoices, and therefore not supported. The same applies to the BASIC and BASIC WL profiles of the ZUGFeRD 2.x, announced by the <ram:GuidelineSpecifiedDocumentContextParameter> tag in the header.

Price

The solution is offered at a fixed fee per end customer / D365 tenant:
VersionPriceDeliverablesNotes
Light€890The Vendor invoice import CII Electronic Reporting configurationThis option does not require any X++ customisations or 3rd party software and can be installed and used right away.
Light+€1200Same as the Light version but with 5 hours of prepaid support and installation 

You can acquire the solution on the official Microsoft AppSource marketplace: ZUGFeRD CII import (microsoft.com)

 

Setup and use

 
    1. Follow the steps outlined in the Microsoft’s guidance Import vendor electronic invoices – Finance | Dynamics 365 | Microsoft Learn:
    2. Import the same three configurations from Microsoft (Prerequisites);
    3. Import the configuration Vendor invoice import CII.xml provided to you (menu Organisation administration > Electronic reporting > Configurations, button Exchange / Load from XML file);
    4. Open Accounts payable > Setup > Accounts payable parameters; on the Electronic documents tab, select the imported Vendor invoice import CII format.
    5. To run either one of the formats – UBL or CII – by choice, you may download and import a complimentary X++ extension with an additional parameter CII vendor invoice and an own menu item AP > Periodic tasks > Import vendor invoices CII underneath the standard one: VendImportInvoice_CII.axpp. In the batch execution mode this does not matter, because each of the formats becomes its own Electronic source with a set of SharePoint folders etc.
    6. Prepare the master data: make sure the vendors are stored with proper VAT numbers in Dynamics 365 for Finance. They must have the proper country prefix “DE” and may not contain any spaces or special characters.
    7. Make sure that the vendor’s external item ID mapping exists. Any Buyer Assigned ID (our item number) potentially sent by the vendor is neglected by the Microsoft’s mapping, and the conversion to the internal Item ID is always handled via the external item IDs. Under these conditions, the import works as expected and the PO lines may be matched.
    8. Make sure that the units of measure are properly mapped to the UNECE Recommendation No. 20 list called “Codes for Units of Measure Used in International Trade”. For instance, the UNECE unit H87 should be mapped to PCS or STK, while C62 may become EA in our system; see also a longer list in https://erconsult.eu/de/blog/aktueller-stand-der-erechnung-in-d365-for-finance-deutschland/. You may need to introduce new units of measure, because the External codes table (ExtCodeValueTable in particular) assumes the 1:1 relation between the system units in D365 and the external unit codes.
    9. Perform an interactive test upload by using the function Accounts payable > Periodic tasks > Import vendor invoices (or Import vendor invoices CII if you installed and configured the above extension from step 5). Beware: contrary to the UBL format, the CII (“COMFORT”) invoice does not include any line-by-line reference to the purchase order lines. Just the PO number is sent in the header. We assume that the numeration of the invoice lines mostly follows the PO lines numeration. If not, the standard mapping will fall back to the matching by the line purchase price.
    10. Configure the batch mode with Electronic reporting sources i.e. SharePoint folders as outlined in the above Microsoft’s guidance: Import vendor electronic invoices – Configure the sources to import files in batch mode.
    11. The standard UBL import from Microsoft and our CII import may be “daisy-chained”: set the error folder (Electronic reporting sources -> Settings / Document type for failed files) of the CII import the same as the input folder (Settings / Document type for input sources) for the UBL. If the XML starts with the <rsm:CrossIndustryInvoice> tag and features the <rsm:>, <ram:> namespaces, then it is a ZUGFeRD and it will be processed regularly by the CII import. If the XML starts with the <ubl:Invoice> or <ubl:CreditNote> tag and features <cbc:>, <cac:> namespaces, the CII parsing is going to fail early, and the XML file will be passed to the UBL parser, which takes it from there.

Cardinality of the external item number

In Dynamics 365 Supply Chain Management, the relationship between an external item number and an internal item ID is strictly 1:1. Each external ID points to exactly one internal product. This can cause issues when using Microsoft’s Vendor invoice mapping to destination, especially if Procurement categories were converted into service items during the vendor invoice import implementation. For example, spare parts that were once all booked under the procurement category “Maintenance and repair” now require separate released products, and every type of stationery once grouped under “Office supplies” must be split into multiple products. With mapping based on vendor external item numbers, this means creating a separate released product record for every sheet of paper or pen type.

To reduce this complexity, we recommend a small extension to the CustVendExternalItem table. Vendor invoice mapping to destination relies on the method CustVendExternalItem.getItemIdForInvoiceAccount_BR() , which could theoretically return the same internal item ID for different external IDs. However, the table’s unique index blocks multiple external numbers from being linked to the same product and vendor. Fortunately, Microsoft provided an extension point fieldIdsToHash() that allows you to add new fields into the uniqueness constraint, compressed into a hash. The code below extends this index with the Description field, so multiple vendor external item numbers can point to the same internal product.

				
					/// <summary>
/// Allow for internal ItemId 1 : N ExternalItemId
/// </summary>
[ExtensionOf(tableStr(CustVendExternalItem))]
final public class CustVendExternalItem_CII_Extension
{
    /// <summary>
    /// Add the Description to the list of fields that define the uniqueness of a record
    /// </summary>
    /// <returns>The set of field Ids.</returns>
    protected Set fieldIdsToHash()
    {
        Set hashFields = next fieldIdsToHash();

        if (this.ModuleType != ModuleInventPurchSalesVendCustGroup::Vend && 
            this.ModuleType != ModuleInventPurchSalesVendCustGroup::VendGroup)
        {
            return hashFields;
        }
        if (! this.Description)
        {
            return hashFields;
        }

        PurchParameters purchParameters = PurchParameters::find();
        if (purchParameters.ERModelMappingVendInvoice != 0 ||
            purchParameters.ERModelMappingVendInvoiceCII != 0)
        {
            hashFields.add(fieldNum(CustVendExternalItem, Description));
        }
        return hashFields;
    }

}
				
			

Use this code carefully: if you already rely on the Description field for other purposes, conflicts may arise. Records with an empty description will still behave as in the standard system and act as a fallback when matching external vendor numbers.

Procurement categories matching

Recently we successfully extended the Microsoft’s existing Vendor invoice Mapping to destination (v280.46) to enable supplier invoice matching with purchase orders lines with procurement categories. We added two targeted calculated fields to match purchase order lines by line number or net line price, and incorporated them as additional fallbacks in the PO-line matching logic. We then bound the procurement category and adjusted the ItemId logic to avoid conflicts when category lines are used.

In addition, a purchase order may contain a mix of positive and negative lines to uptake a credit note or a corrective invoice. The standard matching logic ignores the sign of the quantity in the eInvoice. We’ve hardened the logic to only look for PO lines with the same quantity sign as in the invoice line.

Both UBL and CII users benefit from this improvement. You may download it here: Vendor invoice Mapping to destination (ERC) 280.46.2; contact us for more details.

Useful links

Austrian Peppol-UBL e-invoice

E-Invoice in D365
E-Invoice in D365

Austrian Peppol-UBL e-invoice

…in its version 304.13.25 does not work out of the box in Dynamics 365 for Finance, unfortunately. First and foremost, the public entity’s order number (the Customer requisition at the sales header order or in the project contract funding source details) is a must! As you specify the Customer requisition, a reference to the PO line number reference becomes mandatory, too. Yet this invoice line-level field is either malformed or missing. Moreover, Austria always requires an email address of the supplier (us) which is disabled or not working in all 4 standard ER formats. This can be the default e-mail address of the company in the legal entity settings.

As a good start, I recommend the excellent blog series E-Invoice in D365FO for Norway – Part 1 (Intro) – DynFOTech

The core configuration includes specifying the Endpoint ID of the supplier (ours) under Bank account / Routing number in the legal entity parameters, and providing the conversion of the units of measure into the UN standard, see the blog above.  For every unit of measure there must be an own Code ‘axis’ to compensate for the well known design flaw in the external code values cardinality in Dynamics 365 for SCM:

Then, to finally make it work, you have to extend all 4 standard electronic formats from Microsoft and make at least the following changes:

Format changes

Issue/Deficiency Path Peppol Sales invoice Peppol Project Invoice Peppol Sales Credit Note Peppol Project Credit Note
Mandatory Seller/ElectronicMail cac:AccountingSupplierParty/cac:Party/cbc:ElectronicMail must be enabled all the way down, and mapped like this: IF(Invoice.InvoiceBase.CompanyContact.ElectronicMail<>"", Invoice.InvoiceBase.CompanyContact.ElectronicMail, Invoice.InvoiceBase.CompanyInfo.Email) IF(ProjectInvoice.InvoiceBase.Contact.ElectronicMail<>"", ProjectInvoice.InvoiceBase.Contact.ElectronicMail, ProjectInvoice.InvoiceBase.CompanyInfo.Email) IF(Invoice.InvoiceBase.CompanyContact.ElectronicMail<>"", Invoice.InvoiceBase.CompanyContact.ElectronicMail, Invoice.InvoiceBase .CompanyInfo.Email) IF(ProjectInvoice.InvoiceBase.Contact.ElectronicMail<>"", ProjectInvoice.InvoiceBase.Contact.ElectronicMail, ProjectInvoice.InvoiceBase.CompanyInfo.EMail)
Wrong OrderLineRef.ID, namely taken from ProjTransId = alphanumeric instead of numeric Every of the five cac:InvoiceLine/cac:OrderLineReference/cbc:LineID must be unique and therefore enumerated. In the the Project Credit note the tags are missing completely and need to be added from scratch (5x) ('$ATLineNumberCollection'.Collect(1) + '$ATLineNumberCollection'.Sum(false))-1 ('$ATLineNumberCollection'.Collect(1) + '$ATLineNumberCollection'.Sum(false))-1
Missing PaymentMeans, i.e. our (beneficiary) bank account cac:PaymentMeans/cac:PayeeFinancialAccount/cbc:ID, schemeID and .../cac:FinancialInstitutionBranch/cbc:ID must be enabled all the way down and mapped ProjectInvoice.InvoiceBase.CompanyInfo.BankAccount.IBAN ProjectInvoice.InvoiceBase.CompanyInfo.BankAccount.SWIFT
Missing OrderReference (their PO number) cac:OrderReference/cbc:ID must be enabled Invoice.PurchaseOrder
Missing or wrongly formatted line quantity; the sign is properly displayed in Denmark only 🙂 cac:CreditNoteLine/cbc:CreditedQuantity must be enabled IF(OR(Invoice.InvoiceBase.CompanyInfo.PostalAddress.Country="DK", Invoice.InvoiceBase.CompanyInfo.PostalAddress.Country="AT"), -(@.LineBase.Quantity), @.LineBase.Quantity) -(@.LineBase.Quantity)
The ActualDeliveryDate ("Leistungsdatum") refers to the date or the corrected invoice. The data is not really known and not properly mapped, here is a stub: cac:Delivery/cbc:ActualDeliveryDate is completely missing and needs to be added first Invoice.InvoiceBase. ShipmentDate ProjectInvoice. InvoiceBase.VATRegisterDate
The root node bears no name, hence the format cannot be assigned a destination Call the root node "XMLHeader", for example X X

With regards to the collection $ATLineNumberCollection for the enumeration of invoice lines, refer to respective blog below.

Useful links

 

How NOT to send an order confirmation per e-mail

How NOT to send an order confirmation per e-mail

When utilizing configurable business documents (Electronic Reporting) in Dynamics 365, additional steps are required to dispatch various documents such as invoices, delivery notes (referred to as packing slips in the US), sales order confirmations to customers, or purchase order requests to suppliers. Begin as usual with Accounts receivable > Setup > Forms > Form setup, Print management. Select the appropriate Electronic Reporting (ER) configuration as a Report format.

It’s important to note that the conventional flexible print destinations outlined in Set up print management for a module | Microsoft Learn are not applicable for ER reports. Instead, navigate to Organisation Administration > Electronic Reporting > Electronic reporting destination. Here, for each ER configurable business document, create a dedicated line where you can specify Email as the destination under the Settings.

Programmable e-mail recipients

Here’s where it gets interesting: for each From, To, Cc address, clicking Edit provides you with the flexibility to choose between the traditional hard-coded method of extracting business party account details (+Add, Print Management email) or the Configuration email, featuring a low-code ER formula. When opting for the latter choice, Electronic Reporting grants access to the corresponding ER model.

The From formula can be a simple hardcoded text with the unattended e-mail address: "noreply@erconsult.eu".  The mails will be sent via SMTP on its behalf, thus it must be a true Exchange 365 account.

The To = @Business@ field is employed to choose one among several electronic contact addresses (emails) of the party based on the electronic address Purpose. This configuration remains consistent with the classic Print Management setup.

For the Email source account for the To e-mail address, consider the following examples:

Configurable Business Document Party ER Formula to extract the account number
Sales order confirmation Customer model.SalesConfirm.BuyerCustomerParty.Party.PartyIdentification.AccountNumber
Sales order packing slip Customer Missing in the mapping; modify model.BuyerCustomerParty
Sales invoice Customer model.InvoiceBase.InvoiceAccount.AccountNum
Free text invoice Customer model.Customer.AccountNum
Collection letter note Customer model.AccountingCustomerParty.AccountNum
Purchase order Supplier model.PurchaseOrderInquiry.SellerSupplierParty.Party.Reference

The subject of the email can either be set as a fixed value, such as “Lieferschein / Delivery note” or dynamically constructed from components of the document model. This dynamic approach is particularly useful for the Body of the email. The FORMAT function with placeholders does not work. Instead, HTML tags must be concatenated sequentially. Thank you Ludwig Reinhard for this hint. Here is a sample:

"Dear Ladies and Gentlemen,"&"<br>"&"Attached you may find invoice "&model.InvoiceBase.Id&” for your order"&model.InvoiceBase.SalesId&".”&"<br>"&"Best regards, XXX"

Reprint documents safely

In the described setup, Dynamics 365 will automatically dispatch your configurable business documents to your business partners via email every time, even if you attempt to reprint or review the invoice, order confirmation, etc. The customers and suppliers will go nuts. Fortunately, a solution has been introduced since 2021: a feature known as Configure action-dependent ER destinations – Finance & Operations | Dynamics 365 | Microsoft Learn. This feature responds to the button clicked by the user—whether it’s ‘Copy,’ ‘Original,’ or ‘Use Print Management‘—and redirects the document to a different destination, providing a more controlled document distribution process.

With the configuration shown below, reprinted copies of an invoice are directed exclusively to the screen. The ‘View‘ option corresponds here to the buttons Copy preview and Original preview. The ‘Print‘ action is initiated during every post-and-print action when the configurable document is initially generated. Additionally, the ‘Print‘ action is triggered when the user deliberately selects Use print management for reprinting.

Do not send pro-forma documents to your business partners

The electronic reporting destinations unfold their devious nature when the people first preview a document before sending. Dynamics 365 is going to send the document via email regardless of whether the user opts to Use print management or not, proforma or not a proforma.  Namely, both generating a pro-forma sales order confirmation and posting a final sales order confirmation are considered Print actions. This aspect bears potential legal consequences.

The recent feature, “Allow ER destinations adjustment at runtime (Phase 2)“, introduced in version 10.0.36, may offer assistance. However, I consider it intrusive and unsafe as it opens an additional dialog window placing the decision-making in the hands of the user: humans make mistakes.

We’ve identified a somewhat unconventional but more straightforward solution by manipulating and corrupting the Email source account mentioned earlier. Consider the following example:

IF(LEN(model.InvoiceBase.Id)>0, model.InvoiceBase.InvoiceAccount.AccountNum, "FUBAR")

If the invoice number is empty, the system returns a fabricated account number; otherwise, it returns the legitimate account number.

When attempting to send a copy of a pro-forma invoice to the customer’s email address, an exception will be raised, stating, “The email address in the To field is not valid.” The Screen destination will still succeed despite this exception.