Thursday, March 19, 2009

Displaying a lookup with related entity fields




As you all know a CRM lookup displays its related entity primary field. Although this can not be changed using existing customizations; in most cases that suffices. However, there are occasions where you want to display more information in order to avoid opening the related entity form. One solution which I posted about was the lookup preview which builds a preview window for each lookup DataValue. I personally think it’s a great solution and we also have a wizard that facilitates the creation of the preview for us. This post offers a different solution which utilizes a plug-in that retrieves the extra information you wish to display and injects it inside the lookup text. The drawback of this solution is that the lookup can only occupy a certain amount of space. So you should consider expanding the lookup colspan before you use it.

The solution makes use of the post retrieve message on the incident entity. My goal in this demo is to show how to extend the customer lookup on the incident form so if you select an account the customer lookup will display the account name , number and primary contact and if you select a contact then the customer lookup displays the salutation , job title and company fields.

The solution is static but might give you a head start when other requirements of similar nature are in need.


using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;

namespace LookupTextPlugIn
{
public class LookupRetrieveHandler : IPlugin
{
#region IPlugin Members

public void Execute(IPluginExecutionContext context)
{
try
{
LookupRetrieveProxy plugin = new LookupRetrieveProxy(context);
plugin.Execute();
}
catch
{
}
}

#endregion
}

public class LookupRetrieveProxy
{
private IPluginExecutionContext Context;
private Customer Customer;
private DynamicEntity CustomerInfo;

public LookupRetrieveProxy(IPluginExecutionContext context)
{
this.Context = context;
}

public void Execute()
{
if (!Context.OutputParameters.Contains(ParameterName.BusinessEntity))
{
return;
}

DynamicEntity entity = (DynamicEntity)Context.OutputParameters[ParameterName.BusinessEntity];

if (!entity.Properties.Contains("customerid"))
{
return;
}

this.Customer = (Customer)entity.Properties["customerid"];
if ((this.CustomerInfo = RetrieveCustomer()) != null)
{
this.Customer.name = ChangeCustomerName();
}
}

private DynamicEntity RetrieveCustomer()
{
ColumnSet customerColumns = new ColumnSet();
switch (this.Customer.type)
{
case "account":
customerColumns.AddColumn("accountnumber");
customerColumns.AddColumn("primarycontactid");
customerColumns.AddColumn("telephone1");
break;
case "contact":
customerColumns.AddColumn("salutation");
customerColumns.AddColumn("jobtitle");
customerColumns.AddColumn("parentcustomerid");
break;
}

ICrmService Service = this.Context.CreateCrmService(true);

TargetRetrieveDynamic targetRetrieve = new TargetRetrieveDynamic();
targetRetrieve.EntityId = this.Customer.Value;
targetRetrieve.EntityName = this.Customer.type;

RetrieveRequest retrieveRequest = new RetrieveRequest();
retrieveRequest.ColumnSet = customerColumns;
retrieveRequest.ReturnDynamicEntities = true;
retrieveRequest.Target = targetRetrieve;

RetrieveResponse retrieveResponse = (RetrieveResponse)Service.Execute(retrieveRequest);
return retrieveResponse.BusinessEntity as DynamicEntity;
}

private string ChangeCustomerName()
{
StringBuilder lookupText = new StringBuilder();
lookupText.Append(this.Customer.name).Append(" ");

switch (this.CustomerInfo.Name)
{
case "account":
lookupText.Append(this.GetProperty("accountnumber")).Append(", ");
lookupText.Append(this.GetProperty("primarycontactid")).Append(", ");
lookupText.Append(this.GetProperty("telephone1"));
break;
case "contact":
lookupText.Append(this.GetProperty("salutation")).Append(", ");
lookupText.Append(this.GetProperty("jobtitle")).Append(", ");
lookupText.Append(this.GetProperty("primarycustomerid"));
break;
}

return lookupText.ToString();
}

private String GetProperty(string propName)
{
if (!this.CustomerInfo.Properties.Contains(propName))
{
return "";
}

Object property = this.CustomerInfo.Properties[propName];

if (property is String)
{
return property.ToString();
}
else if (property is Customer)
{
return ((Customer)property).name;
}
else if (property is Lookup)
{
return ((Lookup)property).name;
}

//not supproted
return String.Empty;
}
}
}

3 comments:

Anonymous said...

where do you use this code?
i pasted the code in the on load form and in on change customer events and it didn't work.
you use this code us is?

Adi Katz said...

The code is a plug-in (written in c# not js). You need to build it as a class library and register it with the plug-in registration tool.

Christian said...

Very nice, I plan to use this very soon. Thanks for sharing!

-Christian
www.crmdynamo.com