Overlooking many recent Dynamics 365 implementations, it seems that Microsoft’s marketing strategy of ‘marrying’ Dynamics AX and CRM into one Dynamics 365 family is paying off. More and more customers are choosing for the package deal of Operations and Sales. However, as always, the marketing machine is ahead of the troops: with the current state of the integration of the products, we need to be creative in order to make the two systems feel like one.

In this blog post I’ll unveil an effective way to let Microsoft Dynamics 365 for Sales (CRM) interact with Microsoft Dynamics 365 for Finance and Operations (ERP)…

Introduction

Most of us will have some affinity with the Common Data Service, which can also be used to exchange data between Dynamics 365 for Sales (CRM) and Dynamics 365 for Finance and Operations (ERP). However, first of all Common Data Service does not offer real time capabilities at the moment of publishing this blog post. Second, this information exchange happens behind the scenes (on data/service level). But in order to make D365S and D365FO feel like one system, we need a different kind of interaction. An interaction which builds upon real time exchange of information and which builds upon data interaction on form level: creating a new D365FO sales order from D365S should offer an experience which is close to ‘native’ D365FO experience.

Concepts for CRM and ERP interaction

In a recent project context, the customer was looking to emphasize D365S as master system for Customer management and Customer interaction and to emphasize D365FO as their selling system. Therefore, all users were envisioned to work from a 360 degree customer dashboard in D365S which was also CTI enabled (=telephone integrated). Customer interaction in D365S could result in offering a quotation or direct sales which then required to bring the user into the D365FO sphere. In order to make this a seamless experience for the user, we evaluated two concepts:

1. Hub-2-Hub: in this concept, the user has one “Open in Call center” button which opens the D365FO Customer Service form for the Customer Account currently selected in D365S. This Customer service form then offers the out-of-the-box D365FO features to create or edit an existing sales order or return order (quotation was added by minor modification).

See this concept in action (example):

2. Master-Slave: in this concept, the user working from D365S has direct access into the D365FO quick create forms for creating new sales orders and quotations and into the D365FO details forms allowing direct modifications to sales order or quotation. In this project context, we also decided to map the D365FO order holds to D365S tasks. This allowed Call Center agents to spot any order exceptions in D365S (for example missing payments), tackle that exception with the customer and then remove the respective hold by one click into D365FO.See this concept in action (new order):

See this concept in action (new quotation from opportunity):

In both concepts, the data modified or newly created in D365FO is synched back to D365S through the standard CDS templates currently available. So after some minutes, the 360 degree customer dashboard in D365S reflects these changes at next visit of the customer Account. In a few scenarios, the current non-real time CDS behavior was not sufficient to support the business scenario: for example, new customer accounts created in D365S are required to be available in D365FO straight away. Otherwise the quick create form for quotation or sales order creation in D365FO cannot be pre-filled for the customer which was just created in D365S (Master-Slave concept) and the Customer Service form in D365FO cannot be pre-filtered for the that new customer (Hub-2-Hub concept). So here we had to implement real time Azure LogicApp integration to get to the desired result (no further details in this blog post).

The trick: how to realize the interaction on form level

The ‘trick’ to make D365S to D365FO form level interaction possible is to utilize the relative freedom we have to leverage custom URL parts (suffixes) in D365FO. A typical D365FO URL for opening the Sales order form looks like this: https://<CustomerSpecific>.sandbox.ax.dynamics.com/?mi=MCRCustomerService&cmp=<Company>

This is the URL that was opened from D365S in the Master-Slave\Create quote scenario:https://<CustomerSpecific>.sandbox.ax.dynamics.com/?mi=MCRCustomerService&cmp=<Company>&customerid=575342

As you can see, both the D365S Account number (kept in synch with D365FO Customer account through LogicApp) is passed through to D365FO by a custom URL suffix. You need two minor modifications to make this work:

A JavaScript enabled button in D365S (in the previous example the “Create quote” button). The JavaScript code is hosted as a Web resource which holds the function to construct the full D365FO URL for a given button click (see simple example below).

X++ code in D365FO to interpret the custom URL part: form event handler extension on the form Initialize event which does the following (in this example):

Reading the “customerid=<value>” section in the URL

Finding the associated customer record in the CustTable

Setting the active customer in the Customer service form to this customer

D365S Web resource with JScript:

D365FO X++ code:

Due to the Azure AD enabled Single-Sign-On for D365S and D365FO, the D365FO client will open in about 2 seconds after clicking the JavaScript enabled button (the first time is always a bit slower due to caching). And given the Master-Slave 1-click approach which is similar to intra-D365FO behavior, most users will perceive this as ‘seamless’.

Evaluation of the concepts

I prefer the Master-Slave approach over the Hub-2-Hub approach for the following reasons:

With the Hub-2-Hub approach, it is not possible to pass parameter values which concern new records. A good example here is the D365S to D365FO new quotation flow (see Master-Slave picture above). In this context, it is critical to pass the D365S Opportunity ID to D365FO and store it on the new Quotation record created in D365FO. Only then this new Quotation record can, after making it a D365S record through CDS synch, be linked to the original Opportunity record in D365S (which prevents breaking integrity in D365S).

The Master-Slave approach emphasizes a true distinction in ownership of the Customer entity – This provides clarity to the users that they should always start their process in the D365S 360 degree Customer dashboard. By offering direct access from D365S to all selling features in D365FO, access to the customer related forms can also be minimized and/or reduced to view-only. This simplifies the use of both systems for average users.

The Master-Slave concept saves the user clicks compares to the Hub-2-Hub approach.

The strongest point of the Hub-2-Hub approach is that it minimizes customization. But I think looking at the minimal development effort required to implement the Master-Slave concept, this does not outweigh the negative arguments listed above.

Evaluation of the overall solution

Although this solution was well received by the customer in this particular project context, there are some critical notes to make:

The solution presented in this blog post relies on the fact that the D365FO Kernel allows inclusion of custom URL parameters. Since this may change in the future (malicious code may also be triggered in this way!), this is a true weak spot.

Ideally the base part of the URL is not hard coded in JScript but is retrieved dynamically based on an ‘Active environment’ parameter set in D365S.

It could be considered to make the parameter name (in the example above: “customerid”) configurable by a parameter. This could also avoid potential conflicts with new ‘Kernel’ parameters Microsoft might introduce. On the other hand, if the custom URL suffixes are regarded as a “service”, this would vote against this “configurable” approach.

I hope this inspires you in your creative thinking! At least it inspired me.. Special thanks to Stefan Ebert, Georg Braun and Markus Blässle for their creative input to make this happen!