Friday, August 1, 2014

Configuring Business rules in CRM 2013

Business Rules let the system customizer apply conditional logic to a form. For using this feature, it not required to need any programming skills. This also helps to display error messages to the user that remind the users of the defined rules for a particular process. Such error messages prevent the user from saving a record until the issue is resolved.
When we create a business rule, we can apply the scope of the rule, it can be either to all forms, or just one form. If we want to apply a business rule to several forms and not all forms, we must create a copy of the rule for each form. Business rules will be enforced when the respective form is in use, irrespective of the platform, whether it is a browser, tablet or CRM for mobile applications.
Business rules are configured to apply client side logic to data in CRM 2013. This is instead of using processes or custom code that runs on the server, such as workflows or plugins. Business rules apply to data that a user enters or modifies in a form. A business rule must be activated before the logic in the rule takes effect.
Each active business rule that is associated with a specific form is evaluated when that form is loaded, or when the value changes in a field that is included in a condition that is defined in the rule. Business rules are not run again when a record is saved.
If a business rule includes a condition or an action that has a reference to a field that is not displayed on the form, the rule will not run, although an error is not created. It’s better to set non-event dependencies on a form to prevent other system customizers from removing a field without first removing the dependency.
The CRM for tablets client will only display the first 75 fields on a form. Therefore, any additional fields will not be displayed. We recommend that its made sure that all fields that are involved in the business logic that we have defined in Business rules are included in the first 75 fields on a form to avoid variable or unexpected behavior.
When we create a business rule at first its status would be draft and in this state it will not affect any other users. For testing, click the preview button on the ribbon to preview a version of the form. Activated rules and draft business rules are applied to the preview of the form. To apply the logic that is defined to the system, we must save the business rule before activating the same. While the rule is in active status we cannot delete or modify a business rule. For that first we have to deactivate the rule and then make the changes.
We must save the business rule at least once before we activate the rule. When we edit a rule that is already saved, only click save on the command bar if we change the name, conditions and actions would be saved individually.
For creating a similar rule like that of an existing rule, we can open the existing rule and then click on the save as button in the command bar. A new copy of the rule will be created, and we can make the required changes to the copy and then save the same.
If we make any changes to a field in the form using business rules, it will not reset the value automatically even if the condition is reverse now. For that we have to create another rule.
Adding a proper description to the rule is always recommended, which describes for what the rule is created and how it works or interacts with other rules.

Set the scope of a business rule

We can set the scope for the rule to all forms or select any one of the main or mobile forms. If we set the scope to any one form, we must create copies of the rule if we want to apply the rules to other forms, or we can change the scope to all forms if that is appropriate. In this case the rule will be applied to all forms of type Main or Quick Create. We cannot select the scope for a rule to apply only to the quick create form.

Conditions

Conditions define the fields that will cause the rule to be triggered, and the conditions to evaluate to determine whether the actions that are configured in the rule should be performed. We can add multiple conditions based on the same fields or different fields. All conditions must evaluate to “true” for the actions to be applied-this is a logical AND. We cannot do this for an OR.
When creating condition we can do this using the popular operators (=,>,<, or contains data). This depends on the data type of the selected field. Once the field and the operator is selected we have to select the condition type. There we have three options,
  • ·         Field: To compare the value of the selected form field to another field. This can be done only for those fields which are in the form and of same data type.
  • ·         Value: To compare the value with the value what we enter.
  • ·         Formula: This option is available only for those fields which are numerical or date data types. This type can be used to compare the result of a simple calculation that can use either a value from another form field or value that we enter.

Actions

In a business rule, we can add actions from one of the following options,
·         Show error message: To set an error message on a field if the data in the field is not valid. The text we specify for the message will be displayed with an error icon near the field. The record cannot be saved while this message is displayed. If a user clicks the save icon, the focus will move to the first field that is on the form that has an error. If we change a field so that the rule is triggered and reevaluated, and the condition is no longer true, the error will be dismissed.
  • ·         Set field value: Field value can be set in three different ways as did for conditions. If we use an action in the business rule to set the value of a field, the OnChange event handlers for that field will not run. So the JavaScripts configured for the onchange event will not be triggered.
  • ·         Set business required: Change the requirement level for the field. The options are Not Business Required and Business Required. There is no option to set this to business recommended.
  • ·         Set visibility: To change whether the field is displayed in the form. The options are show field and hide field. We cannot use this on sections or tabs.
  • ·         Lock or unlock field: To change whether the field is enabled in the form. The options are lock and unlock. Once the field is locked users cannot edit that field.


For the last three options we have to set the reverse rule to set the property back if the opposite condition is true.

Wednesday, May 21, 2014

CRM - Handling Plugin Messages

In CRM when creating we will be handling multiple messages. I am trying to put different approaches we have to take based on messages in a single place. 


  • Update

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
Entity entity = (Entity)context.InputParameters["Target"];

  • Associate/Disassociate

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
EntityReference entityReference = (EntityReference)context.InputParameters["Target"];
if (context.InputParameters.Contains("Relationship"))
{
string relationshipName = context.InputParameters["Relationship"].ToString();
if (relationshipName == "relationshipnametocheck")
{}}}

   Reference.                     

  • SetState/SetStateDynamicEntity

if (context.InputParameters.Contains("EntityMoniker") && context.InputParameters["EntityMoniker"] is EntityReference)
EntityReference entityReference = (EntityReference)context.InputParameters["EntityMoniker"];

If we have to trigger a plugin when a record status changes, its advisable to register the same for both tthe SetState and SetStateDynamicEntity. The reason why both the messages are required is both messages perform the same action in CRM and as there is not thumb rule for which action which message is fired, its better to register the plugin for both messages so that our plugin works properly. Reference.

Friday, May 9, 2014

CRM - Creating an email using REST endpoints

As a CRM developer everyone of us will undergo a scenario where now or tomorrow we may have to create an email record using REST endpoint. Its pretty easy that we can use any one of the REST approach and do that. But the challenge here is that REST endpoint does not support the party list. Because of this we cannot assign them to the email record which we create.

Solution for this is to create an activity (email) first and then create the a party list entity and link that to the created activity. To see how to do that we can refer to this simple but effective blog from "MS CRM Shop". 

Thanks team for this nice blog. 

Hope this helps !!!

Monday, May 5, 2014

CRM 2013 - Include Middle Name in contact's flyout control

By default, the contact's full name is populated as fly out control in CRM 2013. This will get reflected once the user enters the data and clicks on "Done" button.

The fly out control for the contact is based on the system settings. So if we need to make any changes to the fly out anchor the only way to do this right now is to change the system settings accordingly.

For example, by default the full name is set to have only first name and last name. If we need to have the middle name in the fly out control, include the middle name also in the contact name format under system settings.

For a detailed blog on this same subject please find it here.

Thanks Frank for such a nice blog. 




CRM 2013 - Composite Fields an overview

While trying to understand more on the composite control was able to see a blog in Community forums regarding the same. 

Thanks to the author for such a nice blog. 

Please read the same here.

Hope this help!!!


Saturday, April 26, 2014

CRM 2013 - Refresh and Save functions

In CRM 2013, we have got two different functions one for saving the form and refreshing the form. Advantage of these two are that they are asynchronous in nature which can do the other activities based on the result of this refresh or save. So for example if we need to call function1 if the refresh/save was successful and function2 otherwise its pretty easy now.

We will look at refresh first,
Xrm.Page.data.refresh(save).then(
                function () {
                    //Do something if the refresh is successful
                },
                function () {
                    //Do something if the refresh is unsuccessful
                }
                );
In the above example save is a boolean value which should be used to mention whether we need to save the form after it is refreshed. If true then the form will be saved and if not then the form will not be saved.

Next we will look at the save function.
Xrm.Page.data.save().then(
                function () {
                    //Do something if the save operation is successful.
                },
                function () {
                    //Do something if the save operation is unsuccessful.
                }
                );
In both the above cases the success call back will not have any arguments. It will simply be called if the operation succeeds. At the same time error call back will be having an object with properties:
errorCode: The error code.
message: A localized error message.

One more thing to be noted for these functions are that these two are available only for updated entities.

Hope this helps!!!

Sunday, April 20, 2014

CRM 2013 - Accessing Individual attributes in a composite control

In CRM 2013, the concept of composite attributes is introduced and when the field is used in the form only the composite control will be displayed in the form. When the user has to edit this field the constituent controls will be loaded in the form of flyout controls.

We can get the values of the composite controls using getValue but for setting the value we have to access the individual fields loaded to the form.

These individual forms can be accessed directly. The naming convention followed by such fields are as follows,

<composite control name>_compositionLinkControl_<constituent attribute name>

For example if we have to access address_line1 control in address1_composite use the below code,
Xrm.Page.getControl("address1_composite_compositionLinkControl_address1_line1")

CRM 2013 - Support for tablets

You will be already aware that CRM 2013 support the tablet environment as well. From a developer point of view we need to take care that the code which we are using will also work for the tablet environment. This is because the CRM for tablets does not allow any functions that can block the execution of the scripts. Normal javascript functions like alert, confirm and prompts will not work as we expect in tablets. They will simply throw errors.

If we need to show any message to the user working in tablets then we need to use the latest functions as part of CRM SDK instead of the alerts or prompts. We have to use Xrm.Utility.alertDialog and confirmDialog functions to display messages to the user.This is because these functions do not stop the processing of scripts until the user closes them.

Similarly below are some of the examples that will not work in tablets when using CRM,
  • Xrm.Page.context.getCurrentTheme
  • Xrm.Page.data.entity.getDataXml
  • Xrm.Page.ui.formSelector object methods
  • Xrm.Page.ui.navigation.items collection
  • Xrm.Page.ui.refreshRibbon
  • Xrm.Page.ui.ViewPort methods
  • Xrm.Page.ui.control Webresource and IFRAME control methods
  • Xrm.Page.ui.tab.setDisplayState
  • Xrm.Utility.openWebResource
If opened from the tablets these functions will simply execute an empty function and return nothing. If we expect a return value from these functions it will be undefined.

So if we are customizing in CRM for tablets then its better to distinguish between the code that will run in CRM tablets

It can be done by following below steps,
  1. Get the client type (Xrm.Page.context.client.getClient())
  2. If that is "Mobile" 
  3. Then do the coding for the tablets there
  4. Else do the coding for the normal CRM scenario.
Not only the above fields, CRM for tablets implement the composite fields also in a different way than how the web application implements it. Composite fields will be substituted by the constituent attributes and display them instead.

Similar is the case for Web resources and IFRAMEs. If our code interacts with such objects we can expect that the control will not exist in a tablet CRM environment.

If you are not sure which commands will work on tablets then include a command rule which will not include such commands. 

Wednesday, February 19, 2014

CRM - Adding an activity through code

There can be scenarios where we have to add activities programmatically to the CRM organization either through a plugin or through a workflow. Below is how we can achieve this.
 
Entity followupActivity = new Entity("phonecall");
followupActivity["subject"] = "Followup Phone call activity";
Entity activityPartyFrom = new Entity("activityparty");
activityPartyFrom.Attributes.Add("partyid", new EntityReference("systemuser", workflowContext.UserId));
followupActivity.Attributes.Add("from", new Entity[] { activityPartyFrom });
Entity activityPartyTo = new Entity("activityparty");
activityPartyTo.Attributes.Add("partyid", new EntityReference("lead", "Lead's Guid"));
followupActivity.Attributes.Add("to", new Entity[] { activityPartyTo });
followupActivity["scheduledend"] = DateTime.Now.AddDays(30);
service.Create(followupActivity);
 
 Here I am trying to add a phone call activity and assuming that this is from the workflow, workflowcontext used is the workflow context to get the owner of the activity. I am here trying to add a phone call and the entity should change according to our need. Due date is set to 30 days from today and the from is the user under which the workflow is running and to is a lead whose Guid we need to pass so as to set the To field.
 
Hope this helps !!!

Monday, February 17, 2014

CRM - Passing data between Plugins

When working with Plugins its quite natural to come across the scenarios where a data needs to be shared by two different plugins. This can be achieved using the shared variables. Below is how it can be done. In the plugin which is going to set the variable write the code as follows,
 
context.SharedVariables["UniqueName"] = "Data to be shared";
 
context is the plugin execution context. Now the data that needs to be shared is available in the shared variable UniqueName.
 
Next step is to consume the data available in the other plugin. For that first check whether the shared variable has the respective UniqueName. If available consume the data in it using the below code.
 
string uniqueName = (string)context.SharedVariables["PrimaryContact"];
 
All done. We have the data from first plugin in second one now. Enjoy !!!

Monday, February 10, 2014

WPF - Supressing Script Errors in WPF WebBrowser control

When Web sites hosted in Webbrowser controls are throwing JScript errors then we have to hide them. WebBrowser controls don't have the property to hide script errors so we have to handle it explicitly or we have to use WinForms WebBrowser control.
 
For the first approach we can use the below method in the browsers navigated event.

private void HideScriptErrors(WebBrowser webBrowser, bool hide)
{FieldInfo fieldInfo = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
if (fieldInfo == null)
return;
object objectWebBrowser = fieldInfo.GetValue(webBrowser);
if (objectWebBrowser == null)
return;
objectWebBrowser.GetType().InvokeMember("silent", BindingFlags.SetProperty, null, objectWebBrowser, new object[] { hide });
}

You can look at the original post here.

This worked for me. Hope it will for you as well !!! :)

Thursday, February 6, 2014

CRM 2013 - Create a SDK code project in Visual Studio

As a developer, there can be scenarios where we have to use CRM SDK in our code so as to connect to CRM and use the messages from SDK. To make sure our VS project is ready to use we have to follow some steps.

Even though the title says 2013 this is applicable to 2011 as well.
 

Prerequisites

Below are the prerequisites for the same.
  • Any Visual Studio (even the express edition works): CRM SDK is built on .NET 4.0 so even VS 2010 will work in this case.
  • CRM SDK: If CRM SDK is not installed on your computer, it can be downloaded from here (CRM 2011, CRM 2013).
  • Windows Identity Foundation: If you are using windows 8 or Windows server 2012, then we have to just enable already existing WIF. If you are using windows 7 or windows server 2008, we have install the WIF 3.5. For installing, download it from here.
 Once all the prerequisites are in place we can start creating a project which will interact with CRM from our code. Follow the below steps for achieving our target,
  1. Create a console application for either C# or VB according to our comfort level.
  2. Make sure the target framework is set to MS .NET framework 4.0. By default it will be client profile.
  3. Add all the required reference to our project. This includes below references.
    1. System.Data.Linq
    2. System.DirectoryServices.AccountManagement
    3. System.Runtime.Serialization
    4. System.Security
    5. System.ServiceModel
  4. Add the required SDK assembly reference as per our requirement. This is available from the bin folder of respective CRM version SDK.
  5. Add the required identity reference file. We can get this file from the file location in the system at Program Files\Reference Assemblies\Microsoft\Windows Identity Foundation\v3.5.
We are done with adding the references and now we are ready to go with our development activity.
 
For every project we have to do this. So its better if we can save this as a project template for our future references.
 
For detailed Microsoft documentation please refer the original site here.
Hope this helped everyone. :) !!!
 
 

Tuesday, January 21, 2014

CRM 2011 - Reflexive relationship must specify direction using ReflexiveManyToManyRelationship

When trying to retrieve data for reflexive relationship I was getting the exception which is the title of this post. How I was able to fix the same was by just using once line of code as below which will mention whether the role is referencing or referenced.
 
relationship.PrimaryEntityRole = EntityRole.Referencing;
 
where relationship is the object Relationship.
 
Hope this helped someone. !!!

Friday, January 3, 2014

Visual C# - Check operator

Check operator tells the runtime to generate an OverflowException rather than overflowing  silently when an integral expression or statement exceeds the arithmetic limits of that type.
The checked operator affects expressions with the ++,--,+,-,*,/ and explicit conversion operators between integral types. Checked can be used around either an expression or a statement block. For example:
int a = 1000000;
int b = 1000000;
int c = checked(a*b); //Checks just the expression.
checked  //Checks all expressions in statement block.
{
 ...
 c = a * b;
 ...
}
If we are using a compiler with the /checked command line then this will check all the expressions in the program.
In such a case if we need to disable overflow checking just for specific expressions or statements, we can do so with the unchecked operator. For example:
int x = int.MaxValue;
int y = unchecked (x + 1); //Leaves the expression from checking.
unchecked  //Leaves all the expressions inside the block from checking.
{
 int z = x + 1;
}
Against all the above statements let's say we have a constant expression then the overflow will be evaluated at the compile time itself unless we are applying the unchecked operator.
int x = int.MaxValue + 1; //Compile time error.
int y = unchecked (int.MaxValue + 1); //No errors.

Configuration for CRM Plugins

CRM plugins are always great feature where we can automate many functionality which we cannot automate from user interface. But almost eve...