Ознакомился со статьей Отладка серверного кода, пытаюсь начать отладку некоторого действия бизнес- процесса.
Например, у меня есть некоторое задание- сценарий, где я пишу -
// Создание экземпляра запроса, добавление в запрос колонок и источника данных.
Select selectQuery = new Select(UserConnection)
.Column("Id")
.Column("Name")
.From("Contact");
// Выполнение запроса к базе данных и получение результирующего набора данных.
using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection())
{
using (IDataReader reader = selectQuery.ExecuteReader(dbExecutor))
{
while (reader.Read())
{
// Обработка результатов запроса.
}
}
}
return true;
При попытке компиляции возникло: ошибок - 3, предупреждений - 2
В ходе кодогенерации компиляция не удалась и файлов символов, соответственно, нет - точки останова не срабатывают:
The breakpoint will not currently be hit.
No symbols have been loaded for this document.
Сгенерированный код, который я пытаюсь отладить в Visual Studio -
Нужно- ли определять директивы using в действии "Задание- сценарий"?
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using Terrasoft.Common;
using Terrasoft.Core;
using Terrasoft.Core.DB;
using Terrasoft.Core.Entities;
...
Если да, то они тоже попадут в тело метода ScriptTask1Execute.
Как правильно написать серверный код в действии "Задание- сценарий", чтобы его можно было отладить в MS Visual Studio? Особенно, если на вход действия подается некий параметр события, который в IDE определяет как undefined?
В 7.7 есть особенности использования UserConnection в БП.
Подробнее можно ознакомиться в теме: http://www.community.terrasoft.ru/forum/topic/14645
Директивы using указываются один раз для всего процесса. Делается это структуре процесса (боковая панель).
Также можно указать флаг принудительная компиляция для элемента или процесса и он будет всегда компилироваться, тогда Вам не нужно будет использовать данный подход.
Возникла некоторая необходимость отладить код в элементе бизнес- процесса "Задание- сценарий", а именно - там есть определенный запрос к базе данных, расчеты и последующая вставка результатов в ряд таблиц.
В ..\Terrasoft.WebApp\Web.config настроил выгрузку исходных кодов C# в процессе кодогенерации -
...
...
Подключил библиотеки Terrasoft.
Собственно, пытаюсь отладить какой- нибудь простой запрос, вроде такого -
...
var select = new Select(userConnection)
.Column("Id")
.Column("Name")
.From("Contact");
...
- возникает вопрос, как настроить класс UserConnection... Был бы весьма признателен за информацию, без отладчика весьма и весьма грустно.
Алексей, для отладки есть еще ряд флагов в конфигах. Подробнее на скриншоте:
Для отладки нужно приаттачиться VS к вашему процессу w3wp.exe (если их несколько, то можно различать по имени пользователя, от которого запущен пул приложения)
В студии открываете выгруженный код, ставите точки останова в нужных местах.
Для получения текста запросов:
- для классов Select,Update,Delete есть метод GetSqlText() и свойство BuildParametersAsValue, которое нужно устанавливать в true для явного получения параметров;
- для классов ESQ есть метод GetSelectQuery(UserConnection), который возвращает объект класса Select, а из него уже можно получить текст запроса.
Также для просмотра запросов к БД можно использовать SQL Profiler
Хотел бы поинтересоваться относительно возможности инициирования бизнес- процессов событиями страницы.
Например, у меня на карточке добавления /редактирования должника есть справочник физ. лиц, каждый из них имеет ряд договоров с возможными задолженностями. Я бы хотел по событию выбора физ. лица из справочника инициировать бизнес- процесс выборки всех договоров выбранного физ. лица и просуммировать все задолженности по всем выбранным договорам, затем заполнить соответствующие поля на карточке добавления /редактирования должника.
Альтернативный вариант - проделать все то же, но по событию добавления записи. Данный вариант меня не совсем устраивает, поскольку в таком случае я не смогу увидеть задолженности перед добавлением записи, проверить задолженности без добавления записи.
Существует- ли какое- либо релевантное событие страницы (onchange на выпадающем списке, например), которое могло бы инициировать бизнес- процесс?
Ну, наверное, пересчет через процесс - ресурсоемкое удовольствие.
Не легче сделать агреггирующую колонку в реестре раздела "Контакты"?
Как вариант, Вы можете настроить "Итоги" в разделе "Договоры", и построить динамическую группу, в которой Вы будете изменять контакт.
Тем не менее, вот некоторые размышления на эту тему, если у кого- нибудь появится спортивный интерес - в модели представления можно настроить зависимость колонки и добавить метод- обработчик (см. Как добавить вычисляемое поле), из которого запускать бизнес- процесс, как описано, например, здесь - Запуск процесса с параметрами Действием в карточке
Подскажите, как отловить сигнал завершения БП со страницы раздела. БП запускается с этой же страницы. А после получения сигнала о завершении, выполнить произвольную функцию.
Вы можете вызвать следующий web сервис:
http[s]://<адрес_приложения_bpm'online>/0/ServiceModel/ProcessEngineService.svc/CollectionOfStatistics/Execute?ResultParameterName=RESULTPARAMETERNAME&CreatedById=CreatedById&CalcForPeriod=forPeriod
В результате на клиент придет значение результирующего параметра RESULTPARAMETERNAME после получения которого, Вы можете выполнить произвольную функцию.
Более подробно о сервисе ProcessEngineService.svc Вы можете почитать по ссылке
RESULTPARAMETERNAME - параметр процесса с типом "Строка". В Вашем кейсе достаточно будет ограничить длину строки 50 символами.
Здравствуйте, Алексей. Спасибо за ответ. Возможно я что-то делаю не правильно. Воспользывался вашим советом. Вызываю БП со страницы раздела следующим методом:
var CreatedById =this.Terrasoft.SysValue.CURRENT_USER_CONTACT.value;
var Params ="ResultParameterName=ResultProcess&CreatedById="+ CreatedById +"&CalcForPeriod=false";
Terrasoft.AjaxProvider.request({
url:"../ServiceModel/ProcessEngineService.svc/CollectionOfStatistics/Execute?"+ Params,
method:"POST",
scope:this,
jsonData:{},
callback: function(request, success, response){if(success){//Сюда приходит строка с возвращаемым параметром из БП//Вида : //response.responseText =//"<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">"ProcessEnd"</string>"//Как ее правильно обработать? string.replace мне кажется не совсем верным решением}}});
Как правильно обработать строку вида:
response.responseText = ""ProcessEnd""?
И второй вопрос: в БП есть преднастроенная страница. Соответственно, если она вызывается, то страница раздела ничего не ждет. Параметр response.responseText приходит со значением null и метод в котором вызывается БП завешается. Что не так?
Если в процессе есть преднастроенная страница, то должна открыться и пока этот элемент не будет выполнен, результирующий параметр будет null.
Обработка полностью зависит от Вашей задачи. Так как всегда будет приходить один и тот же параметр, то string.replace, как по мне, очень даже корректное решение.
Принцип следующий:
- заместить нужную схему (откуда будет запускаться процесс)
- добавить кнопку/действие
- добавить обработчик
Пример обработчика для запуска процесса по выделенной записи:
runProcess: function(tag) {
var activeRow = this.getActiveRow();
if (!activeRow) {
return;
}
var processArgs = {
sysProcessName: "UsrReadTest",
parameters: {
DocParam: activeRow.get("Id") // DocParam - параметр процесса
}
};
Terrasoft.ProcessModuleUtilities.executeProcess(processArgs);
}
Здравствуйте! Интересует такой момент.
Вот допустим есть бизнесс процесс и в нем есть поле чтение данных по некоторому условию. Если в ходе выполнения процесса этот элемент не находит соответствующюю условиям запись, то в журнале процессов выдает ошибку и процесс останавливается.
Можна ли как-то обработать эту ошибку в процесе? Тоисть, если элемент чтение данных выдает ошибку, то процесс не останавливается, а переходит на другую ветку процесса где создает новую запись, соответствующую условиям проверки в элементе чтения данных, где произошла ошибка.
Добрый день!
Для таких случаев используйте условные потоки и дополнительные проверки на наличие записей.
Исключения можно обрабатывать только в элементе Задание-сценарий.
А как я могу сделать проверку в условном потоке, если я проверяю допустим счет. Я читаю данные счет и по названию фильтрую. Но если такого нет, то Читать данные выдает ошибку и все. Процес останавливается.
Есть вопрос, кто сталкивался с этой проблемой прошу помочь Создал параметр в БП LeadID, дал значения новый идентификатор лида, при создании лида в БП присвоил полю Id значение LeadID, потом в другой карточке сделал изменения и записал в поле лид значение LeadID. Но туда ничего не записывается, в чем проблема?
Создал параметр в БП LeadID, дал значения новый идентификатор лида, при создании лида в БП присвоил полю Id значение LeadID
Уточните, пожалуйста, зачем такая реализация? При добавлении лида элементом "Добавить данные" Id генерируется автоматически. У элемента "Добавить данные" есть параметр "Id созданной записи" - в этом параметре хранится сгенерированный Id. Значение этого параметра Вы сможете потом записать в другие сущности.
В таком случае сделайте наоборот:
1) Создайте параметр бизнес процесса (с типом уникальный идентификатор)
2) После каждого элемента "Добавить данные", который создает лид, используйте элемент "Формула", чтобы заполнить созданный параметр значением Id созданной записи.
В результате, у Вас в параметре будет хранится корректное значение Id лида.
"Радчук Виталий Владимирович" написал:
The INSERT statement conflicted with the FOREIGN KEY constraint "FKkw7kQYErf0GdDIOp9FOjniv8". The conflict occurred in database "BPMOnline", table "dbo.SysProcessData", column 'Id'.
Где-то на ветвлении в процессе используется обычный поток вместо потока по умолчанию/условного потока. В результате две ветки приходят к одному элементу.
еще вопрос...
сделал как сказали:
первая и третья ветки нормально заполняют поле лид в звонок, а во второй ветке лид создается но не записывается в поле лид карточки звонка. В журнале показывает что элемент "Добавить звонок к созданному лиду" отрабатывает. В чем может быть причина?
Предлагаю убедится, какое именно значение передается в поле Лид карточки Звонка. Для этого добавьте во второй ветке автогенерируемую страницу. С помощью элемента Формула передавать на автогенерируемую страницу Id созданного лида.
Также после создания лида попробуйте добавить таймер с задержкой в 1 секунду, после чего передавать значение Id в карточку звонка.
Предлагаю убедится, какое именно значение передается в поле Лид карточки Звонка. Для этого добавьте во второй ветке автогенерируемую страницу. С помощью элемента Формула передавать на автогенерируемую страницу Id созданного лида.
Также после создания лида попробуйте добавить таймер с задержкой в 1 секунду, после чего передавать значение Id в карточку звонка.
Сделал по другому(решил сделать подобно первой ветке), поменял местами запоминание лида со следующими тремя элементами. И о чудо она сработало так как нужно, в чем ошибка я так и не понял(
Используется BPMonline Bank Sales Версия 7.5.0.1275
Возникает проблема с параметром процесса типа Коллекция. Диаграмма процесса приложена.
В первом сценарии делаем выборку данных и результирующую коллекцию присваиваем параметру процесса. Во втором сценарии достаем нужную информацию из выборки через Entity, которую, в свою очередь, вытаскиваем из коллекции по индексу. Сам индекс инкрементируем в Формуле и проверяем не превысил ли он количество элементов в выборке. Так вот, первый шаг проходит хорошо. Все данные достаются и показаны в окне Проверка результата и соответствуют действительности. Но при заходе на второй круг в элементе-сценарии Формирования текста SMS и номера возникает ошибка
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: Значение индекса находится вне допустимого диапазона значений
at Terrasoft.Core.Entities.EntityCollection.FindNodeByIndex(Int32 index)
at Terrasoft.Core.Process.BirthdayQuery.ScriptTask2Execute(ProcessExecutingContext context)
at Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context)
Индекс при этом равен 1. То есть, от коллекции, похоже, осталась только одна запись.
Если же убрать элемент Автогенерируемая страница, то бизнес-процесс заканчивается нормально с индексом, равным количеству элементов в выборке. Но хотелось бы все же видеть, что именно выбирается на каждом шаге. Настройка параметра-коллекции в приложении.
Код сценария Выборка данных у кого ДР
var esqBirthdays =new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Contact");
contactIdFieldName = esqBirthdays.AddColumn("Id").Name;
esqBirthdays.AddColumn("GivenName");
esqBirthdays.AddColumn("MiddleName");
var esqMacrosTypeMonth = EntitySchemaQueryMacrosType.Month;
var esqFilterByMonth = esqBirthdays.CreateFilter(FilterComparisonType.Equal, "BirthDate", esqMacrosTypeMonth, today.Month);
esqBirthdays.Filters.Add(esqFilterByMonth);
var esqMacrosTypeDay = EntitySchemaQueryMacrosType.DayOfMonth;
var esqFilterByDayToday = esqBirthdays.CreateFilter(FilterComparisonType.Equal, "BirthDate", esqMacrosTypeDay, today.Day);
esqBirthdays.Filters.Add(esqFilterByDayToday);
//Есть моб тел?
var esqFilterWithMobilePhone = esqBirthdays.CreateFilterWithParameters(FilterComparisonType.Equal, "[ContactCommunication:Contact].CommunicationType", new Guid("F039972E-470E-457F-9B77-65054B3534B0"));
esqBirthdays.Filters.Add(esqFilterWithMobilePhone);
//Выполнение запроса и получение результирующей коллекции
entitiesBD = esqBirthdays.GetEntityCollection(UserConnection);
numberOfentitiesBDInCollection = entitiesBD.Count;
currentIndexBD =0;
esqSqlText = esqBirthdays.GetSelectQuery(UserConnection).GetSqlText();
returntrue;
Код сценария Формирования текста СМС и номера
Entity element = entitiesBD[currentIndexBD];
Guid contactID = element.GetTypedColumnValueGuid>(contactIdFieldName); string contactName = element.GetTypedColumnValuestring>("GivenName"); string contactMiddleName = element.GetTypedColumnValuestring>("MiddleName"); string BirthDateText = DateTime.Today.ToString("dd MMMM"); string messageText ="Дорогой(ая) "+contactName+"! Росинбанк поздравляет Вас с Днем Рождения "+BirthDateText+" и желает Вам всех благ! Росинбанк"; if(contactMiddleName!=null) messageText ="Дорогой(ая) "+contactName+" "+contactMiddleName+"! Росинбанк поздравляет Вас с Днем Рождения "+BirthDateText+" и желает Вам всех благ! Росинбанк";
SMSTextBD = messageText;
var contactComm =new EntitySchemaQuery(UserConnection.EntitySchemaManager, "ContactCommunication");
var contacctNumberFieldName = contactComm.AddColumn("Number").Name;
var esqFilter1 = contactComm.CreateFilterWithParameters(FilterComparisonType.Equal, "Contact", contactID);
contactComm.Filters.Add(esqFilter1);
var esqFilter2 = contactComm.CreateFilterWithParameters(FilterComparisonType.Equal, "CommunicationType", new Guid("F039972E-470E-457F-9B77-65054B3534B0"));
contactComm.Filters.Add(esqFilter2);
Права доступа можно раздать нескольким записям одновременно по условию фильтрации. Следует убедится, что объект на который необходимо раздать права – администрируется по записям.
Пользователь 1 создал несколько записей на детали “Адреса” на странице редактирования контакта. Права по умолчанию для всех записей на детали – все создают – у всех есть доступ.
Выполнил процесс, который забирает права доступа у всех сотрудников компании и предоставляет только 1 пользователю.
В результате все записи на детали “Адреса” отображаются только у Supervisor’а. Процесс создавал в версии 7.6
Добрый день. Помогите разобраться.
Были созданы раздел "Расходных материалов" и деталь в Обращении "Расходные материалы в обращении". Общее поле в них это "Модель картриджа". Мне необходимо посчитать количество израсходованных.
Я построила БП, но возможно будет какой то другой совет как это сделать.
Проблема заключается в БП, он отрабатывается, но результата я не получаю.
Трудно определить причину судя по скриншотам. Лучше обратиться в техническую поддержку для детального анализа.
Примечания:
1. “Читать данные расходных материалов в обращении”. В условии следует поставить логическое ИЛИ. Id = Id. Добавленной записи ИЛИ Id = Id. Измененной записи.
2. Следует убедится, что поля “Количество пустых”, “Количество” и параметр “Сумма пустых картриджей” имеют тип Целое.
Кроме того, можно добавить автогенерируемую страницу перед каждым из элементов. И с помощью элемента “Формула” передавать на страницу значения, который мы получаем из чтения данных. Таким образом можно определить на каком из этапов происходит сбой.
Добрый день.
Спасибо, Олег, за помощь.
Я изменила условие на ИЛИ в "Читать данные расходных материалов в обращении", и добавила чтение данных после изменения записи, и все заработало.