Есть ли возможно пакетно изменить серию карточек из интерфейса?

Нравится

4 комментария

"Борисов Михаил Евгеньевич" написал:Есть ли возможно пакетно изменить серию карточек из интерфейса?

Выделяете на гриде и нажимаете изменить. Для этого, конечно, должен быть добавлен функционал MassEdit (если это кастомный раздел) - можно посмотреть в BaseGridArea, TaskEdit

Точно, спасибо. Не видел этой возможности из под обычного пользователя. А как эту способность передать пользователям, не нашел в администрирование? А пакетное обновление идет в обход бизнес логики(код на событиях контролов форм, код на событиях датасета)?

"Борисов Михаил Евгеньевич" написал:код на событиях контролов форм, код на событиях датасета

записи редактируются через датасет (т.е. его события отрабатывают) - надо быть внимательным

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

Добрый день!
Есть вопрос:
В существующем БП необходимо создать две параллельные задачи, при этом вторая задача должна быть создана после сохранения первой. Есть ли возможность перехода на следующее действие бизнес-процесса, если состояние предыдущей задачи "Не начато" или "В работе" ?

Нравится

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

Добрый день, Игорь.
После первой задачи создайте вторую по потоку "Любой результат" .

Здравствуйте Дмитрий!
К сожалению ничего не вышло.
В моём случае вторая задача должна создаваться после нажатия на "ОК" (не выполнения) первой задачи. Таким образом состояние у первой задачи должно быть - "Не начата" или "В работе", а при данных состояниях результата задачи нет.
С другой стороны, если я выбираю состояние "выполнено" - тогда вторая задача создается, но уже после выполнения первой задачи. Но в таком случае это уже будут не параллельный задачи (как например задачи "встреча" и "подтверждение встречи"), а последовательные.
Вопрос ещё открыт.

Я имел ввиду вот так:

т.е. выбрать не конкретный результат, а "Любой результат". Тогда вторая задача будет создана сразу же после первой, в не зависимости от того, какое состояние у первой задачи (не начата, в работе).

Да, я тоже об этом. В данном случае обязательным условием создания Action2 является выполнение Action1 с любым результатом. Однако при создании и сохранении Action1 с состояниями "не начата", "в работе", Action2 не создается.
Т.е. Action2 будет создано только после выполнения Action1
В моём случае необходимо создать две параллельные задачи
и из Action1 передать параметры в Action2

Вопрос только - КАК?

Вам надо в скрипте карточки задачи (scr_TaskEdit) исправить:

/* MODULE WORKFLOW */
	if ((!TaskEdit.StatusChanged) || (!IsFinished) ||
		(IsEmptyGUID(WorkflowItemID))) {
		return;
	}

на

/* MODULE WORKFLOW */
	if ((!TaskEdit.StatusChanged) || 
		(IsEmptyGUID(WorkflowItemID))) {
		return;
	}

вот только тогда у вас не будет учитываться состояние задач вообще при работе с БП, что, мягко говоря, скажется на функционале. Так что так лучше не делать). Можно, конечно, встроить в скрипт выше какие-то проверки и логику - но это перебор.

Если вам надо просто создать (без контроля выполнения) первую задачу и передать параметры во вторую - используйте элемент "Открытие окна" для карточки задачи:

и оттуда сохраните в параметры то, что вам надо.

Могу предложить только костыльно. Поставить задачи последовательно (3-ий комментарий), создать фейковый результат "Нет результата" или просто " ", а при открытии карточки смотреть на пустоту поля результат и привязанный процесс. Т.е. проверить к нужному ли процессу относится задача и поле результат пусто, то ставить ей в результат "Нет результата". Тогда у вас будет результат, и по идеи должно переходить к следующему шагу, хотя не уверен, не проверял.

"Андросов Дмитрий" написал:

Если вам надо просто создать (без контроля выполнения) первую задачу и передать параметры во вторую - используйте элемент "Открытие окна" для карточки задачи:

К сожалению, как от первой, так и от второй задачи потом идет ветвление в зависимости от результата выполнения.

я так понимаю, что вся сложность в том, чтобы передать параметры во вторую задачу?

тогда вижу два варианта:
- сделать как я предложил первый раз, но не удалять !IsFinished, а переделать на какую-то другую логику (добавить тип или еще что-то)
- нужные вам параметры можно выбирать в каком-то другом окне (см то же "Открытие окна" или "Настраиваемое окно редактирования") и потом уже передавать в оба окна задач. Или вообще не передавать параметры :biggrin:

Спасибо Дмитрий! Попробую.

Попробовал сделать, так:
Для состояния "Не начато" задачи Action1 создал результат выполнения "Не начато". Добавил условие, по которому поле ResultID доступно на редактирование. И по этому результату переход на Action 2. Однако, при выборе этого результата Action 2 не создается, текущим элементом остается Action1.

В общем, чтобы БП пошел дальше, нужно, чтобы задача считалась завершенной.
Чтобы задача считалась завершенной нужно, чтобы для выбранного состояния задачи в справочнике "Состояния задач" был установлен признак "Конечное".
Вам лучше создать еще одно состояние (не трогайте не начато)) для ваших целей

"Андросов Дмитрий" написал:

В общем, чтобы БП пошел дальше, нужно, чтобы задача считалась завершенной.

Чтобы задача считалась завершенной нужно, чтобы для выбранного состояния задачи в справочнике "Состояния задач" был установлен признак "Конечное".

Вам лучше создать еще одно состояние (не трогайте не начато)) для ваших целей


А разве в таком случае Action1 не будет считаться выполненной?

"Коновалов Игорь" написал:не будет считаться выполненной

смотря, что вы под этим подразумеваете)
например, введем новое состояние задачи "Принята по БП" с признаком "Конечное" и соответствующим результатом.
Тогда при выборе этого состояния у вас задача будет "Принята по БП" (но не "Выполнена"), но по БП дальше пойдет и состояние у нее будет считаться "конечным"

"Андросов Дмитрий" написал:

например, введем новое состояние задачи "Принята по БП" с признаком "Конечное" и соответствующим результатом.

Тогда при выборе этого состояния у вас задача будет "Принята по БП" (но не "Выполнена"), но по БП дальше пойдет и состояние у нее будет считаться "конечным"


Дмитрий огромное спасибо! Пошел по Вашему пути.
После указанного Вами варианта, для WorkflowItem, соответствующего задаче Action1, обновил поля StateID = ws_InProcess и ActualExecuteDate = null в таблице tbl_WorkflowItem.
Т.о. Элемент БП соответствующий первой задаче (Action1) опять становится активным и после его выполнения доступен переход к др. элементам БП.
УРА!!! Всем спасибо! Вопрос закрыт!

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

Добрый день.

Давно я не задавал здесь вопросов и сам ничего не отвечал. :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;
}

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

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

создаю простейший бизнес-процесс:
начало->открытие окна нового договора->открытие окна нового счета ->завершение

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

IsCopy = true
IsCreatedByContractID = true

Но тут бизнес процесс вылетает с ошибкой на строчке кода

if ((RequestFromWorkflow) &&
                        (Dataset.Values('WorkflowItemID') != NewWorkflowItemID)) {

Пишет Dataset.Values('WorkflowItemID') Набор данных 'Invoices\General\Main Grid\ds_Invoice' не открыт

Как могли эти 2 атрибута окна повлиять на открытие/неоткрытие датасета совершенно не понятно. Как все-таки решить проблему копирования продуктов в этом бизнес-процессе? Вот полная версия функции, где происходит сбой.

function wnd_InvoiceEditOnPrepare(Window) {
/* MODULE WORKFLOW */
        SetAttribute(Window, 'WorkflowDataFields', 'BillStatusID');
/* ENDMODULE WORKFLOW */
        wnd_BaseDBEditOnPrepare(Window);
        Initialize(Window);
/* MODULE WORKFLOW */
        var RequestFromWorkflow = false;
/* ENDMODULE WORKFLOW */
        InvoiceEdit.IsCompleting = false;
/* MODULE WORKFLOW */
        var DefaultValues = GetAttribute(Window, 'DefaultValues');
        var Dataset = BaseDBEdit.Dataset;
        if (Assigned(DefaultValues)) {
                // Post WorkflowItemID anyway because for this Invoice new
                // workflow item was created
                var NewWorkflowItemID = DefaultValues('WorkflowItemID');
                var RequestFromWorkflow = (!IsEmptyValue(NewWorkflowItemID));
                if ((RequestFromWorkflow) &&
                        (Dataset.Values('WorkflowItemID') != NewWorkflowItemID)) {
                        Dataset.Values('WorkflowItemID') = NewWorkflowItemID;
                        if (Dataset.State == dstEdit) {
                                Dataset.Post();
                                Dataset.Edit();
                        }
                }
        }
        if (RequestFromWorkflow && (Dataset.State == dstInsert)) {
                InvoiceEdit.CanCancel = false;
                dlData.Dataset.Values('BillStatusID') = null;
        } else {
                InvoiceEdit.CanCancel = true;
        }
        btnCancel.IsEnabled = InvoiceEdit.CanCancel;
/* ENDMODULE WORKFLOW */
        SetDefValuesByParentItems();
        UpdateInvoiceBasicCurrencyCaptions();
        UpdateInvoiceCurrencyCaptions();
        SetbtnProductsVisibility(Dataset('WorkflowItemID'));
        SetbtnProductsEnability(Dataset.State);
}

Файлы с бизнес-процессом прикладываю

Нравится

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

Добрый день.

Уточните какую версию Вы используете?
Также не совсем понятно, что Вы собираетесь копировать, если после создания документа в нем нет продуктов...

Лучше после создания документа добавить элемент скрипт, и в него перенести логику из действия "Создать счет" раздела "Документы". Там, кроме создания счета, еще после этого и выполняется функция копирования продуктов из документа в счет.

Но учтите, что в текущем варианте, у Вас всегда будет скопировано "0" продуктов, т.к. скрипт выполнится сразу после создания нового документа, т.е. до добавления в него продуктов.

Террасофт CRM 3.4.0.132

Ну я создаю договор, а не документ.

Функцию добавления продуктов в договор я планировал вставить позднее перед созданием счета.

Подскажите откуда брать логику, я не совсем понял. Еще раз обращаю внимание, что копируются продукты в счет из договора, а не документа.

Андрей, здравствуйте.

В принципе, это не принципиально, из договора или документа Вы копируете продукты.

Предлагаю реализовать так:

1 шаг: Открыть карточку договора.
2 шаг: (функция по добавлению продуктов)
3 шаг: (функция по созданию счета и копировании продуктов в счет)

функция с третьего шага уже есть готовая, необходимо лишь её немного модифицировать. Смотрите функцию function CreateInvoiceByContract(ContractIDs) в скрипте wnd_ContractsWorkspaceScript.

Сделал эти 3 шага. Но на 3-м шаге при попытке копировать продукты вылетает с ошибкой Объект не поддерживает это свойство или метод на строчке

NotifyObject.Notify(Window, NotifyMessage, NotifyData)

эта строчка находится в функции

function SendNotify(Window, NotifyMessage, NotifyData) {
	var NotifyObject = Window.Attributes('NotifyObject');
	if (NotifyObject) {
		NotifyObject.Notify(Window, NotifyMessage, NotifyData);
	}
	var NotifyObjectList = Window.Attributes('NotifyObjectList');
	if (!NotifyObjectList) {
		return;
	}
	for (var i = 0; i < NotifyObjectList.length; i++) {
		var NotifyObjectListItem = NotifyObjectList[i];
		if (NotifyObjectListItem) {
			NotifyObjectListItem.Notify(Window, NotifyMessage, NotifyData);
		}
	}
}

для чего вообще нужна нотификация в данном случае и как она работает?
И как исправить бизнес-процесс, чтобы все заработало корректно?
Файлы сервисов процесса прилагаю.

Андрей, сложно сказать в чем проблема сходу - скорее всего, один из параметров функции равен null. Буду тестировать Ваш процесс... Ориентировочно ответ Вам предоставлю в течении 2-х дней.

Спасибо!

Дело в том, что в оригинальной функции строка

CreateNewWindowEdit(Self, 'wnd_InvoiceEdit', DefaultValues, Attributes);

в качестве NotifyObject (параметр Self) передает окна раздела "Договора".
В Вашем случае - Self - это сервис бизнес процеса.
В качестве NotifyObject чаще всего передаются объекты окон,в другие окна, которые вызваны из них. Т.е к примеру при нажатии на лукапное поле, окно выбора в качестве атрибута NotifyObject получает ссылку на окно, в котором была нажата кнопка выбора. Потом, после закрытия окна выбора, данному окну посылается Notify, что окно было закрыто - сообщение MSG_CLOSE.
Система нотификаций используется повсеместно для передачи информации между окнами.

В Вашем случае, можно отключить перадачу NotifyObject, т.е.

CreateNewWindowEdit(null, 'wnd_InvoiceEdit', DefaultValues, Attributes);

Также не понял, почему вы не передали атрибут

Attributes('IsCreatedByContractID') = ContractID;

это необходимо.

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

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

Добрый день!

нужно добавить в tbl_Workflow поле WorkflowNumber по аналогии с документами, т.е. при создании записи давать ей номер

где мне отловить событие добавления записи в эту таблицу, потому как в датасете в BeforePost он не заходит при запуске бизнес-процесса

или может быть в стартовом элементе БП апдейтить workflow, только где его Action я не знаю, а в каждом бизнес-процессе не вариант прописывать апдейт при старте

подскажите какие-нибудь варианты решения, пожалуйста

Нравится

3 комментария

как вариант - триггер в БД INSTEAD OF INSERT

а вот в конфигурации тоже не нашел, где сохраняется экземпляр БП :confused:
уперся в function WFStartByID(WorkflowID, ParamNames, ParamValues), а точнее в

	if (Assigned(Params)) {
		ID = WorkflowEngine.StartWorkflow(WorkflowUSI, Now, Params);
	} else {
		ID = WorkflowEngine.StartWorkflow(WorkflowUSI, Now);
	}
 
// WorkflowEngine 
function GetWorkflowEngine() {
	var WorkflowEngine = GetAttribute(Connector, WorkflowEngineAttrName);
	if (!WorkflowEngine) {
		WorkflowEngine = System.CreateObject('TSWorkflowLibrary.WorkflowEngine');
		Connector.Attributes(WorkflowEngineAttrName) = WorkflowEngine;
		WorkflowEngine.Connector = Connector;
	}
    return WorkflowEngine;
}

Действительно, лучше и проще всего написать триггер.

Спасибо за ответ, Дмитрий!
триггер решил проблему

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

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

т.е. мне нужно получить:

  • Название
  • Автоматически запускать процесс
  • При
  • В источнике данных
  • Описание
  • Оба фильтра

Как это сделать?

Нравится

4 комментария

сделал, вопрос снимается

Виталий,опишите пожалуйста для других))

напишу один из вариантов, дальше по аналогии, можно что угодно вытянуть

идем в scr_DatasetTriggers

в DatasetTriggers.GetWorkflowParams

дописываем:

for (DatasetTriggerID in this.Triggers) {
		AddParam('DatasetTriggerName', wptString, this.Triggers[DatasetTriggerID].Name);
	}

в данном примере я передаю название, но можно поступить проще, например передать сразу DatasetTriggerID - это запись в таблице: tbl_DatasetTrigger

далее в БП

получаем этот параметр обычным способом:

var ParentDiagram = GetDiagramByItem(ScriptItem);
var DatasetTriggerName = WFGetParamValue(ParentDiagram, 'DatasetTriggerName');

Виталий, большое спасибо за один из примеров))

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

Сразу после создания продажи необходимо вывести окно wnd_OfferingInOpportunitiesDetailTreeArea для ввода и редактирования продуктов в продаже. Как связать это окно с созданной раннее продажей и потом сохранить все введенные в это окно продукты? Смотрите схему в прикрепленных файлах.

Нравится

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

Добрый день.

В настройках открываемого окна можно задать соответствие и выбрать, какое окно будет открыто.

"Maxim Gritsenko" написал:

Добрый день.

В настройках открываемого окна можно задать соответствие и выбрать, какое окно будет открыто.

в этом случае возникает ошибка

Ошибка выполнения Microsoft JScript: 'null' - есть null или не является объектом
в скрипте function ProcessBaseDBEditOnPrepare

файлы прилагаю

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

"Maxim Gritsenko" написал:

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

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

Добрый день.

Можно пробовать из скрипта использовать ShowSelectWorkspaceWindow передавая в параметре attributes необходимые для детали атрибуты, список можно посмотреть в RefreshOfferingInOpportunityDetail.
Что бы получить значения параметров БП, воспользуйтесь GetDiagramByItem(DiagramItem) и WFGetParamValue(DiagramItem, ParamName, DefaultValue).

получается примерно такой код

var Attributes = GetNewDictionary(); 
 
var oppID = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'OpportunityID'); 
var ds=Services.GetSingleItemByUSI("ds_Opportunity");  
 
Attributes.Add('AccountFieldName', 'CustomerID');
Attributes.Add('DetailParentTypeFieldName', 'OpportunityTypeID');
Attributes.Add('WorkspaceDataset', ds);	
Attributes.Add('DetailUserFieldsUSI', 'uf_OfferingInOpportunity');
Attributes.Add('DateFieldName', 'StartDate');
 
var SelectWindow = ShowSelectWorkspaceWindow('wnd_OfferingInOpportunitiesDetailTreeArea', NotifyObject, Attributes);

Но тогда непонятно, в какой атрибут записывать oppID, чтобы окно могло знать какой родительской записи соответствуют данные в окне. И каким должен быть NotifyObject и как его правильно создать?

Андрей, мне кажется лучше будет реализовать задачу таким образом:
1. По идентификатору продажи переходить к записи продажи в раздел.
2. Затем делать активной деталь [Продукты] в продаже.

Т.е. не отдельно вызывать реестр детали, а переходить в раздел и фокусироваться на детали.

Пример кода:

.....
            var SelectWindow = ShowSelectWorkspaceWindow('wnd_OpportunitiesWorkspace', Self, Attributes);
            var wndDataWindow = SelectWindow.ComponentsByName('wndData').Window;
            var pcDetailsControl = wndDataWindow.ComponentsByName('pcDetails');
            var pgOfferingsDetailControl = wndDataWindow.ComponentsByName('pgOfferingsDetail');
            if (pcDetailsControl.Size == 0) {
                        pcDetailsControl.Size = 250;
                        if (pcDetailsControl.ActivePage == pgOfferingsDetailControl) {
                                   pcDetailsControl.ActivePage = pcDetailsControl.Items(0);
                        }
            }
            pcDetailsControl.ActivePage = pgOfferingsDetailControl;

На самом деле вывести окно продуктов после карточки редактирования достаточно просто. Нужно всего 10 строк кода. Пример для счета

var InvoiceID = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'InvoiceID');
	var OfferingInInvoiceGridArea = GetSingleItemByCode('wnd_OfferingsDetailTreeArea', Connector.GenGUID());
	OfferingInInvoiceGridArea.Attributes('ParentItemFieldName') = 'InvoiceID';
	OfferingInInvoiceGridArea.Attributes('DatasetUSI') = 'ds_OfferingInInvoice';
	OfferingInInvoiceGridArea.Prepare();
	OfferingInInvoiceGridArea.Attributes('ParentItemID') = InvoiceID;
	var Dataset = OfferingInInvoiceGridArea.ComponentsByName('dlData').Dataset;
	ApplyDatasetFilter(Dataset, 'InvoiceID', InvoiceID, true);
	Dataset.Open(); 
	OfferingInInvoiceGridArea.Show();

Только почему-то за месяц на этот простейший вопрос никто так и не ответил...

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

"Бондарь Наталия" написал:

Андрей, мне кажется лучше будет реализовать задачу таким образом:

1. По идентификатору продажи переходить к записи продажи в раздел.

2. Затем делать активной деталь [Продукты] в продаже.

Если бы это было последним шагом бизнес-процесса, то можно было бы так сделать. Но если после заполнения продуктов в продаже бизнес-процесс продолжится? Как узнать, что пользователь уже закончил вводить продукты и необходимо продолжить бизнес-процесс? С окном все намного понятнее. Закрыл окно - значит процесс продолжается.

"Рябенко Андрей" написал:Теперь возникает следующий вопрос: как в рамках бизнес-процесса проверить введен ли хоть один продукт в окно продуктов, если нет, то показать сообщение об этом и вернуться к окну с продуктами.

Добавьте элемент скрипт, в котором изначально получите количество продуктов в счете:

var InvoiceID = WFGetParamValue(Diagram, 'InvoiceID'); 
    var Dataset = Services.GetNewItemByUSI('ds_OfferingInInvoice'); 
    ApplyDatasetFilter(Dataset, 'InvoiceID', InvoiceID, true);
    Dataset.Open();      
    var RecordsCount = Dataset.RecordsCount;

Затем в зависимости от количества управляйте показом окна и выводом информационного сообщения.

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

Добрый день!

в таблице tbl_WorkflowItem есть поле DiagramItemType скажите, пожалуйста, в какой момент и где задается значение этого поля

значения этого поля можно посмотреть вот здесь
или scr_SysEnums -> Constants for enum _WorkflowDiagramItemTypeEnum

по этому полю легко определять к какому элементу принадлежит данная запись

Я добавил в БП новый элемент Опросы, все для него прописал, все работает, но DiagramItemType проставляется как у задачи - "7"

как мне для элемента "опрос" задать нужное мне значение?

Нравится

4 комментария

Добрый день!
А какое значение вы хотите поставить? Это ведь элемент типа Action

На изображении проставлены константы для каждого элемента, они соответствуют значениям из
scr_SysEnums -> Constants for enum _WorkflowDiagramItemTypeEnum

Большое спасибо за разъяснение!
Отвечая на вопрос: 9, но теперь это не правильно делать
суть была в том, чтобы можно было в разделе "Процессы" отфильтровать нужные мне элементы и чтобы можно было отталкиваясь от этого значения получать из различных элементов ответственных и авторов

Есть ли тогда возможность завести поле, например, DiagramItemSubType и разделить все элементы типа Action?

Добрый вечер.

Создать поле можно, да. Как вариант, на событии OnInitialize действий находите это действие в таблице tbl_WorkflowItem и записывайте туда подтип.

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

Процесс запускается по событию создания записи.
В записи есть поле ответственный менеджер.
Понятно, что id записи находится в AutoID в параметрах диаграммы.
Первый action после старта задача. Не пойму как мне достать ответственного менеджера из записи и поставить его ответственным в задаче....

Нравится

3 комментария

Здравствуйте, Александр!
Если я Вас правильно поняла, то Вам нужно в задаче подставить своего ответственного, а не того, который подставляется по умолчанию.
Попробуйте следующий алгоритм:
1. создайте параметр диаграммы для хранения ИД этого ответственного, назовите, например, RecordOwnerID.
2. при Старте процесса заполните этот параметр:

var Diagram =  GetDiagramByItem(ActionItem); 
var AutoID = WFGetParamValue(Diagram, 'AutoID');
var RecordOwnerID= GetDatasetFieldValueByID('ds_YourDataset', AutoID, 'OwnerID');
WFSetParamValue(Diagram, 'RecordOwnerID', RecordOwnerID);

3. В скрипте wa_TaskActionScript добавьте строчку (надеюсь, куда именно ее добавить, из кода будет понятно -- до и после комментария "//---" базовый код):

....
	DefaultValues.Add('DueDate', DueDate.getVarDate());
//------ownerID
	if (ActionItem.Name == 'YourTaskItem') {
		DefaultValues.Add('OwnerID',WFGetParamValue(Diagram,'RecordOwnerID')); 
	} 
//------
	WFParamsToDictionary(WorkflowAction, DefaultValues,
		'TypeID', 'OwnerID', 'AccountID', 'ContactID', 
....

День добрый!

Уже сам разобрался путем "рытья форума" и складывания из кусочков кода :-) Но все равно спасибо.
Только вторую часть я сделал через связь с параметром диаграммы...
Так, имхо, как то более правильно или я не прав?

Александр, добрый день!
Совершенно верно, параметры элеменов должны быть связаны с параметрами диаграммы, если необходимо ими обмениваться в/из наружу.

Полезной будет также эта ссылка.

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

Добрый день.
Уже писала про фильтрацию в разделе Процессы в теме
Теперь заметили следующую особенность : в реестре всегда отражается, что Ответственный за элемент процесса = создатель этого элемента. (как на рисунке)
Где закралась ошибка? ведь на самом деле ответственный за указанный элемент следующий по процессу сотрудник, а не его создатель.
Фильтр в разделе по ответственному от этого работает не правильно, и пользователи не могут в разделе увидеть свои текущие элементы процессов.

Нравится

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

А Вы в самом процессе переназначаете Ответственного на следующего? А то, я подозреваю, что при создании элемента процесса ответственный ставится как раз равным автору этого (нового) элемента процесса, т.е. текущему пользователю - тому, кто выполняет этот шаг.

Ответственный указан на уровне диаграммы процесса (прямо в дизайнере элемента задача или при передаче параметров процесса) - и это разные пользователи.
Кроме этого вообще-то возможен вариант когда при создании задачи пользователя поменяли вручную (опять же это разные пользователи).

Попробуйте в sq_Workflow добавить JOIN с tbl_Tasl по по WorkflowID, и затем вытащить колонку OwnerID (ну и соответственно OwnerName). Тогда в ней будет отображаться именно ответственный по задаче, а не по процессу.

Проблема не совсем в этом.
По OwnerID элемента процесса в разделе стоит фильтр - отражаются только элементы, за которые пользователь ответственный. Поскольку в самом поле ответственный неправильно указан , то и этот наложенный фильтр работает не правильно.
Пользователи (не администраторы системы) видят в этом разделе только чужие элементы процесса, которые следуют за их собственными выполненными элементами. Те текущего действительно активного своего процесса пользователь не увидит, пока не выполнит этот элемент.
Мой sq_Workflow в приложенном файле.
Как сделать так, чтобы пользователи видели в разделе все же именно свои элементы?

Здравствуйте.

OwnerID элемента процесса = ID контакта запустившего процесс и != ID контакта ответственного по элементу.

Для того, чтобы в реестре настроить колонку, которая бы отображала именно ответственного элемента задачи процесса, необходимо sq_Workflow привести к следующему виду:

2

Итого получим:

1

Нашла ошибку почему отражался в колонке неправильный Ответственный за элемент !
Проблема была в том, что в запрос OwnerName вытягивался как ответственный процесса.
Необходимо в sq_Workflow добавить в JOIN по WorkflowID добавить tbl_Contact, и затем вытащить колонку OwnerName из этой таблицы.
Тогда в колонке будет отображаться именно ответственный за элемент процесса (создатель элемента, а не самого процесса).

Дополнительно добавила в sq_Workflow JOIN с tbl_Tasl по по WorkflowID, для отражения ответственного по самой задаче.

Теперь касательно фильтра, который накладывается в разделе.
Я делала так, чтобы Создатель процесса видел все элементы по этому процессу + Создатель элемента процесса видел этот элемент + Ответственный за задачу видел свои задачи и элементы процесса по этим задачам.
Запрос в файле.
Вопрос закрыт.

Виктория, хорошо что у Вас все получилось.
Если возникнут дополнительные вопросы - обращайтесь.

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