Изменение и прерывание таймера в бизнес-процессе с помощью сценария

Пусть в бизнес-процессе необходимо реализовать следующую логику: в текущем экземпляре некоторого процесса есть один или несколько таймеров, и имеется необходимость повлиять на эти таймеры: прервать, увеличить или уменьшить время, установить конкретное значение. Примером такого процесса может служить процесс приема нового сотрудника (рис. 1), в котором устанавливается таймер на время собеседования с кандидатом. При переносе встречи на другое время возникает необходимость изменить настройки таймера.

Рис. 1. Пример использования таймера в бизнес-процессе приема нового сотрудника

Прерывание таймера из сценария

Рассмотрим вариант, где необходимо прервать конкретный таймер в конкретном известном экземпляре процесса. Причем ссылка на экземпляр процесса содержится контекстной переменной процесса-прерывателя (context.InterruptInstance).

Пример без использования PublicAPI

Для корректной работы сценария необходимо подключить следующие пространства имен:

using EleWise.ELMA.Services;
using EleWise.ELMA.Workflow.Managers;
using EleWise.ELMA.Workflow.Models;
using EleWise.ELMA.Model.Managers;

Текст сценария:

var instances = new []{context.InterruptInstance };//Заполняем массив экземпляров процесса, в которых будет производится поиск таймеров для прерывания
var allInstanceTimers = Locator.GetServiceNotNull<WorkflowInstanceManager>().GetActiveTimerInfos(instances);
//поиск таймера по его наименованию на графической модели
var t = allInstanceTimers.ToList().Find(a => a.ElementName == "Событие 1");
//вывод наименования в контекстную переменную
context.Str = t.ElementName;
var job = EntityManager<IResumeProcessSchedulerJob>.Instance.Load(t.SchedulerJobId);
if (job.Task != null && job.Task.Status == ELMA.Scheduling.Models.SchedulerTaskStatus.Enabled)
{
  //исполнение таймера в настоящий момент, т.е. прерывание
  job.Task.OnceExecuteTime = DateTime.Now;
  job.Task.Save();
}

Пример с использованием PublicAPI

Для корректной работы сценария необходимо подключить следующее пространство имен:

using EleWise.ELMA.API;

Текст сценария:

var schedulerJob = PublicAPI.Processes.Objects.ResumeProcessSchedulerJob.Find(String.Format("WorkflowBookmark in (ElementUid = '2d503b7b-e743-4430-ab2e-134b0a069573' and Instance = {0}) and OnceExecuteStatus is null", context.InterruptInstance.Id)).FirstOrDefault();
PublicAPI.Processes.WorkflowInstance.CloseTimer(context. InterruptInstance, schedulerJob.Id);

2d503b7b-e743-4430-ab2e-134b0a069573 – уникальный идентификатор элемента карты процесса. Его можно увидеть в диалоговом окне настроек таймера на вкладке Общие при наведении курсора мыши на название поля Название (рис. 2).

Рис. 2. Диалоговое окно настроек таймера. Вкладка "Общие". Всплывающая подсказка со значением уникального идентификатора таймера

Изменение времени срабатывания таймера из сценария

Рассмотрим пример, когда требуется изменить значение времени срабатывания таймера в процессе. Допустим, необходимо увеличить значение времени срабатывания всех активных таймеров в процессе, увеличив его на два дня.

Текст сценария:

 var schedulerJob = PublicAPI.Processes.Objects.ResumeProcessSchedulerJob.Find(String.Format("WorkflowBookmark in (Instance = {0}) and OnceExecuteStatus is null", context.InterruptInstance.Id)).FirstOrDefault();
PublicAPI.Processes.WorkflowInstance.ChangeTimer (context. InterruptInstance, schedulerJob.Id, schedulerJob.Task.OnceExecuteTime.Value.AddDays(2));