Выбор счетов клиентов из таблицы

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

Разберем реализацию на примере информации по счетам клиентов в сторонней системе.

В процессе пользователю требуется выбрать конкретный счет клиента и сделать выписку по данному счету. Процесс организован следующим образом:

  1. Пользователь в задаче выбирает клиента.
  2. В пользовательском расширении реализуется запрос информации из веб-сервиса, с записью результатов в специальный справочник для «временной» информации.
  3. Пользователь выбирает из таблицы требуемый счет.
  4. Процесс движется дальше: формируется выписка и т.д.

Для сохранения результатов поиска следует создать специальный справочник, например, 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).

Форма задачи выбора счета выглядит следующим образом:

 Форма задачи состоит из двух важных элементов: поля в контексте с типом 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.

Не забудьте на вкладке Колонки вынести необходимые для отображения колонки. В итоге на форме задачи пользователь сможет увидеть таблицу найденных счетов и выбрать нужный ему для процесса в отдельном поле.

 

Форма выглядит почти так же, как и при использовании блока, однако для блока сложно реализовать какой-либо селектор.

Выбор счета из таблицы на форме

Пользователь уже может увидеть всю необходимую информацию о счетах, но выбор счета остается достаточно неочевидным: есть таблица, в которой все, что нужно, и есть отдельный селектор, в котором надо сделать выбор. Для пользователя было бы удобнее выбирать счет непосредственно из таблицы нажатием кнопки мыши.

К сожалению, определить нажатие кнопки мыши по таблице можно только на стороне клиента – в браузере используя 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, то есть название поля с типом счет в контексте Account и никак иначе.
  • Entity_Account_Id – это название скрытого поля для выбора значения в контекстную переменную на форме задачи или объекта;
  • Entity – стандартный префикс для селекторов на форме задач и объектов;
  • Account – название класса поля в контексте;
  • Id – стандартный постфикс для селектора полей контекста с типом Объект.

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