Sunday, May 22, 2011

Microsoft Dynamics CRM 2011 : How to send Email Notificaiton on Record Sharing?


Solution: Workflows are very useful in Microsoft Dynamics CRM 2011, can be used to send automated email messages, create, update, assign records etc.. but can only be triggered on record creation, status change, assignment, attribute change and deletion and what if it is required to trigger workflow on entity SDK message processing i.e. record sharing etc. For such requirements, i am taking an example of sending email notifications on lead record sharing, You can follow the steps below for sending email notification on lead record sharing.

1.    Create two new attributes in lead entity
    
     a. new_IsSharedRecord (Type = Bit/Two Options)
    
     b. new_LastSharedDateTime (Type = DateTime)

2.    Create plugin that will be triggered on “GrantAccess” message of lead entity and update “new_isSharedRecord”  attribute value to “True” and also store current system date time in “new_LastSharedDateTime”

3.    Create new workflow that will be triggered when “new_isSharedRecord” attribute value will be changed

4.    Check if attribute “new_isSharedRecord” = true then execute below steps

a.    Update attribute value “new_isSharedRecord” = false

b.    Send email message



[Plugin Code]


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Crm.Sdk;

namespace wod.Crm.LeadShareAlert
{
    public class wodPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            // Obtain the execution context from the service provider.
            Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
                serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

            IOrganizationServiceFactory wod_serviceFactory = null;

            IOrganizationService wod_CrmService = null;

            try
            {
                wod_serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                wod_CrmService = wod_serviceFactory.CreateOrganizationService(context.UserId);

                if (context.InputParameters.Contains("Target")
                && context.InputParameters["Target"] is EntityReference)
                {
                    switch (context.MessageName)
                    {
                        case "GrantAccess":

                            EntityReference wod_PluginEntity = (EntityReference)context.InputParameters["Target"];

                            if (wod_PluginEntity.LogicalName == "lead")
                            {
                                Entity wodLead = new Entity(wod_PluginEntity.LogicalName);

                                wodLead.Attributes.Add("leadid", wod_PluginEntity.Id);
                                wodLead.Attributes.Add("new_issharedrecord", true);
                                wodLead.Attributes.Add("new_lastshareddatetime", DateTime.Now);

                                wod_CrmService.Update(wodLead);
                            }

                            break;
                    }
                }

            }

            catch (System.Web.Services.Protocols.SoapException ex)
            {
                throw new InvalidPluginExecutionException(ex.Detail.InnerText);
            }
            catch (Exception ex)
            {
                throw new InvalidPluginExecutionException(ex.Message);
            }
        }
    }
}





Wednesday, May 18, 2011

Microsoft Dynamics CRM 2011 Plugin - How to Retrieve OptionSets Label Text

In Microsoft Dynamics CRM 4 it was easier to retrieve Picklist data labels in Plugins but in CRM 2011 as Picklist is replaced by OptionsSet and in plugin we can no longer retrieve Picklist label form the entity attribute property bag. The Plugin sample code below contains helper methods that can be used to fetch the OptionSet label value.

 [C# Plugin Code]


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;

namespace WOD.Crm.AutoNumbering
{
    public class wod_Plugin : IPlugin
    {

        public void Execute(IServiceProvider serviceProvider)
        {
            // Obtain the execution context from the service provider.
            Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
                serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

            // Obtain the CRM Service Factor and Organization Service Objects.
            IOrganizationServiceFactory wod_serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService wod_CrmService = wod_serviceFactory.CreateOrganizationService(context.UserId);

            // Checking if Input Target is Entity Object.
if (context.InputParameters.Contains("Target") &&
                    context.InputParameters["Target"] is Entity)
                {
                    // Obtain the target entity from the input parameters.
                    Entity entity = (Entity)context.InputParameters["Target"];

                    // 1st Parameter is CRM Service Object, 2nd is Entity Logical Name,  
                    // 3rd is OptionSet name and 4th is OptionSet value.  

                    string wod_labelValue = wodRetrieveOptionSetLabel(wod_CrmService, wod_Entity.LogicalName, "wod_date_position", 10231);
                }
        }

         // Method to retrieve OptionSet label value
        Private string wodRetrieveOptionSetLabel(IOrganizationService CrmWebService, string prmEntityName, string prmAttributeName, int prmOptionSetValue)
        {
            string wod_ReturnLabel = string.Empty;

            OptionMetadataCollection wod_OptionsSetLabels = null;

            wod_OptionsSetLabels = wodRetrieveOptionSetMetaDataCollection(ref CrmWebService, prmEntityName, prmAttributeName);

            foreach (OptionMetadata wod_OptionMetdaData in wod_OptionsSetLabels)
            {
                if (wod_OptionMetdaData.Value == prmOptionSetValue)
                {
                    wod_ReturnLabel = wod_OptionMetdaData.Label.UserLocalizedLabel.Label;
                    break;
                }
            }

            return wod_ReturnLabel;
        }

         // Method to Retrieve OptionSet Options Metada Data Collection.
        Private OptionMetadataCollection wodRetrieveOptionSetMetaDataCollection( IOrganizationService CrmWebService, string prmEntityName, string prmAttributeName)
        {

            OptionMetadataCollection wod_ReturnOptionsCollection = null;
            RetrieveEntityRequest wod_RetrieveEntityRequest = new RetrieveEntityRequest();
            RetrieveEntityResponse wod_RetrieveEntityResponse = new RetrieveEntityResponse();

            wod_RetrieveEntityRequest.LogicalName = prmEntityName;

            wod_RetrieveEntityRequest.EntityFilters = Microsoft.Xrm.Sdk.Metadata.EntityFilters.Attributes;

            wod_RetrieveEntityResponse = (RetrieveEntityResponse)CrmWebService.Execute(wod_RetrieveEntityRequest);

            foreach (AttributeMetadata wod_AttributeMetadata in wod_RetrieveEntityResponse.EntityMetadata.Attributes)
            {
                if (wod_AttributeMetadata.AttributeType == AttributeTypeCode.Picklist &&
                    wod_AttributeMetadata.LogicalName == prmAttributeName)
                {
                    wod_ReturnOptionsCollection = ((PicklistAttributeMetadata)wod_AttributeMetadata).OptionSet.Options;
                    break;
                }
            }

            return wod_ReturnOptionsCollection;
        }

    }
}