Tuesday, August 16, 2011

Sum activities duration Dynamics crm 2011

Sum activities duration Dynamics crm 2011.

This is plugin that sums all completed activites into some custom entity.

Prerequests:
  1. Early binding class. (not a most but makes code writing easier)
    Early binding walkthrough link : http://dynamicslollipops.blogspot.com/2011/07/mscrm-2011-early-binding-plugin.htm

The Plugin code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Xrm;
using System.ServiceModel;

namespace MSCRM2011Plugins
{
    public class SumActivityPlugin : IPlugin
    {

        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));

            try
            {
                IOrganizationServiceFactory serviceFactory =
                    (IOrganizationServiceFactory)serviceProvider.GetService(
                typeof(IOrganizationServiceFactory));
                IOrganizationService service =
                serviceFactory.CreateOrganizationService(context.UserId);

                XrmServiceContext xrm = new XrmServiceContext(service);
                
                // Extract the tracing service.
                ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
                if (tracingService == null){
                    throw new InvalidPluginExecutionException("Failed to retrieve the tracing service.");
                }
                Entity postEntity = null;
                Entity preEntity = null;
                if (context.PostEntityImages.Contains("MyImage"))
                {
                    postEntity = context.PostEntityImages["MyImage"];
                }
                if (context.PreEntityImages.Contains("MyImage"))
                {
                    preEntity = context.PreEntityImages["MyImage"];
                }
                tracingService.Trace("MeesageName = " + context.MessageName);
                if (context.MessageName.ToLower().Equals("delete"))
                {
                    tracingService.Trace("Completed activity was delete recalc total duration for project");
                    CalcProjectActivities(xrm, tracingService, preEntity);
                }
                else
                {
                    tracingService.Trace("calc project total duration");
                    //change state
                    CalcProjectActivities(xrm, tracingService, postEntity);
                }
            }
            catch (FaultException ex)
            {
                throw new InvalidPluginExecutionException(
                "An error occurred in the plug-in.", ex);
            }

        }

        private void CalcProjectActivities(XrmServiceContext xrm, ITracingService tracingService, Entity reldEntity)
        {
           // tracingService.Trace("Get activity");
           // ActivityPointer activity = xrm.ActivityPointerSet.FirstOrDefault(ac => ac.ActivityId == new Guid(reldEntity["activityid"].ToString()));
            tracingService.Trace("Get all related activities");
            IQueryable activities = xrm.ActivityPointerSet.Where(ac => ac.RegardingObjectId != null && ac.RegardingObjectId.Id == ((EntityReference)reldEntity["regardingobjectid"]).Id && ac.ActualDurationMinutes != null && ac.StateCode.Value == ActivityPointerState.Completed);
            if (activities != null)// && activity != null)
            {
                int totalSum = 0;
                foreach (var a in activities)
                {
                    totalSum += a.ActualDurationMinutes.Value;
                }
                ActivityPointer activity = activities.FirstOrDefault();
                tracingService.Trace("total sum = " + totalSum);
                if (activity != null && activity.RegardingObjectId.LogicalName == new_project.EntityLogicalName)
                {
                    new_project relatedProject = xrm.new_projectSet.FirstOrDefault(proj => proj.new_projectId == activity.RegardingObjectId.Id);
                    if (relatedProject.new_totalhours == null && totalSum != 0)
                    {
                        relatedProject.new_totalhours = totalSum;
                        xrm.UpdateObject(relatedProject);
                        xrm.SaveChanges();
                    }
                    else if (relatedProject.new_totalhours != null && relatedProject.new_totalhours.Value != totalSum)
                    {
                        relatedProject.new_totalhours = totalSum;
                        xrm.UpdateObject(relatedProject);
                        xrm.SaveChanges();
                    }
                }
            }
        }
    }
}

*In this example the new_totalhour (int - duration format) attribute updated in custom entity name new_project, You can update any attribute you want.

General plugin code description:

  1. Get the post / pre image of the activity type entity like fax, email appointment and etc.
    not the activity pointer since you can't register setstate, setstatedynamic or delete to activity pointer.
  2. Get from it the regerdingobjectid and the duration of all the other completed activites releted to the same record.
  3. Update the record with the new duration.

Last step is to register the plugin and the steps.
Entities: All the activites you would like to sum have to be registered.
Messages: setstate, setstatedynamic and delete.
Images:
add post image to setstate and setstatedynamic
add pre image to delete.

6 comments:

  1. Do you have the plugin compiled? I am not a programmer but would like to use this for our CRM system, so need clear instructions on what I need to do to implement.

    ReplyDelete
    Replies
    1. Hi,
      Do you have new_project?
      Do you need it to sum duration from all activities?
      Please send me you mail with answers and I'll see what I can do.

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Yes I would appreciate some help on this. I have a project and have used the example above in this file but are receiving many errors on build (may have to do with the early binding class?).
    I would appreciate a copy of your project if possible as this ability to sum all is critical for our CRM project. My email is cheriejross@gmail.com

    Many thanks

    ReplyDelete
    Replies
    1. Hi,
      Sorry for the late replay,
      I'll see what i can do...

      Delete