создаю простейший бизнес-процесс:
начало->открытие окна нового договора->открытие окна нового счета ->завершение
в настройки окна счета добавляю галочку вызывать инициализацию окна перед открытием. Все отрабатывает отлично. Но теперь мне нужно чтобы было копирования продуктов из договора в счет. Для этого в настройках окна счета добавляю 2 атрибута окна
IsCreatedByContractID = true
Но тут бизнес процесс вылетает с ошибкой на строчке кода
(Dataset.Values('WorkflowItemID') != NewWorkflowItemID)) {
Пишет Dataset.Values('WorkflowItemID') Набор данных 'Invoices\General\Main Grid\ds_Invoice' не открыт
Как могли эти 2 атрибута окна повлиять на открытие/неоткрытие датасета совершенно не понятно. Как все-таки решить проблему копирования продуктов в этом бизнес-процессе? Вот полная версия функции, где происходит сбой.
/* 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);
}
Файлы с бизнес-процессом прикладываю
Нравится
Добрый день.
Уточните какую версию Вы используете?
Также не совсем понятно, что Вы собираетесь копировать, если после создания документа в нем нет продуктов...
Лучше после создания документа добавить элемент скрипт, и в него перенести логику из действия "Создать счет" раздела "Документы". Там, кроме создания счета, еще после этого и выполняется функция копирования продуктов из документа в счет.
Но учтите, что в текущем варианте, у Вас всегда будет скопировано "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, выполнить скрипт по копированию продуктов.