(Quick Tip) Solution History in Dynamics 365

Another wonderful and utility post from my friend and fellow MVP Deepesh Somani

MSDYNAMICSBLOG BY DEEPESH

One of the pain points in Dynamics 365 Solution management was that developers or customizers would not have a trail of Solution history.

Well not any more. Dynamics 365 now provides solution history.

Lets first do some things and see the log which will remain

  1. Created a custom solution named Test and then deleted it:

Navigate to Settings-> Under Customization Select Solution History:

The log is being maintained as follows:

  1. Now lets try to export a solution named Test. The log is maintained as follows:

3. Lastly trying to import a solution named Test. The log is maintained here also:

Hope it helps and happy 365ing!

Any problem in CRM – end user,Microsoft  partner or an individual?

Problem Area – Technical, Functional, Training, Development or consulting?

I am here to help, get in touch here: Click here

ABOUT THE AUTHOR:

clip_image011

Twitterhttps://twitter.com/msdynamicsblog
LinkedInhttps://www.linkedin.com/in/deepesh-somani-00296932

Google Play Store:

https://play.google.com/store/apps/details?id=com.dynamicsofdynamicscrm.msdynamicsblog&hl=en

View original post

Advertisements

How do I move my word template for custom entity across environments in Dynamics 365? How can I make the changes manually? – A deep dive into inner workings

It was just another day at my office and my client’s developer just walked up to me and asked – “How do I move my document templates to one environment to another?”. He seems to have manually uploaded in the target environment but that is not showing up the data in the target environment environment when then word template is downloaded.

If you have worked on word templates, you know that this will not work as the custom entity object type codes are different between the source and the target environment. If you are new to word templates, please remember that the entity in your word templates are reference by their object type codes instead of their logical name. So even though you migrated the solution, the object type code of the custom entity will most probably be different and hence this would not work out in the target environment.

So I asked him to use the wonderful XRM toolbox which has the ability to do the same.

image

Worked like a charm like all other XRM toolbox plugins.

But the ordeal does not end here. Every now and  then I get a question – “Can you explain what’s happening underneath? Can I do it without using a tool? Can you tell me where the changes are being made”.

Honestly I am not in favour of not using an utility when it is available. But if you want to dig deep, continue reading. Or may be you are getting an error with the tool and this might just save your day.

We all know the word and the excel files are essentially zip files. I just save my word template with .zip extension.

image

Now since its a .zip file, I can unzip the same.

image

In the folder I search for the object type code which in my case is 10426

image

I just open the three files in a XML editor of my choice and then replace my the object type code 10426 with the new objectypecode of the custom entity in the target environment – 10341

I save the files. And then i select all the contents and then re-zip it.

image

And then change the .zip extension to .docx extension.

And finally when you upload the template in the target environment, it just works fine.

I am not sure when you would do this manually but if you want to really do it and go under the hood, here it is for you.

And sometimes when you get an error, this way may just help you out.

Debajit Dutta

(Dynamics MVP)

For consultation/ corporate training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com

Gotcha! Does Library name really matter while registering event handler in Dynamics 365

Registering an event handler for your form events or field events – Probably the most mundane stuffs that you would perform everyday if you a CRM consultant. But sometimes the simplest things have the greatest mysteries to unfold.

Now here I was in a training session emphasizing the importance of namespaces while you write your JavaScript files. And I was explaining how can putting the same method name in multiple files can actually lead to different event handler being called for your event instead of the desired event handler registered.

And then I get this question – “How is that possible? After all we specify the library name while specifying the event handler. Isn’t it?” Well the participants were pretty experienced in CRM and honestly I was also into split thought after I heard.

image

After all from the basic concept of the Javascript I know,  the first function which matches the name will be called. The best way to know something is trying and that’s what we did.

So I created two files here

file1.js with the below content

// JavaScript source code
function formLoad() {
    var alertStrings = { text: "Alert from file1.js", title: "Alert" };
    var alertOptions = { height: 200, width: 300 };

    Xrm.Navigation.openAlertDialog(alertStrings, alertOptions);
}

file2.js with the below content

// JavaScript source code
function HelloWorld() {
    var alertStrings = { text: "Alert from file2.js", title: "Alert" };
    var alertOptions = { height: 200, width: 300 };

    Xrm.Navigation.openAlertDialog(alertString, alertOptions);
}

Now comes the important part.

I go ahead to the form properties of the Lead form and register the below event handler.

image

Observe here carefully. I have put the file name to new_/scripts/file2.js and the function name I have put is “formLoadwhich is actually not there in the file2.js at all.  Also I have included the both the files in the form libraries as shown in the below screenshot.

image

Now when I open a lead record – Gotcha! I can see the alert

image

Even though I was handling participants who were pretty much experienced but believe me I could literally find an absolute taken aback expression once the alert dialog popped up. In the world of Power Apps and Azure, sometimes the tiniest and mundane stuffs actually leaves us in awe.

So this is one stuff. But what we get from it. Well now you understand that if we have the same method name in both file1 and file2 and you registered an onload event for the method in file1, there is no guarantee which method of which file gets called.

And that’s the whole I repeatedly stress on the use of namespaces while writing JavaScript files.

-Debajit Dutta

(Dynamics MVP)

For consultation/ training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com

Get Api Version Dynamically For WebApi Requests

Loads of my blog readers wanted to know..here is the perfect link to it.

Passion Dynamics

In this post I will quickly cover the requirement of dynamically getting API version of dynamics CRM in JavaScript rather then hard coding it , so that in next releases your JavaScript doesn’t breaks. I am referring to this:

1

For Dynamics CRM version 8.2 or below, do this:

var apiVersion = Xrm.Page.context.getVersion();

For Dynamics CRM version 9 or above, do this:

var apiVersion = Xrm.Utility.getGlobalContext().getVersion();

2

It will give you an expended version which includes minor and major versions. Now, all you have to is crop the number to get only initial number such as 9.1 in this case:

var shortVersion= apiVersion.substring(3, myStr.indexOf(“.”) -1);

then finally use it in your request as:

    req.open("GET",Xrm.Utility.getGlobalContext().getClientUrl()+ "/api/data/"+shortVersion+"/systemusers

Hope this helps!

View original post

{knowhow} Invoking an action from with EntityCollection Input parameter using WebApi in Dynamics 365

Xrm.WebApi methods introduced by Microsoft are great! But not much can be said about Xrm.WebApi.execute method which is used to invoke custom actions from client side code.

To be honest, ever since I have written blogs on Xrm.WebApi.execute like this one- https://debajmecrm.com/2018/07/20/calling-bound-actions-entity-actions-using-xrm-webapi-execute-in-dynamics-v9/, I have been getting huge number of questions on how this topic.

And one of the question that is coming time and again is – How do I pass an input parameter of type EntityCollection. I was baffled a bit as to why this question has popped up time and again but when I really go and search the docs and community, I really find very little information on the same and this answers my curiosity. Well, I have decided to pen this down. Actually it’s pretty simple but in case you don’t know, it can cost you days.

So I created an Action with two input parameters – one with Type entity reference and the other of type Entity Collection. Screenshot for reference.

image

The entity reference is of type Account as well. And in the entity collection also we are going to pass a collection of accounts.

So here is the call to the action which would work just fine.

var request = {};
request.entity = { entityType: "account", id: "475B158C-541C-E511-80D3-3863BB347BA8" };
request.EntRef = { "@account.id": "475B158C-541C-E511-80D3-3863BB347BA7" };
request.EntColl = [
    {
        "@account.id": "475B158C-541C-E511-80D3-3863BB347BA6", "name": "acc1", "@odata.type": "Microsoft.Dynamics.CRM.account"
    }
    ,
    {
        "@account.id": "475B158C-541C-E511-80D3-3863BB347BA5", "name": "acc2", "@odata.type": "Microsoft.Dynamics.CRM.account"
    }

];
request.getMetadata = function () {
    return {
        boundParameter: "entity",
        operationType: 0,
        operationName: "new_ActionProcess",
        parameterTypes: {
            "entity": { typeName: "mscrm.account", structuralProperty: 5 },
            "EntRef": {
                typeName: "mscrm.account",
                 structuralProperty: 5
            },

            "EntColl": {
                typeName: "Collection(mscrm.crmbaseentity)",
                structuralProperty: 4
            }

        }
     };
};

Xrm.WebApi.execute(request).then(
    function (result) {
        debugger;
    },
    function (error) {
    }
);

Highlighted the entity collection areas for easy readability.So as you can see, you need to pass the typeName as “Collection(mscrm.baseentity)”.

This is what we need to do. But the question is how did I find that I need to put this as the type name. After all this name is not something which can come out of intuition.

My suggestion here is, whenever you get stuck with names, fallback to the metadata.

I go to Settings –> Customizations – Developer Resources and download the OData Metadata. Once downloaded when I search for the action name this is what I find.

image

After that it’s just piece of cake.

Hope this helps and saves you some precious time.

-Debajit Dutta

(Dynamics MVP)

For consultation/ training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com

{knowhow} Sequencing Xrm.WebApi methods in Dynamics 365 leveraging JavaScript promise.

Come version 9.0 of Dynamics, Microsoft have introduced the Xrm.WebApi methods which have significantly eased out the task of making web api calls from the client side. However as we are all using this wonderful feature, many of us are unaware of the fact that these API’s are based on Javascript promises.

This article is not to explain what is JavaScript promise. Sharing this wonderful link in case you are unaware – http://www.javascriptkit.com/javatutors/javascriptpromises.shtml.

A great article to get started indeed.

OK. So let’s assume you are already aware of JavaScript promises. Let’s take a sample method to retrieve a record. Below is the Microsoft documentation for retrieving a record.

Xrm.WebApi.retrieveRecord(entityLogicalName, id, options).then(successCallback, errorCallback);

Concentrating on the highlighted part, the first question is – Is it absolutely necessary to define the then part of the API syntax? Can we just call Xrm.WebApi.retrieveRecord(entLogicalName, id, options) without the then part of it?

The answer is – It’s perfectly alright to call. the successCallback and errorCallback are just the event handlers when the promise is fulfilled or rejected.

Now the next part comes is – If it uses javascript promise, then it must allow sequencing. Surprisingly I have seen many implementations of Xrm.WebApi so far but I don’t see much of chaining example. Well, it can be done.

Let’s understand a scenario here. We perform a retrieve on accounts based on some query and then use the accounts to create a contact and set the parentcustomerid field to each accounts retrieved during the retrieve multiple call.

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name&$filter=accountcategorycode eq null").then(
    function success(result) {
         var ids = [];
        for (var i = 0; i < result.entities.length; i++) {
            var ent = result.entities[i];
             var accountId = ent.accountid;
            ids.push(accountId);
        }

        // pass the id’s to the next sequence
        return ids;
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
).
then(function (ids) {
    for (var x = 0; x < ids.length; x++) {
        var contact = {};
        contact["firstname"] = "sample";
        contact["lastname"] = "contact" + (x + 1);
        contact["parentcustomerid@odata.bind"] = "/contacts(" + ids[x] + ")";

        Xrm.WebApi.createRecord("contact", contact);
    }
});

Just focus on the highlighted part in green. As you can see here, in the successCallback of the retrieveMultiple, we first create an array of account id’s and then use the next sequence highlighted in yellow to process the Id’s and create a contact for each account retrieved. Also observe the createRecord call without the then part of it.

In this way you can chain methods as much as you want. Much better way to write than the nested callbacks.  

Hope this helps!

Debajit Dutta
(Dynamics MVP)
For consultation/ training visit
http://www.xrmforyou.com or reach out to us at info@xrmforyou.com

{knowhow} How to edit the Dynamics 365 App for Outlook screen

Recently there was a requirement to change the Dynamics 365 App for Outlook  screen. Basically when you set up the default App for Outlook, the Sitemap contains just the Activities and the Dashboards.

image

However the customer wanted to show the Accounts and some other custom entities there as well in the menu. So how do we include it?

It’s quite obvious that the change needs to be in the SiteMap. However how can I change the Sitemap of the App for Outlook screen? Strangely enough that’s one unexplored area and surprisingly even consultants working day in day out on CRM tends to miss out on this.

To modify the app UI, perform the below steps.

Open up your solution that you are working on and go to Model driven apps.

image

Add the Dynamics 365 App for Outlook app from the list of Apps.

image

Now it’s just like modifying any other app. I just quick edit the sitemap to include the account and then publish it.

Re-open the outlook and you could see your changes in there.

image

Easy wasn’t it?

Hope this helps.

Debajit Dutta
(Dynamics MVP)
For consultation/ training visit
http://www.xrmforyou.com or reach out to us at info@xrmforyou.com