Let’s get started..
Objective
Our objective here is to capture the information that User Inputted through this system form and store the values to the Case entity.Create Fields in the Case Entity
Now, I create the fields that I need in the Case entity- Resolution
- Total Time
- Billable Time
- Remarks
*Resolution Type is already defined in the Status Reason of the Case, in case you want to create new field, it is also possible to do!
What If I Want To Have Another Status Code?
You can go to Status Reason field of the Case entity and Add New Item*Status Reason Field
I create a new item: ‘Enhancement Requested’
Then I put those fields in the Form and make them as read-only
Problem
The challenge here is this entity is a special Entity that seems to be ‘hidden’ in CRM and included as Activity in CRM, thus, considered as Child record of the Case, we should take note on that list to make the proper solution.Solution
Of course as the Consultant we need to give the best solution and the best solution that comes up to the CRM professional is thinking the Out of the box first or the most effortless customization if inbuilt function is not there, Should I create Workflow or Plugin?#1 Can I use Workflow for Case Resolution?
The answer is ‘No’ because the Case Resolution is one of the unsupported entity in Workflow.#2 Can I use the Workflow and use The Case as The Entity?
Okay if you are using the OOB Workflow, the answer is ‘No’ as the solution here, it is not possible because as mentioned before Case Resolution is a child entity, as we know the OOB Workflow cannot get the related record from the 1:N Relationship so you cannot get the Case Resolution entity record through parent Case using Out of The Box CRM Workflow#3 Can I use Plugin?
Yes, of course, but what kind of Plugin?#4 What about Plugin on The Case Resolution Entity?
Surprisingly it works! I tried it.I thought it would not work if I register to the Case Resolution entity on Post-Create Event because at the time Case Resolution Entity is created by the time the Case has been Resolved (status that makes the Case Read-Only).
After some research I see that in the Case the status is still 1 or In Progress
This is possible because CRM has another message Close for Case Entity.
#5 What is the difficulty?
The difficulty here is to retrieve the Total Time here because you need to sum up the times spent in each activity related to the Case.Another difficulty here is to get the Status Code to become the Resolution Type because mentioned before CRM only gives status = 1 (In Progress) not yet Resolved, so that you might need another plugin in the Case entity to capture that, but I recommend you to use the Status Reason field in the Case entity. I you really need this field you can contact me for further development.
#6 So, What Is The Plugin Code?
Here is the Plugin Codepublic class CaseResolution : IPlugin { public void Execute(IServiceProvider serviceProvider) { #region must to have IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); // Create service with context of current user IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); //create tracing service ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); #endregion #region Variable Entity targetCase = new Entity("incident"); string strResolution = string.Empty; int intTotalTime = -1; int intTotalBillableTime = -1; string strRemarks = string.Empty; #endregion if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) { //create entity context Entity entity = (Entity)context.InputParameters["Target"]; if (entity.LogicalName != "incidentresolution") return; try { if (entity.Contains("incidentid")) { //get the related Case targetCase.Id = ((EntityReference)entity["incidentid"]).Id; //capture the Case Resolution Fields strResolution = entity.Contains("subject") ? entity["subject"].ToString() : string.Empty; intTotalBillableTime = entity.Contains("timespent") ? (Int32)entity["timespent"] : 0; strRemarks = entity.Contains("description") ? (entity["description"] != null ? entity["description"].ToString() : string.Empty) : string.Empty; //get the total time from Activities intTotalTime = GetTotalTime(service, targetCase.Id); //update Case with the fields targetCase["new_resolution"] = strResolution; targetCase["new_totalbillabletime"] = intTotalBillableTime; targetCase["new_totaltime"] = intTotalTime; targetCase["new_remark"] = strRemarks; service.Update(targetCase); } } catch (Exception ex) { throw new InvalidPluginExecutionException(ex.Message); } } } private int GetTotalTime(IOrganizationService service, Guid guidRelatedCaseId) { //count the Activity Actual Duration Minutes for this Case //need to sum time spent of each activity (cannot directly using the actualtdurationminutes) int intSumTotalTime = 0; //Retrieve all related Activities by Case QueryExpression query = new QueryExpression("activitypointer"); query.ColumnSet.AddColumns("actualdurationminutes"); query.Criteria = new FilterExpression(); query.Criteria.AddCondition("regardingobjectid", ConditionOperator.Equal, guidRelatedCaseId); // Execute the Query EntityCollection results = service.RetrieveMultiple(query); foreach (Entity entity in results.Entities) { int intActivityTime = 0; intActivityTime = entity.Contains("actualdurationminutes") ? (Int32)entity["actualdurationminutes"] : 0; intSumTotalTime = intSumTotalTime + intActivityTime; } return intSumTotalTime; } }
#5 How to Register The Plugin
Here is the Plugin Registration Tool Setting for this Step
Result
And Here is your Result
I resolve the Case with following information
And here is the captured Information in my Case entity form.
Summary
Here is the summary1. You cannot capture using the Out of the box Workflow because the entity is not supported
2. You can achieve it by creating a plugin updating the Case fields and register the plugin on the Post-Create of the Incident Resolution entity
3. Just be careful, in CRM a case can be closed and can be-reactivated again so every time CRM close the case it will keep updating the field and keep the latest position/value and will create another activity-close case to the related Case
This is how CRM treats the Case Resolution as the Case Activities.
4. CRM stores the total billable time in the 'Time Spent' field, while the Total Time for all activities are not stored in any field, you need to manually count the SUM from each related Case Activities, then store it somewhere else if you want to display it.
5. Once you save those fields in the Case, you will able to see the fields in the Case entity, either through Form, View, or Report of Case entity, while if you are not, you can still show but you need to query agains the Activity entity with type = Case Resolution.
Hope this helps you!
Thank you.
hi, great work. how do you get the resolved case results onto the case form? kindly assist
ReplyDeleteGood solution!
ReplyDeleteDo you know how to bring a custom field value(text) to Remarks from the case to the case resolution form when you resolve the case?
Thanks
:)
Nice Sharing! I like this topic.This site has lots of advantage.I found many interesting things from this site. It helps me in many ways.Thanks for posting this again. Thanks a million and please keep up the effective work Thank yo so much for sharing this kind of info- CRM development company
ReplyDeleteThis is great! Do you have any idea how to resolve a case and just auto populate the resolution field with the word "Resolved" - or to even just not see the case resolution screen when you select the "resolve case" button? Any suggestions would be greatly appreciated. Thanks!
ReplyDeleteHi Buddy,
ReplyDeleteNicely Done.
I am learning CRM and the next task I m trying is to update a custom entity Resolution field with Case Resolution whenever the case is resolved.
Can you please help me with the same.
Hi,
ReplyDeleteI am trying to understand on how to generate SLAs per queue and globally (when transferred to other queue ) for a case. (ie, new case opened and assigned to a queue A, case is then transferred to queue B. I would like to know the total time that queue A had the case and total time queue B had the case and the grand total of the case from open to resolved.
Will your 4 & 5 point help me in this?
Regards,
Ganesh A
You are a genius! I have been able to achieve this with not programing knowledge whatsoever!
ReplyDeleteThank you so much!!
Yvan
Good Solution. Thanks.
ReplyDeletehi sir ,, i want to get the time spend between created on date and resolve date of case ...how can do this even you know after case resolve we cannot update any field on case
ReplyDeleteLots of Good information in your post, I favorited your blog post so I can visit again in the future, Thanks.
ReplyDeletebusiness expense tracker
You can use this cloud service https://web2case.com to capture customer incidents directly into your Dynamics CRM
ReplyDeleteThis is great!
ReplyDeleteGet Data Capture definition and information from here Data Capture Form
ReplyDeleteThis is still relevant and still works (Dynamics CRM online v9.1) -- thank you so much!!
ReplyDeleteHi BDCDebbie,
DeleteYes your correct it's worked for resolution filed only. billable time not working my case. Kindly help me.
Hello to all.
ReplyDeleteIf you want to prevent the user from closing a case with a certain value in the type of case resolution, you can register in the onPreCreate for incidentresolution entity, one plugin that checks the values that are reported by the incidentresolution entity, with something like this:
int InValue = 0;
if (context.ParentContext.ParentContext.PrimaryEntityName == "incident")
{
ParameterCollection valS = (ParameterCollection)context.ParentContext.ParentContext.InputParameters;
foreach(var v in valS)
{
if ((string)v.Key.ToLower() == "status")
{
InValue = ((OptionSetValue)v.Value).Value;
}
}
}
if (inValue != goodValueForMyRequirements)
{
throw new InvalidPluginExecutionException("You enter a invalid status reason for this incident.");
}
Hope this helps.
Regards,
I have tired the above plug in sandbox instance getting below business error.where I need to design form in case entity or case resolution entity kindly help me for this.
ReplyDelete'incident' entity doesn't contain attribute with Name = 'new_totalbillabletime' and NameMapping = 'Logical'.
if it is possible to store resolution in resolved form.