Добрый день! 

Подскажите, пожалуйста, как добавить файл в приложение используя протокол 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 для пакетов которые нужно установить?

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

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

Спасибо

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

Добрый день, Коллеги!

Получил задачу подключения иерархического отображения записей в гриде.

Однако столкнулся со следующей трудностью:

Контейнер, в котором отображается реестр представляет из себя:

"operation": "insert",
"name": "DataGrid",
"parentName": "gridContainer",
"propertyName": "items",
"values": {
		"itemType": Terrasoft.ViewItemType.CONTAINER,
		"className": "Terrasoft.ContainerList"
........
}

Судя по описанию класса сам по себе он не поддерживает иерархию

Однако, существует расширение класса "HierarchicalContainerList"

Возникают следующие вопросы:

1) Актуален ли класс HierarchicalContainerList на текущий момент. Если ли примеры его явного использования? Сможет ли он поддержать иерархическую структуру?

2) При попытке обращения к нему в виде:

"generator": "ConfigurationItemGenerator.generateHierarchicalContainerList"

Не совсем понимаю как именно задать нужные свойства

nestedItemsAttributeName и nestedItemsContainerId:

generateHierarchicalContainerList: function(config, generatorConfig) {
			var containerListConfig = this.generateContainerList(config, generatorConfig);
			containerListConfig.className = "Terrasoft.HierarchicalContainerList";
			Ext.merge(containerListConfig, {
				nestedItemsAttributeName: config.nestedItemsAttributeName,
				nestedItemsContainerId: config.nestedItemsContainerId
			});
			return containerListConfig;
		}

Могу предположить что в nestedItemsAttributeName должно быть наименование колонки, хранящей id родительской записи.

А вот nestedItemsContainerId, не совсем понятно. Похоже что этот атрибут должен принимать сам Id родительской записи.

 

Коллеги, буду благодарен за любую информацию, спасибо!

Нравится

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

Титаев Александр Николаевич,

Насколько я понял, то вся суть проблемы именно в том, что подбор продуктов использует не Grid, а ContainerList.

 

Реализовывал такую же задачу, но не нашел, как сделать ContainerList иерархичестим. Я полностью менял контрол страницы подбора из ContainerList на Grid а точнее на HierarchialGrid.







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







Поэтому, если найдете решение, как сделать красиво, то буду благодарен за совет, как сделать лучше.

 

Александр, судя по упоминаниям в коде, HierarchicalContainerList  используется для отображения параметров в карточке настройки элемента БП (например, вызова подпроцесса и веб-сервиса). Случаев его применения для реестра не вижу.

 

Для реализации древовидных реестров есть дополнение, но оно платное. Вот обсуждение с тех времён, когда ещё было бесплатным.

 

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

 

В «коробке» есть древовидная деталь структуры проекта, реализованная в схеме ProjectStructureDetailV2:

{
	"operation": "merge",
	"name": "DataGrid",
	"values": {
		"id": "StructureGrid",
		"type": "listed",
		"hierarchical": true,
		"sortColumnDirection": {"bindTo": "disableGridSorting"},
		"hierarchicalColumnName": "ParentId",
		"updateExpandHierarchyLevels": {
			"bindTo": "onExpandHierarchyLevels"
		},
		"expandHierarchyLevels": {
			"bindTo": "expandHierarchyLevels"
		},

Там же приведены функции onExpandHierarchyLevels, clearExpandHierarchyLevels, removeExpandHierarchyLevel и другие, реализующие логику древовидности.

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

Спасибо за подсказку! Да, со схемами и сервисами детали ознакамливался в процессе анализа.

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

Дополнение или очевидное задание иерархии при использовании "Terrasoft.ContainerList" на сколько я понял, не возможно (уже пробовал).

Буду думать как выходить из ситуации. Ещё раз спасибо!

 

Титаев Александр Николаевич,

Насколько я понял, то вся суть проблемы именно в том, что подбор продуктов использует не Grid, а ContainerList.

 

Реализовывал такую же задачу, но не нашел, как сделать ContainerList иерархичестим. Я полностью менял контрол страницы подбора из ContainerList на Grid а точнее на HierarchialGrid.







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







Поэтому, если найдете решение, как сделать красиво, то буду благодарен за совет, как сделать лучше.

 

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

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

Да. CSS поможет с этим.

Но мне не нравится чекбокс так же. В контейнерлисте были видны сразу все чекбоксы и отмечал, что мне нужно. А в гриде просто Да/Нет видно. И только при активации строки появляется чекбокс.

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

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

Вроде незначительно, но для пользователя менее удобно

Владислав, галочки и да/нет в реестре обсуждались тут, также ранее заведена идея об этом.

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

Вопрос такой, нужна функциональность NuGet пакета "System.IdentityModel.Tokens.Jwt", а именно "JwtSecurityTokenHandler" для того что бы из полученного JWT Token (при интеграции с другой системой) получить время создания и время окончания действия Token?

В примерах для написания Unit тестов указано, что установить NuGet пакет можно в проект "Terrasoft.Configuration.Tests.csproj", но это будет на сколько я понимаю только для проекта где мы ставим его, а как сделать что бы это еще и в пакете установилось на продуктивную среду?

Нравится

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

На сколько я разобрался, то самый безопасный способ установить NuGet пакет сторонний это создать пакет-проект, так как он создает отдельную dll и потом через интерфейс помет быть использован в конфигурации. Установка NuGet пакета в основную конфигурацию думаю не имеет смысла так как через пакет перенести это не удастся. Ну и забыл указать что все это я нашел что работает через утилиту clio. Если кому надо то у меня сохранилась запись вебинара с описаниями и примером создания такого пакета-проекта. Может кто еще варианты знает?

Александр, Nuget-пакет подключить к приложению нельзя, но можно извлечь из пакета нужную библиотеку и загрузить в конфигурацию как внешнюю библиотеку.

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

 

Информация о потребности возможности добавить Nuget-пакет в приложение уже зарегистрирована.

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

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

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

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

 

Для бизнес-процесса создал служебный справочник с настройками.

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

Процесс валится у пользователей в связи с тем, что у них нет прав доступа на операцию CanManageLookups.

Как можно продолжить процесс с изменением/добавлением значений только в этом справочнике, не раздавая при этом доступ к CanManageLookups?

Нравится

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

Добрый день.

 

Проверка по правам доступа на операцию CanManageLookups выполняется для всех объектов, которые унаследованы от BaseLookup (Базовый справочник).

 

Можно попробовать сменить родителя у объекта Вашего справочника на BaseObject (Базовый объект).

В этом случае не забудьте добавить поля Name и Description, которые есть в базовом справочнике, но нет в базовом объекте.

 

Внесение таких изменений лучше выполнять на тестовой версии.

Алла, зачем менять родителя, просто во встроенном БП справочника перезатереть пустой функцию проверки CheckCanManageLookups.

public override void CheckCanManageLookups() {
}

Так сделано у ряда коробочных справочников, например, у Department.

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

Да, согласна. В данном случае твое решение является оптимальным.

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

Александр, спасибо за ответ. Буду пробовать в это направлении.

 

Алла Савельева,

Алла, ваш вариант тоже подходит, так как использование справочника было лишь номинальным и для удобства администрирования - поля Name и Desc мне не нужны, так как используются поля других справочников: Account + 2 поля Int.

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

В статье простейшее модальное окно разъяснено как создать и использовать окно в схеме страницы. У меня такой вопрос. Возврат результата из модального окна выполнен в subscribeSandboxEvents страницы ContactPageV2. При обработке в методе подписки не доступны атрибуты страницы привязанные к контенту на странице. Какой есть способ присвоить значение по закрытию окна в поле на странице?

Нравится

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

Есть ли возможность в диалоговом окне применить свои методы? В моих методах сложная логика заполнения полей асинхронно вызванным апи.

А пример модального окна по ссылке выше присвоения arg.test какому нибудь контролу не содержит. У меня this.set... выдает ошибку 'this.Set is not a function' из метода subscribe.SanboxEvents

В качестве модального окна можно применять любое, но с ограничениями (например,нельзя открывать другие модальные окна, поэтому выбор из справочника реализован только в выпадающих списках). По поводу set, сложно сказать, не видя того, что Вы делали. Например, в WizardWarningModalBoxPage для этого создали атрибуты, прибиндили их к визуальным компонентам и меняли значения уже им:

 

"AdditionalInfo": {
	dataValueType: Terrasoft.DataValueType.TEXT,
	size: 500,
	value: ""
}
...
this.set("AdditionalInfo", moduleInfo.additionalInfo);
...
"items": [
			{
		"name": "AdditionalInfo",
		"itemType": Terrasoft.ViewItemType.LABEL,
		"caption": {
			"bindTo": "AdditionalInfo"
		},
		"isMultiline": true
	}
]

 

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