Добрый день

Возникла сложность в переносах строк из поля Notes при печати отчета в FastReport.

так выглядит в приложении

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

Так выглядит в БД, если делать выбор в текст

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

Обратываю в FastReport

Cell24.Text = ((String)Report.GetColumnValue("EPMAccountChk.EPMNotes"))
.Replace("<div>","")
.Replace("</div>","")
.Replace("strong","b")
.Replace("em","i");

Сама ячейка имеет значение свойства TextRenderType = HtmlParagraph

Получаю на выходе

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

В принципе как в БД, не придраться, Но не так как на экране.

Если отключить мои замены и свойство TextRenderType перевести в Default, то вообще получаю полное соответсвие БД

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

Если свойство TextRenderType оставить равным HtmlParagraph, и не делать замен, то получим:

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

Если свойство TextRenderType сделать равным HtmlTags, и не делать замен, то получим:

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

Вопрос. Как сделать отображение как на экране в приложении? Как избавится от лишних переносов?

Нравится

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

Ура! Нашел. Метод, "если не можешь найти что делать - пробуй все подряд" работает))

Начал заменять подряд все комбинации "\n\r", "\r\n", "\n", "\r". Нашел.  Это не \n\r как ожидалось, а просто \n. после первой и второй стоки \n\n, в конце просто \n. В итоге делаю следующее:

Cell24.Text = ((String)Report.GetColumnValue("EPMAccountChk.EPMNotes"))
	.Replace("&lt;div&gt;","")
	.Replace("&lt;/div&gt;","")
	.Replace("strong","b")
	.Replace("em","i")
	.Replace("\n\n","&lt;br&gt;")
	.Replace("\n","");

и свойство TextRenderType = HtmlParagraph

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

\n\r - C#

CHAR(10) и CHAR(13) - SQL

#10#13 - делфи если память не изменяет.



Посмотрите, что у вас в fastreport используется и добавить replace спец символа в ваш код 

Литвинко Павел,

Это первое, что пробовал. Забыл написать об этом.

Ура! Нашел. Метод, "если не можешь найти что делать - пробуй все подряд" работает))

Начал заменять подряд все комбинации "\n\r", "\r\n", "\n", "\r". Нашел.  Это не \n\r как ожидалось, а просто \n. после первой и второй стоки \n\n, в конце просто \n. В итоге делаю следующее:

Cell24.Text = ((String)Report.GetColumnValue("EPMAccountChk.EPMNotes"))
	.Replace("&lt;div&gt;","")
	.Replace("&lt;/div&gt;","")
	.Replace("strong","b")
	.Replace("em","i")
	.Replace("\n\n","&lt;br&gt;")
	.Replace("\n","");

и свойство TextRenderType = HtmlParagraph

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

После добавления в Конфигурации колонки (целое число) в объект с именем UsrMinTicketPrice в пакете Custom система не хочет сохраняться. Пишет:

Не удалось обновить структуру для схем:

UsrRating, UsrRating, UsrRating, UsrRating, UsrRating

Нравится

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

Добрый день, 

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

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

Возникла проблема с вызовом веб-сервиса из студии.  Возвращает ошибку 404. Пример сервиса:

 namespace Terrasoft.Configuration
{
    using System;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using System.ServiceModel.Activation;
    using Terrasoft.Core.DB;
    using Terrasoft.Web.Common;
 
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class UpsertContactService : BaseService
    {
        [OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
        ResponseFormat = WebMessageFormat.Json)]
        public string GetTransformValue(string inputParam)
        {
            // Изменение значения входящего параметра.
            var result = inputParam + " changed!";
            return result;
        }
    }
}

Пример вызова:

HttpWebResponse authresponse = (HttpWebResponse)authRequest.GetResponse();
            var myRequest = HttpWebRequest.Create("https://мой сайт/0/ServiceModel/UpsertContactService.svc/GetTransformValue") as HttpWebRequest;
 
            myRequest.Method = "POST";
            myRequest.ContentType = "application/json";
            foreach (Cookie Cook in authresponse.Cookies)
            {
                myRequest.Headers.Add(Cook.Name, Cook.Value);
            }
            myRequest.CookieContainer = bpmCookieContainer;
 
            using (var requestStream = myRequest.GetRequestStream())
            {
                using (var writer = new StreamWriter(requestStream))
                {
                    writer.Write(@"111");
                }
            }
            using (HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse())
            {
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
                {
                    string s = reader.ReadToEnd();
                    Console.WriteLine(s);
                }
            }

Авторизация проходит успешно, БП получилось запустить. Как запустить сервис и получить от него ответ?

Нравится

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

Добрый день

Виталий, в статье на академии есть ответ https://academy.terrasoft.ru/docs/developer/back-end_development/config…

 

Ответ 404 верный, т.к. у вас нет такого сервиса. Вы создаете конфигурационный сервис, который вызывается по другому url.

 

А зачем в Header добавлять значения всех кук из аутентификации? Достаточно только BPMCSRF.

Во-вторых. Вызов под каким пользователем происходит? под портальным? Если да, то надо сервис добавить в список разрешенных для портальных - \папка приложения\Terrasoft.WebApp\SspServices\SspServiceList.txt

Добавить комментарий

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

происходит под админом, сайт в облаке, через постмен тоже 404.

Вот что в браузере пишет:

Добрый день

Виталий, в статье на академии есть ответ https://academy.terrasoft.ru/docs/developer/back-end_development/config…

 

Ответ 404 верный, т.к. у вас нет такого сервиса. Вы создаете конфигурационный сервис, который вызывается по другому url.

 

Артем Гура,

Да! То что нужно! Вот рабочий код:

HttpWebResponse authresponse = (HttpWebResponse)authRequest.GetResponse();
            var myRequest = HttpWebRequest.Create("https://mysite.com/0/rest/UpsertContactService/GetTransformValue") as HttpWebRequest;
 
            myRequest.Method = "POST";
            myRequest.ContentType = "application/json";
            myRequest.Headers.Add(authresponse.Cookies["BPMCSRF"].Name, authresponse.Cookies["BPMCSRF"].Value);
            myRequest.CookieContainer = bpmCookieContainer;
 
            using (var requestStream = myRequest.GetRequestStream())
            {
                using (var writer = new StreamWriter(requestStream))
                {
                    writer.Write(@"{""inputParam"":""Test!""}");
                }
            }
            using (HttpWebResponse response = (HttpWebResponse)myRequest.GetResponse())
            {
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
                {
                    string s = reader.ReadToEnd();
                    Console.WriteLine(s);
                }
            }

И еще как авторизовался, может кому нужно будет:

var authRequest = HttpWebRequest.Create(@"https://mysite.com/ServiceModel/AuthService.svc/Login") as HttpWebRequest;
            authRequest.Method = "POST";
            authRequest.ContentType = "application/json";
            var bpmCookieContainer = new CookieContainer();
            authRequest.CookieContainer = bpmCookieContainer;
            using (var requestStream = authRequest.GetRequestStream())
            {
                using (var writer = new StreamWriter(requestStream))
                {
                    writer.Write(@"{
                                ""UserName"":""Supervisor"",
                                ""UserPassword"":""Supervisor"",
                                ""SolutionName"":""TSBpm"",
                                ""TimeZoneOffset"":-120,
                                ""Language"":""Ru-ru""
                                }");
                }
            }

 

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

Доброго дня!

 

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

 

Есть предположение, что нужно как-то грамотно организовать колбэки с this.reloadGridData(), но никак не выходит. Может кто сталкивался с подобным кейсом

 

Исходный код прилагаю.

addRecord: function(typeColumnValue) {
    var config = {
	    recordId: Terrasoft.GUID_EMPTY,
		operation: Terrasoft.ConfigurationEnums.CardOperation.ADD,
		entitySchemaName: "Account",
		valuePairs: this.getAddMiniPageDefaultValues(),
		miniPageSchemaName: "AccountMiniPage",
	};
    this.openMiniPage(config);
},
 
getAddMiniPageDefaultValues: function() {
    var defaultValues = [];
    defaultValues.push({
        name: "Parent", 
        value: this.get("MasterRecordId")
    });
	defaultValues.push({
	    name: "Category",
		value: "dc199b6d-e948-4598-8a12-c38ca90428d8"
	});
	return defaultValues;
}

Благодарю за ваши ответы

Нравится

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

Вадим, добрый день

У вас деталь - это один модуль, а миникарточка - другой. Единственный вариант общения между модулями - это сообщения. И да, при  работе с этой миникарточкой вы всегда будете отправлять сообщение, а вот реагировать на него будет деталь только в том случае, если этот модуль сейчас загружен в системе (фактически, если он отображается на экране)

Вадим, добрый день.

 

Попробуйте реализовать нужный Вам функционал через обмен сообщениями песочницы. Более подробно об этом можно почитать в статье на Академии.

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

Спасибо за ответ! Однако реализация не совсем очевидна. Неужели для реализации этого кейса придется постоянно публиковать сообщение со стороны добавляемого объекта для обновления детали? Учитывая то, что добавляемый объект, помимо детали, может создаваться и из других мест

Вадим, добрый день

У вас деталь - это один модуль, а миникарточка - другой. Единственный вариант общения между модулями - это сообщения. И да, при  работе с этой миникарточкой вы всегда будете отправлять сообщение, а вот реагировать на него будет деталь только в том случае, если этот модуль сейчас загружен в системе (фактически, если он отображается на экране)

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

Добрый день. Используем пакет GlbDataBinding для привязки данных.

Сейчас возникли вопросы.

1) Если привязывать реестр детали. Можем ли мы быть уверены что при переносе пакета будет использована последняя привязка.

2) Подскажите как правильно найти и удалить дубли из данных по ключу - устаревшие привязки.

Так же и со справочниками. Привязка осуществляется несколько раз.

Нравится

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

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

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

Все настройки реестров сохраняются в объекте SysProfileData. В пакете можете отфильтровать записи по Тип = Данные и Объект = SysProfileData и удалить дубли.

Со справочниками чуть проще. Также фильтруете в Конфигурации по Тип = Данные и Объект = объект конкретного справочника и удаляете дубли.

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

Подскажите пожалуйста, не сделали еще поддержку работы jwt-токенов (внешний сервис аутентификации/авторизации)?

Нравится

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

Добрый день, Вадим!

 

Касательно вопроса аутентификации, на текущий момент из готовых реализаций у нас есть два способа аутентификации: базовая (логин/пароль) и OAuth 2.0. Для использования же  jwt-токенов необходимо писать пользовательские методы аутентификации, что требует навыков разработчика.

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



Спасибо, что помогаете делать наш продукт лучше!



С уважением,

Сидько Елена

Оператор

Группа компаний Terrasoft

 

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

Добрый день!

Подскажите, пожалуйста!

Что значит данное сообщение?

Поиском по документации не нашел.

 

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

Нравится

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

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

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

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

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

Добрый день! 



Настраиваем журнал изменений (ChangeLog) для каждого объекта. После настройки в конфигурациях в пакете Custom создается замещающий объект, текущий пакет (CurrentPackageId) у нас не Custom. Как сделать так, чтобы настройки Журнала изменений сохранялись в текущем пакете?

 

Меняли CustomPackageUId -- не помогло. В конфигурации объекта ставили галку «Вести журнал изменений» -- Журнал включается, но после того, как настраиваешь поля, все равно создается замещающий объект в Custom.

 

Заранее благодарю за ответ

Нравится

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

Вадим, добрый день!

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

Сохранение настроек журнала изменений через интерфейс соответствующего раздела технически работает так, что в любом случае в пакете Custom создаётся замещающий объект, вне зависимости от значения настройки Текущий пакет.

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

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

Вадим, добрый день!

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

Сохранение настроек журнала изменений через интерфейс соответствующего раздела технически работает так, что в любом случае в пакете Custom создаётся замещающий объект, вне зависимости от значения настройки Текущий пакет.

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

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

Благодарю за ответ!

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

Привет, пытаюсь открыть в секции по кнопке форму(через ModalBox.show), но падает ошибка, о том что не может определить ModalBox и соотвественно не вызывается метод show, т.к ModalBox не определен. ModalBox на форму добавлен.

define("OpportunitySectionV2", ["BaseFiltersGenerateModule", "PrintReportUtilities","ModalBox"],

        function(BaseFiltersGenerateModule, ModalBox) {

Нравится

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

У вас ошибка в последовательности объявлений модулей.

Попробуйте так:

define("OpportunitySectionV2", ["BaseFiltersGenerateModule","ModalBox", "PrintReportUtilities"],
        function(BaseFiltersGenerateModule, ModalBox) {

 

У вас ошибка в последовательности объявлений модулей.

Попробуйте так:

define("OpportunitySectionV2", ["BaseFiltersGenerateModule","ModalBox", "PrintReportUtilities"],
        function(BaseFiltersGenerateModule, ModalBox) {

 

Дмитрий Антохин,

Спасибо, помогло)

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

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



Есть объект и для него sql запрос. Доступ к коллекции объекта осуществляется через EntityDataService.svc. 

Одно из полей множественное, для такого поля в sql запросе сделана реализация через 

FOR XML PATH ('Goal'), TYPE

Но при запросе коллекции скобки xml тэгов заменяются их кодовыми значениями. 

<d:AccountLoginQualifiedGoal>&lt;Goal id="9857A30F-3F69-4D07-ADC8-02A61D686C82"&gt;&lt;Name&gt;ЦЕЛЬ№1&lt;/Name&gt;&lt;/Goal&gt;&lt;Goal id="187B496F-B7C5-449A-BDE6-7D07D28296DB"&gt;&lt;Name&gt;ЦЕЛЬ№2&lt;/Name&gt;&lt;/Goal&gt;</d:AccountLoginQualifiedGoal>

Можно ли как-то этого избежать и выводить просто как скобки? Чтобы было вот так.

 <d:AccountLoginQualifiedGoal><Goal id="9857A30F-3F69-4D07-ADC8-02A61D686C82"></Goal><Name>Цель№1</Name></Goal><Goal id="5985A03D-0162-4F02-AA64-BDFCFAC93B49"><Name>Ничего из этого</Name></Goal><Goal id="71EBF4E1-B344-490D-94D9-C67EC77206A9"><Name>Встречи</Name></Goal><Goal id="F6CA356F-635D-4C96-B1E6-D0409172F26E"><Name>Цель№2</Name></Goal></d:AccountLoginQualifiedGoal>

 

Нравится

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

Добрый день. 

Правильно ли я понимаю, что Вы получаете ответ от сервиса EntityDataService.svc в виде : 

 

&lt;d:AccountLoginQualifiedGoal&gt;&amp;lt;Goal id="9857A30F-3F69-4D07-ADC8-02A61D686C82"&amp;gt;&amp;lt;Name&amp;gt;ЦЕЛЬ№1&amp;lt;/Name&amp;gt;&amp;lt;/Goal&amp;gt;&amp;lt;Goal id="187B496F-B7C5-449A-BDE6-7D07D28296DB"&amp;gt;&amp;lt;Name&amp;gt;ЦЕЛЬ№2&amp;lt;/Name&amp;gt;&amp;lt;/Goal&amp;gt;&lt;/d:AccountLoginQualifiedGoal&gt;

 

Mykhailo Storozhuk,

Да, все верно.

Данное поведения полностью корректное. Данную сериализацию делает базовая функциональность .net framework, именно System.Data.Services.DataService. Это нужно для того, что бы не нарушить основной xml.



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



 

Mykhailo Storozhuk, 

Хорошо, спасибо!

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