Microsoft Dynamics CRM has different Activity entities, showing actions from the CRM users.  ActivityPointer records are automatically created when an Activity record is created, enabling developer to retrieve different Activity types with one request.

If you don’t understand how to use the ActivityPointer record you can quickly get bogged down trying to retrieve individual Activity types.

CRM developers should think in entities when designing CRM solutions, activities track the activity and effort of the people using the CRM Solution.

Activities are the actions users do in CRM, often tracking the interaction between users and customers.

CRM has lots of different activities

  • PhoneCall
  • Task
  • Letter
  • Email
  • Appointment
  • Fax
  • Custom Activities

Tracking the activity of users/customers, records the time spent on CRM records. For cases, you can see activities associated with the case.   Tracking activities allows different people to work a record with a full knowledge of the status of the case.

Activity facts

  1. Activity is an entity in CRM, you can look at it in the custom solution
  2. The activity entity is non-editable.
  3. Activity schema name is ActivityPointer e.g ActivityPointer = Activity
  4. ActivityPointer is not the same as Activity Party

Microsoft ActivityPointer description

“Task performed, or to be performed, by a user. An activity is any action for which an entry can be made on a calendar.”

What’s the purpose of the Activity Entity?

If you can’t explain it simply, you don’t understand it well enough.

Albert Einstein

To understand a CRM functionality, you need to understand its purpose.   Once you understand what it’s used for, how it works and why it works in that way.

CRM developers should Start with the CRM SDK and then explain it to yourself in your own words.

The purpose of the Activity entity is in the schema name – ActivityPointer.  Developers can retrieve all activities with one request, instead of multiple retrieves using the different activity types.

The activity views allow you to show all activities for a record, despite the activities being different types (e.g. Email, PhoneCall, Task)

The CRM SDK has a great page on Activity entities.

The diagram shows why understanding Activities is important, Activities are linked to the primary entities in CRM.  Activity entity acts like an interface between primary entities and individual activities.

Why do you need to know ActivityPointer?

ActivityPointer is a generic, it holds links to all activities.  You gain the ability to retrieve all Activities but lose the ability to retrieve individual fields or custom fields on the different Activities.

The alternative would be to have a Sub-grid for each different activity type!

activitypointer views

The ActivityPointer is a wrapper or interface to all activities, it includes the generic fields found on all activities.  Microsoft ensures activities have common fields by making you tick the activity checkbox when creating an activity entity.

ActivityPointer.ActivityId

ActivityPointer.ActivityId will have the same value as the Activity its wrapping.  Using the example of an Email activity.

Email.ActivityId will have the same value as the ActivityPointer.ActivityId

activitypointer view

activity pointer email fetchxml

Doing an advanced find for Activities, when you click on an Activity record it will open the Activity, e.g. click on Activity record of type email, it will open the email.

ActivityId’s are the same because an Activity record is created by CRM when an activity record (Task/PhoneCall/Email/etc) is created.

Activity Types

Doing an advanced find, you can use the Activity Type field on the ActivityPointer entity to see what Activites types can be ActivityPointer records.  The Activity Type is a Global option set

activity type

Activity Type – activitypointer_activitytypecode

activity type 1

IsRegularActivity?

There are lots of activity types which don’t look like regular activities, such as

  • Bulk Operation
  • Case Resolution
  • Opportunity Close

CRM creates activities when a Case/Opportunity is closed but why don’t these activities appear in the Activity views?

The field IsRegularActivity on the ActivityPointer entity is set to no for CRM created Activities.

If you search for all Activities you can view the non-regular activities, I mainly had Case Resolutions

activitypointer

Custom Activities

When creating a custom entity you can specify if the entity is an activity by checking Define as an Activity entity

activity checkbox

I have discussed this in detail in this blog post below

CRM 2013 – When should you create a custom activity entity?

Think about the security limitations of creating Custom Activities, e.g. Any security settings will be applied to all activities. It’s unlikely you want any security on activities because most users need to read and create activities.

Important facts to remember when creating Custom Activities

  • Custom Entities when created by default are not viewable/usable to any users apart from System Administrator and System customizer roles. Other security roles will have to add the entity (don’t forget)
  • If an entity is selected as an Activity this cannot be undone
  • Custom Activity entities are available to users who have access to other Activity entities

I have worked on a project where security concerns meant the custom Activity was converted to a standard entity. We created a custom entity (Which you can apply security too), copied the data into your new entity, deleting the custom Activity.

Activity and SQL

ActivityPointer entity has an SQL table and Filtered view () created on the CRM database.

  • Table – ActivityPointerBase
  • Filter – ActivityPointer

Tables in the CRM database allows you to create reports using Activities.  Best practise is to use the ActivityPointer filter,  why filtered views are useful

The blog post does an excellent job explaining Activity entity with SQL.

All About Activity Entity Query Full Guidance in CRM 2011/2013 : Basic–Complex (ActivityPointer, ActivityParty) Queries in One Post

Activity coding problem

I needed to reactivate a case and reactivate the last Activity for the case.

The existing code activated Tasks but now I needed to activate Tasks and PhoneCalls.

Developer assumptions cause many bugs.  Functionality should work how the user wants it to work, not the developer, remember You are not the end user

I needed to check all the activities for the case and reactivate the last PhoneCall or Task activity.  Task and PhoneCall had a custom field which indicated if the Activity should be reactivated.

The custom field increased the complexity, ActivityPointer record doesn’t contain the custom field because ActivityPointer contains generic fields common on all Activity records.

My plan

  • Retrieve all the Activities using ActivityPointer
  • Loop through Activities, checking if the Activity was of type PhoneCall or Task
  • Use Activity.ActivityId to retrieve the Activity

Here is Linq query I used to retrieve ActivityPointer


        public List<ActivityPointer> GetRecentActivityForIncident(Guid incidentId)
        {
            
            this.tracingService.Trace("Enter Method GetMostRecenActivityForIncident");
            using (OrganizationServiceContext crmContext = new OrganizationServiceContext(this.crmService))
            {
                var mostRecentWrappedTask = (from t in crmContext.CreateQuery<ActivityPointer>()
                    where
                        (t.RegardingObjectId != null && t.RegardingObjectId.Id.Equals(incidentId))
                        && ((int) t.StateCode.Value == (int) TaskState.Completed)
                    orderby t.CreatedOn descending
                    select t);
                return mostRecentWrappedTask.ToList();
            }

        }

After writing this post, there is a simpler solution.  I retrieved all the Activities and had to loop through the list, discarding activities until I got to a Task or PhoneCall.

I could have used the ActivityType filter to retrieve the ActivityPointer records with an ActivityType of PhoneCall and Task.

 

 

 


Filed under: CRM 2013, CRM 2015