Business Rules in Microsoft Dynamics CRM 2013 – New feature introduction & basic facts

Microsoft Dynamics CRM 2013 comes with a new feature called Business rules. Business rules are “almost” a replacement for JavaScript client side UI scripting but only for 5 specific actions. Business rules feature is different Business Process Flows (or Business Processes) so don’t confuse the two. When CRM 2013 is released, it will only have 5 actions that can be done via CRM 2013 business rules. More actions and additional capability enhancements are expected in future updates of Dynamics CRM.

The five actions in the first release of Dynamics CRM 2013 are:

  • Set specific field value (including calculations and formulas),
  • Set business required state for a CRM attribute,
  • Set visibility of a field to visible or invisible (visible = false),
  • lock and unlock Dynamics CRM fields / attributes, and
  • Show an error message on a form if certain conditions are met.

The following Screenshot shows a sample business rule, its conditions and available actions:

Sample Business Rule with Conditions and Available Actions
Sample Business Rule with Conditions and Available Actions

More actions and capabilities expected in later updates but in the mean time, other functionality will need to be created using JavaScript UI similar to how it has been in previous Dynamics CRM version (2011, 4, etc.).

Some important facts, Basics and tips about Business rules in Dynamics CRM:

  • Business Rules work on all clients and devices whether it is Microsoft Dynamics CRM web client, outlook client, tablet, Safari or Dynamics CRM iOS and Android Apps.
  • Business rules are solution aware so they can be included in importing and exporting Dynamics CRM Solutions.
  • Setting a field value in a business rule allows the use of formulas to do calculations for applicable fields such as fields of type “Money”. Addition, subtraction, multiplication & division are the calculation operations available and can be done between fields or values. So for example: set “Total Box Value” field value to “Price per item” field multiplied by “24”. (assuming every box has 24 identical items for instance).
  • Business rules are just a process category similar to workflows and dialogs. It is not a complete replacement of JavaScript. It is written once, works everywhere.
  • Business rules can be customised on the Web and Dynamics CRM Outlook clients only.
  • Business rules are triggered by onLoad, onSave and onChange events.
  • Business rules are written in JavaScript for execution.
  • Always create business rules in deactivated mode.
  • Quick create form supports business rules. so if field is missing, business rule will not fire on quick create form.
  • Business rules will not execute if the field does not exist on the form, the business rule will not get triggered or fired.
  • You cannot call other JavaScript web resources or connect to external data sources from within the business rule.
  • Business rules that belong to the last installed CRM Solution will run last. no limit on the number of actions to attach in a business rule.

* Business rules can be configured and setup from any of the following locations:
1) Entity Customisations in Settings –> Customisations –> Entity –> Business Rules as shown in the following screenshot:

business_rules-1-EntityCustomisations2) On the Form customisation as shown in the next snapshot:

business_rules-2-FormCustomisations3) On the field (attribute) properties dialog, under the business rules tab (new tab in CRM 2013) as shown below:

business_rules-3-FieldProperities
4) In Settings –> Customisations –> fields customisations, open a field customisation form, you have Business rules for this field as shown in the following screenshot:

business_rules-4-FieldCustomisation

 

This new feature will save us from some JavaScript but it is by no means a replacement of JavaScript, yet. Looking forward for more available actions in business rules in next product updates.

What more actions do you think Business Rules should get? Any ideas or thoughts of how to improve this feature? Looking forward for your comments below.

Disabling Microsoft Dynamics CRM 2013 Auto Save feature for a specific entity form or a CRM organisation to avoid undesired execution of plugins or workflows

Microsoft Dynamics CRM 2013 comes with a new auto-save feature which triggers a save action on forms every 30 seconds (approx.). So if you are editing a form, an autosave is triggered automatically by CRM 2013 on regular intervals. This feature means that if you have a plugin or a workflow that first on saving the form, it will be triggered every time the auto save action is fired. This will obviously cause undesirable actions and potentially unexpected consequences to several processes especially in the case of an upgrade from Dynamics CRM 2011 to Dynamics CRM 2013.

To disable the Auto Save feature in Dynamics CRM 2013, you can stop it at organisation level which means NONE of your entity forms will have auto save across both customisable (System) and custom entities and their forms. To do this in Dynamics CRM 2013, you need to go Settings –> System Settings –> General Tab (first tab) –> Enable Auto Save on All forms –> No.

This is shown in the screenshot below:

Enable Disable Auto Save
Enable/Disable Auto Save feature in Microsoft Dynamics CRM 2013

 

Alternatively, if you want to allow Auto Save to work on some entities but not on others, you can write a small JavaScript web resource which can disable auto save on specific forms of your choice. This web resource JScript library can be enabled on selected forms of your choice.

To do this, you can call “GetSaveMode()” in client SDK to detect the auto-save. You can then call “preventDefault()” to write to the server to prevent the save. Here is the full script:

function preventAutoSave(econtext) {
 var eventArgs = econtext.getEventArgs();
 if (eventArgs.getSaveMove() == 70) {
 eventArgs.preventDefault(); 
 }
}

So here are the steps:

  1. Add the above function “preventAutoSave” as a web resource to your Dynamics CRM JavaScript library. Then,
  2. Add this JScript library to the form libraries of the form you want to disable Auto Save on.
  3. You should then register the function on the onSave event on this form you selected. Make sure you select the option to “pass execution context as the first parameter”.

This will stop auto save from triggering on this form. Repeat the same steps above for any form you wish to disable Auto-Save for.

For more information about Auto Save feature in Microsoft Dynamics CRM 2013 please check my other post which provides introduction to Auto Save functionality in #CRM2013 :

http://www.mohamedibrahim.net/blog/2013/09/29/basic-facts-introduction-to-auto-save-feature-in-microsoft-dynamics-crm-2013-msdyncrm-crm2013/

 

Converting Microsoft Dynamics CRM 4 JavaScript to Microsoft Dynamics CRM 2011 Javascript code converter

I have just seen this javascript converter tool and I thought I’ll let everyone know about it as it could be quite beneficial when upgrading Microsoft Dynamics CRM 4.0 to Microsoft Dynamics CRM 2011 including Javascript upgrade and changes.

This is the link for the tool. I haven’t tested it thoroughly myself yet, so please write your comments and reviews below to let everyone know how good this tool is:
http://bingsoft.wordpress.com/2010/09/09/crm-4-to-crm-2011-javascript-converter-tool/
http://crm2011scriptconvert.codeplex.com/

Hope this helps!

Get Current User Security Roles in Microsoft Dynamics CRM 4.0 on client side using JavaScript calls to CRM Service & API

In Microsoft Dynamics CRM 4.0, it is quite common that you want to call the CRM service from client side: i.e. Call the CRM service using JavaScript code that is located on the OnLoad, OnSave or OnChange events on a Dynamics CRM entity or field event.

The most common call is the call to CRM service to determine what roles the current user has.

The following function returns all roles of a specific user by creating a SOAP message request to the CRM Service:

//*********************
function GetCurrentUserRoles()
{
 var xml = "" +
 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
 "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
 GenerateAuthenticationHeader() +
 " <soap:Body>" +
 " <RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
 " <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\">" +
 " <q1:EntityName>role</q1:EntityName>" +
 " <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
 " <q1:Attributes>" +
 " <q1:Attribute>name</q1:Attribute>" +
 " </q1:Attributes>" +
 " </q1:ColumnSet>" +
 " <q1:Distinct>false</q1:Distinct>" +
 " <q1:LinkEntities>" +
 " <q1:LinkEntity>" +
 " <q1:LinkFromAttributeName>roleid</q1:LinkFromAttributeName>" +
 " <q1:LinkFromEntityName>role</q1:LinkFromEntityName>" +
 " <q1:LinkToEntityName>systemuserroles</q1:LinkToEntityName>" +
 " <q1:LinkToAttributeName>roleid</q1:LinkToAttributeName>" +
 " <q1:JoinOperator>Inner</q1:JoinOperator>" +
 " <q1:LinkEntities>" +
 " <q1:LinkEntity>" +
 " <q1:LinkFromAttributeName>systemuserid</q1:LinkFromAttributeName>" +
 " <q1:LinkFromEntityName>systemuserroles</q1:LinkFromEntityName>" +
 " <q1:LinkToEntityName>systemuser</q1:LinkToEntityName>" +
 " <q1:LinkToAttributeName>systemuserid</q1:LinkToAttributeName>" +
 " <q1:JoinOperator>Inner</q1:JoinOperator>" +
 " <q1:LinkCriteria>" +
 " <q1:FilterOperator>And</q1:FilterOperator>" +
 " <q1:Conditions>" +
 " <q1:Condition>" +
 " <q1:AttributeName>systemuserid</q1:AttributeName>" +
 " <q1:Operator>EqualUserId</q1:Operator>" +
 " </q1:Condition>" +
 " </q1:Conditions>" +
 " </q1:LinkCriteria>" +
 " </q1:LinkEntity>" +
 " </q1:LinkEntities>" +
 " </q1:LinkEntity>" +
 " </q1:LinkEntities>" +
 " </query>" +
 " </RetrieveMultiple>" +
 " </soap:Body>" +
 "</soap:Envelope>" +
 "";

 var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
 xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
 xmlHttpRequest.setRequestHeader("SOAPAction"," http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
 xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
 xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
 xmlHttpRequest.send(xml);

 var resultXml = xmlHttpRequest.responseXML;
 return(resultXml);
}
//*********************

 The following function checks if the specified user has a specified user role:

//*********************
function UserHasRole(roleName) {
    //get Current User Roles, oXml is an object
    var oXml = GetCurrentUserRoles();
    if (oXml != null) {
        //select the node text
        var roles = oXml.selectNodes("//BusinessEntity/q1:name");
        if (roles != null) {
            for (i = 0; i < roles.length; i++) {
                if (roles[i].text == roleName) {
                    //return true if user has this role
                    return true;
                }
            }
        }
    }
    //otherwise return false
    return false;
}
//*********************

The following code block uses the above function to do some logic based on user’s security roles:

if(UserHasRole("System Administrator"))
{
  //do something
}
else
{
   //do something else
}

Microsoft Dynamics CRM 4 field level validation using javascript regular expression on client side handling the onChange event to validate and check the value and text of a CRM 4.0 field

Please note that this post is aimed as showing how to use javascript regular expression field level validation in Microsoft Dynamics CRM. The post does not focus on the many ways of getting a regular expression. The example regular expression below is used for explanation only.

If you want to create validation at field level in Microsoft Dynamics CRM 4 to check the input value and text of a CRM field in an entity form, you can do this using regular expressions written in javascript code that handles the on change (onChange) event of this field at client side.

Below is an example of a regular expression but you might want to use your own regex value or search online for almost unlimited number of regular expressions that do just about anything.

For example, if you want to validate a CRM 4 field so that only a 4 digit year value starting from year 1980 is entered in the field text box, follow the following steps:

– Open the entity customisation form
– select the field you want to validate using javascript regular expression.
– Click on field properties, events tab and then open the onChange event.
– In the onChange event type the following javascript code (script) to handle the event and implement the field level validation:

//-----------------------------
//Regular expression ensuring a 4 digit year value is input starting from year 1980.
var reDate =/^(([1]{1}[9]{1}[8-9]{1}\d{1})|([2-9]{1}\d{3}))$/
//Check if the input value satisfies the regular expression condition
if (document.crmForm.all.new_yearfieldname.value.search(reDate)==-1)
{//if match failed
alert("Please enter a valid year value. Year value must be four digits starting from the year 1980")
crmForm.all.new_yearfieldname.value = '';
}
//-----------------

Another way of doing this is as follows;

//-----------------------------
var regexS = "^(([1]{1}[9]{1}[8-9]{1}\d{1})|([2-9]{1}\d{3}))$"; 
var regex = new RegExp( regexS ); 
var results = regex.exec( crmForm.all.new_yearfieldname.value);
if( results == null )   
{//if match failed
alert("Please enter a valid year value. Year value must be four digits starting from the year 1980")
crmForm.all.new_yearfieldname.value = '';
}
//-----------------------------

Hope this helps.

Hide tab in any entity form in Microsoft Dynamics CRM 4 using Javascript in onLoad event of the form.

In many cases, you might want to remove one of the tabs of an entity form in Microsoft Dynamics CRM 4. This can be specifically helpful in two cases:

1- If you want to hide and show tabs depending on a picklist value selection such as contact type: Hide Work details if contact is of type internal contact for example

2- If you want to hide the Administration and Notes tab from an entity form while these tabs are locked and cannot be removed from the entity form.

To hide a tab in an entity form, you can use the following Javascript sample script:

//---------------------------Hide a tab by passing tab name to the function
HideTab('Administration');
//replace "Administration" with your tab name
function HideTab (tabText)
{
 var tab = FindTab(tabText);
 if (tab)
 {
  tab.style.display = "none";
 }
}
function FindTab(tabText)
{
 var tabBar = document.getElementById("crmTabBar");
 if (tabBar)
 {
  var tabs = tabBar.childNodes;  

  for (var i = 0, len = tabs.length; i < len; i++)
  {
   var currentTab = tabs[i];
   if (currentTab.innerText === tabText)
   {
    return currentTab;
   }
  }
 }
}
//-----------------end of script--------

Maxjerin has added a new code suggestion. Maxjerin’s code hides a tab based on the onChange event of a field on the form. If the primary contact “name” field is maxjerin, the tab is displayed. Otherwise the tab is hidden.

I have updated the post to include Maxjerin’s code – Thanks Maxjerin:

Here is the code that I used to HIDE/UNHIDE a tab when I wanted to show it for only one particular user and hide for others. The code includes some alert messages just for debugging purpose which you might find useful to understand the code. You may remove them once done.

This section goes into the onChange section of the Primary Contact lookup field

if (crmForm.all.primarycontactid.DataValue == null )
{
var strTabStatus = TabStatus(‘Profile’);
if ( strTabStatus == ”)
{
alert(“Primary Contact none, hiding the tab”);
HideTab(‘Profile’);
}
}
else if (crmForm.all.primarycontactid.DataValue[0].name == ‘maxjerin’)
{
alert(“Primary Contact p f, unhiding the tab”);
UnHideTab(‘Profile’);
//replace “Administration” with your tab name
}
else if (crmForm.all.primarycontactid.DataValue[0].name != ‘maxjerin’)
{
var strTabStatus = TabStatus(‘Profile’);
if (strTabStatus == ” )
{
alert(“Primary Contact other than maxjerin, Hiding the tab”);
HideTab(‘Profile’);
}
}
function HideTab (tabText)
{
var tab = FindTab(tabText);
if (tab)
{
tab.style.display = “none”;
}
}
function UnHideTab (tabText)
{
var tab = FindTab(tabText);
if (tab)
{
tab.style.display = “”;
}
}
function FindTab(tabText)
{
var tabBar = document.getElementById(“crmTabBar”);
if (tabBar)
{
var tabs = tabBar.childNodes;
for (var i = 0, len = tabs.length; i < len; i++)
{
var currentTab = tabs[i];
if (currentTab.innerText === tabText)
{
return currentTab;
}
}
}
}
function TabStatus(tabText)
{
var tabBar = document.getElementById(“crmTabBar”);
if (tabBar)
{
var tabs = tabBar.childNodes;
for (var i = 0, len = tabs.length; i < len; i++)
{
var currentTab = tabs[i];
if (currentTab.innerText === tabText)
{
if (currentTab.style.display == ‘none’)
{
alert(“tab already hidden, TAB NAME: ” + currentTab.innerText );
return “none”;
}
else
{
alert(“tab is visible, TAB NAME: ” + currentTab.innerText );
return “”;
}
}
}
}
}
//-----------------------------------------------------------------------
Please comment below if you have any feedback or anything to add.
Thanks

Hide, Display, Resize and Rename left navigation links, CRM fields and attributes using Javascript for Microsoft Dyanmics CRM 4.

Scripts for Resizing, Hiding and renaming left navigation links, fields and attributes in Microsoft Dynamics CRM 4 using Javascript. This post is just a collection of some Javascript code for various common scripts that is frequently used in CRM form events, CRM entity events, etc. These script blocks can be used in OnLoad, OnSave events for CRM forms and OnChange events for CRM fields.

//------- Resize CRM form in the onload event
window.resizeTo(screen.availWidth * 0.85, screen.availHeight * 0.85);
//-------Rename left menu link / Left Navigation. Example: Contacts
var navItem = document.getElementById(’navContacts’);
navItem.innerHTML = navItem.innerHTML.replace(’>Contacts’,'>Students’);
//------Hide left menu link / Navigation. Example: Workflow
var navLeftItem = document.getElementById(’navAsyncOperations’);
navLeftItem.style.display = ‘none’;
//-----Hide Left navigation menu item link of a CRM form based on
// a value in a picklist on the same form.
//Get contacts left navigation menu item element.
var navLeftItem = document.getElementById(’navContacts’);
//if picklist (customer type code) value is equal to 1 (1st item in picklist) then
//hide left menu item (contacts link is used as an example), otherwise, show it.
if(crmForm.all.customertypecode.DataValue == 1)
{
 navLeftItem.style.display = ‘none’;
}
else
{
 navLeftItem.style.display = ‘inline’;
}
 //-----Hide a CRM field on a form. example: the "name" field.
crmForm.all.name_c.style.display = 'inline';
crmForm.all.name_d.style.display = 'inline';
//-----Hide a CRM field on a form (example: the "name" field)
//based on the selected value in a picklist
if(crmForm.all.customertypecode.DataValue == 1)
{
         crmForm.all.name_c.style.display = 'inline';
         crmForm.all.name_d.style.display = 'inline';
}
else
{
         crmForm.all.name_c.style.display = 'none';
         crmForm.all.name_d.style.display = 'none';
}  ////Add this code to the OnLoad event of the form and
////to the on change event of the picklist attribute (field) as well
//---------Function to hide CRM field in a form. 
//Function accept fieldname as a parameter and
//boolean parameter to remove (hide) entire row on form
HideField('name'); //replace "name" with your field/attribute name
 
function HideField( fieldName, removeEntireRow )
{
 // Always hide the elements, even if we will be hiding the whole row.
 // This allows us to show another field in this row later without this
 // one showing up.
 var elem = crmForm.all[fieldName + "_c"];
 if( elem != null ) elem.style.display = "none";
 elem = crmForm.all[fieldName + "_d"];
 if( elem != null ) elem.style.display = "none";     
 
 if (removeEntireRow)
 {
  var elem = crmForm.all[fieldName + "_d"];
  if( elem != null ) elem.parentElement.style.display = "none";
 }
}

 This post was written quickly from memory and some code blocks here and there, so you might find some minor spelling mistakes. Please comment below if you find any issues with the script blocks or if you want me to extend this post to include additional script.

Creating left navigation menu items (Links) to other entities on an entity form in Microsoft CRM 4

This is a short and quick post. If you have an entity and you want to add a link to the left hand side navigation menu of its form, then you can do this by one of two things:

1) Using ISV.CONFIG if this link is to an external website, application, etc.. This was discussed in more details in my post on using and editing ISV.CONFIG file

2) Creating a 1:N relationship between this entity and the entity you want to have a link for on the left menu bar.

So for example, if you want to have a link to all projects associated with an account in the account form, you will need to create a relationship between them. i.e. When you open an account form, you want to have a link to projects on the left handside navigation menu of the account form. To do this, you go to customisations, Account entity and in there, create a new 1:N relationship with your required entity (custom entity Project in this case). Create the relationship with Account as the primary entity and Project as the related entity. Save and publish the account form.

Now when you go and open any account record, you will see a link – submenu – item called projects on the left hand side of the Account form. If you click on it, it will allow you to add existing Projects (project records or whatever entity you selected) or you can create new project record.

You can of course apply this to any combination of entities whether customisable or custom.

To rename the left hand side menu navigation bar items, you can have a loo at my other two posts about renaming and hiding these items.

Thanks.

Hiding Left Navigation Menu Items in an Entity Form using Javascript in Microsoft CRM 4

This is just a follow on from my previous post (http://www.mohamedibrahim.net/blog/2009/07/30/renaming-left-menu-items-leftnav-entity-microsoft-dynamics-crm-4/). In this post, I explained how to rename left menu items in an entity form using javascript.

These links are created when a new N:1 relationship is created between two entities. The primary entity in this relationship will get a new left navigation link everytime a new N:1 relationship is created.

We have discussed in the previous post that the code to rename left menu navigation items (links to other N:1 entities) is:

var navItem = document.getElementById(’leftNavMenuItemID’);
navItem.innerHTML = navItem.innerHTML.replace(’>CurrentLinkValue’,’>NewLinkValue’);

So for example:

var navLeftItem = document.getElementById(’navContactsMenuItem’); // this will look for the element contact in the left menu of an account form
navLeftItem .innerHTML = navItem.innerHTML.replace(’>Contacts’,’>Employees’); //This will rename Contacts to Employees in the Account form

Now, to Hide specific links in the left menu, you can use the following script:

// Hide left menu navigation links on an entity form
var navLeftItem = document.getElementById(’navContactsMenuItem’);
navLeftItem .style.display = ‘none’;

This script will be in the OnLoad event of the form of the entity that you want to hide links created on the left handside of this entity form.

Renaming Left Navigation Menu items (leftnav) of an Entity in Microsoft Dynamics CRM 4

I will try to make this as simple and straight to the point as possible.

This post is to explain how to to change the name and rename one or more of the left menu items – leftnav – items of an Entity, for example the Account entity or the Contact entity or any other Custom entity. In summary, this should be done using a script in the onload event of the entity form and apparently can NOT be done using the Isv.Config file.

So for example, when you open an account record, on the left hand side of the Account form you will have the left navigation list of entities which are: Activites, History, Sub-Accounts, Contacts, Relationshiips, Workflows, Opportunities, Leads, Quotes, Orders, Invoices, cases, contracts, marketing lists and campaigns.

To rename any of these entities or any other custom entity has a 1:N relationship with the Account entity, you will need to put some javascript code (or script really) in the OnLoad event of the Account Form. This code will look for the name of the left navigation item (link to an entity) and rename it to whatever you want. You can not do this in ISV.CONFIG as you can only add new links to ISV.CONFIG but you can not edit already existing left menu items in this file as they don’t exist and are not displayed.

So, in the OnLoad event of the entity that you want to rename its left navigation menu items, you will need to put the fulling code (or something like it):

var navItem = document.getElementById(‘leftNavMenuItemID’);
navItem.innerHTML = navItem.innerHTML.replace(‘>CurrentLinkValue’,’>NewLinkValue’);

This code will look for the menu item that has an id (‘leftNavMenuItemID’) in your chosen entity form and replace its current link name to a new link name.

So for example:

var navItem = document.getElementById(‘navContactsMenuItem’);
navItem.innerHTML = navItem.innerHTML.replace(‘>Contacts’,’>Employees’);

If you input this code in the OnLoad event of the Account entity Form, this code will look for the “Contact” entity link in the left navigation and rename it from Contacts to Employees.

You can apply the same to any other entity either it is a customisable (system) or custom entity. You will need to use a HTML tool such as Microsoft’s Internet Explorer Developer Toolbar to find out the ID of the navigation item that you want to rename (‘navContactsMenuItem’).

Please let me know if you have a question or if you want me to clarify more.

Thanks,

Mohamed Ibrahim