Вопрос

При обновлении до 7.11.2 отвалился DataService. Ничего не поменялось в коде внешнего приложения, всё соответствует документации. Авторизация проходит нормально, но 

https://my.site/0/dataservice/json/reply/InsertQuery - выдает 403-ю ошибку Forbidden.

Подскажите, куда копать?

 

У меня такой же вопрос

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

Добрый день, Алексей!

Проверьте Web.config, а именно значение атрибута UseCsrfToken (https://academy.terrasoft.ru/documents/technic-sdk/7-10/zashchita-ot-csrf-atak-pri-integracii-c-bpmonline), если указано значение true, тогда стоит обратить внимание на формирование хедера запроса.

При включенной csrf защите необходимо отправлять BPMCSRF- токен и BPMCSRF -куки, тогда хедер должен выглядеть следующим образом: 

 

Tsopa,Спасибо. Отключил этот флаг и всё снова работает!

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день!

В рамках интеграции сайта клиента с bpm`online появилась необходимость добавлять с сайта файлы на деталь "Файлы и ссылки" обращения. Для этого был написал веб-сервис для добавления файла, так выглядит метод добавления:

 [OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
        ResponseFormat = WebMessageFormat.Json)]
      public string InserCaseFile(CaseFileData data)
    {
      try
      {
        var appConnection = HttpContext.Current.Application["AppConnection"] as AppConnection;
        var userConnection = HttpContext.Current.Session["UserConnection"] as UserConnection;
        var caseFile = new Terrasoft.Configuration.CaseFile(userConnection);
 
    //    byte[] bytes = Convert.FromBase64String(data.File);
     ASCIIEncoding ascii = new ASCIIEncoding();
    var t = ascii.GetBytes(data.File);
	Stream stream = new MemoryStream(t);
 
          var id = Guid.NewGuid();
          caseFile.SetDefColumnValues();
           caseFile.Id = id;
           caseFile.Name = data.Name;
           caseFile.Size = (int)stream.Length;
           caseFile.SetStreamValue("Data", stream);
           caseFile.CaseId = new Guid(data.CaseId);
          caseFile.Save();
          return "Ok";
      }
      catch(Exception er)
      {
        return er.ToString();
      }
 
    }

Для тестирования с помощью SelectQuery веб-службы DataService был получен уже существующий в bpm файл *.txt, при получении значения из колонки Data в json возвращалась строка в кодировке 7-bit ASCII. 

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

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

У меня такой же вопрос

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

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

Посмотрите, как передается файл в ConfigurationFileApi, метод upload.

И принимается в схеме FileApiService, метод public string Upload(Stream fileContent)

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

Добрый день, коллеги.  Проблема была в TypeId, как и написал Максим. Спасибо.

я имею в виду поле TypeId='529BC2F8-0EE0-DF11-971B-001D60E938C6' (это тип File из таблицы FileType)

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Столкнулся со странной ошибкой во время выполнения UpdateQuery:

{
    "success":false,
    "responseStatus": {
        "ErrorCode":"FormatException",
        "Message": "Expected hex 0x in '{0}'.",
        "Errors":[]
    },
    "rowsAffected":-1,
    "nextPrcElReady":false
}

Кто-нибудь знает, в чем может быть причина? Буду благодарен за подсказки

У меня такой же вопрос

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

"Франчук Виталий" написал:Кто-нибудь знает, в чем может быть причина?

В типе колонки. Дебаггером пройдите по update.setParameterValue(поле, значение, тип) и посмотрите соответствие между указаным типом и тем, какое значение задаётся.

"Варфоломеев Данила" написал:
Франчук Виталий пишет:

Кто-нибудь знает, в чем может быть причина?

В типе колонки. Дебаггером пройдите по update.setParameterValue(поле, значение, тип) и посмотрите соответствие между указаным типом и тем, какое значение задаётся.


Вот функция, которая вызывает UpdateQuery:

updateGame: function(id, newTitle) {
    if (id && newTitle) {
  	window.console.log("New title:", newTitle);
	var updateQuery = Ext.create("Terrasoft.UpdateQuery", {
		rootSchemaName: "clrsGamesAvailable"
	});
	updateQuery.filters.addItem(this.createIdColumnFilter(id));
	updateQuery.setParameterValue("clrsGameTitle", newTitle, Terrasoft.DataValueType.TEXT);
 
	updateQuery.execute(function() {
		window.console.log("Game", id, "was updated.");
	});
    }
}

Там в значении параметра - строка (проверил). Есть аналогичная функция, которая создает объекты с еще двумя параметрами. Конкретно этот параметр задан также. Но с InsertQuery все работает, а с UpdateQuery - нет(

"Франчук Виталий" написал:Но с InsertQuery все работает, а с UpdateQuery - нет(

значит проверить фильтр. что this.createIdColumnFilter(id) формирует (надеюсь id - это guid).
плюс скорее всего после execute будет ошибка. id в коллбеке пропадёт

"Варфоломеев Данила" написал:
Франчук Виталий пишет:

Но с InsertQuery все работает, а с UpdateQuery - нет(

значит проверить фильтр. что this.createIdColumnFilter(id) формирует (надеюсь id - это guid).
плюс скорее всего после execute будет ошибка. id в коллбеке пропадёт

createIdColumnFilter: function(id) {
	return Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Id", id);
}

Фильтр вроде как надо создаеться. Смотрел в теле запроса, который получился - там guid

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Собираюсь использовать службу DataService с клиентской части, так как совсем не разбираюсь в С#. Но в документации для чтения и добавления примеры для JS есть, а для удаления и обновления записей -
нет. Прошу помощи: буду очень признателен за пример удаления и обновления записи через DataService на из клиентской части)

У меня такой же вопрос

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

Для обновления ищите по конфигурации слова "Terrasoft.UpdateQuery"
примеров множество, вот из OpportunityManagementEndOfStagePreconfiguredPage:

var updateQuery = Ext.create("Terrasoft.UpdateQuery", {
	rootSchemaName: "Activity"
});
updateQuery.filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
		Terrasoft.ComparisonType.EQUAL, "Id", activityId));
updateQuery.setParameterValue("Status",
		ConfigurationConstants.Activity.Status.Cancel,
		this.Terrasoft.DataValueType.LOOKUP);
updateQuery.execute(function() {
	this.loadActivities();
}, this);

Удаление по словам "Terrasoft.DeleteQuery", примеров так же очень много, вот из DocumentRelationshipDetailV2:

var deleteQuery = this.Ext.create("Terrasoft.DeleteQuery", {
	rootSchemaName: "DocumentRelationship"
});
var masterRecordId = this.get("MasterRecordId");
var filters = this.getDeleteRelationFilters(masterRecordId, selectedRows);
deleteQuery.filters.add("DocumentsFilter", filters);
deleteQuery.execute(function() {
	this.hideBodyMask();
	this.deselectRows();
	this.reloadGridData();
}, this);

"Максим Шевченко" написал:

Для обновления ищите по конфигурации слова "Terrasoft.UpdateQuery"
примеров множество, вот из OpportunityManagementEndOfStagePreconfiguredPage:

var updateQuery = Ext.create("Terrasoft.UpdateQuery", {
        rootSchemaName: "Activity"
});
updateQuery.filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
                Terrasoft.ComparisonType.EQUAL, "Id", activityId));
updateQuery.setParameterValue("Status",
                ConfigurationConstants.Activity.Status.Cancel,
                this.Terrasoft.DataValueType.LOOKUP);
updateQuery.execute(function() {
        this.loadActivities();
}, this);

Удаление по словам "Terrasoft.DeleteQuery", примеров так же очень много, вот из DocumentRelationshipDetailV2:

var deleteQuery = this.Ext.create("Terrasoft.DeleteQuery", {
        rootSchemaName: "DocumentRelationship"
});
var masterRecordId = this.get("MasterRecordId");
var filters = this.getDeleteRelationFilters(masterRecordId, selectedRows);
deleteQuery.filters.add("DocumentsFilter", filters);
deleteQuery.execute(function() {
        this.hideBodyMask();
        this.deselectRows();
        this.reloadGridData();
}, this);


Большое спасибо!

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Нужно решить следующую задачу:
1. Создать новое рабочее место и раздел в нем.
2. На странице раздела должен выводиться список кастомных объектов, каждый из которых имеет id (внешний, не тот который в базе bpmonline), название и ссылку (должна быть кликабельна). Объекты должны подгружаться со стороннего API.

Первый пункт проблем не доставил. А вот второй... Я сам являюсь одним из разработчиков того стороннего API, поэтому сначала возникла идея просто выводить таблицу внутри айфрейма, однако руководство поставило задачу сделать более "умным" способом.

Я решил попытаться сделать деталь с пользовательскими полями по туториалу (https://academy.terrasoft.ru/documents/technic-sdk/7-10/sozdanie-polzova...) версия системы у меня 7.10б однако, следуя примеру, родительским объектом детали следовало указать Base fields detail из пакета BaseFinance, но у меня он не установлен, и не понятно, установить его, или же не стоит тащить целый пакет ради одного объекта. Пытался по-другому создать делаь и вывести список на страницу раздела, но ничего так и не получилося.

После создания детали и добавления списка на страницу раздела, планировал при загрузке страницы посылать AJAX-запрос по API, потом с помощью службы DataService вытащить существующие объекты, сравнить с получены ответом, и с помощью этой же службы удалить неактуальные и добавить новые, и таким образом обойтись без конфигурационных сервисов, так как совсем не знаком с языком С#.

Но, может быть, я пытаюсь двигаться совсем не туда? Прошу советов и подсказок, так как опыта работы с системою нету, все сложно и запутано, документация местам непонятна, колег, знакомых с системой, нету также. Буду признателен за подсказки, в какую сторону двигаться для реализации даного кейса.

У меня такой же вопрос

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

Я думаю вам правильнее будет сделать самый обыкновенный раздел мастером разделов на основании объекта, с текстовой колонкой для ссылки, и с текстовой колонкой для внешнего id (если он guid), или числовой, если число.
Сделать несколько доработок что бы ссылка была кликабельной и вела во внешнюю систему.

А наполнять данный раздел с помощью интеграции. И тут открывается множество вариантов. Будь то запрос во внешнюю систему, с переодичностью. Либо внешняя система будет сохранять данные в bpm посредством odata каждый раз как таковые будут там созданы. Либо написать веб сервис в bpm и вызывать его из внешней системы. С вариантами интеграции можете ознакомится здесь:
https://academy.terrasoft.ru/documents/technic-sdk/7-10/integraciya-s-s…

"Максим Шевченко" написал:

Я думаю вам правильнее будет сделать самый обыкновенный раздел мастером разделов на основании объекта, с текстовой колонкой для ссылки, и с текстовой колонкой для внешнего id (если он guid), или числовой, если число.
Сделать несколько доработок что бы ссылка была кликабельной и вела во внешнюю систему.

А наполнять данный раздел с помощью интеграции. И тут открывается множество вариантов. Будь то запрос во внешнюю систему, с переодичностью. Либо внешняя система будет сохранять данные в bpm посредством odata каждый раз как таковые будут там созданы. Либо написать веб сервис в bpm и вызывать его из внешней системы. С вариантами интеграции можете ознакомится здесь:
https://academy.terrasoft.ru/documents/technic-sdk/7-10/integraciya-s-si...


Спасибо, буду смотреть и пробовать.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день.
Занимаюсь реализацией интеграции с BPM'Online 7.10 через DataService.

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

Код примерно такой

var list = new Dictionarystring, ColumnExpression>();
foreach(....)
{

        list.Add(c1.Attribute.FieldName, new ColumnExpression()
        {
                ExpressionType = EntitySchemaQueryExpressionType.Parameter,
                Parameter = new Parameter()
                {
                        Value = value,
                        DataValueType = c1.Attribute.DataType
                }
        });
}

var insertQuery = new InsertQuery()
{
        RootSchemaName = EntityName,
        ColumnValues = new ColumnValues()
};
insertQuery.ColumnValues.Items = new Dictionarystring, ColumnExpression>(list);

Как только в список полей для создания попадается поле с датой и временем, то при попытке создать запись выходит ошибка.

Позже я пытался вместо объекта DataTime передавать строку с форматированием которое указано в http://www.community.terrasoft.ru/forum/topic/24597 , но это так же не помогло.

1) Подскажите, пожалуйста, как работать с полями дата и время?
2) Есть ли способ чтобы DataService выдавал более UserFrendly ошибку чем "Удаленный сервер возвратил ошибку: (500) Внутренняя ошибка сервера."? Т.к. выяснение того, что ошибка связана именно с типом DataTime заняло много времени, причем формат запроса корректен и "вроде бы" DataService не должен ругаться на него 500 ошибкой...

У меня такой же вопрос

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

Добрый день!

Для передачи даты через DataService формат должен быть следующий : [""\""2000-12-31T09:41:59\""""""""]. Например:

[quote="Мотков Илья"]

Добрый день!

Для передачи даты через DataService формат должен быть следующий : [""\""2000-12-31T09:41:59\""""""""]. Например:

"Габбазов Искандер Рустемович" написал:На сколько я понимаю ваш пример это кусок "правильного" JSON'а.

нет, JSON тут совсем не при чем.
Это текстовое представление формата TimeStamp,
Оператор @ - интерпритирует строку без управляющих последовательностей, ну и двойные кавычки "схлопываются" по две в одну, на выходе имеем

const string startDate = @"""\""2000-12-31T09:41:59\"""""""""";

Добрый день, Илья!

Другим Ильей :) формат указан правильный:
[quote="Мотков Илья"]
const string startDate = @"""\""2000-12-31T09:41:59\"""""""""";

значение

@"""\""2000-12-31T09:41:59\"""""""""";

Илья, нет, формат все же верный, то есть тайм-стамп в экранированных кавычках, и в кавычках. Я не имел ввиду, что это должен быть валидный json, это просто формат, в виде которого по определенным архтиктурным причинам передается дата в приложении.

"Кот Владимир Владимирович" написал:то есть тайм-стамп в экранированных кавычках, и в кавычках.

вот, смысл прояснился :) понятно, спасибо за пояснения.

На данный момент сделал так:

switch (t.Name)
{
	...
 
	case "DateTime":
		value = @"""\""2000-12-31T09:41:59\"""""""""";

Те кто все-таки забрел в эту тему, достаточно передать DateTime обернутым в экранированные кавычки.

var date = DateTime.Now;
 
insertQuery.ColumnValues.Items.Add("....", new ColumnExpression()
{
	ExpressionType = EntitySchemaQueryExpressionType.Parameter,
	Parameter = new Parameter()
	{
		Value = "\""+date+ ""\""""
Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Пишу PHP модуль для связи сайта с BPM. Есть какой-нибудь Wysywig редактор для построения SQL запросов? Писать такие запросы вручную это просто утомительно. К тому же не ясно, как проконтролировать скомпилированный запрос и обработанный DataService

{

            "QueryType": 0,
            "Columns": {
                "Items": {
                    "Name": {
                        "OrderDirection": 0,
                        "OrderPosition": 0,
                        "Caption": null,
                        "Expression": {
                            "ExpressionType": 0,
                            "ColumnPath": "Name"
                        }
                    },
                    "OwnerLogin": {
                        "OrderDirection": 0,
                        "OrderPosition": 0,
                        "Caption": null,
                        "Expression": {
                            "ExpressionType": 0,
                            "ColumnPath": "[WSysAccount:Contact:Owner].Login"
                        }
                    }
                }
            },
            "AllColumns": false,
            "IsDistinct": false,
            "RowCount": 1,
            "Filters": {
                "FilterType": 6,
                "ComparisonType": 0,
                "LogicalOperation": 0,
                "IsNull": true,
                "IsEnabled": true,
                "IsNot": false,
                "Items": {
                    "FilterByPhone": {
                        "FilterType": 1,
                        "ComparisonType": 9,
                        "LogicalOperation": 0,
                        "IsNull": true,
                        "IsEnabled": true,
                        "IsNot": false,
                        "LeftExpression": {
                            "ExpressionType": 0,
                            "ColumnPath": "[ContactCommunication:Contact].SearchNumber"
                        },
                        "RightExpression": {
                            "ExpressionType": 2,
                            "ColumnPath": null,
                            "Parameter": {
                                "DataValueType": 1,
                                "Value": "54326672198"
                            }
                        }
                    }
                }
            },
            "RootSchemaName": "Contact",
            "OperationType": 0
}';

У меня такой же вопрос

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

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

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

Пусть так, а как проконтролировать какой SQL запрос получится из этого запроса? На примитивном запросе с одним условием еще более менее понятно, а вот делаю объединение запроса и привет. Например, хочу эмулировать запрос
SearchNumber in ("54326672198", "54326672197") /* пользователи и через 8ку заносят номера и через +7*/
ну или так SearchNumber="54326672198" or SearchNumber="54326672197"
и всё, не отрабатывает, пробовал и через RightExpressions[] и задавал два Items. В первом случае возвращается всегда error, а во втором случае если искать в первом item "54326672197" находит. если номер во втором item, то соответствий нет.

а уж такие запросы типа select * from dbo where id in (select id from dbo1 where x=y) я понимаю вообще не сделать

Добрый день, Андрей.
Мне кажется, что в Вашем случае значительно лучше подойдут sql view нежели сложные odata запросы. Просто создайте view в базе данных, которая будет Вам возвращать нужную выборку по простому запросу и обращайтесь к ней (view должна быть связана с объектом в конфигурации).
В описанном Вами случае, вьюха будет представлять union таблицы контактов с необходимыми полями и всеми вариантами написания номера. Запрашиваете у вьюхи номер в любом формате - она возвращает нужные данные контакта.
Соответственно, отдельная вьюха под каждую задачу.

Также, ознакомьтесь со статьями
https://academy.terrasoft.ru/documents/technic-sdk/7-9/rabota-s-obektam…
и
https://academy.terrasoft.ru/documents/technic-sdk/7-9/primery-zaprosov…
Чуть более сложные запросы в комбинации со вьюхой позволят построить выборку практически любой сложности.
Опять же, на вьюху можно навесить тригер в БД. Тогда можно вообще кастомные запросы обрабатывать.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Здравствуйте, пытаюсь написать приложение с использованием Веб-службы DataService, проблема в следующем при добавлении записей где указываю поля с датами возвращается ответ "Удаленный сервер возвратил ошибку: (500) Внутренняя ошибка сервера." если убираю поля с датами запись добавляется, если кто то сталкивался подобным отпишитесь.

У меня такой же вопрос

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

Сталкивались, но в другом сервисе, конфигурационном PurchaseService.
Тогда оказалось, что:

Похоже, дело в формате даты. Вы передаёте:
<ns1:Date>2013-08-20T00:00:00+04:00</ns1:Date>
А надо:
<ns1:Date>2013-08-20T00:00:00</ns1:Date>
Если написать в этом формате, веб-сервис отрабатывает без ошибки.

"Зверев Александр" написал:

Сталкивались, но в другом сервисе, конфигурационном PurchaseService.
Тогда оказалось, что:

Похоже, дело в формате даты. Вы передаёте:
<ns1:Date>2013-08-20T00:00:00+04:00</ns1:Date>
А надо:
<ns1:Date>2013-08-20T00:00:00</ns1:Date>
Если написать в этом формате, веб-сервис отрабатывает без ошибки.


Пробовал в разных форматах
20-09-2016 13:55:00
20.09.2016 13:55:00
9/20/2016 13:55:00
все ровно ошибка 500

А если так, как в моём примере, первом и втором?

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день.
Решил разобраться с DataService(https://academy.terrasoft.ua/documents/technic-sdk/7-8-0/veb-sluzhba-dat...), пробую сделать выборку с бд, например передать номер телефона, и получить ФИО контакта, или наоборот передать ФИО/ID и получить все его номера.
Не получилось.

На SDK все как-то очень не ясно и запутано, и нет примера нормального json запроса.
Есть ли у кого нормальные(простые) примеры json body?
Может кто смог бы написать запрос по тексту выше?
Использую обыкновенные REST клиенты(из хрома и фаерфокса).
Буду очень благодарен.

У меня такой же вопрос

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

Неужели никто не знает как работать с DataService(

Здравствуйте.
Попробуйте смоделировать ситуацию и посмотреть запрос, например, при помощи fiddler. Пример прикрепил.

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