Skip Setting a Business process flow during record create in Dynamics 365/ CDS? This simple trick may help you

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

We all love Business Process flows. And why not? Their introduction have solved the age old problem of visualizing a record as and when it progress through multiple stages. Typically lead and opportunity moving through multiple stages, a product moving through multiple stages of development and numerous other examples can be cited.

And yet there can be scenarios where you need to skip applying business process when the record is created. Typical example may be bulk importing records from some other sources where you are not sure about what business process need to be applied and you want the decision to be left to end-users when they work with the respective records. Really there can be scenarios which you never thought.

I've never thought about it like that before | Honest about my faith

In scenarios like this, how do you plan to do the same. After all the default business process flow configured for an entity is automatically applied when you create new record for the entity.

We know for every entity there is a field called ProcessId. You may be wondering, isn’t it deprecated. Yes it is deprecated. However as much surprising it is, the same will come to help in scenarios like this.

All we need to do in this case is set the ProcessId field to Guid.Empty. That’s all.

And how are you going to do it. Well there can be many ways but in our scenario if it is bulk import, we can have a plugin in pre-operation stage where we will set the value of ProcessId to Guid.Empty.

Something like this shall work.

public class SetProcessIdToBlank : IPlugin
    {
       public void Execute(IServiceProvider serviceProvider)
       {
          var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
          var target = (Entity)context.InputParameters["Target"];

         target["processid"] = Guid.Empty;
       }
    }

And now the records shall be created without any Business process flow record.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Stop Assign functionality based on Business Logic using Client API in Dynamics 365

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

Assign – an age old functionality which is there since the time I started working in CRM which dates way back to 2011. So much we have seen about Assign that whenever I talk about Assign it’s like going back to our school days. But sometimes stuff from our school days we miss out which can be quite interesting when we discover it in our later years.

So here was this requirement. When a user clicks on the Assign and try to assign a record to a user or team, there should be some custom business validations based on which we will decide whether to go ahead with the Assign. If not then we will throw a custom message to the user.

So let’s see the tried and tested options and see why they won’t fit here.

Writing a plugin

For me it’s the best solution because it handles server side scenarios as well. However while the plugin shall still be there, the error dialog throw from plugins is not acceptable by the end-users here. They want more of like an alert dialog available in Dynamics 365.

Show hide the Assign button using enable rules

While this works, it is absolutely essential for this validation to be as real time as possible. Also the customer wanted that the end-user should understand why he/ she is not able to assign the record and then take corrective action.

So what’s the other way? We all know that when Assign operation is performed, the record is saved and any save event you have registered fires as well. And here is secret. There is a specific save code for Assign which is 47.

Using the specific save code we can understand whether Assign is currently being executed by the user and take necessary action.

function record_onsave(e) {
    var saveMode = e.getEventArgs().getSaveMode();

   if (saveMode === 47) { // assign
       // perform your custom logic here
       // and show alert using Xrm.Navigation.openAlertDialog if assign is invalid.

      // also you can stop the save using code below.
       e.getEventArgs().preventDefault();
    }
}

Using this simple trick you can actually handle your assign event. One very important point to note here. If you expose the owner field on the form and the end-user updates the owner field, that is not considered as Assign operation and would be treated as regular save (savemode = 1). So your above code shall fail.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Scope of getSharedVariable and setSharedVariable functions in Dynamics 365 Client API

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

These functions have been introduced way back in 2011 but till date I believe this is one of the least used features of Dynamics 365 Client API’s. And partly because of the fact their limited scope when it comes to sharing variables.

I wonder many may have tried it but had to move over to other methods because these methods didn’t meet their needs.

Nonetheless I get this question every time I do a technical training on Dynamics 365 – What are these API’s used for. So I decided to dedicate a blog for this. So let’s start with the Microsoft definition of setSharedVariable function to understand the scope.

Requirements Scope Statements — Business Analyst Learnings

“Sets the value of a variable to be used by a handler after the current handler completes.”

The first impression you get from this definition is – if you have multiple handlers for the onload event of a form and if I set a variable using setSharedVariable method, the other handlers for the same event shall get the value using getSharedVariable function.

function pageLoad(e) {
    console.log("Inside Page Load.");
    e.setSharedVariable("key1", "From pageLoad function.");
    console.log(e.getSharedVariable("key1"));
}

function f1(e) {
    console.log(e.getSharedVariable("key1"));
    e.setSharedVariable("key1", "From f1 function.");
}

function f2(e) {
    console.log(e.getSharedVariable("key1"));
}

So let’s look at the code above. We have three methods – pageLoad, f1 & f2. All these three functions I have registered on the onload event in order. So basically these are three handlers for the same onload event.

image

And then I set a variable using setSharedVariable function.

Now as you can see, I am trying to get the same value in functions f1 & f2.

Let’s see what’s the output.

image

As you can see, the shared variable is available inside the method pageLoad. However it is not available for functions f1 & f2.

So it’s kind of heartbreaking right! So where it is useful and what is the scope of the variable using setSharedvariable function.

I change my pageLoad function to below. As you can see, I am calling an async function to get the record details of an account. By the time, the account details are retrieved, the function have exited. However on-success of retrieve method I am trying to access the value back.

function pageLoad(e) {
    console.log("Inside Page Load.");
    e.setSharedVariable("key1", "From pageLoad function.");

   Xrm.WebApi.retrieveRecord("account", "a8a19cdd-88df-e311-b8e5-6c3be5a8b200", "?$select=name,revenue").then(
       function success(result) {
          console.log("Retrieved values: Name: " + result.name + ", Revenue: " + result.revenue);
          console.log("Printing Shared variable: ", e.getSharedVariable("key1"));

       },
       function (error) {
          console.log(error.message);
          // handle error conditions
       }
    );

}

And here is the output in the console. As you can see, I am still able to access this variable.

image

So if you have some async/ callback functions, these methods will work good for you. However if you trying to persist values across lifetime of the form or even pass data to multiple handlers of the same event, this does not work.

That limits the scope to a great extent. And now I guess you understand why it is used pretty less.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Configure conflict detection for mobile offline synchronization in Dynamics 365

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

In my previous article, I described in detail about Mobile Offline filters. Unlike the previous blog, this one is going to be real short. In this blog I am just going to discuss about a setting for conflict resolution when you have enabled Mobile Offline synchronization for your organization.

If you navigate to Advanced settings –> Mobile Offline, you will find an option – “Mobile Offline Settings”.

Once you click it, it basically opens the System settings –> Mobile client tab. There your have the below option.

image

By default, the value is set to No. So what is this conflict all about? When there is a mismatch of data between client and server, conflict errors occur.This setting help in resolution of these conflicts.

Suppose the user made some changes in offline mode and in the meantime the record has been modified on the server as well. If you set this value as No, the client wins over the server and whenever you go online, the changes made offline shall be synced. Client wins over the server.

If this setting is set to Yes, the server wins over the client and the offline changes are discarded if simultaneously the record the record has been changed on server as well.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Configuring Mobile Offline profiles in Dynamics 365 for Offline Sync on mobile devices

Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com

Trust me we all know about the offline feature of Dynamics 365 Mobile App. And if you ask even experienced Dynamics consultants on how to enable an entity for offline, the answer you get is you need to open the entity customizations and enable the below options.

image

In organization data download filter, you can define the filter criteria for data sync in mobile offline. So for the below filter, only accounts which are active and created in last 20 days shall be downloaded and available for mobile offline.

image

Till this point, almost everyone is aware. What is missed out is the Mobile Offline Profiles. Surprisingly it’s so much less discussed that many are not aware of it. But the fact remains that you need to create mobile offline profiles for users to configure filters that determine how much of an entity’s data (and related entities’ data) will be available to the user while offline.

So let’s see, how you can accomplish the same.

Go to Advanced Settings –> Mobile Offline

image

You may already find some profiles there but let’s start with a simple profile.

I enter a name for the profile – “Sample Offline Profile” and save the record. Here I will only show for account record. However you should do the following steps for all the entities which you want to enable for mobile offline sync.

Click on plus icon in “Mobile Offline Profile Item Details” to create a new Mobile Offline Profile item.

image

Observe I am using “All Records” as option here for data which will be downloaded. However one very important point here – The actual data available for mobile offline sync shall be the intersection of the filters specified in Offline Profile + Filter in organization data filter. If you remember the screenshot above, we have specified the filter there as active accounts created in last 2o days. Hence that shall be respected.

image

You have other options like “Other data filter” and “Custom data filter” using which you can specify custom filter rules.

I save the record. Now the “Mobile Item Profile Offline Association Details” grid becomes activated. In this grid, you can define the related data for account which can be enabled for mobile offline. For example, you want to download the active contact records for each account, we can define that using the below configuration.

image

You can create additional filters on the related records as well.

So we are all set for Account Entity here.

Now the final step is to assign users to this Offline profile. You can add users using the Users grid on the right.

The user “Chandana” is added to the profile. Please note that a user can be added to only one mobile offline profile.

image

And before I end, you remember the Organization data filters that you configured using the entity customization screen. Well, the same is present on the “Mobile Offline Profile Item” record for Account Entity that we just configured.

You can manage the same from here as well. Please note that to remove an entity from Mobile offline capabilities, you need to remove them from Mobile Offline filters where it is being referred.

image

Hope this helps!

Debajit Dutta

(Microsoft MVP)

How to get device location in Dynamics 365 for Mobile

Follow my blog for interesting topics on Dynamics 365, Portals and Power Platform.

The world is into mobile devices and Dynamics 365 is not left far behind. With unified interface, user’s are now getting seamless experience across all devices starting from web browser in desktop clients, to phones and tablets.

Dynamics 365 is well and try mobile now.

Dynamics 365 for phones, Power Apps, and Resco: What are the ...

And when you are in mobile platform, you may feel the need to know device location. And believe me, Microsoft have provided you an API which can give you just that. Following is the code to do that.

Xrm.Device.getCurrentPosition().then(
    function success(location) {
       console.log("Latitude", ":", location.coords.latitude);
       console.log("Longitude:", location.coords.longitude);
    },
    function (error) {
       console.log("error in determining location :", error.message);
    }
);

Please note that the above code will only run on mobile platforms (tablets & Phones). Trying to run it on Web browser in desktop will give you an error – “Operation is not supported by platform.”

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Where does Dynamics 365 Portals/ PowerApps portals store theme information when you change portal theme using PowerApps portal editor?

For training and consulting, write to us at info@xrmforyou.com

Recently I published a blog on the new preview feature for PowerApps portals where it allows you to change the portal theme from PowerApps portal editor. Check this here.

While I received quite a few queries on the same, one of the interesting questions I got is – “Where does Portals store the current theme that is selected? Can I change it without PowerApps portal editor?”

That left me puzzled a bit. Honestly I never thought on those lines.

question mark.jpg

Initially my hunch was Portals must be storing this internally. But somehow I kept the belief that like many other settings, this must also be a site setting which is maintained by the portal.

And finally it was there! The site setting name is “ThemeFeature”

image

To test it, I went ahead and changed the portal theme using PowerApps portal editor, the record is updated with the new “selectedThemeId”.

To me not a very useful information honestly but certainly better to know than not knowing it.

Hope this one helps!

Debajit Dutta

(Microsoft MVP)

Performing updates using alternate key in Dynamics 365 WebAPI and need to make sure it only updates and doesn’t create new record? Check this one out!

For training and consulting, write to us at info@xrmforyou.com

If you have used alternate keys in Dynamics 365 and tried to update using a record using WebAPI alternate key, you know the default behavior of how it works.For example, let’s see the sample code below.

// JavaScript source code

function UpdateRecord(e) {   

var fc = e.getFormContext();
    var serverURL = fc.getClientUrl();

   var request = new XMLHttpRequest();

   request.open("PATCH", serverURL + "/api/data/v9.1/contacts(emailaddress1='debajit.dutta@xrmforyou.com')", true);
    request.setRequestHeader("Accept", "application/json");
    request.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    request.setRequestHeader("OData-MaxVersion", "4.0");
    request.setRequestHeader("OData-Version", "4.0");
    request.onreadystatechange = function () {
       if (this.readyState === 4) {
          request.onreadystatechange = null;
          if (this.status === 204) {
             console.log("record updated successfully.");
          }
          else {
             var error = JSON.parse(this.response).error;
             console.log(error.message);
          }
       }
    };
    var data = {};
    data.firstname = "Debajit";
    data.lastname = "Dutta";

   var body = JSON.stringify(data);
    request.send(body);
}


Here an alternate key is created on “emailaddress1” field of the contact entity. And what I am trying is to update a record using alternate key. The email I am looking for here is – debajit.dutta@xrmforyou.com

You may be wondering – I already know the code

If you know it, you know as well that in the above code, if there is no contact with email address – debajit.dutta@xrmforyou.com, it will try to create a record, else it will update. However in my case, the requirement was to only update and not create. if there is no contact with the email provided, system should throw an error. Wondering how to do it?

Understand Png 7 » PNG Image #238843 - PNG Images - PNGio

It’s pretty simple trick actually. All you need to use one more header – If-Match.

In the code I will just add one more line

request.setRequestHeader("If-Match", "*");

This basically directs the upsert operation to work like a basic update and not update and insert.

Below error you will encounter if you now use the above code and try with an email that does not match for any contact in Dynamics 365.

image

Wondering  if there is any similar header for the upsert to work only with create and not update. Well, there is. The equivalent header is “If-None-Match”.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

Using classList() API in JavaScript to work with multiple classes for a HTML element.

For training and consulting, write to us at info@xrmforyou.com

Today I would like to show you the cool classList API which exists in the native JavaScript API but trust me, so many of us are still not aware of it.

Event I find people with somewhat significant experience of working with JavaScript is not aware of the same.

Well the classList() API allows you to manipulate multiple classes on a HTML element. Let’s try some demo here.

Let’s say we have a HTML div element with id – “main_div”. And you want to add multiple classes to the div element. Let’s see how you can work with those classes using classList() API.

const ele = document.querySelector(“#main_div”);

// You can add many classes here.

ele.classList.Add(“class1”, “class2”, “class3”);

While that’s nice, what’s even cool is the fact you can toggle classes using the toggle method of classList API.

// Remove a class

ele.toggle(“class1”, false);


// add a class

ele.toggle(“class1”, true);

Quite a cool and handy class to learn.

Hope this helps!

Debajit Dutta

(Microsoft MVP)

What is Developer extensions tab in WebFormSteps in Dynamics 365/ PowerApps portals? Is there any significance to it?

For training and consulting, write to us at info@xrmforyou.com

Recently I have been conducting a lot of training on PowerApps Portals. And every time when I start teaching WebForms, I get this question – What is the significance of Developer extensions in WebForm step.

If you are not able to relate, this is what I am talking about.

image

And trust me, this is the question I get in almost every training. And if you are not sure of what is that doing there on the form, you would likely to search a lunch break and expect participants to forget it. . What more worrisome, the documentation is not there even in the Microsoft Docs.

GIVE ME A BREAK! ~ Writers Guild Chuka University

Well if you are on this blog, then no more need to take a break. Developer extension tab is an old functionality from Legacy ADX studio portals. And the documentation is still in ADX community docs right here. What you could have done their previously is define a name for the event that could later be used in asp.net code for the webform to programmatically act on the events. Wit h PowerApps portals no longer supporting asp.net code changes the feature has been deprecated.

I am not sure why it is still there on the WebForm step form. But I believe it is a legacy carry over and would be removed at some later point of time.

Hope this helps!

Debajit Dutta

(Microsoft MVP)