Filling PDF Forms with Electronic Reporting in Dynamics 365 for Finance

Filling PDF Forms with Electronic Reporting in Dynamics 365 for Finance

Dynamics 365 Electronic Reporting (ER) supports output into Excel, Word, and PDF formats. Excel and Word templates are well-covered in documentation and practice, but PDFs remain obscure – there’s only a short article Design ER configurations to fill in PDF templates – Finance & Operations | Dynamics 365 | Microsoft Learn from Microsoft.

The PDF/File component in ER is usable, it fills out static PDF forms. For example, one may take the VAT return or another tax declaration form, import into the ER configuration designer and get it filled out.

Technically, this resembles the old Dynamics Axapta approach using XFDF to inject data into form fields. That still seems to happen under the hood: you map values to fields, and the form gets filled in and flattened into a non-editable PDF. However, PDFs don’t support repeatable ranges like Excel – everything is fixed on the page. If there are – let’s say – several lines, then the subtotals below won’t slide on the PDF page. They’ll remain on the same page as placed on the PDF form, and remain on the exact place on the form.

To simulate Excel-like ranges, Microsoft introduced a naming trick. You create form fields named, e.g., LineNo1, LineNo2, …, LineNo10. In ER, you create a Field group containing a single LineNo field. ER fills LineNo1 with the first record, LineNo2 with the second, and so on. If only two records are present, only LineNo1 and LineNo2 get filled—the rest stay blank. You must not exceed the number of fields available in the form: 11 records will crash the report.

  1. To prepare such a form, you need Adobe Acrobat (not the free Reader). Create a fillable form and assign field names. For repeated fields like headers or footers (e.g. Total_pages), it’s okay to copy-paste – Acrobat auto-numbers them visually (Total_pages#1, #2) but they’re still internally just one field, and ER will fill all copies identically. That is ideal for values repeated on every page.
  2. For tables where every row must be unique, the fields must have unique names (LineNo1, LineNo2, etc.). Renaming manually gets tedious fast. A handy script Acrobat — Rename Duplicate Fields to Unique Fields | Try67 | Custom PDF tools (the script is commercial + Adobe Acrobat Pro is required) automates this: draw a rectangle over the fields, and it appends unique suffixes to overlapping fields across pages. You can prepare a single line of fields, copy-paste the line (do not shuffle but always keep adding them in the strict order from top to bottom: Acrobat keeps track of their numbers and sorts them internally), then start replicating blocks of lines until the page is full, copy-paste full pages in the Acrobat’s “Organize pages” tool, and then batch-rename everything.
  3. Back in ER: in the Format mode, add a PDF/File object and point it to your PDF template. Use the button Import / Update from PDF once to pull in field definitions. Don’t use “Update from PDF” again – it can scramble your mapping. Grouping fields by suffix (e.g., LineNo1..10) doesn’t always work automatically, so you might have to manually create a field group and drop in the core field (LineNo) without suffix.
  4. Apply ENUMERATE(Lines) to record lists to create a structure where @.Number gives you the index (1-based) and @.Value gives the record. Then, in the Mapping mode, set the Name property of the line field in the lower right corner to "LineNo"&TEXT(@.Number), then assign the value from @.Value.YourField as usual with the Bind button. By the way, the order of fields doesn’t matter – unlike Excel, where rows and columns are positional, the PDF is filled at once using a key-value approach (essentially, an FDF file).
  5. Don’t exceed the number of fields in your form. There’s no pagination or overflow – ER won’t split lines across multiple copies of the form. You may limit the data source with the formula like WHERE(@.LinesEnumerated,@.LinesEnumerated.Number<=10) to harden the report. You may also design a custom warning if the number of lines exceeds a certain threshold: Validate Electronic Reporting on execution and show errors or warnings – Arcadi Burria.

In short, ER’s PDF support is usable and powerful enough but static. With proper naming and field repetition strategy, it’s good for things like tax forms, returns, invoices with known limits, etc. The main challenge is preparing the template, not the mapping itself.

Dynamics 365 Intercompany Cost+ pricing

Dynamics 365 Intercompany Cost+ pricing

As highlighted 10 years ago by M. Aamer in his article Inter-company goods trading (sales price equal to cost price) – Microsoft Dynamics AX 2012 – Microsoft Dynamics 365 Blog, there is a parameter Unit price equal to cost price in the intercompany settings in Dynamics 365 for SCM, which enforces the intercompany purchase price at the cost price in the intercompany selling company.

The system tries to update the Sales order – Purchase order pair on 3 occasions:

  • ICO sales order line creation;
  • reservation of the goods in the supplier company;
  • release (!) to the warehouse in that company i.e., just before picking.

The resulting sales price is the current moving average stock price. D365 traverses the inventory transactions, and if no price is known at the given inventory dimensions, it defaults to the price at the item master (this may be relevant in the engineer-to-order scenario, where the ultimate cost price becomes known just shortly before the shipping).

As noted many years ago by my humble self 😉 , the pure cost price is normally not allowed by accounting standards: the “arm’s length” principle must be respected in transfer pricing between companies within a group i.e., there must be a markup on top. The Intercompany percent charge was developed recently by Microsoft to comply: Set up charges on intercompany orders – Supply Chain Management | Dynamics 365 | Microsoft Learn.

At some locations, the misc. charge is not good enough, as the auditors favour an “opaque” sales price with an embedded markup percentage. This may in principle be achieved with a negative line discount to the sales price = cost price.  Normally, negative discounts are frowned upon by D365: “Field 'Discount percentage 1'(= -15,00) can only contain positive numbers.“, but the trick described in the blog “Overwrite a read-only configuration in D365FO” will let you import such a trade agreement.

At the recipient’s side, at the ICO Purchase order, the accounting distribution will be split into the base price (= ICO cost) and the [negative] discount. To satisfy the request for one single SO revenue GL transaction and one single PO change-in-stocks GL transaction, a customization was made out of pure desperation. The markup percentage is stored in a custom field Intercompany percent at the seller’s Item group, and quietly added to the net sales price in the following routine (you may download the source code here: ICOCostPlus.axpp):

				
					[ExtensionOf(classStr(SalesLineType))]
final class SalesLineType_ICOCostPlus_Extension
{
    public CostPrice interCompanyCalcSalesPrice()
    {
        SalesPrice          salesPrice = next interCompanyCalcSalesPrice();

        if (! salesLine.InterCompanyInventTransId ||
            salesLine.SalesQty < 0 ||
            ! salesLine.isStocked())
        {
            return salesPrice;
        }
        if (! salesTable.interCompanyEndpointActionPolicy().UnitPriceEqualsCostPrice)
        {
            return salesPrice;
        }

        InventItemGroup itemGroup = InventItemGroupItem::findByItemIdLegalEntity(salesLine.ItemId, salesLine.DataAreaId).itemGroup();

        if (itemGroup.ICOSalesPercentMarkup != 0)
        {
            salesPrice += CurrencyExchangeHelper::price(salesPrice * itemGroup.ICOSalesPercentMarkup/100, salesLine.CurrencyCode);
        }

        return salesPrice;
    }

}

				
			

Amend GDPdU = GoBD = FEC

Amend GDPdU = GoBD = FEC

The audit export file in Dynamics 365 for Finance may be easily extended, a power user can do it on his/her own. For example, the auditors often ask for a “system date” or time column in the audit file for their DATEV applications: in a nutshell, they need to know when the invoice was really posted, not only the invoice date.

Here is how to fulfil this requirement:

  1. Open the Electronic reporting workspace (Organisation administration >  Workspaces). Make sure a custom “provider” is selected as “active”. Check here to learn how and why: Electronic Reporting (ER) Cookbook 2: new tips from the kitchen
  2. Click the Reporting configurations tile and locate the root Data export model node. To amend the French FEC file, select the  French FEC model mapping instead.
  3. Click +Create configuration and select the “Model Mapping based on data model Data export model” option. Namely, the model itself is very abstract in the case of this data export, the interesting stuff is hidden in the model mapping.
  4. Select the new model mapping in the tree and use the Designer, then click Designer again.
  5. In the Model mapping designer, look for the odd looking objects like _01xxxx, _02xxxx etc. at the bottom of the Data sources list. These are the “Table metadata” objects. I have a feeling that these artifacts were invented solely for this usage scenario of generic data exports with variable columns. In our case, choose _01Sachkonten, then Edit, then Editor.
  6. The Table metadata editor has a unique UI. In the leftmost list, select the Sachkontobuchungen table. In the rightmost list, locate the $Entries/$GeneralJournalEntry/createdDateTime node and Add it to the middle list of fields (see the screenshot above). Rename the new field, if necessary.
  7. That’s it, hit Save, close the table editor, confirm with OK and save the changes in the model mapping designer ultimately.
  8. In the end, Change status of your custom model mapping to Complete and mark it as the Default for model mapping to inactivate the standard one.
  9. If you need to format the date-time column in a special way, you’d need to make a format derived from the standard German audit file output, too. In that one, you’d need to modify the Transformation fmtdatatime. You will learn in the blog Electronic Reporting (ER) Cookbook 3: Working with dates how to do it.
  10. To test your changes, launch General ledger > Periodic tasks > Data export, select the Format mapping (choose your own if you modified it at step 9). Select Table Group = Ledger accounts, choose the dates, launch and verify the output in one of files in the resulting ZIP offered for download:


"130300-001-";2025-02-21;"Period 2";"68721077482";"Benutzung";"Verkauf - Lieferschein-Umsatzerlös, Gegenkonto";"Nein";"Nein";499,96;"EUR";499,96;"";21.02.2025;"SPS-1000165";21.02.2025;"SPK-000166";"Aktuell";"";"";68719785542;"SPK-000166"


"140200-001-";2025-02-21;"Period 2";"68721077479";"Benutzung";"Kosten der gelieferten Einheiten";"Nein";"Ja";-315,50;"EUR";-315,50;"";21.02.2025;"SPS-1000165";21.02.2025;"SPK-000166";"Aktuell";"";"";68719785542;"SPK-000166"

By the way, you may use the parameter Include “Create by” field to comply with another common requirement: export the user ID to prove to the auditor that it is the accountant who makes the ledger transactions, not an IT consultant 😉