Showing posts with label Ribbon Button. Show all posts
Showing posts with label Ribbon Button. Show all posts

Friday, 2 June 2017

How to assign a record to the current user via JavaScript

Recently I got a requirement from the customer to create a ribbon button on a custom entity so that a user can click on that button and get the record assigned to him/herself. You might wonder why create a ribbon button when we have the “Assign” button clearly. Reason is we need to do some web service calls to external systems too when user click on that button; so we needed a custom ribbon button.


I could achieve this easily by creating a JavaScript function like below to update the owner id and call this function on click of the ribbon button.


function AssignRecordToCurrentUser() {   
    var currentRecordId = Xrm.Page.data.entity.getId().replace("{", '').replace("}", '');
    var currentUserId = Xrm.Page.context.getUserId().replace("{", '').replace("}", '');       

    var entity = {};
    entity["ownerid@odata.bind"] = "/systemusers(" + currentUserId + ")";   
    var req = new XMLHttpRequest();
    req.open("PATCH", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_workitems(" + currentRecordId + ")", false); // my entity name is new_workitem
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");   
    req.onreadystatechange = function () {
        if (this.readyState === 4) {
            debugger;
            req.onreadystatechange = null;
            if (this.status === 204) {
                //Success - No Return Data - Do Something
            } else {
                Xrm.Utility.alertDialog(this.statusText);
            }
        }
    };
    req.send(JSON.stringify(entity));
} 

This works fine as long as the current user has got the write privileges to the entity. If the current user has read only rights this throws an exception. So when I was searching the web I found that we need to pass an additional parameter and impersonate the call. So I used the GUID of a system administrator like below.

function AssignRecordToCurrentUser() {
    var currentRecordId = Xrm.Page.data.entity.getId().replace("{", '').replace("}", '');
    var currentUserId = Xrm.Page.context.getUserId().replace("{", '').replace("}", '');

    var entity = {};
    entity["ownerid@odata.bind"] = "/systemusers(" + currentUserId + ")";
    var impersonateUserId = "A734DA29-7993-DE11-BECE-005056B47DB0";// GUID of the system administrator
    var req = new XMLHttpRequest();
    req.open("PATCH", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_workitems(" + currentRecordId + ")", false);// my entity name is new_workitem
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.setRequestHeader("MSCRMCallerID", impersonateUserId);
    req.onreadystatechange = function () {
        if (this.readyState === 4) {
            debugger;
            req.onreadystatechange = null;
            if (this.status === 204) {
                //Success - No Return Data - Do Something
            } else {
                Xrm.Utility.alertDialog(this.statusText);
            }
        }
    };
    req.send(JSON.stringify(entity));
}

But this did not work either. L

So I came up with another idea!!
I created an action to assign the record and then called that action from the JavaScript function. Here in this action I am passing the current user as an input parameter to the action.

My action looks like below:
















This is the parameter:














And the JavaScript to call the action is like this:

function AssignRecordToCurrentUser () {
    debugger;
    var currentRecordIdString = Xrm.Page.data.entity.getId();
    var currentRecordId = currentRecordIdString.replace("{", '').replace("}", '');
    var currentUserId = Xrm.Page.context.getUserId().replace("{", '').replace("}", '');
    var entityName = "new_workitem";

    ////using action
    debugger;
    var parameters = {};
    var currentuser = {};                                      
    currentuser.systemuserid = currentUserId;
    currentuser["@odata.type"] = "Microsoft.Dynamics.CRM.systemuser";
    parameters.CurrentUser = currentuser;

    var req = new XMLHttpRequest();
    req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_workitems(" + currentRecordId + ")/Microsoft.Dynamics.CRM.new_Assignworkitemtocurrentuser", false);
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.onreadystatechange = function () {
        if (this.readyState === 4) {
            req.onreadystatechange = null;
            if (this.status === 204) {
                debugger;
                //Success - No Return Data - Do Something
            } else {
                debugger;
                Xrm.Utility.alertDialog(this.statusText);
            }
        }
    };
    req.send(JSON.stringify(parameters));
}

Make sure you activate your action.
I hope this will help you!

Tuesday, 21 February 2017

Enable activity menu ribbon buttons for custom activity entities

Enable activity menu ribbon buttons for custom entities
If you have enabled activities for a custom entity in Dynamics CRM you might want those activities to be created from the ribbon menu without navigating; like this:


Then you have to follow these steps:
First install Ribbon Work Bench (you can download it from http://develop1.net/public/rwb/ribbonworkbench.aspx)
Then create a solution and include only the entity you want to add ribbon buttons.
Open ribbon work bench and open that solution you created.
There you have to add a command for each activity type. E.g. Email, Phone Call, Task, Appointment etc. No need to create any buttons. Commands will do the job.



Email Button:
Command Id: Mscrm.SendEmailPrimaryRecord


Action: Javascript Command
                Function Name: Mscrm.RibbonActions.addActivityOnForm
                Library: /_static/_common/scripts/RibbonActions.js
                Parameters: Int Parameter, Value: 4202





Display Rules:


 1.  Mscrm.AddActivityToPrimary


Id: Mscrm.AddActivityToPrimary
IsCore: False
Steps:



i)                    EntityPrivilegeRule
-          AppliesTo: PrimaryEntity
-          PrivilegeDepth: Basic
-          PrivilegeType: AppendTo

ii)                   EntityPrivilegeRule
-          EntityName: activitypointer
-          PrivilegeDepth: Basic
-          PrivilegeType: Create

iii)                 EntityPrivilegeRule
-          EntityName: activitypointer
-          PrivilegeDepth: Basic
-          PrivilegeType: Append

iv)                 EntityPropertyRule
-          AppliesTo: PrimaryEntity
-          PropertyName: HasActivities
-          PropertyValue: True

Mscrm.WriteActivityPermission



Id: Mscrm.WriteActivityPermission
IsCore: False
Steps:
i)                    EntityPrivilegeRule
-          EntityName: activitypointer
-          PrivilegeDepth: Basic
-          PrivilegeType: Write
EnableRules
       
   1.


Id: Mscrm.FormStateExistingOrReadOnly
IsCore: False
Steps:
i)                    OrEnableRule:





OrGroup 1


OrGroup2


   2. 




Id: Mscrm.AppendToPrimary
IsCore: False
Steps:




Follow the same pattern and create commands for each activity type. Only difference is the integer parameter value needs to be changed based on the activity type.


How to tackle Concurrent Business Process flows

Dynamics 365 has introduced the new feature of Concurrent Business Process Flows. Here is a couple of good articles on that: http://dev...