Добрый день.
Только начинаю разрабатывать в BPM, и одной из первых задач у меня стало создание правила расчета сроков в обращении.
Пытаюсь реализовать функционал расчета сроков в обращении используя пример https://academy.terrasoft.ru/documents/technic-sdk/7-12/dobavlenie-novogo-pravila-rascheta-srokov-v-obrashchenii
В данный пример (в исходный код "класс с механизмом получения временных параметров") внес небольшие изменения, а именно, мне нужно получить Категорию обращения (стандартное поле) из текущего обращения и добавить полученную категорию в фильтр справочника, в котором содержатся данные для расчета времени (аналогичный примеру, только с полем "Категория обращения").
Получить Категорию обращения я попытался таким способом:
public class UsrMKtermsStrategy: BaseTermStrategy<CaseTermInterval, CaseTermStates> { // Класс-контейнер для хранения данных, полученных из точки входа. 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<string, object> args) : base(userConnection) { _strategyData = args.ToObject<StrategyData>(); }
В результате при добавлении фильтра в 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; } } }