Переход к следующему шагу бизнес-процесса по нажатию кнопки в собственной форме

Добрый день.

Давно я не задавал здесь вопросов и сам ничего не отвечал. :smile:

Есть проблема следующего рода:

Стандартный элемент бизнес-процесса "Вопрос пользователю" очень не удобен, когда пользователь должен дать простой ответ "Да/Нет" на какой-то вопрос. В связи с этим сделал отдельное окно с двумя кнопками, которое запускается после очередного шага в процессе. А вот дальше двигается с огромным трудом. Кнопки реагируют на нажатие хорошо если один раз из 10. То есть нажимаем на кнопку "Нет", но ничего не происходит. Нажимаем много раз подряд и каким-то чудом при одном из кликов процесс продвигается вперед в нужно направлении.

На обработчик нажатия кнопок уже каких только процедур не вешал. Сейчас они выглядят примерно вот так:

System.ProcessMessages();
NotifyObject = Self.Attributes('NotifyObject');
if (Assigned(NotifyObject)) {  
        NotifyObject.Notify(Self, MSG_OK, null);               
}
return true;

Пробовал также вместо return true; ставить Self.ModalResult = wmrCancel;, и пробовал еще просто Self.Close();.

Видимо где-то я не до конца понял, как уведомить процесс о том, что нажата та или иная кнопка. Как это правильно нужно делать?

И еще одно замечание, перед появлением этого окна происходит отправка уведомления через почту (может это как-то влияет).

Нравится

9 комментариев

Добрый день!
я так понимаю, что все манипуляции связаны с тем, что что-то из базового функционала работает не так как хочется.
Предлагаю, все таки, работать с коробочными элементами, а не придумывать свои из-за проблем с работой коробки.
Давайте разберемся, что именно не работает и почему не срабатывает "вопрос пользователю".
Опишите немного подробней сам процесс.

Так же, укажите версию продукта и продукт.

Добрый день, Сергей.

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

Заказчик хочет чтобы было нормальное диалоговое окно с двумя кнопками, чтобы можно было одним кликом все сделать. Особенно это актуально, если учесть, что RadioButton по размера гораздо меньше, чем кнопка, а потому попадать в нее сложнее.

"Sergey Karpenko" написал:Предлагаю, все таки, работать с коробочными элементами, а не придумывать свои из-за проблем с работой коробки.

Коробочные универсальные элементы далеко не всегда являются самыми удобными с точки зрения пользовательского интерфейса. И когда встают вопросы влияния интерфейса на скорость работы приходится изобретать велосипеды. Тут уж ничего не поделаешь. :smile:

Продукт: Terrasoft CRM 3.4.1.119

Если не сложно, предоставьте, пожалуйста весь код, какие обработчики для wa_ ......

Вот так выглядит кусочек бизнес-процесса, относящийся к запуску этой формы:

Это настройки элементы в бизнес-процессе:

А вот все, что есть в скрипте этого окна:

//-----------------------------------------------------------------------------
// wnd_OpenForm2ConfirmScript
//-----------------------------------------------------------------------------
 
var NotifyObject;	
 
function btnYesOnClick(Control) {
	Log.Write(2, "Yes click.");
//	var NotifyObject = Self.Attributes('NotifyObject');
	System.ProcessMessages();
	if (Assigned(NotifyObject)) {	
		NotifyObject.Notify(Self, MSG_OK, null);		
		Log.Write(2, "MSG_OK.");
	}
	Log.Write(2, "Before close OK.");
	return true;
//	Self.ModalResult = wmrOK;		
//	Self.Close();
}
 
function btnNoOnClick(Control) {
	Log.Write(2, "No click.");
//	var NotifyObject = Self.Attributes('NotifyObject');	
	System.ProcessMessages();
	if (Assigned(NotifyObject)) {
		Log.Write(2, "MSG_CLOSE.");
		NotifyObject.Notify(Self, MSG_CLOSE, null);
	}	
	Log.Write(2, "Before close Cancel.");	
	return false;
//	Self.ModalResult = wmrCancel;		
//	Self.Close();
}
 
function wnd_OpenForm2ConfirmOnPrepare(Window) {
        Log.Write(2, "OnPrepare");
	NotifyObject = Self.Attributes('NotifyObject');	
}
 
function wnd_OpenForm2ConfirmOnCloseQuery(Window, CanClose) {
	CanClose.Value = true;
}

То что закомментировано - это мы попытки по разному реализовать обработчики.

Неужели так и нет информации? Может кто-нибудь хотя бы скажет где и что почитать по этому поводу?

Здравствуйте, Алексей.

Корректным вариантом решения, будет создание своего 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;
}

После этого процесс отлично понимает с каким результатом отработало открытое окно и двигается дальше в нужном направлении.

Показать все комментарии