Добрый день

 

Есть интересная задача. Надо в БП по событию подключится к стороннему серверу MS-SQL и выполнить хранимую процедуру с двумя параметрами, которая вернет нам таблицу данных. Далее эту таблицу данных сохранить в кастомном разделе в системе и настроить связи с другими объектами.

Затык именно в подключении к стороннему серверу БД и вызове процедуры.

В MSSMS это выглядит как:

EXECUTE [dbo].[GetDataForCRM] @nomer,@date 

 

Нравится

8 комментариев
Лучший ответ

Добрый день!

Пробовали ли настраивать линкованные серверы? Если получится подключить сторонний сервер, то можно будет отправлять на него sql-запросы.

Добрый день!

Пробовали ли настраивать линкованные серверы? Если получится подключить сторонний сервер, то можно будет отправлять на него sql-запросы.

Указать имя сервера

Логин и пароль

Разрешить RPC для вызова ХП

Спасибо, помогло, частично. в MSSMS могу вызвать как

EXEC [LinkedServer].[LinkedDB].[dbo].[GetDataForCRM] @nomer,@date 

Как передать что надо вызывать на связанном сервере? Если я указываю полный путь процедуры, а не только имя, то получаю

EXEC [dbo].[[LinkedServer].[LinkedDB].[dbo].[GetDataForCRM]] @nomer,@date 

 

Алексей, функцию на связанном сервере запускают специальным образом, через OPENQUERY или sp_executesql, см. примеры тут.

SELECT SomeField
    FROM OPENQUERY([YOURSERVER], 'SELECT * FROM [SOMEDB].dbo.fn_SomeRemoteFunction(NULL)') tst

 

Зверев Александр,

т.е. через

StoredProcedure getDataForCRM = new StoredProcedure(UserConnection, "GetDataForCRM")
				.WithParameter("nomer", numberDoc)
				.WithParameter("date", dateDoc) as StoredProcedure;

не выйдет получить данные?

Так запускается хранимка на локальном сервере БД, а вопрос был о запуске на другом, связанном.

 

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

 

Также не очень понятно, Вам нужно хранимую процедуру или таки функцию? Таблицу с результатами может возвращать последняя.

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

В ActivtiyPageV2 для элемента StartDate определён генератор "TimezoneGenerator.generateTimezoneButton"

 

{
 "operation": "insert",
 "parentName": "Header",
 "propertyName": "items",
 "name": "StartDate",
 "values": {
  "bindTo": "StartDate",
  "name": "StartDate",
  "generator": "TimezoneGenerator.generateTimezoneButton",
  "layout": {"column": 0, "row": 1, "colSpan": 12}
 }
},



Определил, что данное свойство не должно быть строкой или функцией (см. ViewGeneratorV2 методы hasItemCustomGenerator и generateItem).

НО если устанавливаю значение например 0 или null для для свойства generator,

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

Свойство generator не было определено в классе Terrasoft.controls.Label

 

Как в замещающей схеме отключить свойство generator для данного элемента?

Нравится

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

В EmailTemplatePageV2 это свойство — именно функция:

{
	"operation": "insert",
	"parentName": "TemplateContaner",
	"propertyName": "items",
	"name": "Body",
	"values": {
		"generator": function() {
			return {
				"className": "Terrasoft.IframeControl",
				"id": "preview-content-iframe",
				"iframeContent": {"bindTo": "BodyToDisplay"}
			};
		}
	}
}

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

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

Добрый день,

 

столкнулась с такой проблемой. Мы используем для црм глобальный поиск elasticsearch:5.6.9.

 

тут полное описание, как было сделано

https://academy.terrasoft.ru/documents/administration/7-16/nastroyka-se…

OS: Ubuntu 18.04

 

Все работало наверное около 2х месяцев. В один прекрасный что-то сломалось. Как раз хотела перевести на Ubuntu 20.04. Разбираться не стала - переустановила 2 машины. И опять счастье на 1,5-2 месяца. Утром позвонили и сказали вчера работало - сегодня уже нет.

 

На первой машине оба раза вылезает ошибка

[2020-12-03T11:26:14,489][WARN ][o.e.d.i.m.TypeParsers    ] field [include_in_all] is deprecated, as [_all] is deprecated, and will be disallowed in 6.0, use [copy_to] instead.

 

Сколько я понимаю, что обновляется что-то.. скорее всего, что лежит в контейнере на второй машине до версии 6,0 (индексы, база данных). А сам elasticsearch версии 5.6.9 .

 

Помогите пожалуйста разобраться.

 

С уважением,

Екатерина.

Нравится

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

Сообщение «[2020-12-03T11:26:14,489][WARN ][o.e.d.i.m.TypeParsers    ] field [include_in_all] is deprecated, as [_all] is deprecated, and will be disallowed in 6.0, use [copy_to] instead.» не является ошибкой, это предупреждение, что какая-то функциональность является устаревшей и не будет работать в новой версии 6.0. Если у Вас используется 5.6.9, то влиять на работу в момент показа сообщения ещё до обновления это не должно.

О причинах лучше уточнить у администраторов сервера. Может, действительно автоматически обновляют.

А если у Вас глобальный поиск версии 1.7, то там в инструкции вообще явно ElasticSearch версии 5.6.8 рекомендуют.

Зверев Александр,

спасибо большое. Нашли ошибку. Память кончилась. Когда ему не хватает память почему-то ломается индексация. Увеличение памяти решило проблему

 

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

В публикации 2 РАЗДЕЛА ОТ ОДНОГО ОБЪЕКТА рассказано как вывести объекты другого раздела.

А мне бы хотелось в новом разделе выводить записи старого в Состояние="Завершено". Есть ли способ это сделать ? Например на раздел выводить содержимое не table БД, а собственного view ?  

Нравится

2 комментария
Лучший ответ

Добрый день.

Я так делала именно через view, то есть создаете нужное представление и его используете в качестве источника данных для раздела.

Из минусов:

1) раздел пришлось регистрировать вручную, так как используется представление, а не таблица

2) некоторые функции раздела пришлось отключить или изменить.

За пример можете взять ещё базовый раздел 'Библиотека процессов' ('Process library').

Добрый день.

Я так делала именно через view, то есть создаете нужное представление и его используете в качестве источника данных для раздела.

Из минусов:

1) раздел пришлось регистрировать вручную, так как используется представление, а не таблица

2) некоторые функции раздела пришлось отключить или изменить.

За пример можете взять ещё базовый раздел 'Библиотека процессов' ('Process library').

Для данной задачи достаточно быстрого фильтра, как мне кажется

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

Добрый день! 

Подскажите, пожалуйста, как добавить файл в приложение используя протокол OData4. Спасибо!

Нравится

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

Руслан, для добавления файлов не используют OData, для этого есть специальный сервис FileApiService. По работе с ним см. темы.

Есть получение, изменение и удаление - https://academy.terrasoft.ru/docs/7-17/developer/integrations_and_api/d…

Почему же нет добавления?

Руслан, уточнил, такая возможность тоже есть.

Через OData для этого понадобится два запроса (POST для создания записи в таблице и PUT для заполнения содержимого файла).

Ваше пожелание зафиксировали, информацию в академии должны дополнить.

Зверев Александр,

Отлично, Александр! Я так тоже пробовал, но при попытке создать запись в объект OpportunityFile возникает ошибка. Подожду что напишут в инструкции. Может какие то детали всплывут.

Руслан Хасанов,

А почему Вы не хотите обратиться в поддержку, чтобы Вам предоставили инструкцию по данному вопросу?

Дело в том, что информация в академии может быть изменена не так быстро, как хотелось бы)

Хорошо, Алла, последую вашей рекомендации.

Руслан Хасанов,

Вы можете также в этом посте подробнее описать, с какой ошибкой столкнулись.

Т.к. не нашел команды добавления файла в приложение, то решил пойти другим путем - создать запись в таблице OpportunityFile, а потом изменить значение колонки с данными. Но при попытке отправить запрос на создание записи выходит ошибка "500 Internal Server Error" и текст сообщения:

{
    "error": {
        "code": "",
        "message": "An error has occurred."
    }
}

Вот примерный код запроса:

curl --location --request POST 'https://my.server.com/0/odata/OpportunityFile' \
--header 'BPMCSRF: wGPAf9dJpOsuoMMZcUufku' \
--header 'Content-Type: application/json' \
--header 'ForceUseSession: true' \
--data-raw '{
    "Name": "Field2Value"
}'

 

Руслан, там говорили о PUT, а не POST для наполнения содержимого.

В документации OData упоминается тоже PUT.

 

 

Зверев Александр,

Не внимательно вы прочитали мое сообщение. Мне надо добавить файл, а не изменить. Поэтому я сначала отравлял POST запрос с пустым полем Data (документация OData), а потом как раз хотел использовать PUT (как указано в документации), для изменения данных.

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

Как минимум, смущает отсутствие названий и значений других полей, в том числе TypeId, Version, Size и OpportunityId для связи с разделом.

Зверев Александр,

Спасибо, Александр, за подсказку. Указал дополнительные поля:

curl --location --request POST 'https://my.server.com/0/odata/OpportunityFile' \
--header 'BPMCSRF: Bu22JsKAnOHOxv1HjfcigO' \
--header 'Content-Type: text/plain' \
--data-raw '{
    "Name": "filename.ext",
    "TypeId": "529BC2F8-0EE0-DF11-971B-001D60E938C6",
    "Version": "1", 
    "Size": "0",
    "ProcessListeners", "0",
    "OpportunityId", "9cbc64b5-2e4c-44ca-b551-58739e6099b7"    
}'

Теперь ошибка другая (415 Unsupported Media Type): 

{
    "error": {
        "code": "",
        "message": "The request entity's media type 'text/plain' is not supported for this resource."
    }
}

Не дает этот запрос создать запись без двоичных данных в теле запроса. Попробую вынести параметры в адресную строку и файл вложить в тело запроса.

Сформировал следующий запрос:

curl --location --request POST 'https://my.server.com/0/odata/OpportunityFile?name=kyoScan-‎4‎.‎23‎.‎2020-‎14‎.‎07‎.‎08.pdf&typeid=529BC2F8-0EE0-DF11-971B-001D60E938C6&version=1&size=98888&ProcessListeners=0&OpportunityId=9cbc64b5-2e4c-44ca-b551-58739e6099b7' \
--header 'BPMCSRF: Bu22JsKAnOHOxv1HjfcigO' \
--header 'Content-Type: application/pdf' \
--data-binary '@/D:/kyoScan-‎4‎.‎23‎.‎2020-‎14‎.‎07‎.‎08.pdf'

Выдает такую же ошибку - 415 Unsupported Media Type.

Пробовал передавать doc и png файлы, так же 415-ая ошибка.

{
    "error": {
        "code": "",
        "message": "The request entity's media type 'application/pdf' is not supported for this resource."
    }
}

 

Если дело только в невозможности загрузить pdf, doc и png, проверьте ещё системные настройки безопасной загрузки файлов, может, там нет нужных типов.

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

Привет. 

Нудно создать редактируемый грида в DataView (по аналогии с "Расписанием" в активностях) из отдельной таблицы.

Насколько я понимаю все сводиться к созданию своего аналога GridData, возможно с логикой из схема "Деталь с редактируемым реестром". Но опять же интересуют детали.

Есть идеи или примеры кода по реализации?

Нравится

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

Андрей, если интересуют детали, как создать деталь с редактируемым реестром, есть в статье. Также шаблоны разных деталей, как редактируемых, так и нет, есть в бесплатном дополнении.

Зверев Александр,

Создание редактируемой детали на странице не проблема, проблема доставание этого грида и помещение его в схему раздела (Section) по соседству с основным.

По соседству — это как? Он должен выводить с фильтром по записи в основном реестре? Так такое уже есть в любом разделе с редактируемой деталью, если в карточке слева открыть панель с вертикальным реестром. Например, раздел «Заказы»:

Зверев Александр,

по соседству с базовым DataView, а именно на новом(DataView), мной созданным.

Пример что имею ввиду под этим показано на скрине, это раздел Активности: 

 

По сути мне нужно в отдельному DateView создать свой Grid и сделать его редактируемым. Но так как аналогичного решения я не заметил в системе, то мне они и нужны, и я был бы признателен за такие или что-то схожее что повысит мое понимание.

Андреев Андрей Сергеевич,

Возможно, раздел "Планирование" похож на ваши задачи?

Андрей, таких не видел. Есть разные дополнения, добавляющие в разделы ещё одну кнопку, включающую режим с каким-то необычным видом, например, бесплатное «Канбан-доска» или два вида «Диаграммы Гантта» (но те платные). Установив, можно увидеть, как происходит добавление компонента и работа в нём с данными в таблице раздела.

Владимир Соколов пишет:

Возможно, раздел "Планирование" похож на ваши задачи?

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

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

Кстати, планируется в интерфейсе пользователя появление новых контролов на Angular? Или всё останется в конфигураторе? 

А есть какие-то конкретные пожелания по недостающим компонентам в мастере раздела или главное, чтобы новые и именно на Angular?

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

Коллеги, привет!

 

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

 

Собственно, упаковка Creatio 7.16.4 full bundle в docker image и запуск связки Redis+Postgres+Creatio особых проблем не вызвала. Но вот по функциональности остаются вопросы.

 

1. Когда я просто пытаюсь войти в конфигуратор, то получаю 404 ошибку (т.е. ссылка на документ по его ID оказалась не найдена - https://localhost/ViewPage.aspx?Id=5e5f9a9e-aa7d-407d-9e1e-1c24c3f9b59a). Тут я "обошел" проблему просто вбив https://localhost/dev и вошел в обновленный конфигуратор. 

 

2. Дальше я попытался перейти в список SVN repos, но оно бесконечно грузится. Ошибка возникает при попытке получить список репозиториев через сервис, который вроде как должен быть, но его нет (https://localhost/ServiceModel/SourceControlService.svc/GetRepositories отдает 404 ошибку).

 

3. Ну, думаю, фиг с ним. Решил загрузить свой пакет из файла и он у меня валится при компиляции с ошибкой error CS0117: 'HttpContext' does not contain a definition for 'Current' на строчке:

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

 

Что-то сильно изменилось в этом плане? Т.е. теперь для того, чтобы плагины работали для .net Core версии их надо как-то адаптировать? Может есть уже какая-то документация на предмет миграции кода или его универсализации?

 

Нравится

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

Максим, по первому вопросу, вероятно, дело в том, что Вы используете версию под Net Core. Там нет частей системы, сделанных на основе интерфейса 5.Х, то есть до версии 7.17 не было раздела «Конфигурация», где его переписали. Странно, что на 7.16.4 удалось войти в обновлённый конфигуратор, возможно, это была какая-то его бета-версия.

 

По второму вопросу не уверен, либо тоже какие-то ограничения этой платформы, либо что-то не так настроили при установке. Как проводится установка на Docker, есть в статье. В любом случае, для более полной поддержки Net Core лучше будет обновиться до 7.17 и проверить наличие сервиса уже там.

 

По третьему, опять же, дело в Net Core. Чтобы сделать универсальный скрипт, работающий и там, и под Net Framework, нужно внести в коде некоторые правки:

Для обеспечения миграции от ASP.NET Framework к ASP.Net Core сервисов, реализованых без наследования базового класса Terrasoft.Web.Common.BaseService, предоставлена возможность получать контекст двумя способами:

  • Не рекомендуемый способ: получать контекст через статическое свойство HttpContext.Current. Для обеспечения легкой миграции от фреймворка ASP.NET Framework к ASP.Net Core нужно добавить в исходный код сервиса с помощью директивы using пространство имен Terrasoft.Web.Http.Abstractions, в котором реализован унифицированный доступ к HttpContext, используя статическое свойство HttpContext.Current. При адаптации старого кода к новому фреймворку достаточно заменить namespace System.Web на Terrasoft.Web.Http.Abstractions.
  • Рекомендуемый способ: получать контекст через IHttpContextAccessor зарегистрированный в DI (ClassFactory) . Этот способ позволяет покрывать код тестами. Подробнее об использовании фабрики классов можно узнать из статьи "Замещающие классы".

Подробнее об этом см. статью.

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

Добрый день.

Как реализовать возможность добавлять одному продукту, по одному прайс-листу несколько цен.

Пример.

цена формируется из двух условий - тип доставки и регион доставки.

Регион доставки - это прайс-лист, а тип доставки это критерий.

Матричный прайс лист

Т.е. Товару мы должны присвоить один и тот же прайс-лист с разными типами доставки.

 

Продукт  |   Регион доставки  |   Тип доставки

Товар1    |   Новосибирск        |   Срочная доставка

Товар1    |   Новосибирск        |   Обычная доставка

Товар1    |   Смоленск               |   Срочная доставка

 

Нравится

1 комментарий
Лучший ответ

Это довольно сложная задача, которая потребует изменений кода во многих местах и еще не факт, что будет работать стабильно. Когда у нас стояла подобная задача, то проще оказалось держать разные PriceLists для разных случаев. Т.е. в данном случае будет свой PL для доставки в Регион1-обычная и отдельный для Регион1-срочная. Тут надо понимать, что PL применяется зачастую в определенных связках (т.е. когда добавляешь продукт к квоте или оппортьюнити). В этом случае как раз задаешь связь с продуктом и выбираешь нужный PL в зависимости от ситуации. Тогда можно сделать некую автоматизацию по определению кретерия и проставления нужного PL в связующую таблицу.

Это довольно сложная задача, которая потребует изменений кода во многих местах и еще не факт, что будет работать стабильно. Когда у нас стояла подобная задача, то проще оказалось держать разные PriceLists для разных случаев. Т.е. в данном случае будет свой PL для доставки в Регион1-обычная и отдельный для Регион1-срочная. Тут надо понимать, что PL применяется зачастую в определенных связках (т.е. когда добавляешь продукт к квоте или оппортьюнити). В этом случае как раз задаешь связь с продуктом и выбираешь нужный PL в зависимости от ситуации. Тогда можно сделать некую автоматизацию по определению кретерия и проставления нужного PL в связующую таблицу.

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

Как я могу передать строковый спец символ вместе с ссылкой?

Добрый день, когда передаю строку вида, которая содержит ссылку

xmlns:xs= \"http://www.w3.org/2001/XMLSchema\"

то на выходе я получаю \"www.w3.org/2001/XMLSchema", без последнего символа \, с строками отличными от данной все работает нормально

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

historyContactInfo = historyContactInfo.Replace(@"\r\n", string.Empty).Replace(@"\", string.Empty).Replace("\"",@" \" +"\"");

 

Пробуя подобное на .net Framework все формируется нормально

Также я пробовал делать замену с помощью символа &quot, все равно не пропускает

Нравится

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

Опишите более подробно, что делаете, что хотели и что вышло.

В системе серверный код компилируется под тот же  .net Framework или .net Core компилятором от Microsoft, отличий быть не должно.

 

Как работать с этим символом, см. тут:

The backslash ("\") character is a special escape character used to indicate other special characters such as new lines (\n), tabs (\t), or quotation marks (\"). If you want to include a backslash character itself, you need two backslashes or use the @ verbatim string: "\\Tasks" or @"\Tasks".

Read the MSDN documentation/C# Specification which discusses the characters that are escaped using the backslash character and the use of the verbatim string literal.

Generally speaking, most C# .NET developers tend to favour using the @ verbatim strings when building file/folder paths since it saves them from having to write double backslashes all the time and they can directly copy/paste the path, so I would suggest that you get in the habit of doing the same.

 

 

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

Может кто использует Clio ? Я так понимаю разработчики заняты, так как на странице GitHub версия исходников 2.0.0.10, при этом указано что последняя версия 2.0.0.9, а при установке через dotnet tool ставиться 2.0.0.12. На вопросы ответов не вижу, рекомендации по ошибкам не как не обрабатываются.

Потому может кто в курсе, при установке пакета делается ли резервная копия конфигурации, и если да то можно ли восстановить еще через Clio?

Нравится

4 комментария
Лучший ответ

Как один из вариантов, да, всё верно.

Александр, по последнему вопросу:

На данный момент для создания резервной копии необходимо самому выгружать пакет/ы с помощью Clio (той версии, которой нужно) и уже после установки новой версии (в случае непредвиденных ситуаций) откатывать на предыдущую версию.

Зверев Александр,

То есть в начале нужно сделать pull для пакетов которые буду обновлять, а потом push для пакетов которые нужно установить?

Как один из вариантов, да, всё верно.

Зверев Александр,

Спасибо

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