LINQ: GroupBy, Sum and EntityCollection

Just resharing a sample code that could be used for group by and sum operation on EntityCollection.

Suppose below is the output that we want

Continue reading “LINQ: GroupBy, Sum and EntityCollection”

Execute js in synchronise mode

Repost with some minor change ..

One limit of the OData endpoint is that the response can only include up to 50 records, so if your result set has more records it’s necessary to reiterate the request using the url inside the __next property contained inside the returned object.

The following code shows how to fetch the request using synchronous calls, because sometimes you need (or want) to block the user 🙂

Continue reading “Execute js in synchronise mode”

Security roles JS updates

UCI has plenty of new features, one it is security roles fetch is very good one though did not creek. Good thing about it is, it will gives us all security roles along with its name in userSettings itself.

Here is code snippet of it

// Get Logged In User's Context
     var userSettings = Xrm.Utility.getGlobalContext().userSettings;
     // Get Logged In User Security Roles
     var loggedInUsersecurityRolesGuids = userSettings.securityRoles;
     var loggedInUsersecurityRoles = userSettings.roles;
     var isUserAdmin = false;
     for (var i = 0; i < loggedInUsersecurityRolesGuids.length; i++) {
     if (loggedInUsersecurityRoles._collection[loggedInUsersecurityRolesGuids[i]].name === "System Administrator" ||         loggedInUsersecurityRoles._collection[loggedInUsersecurityRolesGuids[i]].name === "*System Administrator")     
{ isUserAdmin = true; } }

if (isUserAdmin) {
//do something      
     }

Thanks.

Open dynamics record in dialog/Modal popup using navigateTo Client API

In 2020 Release Wave 1 Update for Dynamics 365 introduced navigateTo Client API to open main form of dynamics record in dialog instead Xrm.Navigation.openForm. This helps record to open in new window or same window of browser.

Also with the help of Xrm.Navigation.navigateTo, we can open custom HTML too and we can pass some parameters or accept return values in MSD 365 JavaScript too.

Below, we have provided information about how to open the CRM record in dialog. So to open new form for the entity is by below code snippet ..

var parameters = {};
             parameters["soft_para1"] = formContext.data.entity.getId();
             parameters["soft_para2"] = formKeyString;
             parameters["soft_para3"] = 1;

var pageInput = {
             pageType: "entityrecord",
             entityName: "soft_entityLogicalName",
             data: parameters,
             formId: "71ca9461-3209-4740-bd62-7320af2ae89c"
         };  


Xrm.Navigation.navigateTo(pageInput, { target: 2 }).then(
         function success() {
             //do something 
             //do something
         },
         function error() { }
     );

To open existing record use below code snippet

var pageProperty = {
                     pageType: “entityrecord”,
                     entityName: “contact”,
                     formType: 2,
                     entityId: “979dfe31-0686-ea11-a811-000d3a579c9c”//guid of record
                  };

var navigationProperty = {
                 target: 2,
                 width: { value: 80, unit: “%” },
                 position: 1
               };
Xrm.Navigation.navigateTo(pageProperty, navigationProperty);

Now, to show some custom html page

var dialogParameters = {
 pageType: "webresource",//required
 webresourceName: "ab_/ModalDialog.html",//Html Webresource that will be shown
 data: data//optional
};
 
var navigationOptions = {
 target: 2,//use 1 if you want to open page inline or 2 to open it as dialog
 width: 400,
 height: 300,
 position: 1//1 to locate dialog in center and 2 to locate it on the side
};
 
Xrm.Navigation.navigateTo(dialogParameters, navigationOptions).then(
 function (returnValue){
 //you can add handling of resultValue here
 console.log(returnValue);
 //put your success handler here
 },
 function(e) {
 //put your error handler here
 });

hope it helps.

Another good thing Navigation …..

We can show some HTML page here as well, we can pass parameters and accept some return value too using same above method.

Xrm.Navigation.navigateTo

Passing values to HTML page and accepting values in MSD 365 js which are passed from HTML page

function RestrictedCommand() {

    var pageInput = { //pass values to page 

        pageType: "webresource",
        webresourceName: "soft_modelpopup_restrict",
        data: "Incident"

    };

    var navigationOptions = {

        target: 2,
        width: 500, // value specified in pixel
        height: 250, // value specified in pixel
        position: 1

    };

    Xrm.Navigation.navigateTo(pageInput, navigationOptions).then(

        function success(returnValue) { //returnValue will return value from HTML page 

            switch (returnValue.returnValue) {

                case "883990000":                
                    window.close();
                    var ResValue = parseInt(returnValue.returnValue);
                    //your logic 
                    formContext.data.save();
                    break;

                case "0":
                    window.close();

                    //your logic
                    break;

                case "Cancel":
                default:
                    window.close;
            }

        },

        function error() {
            // Handle errors
        }

    );
}

Design your HTML page and pass values like below

<html>
<head>
    <title>Restriction reason</title>
</head>
<body onload="PoppupOnload()">
    
    <style>

        p {
            font-family: Calibri;
            font-size: 15px;
        }

        label {
            font-family: Calibri;
            font-size: 15px;
        }

        .select {
            font-family: Calibri;
        }

        .button {
            background-color: #0047b3;
            border: none;
            color: white;
            padding: 12px 29px;
            text-align: center;
            font-family: Calibri;
            text-decoration: none;
            display: inline-block;
            font-size: 15px;
            margin: 4px 2px;
            cursor: pointer;
            float: right;
        }
    </style>

    <script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
    <script>
        function SubmitClick() {

            var e = document.getElementById("soft_reason");
            var result = e.options[e.selectedIndex].value;

            if (result == "0") {
                openAlert("Please select correct reason or click on 'Cancel' button to cancel the action.");

            } else {
                window.returnValue = result;
                window.close();
            }
        }

        function CancelClick() {
            window.returnValue = "Cancel";
            window.close();
        }

        function PoppupOnload() {
            debugger;
            var queryString = location.search.substring(1);
            switch (queryString.split("=")[1]) {

                case "Incident":
                    document.getElementById("PersonMessage").style.display = "none";
                    break;
                case "Contact":
                    document.getElementById("IncidentMessage").style.display = "none";

                default: window.close();
            }

        }

        function openAlert(errormessage) {

            var alertStrings = { confirmButtonLabel: "OK", text: errormessage };

            var alertOptions = { height: 175, width: 350 };

            Xrm.Navigation.openAlertDialog(alertStrings, alertOptions).then(

                function success(result) {

                },

                function (error) {

                }

            );
        }
    </script>


    <p id="IncidentMessage">Please note that by restricting the Case record any child records like Goal, Action taken, General Assessment etc. will also be restricted. If you would like to continue then please provide the reason for restriction below:</p>
    <p id="PersonMessage">Please note that by restricting the Person record any open Case record associated to the Person will also be restricted. If you would like to continue then please provide the reason for restriction below:</p>


    <label for="dhhs_restrictionreason">Restriction reason:</label>
    <select class="select" name="dhhs_restrictionreason" id="dhhs_restrictionreason">
        <option value="0">--Select--</option>
        <!--<option value="883990000">Person known to staff</option>-->
        <option value="883990001">Sensitive case</option>
        <option value="883990002">High profile incident</option>
        <option value="883990003">Client request</option>
    </select>
    <br><br>
    <input type="submit" class="button" value="Cancel" onclick="CancelClick()">
    <input type="submit" class="button" value="Restrict" onclick="SubmitClick()">

</body>
</html>

it will look like this …

Hope it helps

Thanks!

Get the list of the dirty fields on the Dynamics 365

To quickly get the list of all the dirty fields

Open the debugger tool and put the following script in the console window

Xrm.Page.data.entity.getDataXml();

Get logged in user’s Security roles names in UCI

Here is sample code to get security roles name of logged in user.

function GetLoggedInUserSecurityRoleNames() {
 // Get Logged In User Context
 var userSettings = Xrm.Utility.getGlobalContext().userSettings;
 // Get Logged In User Security Roles
 var loggedInUsersecurityRolesGuidArray = userSettings.securityRoles;
 var totalSecurityRolesArray = new Array();
 var rolesOutputText = "";

if (loggedInUsersecurityRolesGuidArray.length > 0) {
 Xrm.WebApi.retrieveMultipleRecords("roles", "?$select=name,roleid").then(
 function success(result) {
 if (result.entities.length > 0) {
 // Push Role Names and Role Ids to Array
 for (var rolesCount = 0; rolesCount < result.entities.length; rolesCount++) {
 totalSecurityRolesArray.push({ RoleName: result.entities[rolesCount].name, RoleId: result.entities[rolesCount].roleid });
 }

rolesOutputText = userSettings.userName + " has the below Security Roles\n------------------------------------\n";

// Compare the User Security Roles with Total Security Roles
 for (var userSecurityRolesCounter = 0; userSecurityRolesCounter < loggedInUsersecurityRolesGuidArray.length; userSecurityRolesCounter++) {
 for (var totalsecurityRolesCounter = 0; totalsecurityRolesCounter < totalSecurityRolesArray.length; totalsecurityRolesCounter++) {
 if (totalSecurityRolesArray[totalsecurityRolesCounter].RoleId.toLowerCase() == loggedInUsersecurityRolesGuidArray[userSecurityRolesCounter].toLowerCase()) {
 rolesOutputText += totalSecurityRolesArray[totalsecurityRolesCounter].RoleName + "\n";
 break;
 }
 }
 }
 }

// Show User Roles
 Xrm.Utility.alertDialog(rolesOutputText, null);
 },
 function (error) {
 // Show error
 Xrm.Utility.alertDialog(error.message, null);
 });
 }
}

Duplicate workflows in advanced find – CRM 365

While searching for the process in the Advanced Find of my MS Dynamics CRM 365 environment, I noticed that several “duplicates” of the process appeared. Although they had the same name, some of them were in Draft Mode and two were Active. One curious thing that I saw was few processes are same logic and steps, also, whenever I did a change in one of my Active workflow/business rule, the other was replicating the change. This made me had a hard time trying to figure out what was happening, specially because after searching the duplicates in the Default solution to delete them, only one appeared.

Continue reading “Duplicate workflows in advanced find – CRM 365”

Activate-Deactivate Plugins/Process with code

while deploying our customisation to target environment many times we need disable/deactivate plugins and or process. Manually, its straight forward but what about when you are working with DevOps or you cannot touch target environment. In such environment, we need to handle it with code. So for that here are the steps …

Continue reading “Activate-Deactivate Plugins/Process with code”

System jobs in Dynamics

For DevOps, we have to handle each and everything from code behind and in automated way. Thus, wrote code to create manage System jobs to delete records every night in Dynamics. Here are the main points from my understanding ..

The BulkDeleteRequest message will create a bulk delete job that will be automatically executed on a specified interval for a specified set of data.  The job will be executed by the CRM Asynchronous service.

Continue reading “System jobs in Dynamics”

Pass parameter to RDL

Sometime we need to send parameter dynamically to SSRS report, to achieve it below JS function will help … here key thing is “&p:”, whatever next to this one will be considered as parameter, e.g. “&p:parameterName=parameterValue”. You can pass more than one parameters too.

Continue reading “Pass parameter to RDL”