Tuesday, October 29, 2013

Filtering activities by type in CRM views

In some scenarios you might want to wish to filter your activity views by activity types. While it sounds very trivial it can be a bit more complex in the context of solutions because activity type is stored as objecttypecode (OTC) which is different in each environment for custom activities.

 

Scenario

I defined a custom activity called “Follow-up” and I would like a view/sub-grid in the account form which shows me all the related Follow-ups to the account (I don’t want to see any other activity there). I also don’t want to create an additional relationship between Account and Follow-up but rather use the generic “Regarding” lookup that is used by all custom activities.

 

Solution #1

I can simply define or edit an existing view and use the field “Activity Type” (activitytypecode) to filter and show only the activity type that I desire:

image

After I do this I can use my view in a sub-grid and voila, very simple, I now have a sub-grid in the form which displays related activities but only those of type “Task” and “Follow-up”:

image

 

The problem with solution #1

The problem now is that when I transport this view and form to QA/Prod or to another CRM organization, it might break. The reason is that the view uses the activitytypecode field to filter on activity type. This field references an objecttypecode (OTC) which is a unique number given to each entity. For system entities (task, accounts, etc) the OTC is the same in all environments. However, for custom entities, new OTCs are assigned incrementally so there is no guarantee that they are consistent across environments. In my dev environment, this is what my view definition looks like in the exported solution:image

While I can be sure that 4212 is always “task” in all environments, I cannot be sure that 10007 is my custom activity “Follow-up'” in all environments. In fact, an entity with OTC 10007 might not even exist in other environments, even if my custom “Follow-up” entity does exist (but with a different OTC).

 

Solution #2

If I would like to avoid my solution referencing a hard-coded OTC, I can use linked-entity in my view as a work-around. However, I cannot edit the views in the view designer of the application because it does not support joins. I would need to export my solution and edit the view XML in the solution file and then import it back. I will update the XML of the view I defined above in order to retrieve all tasks and follow-ups but without using the activitytypecode attribute:

image

Note that there is no reference to any objecttypecode in the view definition above, but it will automatically filter to show only activities of type new_followup because of the inner join. In order to update the view XML you will need to include the Activity entity to a solution, export the solution and then look for your view in the customizations.xml file and update the view definition fetchxml.

The problem with solution #2

Although solution #2 will work in all environments and will not break even if you transport the solution to another organization (as long as the new_followup entity exists), there are some disadvantages of this approach: First, the view filter criteria cannot be edited using the application view designer (so you will always need to update the XML if changes are required). Second, this only works if you want to filter to display a single activity type. However, if your requirement is to filter the activities to show 2 or more activity types (e.g. Follow-ups and tasks) then you will not be able to do this solution and only then I’d recommend solution #3.

 

Solution #3

Thanks Jukka for suggesting this. Every activity has at least on activity party (at least the owner). Therefore, we can leverage the activity party relationship to display “all activities which have an activity party which has a parent activity of type X”. This is what the query would look like if I only want to display Follow-up activities for example:

image

The problem with solution #3

The only problem with this solution is that it only works if you want to display a single activity type. If for example you have multiple custom activities and you want a view to display only follow-up and task activities then this will not be possible. Note however that if you want to display only custom activities you can easily filter out the out-of-the-box activities using solution #1 with a filter of “Does Not Equal (task,appointment, etc).” and that will be fine to transport across organizations because OTC for out-of-the-box activities are always constant.

 

Solution #4

You might be disappointed but if you need to filter to display more than 1 activity type but not all activity types, and you are using custom activities in your filter, then the only other solution would be to stick to solution #1 (see above) and then create a tool that automatically remaps the objecttypecode in the views xml to replace it with the appropriate objecttypecode in the target environment. You could do so as a stand-alone tool or you can have a post-solution action which does this for you (using the solution configuration page web resource).

2 comments:

  1. Could you possibly create an Activity view filter where you would set a criteria like "Created On contains data" for an attribute on the Follow-up custom activity entity? If you build the relationship in the query through the activity party entity, this would avoid referencing the OTC yet leave it editable in Advanced Find. Here's the resulting FetchXML from a query I tested:















    ReplyDelete
  2. Thanks, makes sense, post updated!

    ReplyDelete