Копирование продуктов в бизнес-процессе

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

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

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