I have worked on a couple MS Dynamics CRM projects for Call Center clients, one of the common requirements is record lock - when an agent opens a record, be it a lead or case, this record should be made exclusively available to the agent. Typically, these records are commonly accessible by all agents, until an agent marks one record, usually by opening it. An agent may choose not to work on this record, but until the record is released back to the "pool", this agent has the exclusive access.
Out of box, MS CRM comes with Queue and Queue item. They have never been good enough for such a scenario, because Queue Item is manually picked, and is just an intersect table between Queue and the actual record. A user/agent can bypass the Queue and work on the actual record if the user wants to. More often than not, in a call center environment where agents are measured by individual accomplishment, Queue and Queue Item do not meet the business requirement.
I started with assigning the record using JavaScript, i.e. when a record is loaded, an Onload JavaScript function it will assign the record to the executing user. The following users will be alerted if they try to open the same record. But this assignment occurs in client side, there are always possible lags between the local client and the server. It is simply not a reliable solution.
Out of box, MS CRM comes with Queue and Queue item. They have never been good enough for such a scenario, because Queue Item is manually picked, and is just an intersect table between Queue and the actual record. A user/agent can bypass the Queue and work on the actual record if the user wants to. More often than not, in a call center environment where agents are measured by individual accomplishment, Queue and Queue Item do not meet the business requirement.
I started with assigning the record using JavaScript, i.e. when a record is loaded, an Onload JavaScript function it will assign the record to the executing user. The following users will be alerted if they try to open the same record. But this assignment occurs in client side, there are always possible lags between the local client and the server. It is simply not a reliable solution.
So I decided to use a Retrieve plugin to achieve this. The idea is when a record is retrieved, the plugin will assign the record to the user. This is not a complete solution but the code snippet. You definitely need other mechanism/processes in place to meet your own business requirement.
Anyway, in my example, the entity is PhoneCall. The step is registered on post-operation of Retrieve.
public void Execute(IServiceProvider serviceProvider) {
try {
IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext));
if (context.Depth > 1) { return; }
if (context.OutputParameters.Contains("BusinessEntity") && context.OutputParameters["BusinessEntity"] is Entity)
{
Entity entity = (Entity)context.OutputParameters["BusinessEntity"];
if (entity.LogicalName == "phonecall" && entity.GetAttributeValue<OptionSetValue>("statecode").Value == 0) //if the phone is open
{
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
Guid PhoneCallId = context.PrimaryEntityId;
Guid userId = context.UserId;
//assignment
AssignRequest assign = new AssignRequest
{
Assignee = new EntityReference("systemuser", userId),
Target = new EntityReference("phonecall", PhoneCallId)
};
// Execute the Request
service.Execute(assign);
}
}
} catch (Exception ex) {
throw new InvalidPluginExecutionException(ex.Message.ToString());
}
}
No comments:
Post a Comment