Добрый день.
Только начинаю разрабатывать в BPM, и одной из первых задач у меня стало создание правила расчета сроков в обращении.
Пытаюсь реализовать функционал расчета сроков в обращении используя пример https://academy.terrasoft.ru/documents/technic-sdk/7-12/dobavlenie-novogo-pravila-rascheta-srokov-v-obrashchenii
В данный пример (в исходный код "класс с механизмом получения временных параметров") внес небольшие изменения, а именно, мне нужно получить Категорию обращения (стандартное поле) из текущего обращения и добавить полученную категорию в фильтр справочника, в котором содержатся данные для расчета времени (аналогичный примеру, только с полем "Категория обращения").
Получить Категорию обращения я попытался таким способом:
public class UsrMKtermsStrategy: BaseTermStrategy
{
// Класс-контейнер для хранения данных, полученных из точки входа.
protected class StrategyData
{
public Guid ServiceItemId {
get;
set;
}
public Guid PriorityId {
get;
set;
}
public Guid CategoryId {
get;
set;
}
}
// Поле, хранящее данные, полученные из точки входа.
protected StrategyData _strategyData;
// Параметризированный конструктор, необходимый для корректной
// инициализации классом-селектором.
public UsrMKtermsStrategy(UserConnection userConnection, Dictionary args)
: base(userConnection) {
_strategyData = args.ToObject();
}
В результате при добавлении фильтра в esq.CreateFilterWithParameters(FilterComparisonType.Equal, "UsrCategory", _strategyData.CategoryId); у меня передается пустой GUID.
Я так понимаю, причина в том, что не передается аргумент CategoryId
Подскажите, как мне передать Категорию обращения в класс с механизмом получения временных параметров. Пробывал использовать аргумент CaseID и получать Категорию через EntitySchemaQuery. Вариант не подошел, т.к. на момент срабатывания правила и расчета сроков обращение еще не сохранено в БД, и расчет происходит только на сохраненном обращении.
Нравится
Здравствуйте, Антон!
Убедитесь, что вы добавили Категорию в созданный объект (по п.1 из инструкции).
Так как в инструкции указано, что поля, по которым будет выполнятся фильтрация, должны быть добавлены в объект (скриншоты из инструкции - http://prntscr.com/jgj5av, http://prntscr.com/jgj5i5).
Спасибо. Ссылки на Категорию в созданный объект добавил первым делом.
Удалось разобраться самостоятельно:
1) В клиентскую схему схему CasePage добавил пересоздание метода "prepareCaseTermCalculatorConditions" добавив "this.addToConditions(conditions, "Category");
prepareCaseTermCalculatorConditions: function() {
var conditions = [];
this.addToConditions(conditions, "ServiceItem");
this.addToConditions(conditions, "ServicePact");
this.addToConditions(conditions, "Priority");
this.addToConditions(conditions, "Id");
this.addToConditions(conditions, "SolutionOverdue");
this.addToConditions(conditions, "Category");
return conditions;
},2) Исправил ошибки в исходном коде статьи, а именно:
a) Фильтры в EntitySchemaQuery создавались, но не добавлялись. Т.е. небыло esq.Filters.Add(esqFirstFilter);
b) Не использовался «using Terrasoft.Configuration.SLMExtensions;» и перевод результата в минуты («result.ResponseTerm = term.ConvertToMinutes();»). В итоге сильнос сбивалась логика калькуляции паузы при переоткрытии обращения.
В итоге мой серверный исходный код получился следующий:
namespace Terrasoft.Configuration
{
using System;
using System.Collections.Generic;
using Terrasoft.Common;
using Terrasoft.Configuration.Calendars;
using Terrasoft.Configuration.SLMExtensions;
using Terrasoft.Core;
using Terrasoft.Core.Entities;
using CalendarsTimeUnit = Calendars.TimeUnit;
using SystemSettings = Terrasoft.Core.Configuration.SysSettings;
//
using System.Collections.ObjectModel;
using System.Data;
using Terrasoft.Core.DB;
public class UsrMKtermsStrategy: BaseTermStrategy<CaseTermInterval, CaseTermStates>
{
// Класс-контейнер для хранения данных, полученных из точки входа.
protected class StrategyData
{
public Guid ServiceItemId {
get;
set;
}
public Guid CaseId {
get;
set;
}
public Guid PriorityId {
get;
set;
}
public Guid CategoryId {
get;
set;
}
}
// Поле, хранящее данные, полученные из точки входа.
protected StrategyData _strategyData;
// Параметризированный конструктор, необходимый для корректной
// инициализации классом-селектором.
public UsrMKtermsStrategy(UserConnection userConnection, Dictionary<string, object> args)
: base(userConnection) {
_strategyData = args.ToObject<StrategyData>();
}
// Метод, который получает данные и возвращает их в экземпляре класса CaseTermInterval.
public override CaseTermInterval GetTermInterval(CaseTermStates mask) {
var result = new CaseTermInterval();
// Создание EntitySchemaQuery запроса.
var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "UsrTimeCalc");
// Добавление колонок в запрос.
string reactionTimeUnitColumnName = esq.AddColumn("UsrReactionTimeUnit.Code").Name;
string reactionTimeValueColumnName = esq.AddColumn("UsrReactionTimeValue").Name;
string solutionTimeUnitColumnName = esq.AddColumn("UsrSolutionTimeUnit.Code").Name;
string solutionTimeValueColumnName = esq.AddColumn("UsrSolutionTimeValue").Name;
string calendarColumnName = esq.AddColumn("UsrCalendarId.Id").Name;
// Добавление фильтров в запрос.
var esqFirstFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "UsrPriority", _strategyData.PriorityId);
//var esqSecondFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "UsrCategory", categoryGuid);
var esqSecondFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "UsrCategory", _strategyData.CategoryId);
esq.Filters.Add(esqFirstFilter);
esq.Filters.Add(esqSecondFilter);
// Выполнение и обработка результатов запроса.
EntityCollection entityCollection = esq.GetEntityCollection(UserConnection);
if (entityCollection.IsNotEmpty()) {
// Добавление к возвращаемому значению времени реакции.
if (!mask.HasFlag(CaseTermStates.ContainsResponse)) {
var term = new TimeTerm {
Type = entityCollection[0].GetTypedColumnValue<CalendarsTimeUnit>(reactionTimeUnitColumnName),
Value = entityCollection[0].GetTypedColumnValue<int>(reactionTimeValueColumnName),
CalendarId = entityCollection[0].GetTypedColumnValue<Guid>(calendarColumnName)
};
result.ResponseTerm = term.ConvertToMinutes();
}
// Добавление к возвращаемому значению времени разрешения.
if (!mask.HasFlag(CaseTermStates.ContainsResolve)) {
var term = new TimeTerm {
Type = entityCollection[0].GetTypedColumnValue<CalendarsTimeUnit>(solutionTimeUnitColumnName),
Value = entityCollection[0].GetTypedColumnValue<int>(solutionTimeValueColumnName),
CalendarId = entityCollection[0].GetTypedColumnValue<Guid>(calendarColumnName)
};
result.ResolveTerm = term.ConvertToMinutes();
}
}
return result;
}
}
}