Problem

Dynamics 365 BPF design change causing the following issues:

  1. Each user seeing different active BPF on the same record, causing user perception and usability issues.
  2. For the records migrated from Dynamics 2016 to Dynamics 365, a different active BPF may appear for each user.
  3. Out of box workflows depending upon process and stage attributes behave weirdly.
  4. New server side APIs not returning correct active process per user.

Context

Before Dynamics 365, BPF used to follow the below architecture:

  1. Each entity was to have at max one active business process flow.
  2. On the entity record, the GUID of the active BPF was saved on the ProcessId field.
  3. Similarly, the GUID of the active stage was saved on the StageId field.

For setting up the active process on any entity record, we were just setting the values in these two fields either programmatically or using out-of-the-box workflows and actions.

However, with Dynamics 365, a record can have multiple concurrent active BPFs on the same record. As per different MSDN blogs, mentioned below changes are to be made in the system:

  • Instead of setting values in these two fields, user needs to execute SetProcessRequest request against the target record.
  • Like before, there is also a command action SetAction provided by Dynamics which can be called in and out-of-box workflow to set the BPF.
  • The two fields ProcessId and StageId are not to be used for comparison as there is no guarantee that correct values will be updated back to these fields.
  • For programmatically progressing the next stage, we will need to execute two separate requests, RetrieveProcessInstancesRequest and RetrieveActivePathRequest.

Issues Encountered

Different BPF Coming for Different Users

The main problem with SetProcessRequest is that, with Dynamics 365, it is only setting a BPF for one user and not for everyone else. For example, consider the mentioned below scenario

  1. For an entity, there are two BPFs: BPF A and BPF B. BPF A is the default business process. The screenshot below shows the two BPFs configured for an account entity.

 

In BPF A, there is only one stage where user needs to enter the Account Name. Shown below is another BPF B which is also having just one stage Account Number for the account entity.

  1. Now, write an out-of-the-box workflow upon creation of account entity. Please note that the workflow can also be configured for update of account. In the workflow, the idea is to change the active process of the record from BPF A to BPF B. Below is the screenshot for the same.

 

 

Please note that action SetProcess will behave the same way as the SDK call of SetProcessRequest.

  1. Now create a new record of account. Below are the screenshots for the same.

Please note that being the default BPF, BPF A appears on the account form before the record is created.

 

Now create the record. In doing so, the workflow that we have written will execute and will set the active BPF of the account record to BPF B. Review the BPF which is coming on the record.

 

Another way of setting up the BPF would be to execute “SetProcessRequest” on post create plugin on the record. It will behave the same way.

  1. Now log in with another user who is not the owner of the workflow. Open the record created in the previous step. Review and ensure that BPF A is coming on the record header.

This implies that the workflow did not set BPF B as the active business process of the record for all the users. Similar behaviour is also observed for SetProcessRequest.

Implications

  1. Up until Dynamics 2016, all users were seeing the same active business process flow with same stage. However, with Dynamics 365, it will depend upon the user. Different users can see different BPFs on the same record even if they have the same security role. This can lead to confusion.
  2. If there is any clientside scripting based upon the active BPF, it may behave differently for different users.

Workflows based on Process Id attributes not behaving properly

A second issue which we encountered was that, any out-of-the-box workflow which was based on Process Id related fields was behaving weirdly. Below are things that were observed.

  1. Below is an on-demand workflow we created. It’s just reading values from the Process Id field and populating it in the account. Please note that the scope is “Organisation” and not user.

 

 

Now, we run the on-demand workflow for both the users.

For the administrator user, please note that it gives the stage name BPF B, and for the other user, it gives the stage name BPF A.

 

Implications

  1. As compared to the first issue, this abnormal behaviour may cause some major implications. There is a wide variety of checks that a user might have placed on the active stage name. All those workflows need to be analysed; otherwise, it can cause major data issues in the environment.
  2. Some of the above workflows may be running for the entire organisation. However, with the concept of Active Business Process Flow per user, the implications for those workflows will need to be analysed.

C# SDK for returning active process and stage not working properly

I am quite confused if the first 2 are bugs or new features in Dynamics 365. But even if the first two can be discounted as features, this third issue surely implies that something seems to be incorrect in the concurrent BPFs.

The Model business process flows blog from Microsoft indicates that with Dynamics 365, the ProcessId and StageId fields present on the record are not to be used. Instead, we must modify the design to read active stage and process from the newly introduced APIs.

  1. For Client side scripting, the API functions defined in the article Xrm.Page.data.process (client-side reference)
    are available. If the first 2 are considered as Design changes, these API’s are working fine. That is, the API is returning the active process and stage based upon what each user is seeing on the record header.
  1. However the same cannot be said about the server side methods mentioned in Model business process flows. It clearly says that user must use the server side methods for retrieving the Active Process, Active Stage and progressing to the next stage.
    1. SetProcessRequest for setting the active process
    2. RetrieveProcessInstances for retrieving the active processes on the record and then using similar request for moving the record to the next stage. Mentioned below blog indicates that the active process records returned by the request will be in order of moifiedon date. Thus if there are multiple active processes on the same record, the first one will be the active business process which would be visible on the GUI.

Active BPF Issue After Migrating from Dynamics CRM 2016 to Dynamics 365

Here are the observations:

  1. I tried running the RetrieveProcessInstanceRequest for both the users. It was observed that the response was having same value of “ModifiedOn” date for both the records.
  2. Therefore, to one user, it seems it was giving the correct BPF, but to another, it was giving incorrect BPF.

Proposed Workarounds

Please note that as part of discussions with Microsoft Support, we were suggested the mentioned below workaround. I am still working on few workarounds to resolve the above mentioned issue, but the analysis is not yet complete.

  1. Writing an Action and then pre-validate plugin on that action. The first step would be to set the same BPF for all the users in the system. Depending upon other cases, there might be some instances where we need to set same BPF for just a particular team. Mentioned below is a pseudo code for the same.
    1. Create an action on account.
    2. Upon creation of the account, call the action.
    3. Write a prevalidate plugin on the created action.
    4. In the plugin, execute request “SetProcessRequest” for all the users in the system. It can be done by altering the context.userid value while creating the IOrganisationService request.
    5. This should set same BPFs for all the users.
  2. Writing a JavaScript client code to set the correct BPF for any new user.
    1. In case a new user is added in the system, there won’t be any logic to set correct BPF for all the records; therefore, a JavaScript client will need to be written to check the active BPF on the record. For the logged in user, if the BPF is different from what it should have actually been, execute client side API to set the correct BPF.
  3. Removing comparisons with stage name and process name. (Please note that it will only work for new records created in the system, after points 1 and 2 have been executed.)
    1. Remove any reference of Process stage name from the out-of-the-box workflow. Use the server side api provided (RetrieveProcessInstancesRequest) to retrieve the active process.
  4. For records migrated from CRM 2016 to Dynamics 365 and for which active process is not coming as expected, not sure if SetActiveProcess request will work. Maybe if it’s executed in context of all the users, it will set the correct process for all the users.

Concerns in the proposed workaround

  1. The custom code to execute SetProcessRequest for each user—depending upon the users present in the system—might turn out to be a very costly operation. In addition to it, JavaScript client code to update the active BPF for new users may introduce lots of custom code.
  2. I am not yet sure about how RetrieveActiveInstanceRequest will behave if a new user is added to the system. Even for new records which have not been migrated from CRM 2016, the API may start returning incorrect active process. (ModifiedOn date will be same for the active BPF’s.) A workaround would be to manually compare the Modified On date of all the processes and based upon the requirement, picking the correct one.
  3. There is no clear workaround strategy for records migrated from CRM 2016 to Dynamics 365. If SetProcessRequest is executed for all the users, it may set the correct BPF for that record for all the users. But as illustrated earlier, it may turn out to be a time consuming and costly operation.

 

Co-Author: Madhav Gorthi