Deep links available in every form

Ievgen Miroshnikov gave me the idea and Microsoft also has some information here.

The following extends the standard button available in every Dynamics 365 for Finance and Operations form to provide the deep link to the currently select record of the primary form data source.

Copy the link and share it. The recipient will jump directly to the currently selected record.

(I wonder why Microsoft doesn’t provide this in standard D365FO – this is actually what you would expect from the button.)


using Microsoft.Dynamics.AX.Framework.Utilities;
using Microsoft.Dynamics.@Client.ServerForm.Contexts;

/// <summary>
/// The class <c>URLUtility_Extension</c> contains extension methods for the <c>URLUtility</c> class.
/// </summary>
public static class URLUtility_Extension
    public static str generateRecordUrl(str _menuItemName, MenuItemType _menuItemType, DataSourceName _dataSourceName, Map _indexFieldValuesMap, DataAreaId _dataAreaId = curExt())
        System.Uri host                     = SessionContext::Get_Current().Get_RequestUrl();
        UrlHelper.UrlGenerator generator    = new UrlHelper.UrlGenerator();
        generator.MenuItemName              = _menuItemName;
        generator.MenuItemType              = _menuItemType;
        generator.HostUrl                   = host.GetLeftPart(System.UriPartial::Path);
        generator.Company                   = _dataAreaId;
        generator.EncryptRequestQuery       = true;

        if (_dataSourceName && _indexFieldValuesMap)
            MapEnumerator mapEnumerator = _indexFieldValuesMap.getEnumerator();

            var requestQueryParameterCollection = generator.RequestQueryParameterCollection;

            while (mapEnumerator.moveNext())
                requestQueryParameterCollection.UpdateOrAddEntry(_dataSourceName, mapEnumerator.currentKey(), mapEnumerator.currentValue());

        return generator.GenerateFullUrl().AbsoluteUri;

    public static str generateRecordUrlFromDataSource(FormDataSource _formDataSource)
        FormRun         formRun         = _formDataSource.formRun();
        str             menuItemName    = formRun.args().menuItemName();
        MenuItemType    menuItemType    = formRun.args().menuItemType();
        DataSourceName  dataSourceName  =;

        TableId   tableId   = _formDataSource.table();
        DictTable dictTable = new DictTable(tableId);
        DictIndex dictIndex = new DictIndex(tableId, dictTable.primaryIndex());

        int     fieldCount          = dictIndex.numberOfFields();
        Map     indexFieldValuesMap = new Map(Types::String, Types::String);
        Common  record              = _formDataSource.cursor();
        FieldId primaryKeyFieldId;

        for (int fieldIndex = 1; fieldIndex <= fieldCount; fieldIndex++)
            primaryKeyFieldId = dictIndex.field(fieldIndex);

            indexFieldValuesMap.insert(fieldId2Name(tableId, primaryKeyFieldId), any2Str(record.(primaryKeyFieldId)));

        return URLUtility::generateRecordUrl(menuItemName, menuItemType, dataSourceName, indexFieldValuesMap, record.DataAreaId);

    public static str generateUrl(FormRun formRun)
        str url = next generateUrl(formRun);

        if (formRun && formRun.dataSource(1) && formRun.dataSource(1).cursor())
            url = URLUtility::generateRecordUrlFromDataSource(formRun.dataSource(1));
        return url;

Change based alerts using Microsoft Flow

Rob showed how to make Date Based Alerts using Microsoft Flow. So this is a great start into the future of the still missing AX alerts. But of course we want change based alerts for example to be informed about a sales order that has been processed. It does not take to long to find out that this is still not possible in the way it has been in the past. However you can get a message once the sales order reaches a certain status:

You see that the sales order is hard coded and once the sales order status has changed, you will receive an email every day. So why not use your Android Flow App to disable or delete the Flow?

Mass changes to Number Sequences in Dynamics 365 for Operations

Get Microsoft Dynamics Office Add-in for Excel 2016

Open Number sequences in Excel

In D365fO go to Organization administration > Number sequences > Number sequences

Press Office Button > Open in Excel

Add format field to Excel

In Excel add the Format field. (Note: add the Name Field as well! Otherwise it will be reset.)

Edit data

Change the format as desired (e.g. remove the dash using excel search & replace)


Press Publish

Advanced Filter/Sort in D365 1611 (November 2016)


  • I want to filter the released products by “Tracking dimension group”
  • In AX 2012 R3 I right-clicked on the field I wanted to search by, selected “Filter by field” and added entered the search-text.

Steps in D365

What doesn’t work

  • A right mouse click doesn’t allow me to filter.
  • The filter tab doesn’t allow me to filter by “Tracking dimension group”

Use “Advanced Filter/Sort”

  • This does not differ from AX 2012, but the shortcut of AX 2012 is sorely missed
  • Open “Advanced Filter/Sort”

  • Add Tables

  • Add filter field

  • Hey presto!

Comparison: “Use futures date as requirement date”


Master plan setup – Use futures date as requirement date

pl-PO Use Futures date as Requirement date = Yes


pl-PO Use Futures date as Requirement date = No


pl-PO + pl-Prod Use Futures date as Requirement date = No


Coverage group – Action Basis Date

Action Basis date = Requirement date


Action Basis date = Futures date


Test cases


Sales order with confirmed delivery date: 16.11.2016; the lead time setup of the purchase item (M0009) doesn’t allow the PO to be on time.


pl-PO Use Futures date as Requirement date = Yes; Action Basis date = Requirement date


pl-PO Use Futures date as Requirement date = Yes; Action Basis date = Futures date


pl-PO Use Futures date as Requirement date = No; Action Basis date = Requirement/Futures date

Note: Changing Action Basis date does not have an affect


pl-PO + pl-Prod Use Futures date as Requirement date = No; Action Basis date = Futures/Requirement date

Note: Changing Action Basis date does not have an affect



USE: Use Futures date as Requirement date = Yes; Action Basis date = Requirement date

With this setting the system tells you what is late and what you should try to do about it.

Minimal Setup for new Workflow

Sumit created nice overview of workflow-implementations in AX:

Developing a new Workflow

The section below describes briefly, the process of developing a new workflow.

To develop a new workflow, following artifacts or objects need to be created / modified:

  • Workflow Categories
  • Workflow Templates
  • Workflow Query (Document)
  • Workflow Approvals and Tasks (Tasks are optional)
  • Enabling the workflows on the form
  • Workflow submission classes

Let us go through each of these artifacts one by one:

Create Workflow Categories

A workflow category defines the module in which the workflow will be available. Modules are defined by the SysModule enum. You will be doing following here:

  • Create a new category in workflow categories node (AOT>>Workflow>>Workflow Categories)
  • Specify the name and module to which it belongs

Create Workflow Templates (AX 2012: Workflow Types)

A workflow template brings all the different elements of the workflow together. Workflow configurations are created based on a template, and many configurations can be based on the same template. The template defines which actions are allowed and which are required.

You will be doing following here:

  • Create a new template in the workflow templates node (AOT>>Workflow>>Workflow Templates) (AX 2012: AOT>>Workflow>>Workflow Types)
  • Specify a name and category to which it belongs

Next we create a work flow document.

Create Workflow Document

A query defines what tables are used to determine that a workflow can be initiated. Here you will do the following

  • Create a new query (AOT>>Queries)
  • Specify a name and Add required tables to the data source.
  • Create a new class extending from WorkFlowDocument class (AOT>>Classes)
  • Override the method getQueryName and return the name of newly created query
  • Save the class
  • Once query and its supporting class is created, attach this to Workflow template (Specify it under the Document property of template; AX 2012: type)

Next step is to attach Approvals and / or Tasks

Create Workflow Approvals (or Tasks):

An approval route may contain a number of outcomes. It may be approved, rejected, returned or a change may be requested (For task it will be complete, reject or request change). The Workflow Approval element determines which of these outcomes is allowed and what happens in the event of each outcome. Each outcome can trigger specific code by specifying a menu item for each item. Do the following to create an approval

  • Create a new approval object in the Approvals node. (AOT>>Workflow>>Approvals)
  • Specify a unique name for the approval
  • Specify the Document (The class created for query) in the Document property
  • Specify ParticipantProvider. Normally you specify WorkflowUserGroupParticipantProvider, but you can create your own participant provider. (Missing in AX 2012)
  • Specify DueDateProvider. Normally you specify WorkflowWorkCalendarDueDateProvider, but you can create your own due date provider. (Missing in AX 2012)
  • Specify HierarchyProvider. Normally you specify WorkflowLimitHierarchyProvider, but you can create your own hierarchy provider. (Missing in AX 2012)
  • Set the DocumentMenuItem to form menu item where you want the workflow to appear (Example sales order etc.)
  • Approval Outcomes:
    • Use a standard class that acts as an engine for all approval outcomes
    • You are not required to do anything but set the workflow to applicable outcomes, therefore call the same class from different menu items. The menu items simply allow you to use two different labels. In more complex workflows it may be necessary to override or copy and modify this class rather than use it directly. Example: If you have to set an outcome for Approved do the following:
      1. Create a new Action type menu item and specify a name to it
      2. Set ObjectType property to Class and Object property to WorkflowWorkItemActionManager
      3. Now get to Workflow>>Approvals>>Approval_you_created>>Outcomes>>Approve node and specify ActionMenuItem as new menuitem created before.
      4. Repeat Step 2 for all the outcomes you need
    • If you do not need an outcome you can simply disable it by changing Enabled property to No
  • Once completed, drag and drop this approval (or task) into the previously created workflow template (AX 2012: Worfklow Type)

Enable workflow on a form

Now that the workflow template is defined, you can specify which forms will use this template. Do the following:

  • Add a WorkflowState field (More can be added by CreatedBy, Time, Status etc.) to the required table
  • In the desired form, go to the design node properties and set property WorkFlowEnabled to “Yes”, set the WorkFlowDataSource (the table of the previous step) and (AX 2012 only) set the WorkflowType as defined above.
  • If you want, you can override the method canSubmitToWorkflow on the form and specify conditions when user can submit the record to workflow

After enabling the workflow on class, create a class to submit the records to workflow

Create a Submit to Workflow class

To submit a document to workflow, call standard code to prompt the user for a comment and to process the submission. (Look at PurchReqWorkflow class for an example)

  • After creating the submit to workflow class, create a corresponding action menu item
  • Now traverse to the workflow template (AX 2012: Worfklow Type) and specify this submit to workflow class menu item on the SubmitToWorkFlowMenuItem property
  • Once this is done you can then configure the workflow and test it. (You can refer the Workflows – Installation and Configuration document that I sent earlier for configuring the workflows)

This will give you a broad idea as to what needs to be done for creating a workflow.


In AX 2012 it is required to update CIL before the Workflow can be configured.

[updated for AX 2012 on 07/07/2014]

Product configurator – Front-end call stack

Instantiate and load front-end

1. Starting Point

  • Called by PCExecuteVariantConfiguration
  • Form PCRuntimeConfigurator
  • Class PCRuntimeConfiguratorFormFactory.create

 2. First the model is loaded into an XML

  • PCRuntimeLibrary::getModelXMLIL –> Only Model, no values (Values come only in Step 4.)
  • Calls PCXmlSessionWriterModel.writeModel
  • Calls PCXmlSessionWriterComponent.write
  • Calls PCXmlSessionWriterComponentAttribute.write

3. Using the .Net Class is used to process the xml

  • Microsoft.Dynamics.Ax.Frameworks.Controls.ProductConfiguration.Iconfigurator
  • Instantiated in PCRuntimeConfigurator.loadModel

4. Assign Values to front-end

  • Triggered by PCRuntimeConfigurator.loadAttributeValues()
  • PCConfigurationLoader.runIL
  • PCConfigurationLoader.loadValues

5. Frontend-Handlers

  • The Font-End calls PCRuntimeUIConfigurator.userSelectedValue to assign user selected values to front end.

Save front-end results

1. Front-end returns XML

  • Processed by PCXMLParse… classes
  • e.g. PcXmlParseComponentAttribute.parseIL (modified for config description – hidden attributes)

2. XML Parser returns PCAdaptor… classes that do the further processing

  • PCAdaptorVisitorConfigurationReuse: handle reusability of configurations
    • PCAdaptorComponent.createReuseConfiguration
    • PCAdaptorComponent.reuseConfigurationExists()
  • PCAdaptorVisitorBOMGeneration: create BOM

3. Finally update the Sales Line

  • PCExecuteVariantConfiguration.updateDemandSourceDocumentLine