C#
парсинг
почта
Технические вопросы
7.x

Здравствуйте. Скажите пожалуйста, как можно в bpm'online sales team 7.8.2 в бизнес процессе получить тело входящего письма.
Процесс запускается по сигналу входящего письма, читаются данные письма а вот, как дальше быть? Как распарсить?
Скрин прилагаю.

Нравится

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

Здравствуйте, Максим!

Тело письма хранится в поле Body. Парсить письмо можно элементом "Задание-сценарий", но нужны навыки программирования на языке C#.

"Демьяник Алексей" написал:

Здравствуйте, Максим!

Тело письма хранится в поле Body. Парсить письмо можно элементом "Задание-сценарий", но нужны навыки программирования на языке C#.


Я уже разобрался как получить тело письма. Через параметры бизнес процесса.

Показать все комментарии
C#
внутренняя ошибка сервера
удаление записей
Технические вопросы
7.x

Добрый день! Необходимо с помощью API вывести список контактов и редактировать, удалять их. Вывести получилось, при удалении возникает ошибка "Удаленный сервер возвратил ошибку: (500) Внутренняя ошибка сервера."

Использую http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/WorkWithBpm...
WebResponse response = request.GetResponse() не хочет выполняться. В чем может быть ошибка?
Спасибо.

Нравится

1 комментарий

Добрый день!
Посмотрите, например Fiddler'ом какой ответ от сервера, ведь 500 - это все что угодно. Далее, 99% что там будет ошибка Method not allowed. Это означает, что у вас включен компонент IIS'а WebDAV. Он запрещает выполнение запросов типа DELETE. Для этого нужно выключить этот компонент

Показать все комментарии
C#
JSON
JSON ответ
post
бизнес-процесс
Технические вопросы
7.x

Привет.
Есть POST сервис на C#, который принимает и возвращает json.
Появилась идея, чтоб не регистрировать этот сервис в bpmonline запускать его через бизнес процесс.
Все нормально работает, но вот как передать в БП json тело и получить некий json обратно?
Пока удалось только передать параметры в Url.

Нравится

1 комментарий

Добрый день,
На данный момент в сервисе ProcessEngineService нет такого метода, который бы позволял передавать параметры из тела POST запроса. Есть похожий метод ExecuteProcessWithResultPost но он устанавливает параметры процесса только из URL.

Показать все комментарии
C#
EntitySchemaQuery
insert
MS Visual Studio
select
update
запрос
Технические вопросы
7.x

Коллеги, приветствую.

Есть определенный интерес поизучать классы Select, Insert, Update, EntitySchemaQuery и подробнее
разобраться, как с ними работать.

Чтобы это было проще и быстрее мне бы хотелось иметь возможность работать с ними из MS Visual Studio.

Например, запрос из статьи Использование EntitySchemaQuery для построения запросов к базе данных:

// Создание экземпляра запроса, добавление в запрос колонок и источника данных.
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())
        {
            // Обработка результатов запроса.
        }
    }
}

Собственно, вопрос в конфигурировании класса UserConnection, как его использовать "вне платформы", не в режиме отладки?

Например, в методе Main:

static void Main(string[] args)
{
}

В элементе "Задание- сценарий" я могу получить его таким образом:

var userConnection = Get("UserConnection");

В Web- сервисе WCF:

var userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];

Был бы весьма признателен за информацию.

Спасибо.

--
С уважением, Алексей Быков.

Нравится

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

Здравствуйте.
Если сайт у вас развернуть on-site, то есть, поднят на своем IIS сервере:
Тогда у вас есть возможность написать свой, к примеру, веб-сервис, или даже скрипт-сценарий, и пользуясь статьей по отладке,
http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/ServerCode…
ставить точки останова, и изучать поведение серверного ESQ.
Здесь главное, что бы код был частью системы, поэтому его и нужно писать как часть системы (веб-сервис, бизнес-процесс, и.т.д.), а не сторонние dll,exe,итд.
С автономной программы этого сделать не получится.

Если же сайт on-demand, то есть, развернут как http://имя-сайта.bpmonline.com/
То такой возможности у Вас нет, и со стороннего процесса (программы), Вы никак не обратитесь к ядру системы.
Из сторонних программ написанных Вами в Visual Studio, Вы можете разве что обратится к уже написанным веб-сервисам в рамках структуры сайта, либо же по протоколу OData,
http://academy.terrasoft.ua/documents/docs/technic/SDK/7.4.1/WorkWithBp… что, конечно же, совсем не запросы ESQ.

Александр, спасибо большое за ответ!

Показать все комментарии
C#
select
SQL
подзапрос
Технические вопросы
7.x

Коллеги, приветствую.

Есть некоторый запрос, который возвращает дату платежа и дату последней активности по платежу:

SELECT
        ContactId AS debtorId,
        t1.CreatedOn AS activityDate,
        t2.CreatedOn AS paymentDate
FROM Activity AS t1 INNER JOIN UsrPayments AS t2
        ON t1.ContactId = t2.UsrDebtorId
WHERE t1.CreatedOn = (
        SELECT max(CreatedOn) FROM Activity
        WHERE t1.ContactId = t2.UsrDebtorId
);

И есть некоторый код C#, где с помощью подзапроса я хочу определить дату последней активности по платежу, аналогично тому, как я это делаю выше на native SQL:

var selectNewPayments = (Select)new Select(userConnection)
        .Column("t1", "ContactId")
        .Column("t1", "CreatedOn")
        .Column("t2", "CreatedOn")
        .From("Activity").As("t1")
        .Join(JoinType.Inner, "UsrPayments").As("t2")
        .On("t1", "ContactId").IsEqual("t2", "UsrDebtorId")
        .Where("... здесь подзапрос и обращение к функции max() ...")
        as Select;

Как этот подзапрос написать?

Был бы весьма признателен за информацию.

Спасибо.

--
С уважением, Алексей Быков.

Нравится

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

Здравствуйте!
Все функции описаны по ссылке.

Пример:

SELECT 
C.Name,
(SELECT COUNT(*) FROM Activity A WHERE A.ContactId = C.Id) As ActivityCount
FROM Contact C

Перевод в С#:

var subSelect = new Select(userConnection)
                .Column(Func.Count(Column.Asterisk()))
.From("Activity").As("A")
.Where("C", "Id").IsEqual("A", "ContactId").As("ActivityCount")
var select = new Select(userConnection)
                .Column("C", "Name")
                .Column(subSelect)
.From("Contact").As("C")

Супер! Алексей, спасибо большое.

А можно то же самое, только не Select'ом а с помощью ESQ?

Здравствуйте, Олег!

Примеры доступны по ссылке:
https://www.terrasoft.ru/bpmonlinesdk/UsingEntitySchemaQuery.html

"Шамшин_Олег" написал:А можно то же самое, только не Select'ом а с помощью ESQ?

1. Делаете один esq запрос на содержимое подзапроса, выбираете из него, список Id, или чего вам нужно, в оригинальном посте подзапрос выбирал CreatedOn. Формируете массив этих CreatedOn.

2. В колбеке после возврата результата подзапроса, формируете новый esq запрос, с фильтрацией нужной колонки, в оригинальном посте CreatedOn на вхождение в массив ранее выбранных CreatedOn.

Т.к. фильтрация createColumnInFilterWithParameters спокойно проверит вхождение колонки и в массив.
Пример оторванный от контекста esq, рассматривает только создания фильтра, но такой фильтр подставленный в esq будет работать и в esq:
http://www.community.terrasoft.ru/forum/topic/11497#comment-50859

Показать все комментарии
C#
бизнес-процесс
Задание-сценарий
коллекция объектов
установка параметра
Технические вопросы
7.x

Коллеги, приветствую.

Есть некоторый код C# в действии "Задание- сценарий", читающий из базы данных определенную информацию и, если таковая есть - устанавливает параметр процесса, скажем, isNewPayments.

Далее по процессу у меня есть "исключающее или" и два варианта потоков соответственно.

var userConnection = Get("UserConnection");
Set("isNewPayments", -1);

var selectNewPayments = (Select)new Select(userConnection)
   .Column("t1", "ContactId")
   .Column("t1", "CreatedOn")
   .Column("t2", "CreatedOn")
   .From("Activity").As("t1")
   .Join(JoinType.Inner, "UsrPayments").As("t2")
   .On("t1", "ContactId").IsEqual("t2", "UsrDebtorId")
   .Where("t1", "CreatedOn").IsLess("t2", "CreatedOn")
   .OrderByAsc("t1", "id") as Select;

using (DBExecutor dbExecutor = userConnection.EnsureDBConnection())
{
    using (IDataReader reader = selectNewPayments.ExecuteReader(dbExecutor))
    {
        if(reader.Read()) {
                Set("isNewPayments", 1);
        } else {
                Set("isNewPayments", -1);
        }
    }
}

return true;

Это работает.

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

Если для метода Get я могу указать тип,

var isNewPayments = Get("isNewPayments");

- то как указать тип для метода Set, если аргумент- коллекция объектов?

Был бы весьма признателен за информацию.

Спасибо.

--
С уважением, Алексей Быков.

Нравится

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

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

Уточните, пожалуйста, Вашу задачу.

Вы хотите в параметр процесса записывать коллекцию объектов, или параметр процесса хранит коллекцию и Вы хотите ее получить в элементе "Задание-сценарий"?

Алексей, спасибо за ответ! Вообще же, было бы интересно узнать, как быть и в том, и в другом случае.
Если я оперирую объектами, например, то могу читать параметры бизнес- процесса и устанавливать таким образом:

// Чтение параметра бизнес- процесса
var paramOne = Get<Decimal>("paramOne"); // Тип данных в дизайнере "Дробное число (0,01)"
 
...
paramOne = decimal.Parse(reader["UsrColumnWithData"].ToString());
...
 
// Запись в параметр бизнес- процесса, тип данных не указываю - работает
Set("paramOne", paramOne);

В случае с коллекцией объектов, как использовать Get и Set?

Добрый день!
В новом движке процессов работать можно только с параметрами процесса, либо напрямую с параметрами элементов, на которые настроен маппинг.
Т.е. если есть результат коллекции, с которым необходимо работать в Задание-сценарий подойдет такой пример:
1. Создать параметр процесса типа Строка - TestParam.
2. В значение параметра указать [#Read data 1.First item of resulting collection#].GetTypedColumnValue("Name")
3. В элементе Задание-сценарий работать с параметром.
var contactFullName = Get("TestParam");

Или в свойствах элемента Задание-сценарий убрать птичку "Для интерпретируемого процесса" и писать код как для старого движка.

Здравствуйте, Олег! Спасибо большое за ответ!

Олег, а как быть если ситуация обратная? Сценарий сформировал коллекцию обьектов и её нужно передать в параметр БП?

"Горовецкий Вячеслав Илларионович" написал:

Олег, а как быть если ситуация обратная? Сценарий сформировал коллекцию обьектов и её нужно передать в параметр БП?

Приведите, пожалуйста, пример, где элемент "Задание-сценарий" формирует коллекцию, которая дальше используется по процессу.

Например, я пишу вебсервис, как у вас описано на академии (кстати тот пример не рабочий в 7.7). Этот сервис вызывает бизнес процесс, состоящий из одного элемента типа скрипт, который по заданным параметрам работает с ESQ и формирует, допустим некий список контрагентов (это коллекция неких объектов). Этот список нужно передать в исходящий параметр для выгрузки в качестве результата работы вебсервиса.

А теперь вопрос. Какой должен быть тип исходящего параметра у процесса (Entity или массив Entity) и как в него передать список объектов, полученных в скрипте?

Пример для интерпретируемого процесса:
Важно! В процессе в Usings необходимо подключить:
Terrasoft.Common.Json

var myUserConnection = context.UserConnection;
var esq = new EntitySchemaQuery(myUserConnection.EntitySchemaManager, "Account");
var nameColumn = esq.AddColumn("Name");
var primaryContactColumn = esq.AddColumn("PrimaryContact.Name");
var gorovetskiyContactId = new Guid("CEDA7503-8EAC-4581-B88F-DB537A27EB2C");
var filter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "PrimaryContact", gorovetskiyContactId);
esq.Filters.Add(filter);
var entityCollection = esq.GetEntityCollection(myUserConnection);
if (entityCollection.Count == 0) {
Set("AccountList", string.Empty);
return true;
}
var accounts = new List ();
foreach(var entity in entityCollection) {
var account = new {
Name = entity.GetTypedColumnValue(nameColumn.Name),
PrimaryContact = entity.GetTypedColumnValue(primaryContactColumn.Name)
};
accounts.Add(account);
}
string serialized = Json.Serialize(accounts);
Set("AccountList", serialized);
// пример для компилируемого процесса: AccountList = serialized
// параметр процесса AccountList - тип неограниченная строка – параметр процесса
//Json.Deserialize>(source) – пример, как выполнить обратное действие
return true;

Показать все комментарии
C#
select
SQL
бизнес-процесс
запрос
Технические вопросы
7.x

Коллеги, приветствую.

Есть некоторый запрос, который возвращает информацию по должнику и последней активности, проявленной в отношении него:

SELECT
        TOP 1  
        ContactId as id,
        AC.CreatedOn as activityDate,
        UP.CreatedOn as paymentDate

FROM
        Activity as AC INNER JOIN UsrPayments as UP
                ON AC.ContactId = UP.UsrDebtorId
WHERE
        UP.CreatedOn  > AC.CreatedOn

ORDER BY AC.id ASC;

И есть некоторый код на C#, где с помощью класса Select проделывается то же, но считываются записи по всем активностям:

var selectNewPayments = (Select)new Select(userConnection)
                .Column("t1", "ContactId")
                .Column("t1", "CreatedOn")
                .Column("t2", "CreatedOn")
                .From("Activity").As("t1")
                .Join(JoinType.Inner, "UsrPayments").As("t2")
                .On("t1", "ContactId").IsEqual("t2", "UsrDebtorId")
                .Where("t1", "CreatedOn")
                .IsLess("t2", "CreatedOn") as Select;

Как прочитать только первую запись?

Был бы весьма признателен за информацию.

Спасибо.

--
С уважением, Алексей Быков.

Нравится

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

Нашел, собственно -

var selectNewPayments = (Select)new Select(userConnection)
   .Top(1)
   .Column("t1", "ContactId") 
   .Column("t1", "CreatedOn")
   .Column("t2", "CreatedOn")
   .From("Activity").As("t1")
   .Join(JoinType.Inner, "UsrPayments").As("t2")
   .On("t1", "ContactId").IsEqual("t2", "UsrDebtorId")
   .Where("t1", "CreatedOn").IsLess("t2", "CreatedOn").OrderByAsc("t1", "id") as Select;

Такой запрос возможен???

select count(ID)

   from [dbo].[Case] AS TI

WHERE DATEPART(HOUR, DATEADD(hh, 6, TI.[UsrDueDate])) >=9  and DATEPART(HOUR, DATEADD(hh, 6, TI.[UsrDueDate])) <12

and FORMAT(DATEADD(hh, 6, TI.[UsrDueDate]), N'yyyy.MM.dd') = FORMAT(cast(GETDATE() +1 as date), N'yyyy.MM.dd')

Показать все комментарии
C#
EntityCollection
бизнес-процесс
задание- сценарий
чтение данных
Технические вопросы
7.x

Коллеги, приветствую.

Есть некоторый элемент- действие "Чтение данных", который считывает записи из таблицы и помещает в некоторую результирующую коллекцию ResultEntityCollection.

Как обратиться к этой коллекции из кода C# в действии "Задание- сценарий"?

Был бы весьма признателен за информацию.

Спасибо.

--
С уважением, Алексей Быков.

Нравится

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

Алексей,

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

Олег, спасибо большое за ответ! Посмотрю сегодня.

Олег, не могли бы Вы выложить пример в UTF-8? Был бы весьма признателен.

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

Согласно этому сайту, мой коллега хотел написать следующее:
1. Создать параметр процесса типа Строка - TestParam.
2. В значение параметра указать [#Read data 1.First item of resulting collection#].GetTypedColumnValue("Name")
3. В элементе Задание-сценарий работать с параметром.
var contactFullName = Get("TestParam");

Отлично, спасибо большое за ответ!

Показать все комментарии
C#
DBExecutor
select
SQL запрос
Технические вопросы
7.x

Коллеги, приветствую.

Столкнулся с некоторыми трудностями чтения из базы данных с помощью объекта DBExecutor.

Есть простой кастомный запрос:

 

var userConnection = Get("UserConnection");
Guid addedRecordId = Get("addedRecordId");

var selectQuery = new Select(userConnection)
        .Column("UsrName")
        .From("UsrDebt").As("ud")
        .Where("UD", "Id")
                .IsEqual(Column.Parameter(addedRecordId));

 

Читаю значение UsrName (пример - Помогите с запросом):

 

using (var dbExecutor = userConnection.EnsureDBConnection()) {
        var name = selectQuery.ExecuteScalar(dbExecutor); // строка 46
}

 

Получаю ошибку компиляции -

Если читаю набор данных, как показано в статье Использование EntitySchemaQuery для построения запросов к базе данных:

 

var userConnection = Get("UserConnection");
Guid addedRecordId = Get("addedRecordId");

var selectQuery =
        new Select(userConnection)
        .Column("UsrName")
        .From("UsrDebt").As("ud")
        .Where("UD", "Id")
                .IsEqual(Column.Parameter(addedRecordId));

// Выполнение запроса к базе данных и получение результирующего набора данных.
using (DBExecutor dbExecutor = userConnection.EnsureDBConnection())
{
    using (IDataReader reader = selectQuery.ExecuteReader(dbExecutor)) // строка 48
    {
        while (reader.Read())
        {
            // Обработка результатов запроса.
        }
    }
}

 

Получаю такую ошибку:

Как я могу получить значения из базы данных с помощью объекта DBExecutor?

Был бы весьма признателен за информацию.

Спасибо.

--
С уважением, Алексей Быков.

Нравится

1 комментарий

Добавил преобразование к типу Select, теперь все Ок.

var selectQuery = new Select(userConnection)
    	.Column("UsrName")
    	.From("UsrDebt").As("ud")
    	.Where("UD", "Id")
	.IsEqual(Column.Parameter(addedRecordId)) as Select;
Показать все комментарии
7.4
C#
EntitySchemaQuery
добавление данных
Технические вопросы
7.x

Добрый день,
Необходимо добавлять лида после появления активности. Добавил событийный подпроцесс "после добавления записи" в объект "Активность", добавил подпроцесс и стартовое сообщение
1
Собственно вопросы:
- Как в коде обратиться к значениям колонок добавленной записи? что то вроде this.Entity.GetTypedColumnValue("Title"); ?
- Как используя EntitySchemaQuery добавить запись в таблицу лидов? На sdk примеры использования только на выборку, а на форуме находится только добавление через insert или же примеры использования выборки

Нравится

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

1.

Entity.GetTypedColumnValue<string>("Title");  

2. Добавление ESQ

EntitySchema schema = UserConnection.EntitySchemaManager.GetInstanceByName("Lead");
Entity entity = schema.CreateEntity(UserConnection);
entity.SetDefColumnValues();
entity.SetColumnValue("LeadName", "Новый лид");
entity.Save();

Большое спасибо :smile:

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