Italian eInvoicing FatturaPA: Part 2

Italian eInvoicing FatturaPA: Part 2

You thought this was over? Not at all, the implementation of the FatturaPA format in D365FO harbors many pearls : )

DatiBollo, ImportoBollo

The “Bollo” or the Import duty seems to be a self-assessed Italian charge on certain deliveries. The user should be able to apply stamp duties to a subset of outbound invoices at will. The total stamp duty load is deducted by the Italian authorities periodically by harvesting the electronic invoices. In case the stamp duty is applicable, the tag should say “si” and should give the [positive] amount: 2.00.

Sales charge setupThe standard D365FO electronic format assumes the stamp duty is represented by a miscellaneous charge to the sales order. These charges trigger the XML element; otherwise the miscellaneous charge is exported as a regular invoice line.
The respective charge code can be configured with a transit debit and a transit credit account and added to any sales line manually or automatically as a auto-charge:

Electronic parametersThe system relies on the Spanish parameter Stamp duty to identify the dedicated miscellaneous charges code representing this duty. Unfortunately, this Spanish parameter is unavailable in Italy by definition, check the button Electronic document properties in the legal entities form:

Moreover, in the mapping between the database and the format the charges code was missing, and the duty only took sales order header level charges into accounts. A custom mapping needs to be derived from the Customer invoice model – Model mapping Customer invoice to fix this. This mapping must be declared Default for model mapping = Yes.
In the format the parametrized query $StampDutyCharges can be extended by a hardcoded check if the charge code begins with “Bollo”, then both the header-level and line-level charges can be merged into a single list:
IF(ISEMPTY('Stamp duty'),
LISTJOIN(WHERE(@.InvoiceBase.MarkupTransaction,
LEFT(@.InvoiceBase.MarkupTransaction.Code,5)="Bollo"),
WHERE(@.LineItem.MarkupTransaction,
LEFT(@.LineItem.MarkupTransaction.Code,5)="Bollo")),

WHERE(@.InvoiceBase.MarkupTransaction,
@.InvoiceBase.MarkupTransaction.Code='Stamp duty'.Value))

RiferimentoNormativo

The RiferimentoNormativo delivers the legal justification for tax exempt invoices and refers to the Italian tax codex, e.g. <RiferimentoNormativo. This tag was completely missing in the standard format. The tax code description is a good place to store the justification, the Customer invoice model has a node to store this data, but in the standard mapping the tax code description was not bound to the model. The derived mapping needs to be adjusted at the node CustInvoiceJour/<Relations/TaxTrans :
@.'>Relations'.TaxTable.TaxName

A new conditional XML element shall be added to the format configuration:
XMLHeader/p:FatturaElettronica/FatturaElettronicaBody/DatiBeniServizi/DatiRiepilogo/RiferimentoNormativo:
@.lines.TaxDescription

The Enabled-condition for the tag shall trigger the XML element only if the delivery is tax exempt, and this correlates with the “Natura” tag:
@.lines.'$IsVisibleNatura'

Credit notes in FatturaPA and ESTEROMETRO

The worst comes at the end. It turned out that credit notes ( = TD04) must have the positive sign throughout the XML file. This requires massive changes in the DettaglioLinee section
ABS(@.LineBase.Quantity)
ABS(IF(@.LineBase.Quantity<0, -(1)*@.LineBase.'$FinalUnitPrice', @.LineBase.'$FinalUnitPrice'))
DatiRiepilogo
ABS(@.aggregated.Amount_Sum)
and DatiPagamento sections:
ABS(@.DueAmount)
Similar amendments but just at one place should be made in the ESTEROMETRO (which is a kind of an EU Sales list report for Italy) electronic formats, such as the “Report customer invoices IT” and “Report vendor invoices IT”.

Refresh master data cache in D365FO

Refresh master data cache in D365FO

Having imported deeply cached master data into the D365FO Production environment (such as ‘entire table’-cached project groups, absence groups etc.), you may find the target form seemingly empty. An attempt to create the records manually with the same IDs fails with a “Record already exists…” error message. I.e. the data has been imported by the Data management framework, successfully loaded into the Azure SQL Database but not visible to this application server instance.

Solution: execute the below command in the browser, then reload the form:
https://xxxprod.operations.dynamics.com/?mi=SysClassRunner&cls=SysFlushData

This launches the SysFlushData class known from previous AX versions with the help of the SysClassRunner shell and force refreshes the cache.

Electronic reporting: Italian eInvoicing FatturaPA, CIG and CUP numbers, RIBA

Electronic reporting: Italian eInvoicing FatturaPA, CIG and CUP numbers, RIBA

Introduction

The use of eInvoices in public procurement in Italy is mandatory for ministries, tax agencies and national security agencies since June 2014. Since 31 March 2015, it is mandatory for all public entities. We also see private companies embarking this platform. Every supplier must comply and provide invoices in the “FatturaPA” format which is perfectly described in English (!) here.

In Dynamics 365 for Finance and Operations, the [public] client must have the parameter eInvoice set to Yes to activate electronic invoicing. If the eInvoice attachment has been activated as well, D365FO even embeds a copy of the invoice into the XML stream (as a PDF encoded by Base64 algorithm and stored in a CDATA block).

The eInvoices are driven by the Electronic Reporting. As I am writing this, the most recent version is the format “Sales invoice (IT)” v 29.34, based on the “Customer invoice model” and mapping v 29 from the 15th of January 2019.

In essence, you download the above 2 configurations, deploy them at Organization administration > Electronic reporting > Configurations, put an anchor on the Electronic documents tab at Accounts receivable > Setup > Accounts receivable parameters.
With this setup on hand, you post your sales or project invoice and it creates a record in the Accounts receivable > Invoices > E-Invoices > Electronic invoices list. These records are then processed manually or in a batch and the ER generates and drops XML files.

The problem is, the output is full of bugs.

DatiOrdineAcquisto, CodiceCIG, CodiceCUP, RiferimentoNumeroLinea

To crack down on mafia, the government issues CUP and CIG codes to identify contracts or assignments with public investments. They are tracked end-to-end from the invoice down to the payment (e.g. RIBA bills of exchange, see below). In Dynamics 365, these numbers need to be entered into the Base document part in the sales order header. As you post the sales invoice, it creates a persisting copy of the BaseDocument_IT record and attaches it to the invoice record CustInvoiceJour. The ER picks it up and the Base document type triggers one of the 5 sections <DatiOrdineAcquisto>, <DatiContratto>, <DatiFattureCollegate> and so on. So much for theory.

The code in \Data Dictionary\Tables\BaseDocument_IT\Methods\updateRefRecords is wrong in so many ways. It is going to fail creating a record for 2 invoices for the same order, 2 orders for the same public tender. The ER cannot find the record BaseDocument_IT, and the section <DatiOrdineAcquisto> is then missing in the output.

To mitigate this, you must create a mapping derived from Customer invoice model, declare it Default for model mapping and put a fallback into the InvoiceBase/BaseDocument_IT node:
IF(NOT(ISEMPTY(CustInvoiceJour.'<Relations'.BaseDocument_IT)),
CustInvoiceJour.'<Relations'.BaseDocument_IT,
CustInvoiceJour.'salesTable()'.'<Relations'.BaseDocument_IT)

Furthermore, the user may fail to provide the Line number in the Base document group. As a result, the <RiferimentoNumeroLinea> XML element is going to be missing in the output. The FatturaPA documentation told this element was not mandatory but in practice it is.

You need to derive a custom format from “Sales invoice (IT)” and improve it by substituting an empty line number (if not entered by the user) with “1” as long as any of the Base document types in the SO header has been selected. The below change needs to be replicated 5 times for the 5 respective types of the public sector Base documents.
For example, the node XMLHeader/p:FatturaElettronica/FatturaElettronicaBody/DatiGenerali/DatiOrdineAcquisto/RiferimentoNumeroLinea can be bound to
IF(@.LineNumber>0, @.LineNumber, 1)

RIBA CIG and CUP codes in the record 50

The Ri.Ba. is an electronic format for exchange bills remittances common in Italy. It is well described by bella Mrs. Santoro: Italian Ri.Ba. (Bill of Exchange) setup and process. This guidance was for AX2009, but the process remained the same and is valid in all points with the exception of the data export engine.
The current version of the ER configuration is “RIBA collection remittance (IT)” v 25.27 based on the “Payment model” 25 with the mapping “Payment model mapping 1611” v 25.27.

In the record 50 of the remittance it should provide the CIG and CUP codes in a long string. With the BaseDocument_IT record missing, this is going to fail. The workaround is similar: in a custom derived model at 2 places with
@.'$CustInvoiceJour'.'<Relations'.BaseDocument_IT.xxx

you need to put
IF(NOT(ISEMPTY(@.'$CustInvoiceJour'.'<Relations'.BaseDocument_IT)),
@.'$CustInvoiceJour'.'<Relations'.BaseDocument_IT.TenderCode,
@.'$CustInvoiceJour'.'salesTable()'.'<Relations'.BaseDocument_IT.TenderCode)

CodiceFiscale and IdCodice

The own VAT Code (e.g. IT00XXXXXXXXX) may differ from the Fiscal code (e.g. 00YYYYYYYYY) which is entered in a separate field CoRegNum in the company information. The eInvoice format in D365FO takes wrongly the Fiscal Code for the VAT Code value. You need to derive a custom format from Sales invoice (IT), and replace the binding for the <IdCodice> element and its “Enabled” (“?”) condition with
Invoice.InvoiceBase.CompanyInfo.VATNumber
Similarly, the EU VAT number of the customer may not match the fiscal code; moreover, the standard ER configuration erroneously takes the data from the Order customer in the sales order and not the Invoice customer account.
First and foremost, in the mapping the FiscalCode of the customer is not bound to the table. Fix this, then replace the binding in the derived format at 3 places and 3 conditions like this:
Invoice.InvoiceCustomerAccount.FiscalCode

Continued: Italian eInvoicing FatturaPA: Part 2