Thursday 19 July 2018

Filter Activities based on users

Filter Activities based on User


                                Recently I got a requirement to filter emails in activities tab based on users. By default in Activities pane, it will show all emails regarding the current record. So there is no OOB functionality to achieve. And unfortunately, apply a custom filter on Activities pane using JavaScript also not possible as it's not a grid. So we need to register a Plugin on Retrieve Multiple.

How Query looks like?
                                
                              Here in Activities, we only will get Activity related information.so we need to Link related entity of ActivityParty. In this entity, we will get only two fields which are Participation Type and Party. Here Participation Type can be From/To/CC/BCC. This will be based on your requirement. Party is the MultiLookup which you can choose All Entity Records which entities allowing Emails in Communication & Collaboration section while creating an entity. This Acts as Activity Party.

                                By default, CRM will have a Plugin Step Retrieve Multiple. So either we can append our custom query or we can completely remove existing CRM query and add our custom query. But appending our custom query will be the best practice.

Here is the Query

QueryExpression qe = (QueryExpression)Context.InputParameters["Query"];
                    LinkEntity linkEntity = new LinkEntity("activitypointer", "activityparty", "activityid", "activityid", JoinOperator.Inner);

                    linkEntity.LinkCriteria.AddCondition(new ConditionExpression("partyid", ConditionOperator.Equal, Context.InitiatingUserId));

                    FilterExpression filter1 = new FilterExpression(LogicalOperator.Or);
                    //filter1.Conditions.Add(
                    filter1.Conditions.Add(new ConditionExpression("participationtypemask", ConditionOperator.Equal, 2));
                    filter1.Conditions.Add(new ConditionExpression("participationtypemask", ConditionOperator.Equal, 3));
                    filter1.Conditions.Add(new ConditionExpression("participationtypemask", ConditionOperator.Equal, 4));
                    linkEntity.LinkCriteria.AddFilter(filter1);
                    qe.LinkEntities.Add(linkEntity);
                    Context.InputParameters["Query"] = qe;
                   
As explained, the above query will retrieve activities where Participation Type will be either To/CC/BCC. I am showing emails to the user whether he involves any of the above participation types. And Party should be User and who is calling this Plugin. So who is new to CRM should care that while registering your step you need to select Run in Users context as Calling User.


Here is the full code:

public void Execute(IServiceProvider serviceProvider)
        {
 
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
            QueryExpression qe = (QueryExpression)Context.InputParameters["Query"];
            AppendLog("Activity.Retrieve Multiple-Started");
            if (qe.EntityName == "activitypointer"&& Context.MessageName == "RetrieveMultiple")
            {
                FilterActivities(userService);
               
            }
            AppendLog("Activity.Retrieve Multiple-Finished");
        }


public void FilterActivities(IOrganizationService service ,IPluginExecutionContext Context)
        {
            try
            {
               
                if (Context.InputParameters["Query"] is QueryExpression)
                {

                    QueryExpression qe = (QueryExpression)Context.InputParameters["Query"];
                    LinkEntity linkEntity = new LinkEntity("activitypointer", "activityparty", "activityid", "activityid", JoinOperator.Inner);

                    linkEntity.LinkCriteria.AddCondition(new ConditionExpression("partyid", ConditionOperator.Equal, Context.InitiatingUserId));

                    FilterExpression filter1 = new FilterExpression(LogicalOperator.Or);
                    //filter1.Conditions.Add(
                    filter1.Conditions.Add(new ConditionExpression("participationtypemask", ConditionOperator.Equal, 2));
                    filter1.Conditions.Add(new ConditionExpression("participationtypemask", ConditionOperator.Equal, 3));
                    filter1.Conditions.Add(new ConditionExpression("participationtypemask", ConditionOperator.Equal, 4));
                    linkEntity.LinkCriteria.AddFilter(filter1);
                    qe.LinkEntities.Add(linkEntity);
                    Context.InputParameters["Query"] = qe;
                    return;
                }
            }
            catch (Exception ex)
            {
               
                throw;
            }
        }

Plugin step Details
Message Name: Retrieve Multiple
Event Pipe Line Stage: Pre-Operation
Primary Entity: Activity Pointer

Why Pre Create?

As I already mentioned, for every entity CRM will have to Retrieve Multiple Step and whenever we want to use advanced find then based on the query we passed, it will call the Plugin Step with the provided query. So before the operation of Plugin Step completed, we need to inject our query also. So this can be possible before the operation. So we need to register on Pre-Operation.

                Once we registered this Plugin and open any record which is having Activities Pane, you can see his related Activities only.


Hope it Helps!

2 comments:

  1. Recently i have faced this requirement,From this post i have got the solution.Thank You so much.

    ReplyDelete
  2. Thanks for sharing this.It helps me lot

    ReplyDelete