Ниже приведен поток бизнес-процессов (BPF) для объекта Opportunity.Я создал плагин, который автоматически продвигает этот BPF до последней стадии при обновлении поля в Opportunity.
При отправке сообщения RetrieveActivePathRequest для Возможности, которая удовлетворяет условию, изображенному выше (и, таким образом, использует все этапы BPF), я получаю RetrieveActivePathResponse, и мой плагин работает должным образом:
// Retrieve the process stages in the active path of the current process instance
RetrieveActivePathRequest activePathRequest = new RetrieveActivePathRequest
{
ProcessInstanceId = activeProcessId
};
RetrieveActivePathResponse activePathResponse = (RetrieveActivePathResponse)service.Execute(activePathRequest);
Однако отправка сообщения RetrieveActivePathRequest для Возможности, которая не удовлетворяет условию (и, следовательно, использует только первые три этапа BPF), приводит к System.ServiceModel.FaultException .
Я подозреваю, что это может быть связано с тем, что в BPF условие «else» не разветвляется на стадию.Я добавил общую стадию и связал ее с условием «else» и последней стадией, изображенной выше, и больше не испытывал исключения.Мой плагин работал как ожидалось и автоматически продвигал BPF.
Два вопроса:
Почему это так?Я могу вручную пройти каждый этап и завершить BPF в любом сценарии, так почему я не могу программно сделать то же самое?
Есть ли альтернативный способ обработки этого сценария, поэтому я может автоматически продвигать BPF (как есть) с моим плагином?Я бы предпочел не создавать общую сцену или два отдельных BPF, если это вообще возможно.
Редактировать:
Если кому-то интересно, это вся функция, которую я использую дляавтоматическое продвижение BPF.
private static void AdvanceBusinessProcessFlow(IOrganizationService service, ExtendedPluginContext context, Guid opportunityId)
{
// Retrieve all process instances
RetrieveProcessInstancesRequest instanceRequest = new RetrieveProcessInstancesRequest
{
EntityId = opportunityId,
EntityLogicalName = XrmOpportunity.EntityLogicalName
};
RetrieveProcessInstancesResponse instanceResponse = (RetrieveProcessInstancesResponse)service.Execute(instanceRequest);
// First record is the active process instance
Entity activeProcessInstance = instanceResponse.Processes.Entities[0];
var activeProcessId = activeProcessInstance.Id;
var activeStageId = new Guid(activeProcessInstance.Attributes["processstageid"].ToString());
// Retrieve the process stages in the active path of the current process instance
RetrieveActivePathRequest activePathRequest = new RetrieveActivePathRequest
{
ProcessInstanceId = activeProcessId
};
// System.ServiceModel.FaultException exception occurs here
RetrieveActivePathResponse activePathResponse = (RetrieveActivePathResponse)service.Execute(activePathRequest);
string activeStageName;
int? activeStagePosition = null;
int stageCount = activePathResponse.ProcessStages.Entities.Count;
// Iterate through all process stages and identify active stage
for (int i = 0; i < stageCount; i++)
{
if (activePathResponse.ProcessStages.Entities[i].Attributes["processstageid"].ToString() == activeStageId.ToString())
{
activeStageName = activePathResponse.ProcessStages.Entities[i].Attributes["stagename"].ToString();
activeStagePosition = i;
}
}
// If an active stage position is not identified, do nothing
if (activeStagePosition == null)
{
throw new InvalidPluginExecutionException("No active stage of business process flow was identified!");
}
// Auto-advance active stages of BPF to last stage so that BPF can be auto-finished
while (activeStagePosition < stageCount - 1)
{
// Retrieve the stage ID of the next stage to be set as the active stage
var newActiveStageId = (Guid) activePathResponse.ProcessStages.Entities[(int) ++activeStagePosition].Attributes["processstageid"];
// Retrieve the process instance record to update its active stage
ColumnSet columnSet = new ColumnSet();
columnSet.AddColumn("activestageid");
Entity retrievedProcessInstance = service.Retrieve(dfnd_opportunitydispoprocess.EntityLogicalName, activeProcessId, columnSet);
// Update active process stage
retrievedProcessInstance["activestageid"] = new EntityReference(ProcessStage.EntityLogicalName, newActiveStageId);
service.Update(retrievedProcessInstance);
}
}