Sometimes you pay Reverse Charge in D365

Sometimes you pay Reverse Charge in D365

Under the “reverse charge system” it is the company receiving the service that is liable to pay the VAT, and not the company providing the service. Normally, the net amount of VAT to pay is offset by the same amount of the receivable VAT, and the tax burden remains 0. But not always: sometimes the tax office wins. These are 2 cases I’ve got this year:

    • A service was provided by an EU entrepreneur who had no EU VAT number. The invoice was VAT excluded, but I had to calculate the VAT payable (reporting code 1157 „Steuerschuldübergang bei Bezug gemäß § 19 Abs. 1 zweiter Satz, § 19 Abs. 1c“ in Austria, code 47 „Steuer, im Inland steuerpflichtige sonstige Leistung eines EU Unternehmers § 13b Abs. 1 UStG“ in Germany), while the VAT receivable was nil (otherwise reported as 1166 „Vorsteuer: Steuerschuldübergang gemäß §19, grenzüberschreitende Leistungen“ in Austria or code 67 „Vorsteuer aus Umsätzen nach §13b Abs. 2 Nr. 11“ in Germany).
    • There are more and more citizens who sell excess solar power to the grid, thanks to the overall trend, public incentives and the war. This falls under an obscure, but less and less exotic Reverse Charge regime for producers/resellers of electricity (reporting code 1132 “Steuerschuldübergang bei Bezug gemäß § 19 Abs. 1d: Gas und Elektrizität“ in Austria). If they resell, they have a deductible VAT to offset. But if they produce, they have to pay on top of the Credit note granted to them by an energy company or the authority.

Solution in Dynamics 365 for Finance

The 2 business cases have the same process in common:
– One becomes an invoice (or a credit note) from a supplier (vendor) over €100
– One pays (or receives) €100 to the supplier
– One pays €20 (€19) to the tax office
 
To implement this in Dynamics 365 for Finance, we activate the Use tax in the VAT group (en-us: Sales tax group) as usual (see Minimalistic EU VAT configuration in D365):

On top of that, the special VAT code (here: ServEUnond) for the non-deductible Reverse Charge receives Non deductible % = 100% in the tax code value:
 
The use tax VAT from the supplier invoice calculated in this way “elongates” the original expense, the GL voucher reflects the fact that the service effectively becomes more expensive by 19% (in DE):
This may be considered right or wrong, but a different expense account such as 7xxx “VAT, non-deductible” is not possible in standard Dynamics 365. If needed, this tax expense may be reallocated to a different account manually at the end of the period.
 
The monthly/quarterly Tax > Declaration > VAT > Settle and post VAT operation does not find any VAT receivable to offset the VAT payable and transfers the liability into the Tax authority’s payable account:
Bingo!

Enumerate lines in Configurable Business Documents

Enumerate lines in Configurable Business Documents

The delivery note, invoice etc. Report Data Providers in Dynamics 365 for Finance do not expose line numbers for no obvious reason. For instance, the SalesInvoiceTmp  table sent from D365 to the report renderer – whatever it is – misses the line number. The situation becomes dire when it comes to Electronic Reporting / Configurable Business Documents.

The ENUMERATE(Lines) function applied to the lines makes a totally new object {Number, Value} and every binding “@” becomes “@.Value“. This is a massive change in the report, very hard to maintain and upgrade (rebase).

In XML or CSV outbound formats there is a Counter element, it auto-counts itself. In Excel and Word outbound formats there are just RangesCells. I thought we worked with lists as isolated objects and there were no internal variables in Electronic Reporting which were aware of the execution history.

But today I finally understood what the DATA COLLECTION does. It is a listener, you pass a value to it, it returns it back unchanged but keeps a global variable to count and summarise the values.

For example, to enumerate delivery note (en-us: packing slip) lines, first create a root Data collection class of the integer type in the Mapping to the right, Collect all values = Yes, let’s call it a LineNumberCollection.

Then put the following formula into the Excel Cell with the line number:
LineNumberCollection.Collect(1)+LineNumberCollection.Sum(false)-1 

The first LineNumberCollection.Collect() call takes 1, records 1 internally, and returns the 1 back into the cell. The second call LineNumberCollection.Sum(false) adds the running total of 1’es recorded so far. The last operand subtracts 1.

Here is the result: Bingo!

Batch jobs in D365: a Russian roulette

Batch jobs in D365: a Russian roulette

Real world production scenarios include automated batch tasks executed in the background with some cadence: Batch processing overview – Finance & Operations. They apply to sets of documents fetched at the run time, for example to sales orders delivered, but not invoiced yet. Obviously, every day the query with the documents should return a different set with the recently despatched sales orders. It is called Late selection: Late selection in D365FO – D365Tour. So far so known.

As the complexity of the business grows, so does the complexity of the batch jobs. You’ll need jobs consisting of multiple tasks, executed one after another. It is called task dependency, or task Constraints. One of the latest unpleasant discoveries was the fact, that you cannot always rely on the sequence of steps set in the batch job: the most useful tasks, such as the SalesFormLetter_Invoice and its likes (used to update sales and purchase orders with order confirmations, delivery notes and invoices) act as orchestrators and spin off child batch tasks for simultaneous, multi-threaded sales order, purchase order, production order processing. These child tasks are not constrained (!) and get executed at a first come, first served basis. They may still run while the master task SalesFormLetter_Invoice seemingly ends and relays the baton to the next task. This leads to interference and racing conditions. You better evaluate the average execution time of the master controller task as a whole, put these controllers into different batch jobs, schedule them at a safe time distance from one another.

Heterogenous batch jobs as the one shown below pose a different challenge.

Here is the how-to instruction:

  1. Spin off the first task from the main menu (here: Production control > Periodic tasks > Production order status update) and choose Run in the background / Batch processing. This will be your starting point, a template for the batch job.
  2. Locate the batch job in the My batch jobs list, set the status to Withheld and start editing.
  3. Every task within a batch job needs a Class name. Now you know the class name of the first task: ProdMultiCostEstimation. To add the next task, you have to manually specify its Class name. The owners of this framework provided a lookup list, but it is slow and completely dysfunctional: it shows just a fraction of the possible executable RunBase or SysOperation classes, sometimes it crashes if there are some bad customizations in the source code. If you don’t know the class name, repeat the step 1 to reveal it.
  4. Add the next task, type the class name in. The first time it will take the system up to 20-30 seconds to accept and retrieve the Class description.
  5. Most batch tasks need a query. Click Parameters to populate it. Here you experience another nasty trait of the batch framework: the query shown is the last one you used in the system elsewhere. It is not necessarily the one really persisting at the batch task. Another user is not going to see your query criteria at all: only the owner/creator has the control. *1) *2) *3)
  6. On the Batch task details tab, Constraints, choose the predecessor task to build a chain. You many need to change the Expected status to Ended or error if the batch job has to continue with the next task on an error somewhere in the chain.
  7. Check the recurrence, remove the Alerts if needed, and put the Batch job back to Waiting.

1) Lessons learned: take a screenshot of every query and parameter, document it thoroughly to pass the maintenance to the Dynamics system administrator.

2) In certain cases a manually added task does not let edit the execution parameters and/or the query. Sometimes(e.g. on sales order updates) it helps to execute the same periodic task in the normal user session once. This is the reason why it is often hard to pre-configure the batch jobs in a “Golden Config” environment: it may need real transactions to execute against. Sometimes it wishes to be initialised from the main menu and nowhere else because badly programmed. In such a case, start your step 1 – the key task – from this critical periodic task. Should there be 2 such bitchy tasks in one batch job chain, it is over. They must be separated into different batch jobs.  

3) As a really bad surprize came the fact that even the owner has no control over the query: if you use the Late selection, in a chain of nearly identical tasks as the ones below, the QUERY OF THE LAST TASK IS APPLIED TO EVERY TASK of the kind, at least in the case of the production order status updates.

You should let the bloody job run one first time, then put the batch job back on hold and adjust the queries in the tasks once more, then save and re-activate the batch job.