кейс:

2 вида обращений: внешние - заводятся оператором по звонку, внутренние - от сотрудников, регистрируются автоматически по емейлу и вебсервисом уходят (планируется для реализации) в itil.

нужно сделать так, чтоб операторам вообще были не видны обращения, пришедшие с ящика для itil

Нравится

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

Мы делали похожее разделение для разных видов поддержки. 



Кратко: бизнес-процесс, реагирующий на смену SLA (или другого параметра) и устанавливающий права на кейс и активности по этому кейсу в зависимости от параметра.



При этом у нас было так, что it-отдел видел и те, и другие обращения

Мы делали похожее разделение для разных видов поддержки. 



Кратко: бизнес-процесс, реагирующий на смену SLA (или другого параметра) и устанавливающий права на кейс и активности по этому кейсу в зависимости от параметра.



При этом у нас было так, что it-отдел видел и те, и другие обращения

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

спасибо. посмотрю. у нас it не будет пользоваться системой пока

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

Добрый день! Прошу подсказать, как выдать права на добавление записи в Средствах связи в разделе Контакты, когда права на саму запись в разделе только на чтение. 

Прикрепленные файлы

Нравится

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

Добрый день.

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

Таким образом, чтобы на все поля, кроме полей средств связи (мобильный телефон, рабочий телефон и email) был доступ на чтение, а для полей средств связи на чтение и редактирование.

Нужно в объекте ContactCommunication убрать наследование прав от Contact. И уже управлять правами на ContactCommunication независимо от Contact

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

В объекте

ContactCommunication 

наследование прав от Контакта очистила, опубликовала изменения. Но при сохранении записи выходит предупреждение, что "

Недостаточно прав для изменения записи в объекте "Контакт".

" . Подскажите пожалуйста, другие варианты?! 

Добрый день.

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

Таким образом, чтобы на все поля, кроме полей средств связи (мобильный телефон, рабочий телефон и email) был доступ на чтение, а для полей средств связи на чтение и редактирование.

Интересно, а синхронизацию средств связи с полями Contact можно сделать на стороне сервера без учёта прав доступа на Contact? Так как редактирующий средства связи может иногда иметь права на редактирование самого Contact



Или, наоборот, не разрешать использовать те средства связи, которые синхронизируются с полями Contact 

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

Интересно, а синхронизацию средств связи с полями Contact можно сделать на стороне сервера без учёта прав доступа на Contact?

Конечно, можно и так реализовать, но тут уже без навыков разработки не сделать.

В конечном счете, все зависит от Вашей бизнес-задачи.

Думаю, что именно из-за того, что должен быть доступ и на Contact, в базовой версии у схемы ContactCommunication указано, что права доступа наследуются от Contact.

Алла Савельева пишет:

Добрый день.

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

Таким образом, чтобы на все поля, кроме полей средств связи (мобильный телефон, рабочий телефон и email) был доступ на чтение, а для полей средств связи на чтение и редактирование.

Добрый день! Коллеги, благодарю за Ваши ответы! Добавление номеров работает  

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

Доброго времени суток, коллеги подскажите пожалуйста есть ошибка которая часто повторяется когда переходишь по преднастроенным старницам нажимаешь на кнопку для перехода к следующей странице в строке браузера урл меняется на следующую страницу при этом переход не осуществляется страница остается текущая в консоли появляется следующая ошибка Cannot set property 'showNextPrcEl' of undefined  (скрине 1). Сделал замещение в модуле CustomProcessPageV2Utilities что бы посмотреть что приходит в объекты currentState и newState в методе completeExecution оба не пустые (скрин 2). в БП процесс движется к следующему элементу если есть или если он конечный то завершается без ошибок. Подскажите  что может быть и как поправить заранее благодарен

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

Нравится

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

Дмитрий, тут Вы писали, что это ещё связано с элементом привязки процесса к объекту. Или « Cannot set property 'showNextPrcEl' of undefined» само по себе, а остановки при попытке привязки сами?

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

Добрый день, коллеги подскажите пожалуйста как по ролям настраивается коммуникационная панель? перестали запускать процессы по нажатию на кнопки, запускаются только под Supervisor подскажите куда капать пробовал выставлять роль системного администратора процессы так же не запускаются. Остальные бизнес процессы запускаются  

Нравится

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

Дмитрий, не очень понятно, Вы что-то настраивали в правах и после этого перестало? О каких именно процессах и кнопках речь? Что-то при нажатии пишется в консоли браузера?

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

Добрый день, подскажите в чем может быть проблема есть БП в котором открываются кастомные страницы по нажатию на кнопки, через раз стопорится на элементе ПРИВЯЗАТЬ ПРОЦЕСС К ОБЪЕКТУ в журнале пишет что выполняется на диаграмме показывает что остановился на этом элементе при это переход по страницам не происходит вечный спинер и в консоли ошибка :

Uncaught TypeError: Cannot set property 'showNextPrcEl' of undefined

Нравится

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

На привязке стопорится, если Id, который привязывается, не определён. 

На привязке стопорится, если Id, который привязывается, не определён. 

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

 

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

if (EntitySchemaId == Guid.Empty || EntityId == Guid.Empty) {
	return false;
}
Guid sysSchemaId;
var entitySchemaIdParameter = new QueryParameter(EntitySchemaId);
var sysSchemaViewSelect = new Select(UserConnection).
		Top(1).
		Column("UId").
	From("VwSysSchemaInWorkspace").
	Where("Id").IsEqual(entitySchemaIdParameter).
	Or("UId").IsEqual(entitySchemaIdParameter) as Select;
using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection()) {
	using (var reader = sysSchemaViewSelect.ExecuteReader(dbExecutor)) {
		while (reader.Read()) {
			sysSchemaId = UserConnection.DBTypeConverter.DBValueToGuid(reader[0]);
			UserConnection.IProcessEngine.LinkProcessToEntity(Owner, sysSchemaId, EntityId);
		}
	}
}
return true;

Как видим, в самом начале идут проверки Id схемы и записи, если что-то из них пустое, выполнение прерывается с отрицательным результатом.

 

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

 

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

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

спасибо за подсказку буду проверять

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

Всем доброго времени! Есть вопрос на примере простенького процесса:

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

 

Если пользователь выбирает вариант:

"Отлично" - шаг должен завершится без обязательного заполнения поля "комментарий".

"Плохо" - шаг должен завершится с обязательным заполнением поля "комментарий".

 

Как проще реализовать проверку факта заполнения поля в зависимости от нажатой кнопки?

 

Нравится

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

Сделайте поле "Комментарий" обязательным

И при кнопке "Хорошо" уберите проверку обязательности

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Сделайте поле "Комментарий" обязательным

И при кнопке "Хорошо" уберите проверку обязательности

t.ponomarov,

спасибо, этот вариант не хотел использовать чтобы не "отлучать" пользователя от информации на главной странице.

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

спасибо, как то не сообразил за эту функцию. 

 

Если в один элемент, то только через преднастроенную страницу.

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

Доброго времени суток! Коллеги, помогите пожалуйста с переводом запроса SQL на С# для использования в конфигурационном веб-сервисе. Необходимо через запрос к веб-сервису по ИНН контакта получать в ответе перечень Id заявок и Названий их статусов. SQL запрос выглядит так:

 

SELECT a.Id, s.Name

FROM dbo.Application a

INNER JOIN dbo.Contact c ON a.ContactId = c.Id

INNER JOIN dbo.AppStatus s ON a.StatusId = s.Id

WHERE c.INNN='1234567890'

 

Нравится

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

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

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

Сделал согласно информации в указанных статьях:

        public string UsrGetAppInfoByINN(string INN) {
            // Результат по умолчанию.
            var result = "";
            // Экземпляр EntitySchemaQuery, обращающийся в таблицу Application базы данных.
            var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");
            // Добавление колонок в запрос.
            esqQuery.AddColumn("Id");
            esqQuery.AddColumn("[AppStatus:Id:StatusId].Name");
            esqQuery.AddColumn("[Contact:Id:ContactId].INN");
               // Фильтрация данных запроса.
            var esqFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "INN", INN);
            esq.Filters.Add(esqFilter);
            // Получение результата запроса.
            string esqSqlText = esqQuery.GetSelectQuery(UserConnection).GetSqlText(); 
            // Возвратить результат.
            return result;

При публикации получаю ошибки "The name 'esq' does not exist in current context в строках:   

            var esqFilter = esq.CreateFilterWithParameters(FilterComparisonType.Equal, "INN", INN);
            esq.Filters.Add(esqFilter);

            esq.Filters.Add(esqFilter);

Так у Вас переменная называется esqQuery, а не esq.

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

заменил esq на esqQuery. Схема публикуется, но на запрос приходит ошибка: 

The server encountered an error processing the request. The exception message is 'Элемент коллекции с именем StatusId не найден'. 

Если убрать эту строку из кода - ругается на следующую ContactId, хотя обе эти колонки есть в таблице Application

        public string UsrGetAppInfoByContactINN(string INN) {
            // Результат по умолчанию.
            var result = "";
            // Экземпляр EntitySchemaQuery, обращающийся в таблицу Application базы данных.
            var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");
            // Добавление колонок в запрос.
            esqQuery.AddColumn("INN");
            esqQuery.AddColumn("[AppStatus:Id:StatusId].Name");
            esqQuery.AddColumn("[Contact:Id:ContactId].INN");
               // Фильтрация данных запроса.
            var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "INN", INN);
            esqQuery.Filters.Add(esqFilter);
            // Получение результата запроса.
            string esqSqlText = esqQuery.GetSelectQuery(UserConnection).GetSqlText(); 
            // Возвратить результат.
            return result;

Что я делаю не так?

Нужно писать названия полей без Id, см. примеры по ссылке выше.

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

не понимаю почему без Id, если колонки в таблице так и называются: ContactId, StatusId, но это помогло, спасибо.

 

Правда теперь после отправки запроса - я получаю пустой ответ на запрос:

{"UsrGetAppInfoByContactINN":""}

 

Александр О,

здравствуйте! Далее Вам необходимо получить коллекцию

var collection = esqQuery.GetEntityCollection(UserConnection);
if(collection.Count > 0)
{
  foreach(var entity in collection)
  {
     var name = entity.GetTypedColumnValue<string>("Name");
  }
}

 Примерно так.

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

var appColName = esqQuery.AddColumn("[AppStatus:Id:StatusId].Name").Name;
 
var collection = esqQuery.GetEntityCollection(UserConnection);
if(collection.Count > 0)
{
  foreach(var entity in collection)
  {
     var name = entity.GetTypedColumnValue<string>(appColName);
  }
}



 

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

не понимаю почему без Id, если колонки в таблице так и называются

Оно в этом случае не пишется, при генерации запроса подставляется автоматически.

Нигрескул Алексей,

с помощью Ваших рекомендаций и дополнительных танцев с бубном схема видоизменилась на:

        public string UsrGetAppInfoByContactSSN(string ContactINN) {
            var result = "";
            var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");
            var appColApplicationId = esqQuery.AddColumn("Id").Name;
            var appColStatus = esqQuery.AddColumn("Status.Name").Name;
            var appColINN = esqQuery.AddColumn("Contact.INN").Name;
            var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "Contact.INN", ContactINN);
            esqQuery.Filters.Add(esqFilter);
            var collection = esqQuery.GetEntityCollection(UserConnection);
                if(collection.Count > 0)
                    {
                      foreach(var entity in collection)
                        {
            var name = ("ApplicationId:").ToString() + entity.GetTypedColumnValue<string>(appColApplicationId)
                   +(", Status:").ToString() + entity.GetTypedColumnValue<string>(appColStatus)
                   +(", INN:").ToString() + entity.GetTypedColumnValue<string>(appColINN);
            return name;
                        }
                     }
            return result;

 В результате в ответ на запрос получаю:

{"UsrGetAppInfoByContactSSNResult":"ApplicationId:cee41684-295b-4384-8dfb-1fa3fdd835cc, Status:Підтверджена, INN:4562378478"}

Но это только одна запись.

Что нужно изменить в схеме чтобы в ответе приходили все найденные записи? Например так:

{"UsrGetAppInfoByContactSSNResult":
"ApplicationId:a913e1c5-6e83-428c-b095-0cf1b3aca5bf, Status:Підтверджена, INN:4562378478"
"ApplicationId:cee41684-295b-438e-8dfb-1fa3fdd835cc, Status:В роботі, INN:4562378478"
"ApplicationId:47a7a0be-4c21-430f-9da9-7d1b658cff92, Status:Відмовлено, INN:4562378478"
}

 

Александр О,

здравствуйте! В таком случае я бы сделал так:

public class AppInfoByContactSSN
{
 public Guid ApplicationId {get;set;}
 public string StatusName {get;set;}
 public string Inn {get; set;}
}
 
public List<AppInfoByContactSSN> UsrGetAppInfoByContactSSN(string ContactINN) {
            var result = new List<AppInfoByContactSSN>();
            var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");
            var appColApplicationId = esqQuery.AddColumn("Id").Name;
            var appColStatus = esqQuery.AddColumn("Status.Name").Name;
            var appColINN = esqQuery.AddColumn("Contact.INN").Name;
            var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "Contact.INN", ContactINN);
            esqQuery.Filters.Add(esqFilter);
            var collection = esqQuery.GetEntityCollection(UserConnection);
                if(collection.Count > 0)
                {
                      foreach(var entity in collection)
                        {
                           result.Add(new AppInfoByContactSSN {
					ApplicationId = entity.GetTypedColumnValue<Guid>(appColApplicationId),
					StatusName = entity.GetTypedColumnValue<string>(appColStatus),
					Inn = entity.GetTypedColumnValue<string>(appColINN)
				});
                        }
                 }
 
             return result;  
}

 

Нигрескул Алексей,

пришлось еще добавить в using System.Collections.Generic;

Но при публикации на строку:

public List<AppInfoByContactSSN> UsrGetAppInfoByContactSSN(string ContactINN) {

выдает ошибку: a namespace cannot directly contain members such us fields or methods.

 

Полный код:

namespace Terrasoft.Configuration.UsrCustomNamespace
{
    using System;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using System.ServiceModel.Activation;
    using Terrasoft.Core;
    using Terrasoft.Web.Common;
    using Terrasoft.Core.Entities;
    using System.Collections.Generic;
 
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
     public class AppInfoByContactSSN
       {
        public Guid ApplicationId {get;set;}
        public string StatusName {get;set;}
        public string Inn {get; set;}
       }
 
        [OperationContract]
        [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
        ResponseFormat = WebMessageFormat.Json)]
 
        public List<AppInfoByContactSSN> UsrGetAppInfoByContactSSN(string ContactINN) {
            var result = new List<AppInfoByContactSSN>();
            var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");
            var appColApplicationId = esqQuery.AddColumn("Id").Name;
            var appColStatus = esqQuery.AddColumn("Status.Name").Name;
            var appColINN = esqQuery.AddColumn("Contact.INN").Name;
            var esqFilter = esqQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "Contact.INN", ContactINN);
            esqQuery.Filters.Add(esqFilter);
            var collection = esqQuery.GetEntityCollection(UserConnection);
             if(collection.Count > 0)
                {
                 foreach(var entity in collection)
                  {
                    result.Add(new AppInfoByContactSSN {
                    ApplicationId = entity.GetTypedColumnValue<Guid>(appColApplicationId),
                    StatusName = entity.GetTypedColumnValue<string>(appColStatus),
                    Inn = entity.GetTypedColumnValue<string>(appColINN)
                   });
                  }
                }
            return result;
     }
}

 

Так у Вас метод не внутри класса, а после, потому и ругается. Метод должен быть в классе, а не в окружающем его namespace.

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

так тоже пробовал, но на строку:

var esqQuery = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Application");

выдает ошибку:

An object reference is required for t he non-static field, method, or property 'User.Connection.EntitySchemaManager'

 

и на строку:

var collection = esqQuery.GetEntityCollection(UserConnection);

выдает ошибку:

'UserConnection' is a type, which is not valid in the given context

 

Александр, значит, у Вас в переменной UserConnection не то, что должно там быть. Попробуйте поискать в конфигурации или на этом  сайте примеры, как правильно делать. А если выдаёт ошибку, то по её тексту можно найти поиском в Интернете более подробное пояснение, что это означает.

 

Пример создания сервиса есть тут. Как минимум, у Вас не хватает наследования класса от BaseService.

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

Всем привет, подскажите кто-то сталкивался с такой проблемой?

 

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

Нравится

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

Александр, ошибка «sectionGroupName» связана с параметром webApplicationPath.

Это путь к веб-приложению, из которого будет вычитана информация по соединению с БД. Необязательный параметр. Если не указан — соединение будет установлено с базой, указанной в строке соединения в файле App.Config приложения. Если указан — соединение будет установлено с БД из файла ConnectionStrings.config веб-приложения. Используется для всех операций, в которых участвует БД.



В Вашем случает аргументом параметра является не корневая директория приложения (пример: C:\Bpmonline\WebApp\CRMBPM), которая содержит файл ConnectionStrings.config, а C:\Bpmonline\WebApp\CRMBPM\Terrasoft.WebApp, что является некорректным.

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

Спасибо.

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

Добрый день!

На карточке Контрагента есть 2 справочных поля "Код отрасли" и "Отрасль", когда указываешь Код отрасли, выходят записи Отрасли в соответствии с кодом.

Настроила бизнес правило "Добавлять фильтр значений в поле" по справочнику "Отрасль".

По бизнес правилу в поле "Отрасли" не отображаются записи более 3х значении, и по полю "Код отрасли" так же. 

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

 

Каждая запись по коду, к примеру, 01, имеет свой "Стат гов ID", которая будет использоваться при интеграции  

 

Прикрепленные файлы

Нравится

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

Айгерим, не совсем понял, как между собой связаны эти 2 справочника и как именно правило настроили. Если в справочнике «Код отрасли» первичное поле для отображения «Название», то почему у Вас несколько со значением 98?

 

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

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

Делаю отчет в FastReport по аналогии со статьей в Академии. 

https://academy.terrasoft.ru/documents/technic-sdk/7-16/primer-nastroyki-otcheta



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

Источники данных.

{
    "ProviderName": "MortgageConclusionDataProvider",
    "Schemas": {
        "MortgageConclusionData": {
            "GroupName": {"DataValueType": 1},
            "Account": {"DataValueType": 1},
            "PreparationDate": {"DataValueType": 7},
            "ConclusionType": {"DataValueType": 1}
        },
        "LevelSecurityData": {
            "MortgageConclusion": {"DataValueType": 0},
            "SublimitTypes": {"DataValueType": 0},
            "NameSublimitTypes": {"DataValueType": 1},
            "Groupe": {"DataValueType": 1},
            "TargetUse": {"DataValueType": 1},
            "AmountLimit": {"DataValueType": 5}
        },
        "LocalizableStrings": {
            "ReportTitle": {"DataValueType": 1},
            ...
        }
    }
}



В сервисе прописываю логику:

 

public Task<ReportDataDictionary> GetData(UserConnection userConnection, IReadOnlyDictionary<string, object> parameters) {
            var filter = ExtractFilterFromParameters(userConnection, _entitySchemaUId, parameters);
            var result = new ReportDataDictionary {
                // Заполнить колонки в отчете.
                ["MortgageConclusionData"] = GetMortgageConclusionData(userConnection, _entitySchemaUId, filter),
                ["LevelSecurityData"] = GetLevelSecurityData(userConnection, _entityLevelSecuritySchemaUId),
                ["LocalizableStrings"] = GetLocalizableStrings(userConnection)
            };
            return Task.FromResult(result);
        }

И при формировании отчета ошибка 

 Error while sending request 

    response status: 500 (Internal Server Error)

    request url: ...FastReportService/CreateReport

    method: POST

    request data: {"reportTemplateId":"a1c1f160-a7c2-56a0-edcb-1101dde5a74e","reportCaption":"Заключение","reportSchemaName":"MortgageConclusion","report...

Через Profiler запросы сформировались, данные есть.

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

Спасибо!

Нравится

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

Судя по сообщению из логов, второе исключение происходит в схеме FastReportService, в функции:

[Obsolete("7.15.3")]
[OperationContract]
[WebGet(UriTemplate = "GetReportFile/{key}")]
public Stream GetReportFile(string key) {
	var data = PopFromSessionData(key);
	string contentDisposition = "attachment; filename*=UTF-8''" + data.Key;
	var reportStream = new MemoryStream(data.Value);
	WebResponseProcessor.AssignFileResponseContent(HttpContextAccessor.GetInstance(), "application/pdf; charset=UTF-8", reportStream.Length, contentDisposition);
	return reportStream;
}
 
private KeyValuePair&lt;string, byte[]&gt; PopFromSessionData(string sessionKey) {
	var data = (KeyValuePair&lt;string, byte[]&gt;)UserConnection.SessionData[sessionKey];
	UserConnection.SessionData.Remove(sessionKey);
	return data;
}

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

[Obsolete("7.15.3")]
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
public string CreateReport(Guid reportTemplateId, string reportCaption, string reportSchemaName, string reportFilters) {
	try {
		var reportParameters = new Dictionary&lt;string, object&gt; {
			["EsqFilters"] = new Dictionary&lt;string, Filters&gt; {
				[reportSchemaName] = JsonConvert.DeserializeObject&lt;Filters&gt;(reportFilters)
			}
		};
		var reportBytes = InternalCreateReport(reportTemplateId, reportParameters);
		return PushToSessionData(new KeyValuePair&lt;string, byte[]&gt;($"{HttpUtility.UrlPathEncode(reportCaption)}.pdf", reportBytes));
	} catch (Exception exception) {
		throw new WebFaultException&lt;FastReportGenerationException&gt;(
			new FastReportGenerationException(exception),
			HttpStatusCode.InternalServerError);
	}
}

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

 

А у Вас response status: 500 только на конкретном отчёте, который разрабатываете, на остальных нормально?

 

По поводу примеров, кроме описанного в академии, в системе есть ещё стандартные «Знаменательные события контакта» и «Полнота наполнения данными». В первом — несколько источников и схема ContactAnniversariesReportDataProvider, в ней интересующая Вас функция:

public Task&lt;ReportDataDictionary&gt; GetData(UserConnection userConnection,
    IReadOnlyDictionary&lt;string, object&gt; parameters) {
    var contactFilter = ExtractFilterFromParameters(userConnection, _contactEntitySchemaUId, parameters);
    var result = new ReportDataDictionary {
        ["Contact"] = GetContactData(userConnection, _contactEntitySchemaUId, contactFilter),
        ["ContactAnniversary"] = GetContactAnniversaryData(userConnection, _contactAnniversaryEntitySchemaUId,
            contactFilter),
        ["LocalizableStrings"] = GetLocalizableStrings(userConnection)
    };
    return Task.FromResult(result);
}

 Но обратите внимание, выше в коде есть сами функции GetContactData и GetContactAnniversaryData, получающие из базы коллекцию данных с указанным фильтром.

Елена, ошибка 500 происходит на сервере, то есть в логах должна быть более подробная информация, где именно в коде она возникает.

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

2020-08-05 18:06:11,849 [192] ERROR  Terrasoft.Web.Common.ServiceModel.ErrorHandler ProvideFault - Internal Server Error
System.ServiceModel.Web.WebFaultException`1[Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException]: Internal Server Error (Дополнительные сведения об ошибке — Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException: Error during report generation).
2020-08-05 18:06:11,864 [192] ERROR  Terrasoft.WebApp.FileWebEventProvider RaiseInternal - Date: 05.08.2020 18:06:11
Date (UTC): 05.08.2020 15:06:11
 
Exception Message: Internal Server Error
Exception Type: System.ServiceModel.Web.WebFaultException`1[Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException]
Exception Source: Terrasoft.Configuration
 
Exception Stack Trace:
   в Terrasoft.Configuration.Reporting.FastReport.FastReportService.CreateReport(Guid reportTemplateId, String reportCaption, String reportSchemaName, String reportFilters)
   в SyncInvokeCreateReport(Object , Object[] , Object[] )
   в System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
   в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
   в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
 
SessionID: xxiqbf2pqlqi4uvge2vbjffb
Request URL: /0/rest/FastReportService/CreateReport
Request Path: /0/rest/FastReportService/CreateReport
Request UrlReferrer: http://192.168.222.228:82/0/Nui/ViewModule.aspx
Request Type: POST
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
User Host Address: 192.168.10.131
User: Supervisor
Is Authenticated: True
Authentication Type: Forms
Is Secure Connection: False
 
Application Version: 7.16.0.4449
 
Application Virtual Path: /0
Application Trust Level: Full
 
Is Local: False
 
Process ID: 3988
Process Name: w3wp.exe
OS Version: Microsoft Windows NT 10.0.14393.0
Net Framework Version: 4.0.30319.42000
DBExecutor Type: MSSqlExecutor
 
&lt;--&gt;
 
2020-08-05 18:06:11,880 [192] ERROR  Terrasoft.Web.Common.ServiceModel.ErrorHandler HandleError - Internal Server Error
System.ServiceModel.Web.WebFaultException`1[Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException]: Internal Server Error (Дополнительные сведения об ошибке — Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException: Error during report generation).
2020-08-05 18:06:11,974 [192] ERROR  Terrasoft.Web.Common.ServiceModel.ErrorHandler ProvideFault - Ссылка на объект не указывает на экземпляр объекта.
System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
   в Terrasoft.Configuration.Reporting.FastReport.FastReportService.PopFromSessionData(String sessionKey)
   в Terrasoft.Configuration.Reporting.FastReport.FastReportService.GetReportFile(String key)
   в SyncInvokeGetReportFile(Object , Object[] , Object[] )
   в System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
   в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
   в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
2020-08-05 18:06:11,974 [192] ERROR  Terrasoft.WebApp.FileWebEventProvider RaiseInternal - Date: 05.08.2020 18:06:11
Date (UTC): 05.08.2020 15:06:11
 
Exception Message: Ссылка на объект не указывает на экземпляр объекта.
Exception Type: System.ServiceModel.FaultException`1[System.NullReferenceException]
Exception Source: 
 
Exception Stack Trace:
 
 
SessionID: xxiqbf2pqlqi4uvge2vbjffb
Request URL: /0/rest/FastReportService/GetReportFile/undefined
Request Path: /0/rest/FastReportService/GetReportFile/undefined
Request Type: GET
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
User Host Address: 192.168.10.131
User: Supervisor
Is Authenticated: True
Authentication Type: Forms
Is Secure Connection: False
 
Application Version: 7.16.0.4449
Application Virtual Path: /0
Application Trust Level: Full
Is Local: False
 
Process ID: 3988
Process Name: w3wp.exe
OS Version: Microsoft Windows NT 10.0.14393.0
Net Framework Version: 4.0.30319.42000
DBExecutor Type: MSSqlExecutor
 
&lt;--&gt;
 
2020-08-05 18:06:11,989 [192] ERROR Terrasoft.Web.Common.ServiceModel.ErrorHandler HandleError - Ссылка на объект не указывает на экземпляр объекта.
System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
   в Terrasoft.Configuration.Reporting.FastReport.FastReportService.PopFromSessionData(String sessionKey)
   в Terrasoft.Configuration.Reporting.FastReport.FastReportService.GetReportFile(String key)
   в SyncInvokeGetReportFile(Object , Object[] , Object[] )
   в System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
   в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
   в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

 

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

Куда смотреть, что проверять?)

 

Судя по сообщению из логов, второе исключение происходит в схеме FastReportService, в функции:

[Obsolete("7.15.3")]
[OperationContract]
[WebGet(UriTemplate = "GetReportFile/{key}")]
public Stream GetReportFile(string key) {
	var data = PopFromSessionData(key);
	string contentDisposition = "attachment; filename*=UTF-8''" + data.Key;
	var reportStream = new MemoryStream(data.Value);
	WebResponseProcessor.AssignFileResponseContent(HttpContextAccessor.GetInstance(), "application/pdf; charset=UTF-8", reportStream.Length, contentDisposition);
	return reportStream;
}
 
private KeyValuePair&lt;string, byte[]&gt; PopFromSessionData(string sessionKey) {
	var data = (KeyValuePair&lt;string, byte[]&gt;)UserConnection.SessionData[sessionKey];
	UserConnection.SessionData.Remove(sessionKey);
	return data;
}

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

[Obsolete("7.15.3")]
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
public string CreateReport(Guid reportTemplateId, string reportCaption, string reportSchemaName, string reportFilters) {
	try {
		var reportParameters = new Dictionary&lt;string, object&gt; {
			["EsqFilters"] = new Dictionary&lt;string, Filters&gt; {
				[reportSchemaName] = JsonConvert.DeserializeObject&lt;Filters&gt;(reportFilters)
			}
		};
		var reportBytes = InternalCreateReport(reportTemplateId, reportParameters);
		return PushToSessionData(new KeyValuePair&lt;string, byte[]&gt;($"{HttpUtility.UrlPathEncode(reportCaption)}.pdf", reportBytes));
	} catch (Exception exception) {
		throw new WebFaultException&lt;FastReportGenerationException&gt;(
			new FastReportGenerationException(exception),
			HttpStatusCode.InternalServerError);
	}
}

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

 

А у Вас response status: 500 только на конкретном отчёте, который разрабатываете, на остальных нормально?

 

По поводу примеров, кроме описанного в академии, в системе есть ещё стандартные «Знаменательные события контакта» и «Полнота наполнения данными». В первом — несколько источников и схема ContactAnniversariesReportDataProvider, в ней интересующая Вас функция:

public Task&lt;ReportDataDictionary&gt; GetData(UserConnection userConnection,
    IReadOnlyDictionary&lt;string, object&gt; parameters) {
    var contactFilter = ExtractFilterFromParameters(userConnection, _contactEntitySchemaUId, parameters);
    var result = new ReportDataDictionary {
        ["Contact"] = GetContactData(userConnection, _contactEntitySchemaUId, contactFilter),
        ["ContactAnniversary"] = GetContactAnniversaryData(userConnection, _contactAnniversaryEntitySchemaUId,
            contactFilter),
        ["LocalizableStrings"] = GetLocalizableStrings(userConnection)
    };
    return Task.FromResult(result);
}

 Но обратите внимание, выше в коде есть сами функции GetContactData и GetContactAnniversaryData, получающие из базы коллекцию данных с указанным фильтром.

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

Спасибо за помощь, 

«Знаменательные события контакта» нашла, сделала полностью по аналогии. Та же ошибка.

Ошибка исчезает, как только убираю второй источник данных(

Может быть дело в версии, отчет на 16.1 - наша 16.0...

Если дело в версии, зарегистрируйте тестовый сайт и проверьте такое же там.

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