Здравствуйте, столкнулся с проблемой. При создании в шаблоне подписи отображаются html форматирование текста. С чем может быть связано.

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

Нравится

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

Добрый день!



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

Не совсем понятен первый вопрос, кроме самого ФИО ничего в этой подписи не менял, она подтянулась именно так. Если их стереть и ввести данные самому, то все будет нормально. Но эти данные из подписи, подтягивающиеся автоматически.

Письмо клиенту отправляется именно в таком виде (с тегами).

Булат Хабирзянов,

Благодарю за уточнение. Я правильно понял, что Вы подтягиваете шаблон из справочника, и подпись в нём подтягивается с html-тэгами? Если так, проверьте, пожалуйста, при открытии шаблона в справочнике, он отображается корректно?

Роман Казекин,

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

 

Булат Хабирзянов,

Спасибо за дополнительную информацию!

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

2. Уточните, пожалуйста, в настройке почтового ящика подпись отображается корректно?

Роман Казекин,

1. Все верно

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

uid ActivityEmailId = Get<Guid>("ActivityEmailId");
Guid AttachmentType = Get<Guid>("AttachmentType");
Guid documentId = Get<Guid>("DocumentId");
Guid documentFileId = Guid.Empty;
byte[] documentData = Array.Empty<byte>();
string filename = "";
var mySelect = new Select(UserConnection)
    .Column("Id")
    .Column("Data")
    .Column("Name")
    .From("DocumentFile")
    .Where("DocumentFile", "DocumentId").IsEqual(Terrasoft.Core.DB.Column.Parameter(documentId)) as Select;
try 
{
	using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection())
	{
	    using (IDataReader dataReader = mySelect.ExecuteReader(dbExecutor))
	    {
	        while (dataReader.Read())
	        {
 
	            documentFileId=dataReader.GetColumnValue<Guid>("Id");
	            documentData = dataReader.GetColumnValue<byte[]>("Data");
	            filename = dataReader.GetColumnValue<string>("Name");
	        }
	    }
	}
 
	var entity = UserConnection.EntitySchemaManager.GetInstanceByName("ActivityFile");
	var fileEntity = entity.CreateEntity(UserConnection);
	fileEntity.SetDefColumnValues();
	fileEntity.SetColumnValue("ActivityId", ActivityEmailId);
	fileEntity.SetColumnValue("TypeId", AttachmentType);
	fileEntity.SetColumnValue("Name", filename);
	fileEntity.SetColumnValue("Data", documentData);
	fileEntity.Save();
	//var emailClientFactory = ClassFactory.Get<EmailClientFactory>(new ConstructorArgument("userConnection", UserConnection));
	//var activityEmailSender = new ActivityEmailSender(emailClientFactory, UserConnection);
	//activityEmailSender.Send(ActivityEmailId);
}
catch (Exception e)
{
    throw;
}
return true;

 

Еще забавная вещь. если переключить, то все выводится нормально. Только отступы появились

Булат Хабирзянов,

 

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



Приведу пример.



Мы пишем в обычном режиме код:

<br><h1>BOLDBR<br></h1>

 

Переходим в html-режим (нажимаем на кнопку с синей буквой а) и видим текст с учётом указанной нами разметки (скриншот прилагаю).

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

Спасибо!

Хорошо, понятно. Но тут возникает вопрос, при формировании письма текст отображается с тэгами, не думаю, что каждый менеджер знает что такое html, теги и все такое. Можно ли как-то поставить вид отображения без тэгов по умолчанию?

Булат Хабирзянов,

Пользовательскими средствами изменение данного поведения невозможно. Только средствами разработки.

Роман Казекин,

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

 

Булат Хабирзянов, 

 

Здравствуйте! Сам модуль ckeditor лежит в пакете NUI, файлы расположены по пути TerrasoftWebApp/Resources/ui/CKEditor.

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

При выведении в Итоги виджета "список" данных объекта, созданного на основе View, в Списке  иногда отображаются дублирующиеся записи. Но при экспорте в excel такие дубли отсутствуют. Есть подозрение, что такое поведение связано как-то с пагинацией.  Такая же ситуация происходит если делать на основе такого объекта деталь.

Кто-нибудь сталкивался с подобным?

Ниже пример схемы View используемый для объекта

CREATE VIEW [dbo].[VwTest] AS

SELECT

    NEWID() as Id

    ,GETDATE() as CreatedOn

    ,(SELECT Id FROM Contact WHERE Id='BE80A149-0089-4311-A775-CA6CD8937E2B') as CreatedById

    ,GETDATE() as ModifiedOn

    ,(SELECT Id FROM Contact WHERE Id='BE80A149-0089-4311-A775-CA6CD8937E2B') as ModifiedById

    ,0 as ProcessListeners

    ,Id as ContactId

    ,Age

FROM Contact

WHERE Age>30

 

 

 

Нравится

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

Добрый день!

Прошу уточнить следующую информацию:

1. Полную версию приложения

2. Данное поведение наблюдается с одним объектом, или воспроизводится вне зависимости от объекта?

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

 

Спасибо!

Роман Казекин,

 1. Версия Sale Ent 7.16.3

2. Данное поведение характерно для всех объектов созданных на основе view.

3.

- Создал View ( как описано выше)

-  в управление конфигурацией создал объект с названием View

- включил checkbox Поведение - Представление в базе данных

4. Вывод объекта в Итогах в виде Списка

Евгений Кобзарь,

 

Уточните, пожалуйста, по какому полю Вы определяете записи, как дубли?

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

Роман Казекин,

По полю Контакт. Select с View выбирает только 1 запись. Но в таблице/списке показывает несколько. Как правило происходит такое когда нажимаешь кнопку Показать больше. См. скриншот

Евгений Кобзарь,

 

Проверьте значение колонки ContactId, если там разные значения для записей, которые дублируются, то это значит что у Вас есть дубли в контактах. То есть это разные записи с одинаковыми данными.

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

 

https://academy.terrasoft.ru/docs/user/bazis_platformy/dannye/dubli/poi…

Роман Казекин,

 

Дублей нет. На скриншоте видно, что ссылки на эти записи формируются идентичные (на основе одного Id). Мне кажется что проблема все же в offsetе и order by (по Id).  При нажатии показать больше идет повторный запрос к View у которого НЕ статический  ID (newid()). Если это так? То каким образом можно и как правильно во view создать этот ID.

Добрый день

Евгений, это абсолютно объяснимое поведение View при использовании Fetch next. Вы же получаете записи пачками, а каждая пачка имеет свои Id и сортировка может вам выдать "дубль"

Как правильно? Просто используейте Id из основного объекта. Вы же выбираете из Contact, так берите его Id вместо генерации newid()

 

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

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

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

Нравится

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

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

Dima Avdoshin,

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

Булат Хабирзянов,

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

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

Хорошо, подскажите как понять системе какие продукты нужны (условие или фильтр здесь на вариант, тк логики выбора продукта как таковой нет, менеджер сам может решить какой из продуктов ему выбрать и установить определенный тип цен). Сейчас можно поменять как у всей продукции сразу или зайдя в продукт и сменить тип цен там и не совсем понятно как можно реализовать выборку, для удобства менеджера (если например позиций будет 50, и тип цен нужно поменять только у 20, то заходить в каждый будет долго).

Вопрос был в том можно ли словить в коде продукты выбранные с помощью ctrl.

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

Булат Хабирзянов,

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

в кол бэке же можно уже отловить поля которые человек выбрал

и в конфиге прописать 

config.multiSelect = true;
только не забудь иначе поставить, что бы базовая логика для обычных справочных полей отрабатывала
 openLookup: function (config, callback, scope) {
                    var self = this;
					if (config.columnName === "qrtOptionServiceTransit") {
						var options = this.get("qrtIdsOptions");
						var list = [];
						if(options) {
							list = options.split(",");
						}
                        var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                            rootSchemaName: "qrtOptionServiceTransit"
                        });
						esq.addColumn("Id");
                        var collectionOptions = self.get("qrtOptionsCollection");
 
 
                        if(collectionOptions !== null	&amp;&amp; collectionOptions.length !== 0) {
 
							var esqFirstFilter = esq.createColumnInFilterWithParameters("Id", collectionOptions);
							esq.filters.add("esqFirstFilter", esqFirstFilter);
						} else {
							esq.filters.add("filter01", this.Terrasoft.createColumnFilterWithParameter(
                                this.Terrasoft.ComparisonType.EQUAL, "Id", this.get("Id")));
						}
 
                        esq.getEntityCollection(function (result) {
                            if (result.success) {
                                var existsContactsCollection = [];
                                var selectedRows = [];
                                result.collection.each(function (item) {
                                    var id = item.get("Id");
 
                                    if(list.includes(id)){
                                        selectedRows.push(id)
                                    }
                                    existsContactsCollection.push(id);
                                });
 
                                config.multiSelect = true;
 
                                config.selectedRows = (list[0] !== "") ? selectedRows : null;
 
                                if(existsContactsCollection.length !== 0) {
									var existsFilter = this.Terrasoft.createColumnInFilterWithParameters("Id",existsContactsCollection);
									existsFilter.comparisonType = this.Terrasoft.ComparisonType.EQUAL;
									existsFilter.Name = "existsFilter";
									config.filters = existsFilter;
								} else {
									var existsFilter = this.Terrasoft.createColumnFilterWithParameter(this.Terrasoft.ComparisonType.EQUAL, "Id", this.get("Id"));
									existsFilter.comparisonType = this.Terrasoft.ComparisonType.EQUAL;
									existsFilter.Name = "existsFilter";
									config.filters = existsFilter;
								}
                                Terrasoft.LookupUtilities.open({
                                    "lookupConfig": config,
                                    "sandbox": this.sandbox,
                                    "keepAlive": config.keepAlive,
                                    "lookupModuleId": config.lookupModuleId,
                                    "lookupPageName": config.lookupPageName,
                                }, this.addCallBack, this);
 
                            }
                        }, this);
						//&lt;----------------
					} else {
						Terrasoft.LookupUtilities.open({
							"lookupConfig": config,
							"sandbox": this.sandbox,
							"keepAlive": config.keepAlive,
							"lookupModuleId": config.lookupModuleId,
							"lookupPageName": config.lookupPageName,
						}, this.addCallBack, this);
					}
				},
 
                addCallBack: function (args) {
					this.selectedRows = args.selectedRows.getItems();
					this.selectedItems = [];
					var selectedItems2 = [];
 
					this.selectedRows.forEach(function (item) {
						this.selectedItems.push(item.displayValue);
						selectedItems2.push(item.value)
						this.loadLookupDisplayValue(args.columnName, item.value);
					}, this);
 
					if(args.columnName === "qrtOptionServiceTransit") {
						this.set("qrtOptions", (String(this.selectedItems)).replace(/,/g, ";\n"));
						this.set("qrtIdsOptions", String(selectedItems2).replace(/,/g, ","));
					}
					//&lt;----------------
				},

 

Dima Avdoshin,

Спасибо за наводку, но я нашел то. что мне нужно

// Метод-обработчик действия. Отображает в информационном окне список контрагентов.
showOrdersInfo: function() {
		var opportunityId = this.get("OpportunityId");
		// Получение массива идентификаторов выбранных записей.
		var selectedRows = this.get("SelectedRows");
		console.log(selectedRows);
		// Получение коллекции данных записей реестра.
		for(var i = 0; i &lt; selectedRows.length; i++){
			var args = {
				// Имя процесса, который необходимо запустить.
				sysProcessName: "IptChangePriceListSelectedProducts",
				// Параметры процесса
				parameters: {
					OpportunityId: opportunityId,
					Product: selectedRows[i],
					PriceList: "24D9B628-C3FC-45E2-AC97-7CD17CE22FB9",
				}
			};
			// Запуск пользовательского бизнес-процесса.
			ProcessModuleUtilities.executeProcess(args);
		}
},

в детали добавил кнопку, привязал функцию выше на кнопку, где запускаю процесс

и все прекрасно работает. 

var selectedRows = this.get("SelectedRows"); создает массив из выбранных с помощью ctrl объектов. 

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

Добрый день!

Подскажите, как из бизнесс процесса вызвать создание Excel отчета, настроенного в ADVANCED EXCEL REPORTS (https://marketplace.terrasoft.ru/app/advanced-excel-reports-creatio)?

Нравится

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

За генерацию отчет отвечает класс BpmReportGenerator

За запуск генерации отвечает веб-сервис BpmReportGeneratorService

Есть два пути: дернуть сервис с нужным методом и параметрами, либо запустить генерацию миную сервис. Пример есть в бп BpmReportSchedulerProcess

 

За генерацию отчет отвечает класс BpmReportGenerator

За запуск генерации отвечает веб-сервис BpmReportGeneratorService

Есть два пути: дернуть сервис с нужным методом и параметрами, либо запустить генерацию миную сервис. Пример есть в бп BpmReportSchedulerProcess

 

Трефилов Павел Сергеевич,

Спасибо!

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

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

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

Подскажите, пожалуйста, как сделать чтобы срабатывал один БП.

Спасибо!

Нравится

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

Сделать один сигнал, реагирующий на изменение двух полей

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

На самом деле БП так и настроен, есть один сигнал, принимающий изменение двух полей, но почему-то запускается два БП.

Руслан Хасанов пишет:

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

Все гораздо проще оказалось, есть другой процесс, который изменял поля. 

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

Есть раздел договоры, когда проваливаюсь в запись и нажимаю на контрагента, то система просто зависает и пишет Uncaught TypeError: Cannot read property 'entitySchemaName' of undefined , не совсем понимаю куда копать, при это когда захожу в контрагента из раздела контрагент этой ошибки нет

с чем можно связано и куда копать

core-base.js:704 user: Supervisor/7f3b869f-34f3-4f20-ab4d-7480a5fdf647

 file: https://support.ru/0/conf/content/SchemaBuilderV2.js?hash=fb899ee9f0b54…

 line: 543

 column: 57

 message: Uncaught TypeError: Cannot read property 'entitySchemaName' of undefined 

 stack: TypeError: Cannot read property 'entitySchemaName' of undefined

    at i. (https://support.ru/0/conf/content/SchemaBuilderV2.js?hash=fb899ee9f0b54…)

    at https://support.ru/core/c9cf54cfbeb445fbb561c4bf11e53272/combined/all-c…

    at Object.execCb (https://support.ru/core/057665f97324038f6c7c326b6734de6b/requirejs/requ…)

    at Module.check (https://support.ru/core/057665f97324038f6c7c326b6734de6b/requirejs/requ…)

    at Module.enable (https://support.ru/core/057665f97324038f6c7c326b6734de6b/requirejs/requ…)

    at Module.init (https://support.ru/core/057665f97324038f6c7c326b6734de6b/requirejs/requ…)

    at https://support.ru/core/057665f97324038f6c7c326b6734de6b/requirejs/requ…

Нравится

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

Добрый день!

 

Такая ошибка может быть по нескольким причинам.

 

1) Попробуйте выполнить следующее действия:

1. Открыть конфигурацию, найти последнюю измененную схему страницы и реестра Контрагента. Их названия будут соответствовать Страница - AccountPageV2, Раздел - AccountSectionV2.

2. Выполнилть пересохранение схемы раздела и старицы, ничего изменять не нужно, просто пересохранить модули.

3. Скомпилируйте приложение.

4. Очистите кэш браузера для пользователей у которых наблюдается ошибка и проверьте её воспроизведение еще раз.

 

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

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

Использую очень простой метод (см. ниже)  в контексте двух событий:

1) onEntityInitialized

2) при изменении поля Account на карточке.

В первом случае формируется запрос без использования фильтра по идентификатору контрагента, во втором с фильтром. В обоих случаях "var account = this.get("Account");" успешно вычисляется. Как добиться гарантированной фильтрации в обоих случаях?

 

         setIsAffiliated: function() {

                var account = this.get("Account");

                

                var esq = Ext.create("Terrasoft.EntitySchemaQuery", {

                    rootSchemaName: "Account"

                });

                //esq.rowCount = 1;

                esq.addColumn("IsAffiliatedLegalEntity");

                esq.filters.add("Account", esq.createColumnFilterWithParameter(

                    Terrasoft.ComparisonType.EQUAL,

                    "Id",

                    account.Id));

                esq.getEntityCollection(function(result) {

                    if (result.success) {

                        var first = result.collection.firstOrDefault();

                        if (!Ext.isEmpty(first)) {

                            var isAffil = first.get("IsAffiliatedLegalEntity");

                            this.set("IsAffiliatedLegalEntity", isAffil);

                        }

                    }

                }, this);

            }

Нравится

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

                var accVal = account.value;

                var accId = account.Id;

Нашел причину. Она в том, что возвращаются разные объекты в двух случаях, но в обоих идентификатор контрагента доступен так "account.value;"

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

Следует посмотреть какое значение возвращает строка  

var account = this.get("Account"); 

Если оно одно и тоже, то довольно странно, что в одном случае фильтр не используется.

                var accVal = account.value;

                var accId = account.Id;

Нашел причину. Она в том, что возвращаются разные объекты в двух случаях, но в обоих идентификатор контрагента доступен так "account.value;"

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

Добрый день.

Пытаюсь настроить аутентификацию пользователей Active Directory через LDAP на .NET Framework

По этой инструкции.

https://academy.terrasoft.ru/docs/user/ustanovka_i_administrirovanie/upravlenie_polzovateljami_i_dostupom/sinhronizaciya_polzovatelej_s_ldap/nastroit_autentifikaciyu_s_ldap

 

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

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

 

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

Нравится

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

Такая ошибка теоретически может возникнуть из-за некорректного заполнения конфигурационных файлов. Например, были допущены какие-то синтаксические ошибки, вроде того, что в \web.config перечень провайдеров указан через символы "".

 

Чтобы сказать что-то более конкретное, нужно увидеть содержимое файла \web.config. Попробуйте сравнить настройки с примером на Академии, возможно обнаружите несовпадения или ошибки синтаксиса.

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

Здравствуйте, можно ли ограничить доступ на определенные поля в справочнике?

Нравится

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

Булат Хабирзянов, здравствуйте.

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

Узнать объект справочника можно в его свойствах.

А далее, стандартно, как для любого объекта, настраиваем права в разделе "Права доступа на объекты" на объект справочника.

Булат Хабирзянов, здравствуйте.

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

Узнать объект справочника можно в его свойствах.

А далее, стандартно, как для любого объекта, настраиваем права в разделе "Права доступа на объекты" на объект справочника.

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

Здравствуйте, кейс звучит так: Создать БП в котором будет формироваться отчет (созданный в конструкторе отчетов) и в дальнейшем по расписанию отправляться на почту. 

Вопрос, возможно ли в БП вызвать формирование отчета из конструктора отчетов.

Нравится

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

Насколько я понимаю, под конструктором отчётов имеется ввиду приложение Excel reports builder for Creatio?

 

Если так, то ещё существует приложение Auto reports MS Excel for Creatio, функционал которого как раз и заключается в автоматической отправке отчётов по расписанию из БП. Возможно, это приложение покроет все потребности.

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