В расширенных настройках элемента [Открыть страницу редактирования] отображаются связи активности и служебные параметры. Самый простой способ добавить связь активности с другим разделом – включить в этом разделе кейс менеджмент. Добавить дополнительные параметры колонки активности (текстовые/булевые …) в элемент не получится, в таком случае нужно создавать новый элемент.
Кроме того не рекомендую работать со служебной активностью (которая создается при выполнении элемента) как с обычной. На нее завязана дополнительная логика в системе, это может привести к нарушению пользовательской бизнес-логики.
Кроме того не рекомендую работать со служебной активностью (которая создается при выполнении элемента) как с обычной. На нее завязана дополнительная логика в системе, это может привести к нарушению пользовательской бизнес-логики.
К сожалению, эта активность показывается в реестре вместе со всеми активностями, как обычная. И очень нелогично, когда половина параметров у нее будет пустая...
Id служебной активности хранится в параметре элемента “Уникальный идентификатор активности”.
Если процесс компилируемый можно обработать запись в параллельной ветке (с небольшой задержкой).
Можно привязать эту активность к какой-нибудь сущности (через расширенные настройки) и в реестре отфильтровать все записи по этой сущности. Это связь будет условным признаком по которому можно выполнить фильтрацию.
Как и раньше в базовый процесс нет возможности вносить правки пользовательскими средствами. Изначально необходимо заместить его и уже свой можно править. В версии 7.8 это делать гораздо легче - по нажатию на кнопку "Действия" - "Копировать диаграмму". Прикрепил для наглядности скриншот 1.
Что касается отдельной стадии, то здесь никаких изменений по сравнению с предыдущей версией нет. Аналогично можно найти в разделе "Конфигурация" схему (так как отдельные стадии идет как отдельными схемами процесса), заместить и редактировать в зависимости от потребностей. Прикрепил скриншот 2 для наглядности. Что касается удаления существующей/добавления новой, то в версии 7.8 изменен справочник "стадии продаж" и теперь там есть возможность проставлять признак "Показывать на индикаторе стадий". Соответственно, нужно убрать из нужной стадии этот признак, чтоб у пользователей не было возможности переходить на эту стадию по клику на прогресбар. Также, в самом процессе необходимо внести некоторые исправления, например, в в элементе процесса, который идет перед удаляемым нами в последнем элементе "изменение данных" необходимо указать, что при выполнении условий нужно переходить уже на другую стадию (действия аналогичны как для добавления своей стадии, так и для отмены использования уже существующей).
Для элемента БП Задача есть настройка "Открывать карточку редактирования":
Но она всего лишь меняет свойства WorkflowAction ProcessImmediately (переключает выполнять ли этот элемент сразу или приостанавливать БП до нажатия "Выполнить шаг"). А мне хотелось, чтобы была возможность создавать задачу, не открывая ее карточку и не прерывая процесс.
Вот, что я сделал (+ бонус добавление напоминания для ответственного по галочке на время начала задачи):
добавил два CheckBox'a в wnd_TaskActionEdit
- chbAutoCreate
- chbAddReminding
в скрипт wnd_TaskActionEditScript
- в функцию function LoadData(DiagramItem) в конце добавил:
в wa_TaskAction добавил два параметра:
- AutoCreate
- AddReminding
в скрипт wa_TaskActionScript в function wa_TaskActionOnExecute добавил:
- после DefaultValues.Add('StartDate', ExecuteDate);
f (WFGetParamsMapItemValue(ActionItem,'AddReminding')){
DefaultValues.Add('RemindToOwnerDate', ExecuteDate);// вместо ExecuteDate можно подставить любую другую дату/логику }
- переделал условие перед CreateNewTask(DefaultValues)
Кстати, чтобы добавить автоматическое заполнение (из параметров) каких-то кастомных полей для создаваемой задачи, как это происходит с контрагент\контакт\продажа\договор (на примере моего поля LeadsID) надо в скрипт wa_TaskActionScript:
"Владимир Соколов" написал:В 3.3.2 этого нет. А как выполнить такую же функциональность?
Не смогу вам сейчас посоветовать что-то конкретное. Попробуйте "обновить" частично до 3.4 - загрузить в вашу конфигурацию сервисы (в части касающейся того, что вам нужно) из 3.4, или вручную сравнить и добавить то, чего не хватает.
в приложении - ветка wa_TaskAction из базовой 3.4.1. Нет факт что без допиливания сработает wa_taskaction.rar
Спасибо за наводку.
В 3.3 создал функцию, и с ней реализовал ту же самую логику
function CreateTask(DefaultValues, ActionItem, ParentDiagramScript, WindowScript){
//Функция создаёт задачу без открытия карточки
var ParentDiagram = GetDiagramByItem(ActionItem);
var TaskObject = {};
TaskObject.DefaultValues = DefaultValues;
TaskObject.Dataset = GetSingleItemByCode('ds_Task', 'WFCreateTask');
TaskObject.Dataset.Append();
SetDefaultValues(TaskObject);
var TaskID = Connector.GenGUID();
TaskObject.Dataset.Values('ID') = TaskID;
var OwnerID = TaskObject.Dataset.Values('OwnerID');
TaskObject.Dataset.Post();
Дмитрий Александрович, такое понятие как перевод выполнения БП на другого пользователя отсутствует.
Сделать так, чтобы процесс начал выполняться от лица другого пользователя можно только используя элемент «Задача» и устанавливая ответственного в задаче.
Однако в таком случае будет наблюдаться следующая ситуация: у пользователя, который запустил БП, отобразится задача, где автор – другой контакт. Тот кто выполнит задачу и будет дальнейшим владельцем БП.
Уверен, многие так или иначе задавались тем же вопросом.
Я потратил на это день, но вроде бы решил задачу.
Сделал WorkflowAction под названием "WorkflowTransfer". Как всегда большую часть скриптов взял у самих же Террасофт (из действия wa_OpenWindow).
Как работает:
1) Открывается окно wnd_SelectData с датасетом ds_Owner, выбирается новый ответственный
2) посылается notify обратно на WorkflowItem
3) Меняется (Edit() - присвоение - Post()) ответственный в датасете элемента БП (ItemDataset)
4) элемент закрывается с результатом Отменено, но уже на нового ответственного
5) новый ответственный в разделе процессов нажимает "Выполнить шаг"
6) проверяется соответствие ответственного по элементу текущему пользователю - если да, процесс продолжается, если нет - опять выбор нового ответственного. workflowtransfer.rar
У меня, на версии 3.4.1 XRM в одной (пока) конкретной ситуации работает.
Считаю, что решение в стадии BETA и буду благодарен за фидбек и участие в тесте
Много времени потратил именно на то, чтобы сделать это именно одним отдельным действием - так гораздо удобнее. Как вариант можно переделать wa_OpenWindow или делать два действия - выбирать Ответственного и потом скриптом менять его в БП
Давно я не задавал здесь вопросов и сам ничего не отвечал.
Есть проблема следующего рода:
Стандартный элемент бизнес-процесса "Вопрос пользователю" очень не удобен, когда пользователь должен дать простой ответ "Да/Нет" на какой-то вопрос. В связи с этим сделал отдельное окно с двумя кнопками, которое запускается после очередного шага в процессе. А вот дальше двигается с огромным трудом. Кнопки реагируют на нажатие хорошо если один раз из 10. То есть нажимаем на кнопку "Нет", но ничего не происходит. Нажимаем много раз подряд и каким-то чудом при одном из кликов процесс продвигается вперед в нужно направлении.
На обработчик нажатия кнопок уже каких только процедур не вешал. Сейчас они выглядят примерно вот так:
Добрый день!
я так понимаю, что все манипуляции связаны с тем, что что-то из базового функционала работает не так как хочется.
Предлагаю, все таки, работать с коробочными элементами, а не придумывать свои из-за проблем с работой коробки.
Давайте разберемся, что именно не работает и почему не срабатывает "вопрос пользователю".
Опишите немного подробней сам процесс.
Вопрос пользователю срабатывает нормально. Просто вопрос звучит примерно так: "Перейти к заполнению детальной информации?" И всего два варианта ответа: "Да" и "Нет". Для того, чтобы ответить нужно сделать два клика мышкой: выбрать вариант ответа и нажать кнопку. А поскольку поток оформляемых заявок большой, то вот это лишнее движение мышкой уже начинает влияет на скорость работы.
Заказчик хочет чтобы было нормальное диалоговое окно с двумя кнопками, чтобы можно было одним кликом все сделать. Особенно это актуально, если учесть, что RadioButton по размера гораздо меньше, чем кнопка, а потому попадать в нее сложнее.
"Sergey Karpenko" написал:Предлагаю, все таки, работать с коробочными элементами, а не придумывать свои из-за проблем с работой коробки.
Коробочные универсальные элементы далеко не всегда являются самыми удобными с точки зрения пользовательского интерфейса. И когда встают вопросы влияния интерфейса на скорость работы приходится изобретать велосипеды. Тут уж ничего не поделаешь. :smile:
Корректным вариантом решения, будет создание своего workflow action-a, в котором необходимо описать окна, написать скрипты и т.д.
Задача нетривиальная, поддержкой не выполнялась и поэтому соответствующих инструкций нет.
Можем только посоветовать делать с дебагером по аналогии с другими wa..
Я не совсем понял, почему нужно делать новый workflow action, если уже есть "Открыть окно". Мне по сути и нужно открыть окно, а потом продолжить процесс в зависимости от того, нажали ли в открытом окне "ОК" или "Отмена" (то что на кнопках надписи другие - это не важно).
Разница-то только в том, что я не какое-то стандартное окно использую, а собранное мной с нуля.
Необходимо использовать wa, так как обработка возврата результата происходит в нем. wa открывает окно, окно получает результат нажатия кнопки, записывает себе в атрибуты, wa читает атрибуты открытого им окна и продолжает процесс в зависимости от полученного значения. В скрипте окна Вам необходимо реализовать возврат значения используя атрибуты этого окна (переданные при открытии окна из wa). Так, как это реализовано, например, в окне wnd_Decision:
По нажатию на ОК происходит вызов функции CheckResult, в теле которой отстраивается набор вариантов для выбора и собирается массив с результатом. Вам необходимо в результат записать просто свое значение. Затем, происходит вызов функции ProcessClose, в теле которой массив с результатами собирается в строку разделенную ";" и происходит толчок процесса ID которого взят из атрибутов.
В конце концов разобрался. Выкладываю решение здесь.
Не нужно делать дополнительных WA, так как есть уже готовый WA "Открыть окно", который и так замечательно умеет отрабатывать нажатия кнопок "OK" и "Cancel" на формах.
Для того, чтобы все заработало нужно было либо снять галочку "Запретить закрытие окна без сохранения/выбора", либо при инициализации окна прописать вот это:
SetAttribute(Self, 'DisableClose', false);
Далее нужен скрипт, в котором будет всего четыре обработчика событий: два на кнопках, один на инициализацию форму и последний на событие проверки возможности закрытия. Вот так выглядит этот скрипт:
var NotifyObject;
function btnYesOnClick(Control){
System.ProcessMessages();if(Assigned(NotifyObject)){
NotifyObject.Notify(Self, MSG_OK, null);}}
function btnNoOnClick(Control){
System.ProcessMessages();if(Assigned(NotifyObject)){
NotifyObject.Notify(Self, MSG_CLOSE, null);}}
function wnd_OpenForm2ConfirmOnPrepare(Window){
NotifyObject = Self.Attributes('NotifyObject');}
function wnd_OpenForm2ConfirmOnCloseQuery(Window, CanClose){
CanClose.Value=true;}
После этого процесс отлично понимает с каким результатом отработало открытое окно и двигается дальше в нужном направлении.
На днях возник небольшой вопрос, решить который все никак не представляется возможным.
У нас есть ряд workflow-процессов у которых в свою очередь есть большое кол-во свойств (параметров со значениями) процесса.
К сожалению, в связи с одной пунктуационной ошибки ранее, у некоторых процессов поле Parameters в таблице Workflow стало NULL.
В этот момент и возник вопрос:
Как можно восстановить хотя бы названия параметров, которые создавались на предыдущих шагах процесса?
Значения параметров я могу заполнить сам. Но все наименования не припомню.
А искать другой процесс на таком же шаге, который шел по тем же веткам, сложно.
Может можно как-то программно пройти все предыдущие шаги и считать названия создаваемых переменных?
Но при этом не выполняя содержимое всех шагов.
Дабы не дублировать сущности, создаваемые по пути.
Т.е. у Вас есть незавершенные процессы, параметры которых были удалены, и Вам необходимо восстановить для дальнейшей корректной работы сами параметры и их значения?
Если да, то, к сожалению, это не возможно.
Даже если Вы запустите дубль процесса, дойдете до шага, на котором произошел сбой, и скопируете поле Parameters с одного процесса в другой, то все-ровно значения параметров будут не те, которые Вам необходимы в "некорректном" процессе. Названия же параметров, вы в принципе можете просмотреть в Террасофт Администраторе в свойствах диаграммы процесса.
Посмотреть я их, безусловно, могу
И даже могу поднять бэкап БД за период, когда еще были эти параметры у интересного мне процесса
Но хотелось бы попробовать найти чуть более изящное решение
Если оно есть, конечно же
Вопрос скорее в другом
Можно ли как-то получить их скриптом? Например распарсить в tbl_Service поле XMLData у процесса?!
Или, скажем, через функции террасофта можно получить список параметров у определенного шага\процесса?
Иван, посмотреть параметры конкретного дейтсвия можно в ТС Администраторе по правому клику:
а распарсить BLOB в XML можно следующим способом:
CREATE TABLE #Sample(
BLOB VARBINARY(MAX) NOT NULL)
INSERT #Sample
SELECT 0x3C526F772049443D2231223E5065736F2C204D56503C2F526F773E
SELECT *
FROM #Sample
ALTER TABLE #Sample
ADD MyXML AS CAST(CAST(BLOB AS VARCHAR(MAX)) AS XML)-- Display the result
SELECT *
FROM #Sample
Но, к сожалению, он не отвечает на вопрос
Можно ли как-то получить список параметров элемента бизнес процесса скриптом?
Например, кнопку сделать в гриде процессов для получения отсутствующих параметров
И распарсить XML представленный как Varbinary или Image тоже не проблема. Вот только Image у элемента Workflow Diagram в tbl_Service не парсится как XML
Параметры, которые "вшиты" в действия - даже после их удаления при выполнении действия - будут созданы.
Параметры диаграммы, которые пользовательские, восстановить не получится. Но посмотреть их список можно прямо в ТС Администраторе в свойствах диаграммы, если конечно они и там не были удалены.
Долго воевал с передачей параметра из подпроцесса. Почему-то в любом случае передавался только один вариант. А решение крылось в особенности обработки события OnFinish для завершающих элементов процесса. Если в диаграмме есть несколько завершающих элементов и у каждого указан свой обработчик события OnFinish, то в любом случае вызывается тот, что расположен раньше в скрипте.
Чтобы запустить бизнес-процесс, например, «Продажа» по выбранному контакту в реестре записей раздела Контакты, я создал действие «Запустить процесс Продажа». На событие OnExecute прописал код:
function StartWFbyContact(WorkflowUSI, GridDataset){ var ParamNames =new Array(); var ParamValues =new Array(); var FieldValue = GridDataset.CommaText;
ParamNames.push('ContactID');
ParamValues.push(FieldValue); var Params = WFArrayToParams(ParamNames, ParamValues); var WorkflowEngine = GetAttribute(Connector,'WorkflowEngine'); var Now =new Date().getVarDate();
WorkflowEngine.StartWorkflow(WorkflowUSI, Now, Params); }
function amiWorkWithClientOnExecute(ActionMenuItem, Sender){ var GridDataset = BaseWorkspace.Grid.SelectedIDs; var SelectCount = GridDataset.Count; switch(SelectCount){ case1: var WorkflowUSI ="Workflow\\Workflow Diagrams\\wd_WorkWithClient";
StartWFbyContact(WorkflowUSI, GridDataset); return case SelectCount 1:
Message("Контакт не выбран"); return case SelectCount >1:
Message("Выбрано более одного контакта"); return } }
И подключил скрипт scr_WorkflowUtils.
Это все! ;-)
Здравствуйте, Виталий
Реализовала по Вашему примеру запуск процесса из раздела Контрагенты. Процесс запустился, но Параметр не присвоился, то есть поле Котнтрагент осталось пустым.
В первой задаче процесса параметр AccountID является Входящим/Исходящим (Исходящим по причине того, что если запускать процесс в разделе Процессы - в первой задаче процесса задается Контрагент, а Входящим он должен быть для запуска процесса как раз из раздела Контрагентов, насколько я понимаю).
Если в чем-то ошиблась или есть другие причины проблемы с параметром, подскажите, пожалуйста.
Я так понимаю, эти строки мне надо в функции BeforeExecute задачи прописать? Вот что написала, но результата нет:
function ActionItem1OnBeforeExecute(ActionItem){
var ParentDiagram = GetDiagramByItem(ActionItem);
var AccountID = WFGetParamValue(ParentDiagram, 'AccountID');if(!IsEmptyValue(AccountID)){
WFSetParamValue(ActionItem, 'AccountID', AccountID, 0);}}
1)Да, параметр в диаграмме не пустой, там есть значение при запуске первой задачи.
2)Да, параметр создан и привязан к параметру диаграммы с тем же именем AccountID.
Кажется, стало ясно, в чем причина.
У меня в начале бизнес процесса стоит элемент Script, а только за ним задача. Script создает Продажу (это сделано для того, что бы пользователю не нужно было лишний шаг в процессе проходить. То есть важно, что бы продажа сама по себе жила и в процессе не мелькала в качестве шагов). Но в Связи параметров нет Script, поэтому ему не удается передать параметр в начале процесса.
Так вот надо как-то с этим теперь справиться :exclaim:
Получилось передавать параметр первой задаче процесса, идущей за Script при выполнении Script. Задача запускается с уже непустым параметро AccountID, но в карточке все равно поле пустое.
Хелп
еще пример мистики :(
пытался реализовать аналогичный пример запуска БП
function amiWorkWithClientOnExecute(ActionMenuItem, Sender){
var GridDataset = BaseWorkspace.Grid.SelectedIDs;
var SelectCount = GridDataset.Count;switch(SelectCount){
....
и даже один раз сработало :)
но потом начал код приводить в порядок и в какой-то момент начал получать облом
[font=monospace]
Сообщение об ошибке: 'BaseWorkspace' is undefined
[/font]
не подскажите куда копать?
Для того, чтобы запустить БП при условиях, например, Состояние = Выполнена, Результат = Требует изменений, Вам необходимо сделать некоторые доработки конфигурации:
В скрипте scr_TaskEdit реализовать следующую функцию:
function StartWFByTaskResultAndStatus(CompareStatusID, CompareResultID){ var Dataset = dlData.Dataset; var ResultID = Dataset.Values('ResultID'); var StatusID = Dataset.Values('StatusID'); if(IsEmptyValue(ResultID)|| IsEmptyValue(StatusID)){ return; } if(StatusID != CompareStatusID || ResultID != CompareResultID){ return; } var WorkflowID ='{9F1762FC-A82B-4807-B2C7-CA83CEF06690}';//указать ID нужного БП
WFStartByID(WorkflowID,null,null); }
Далее на событие OnDatasetAfterPost для DlData в функцию дописать следующий код:
var CompareStatusID ='{F598ECDB-4EEF-4FA8-9E69-A36B053501E5}';// указать ID необходимого состояния задачи из tbl_TaskStatus var CompareResultID ='{092822D2-4471-44BC-94D4-0BF272D81D47}';//указать ID необходимого результата задачи из tbl_TaskResult