Control Business Rules Order in CRM 2013


The CRM 2013 forms execute the scripts in the following order:

  1. System Scripts logic
  2. Custom Form Scripts logic
  3. Business Rules logic

Since the Business Rules logic is executed after Custom form scripts, hence any logic done in custom form script for a specific field will be overridden by the Business Rules logic for the same field. The developers/users should take care of this while trying to implement any logic for fields in both JavaScript file/s and Business Rules.

Moreover, there will be scenarios in which there are couple of Business Rules that needs to be executed in a specific order. So, the thumb rule to remember is to activate the Business Rules in the same order in which they need to be executed.

I hope this helps.

Microsoft CRM 2011 Rollup 15 Released on 07 October 2013


The details for the Rollup 15 can be found at

http://support.microsoft.com/default.aspx?kbid=2843571

The download link is:

http://www.microsoft.com/en-us/download/details.aspx?id=40346

Cheers,

Anubhav

Implement “Work On” and “Release” ribbon button on Entity form (Case)


I wanted to accept and release the queue items from the Case form but could not find any helpful resource.

The following steps will let the current logged in CRM user to accept / work on the case and release the case queue item.

1. Include json2.js and jquery.js on the Form library.

2. Create JavaScript web resource new_/Scripts/incident.js on the Case Form with the code given below:

function Accept_Issue(accept) {

var issueId = Xrm.Page.data.entity.getId();

var queueitemid = null;

var record = null;

$.ajax({

type: “GET”,

async: false,

contentType: “application/json; charset=utf-8”,

datatype: “json”,

url: Xrm.Page.context.getServerUrl() + “/XRMServices/2011/OrganizationData.svc/QueueItemSet?$filter=ObjectId/Id eq guid'” + issueId + “‘”,

beforeSend: function (XMLHttpRequest) {

XMLHttpRequest.setRequestHeader(“Accept”, “application/json”);

},

success: function (data, textStatus, XmlHttpRequest) {

record = data.d.results[0];

if (record != null) {

if (record.QueueItemId != null) {

queueitemid = record.QueueItemId;

if (accept) {

var objUser = null;

objUser = GetUser();

if (objUser != null && objUser.SystemUserId != null) {

record.WorkerId.Id = objUser.SystemUserId;

record.WorkerId.Name = objUser.FullName;

}

else

record.WorkerId.Id = Xrm.Page.context.getUserId();

record.WorkerId.LogicalName = “systemuser”;

record.ModifiedOn = new Date();

record.WorkerIdModifiedOn = new Date();

}

else {

record.WorkerId.Id = null;

record.WorkerId.Name = null;

record.WorkerId.LogicalName = null;

record.ModifiedOn = new Date();

record.WorkerIdModifiedOn = null;

}

record.EnteredOn = new Date(formatDatefield(record.EnteredOn));

record.CreatedOn = new Date(formatDatefield(record.CreatedOn));

if (queueitemid != null)

updateworkon(queueitemid, record, “QueueItemSet”, QueueItemUpdateCompleted, null);

}

}

data = null;

},

error: function (XMLHttpRequest, textStatus, errorThrown) {

errorHandler(XMLHttpRequest, textStatus, errorThrown);

}

});

record = null;

issueId = null;

}

function GetUser() {

var context;

var serverUrl;

var UserID;

var ODataPath;

var res = null;

context = Xrm.Page.context;

serverUrl = context.getServerUrl();

UserID = context.getUserId();

ODataPath = serverUrl + “/XRMServices/2011/OrganizationData.svc”;

var retrieveUserReq = new XMLHttpRequest();

retrieveUserReq.open(“GET”, ODataPath + “/SystemUserSet(guid'” + UserID + “‘)”, false);

retrieveUserReq.setRequestHeader(“Accept”, “application/json”);

retrieveUserReq.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);

retrieveUserReq.onreadystatechange = function () {

res = retrieveUserReqCallBack(this);

};

retrieveUserReq.send();

return res;

}

function retrieveUserReqCallBack(retrieveUserReq) {

var retrievedUser = null;

if (retrieveUserReq.readyState == 4 /* complete */) {

if (retrieveUserReq.status == 200) {

var retrievedUser = this.parent.JSON.parse(retrieveUserReq.responseText).d;

}

else {

alert(“Error in Fetching User data”);

}

}

return retrievedUser;

}

function formatDatefield(enton) {

return parseInt(enton.substring(enton.indexOf(“(“) + 1, enton.lastIndexOf(“)”)));

}

function QueueItemUpdateCompleted(data, textStatus, XmlHttpRequest) {

var mydata = data;

if (!Xrm.Page.getAttribute(“new_is_accepted”).getValue())

Xrm.Page.getAttribute(“new_is_accepted”).setValue(true);

else

Xrm.Page.getAttribute(“new_is_accepted”).setValue(false);

Xrm.Page.getAttribute(“new_is_accepted”).setSubmitMode(“always”);

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

}

function updateworkon(id, entityObject, odataSetName, successCallback, errorCallback) {

if (!id) {

alert(“record id is required.”); return;

}

else { id = encodeURIComponent(id); }

if (!odataSetName) {

alert(“odataSetName is required.”); return;

}

else { odataSetName = encodeURIComponent(odataSetName); }

if (!entityObject) {

alert(“entityObject is required.”); return;

}

var jsonEntity = window.JSON.stringify(entityObject);

$.ajax({

type: “POST”,

contentType: “application/json; charset=utf-8”,

datatype: “json”,

data: jsonEntity,

url: Xrm.Page.context.getServerUrl() + “/XRMServices/2011/OrganizationData.svc” + “/” + odataSetName + “(guid'” + id + “‘)”,

beforeSend: function (XMLHttpRequest) {

XMLHttpRequest.setRequestHeader(“Accept”, “application/json”);

XMLHttpRequest.setRequestHeader(“X-HTTP-Method”, “MERGE”);

},

success: function (data, textStatus, XmlHttpRequest) {

data = new Object();

data.id = id;

if (successCallback) {

successCallback(data, textStatus, XmlHttpRequest);

}

data = null;

},

error: function (XmlHttpRequest, textStatus, errorThrown) {

if (errorCallback) errorCallback(XmlHttpRequest, textStatus, errorThrown);

else errorHandler(XmlHttpRequest, textStatus, errorThrown);

}

});

}

function errorHandler(XMLHttpRequest, textStatus, errorThrown) {

if (XMLHttpRequest.status == 12029) { return new Error(“The attempt to connect to the server failed.”); }

if (XMLHttpRequest.status == 12007) { return new Error(“The server name could not be resolved.”); }

var errorText;

try

{ errorText = JSON.parse(XMLHttpRequest.responseText).error.message.value; }

catch (e)

{ errorText = XMLHttpRequest.responseText }

alert(“Error : ” + XMLHttpRequest.status + “: ” + XMLHttpRequest.statusText + “: ” + errorText);

error = null; XMLHttpRequest = null;

}

3. Create a field on the form (new_is_accepted Type: bool – two options) to track whether the form is in accepted mode.

4. Create Custom Ribbon buttons of “Work On” and “Release”. The code for RibbonDiff tag is given below:

<RibbonDiffXml>

<CustomActions>

<CustomAction Id=”sample.Form.incident.MainTab.QueueManagement.CustomAction” Location=”Mscrm.Form.incident.MainTab.Groups._children” Sequence=”15″>

<CommandUIDefinition>

<Group Command=”Mscrm.Enabled” Description=”$LocLabels:sample.Form.incident.MainTab.QueueManagement.Title” Id=”sample.Form.incident.MainTab.QueueManagement” Image32by32Popup=”/_imgs/ribbon/Actions_32.png” Sequence=”15″ Template=”Mscrm.Templates.Flexible2″ Title=”$LocLabels:sample.Form.incident.MainTab.QueueManagement.Title”>

<Controls Id=”sample.Form.incident.MainTab.QueueManagement.Controls”>

<Button Command=”samplesample.Form.incident.MainTab.QueueManagement.Accept.Command” Id=”samplesample.Form.incident.MainTab.QueueManagement.Accept” Image32by32=”/_imgs/Workplace/WorkOn_32.png” Image16by16=”/_imgs/Workplace/WorkOn_16.png” LabelText=”$LocLabels:samplesample.Form.incident.MainTab.QueueManagement.Accept.LabelText” Sequence=”20″ TemplateAlias=”o1″ ToolTipTitle=”$LocLabels:samplesample.Form.incident.MainTab.QueueManagement.Accept.ToolTipTitle” ToolTipDescription=”$LocLabels:samplesample.Form.incident.MainTab.QueueManagement.Accept.ToolTipDescription” />

<Button Command=”samplesample.Form.incident.MainTab.QueueManagement.Release.Command” Id=”samplesample.Form.incident.MainTab.QueueManagement.Release” Image32by32=”/_imgs/ribbon/ReleaseFromQueue_32.png” Image16by16=”/_imgs/ribbon/ReleaseFromQueue_16.png” LabelText=”$LocLabels:samplesample.Form.incident.MainTab.QueueManagement.Release.LabelText” Sequence=”30″ TemplateAlias=”o1″ ToolTipTitle=”$LocLabels:samplesample.Form.incident.MainTab.QueueManagement.Release.ToolTipTitle” ToolTipDescription=”$LocLabels:samplesample.Form.incident.MainTab.QueueManagement.Release.ToolTipDescription” />

</Controls>

</Group>

</CommandUIDefinition>

</CustomAction>

<CustomAction Id=”sample.Form.incident.MainTab.QueueManagement.MaxSize.CustomAction” Location=”Mscrm.Form.incident.MainTab.Scaling._children” Sequence=”10″>

<CommandUIDefinition>

<MaxSize GroupId=”sample.Form.incident.MainTab.QueueManagement” Id=”sample.Form.incident.MainTab.QueueManagement.MaxSize” Sequence=”10″ Size=”LargeMedium” />

</CommandUIDefinition>

</CustomAction>

<CustomAction Id=”sample.Form.incident.MainTab.QueueManagement.Scale.Popup.CustomAction” Location=”Mscrm.Form.incident.MainTab.Scaling._children” Sequence=”300″>

<CommandUIDefinition>

<Scale GroupId=”sample.Form.incident.MainTab.QueueManagement” Id=”sample.Form.incident.MainTab.QueueManagement.Scale.Popup” Sequence=”300″ Size=”Popup” />

</CommandUIDefinition>

</CustomAction>

</CustomActions>

<Templates>

<RibbonTemplates Id=”Mscrm.Templates”></RibbonTemplates>

</Templates>

<CommandDefinitions>

<CommandDefinition Id=”samplesample.Form.incident.MainTab.QueueManagement.Accept.Command”>

<EnableRules />

<DisplayRules>

<DisplayRule Id=”samplesample.Form.incident.MainTab.QueueManagement.Accept.Command.DisplayRule.ValueRule” />

</DisplayRules>

<Actions>

<JavaScriptFunction FunctionName=”Accept_Issue” Library=”$webresource:new_/Scripts/incident.js”>

<BoolParameter Value=”true” />

</JavaScriptFunction>

</Actions>

</CommandDefinition>

<CommandDefinition Id=”samplesample.Form.incident.MainTab.QueueManagement.Release.Command”>

<EnableRules />

<DisplayRules>

<DisplayRule Id=”samplesample.Form.incident.MainTab.QueueManagement.Release.Command.DisplayRule.ValueRule” />

</DisplayRules>

<Actions>

<JavaScriptFunction FunctionName=”Accept_Issue” Library=”$webresource:new_/Scripts/incident.js”>

<BoolParameter Value=”false” />

</JavaScriptFunction>

</Actions>

</CommandDefinition>

</CommandDefinitions>

<RuleDefinitions>

<TabDisplayRules />

<DisplayRules>

<DisplayRule Id=”samplesample.Form.incident.MainTab.QueueManagement.Accept.Command.DisplayRule.ValueRule”>

<ValueRule Field=”new_is_accepted” Value=”1″ Default=”false” InvertResult=”true” />

</DisplayRule>

<DisplayRule Id=”samplesample.Form.incident.MainTab.QueueManagement.Release.Command.DisplayRule.ValueRule”>

<ValueRule Field=”new_is_accepted” Value=”null” InvertResult=”true” />

<ValueRule Field=”new_is_accepted” Value=”1″ />

</DisplayRule>

</DisplayRules>

<EnableRules />

</RuleDefinitions>

<LocLabels>

<LocLabel Id=”sample.Form.incident.MainTab.QueueManagement.Title”>

<Titles>

<Title description=”Queue Management” languagecode=”1033″ />

</Titles>

</LocLabel>

<LocLabel Id=”samplesample.Form.incident.MainTab.QueueManagement.Accept.LabelText”>

<Titles>

<Title description=”Accept” languagecode=”1033″ />

</Titles>

</LocLabel>

<LocLabel Id=”samplesample.Form.incident.MainTab.QueueManagement.Accept.ToolTipDescription”>

<Titles>

<Title description=”Accept the Issue” languagecode=”1033″ />

</Titles>

</LocLabel>

<LocLabel Id=”samplesample.Form.incident.MainTab.QueueManagement.Accept.ToolTipTitle”>

<Titles>

<Title description=”Accept” languagecode=”1033″ />

</Titles>

</LocLabel>

<LocLabel Id=”samplesample.Form.incident.MainTab.QueueManagement.Release.LabelText”>

<Titles>

<Title description=”Release” languagecode=”1033″ />

</Titles>

</LocLabel>

<LocLabel Id=”samplesample.Form.incident.MainTab.QueueManagement.Release.ToolTipDescription”>

<Titles>

<Title description=”Release the Issue” languagecode=”1033″ />

</Titles>

</LocLabel>

<LocLabel Id=”samplesample.Form.incident.MainTab.QueueManagement.Release.ToolTipTitle”>

<Titles>

<Title description=”Release” languagecode=”1033″ />

</Titles>

</LocLabel>

</LocLabels>

</RibbonDiffXml>

5. The ribbon buttons call the Accept_Issue(accept) function and pass the Boolean value to the function. The ribbon buttons get displayed depending on the value of the Boolean field “new_is_accepted”. If the field value is “null” / “False” / “No” then only “Accept button will be displayed, otherwise for the field value “True” / “Yes” “Release” button will be displayed.

I hope the steps will give a quick start for the customizations and JavaScript code.

Microsoft CRM 2011 Rollup 14 Released on 11 July 2013


The details for the Rollup 14 can be found at

http://support.microsoft.com/kb/2849744

 

The download link is:

http://www.microsoft.com/en-us/download/details.aspx?id=39624

 

Cheers,

Anubhav

Critical Update for Microsoft Dynamics CRM 2011 (KB2855319)


A critical Update for CRM 2011 has been released on 26/7/2013.

The link is given below:

http://www.microsoft.com/en-sg/download/details.aspx?id=39691

Source: Microsoft

Implicit Shares in Microsoft CRM 2011


Excellent Article by Gareth. Must read article related to Implicit Sharing in Microsoft Dynamics CRM 2011…

GT // CRM

Microsoft CRM has a security model feature which is not well documented but can be of use when designing the security for your CRM implementation.   The concept is that with CRM configured a certain way you can ensure that child records created in CRM are automatically shared to the owner of the parent record.    A common place you might want to do this is with customer records (Contacts and Accounts) – where you might like any child records added to these records by other users to be always visible to the owner of that Customer record.   CRM utilizes Shares for this but these are hidden shares that you will not see in the CRM UI.   They do exist in the PrincipalObjectAccess (POA) table though.   Because Sharing is used, users are able to see records above and beyond what their security role permits.  i.e. A user’s security role may grant them…

View original post 774 more words

Next Newer Entries