In this scenario, we need to find a user in a team with the least number of Tasks assigned to them on a particular date so that we can assign a newly created Task record to them. This example can easily be extended to look at all activities due on a date (activitypointer record).
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections.Generic;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.Workflow;
using Microsoft.Crm.Workflow.Activities;
namespace CustomWorkflow
{
[CrmWorkflowActivity("Find User with least Tasks due on specified Date", "Custom")]
public partial class AvailableUser: SequenceActivity
{
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executioncontext)
{
# region get an instance of the Crm Web service
IContextService contextservice = (IContextService)executioncontext.GetService(typeof(IContextService));
IWorkflowContext context = contextservice.Context;
ICrmService crm = context.CreateCrmService(true);
# endregion
GetUserWhoHasLeastTasksDueOn(crm);
return ActivityExecutionStatus.Closed;
}
private void GetUserWhoHasLeastTasksDueOn(ICrmService crm)
{
# region variables
List users = null;
int? leastcount = null;
Guid leastuser = Guid.Empty;
# endregion
/* get a list of users in the team */
users = GetTeamMembers(crm);
/* only proceed if we have found some users */
if (users != null)
{
foreach (Guid userid in users)
{
/* get a list of Task activities due on the specified date for this user */
List tasks = FindTasksDueOnDateForUser(userid, crm);
/* check if this user's due Tasks are less than what we've found so far */
if (tasks != null && ( leastcount == null || leastcount > tasks.Count))
{
leastcount = tasks.Count;
leastuser = userid;
}
}
}
/* assign our output User variable a value */
if (!leastuser.Equals(Guid.Empty))
user = new Lookup(EntityName.systemuser.ToString(), leastuser);
}
private List FindTasksDueOnDateForUser(Guid userid, ICrmService crm)
{
List tasks = null;
try
{
ConditionExpression owner = new ConditionExpression("ownerid", ConditionOperator.Equal, userid.ToString());
ConditionExpression duedate = new ConditionExpression("scheduledend", ConditionOperator.On, dueDate.Value);
FilterExpression filter = new FilterExpression();
filter.AddCondition(owner);
filter.AddCondition(duedate);
filter.FilterOperator = LogicalOperator.And;
ColumnSet cols = new ColumnSet(new string[] { "activityid" });
QueryExpression query = new QueryExpression();
query.ColumnSet = cols;
query.Criteria = filter;
query.EntityName = EntityName.task.ToString();
BusinessEntityCollection collection = crm.RetrieveMultiple(query);
if (collection != null)
tasks = collection.BusinessEntities;
}
catch
{
}
return tasks;
}
private List GetTeamMembers(ICrmService crm)
{
List members = null;
try
{
RetrieveMembersTeamRequest request = new RetrieveMembersTeamRequest();
request.EntityId = team.Value;
request.MemberColumnSet = new ColumnSet(new string[] { "systemuserid" });
RetrieveMembersTeamResponse response = (RetrieveMembersTeamResponse)crm.Execute(request);
members = new List();
if (response.BusinessEntityCollection != null)
foreach (systemuser user in response.BusinessEntityCollection.BusinessEntities)
members.Add(user.systemuserid.Value);
}
catch
{
}
return members;
}
# region workflow dependencies (inputs and outputs)
public static DependencyProperty dueDateProperty = DependencyProperty.Register("dueDate", typeof(CrmDateTime), typeof(AvailableUser));
public static DependencyProperty teamProperty = DependencyProperty.Register("team", typeof(Lookup), typeof(AvailableUser));
public static DependencyProperty userProperty = DependencyProperty.Register("user", typeof(Lookup), typeof(AvailableUser));
[CrmInput("The estimated close date")]
public CrmDateTime dueDate
{
get
{
return (CrmDateTime)base.GetValue(dueDateProperty);
}
set
{
base.SetValue(dueDateProperty, value);
}
}
[CrmInput("The team handling this Task")]
[CrmReferenceTarget("team")]
public Lookup team
{
get
{
return (Lookup)base.GetValue(teamProperty);
}
set
{
base.SetValue(teamProperty, value);
}
}
[CrmOutput("Available User")]
[CrmReferenceTarget("systemuser")]
public Lookup user
{
get
{
return (Lookup)base.GetValue(userProperty);
}
set
{
base.SetValue(userProperty, value);
}
}
# endregion
}
}