Import managed solution with BPF prefix new_

There are some issues when you upgrade the Dev environment and you have custom Business Process Flows (BPF) and when you export the solution with that BPF as manage and import in the Test/Prod environment but it is giving an error. This is because the prefix of the BPF is with “new_” instead of the prefix of the solution.

 
There is a known article that explains how to solve the issue:

https://support.microsoft.com/en-us/help/4020021/after-updating-to-dynamics-365-mismatched-business-process-flow-entity

Following the steps will help you to overcome this issue without having to open a support ticket or running scripts directly in the DB.

Have in mind that these steps are to be performed in the sandbox that there isn’t any problem deleting the BPF so the records related to that are all deleted.

Hope this helps.

Advertisements

Business flows not switching by Workflow/Plugin

The problem is when you want to have a Business Process Flow (BPF) that changes automatically when a user changes a field, but that process flow is only changing to that user and not to the others.

For example:

When user1 changes the field, he can see the BPF changing after the reload of the form. When user2 looks at the same record, he can’t see the BPF changed.

This happens because the BPF’s in Dynamics 365  allows multiple processes to run concurrently against the same record and the process that is running for a user might not be the same to the other user.

To have a workaround that works, it is necessary to implement a JScript OnLoad calling that will set the active process in the record to the one that the user wants, for that it can be used Xrm.Page.data.process.setActiveProcess/setActiveProcessInstance.

If you want to know more about the new BPF and how it works, take a look at this post.

Hope this helps.

Use Workflow to fill a field with the stage name

As you might know, in the Opportunity entity there was a field that saves the text of each stage, but if you want that for other entities that field might not be available.
There was a way that worked until the version 8.2, where you build a workflow to run in the entity that you have the BPF and then save the Process Stage Name to the field that you created.
In the new version that isn’t working very well, from my tests it is only saving the previous stage name (the stage that was before the active).
Now to have the actual stage I had to do like this:

-With the next BPF from 8.2, this isn’t working well since it is only putting in the field the previous stage.
-To achieve the what you want, you need to create a workflow that is running in the BPF entity of the process, for example, Phone to Case Process.
-Create a custom field to save the text.
-You put the workflow in sync, then select to run when “Process is applied” and “Process changes” then you select the field “Active Stage Id”
-Then you insert the step Update Record, change it to “Incident Id (Case)” in the workflow and in the properties you add to the field that you want to save the text of the process. On the right options Look for: Active Stage Id (Process Stage) and then the field Process Stage.

It should look like this:

Moving between BPF stages programmatically

This is a simple code example that you can use to do move stages of a Business Process Flow (it can be improved, for example, to not have the stages id in the code). Also, I was using early bound class for this example. The field TraversedPath needs to be updated accordingly the stage that you are moving, so if you are going forward you need to add the stages, if you are going backward you need to remove the stages.

I have 3 Opportunities in the system:

  • Opp1 -> Stage1
  • Opp2 -> Stage2
  • Opp3 -> Stage3

And want to change the stages to:

  • Opp1 -> Stage3
  • Opp2 -> Stage1
  • Opp3 -> Stage2
try
{
   string connectionString = GetServiceConfiguration();

   CrmServiceClient conn = new CrmServiceClient(connectionString);
   _serviceProxy = (IOrganizationService)conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient : (IOrganizationService)conn.OrganizationServiceProxy;

   string fetchXml = @"";

   EntityCollection result = _serviceProxy.RetrieveMultiple(new FetchExpression(fetchXml));
   string processid = "3E8EBEE6-A2BC-4451-9C5F-B146B085413A";
   string stage1 = "6b9ce798-221a-4260-90b2-2a95ed51a5bc";
   string stage2 = "650e06b4-789b-46c1-822b-0da76bedb1ed";
   string stage3 = "d3ca8878-8d7b-47b9-852d-fcd838790cfd";
   foreach (Opportunity opp in result.Entities)
   {
      string id = opp.Id.ToString();

      Entity op = new Entity("opportunity");
      op.Id = opp.Id;

      if (opp.StageId.Value.ToString().ToUpper() == stage1.ToUpper())
      {
         op["processid"] = new Guid(processid);
         op["stageid"] = new Guid(stage3);
         op["traversedpath"] = new Guid(stage1.ToLower()) + "," + new Guid(stage2.ToLower()) + "," + new Guid(stage3.ToLower()).ToString();
      }
      if (opp.StageId.Value.ToString().ToUpper() == stage2.ToUpper())
      {
         op["processid"] = new Guid(processid);
         op["stageid"] = new Guid(stage1);
         op["traversedpath"] = new Guid(stage1.ToLower()).ToString();
      }
      if (opp.StageId.Value.ToString().ToUpper() == stage3.ToUpper())
      {
         op["processid"] = new Guid(processid);
         op["stageid"] = new Guid(stage2);
         op["traversedpath"] = new Guid(stage1.ToLower()) + "," + new Guid(stage2.ToLower()).ToString();
      }

      _serviceProxy.Update(op);
   }
}
catch (Exception ex)
{
   throw;
}