Добрый день!

Пытаюсь по инструкции создать запись в таблице OpportunityFile. 

При отправке запрос сервер возвращает 500 ошибку Internal Server Error. 

Подскажите, пожалуйста, что не так делаю?

Код запроса:

curl --location --request POST 'https://my.domain.com/0/odata/opportunityfile' \
--header 'BPMCSRF: mbaZawvWrbrf0jub0ayr7O' \
--header 'Content-Type: application/json' \
--header 'Cookie: UserName=username; BPMLOADER=5vurytjra4qxcy2ym1xjsfji; .ASPXAUTH=8FFC3373A07416E90889F9B924E2FFB16B7A75335673C6A585B4FBD7941A36C709548056A1C53030AA0A65C6BC5B9C1F4D5B58195B65BA3BDBFF5F34542A423746FE1329F390C67190FD230C47E8834F89E7D448FC2C14D32C46FF77C6BB64D7A47057BA009B80E4F31093730B41DFDADEF0F70DC3A1A7130D6450ACC136080AB6DACE828A8B68420B4701C983818AFD1CF38573D7DC5E127180D93C8B8D86314CBCFCB86CCEE9E7B5EB1D30248EA25B3AC465E7ADFFA0E891FAB31B2A72627E88A5520BFC625E8701DCF9F7756E1287EA7535F445C13633DE89166AB35BE431C315AD66A10F583CD0D4E31FCC6092701635AAC199D74E9B807A632D9A3BBA2AF3BF0893BB09C9CBDBD3BA110E434B9BFEC744B464D1BF833579317AE62D59D99E58C7C3E40FC03C37BB1BFC401CD958E69A12C3B132DDF1AF7DE58176B26DC6F1DCE91B10CDBDBF98464C7D4047C512010D423A074E4A9EBEC2656F2C45CC76B77EF82C241564FE95494EA754421B45B9BDF2FFAE60853A6F6B44CDA4229AB1FF557FD4; BPMCSRF=mbaZawvWrbrf0jub0ayr7O; BPMSESSIONID=0tt2ubyrc4mo2c4ci5dpwg0w' \
--data-raw '{
    "Name": "FieldValue"
}'

 

Нравится

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

Руслан, ошибка 500 означает, что более подробная информация будет в логах приложения на веб-сервере.

Но, скорее всего, просто не заполнено обязательное поле OpportunityId в объекте, по которому должна осуществляться связь с объектом раздела, куда добавляется файл.

Руслан, ошибка 500 означает, что более подробная информация будет в логах приложения на веб-сервере.

Но, скорее всего, просто не заполнено обязательное поле OpportunityId в объекте, по которому должна осуществляться связь с объектом раздела, куда добавляется файл.

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

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

Такого нет, логи общие для всего сайта. Могут писаться в файлы (Error.log и подобные) или в базу, если так настроено логирование.

В файле Error.log имеется единственная запись:

2020-12-23 08:24:08,710 [1] ERROR IIS APPPOOL\BPMonline Terrasoft.Core.Entities.Events.EntityEventListenersLoader CreateListenerInstance - Error while creating entity event instance of type FileSecurityExcludedUriEventListener
Terrasoft.Core.InstanceActivationException: Error creating an instance of the "Terrasoft.Web.FileSecurity.IFileSecurityExcludedUrisProvider" class ---> Ninject.ActivationException: Error activating IFileSecurityExcludedUrisProvider using binding from IFileSecurityExcludedUrisProvider to method
Provider returned null.
Activation path:
  1) Request for IFileSecurityExcludedUrisProvider
 
Suggestions:
  1) Ensure that the provider handles creation requests properly.
 
   at Ninject.Activation.Context.ResolveInternal(Object scope)
   at Ninject.Activation.Context.Resolve()
   at Ninject.KernelBase.Resolve(IRequest request, Boolean handleMissingBindings)
   at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters)
   at Terrasoft.Core.Factories.ClassFactory.GetInstance[T](Func`1 action)
   --- End of inner exception stack trace ---
   at Terrasoft.Core.Factories.ClassFactory.GetInstance[T](Func`1 action)
   at DynamicInjector7f791e96d519466d85d3463387ed1a0f(Object[] )
   at Ninject.Activation.Context.ResolveInternal(Object scope)
   at Ninject.Activation.Context.Resolve()
   at Ninject.KernelBase.Resolve(IRequest request, Boolean handleMissingBindings)
   at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, String name, IParameter[] parameters)
   at Terrasoft.Core.Factories.ClassFactory.GetInstance[T](Func`1 action)
   at Terrasoft.Core.Entities.Events.EntityEventListenersLoader.CreateListenerInstance(Type classType)

Имеет ли она отношение к проблеме?

К проблеме, скорее всего, относится то, что в запросе нет значения поля OpportunityId, которое в объекте обязательное.

Или с ним будет то же самое?

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

Добрый день!

Перед мной стоит такая задача. Нужно в бизнес-процессе, который запускается периодически (раз в 10 минут), получать список Обращений (Case) по определенному критерию и затем по каждому такому Обращению отправлять письмо. Я читал, что можно сформировать список объектов и передать его каким-то образом в бизнес-процесс, который обрабатывал бы этот список и отправлял письма. К сожалению, не могу найти примеров такого решения. Возможно, кто-то может дать ссылку на описание подобного варианта? Или же есть более удобные способы решения такой задачи? Заранее спасибо за ответ.

Нравится

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

Добрый день.

 

Посмотрите описание решения подобной задачи в статье по работе с коллекциями.

Добрый день.

 

Посмотрите описание решения подобной задачи в статье по работе с коллекциями.

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

 Большое спасибо за Ваш ответ. Очень полезная ссылка.

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

Как сделать отмену сохранения entity?

Реализую пример из руководства Бизнес-логика объектов.

namespace Terrasoft.Configuration.VSSales
{
    using System.Threading;
    using Terrasoft.Core;
    using Terrasoft.Core.Entities;
    using Terrasoft.Core.Entities.AsyncOperations;
    using Terrasoft.Core.Entities.AsyncOperations.Interfaces;
    using Terrasoft.Core.Entities.Events;
    using Terrasoft.Core.Factories;
 
    /// <summary>
    /// Слушатель событий сущности "Коммерческие условия".
    /// </summary>
    [EntityEventListener(SchemaName = "ScPriceType")]
    public class ScPriceTypeEventListener : BaseEntityEventListener
    {
        /// <summary>
        /// Обработчик события перед сохранением записи.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public override void OnSaving(object sender, EntityBeforeEventArgs e) {
            var entity = (Entity)sender;
            var userConnection = entity?.UserConnection;
            var foo = false;  // Здесь будет проверка на условие.
            if (foo) {
                // Всё нормально, сохраняем.
                base.OnSaving(sender, e);
            } else {
                // Условие не выполнено, отмена.
                // Что здесь надо написать?
                sender = null; // Не сработало.
            }
        }
    }
}

 

Нравится

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

Добрый день.

 

Для отмены сохранения попробуйте написать такую строчку:

e.IsCanceled = false;

 

Добрый день.

 

Для отмены сохранения попробуйте написать такую строчку:

e.IsCanceled = false;

 

Спасибо, работает.

public override void OnSaving(object sender, EntityBeforeEventArgs e) {
  var entity = (Entity)sender;
  var userConnection = entity?.UserConnection;
 
  if (CheckRules(userConnection, entity)) {
      // Всё нормально, сохраняем.
      base.OnSaving(sender, e);
  } else {
      // Условие не выполнено, отмена.
      if (!(entity is null)) {
          // Вот так работает отмена сохранения записи.
          e.IsCanceled = true;
      }
  }
}

 

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

Добрый день!

У меня стоит задача обработки событий изменения некоторых реквизитов (Категория, Сервисный договор, Сервис) сущности Case (Обращения). Я могу в  событийном процессе обрабатывать события "Перед сохранением записи", "После сохранения записи", но я не совсем понимаю, как реализовать реакцию именно на изменение некоторых реквизитов. Т.е. если произошла запись, но перечисленные выше реквизиты не изменились, то ничего делать не нужно. Логика подсказывает, что нужно иметь "снимок" объекта до сохранения и сравнить его с значениями после. Как же это сделать? Заранее спасибо за помощь.

Нравится

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

На событие CaseSaving получаете в параметр старое значение поля:

 

AccountOldId = Entity.GetTypedOldColumnValue&lt;Guid&gt;("AccountId");
return true;

 

На событие CasеSaved уже можно сравнивать полученный параметр с новым значением

 

var NameEntity = new Entity(Entity);
if (NameEntity.FetchFromDB(Entity.PrimaryColumnValue)) {
	Guid accountId = NameEntity.GetTypedColumnValue&lt;Guid&gt;("AccountId");
 
	if ((AccountOldId != accountId)  { 
               ....
    }
 
}
return true;

 

Смотрите в сторону объекта Case пакета Case. на событие CaseSaving. Так же есть метод в процессе IsStatusChanged. 

 

Еще очень поможет методы событийного процесса объекта Case пакета SLM. Событие так же CaseSaving. Метод GetIsNeedToLogLifecycle() и GetLoggingColumns(). В последнем определяется на какие колонки пишется жизненный цикл обработки обращения. По аналогии я сделал свой журнал обработки обращения со своими колонками.

На событие CaseSaving получаете в параметр старое значение поля:

 

AccountOldId = Entity.GetTypedOldColumnValue&lt;Guid&gt;("AccountId");
return true;

 

На событие CasеSaved уже можно сравнивать полученный параметр с новым значением

 

var NameEntity = new Entity(Entity);
if (NameEntity.FetchFromDB(Entity.PrimaryColumnValue)) {
	Guid accountId = NameEntity.GetTypedColumnValue&lt;Guid&gt;("AccountId");
 
	if ((AccountOldId != accountId)  { 
               ....
    }
 
}
return true;

 

Владимир Соколов,

 Большое спасибо за Ваш ответ. Буду разбираться.

Алексей Следь,

 Большое спасибо за Ваш ответ. Буду разбираться.

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

Добрый день!

Периодически возникают задачи для реализации их в системе.

Ищу людей, заинтересованных в сдельной работе.

Важен опыт внедрения и разработки. Объем программирования небольшой. Основной объем задач - разработка / доработка форм, кейсов, процессов.

Нравится

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

Добавляю данные в бизнес-процессе через задание сценарий. Делаем многострочный Insert

var insCertificateData = new Insert(UserConnection).Into("NavCertificateData");
foreach (var entity in navCertificateData)
{
	insCertificateData.Values()
		.Set("NavCertificate", Column.Parameter(certificateId))
		.Set("NavProduct", Column.Parameter(entity.NavProduct ))
		.Set("NavDiametr", Column.Parameter(entity.NavDiametr))
		.Set("NavMarka", Column.Parameter(entity.NavMarka,))
		.Set("NavNippelAssembly", Column.Parameter(entity.NavNippelAssembly))
		.Set("NavQuantity", Column.Parameter(entity.NavQuantity))
		.Set("NavWeight", Column.Parameter(entity.NavWeight))
		.Set("NavMinUES", Column.Parameter(entity.NavMinUES))
		.Set("NavMaxUES", Column.Parameter(entity.NavMaxUES))
		.Set("NavMinLength", Column.Parameter(entity.NavMinLength))
		.Set("NavMaxLength", Column.Parameter(entity.NavMaxLength))
		.Set("NavDK", Column.Parameter(entity.NavDK))
		.Set("NavBend", Column.Parameter(entity.NavBend))
		.Set("NavKTP", Column.Parameter(entity.NavKTP))
		.Set("NavCompanyGrafit", Column.Parameter(entity.NavCompanyGrafit));
}
insCertificateData.Execute();

В основном все типа string. В значении NavNippelAssembly иногда приходит EmptyString. И в этом случае получаем ошибку 

"Для параметра \"P5\" со значением null необходимо указать тип данных"

Собственно есть Column.Parameter(Object,DataValueType). Полагаю, что надо его использовать, но как указать этот самый DataValuType? Тип строка  

Нравится

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

Алексей Следь,

Посмотрите обсуждение в этой теме.

Для установки null можно использовать Column.Const(null)

Николай Кузьмин,

Так у меня ж не всегда null и 5 полей, где может быть string.Empty

Алексей Следь,

Посмотрите обсуждение в этой теме.

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

 .Set("IndustryId", ((IndustryIdParameter!=Guid.Empty)?Column.Parameter(IndustryIdParameter):Column.Const(null)))

Ну, или проверять условие и если не выполняется, не производить добавление к формируемому запросу этого Set, тогда в SQL-запросе вообще не будет упоминания этого пустого поля.

Мда, как всегда решение на поверхности лежало. 

Александр, по мне правильней тогда делать сравнение не со string.Empty, а проверять stringIsNullOrEmpty(). А т.к. табличка у меня нуллы не поддерживает, то все пришло к такой конструкции

.Set("NavProduct", (string.IsNullOrEmpty(entity.NavProduct)? Column.Parameter(string.Empty) : Column.Parameter(entity.NavProduct)))

 

Алексей, если всё так, как описали, то зачем вообще два раза писать Column.Parameter и проверять на Empty? Можно только на null при помощи «??», как предложили тут:

.Set("NavProduct", Column.Parameter(entity.NavProduct ?? string.Empty))

 

Александр, учитывая источник данных, лучше проверять на Null и Empty. В любой момент Null может стать пустой строкой.

Так пустая строка в итоге и пишется, её же не надо на такую же заменять, можно сразу в параметр.

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

Добрый день!

Подскажите, пожалуйста, где используется пользователь с именем SysPortalConnection и можно ли его отключить?

Нравится

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

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

Логин и пароль этого пользователя при этом используются в ядре при обращении к AppConnection, там они считываются из внутреннего Web.config из значений параметров UserManagementSauName и UserManagementSauPassword.

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

 

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

Установлено дополнение Excel reports builder for Creatio

https://marketplace.terrasoft.ru/app/excel-reports-builder-creatio

При установке ошибок не было, дополнение установлено успешно.

 

При попытке добавить запись в раздел сразу открывается карточка редактирования, при этом в консоли наблюдаются ошибки:

Изображение удалено.

Ну и далее ничего сделать нельзя.

Версия системы: 7.16.4.1731

 

Прошу подсказать как исправить.

Спасибо.

 

Нравится

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

Сергей, добрый день!

 

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

 

Также уточните продукт Creatio для воспроизведения ошибки.

Переустановку приложения выполнял несколько раз, результат один и тот же... ошибка.

Продукт: bpmonline sales enterprise & marketing & service enterprise

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

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

Добрый день

 

Есть интересная задача. Надо в БП по событию подключится к стороннему серверу 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;

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

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

 

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

 

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

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

как получить последние номера банковских карт 

4444666699997777 

как получить последние 4 числа?

Нравится

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

Grigor Sargsyan,

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

Подробнее о разработке пользовательского макроса можно почитать на Академии по этой ссылке.

Уточните, номер карты хранится в текстовой или строковой переменной?

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

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

в печатных формах 

Носуля Роман Викторович,

по моему целочисленное или строковой 

Grigor Sargsyan,

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

Подробнее о разработке пользовательского макроса можно почитать на Академии по этой ссылке.

Григор, можно поступить более универсально: создать новое текстовое поле в этом же объекте и при создании записи или изменении поля с полным номером вычислять последние 4 цифры и записывать в это поле. Это можно сделать во встроенном или отдельном БП или даже в триггере (если записи в таблице могут создаваться/меняться напрямую в базе).

В БП придётся вычислять скриптом, поскольку такой функции элемент «Формула» не поддерживает. В скрипте можно использовать C#-функцию Substring:

var last4 = cardnumber.Substring(cardnumber.Length - 4);

 

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

тоисть source code ?

Да, если в формуле использовать эту функцию не получится, использовать элемент-скрипт.

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