Нашел более правильное решение, т.к. Case переводиться в состояния закрыто с использованием сущности IncidentResolution, то вполне логично повесить на создание этой сущности плагин, который на Post-operation будет апдейтить Кейс.
X++:
public 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;
}
}