[ELMA3] Заполнение метрик процесса через сценарии
В системе ELMA предусмотрена возможность создавать метрики/показатели процесса или экземпляра процесса.
В данной статье рассмотрены примеры заполнения значений метрик через сценарии процесса.
Например, время обработки заявки в бизнес-процессе «Рассмотрение заявки» заносится пользователем в контекстную переменную VremyaNaObrabotku. Требуется записать это время в метрику экземпляра процесса VremyaObrabotkiZayavki.
Для этого в бизнес-процессе необходимо разместить следующий сценарий:
// Получить метрику экземпляра процесса и привести его к типу P_ProcessSMetrikami_IM var metricValues = context.WorkflowInstance.MetricValues as P_ProcessSMetrikami_IM; // Присвоить метрике экземпляра процесса значение из контекстной переменной VremyaNaObrabotku metricValues.VremyaObrabotkiZayavki = Convert.ToInt32(context.VremyaNaObrabotku); // Сохранить метрику экземпляра процесса metricValues.Save();
Тип, к которому требуется привести метрику, можно узнать в Дизайнере ELMA в карточке процесса на вкладке "Настройки":

Рис. 1. Дизайнер ELMA. Карточка процесса. Вкладка "Метрики и показатели". Структура метрик экземпляра процесса
Другая часто возникающая задача – сохранение количества запусков процесса для персональной метрики.
В данном случае идёт работа с метрикой процесса, а не с метрикой экземпляра процесса.
Необходимо создать метрику процесса в карточке процесса на вкладке "Метрики и показатели" со следующими параметрами:

Рис. 2. Шаг 1. Название показателя

Рис 3. Шаг 2. Значение показателя

Рис. 4. Шаг 3. Правило вычисления
В сценарии процесса для заполнения метрики необходимо использовать следующий код:
var processMetrics = context.WorkflowInstance.Process.ProcessMetrics.EntityProperties.Cast<ProcessMetric>();
if(processMetrics != null){
//поиск метрики процесса по названию
var isp = processMetrics.FirstOrDefault(pm => pm.Name == "KolichestvoZapuskov");
if (isp != null){
//если метрика является персональной, то необходимо указать контекстную переменную, в которой будет храниться пользователь, запустивший процесс; в противном случае вместо context.Ispolnitelj надо подставить null
SaveMetricValue(isp, context.Ispolnitelj);
}
}
Также в сценарий процесса необходимо добавить метод сохранения значения метрики:
Пример сценария с использованием PublicAPI
Пространства имен:
using EleWise.ELMA.Workflow.Models; using EleWise.ELMA.Security.Models; using EleWise.ELMA.Services; using EleWise.ELMA.KPI.Common.Interfaces; using EleWise.ELMA.Logging;
Текст сценария:
private void SaveMetricValue(ProcessMetric metric, User responsible)
{
var filter = PublicAPI.Processes.Objects.ProcessMetricValue.Filter().Responsible(responsible).ProcessMetricUid(metric.Uid);
if (metric.UsePeriodicity && metric.PeriodicityUid.HasValue)
{
var periodService = Locator.GetServiceNotNull<IPeriodicityService>();
var periodicity = periodService.Load(metric.PeriodicityUid.Value);
if (periodicity != null)
{
var period = periodService.GetPeriod(periodicity, DateTime.Now);
filter = filter.PeriodStart(period.First).PeriodEnd(period.Second);
}
}
var ispValue = filter.Find().FirstOrDefault();
if (ispValue != null)
{
double doubleValue;
if (double.TryParse(ispValue.Value.ToString(), out doubleValue))
{
PublicAPI.Processes.Objects.ProcessMetricValue. SetMetricValue(metric,doubleValue + 1,DateTime.Now,responsible);
} else
{
Logger.Log.Error(String.Format("Ошибка при вычислении показателя {0}", metric.DisplayName));
}
} else
{
PublicAPI.Processes.Objects.ProcessMetricValue. SetMetricValue(metric,1,DateTime.Now,responsible);
}
}
Пример сценария без использования PublicAPI
Пространства имен:
using EleWise.ELMA.Workflow.Models; using EleWise.ELMA.Security.Models; using EleWise.ELMA.Model.Services; using EleWise.ELMA.Services; using EleWise.ELMA.KPI.Common.Interfaces; using EleWise.ELMA.Workflow.Managers; using EleWise.ELMA.Logging;
Текст сценария:
private void SaveMetricValue(ProcessMetric metric, IUser responsible){
var filter = InterfaceActivator.Create<IProcessMetricValueFilter>();
filter.DisableSecurity = true;
filter.Responsible = responsible;
filter.ProcessMetricUid = metric.Uid;
if(metric.UsePeriodicity && metric.PeriodicityUid.HasValue){
var periodService = Locator.GetServiceNotNull<IPeriodicityService>();
var periodicity = periodService.Load(metric.PeriodicityUid.Value);
if (periodicity != null){
var period = periodService.GetPeriod(periodicity, DateTime.Now);
filter.PeriodStart = period.First;
filter.PeriodEnd = period.Second;
}
}
IProcessMetricValue ispValue = ProcessMetricValueManager.Instance.Find(filter, FetchOptions.All).FirstOrDefault();
if (ispValue != null){
double doubleValue;
if (double.TryParse(ispValue.Value.ToString(), out doubleValue)){
ProcessMetricValueManager.Instance.MetricSave(metric, responsible, doubleValue + 1);
} else {
Logger.Log.Error(String.Format("Ошибка при вычислении показателя {0}", metric.DisplayName));
}
}
else{
ProcessMetricValueManager.Instance.MetricSave(metric, responsible, 1);
}
}