Customer field type query enhancement using a RetrieveMultiple plugin
In a previous post I discussed some of the issues and limitations when using the Customer field type. One of the issues I highlighted was that when viewing Recent Cases on the Contact it would only return Cases where the Contact was set as the Customer, not as the Primary Contact. Where the Contact could be listed as the Customer or Case Primary Contact two subgrids would be required (one for each relationship).
Now that I have finally emptied my fridge of leftover beer from Christmas I thought I would investigate whether it would be possible to display both of these in the same subgrid using a plugin on RetrieveMultiple of Case to intercept and amend the query before it is executed. It turns out it is indeed possible.
This will of course work for any entity that uses the Customer field type, not just Case. To use this for other entities simply register the plugin on RetrieveMultiple of the required entity (step 2).
Please note that the code below has little of no error handling in and was simply a proof of concept. It is certainly not ready for any production environments but will hopefully give others a starting point.
Steps to achieve this:
- Create a new plugin
using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using System; namespace LSD.Plugins.RetrieveMultiple { public class CaseQueryRetrieveMultiple : IPlugin { #region Secure/Unsecure Configuration Setup private string _secureConfig = null; private string _unsecureConfig = null; public CaseQueryRetrieveMultiple(string unsecureConfig, string secureConfig) { _secureConfig = secureConfig; _unsecureConfig = unsecureConfig; } #endregion public void Execute(IServiceProvider serviceProvider) { ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = factory.CreateOrganizationService(context.UserId); try { if(context.InputParameters.Contains("Query")) { QueryExpression objQueryExpression = (QueryExpression)context.InputParameters["Query"]; FilterExpression customerFilter = new FilterExpression(LogicalOperator.Or); FilterExpression otherFilters = new FilterExpression(LogicalOperator.And); FilterExpression combinedFilters = new FilterExpression(LogicalOperator.And); foreach (ConditionExpression condition in objQueryExpression.Criteria.Conditions) { if(condition.AttributeName == "customerid") { var recordId = condition.Values[0]; customerFilter.Conditions.Add(new ConditionExpression("customerid", ConditionOperator.Equal, recordId)); customerFilter.Conditions.Add(new ConditionExpression("primarycontactid", ConditionOperator.Equal, recordId)); } else { otherFilters.Conditions.Add(condition); } } combinedFilters.AddFilter(customerFilter); combinedFilters.AddFilter(otherFilters); objQueryExpression.Criteria = combinedFilters; } } catch (Exception e) { throw new InvalidPluginExecutionException(e.Message); } } } }
- Register this on Pre-operation of RetrieveMultiple on the incident entity
- Update the Step and View your subgrid
Now you can just display the one subgrid without missing any vital information.
This was originally posted here.
*This post is locked for comments