[ELMA3] Выбор счетов клиентов из таблицы
В рамках интеграции со сторонней системой в бизнес-процессах есть необходимость получать список объектов и предоставлять пользователю выбор одного значения. Важно понимать, что это не справочники, которые можно импортировать один раз и поддерживать синхронизацию изменений, а часто изменяющиеся объекты.
Разберем реализацию на примере информации по счетам клиентов в сторонней системе.
В процессе пользователю требуется выбрать конкретный счет клиента и сделать выписку по данному счету. Процесс организован следующим образом:
- Пользователь в задаче выбирает клиента.
- В пользовательском расширении реализуется запрос информации из веб-сервиса, с записью результатов в специальный справочник для «временной» информации.
- Пользователь выбирает из таблицы требуемый счет.
- Процесс движется дальше: формируется выписка и т.д.
Для сохранения результатов поиска следует создать специальный справочник, например, SearchResultObject с отображаемым названием Счет. Данное решение принято, исходя из того, что записи справочника можно создавать в рамках пользовательского расширения в процессе, удобно передавать в подпроцессы и сохранять временные изменения, не требующие повторного запроса информации из внешней системы (флажки, справочную информацию).
В коде пользовательского расширения осуществляется вызов сервиса. Затем полученные результаты записываются в справочник Счет (SearchResultObject). Обязательным условием является наличие в этом справочнике поля с типом Экземпляр процесса Workflow (Объект) для организации дальнейшего вывода на форму.
Код пользовательского расширения выглядит следующим образом:
var ws = new WebService();
var WSAnswer = ws.GetAccountsInfoByClient(parameters.Client.Uid);
foreach (var item in WSAnswer)
{
var resultobject = new SearchResultObject();
resultobject.Number = item.Number;
resultobject.OpenDate = item.OpenDate;
resultobject.CardNumber= item.CardNumber;
resultobject.Cash = item.Cash;
resultobject.WorkFlowInstance= parameters.WorkFlowInstance;
resultobject.Save();
}
Далее на форме задачи в этом экземпляре процесса список счетов выводится с фильтром по WorkflowInstance.Id в контекстную переменную и/или в список связанных сущностей (стандартный элемент конструктора форм https://www.elma-bpm.ru/kb/article-829.html).

Форма задачи выбора счета выглядит следующим образом:
.png)
Форма задачи состоит из двух важных элементов: поля в контексте с типом SearchResultObject (Объект), обязательным для заполнения, и списком связанных элементов.
Поля в контексте с типом Счет (Объект)
Обычное поле в контексте. На форме задачи установлен сценарий при открытии формы, который ограничивает выбор значения в эту переменную. Суть в том, что следует предоставить для выбора только те записи, которые были получены в текущем процессе – отфильтровать по полю WorkflowInstance. Примерный код сценария следующий:
var st = context.GetSettingsFor(x=>x.SearchResultObject) as EntitySettings;
st.FilterQuery = “WorkflowInstance=”+context.WorkflowInstance.Id;
st.Save();
В общем случае решение уже готово и его можно корректно использовать в процессе, однако для пользователя выбор счета будет крайне неудобен, так как в выпадающем списке он не увидит ничего, кроме номера счета.
Конечно, можно сделать сценарий на выбор счета и выводить информацию о нем на форму, однако такое решение будет работать медленнее и пользователю придется перебирать счета, пока он не увидит нужную информацию.
Таблица счетов на форме
Для улучшения формы и предоставления пользователю информации о найденных счетах следует вывести информацию о них в удобном табличном виде. Так как счета сохраняются в справочник, можно воспользоваться стандартным элементом конструктора форм – список связанных объектов.

Для отображения надо выбрать объект Счет (класс SearchResultObject) и ввести корректную строку для EQL-фильтрации. По сути, надо фильтровать так же, как и в поле для выбора счета – по WorkflowInstance.

Строка EQL-фильтра будет выглядеть следующим образом:
WorkflowInstance = {$WorkflowBookmark.Instance.Id}
Если потребовалось добавить дополнительные условия (IsActive=true, Cash>0), не забудьте написать их здесь, чтобы у пользователя не было возможности выбрать лишние счета или увидеть счета, которые нельзя выбрать.
Подробнее об использовании этого элемента на форме процессной задачи можно прочитать в статье https://www.elma-bpm.ru/kb/article-829.html.
Не забудьте на вкладке Колонки вынести необходимые для отображения колонки. В итоге на форме задачи пользователь сможет увидеть таблицу найденных счетов и выбрать нужный ему для процесса в отдельном поле.
.png)
Форма выглядит почти так же, как и при использовании блока, однако для блока сложно реализовать какой-либо селектор.
Выбор счета из таблицы на форме
Пользователь уже может увидеть всю необходимую информацию о счетах, но выбор счета остается достаточно неочевидным: есть таблица, в которой все, что нужно, и есть отдельный селектор, в котором надо сделать выбор. Для пользователя было бы удобнее выбирать счет непосредственно из таблицы нажатием кнопки мыши.
К сожалению, определить нажатие кнопки мыши по таблице можно только на стороне клиента – в браузере используя JavaScript. В системе ELMA предусмотрены некоторые часто используемые функции JavaScript, например, выбор значения в поле с типом Объект:
var selector = elma.EntitySelector.Manager.get(’Entity_Account_Id’);
selector.addItem(’123’);
Такой скрипт выбирает в контекстную переменную на форме с названием класса Account счет с идентификатором 123.
Кроме этого, когда пользователь наводит мышью на счет в таблице, его можно подсветить, чтобы сделать выбор более очевидным. Это можно сделать, определив в html-разметке CSS-стиль для строки таблицы на форме (<tr>) при наведении мыши (tr:hover):
<style type=\"text/css\">";
str += ".resize-mode-web tr:hover{background-color: #CBE2FF;}";
str += "</style>
Таким образом, можно реализовать и подсветку строк таблицы перед выбором счета и сам выбор счета из таблицы.
Так как скрипт для выбора требует явно передавать идентификатор счета, этот код лучше всего будет выводить непосредственно в таблице. Для этого можно в справочнике Счет (SearchResultObject) добавить поле с типом Html и указать ему вычисление значения сценарием.

Так как предполагается в это поле написать JavaScript код и CSS-стиль, видимого содержимого у него не будет, соответственно, отображаемое имя может быть кратким и ничего не значащим: в нашем случае – это «звездочка» (*).

Также следует указать минимальную удобную ширину колонки 20 пикселей и вписать текст сценария:
new Func<System.Web.HtmlString>(() => {
string str = "";
str += System.String.Format("<div id=\"customDiv{0}\">*</div> {1}", Id.ToString(), System.Environment.NewLine);
str += "<script>" + System.Environment.NewLine;
str += "$(document).ready(" + System.Environment.NewLine;
str += "function(){" + System.Environment.NewLine;
str += String.Format("$(’#customDiv{0}’).parent().parent().parent().parent().bind(\"click\", function()", Id.ToString());
str += "{" + System.Environment.NewLine;
str += "var selector = elma.EntitySelector.Manager.get(’Entity_Account_Id’);";
str += String.Format("selector.addItem(’{0}’);", Id.ToString());
str += "return false;" + System.Environment.NewLine;
str += "})" + System.Environment.NewLine;
str += "});";
str += "</script>";
str += System.Environment.NewLine;
str += "<style type=\"text/css\">";
str += ".resize-mode-web tr:hover{background-color: #CBE2FF;}";
str += "</style>";
return new System.Web.HtmlString(str);
})()
При копировании из браузера может возникнуть проблема, связанная с неправильным отображением апострофов. На рисунке ниже приведен пример того, как должны выглядеть апострофы.
![]()
Если использовать некорректные апострофы, сценарий не будет работать. Необходимо заменить их на корректные (это можно сделать при помощи сочетания клавиш ctrl+F, Заменить.
Подробнее о сценариях вычисления значения поля можно прочитать в статье https://www.elma-bpm.ru/kb/article-466.html
- Entity_Account_Id – это название скрытого поля для выбора значения в контекстную переменную на форме задачи или объекта;
- Entity – стандартный префикс для селекторов на форме задач и объектов;
- Account – название класса поля в контексте;
- Id – стандартный постфикс для селектора полей контекста с типом Объект.
Этот код получается достаточно однотипным для любых объектов, и его можно перенести для других справочников, которые вы предполагаете выбирать в контекст процесса из таблиц (списка связанных объектов). При этом обязательно должно соблюдаться соответствие между названием класса поля для выбора в контексте процесса и тем, что указано в коде.