Wednesday, May 17, 2017

D3FO: Customizing interaction classes using extensions

Dynamics AX technical community is finding cool and tricky ways to create extensions for customization's. In this post, let’s do a quick walk through on how we can customize a list page interaction class via extensions.  
To do this let's add a new button on sales order list page and enable/disable it on the basis of sales order status.

Below are the high level steps :
  • Create a new class to write the business logic to be executed by your new button.
  • Create a new menu item linked to your class
  • Create extension of the list page and add your new button
  • Create event handler for the list page interaction class and enable/disable the new button 

Let's create a new class: I have shown the total sales order amount in the Info-log, to show an example of business process in the method.

Now we create a new action type menu item for this class as shown below:

Create an extension of SalesTableListPage from : To do this, right click on the SalesTableListPage object in the AOT  and select "Create extension" . Make sure your model, where you are creating the project, has a reference to Application suite else this option will not be enabled.

In the designer window, expand the design node and navigate to the action pane where you want to add the button. Let’s add a new button group and add the menu item we created

Verify that the menu item button is having correct properties and define the data source property as SalesTable

Build the project and test the button. When you open the sales table list page the new button is visible

Click on the button just to make sure that it’s working. On clicking it we can see that Infolog is shown to display the Sales order total amount

Now let's add more logic to our button to only be enabled for sales orders which are not invoiced. Typically we would go to the interaction class and modify the function which is enabling/disabling button, but we want to do this without customizing the standard class and with the use of extensions.
That means we need to subscribe to the method of the interaction class. We can see that interaction class as methods available which are pretty much self-explanatory by their names. We can see there are few methods which set the button properties 

As we added the button in the sales order action pane group we can see that there is a method in this class which used to set buttons on the sales order action pane tab menu items . Notice that this is a protected method.  

Ideally you may want to create an event handler for this method. Try to right click on this method and then select the option to create a post event handler 

You will be greeted with the below error message. We can only create event handlers for Hookable methods. The definition of  Hookable method is also shown in the error message, these are non-abstract methods that are either public or tagged with the "Hookable" attribute as true. 

Let's find a hookable method in the interaction class:  On a quick scan in the class you can see that the setButtonEnabled() method is a protected method and decorated with the "HookableAttribute" as true. 

This is an important point for ISV's to consider when design their solutions, as this attribute will be helpful to tag extension plugs.Let's create an event handler listener for this method 

Add the event handler in the new class which we already created 

Now we need to  :
·         Get the object of the interaction class
·         Get the current sales table record
·         Set the button access

The below lines of code represent each step 

Below is the code text in case you want to reuse it
    /// This method enables/disables the new process button based on the sales order status

    [PostHandlerFor(classStr(SalesTableListPageInteraction), methodStr(SalesTableListPageInteraction, setButtonEnabled))]
    public static void SalesTableListPageInteraction_Post_setButtonEnabled(XppPrePostArgs args)
        SalesTableListPageInteraction salesTableListPageInteraction = args.getThis();
        SalesTable salesTable = salesTableListPageInteraction.listPage().activeRecord(queryDataSourceStr(SalesTableListPage, SalesTable)) as SalesTable;
        salesTableListPageInteraction.listPage().actionPaneControlEnabled(formControlStr(SalesTableListPage, RGSalesProcess),SalesTable.SalesStatus != SalesStatus::Invoiced);

Now we build the project and run the list page form to see if the button is disabled for invoiced sales orders:
The button is disabled for an invoiced sales order

The button is enabled for a sales order having a status other than Invoiced.

Thanks for reading the blog. Your feedback is welcome and keep sharing any cool ideas around extensions and the new frameworks of D3FO. 

Saturday, April 1, 2017

Technical overview - Gantt control in Dynamics 365 for operations

In Microsoft Dynamics 365 for operations, form controls are split into logical and physical parts. The physical presentation is HTML, JavaScript and CSS within the browser and the logical state always runs on server which is controlled by X++.
ActiveX, ManagedHost and WPF controls were used in AX2012  to add new custom controls, these  are incompatible with HTML based platform and cannot be used in D3FO.

A new extensible control framework is introduced in D3FO which lets you add custom controls by using HTML5, Javascript and CSS3. The new Gantt control in D3FO is implemented by using extensible control framework.It comes with an advantage that you don’t  have to pay an additional license fee to use the control in your own forms or to extend the control.

In this post let's do a quick technical walkthrough on the various elements of the Gantt control and how to use it on your forms.

 The below diagram shows the basic elements of a Gantt control.
In a Gantt chart we can identify as per below sample diagram:
Lets go through brief summary of each Gantt element:
Activity : This is most important element is a Gantt control. Each activity is allocated its own row in the chart. Activities can form a hierarchy, like a tree, by referencing a parent activity. Two activities can be connected to each other through links. A Gantt activity can be further classified into a Milestone activity, task activity or a summary activity. Technical base is provided  a base enum which holds the type of Gantt control activity 

Below classes which are used to initialise and hold data for the activities for a Gantt control.
Links : Links are used to connect two activities on a Gantt control. The Link information is stored as a data contract in the class GanttControlLink.
The link types are stored in GanttLinkType enumeration:
FF : End to end link
FS : End to start link
SF : Start to End Link
SS : Start to start link

Vertical Markers: This represents a vertical marker on a Gantt control . This information is stored as a data contract in the ganttControlVerticalMarker class. The date time method stores the information of the date/time where the marker should be shown on the control. The text is text which is shown next to the marker.  We can add more than 1 markers on the control.
Calendar and working time intervals : Calendar holds the calendar ID and the working time intervals holds a set of working time information. These are controlled by GanttControlCalendar and GanttControlWorkingTimeInterval classes. This information is stored in below contract classes:

The list of working times in the GanttControlClendar is generated based on the GanttControlWorkingTimeInterval contract as shown in the below contract method

Columns: These are the column on a Gantt chart grid and are stored in the class GanttControlColumn as a contract. The below parm methods store the Columns information. The alignment is controlle d by SysAlignment base enum 

Configurations : Gantt configurations refer to configuration of view and edit behaviour of the Gantt control. There are configuration settings which are stored as a data contract. Use calendars method determines if calendars should be used in the Gantt chart. Switching calendars off have a huge performance benefit. Some configurations for Gantt control are :
  •  Show all links determines if all links should be shown; otherwise only links for the currently selected chain will be shown.
  • Use theme colours Determines if standard AX theme colours should be used for the elements of the chart.
  • Allow move activities Determines if activities are allowed to be moved using drag/drop.
  • Allow resize activities Determines if activities are allowed to be resized using drag/drop.
  • Allow completion change Determines if activities can have the completion percentage set using drag/drop.
  • Vertical move mode Determines if/how activities are allowed to be moved vertically.
Below list of methods show the configurations which can be defined when initialising the Gantt configuration.  
Gantt control timescales : Represents settings for a time scale on a Gantt chart. These are stored in the GanttControlConfiguration contract. The below methods are used in the contract

Gantt Control : This is the Gantt control class which stores the information of all the Gantt elements. The class name is GanttControl and it has methods to store the Gantt elements information. If you look at this class then you will see that this stores most of the Gantt elements information as a List. 

Vertical markers
How it all works together: We can add a new Gantt control on the form by selecting it from the list of control available when we add a new control
We need to define auto declaration as true

 We can now set/populate to the GanttControl class methods using this control and load the gantt elements. A very good example is shown on the tutorial_Gantt form shipped in application foundation

All the activities are added to a list and
And then the list is assigned in the GanttControl class

To load the GanttControl we have to write the X++ code to create and populate the contracts, lists and initliaze the Gantt classes. The complete code sample can be referenced in tutorial_gantt form which shows the Gantt control as below:


There is much more to what we can do with the Gantt control classes and with the power of extensible control framework. It provides a great platform for vendors and ISV's to build amazing Gantt extensions and advanced controls.



Saturday, March 11, 2017

Consuming custom common data model entity in powerapps

In the previous post we saw how we can create a new custom entity in common data model. In this post let's do a quick walkthrough of how we can consume it in powerApps and create/update data for that entity from powerapp. 

In the bottom left corner of the powerapp portal you will find the button to create a new app

Select if you want to use the powerapps studio for windows or the powerapps studio for web to create the new app. In this example I choose Powerapp studio for Web

Microsoft provides out of the box templates for creating apps. Let's create a simple phone layout app for connecting to CDM database via Common Data Service 

You will land on the connections page. Here we can see the CDM database we created in previous post. Once you select the CDM DB then you can see the desired entity . Notice we can see our custom "Approved vendors" entity

Click Connect

The app building service will run and take around a minute to build a default app for the selected entity

You will land in the designer window of the created app. The system created a basic 3 page app (based on the template we selected) to view and edit the data of the entity and also shows the data in the preview.  

We can navigate to different pages to see how it looks

Now let's save the app on the cloud, to do this go to  File -->  Save as --> Select the cloud option and give it a name and save it

Once this is finished you can access the app from other devices.
I installed powerApps on my Android phone and logged in. The new app was visible under My apps.

On opening the App I can view the data on my mobile phone.
Below are screenshots from my mobile

Notice that the vendor ID field shows the lookup by fetching the data from the CDM vendors entity

   Once the record is saved we can edit it again

We can go back to CDM database and view the data of the entity.  The new records we created from the App is visible here.

Users can build their own apps without writing a single line of code by leveraging the out of box available templates. Store them on Cloud and share with other users of their company.
This is a big game changer as smart users can now leverage all the tools and power from the cloud to be more productive and use the systems in much powerful and smarter ways.