In this post, I will briefly describe what is required to create a plug-in which will set the “Last Contacted On” field for Contacts and Accounts in Microsoft Dynamics CRM 2011. This functionality will allow CRM Users to keep track of customer follow-ups when Activities are completed in the system.
Firstly, I have created a new DateTime field called Last Contacted On which is displayed on the Account and Contact headers. Each time an Activity is completed where the Contact is a recipient or is set in the Regarding field, the system will automatically update the Last Contacted On field on the Contact and the related Account (if one exists).
The plug-in needs to be registered on the following triggers:• SetStateDynamicEntity (post, synchronous) – phonecall, letter, fax, appointment
SetStateDynamicEntity fires when the status of a record has changed - for example, when an Activity changes to a “Completed” state. DeliverPromote fires when an outgoing e-mail is tracked in CRM.
For our SetStateDynamicEntity trigger, CRM provides two important properties – EntityMoniker which is an EntityReference to the Activity, and State which is an OptionSetValue that allows us to get the new statecode of the activity. We only want to run the plug-in if the statecode has changed to “1” (Completed). We can obtain these two properties via the context.InputParameters collection.
Checking Recipients – E-mails
When the DeliverPromote trigger executes, the InputParameters collection doesn’t provide us with any useful information. Therefore we must retrieve the e-mail activity from the database using the following code snippet:
Entity email = _sdk.Retrieve("email", context.PrimaryEntityId, new ColumnSet("to", "cc", "directioncode"));
Next we can simply loop through the to and cc EntityCollection objects and check if the recipient is a Contact. You may also want to check the recipient e-mail address so you can prevent the plug-in from firing when sending e-mails to other staff within your organisation.
Checking Recipients – Other Activity Types
Most activity types in CRM 2011 make use of common fields and identical schema names for these fields which makes it easier to write code to execute across multiple entity types. For example, Phone Call, Fax and Letter all contain the to field which we can use to retrieve the recipient(s) for the activity.
EntityCollection to = activity.GetAttributeValue<EntityCollection>("to");
The Appointment entity is a special activity type so we need to check the requiredattendees and optionalattendees fields.
EntityCollection required = activity.GetAttributeValue<EntityCollection>("requiredattendees");
EntityCollection optional = activity.GetAttributeValue<EntityCollection>("optionalattendees");
We can apply similar logic as we have done with the e-mail activity and check if the recipient(s) are Contacts. Note that if the to, requiredattendees, or optionalattendees do not contain any data, we can check the regardingobjectid field instead.
EntityReference regardingRef = activity.GetAttributeValue<EntityReference>("regardingobjectid");
Now that we have identified the recipients which are Contacts, we can perform a simple update of these Contacts and set the Last Contacted On field.
If you want to request the source code for this plug-in, please contact us.