Добрый день, уважаемые коллеги!

Есть следующий кейс: 1. На странице Контрагента указывается наше ответственное подразделение, выбирается из справочника.

2. В записях справочника Подразделений есть признак (булево) можно выбирать это подразделение для указания в Контрагентах или нет - UsrProhibitSelectionAccount

3. Нужно запретить выбор записи Подразделения, если признак UsrProhibitSelectionAccount = true

4. Настраиваю правило валидации, как описано https://academy.terrasoft.ru/documents/technic-sdk/7-16/dobavlenie-vali…

5. При выборе значения из справочника правило отрабатывает. Но если вводить запрещенное подразделение вручную, то оно спокойно остается в поле и позволяет сохранить значение.

Подскажите, пожалуйста, что нужно сделать в данном случае? Благодарю за помощьИзображение удалено.

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

Добавленные методы в карточку Контрагента

methods: {
			// Метод-валидатор значения колонки [UsrDepartment] // semmrn
            DepartmentValidator: function() {
                // Переменная для хранения сообщения об ошибке валидации.
                var invalidMessage = "";
                // Проверка значения колонки [UsrDepartment]
                var AccountDepartments = this.get("UsrDepartment");
                if (AccountDepartments.UsrProhibitSelectionAccount) {
                    // Если значение колонки [UsrAccountDepartments.UsrProhibitSelectionAccount] 
                    // запрещено к выбору = да, то
                    // в переменную invalidMessage помещается значение локализуемой строки с сообщением
                    // об ошибке валидации.
                    invalidMessage = this.get("Resources.Strings.DepartmentMustBeAllowed");
                }
                // Объект, свойство которого содержит сообщение об ошибке валидации.
                // Если валидация прошла успешна, в объекте возвращается пустая строка.
                return {
                    // Сообщение об ошибке валидации.
                    invalidMessage: invalidMessage
                };
            },
            // Переопределение базового метода, инициализирующего пользовательские валидаторы.
            setValidationConfig: function() {
                // Вызывает инициализацию валидаторов родительской модели представления.
                this.callParent(arguments);
                // Для колонки [UsrDepartment] добавляется метод-валидатор DepartmentValidator().
                this.addColumnValidator("UsrDepartment", this.DepartmentValidator);
                }
		},

 

Нравится

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

Для того, что Вы хотите есть как раз валидация, которую Вы пробовали в первом сообщении. Она должна предотвращать и от ручного ввода. Не смотрели в отладке, функция-валидатор выполняется, что в поле AccountDepartments и как срабатывает условие?

Доброго дня, Марина. Почему Вы не хотите сделать настройку посредством бизнес-правила (фильтрацией)? 

Марина, ещё можно деактивировать при помощи стандартного механизма:

Если одно или несколько значений справочника устарели и больше не используются, то такие значения можно деактивировать (Рис. 2). Деактивированное значение не будет отображаться при выборе значений в справочных полях. При этом пользователи продолжат видеть это значение в тех записях, где оно было указано ранее, и смогут использовать его для фильтрации. По умолчанию возможность деактивировать значения справочника выключена. Разрешить деактивацию записей для нужного справочника можно в разделе [Конфигурация]. Подробнее о настройке читайте в статье “Деактивация записей объектов”.

Рис. 2 — Деактивированное значение справочника [Типы статей базы знаний]

section_lookups_deactivated_record_example.png 

Но так будет запрещён выбор не в конкретной карточке, а везде. 

Уважаемые коллеги, спасибо за Ваши предложения.

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

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

Для того, что Вы хотите есть как раз валидация, которую Вы пробовали в первом сообщении. Она должна предотвращать и от ручного ввода. Не смотрели в отладке, функция-валидатор выполняется, что в поле AccountDepartments и как срабатывает условие?

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

 

благодарю), ситуация, действительно, прояснилась через отладчик

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

Добрый день!



Планирую интеграцию одного приложения с Creatio CRM через внешний API на OData4.

Читаю документацию, и вижу, что любую сущность можно получить через отдельный запрос. Но изначально система не знает какие сущности могут быть в системе, и чтобы получить их список нужно выполнить SQL-запрос (по инстркуции):

 

для MySQL

SELECT * FROM INFORMATION_SCHEMA.TABLES

для Oracle

SELECT * FROM ALL_TABLES

для PostgreSQL

SELECT table_name FROM information_schema.tables

 

У меня есть только данные для авторизации юзера через OData4, и этот запрос мне никак не выполнить.



Есть ли какой-то способ через внешний API получить список всех таблиц?

Нравится

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

Павел, можно ещё

https://{server}/0/odata/

Так будет результат в  JSON.

 

Либо воспользоваться информацией из таблицы SysSchema, которая тоже доступна по OData. За объекты отвечает EntitySchemaManager, получить список можно с таким фильтром:

https://{server}/0/odata/SysSchema?$filter=ManagerName%20eq%20%27EntitySchemaManager%27

А вариант с выбором из базы не очень подходит, поскольку зависит от платформы, плюс не все таблицы в базе связаны с объектами конфигурации и могут быть доступны по OData. И наоборот, часть объектов сделаны не на основе table, а по view.

Нашел сам



Запрос на 

https://{server}/0/odata/$metadata

возвращает внутри <Schema Namespace="Terrasoft.Configuration.OData" xmlns="http://docs.oasis-open.org/odata/ns/edm"> все сущности

Павел, можно ещё

https://{server}/0/odata/

Так будет результат в  JSON.

 

Либо воспользоваться информацией из таблицы SysSchema, которая тоже доступна по OData. За объекты отвечает EntitySchemaManager, получить список можно с таким фильтром:

https://{server}/0/odata/SysSchema?$filter=ManagerName%20eq%20%27EntitySchemaManager%27

А вариант с выбором из базы не очень подходит, поскольку зависит от платформы, плюс не все таблицы в базе связаны с объектами конфигурации и могут быть доступны по OData. И наоборот, часть объектов сделаны не на основе table, а по view.

Зверев Александр, Спасибо! А метадату конкретной сущности как получить? 

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

В https://{server}/0/odata/$metadata всё есть.

Pavel Buev,

Добрый день Павел, нашли решение получение метадаты конктретной сущности? ищу рещение такой же проблемы

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

Добрый день.

 

Есть 3 потребности в работе с аналитикой:

  1. возможность делать скриншот отдельных виджетов
  2. при нажатии на действия "скриншот" Система должна делать скриншот виджета, сохранять изображение, на котором отсутствуют вспомогательные иконки (шестеренка и т.д.")
  3. расширить контейнер, чтобы влезал текст на диаграмме целиком?



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

1) Подскажите возможна ли такая реализация? Куда необходимо смотреть?

2) Планируется ли реализация этих требований в  базовой функциональности платформы в последующих версиях?

Нравится

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

Добрый день.

С версии  7.15.2 изменились схемы отрисовки графиков, был выполнен переход к Chart.js. На текущей версии, к сожалению, ещё нет возможности настроить полное отображение текстов подписей графиков через пользовательский интерфейс. 

По информации от авторов функциональности:

1. Такой возможности не планировали давать. В Windows и macOs есть штатные средства для создания скриншотов, а также существуют утилиты, которые помогают редактировать скриншот по усмотрению пользователя, например, ShareX.

2. Аналогично.

3. Подобные изменения запланированы на второй квартал следующего года.

 

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

 

Согласен, что по п.1 и п.2 можно использовать штатные/сторонние средства.

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

 

Если Вы подскажите, где в системе нужно копать для настройки видимости иконок виджетов и кнопки "скриншот", я буду благодарен.

 

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

 

\\п.3  Подобные изменения запланированы на второй квартал следующего года.

Если необходимо расширить контейнер с текстом в рамках текущей версии (а не спустя 8 месяцев), то каким образом Вы рекомендовали бы действовать?

По Вашим вопросам и пожеланиям зарегистрированы идеи: «Итоги. Надо сохранять скриншот только одного графика (виджета), а не только всей вкладки итогов.» и «Итоги. Работа с графиками. Текст (подпись/заголовок) в графике не отображается полностью, обрезаны подписи».

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

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

Остался один только вопрос: Если необходимо расширить контейнер с текстом в рамках текущей версии (а не спустя 8 месяцев), то каким образом Вы рекомендовали бы действовать?

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

Кстати, на демо-сайте не вижу таких примеров как у Вас, там легенда слева написана вертикально (но если делать длинной, на другую строку не перенеслась):

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

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

Studio развернута on-side.

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

Каким образом можно это исправить?

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

Нравится

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

Добрый день, Андрей.

Вам необходимо выполнить этот скрипт в вашей БД:

UPDATE AdminUnitFeatureState
SET FeatureState = 1
WHERE FeatureId IN (SELECT ID FROM Feature (NOLOCK) WHERE Code = 'UseProcessDiagramComponent')

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



Судя по всему, фича, которая отвечает за новый дизайнер БП, не изменила свое состояние.

Добрый день, Андрей.

Вам необходимо выполнить этот скрипт в вашей БД:

UPDATE AdminUnitFeatureState
SET FeatureState = 1
WHERE FeatureId IN (SELECT ID FROM Feature (NOLOCK) WHERE Code = 'UseProcessDiagramComponent')

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



Судя по всему, фича, которая отвечает за новый дизайнер БП, не изменила свое состояние.

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

Здравствуйте, спасибо большое за отклик, скрипт не стработал, так как UseProcessDiagramComponent и так стоял с состаянием 1, но зайдя на  FeaturesPage, данный компонент показывало неактивым, Снова почистил весь кеш - не помогло, включил вручную, в таблице AdminUnitFeatureState добавилась строка с приязкой к SysAdminUnit и заработало.



Еще раз спасибо за подскаску куда смотреть.

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

Скажите пожалуйста, будет ли приложение отображать push активностей/email активностей, созданные из бизнес процессов?

Нравится

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

К сожалению push уведомление не работает, в системе от  другого пользователя добавил активность, указав себя ответственным по задаче, но в телефоне pusha нет. система ios

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

 

push-уведомление создается ответственному сотруднику, если установлено напоминание ответственному (признак Ответственному в группе полей Напоминания на странице активности).

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

На сборку Sales enterprise (on-site) установлено приложение "Расчет рабочих дней в бизнес-процессах" https://marketplace.terrasoft.ru/template/raschet-rabochih-dney-v-biznes-processah

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

Каким образом можно это исправить?

 

Нравится

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

Скорее всего проблема в иерархии пакетов. Сделайте зависимость своего пакета от их пакета

Скорее всего проблема в иерархии пакетов. Сделайте зависимость своего пакета от их пакета

Добрый день, Мария!

 

Алексей прав, по умолчанию действия процесса будут доступны только для бизнес-процессов пакета Custom. Если вы настраиваете бизнес-процессы в своем пользовательском пакете, добавьте зависимость в свой пакет от пакета приложения GlbCalendarService.

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

Есть процесс в котором идет обработка писем и автоматическая рассылка. Если отправлять письма через элемент отправить Email, то все отлично форматирует. пустые данные просто пропускает. Но отправленные письма должны прикрепляться к обращению. Поэтому при отправке письма используются скрипты, а не элемент БП Отправить Email. Остается вопрос как в письме убрать желтизну от макросов на те данные, которых еще нет в обращении

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

Нравится

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

Алексей, а какие именно скрипты используете для отправки и замены макросов? Откуда вообще взялся жёлтый цвет, он был в сохранённом в справочнике шаблоне письма?

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

var contactEmail = Get&lt;string&gt;("ContactMail");
var senderEmail = Get&lt;string&gt;("SenderEmail");
var caseId = Get&lt;Guid&gt;("CaseId");
var templateId = Get&lt;Guid&gt;("TemplateEmail");
var userConnection = UserConnection.AppConnection.SystemUserConnection;
var emailTemplateMacrosManager = new EmailWithMacrosManager(userConnection);
if (UserConnection.GetIsFeatureEnabled("EmailMessageMultiLanguageV2")) {
	_log.Debug("EmailMessageMultiLanguageV2=true");
	emailTemplateMacrosManager.SendEmailFromTo(caseId, templateId, senderEmail, contactEmail);
} else {
	var emailTemplateStore = new EmailTemplateStore(userConnection);
	var emailTemplateLanguageHelper = new EmailTemplateLanguageHelper(caseId, userConnection);
	var languageId = emailTemplateLanguageHelper.GetLanguageId(templateId);
	var templateEntity = emailTemplateStore.GetTemplate(templateId, languageId);
	emailTemplateMacrosManager.SendEmailFromTo(caseId, templateEntity.PrimaryColumnValue, senderEmail, contactEmail);
}
return true;

 

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

 

Сама логика с жёлтым цветом реализована в MacrosHelperV2:

private const string MacrosHighlightsTemplate = "&lt;span class=\"unhandled-macro\" style=\"background-color:#fff94f;\"&gt;[#{0}#]&lt;/span&gt;";
...
/// &lt;summary&gt;
/// Returns the DOM markup to highlight value.
/// &lt;/summary&gt;
/// &lt;param name="value"&gt;Text that needs to be highlighted.&lt;/param&gt;
/// &lt;returns&gt;DOM markup.&lt;/returns&gt;
private string GetHighlights(string value) {
	string highlight = string.Format(MacrosHighlightsTemplate, value);
	return highlight;
}
...
/// &lt;summary&gt;
/// Highlights macroses in template text.
/// &lt;/summary&gt;
/// &lt;param name="template"&gt;Template text.&lt;/param&gt;
/// &lt;param name="macrosInfo"&gt;Macroses list.&lt;/param&gt;
/// &lt;returns&gt;Template text with highlights.&lt;/returns&gt;
protected virtual string ReplaceMacros(string template, List&lt;MacrosInfo&gt; macrosInfo) {
	string result = template;
	foreach (MacrosInfo item in macrosInfo) {
		string macrosDisplayValue = string.Format(MacrosTemplate, item.Alias);
		string highlights = GetHighlights(item.Alias);
		result = result.Replace(macrosDisplayValue, highlights);
	}
	return result;
}

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

У Вас используются функции из схем EmailWithMacrosManager (SendEmailFromTo и GetTemplateBody), BaseEmailWithMacrosManager (GetTemplateBody), GlobalMacrosHelper(GetTextTemplate) и MacrosHelperV2 (GetTextTemplate, GetHighlightedTemplate, ReplaceMacros и GetHighlights).

 

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

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

Проблема в том что не могу отследить событие добавление файла на деталь "Файлы и ссылки".

"KtFilesConfirmingDiscountDetail": {
	"schemaName": "KtFilesConfirmingDiscountDetail",
	"entitySchemaName": "KtFilesConfirmingDiscount",
	"filter": {
		"detailColumn": "KtOpportunityProductInterest",
		"masterColumn": "Id"
	},
	"subscriber": {
		"methodName": "discountValueEnable"
	}
}

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

Нравится

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

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

 

Если нужно разработать свою логику со срабатыванием на добавление, можно в обычном БП или встроенном БП объекта файла в этом разделе завязаться на событие добавления.

 

Например, в CaseFile есть такая логика:

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

 

Код детали

define("KtFilesConfirmingDiscountDetail", ["css!KtFilesConfirmingDiscountDetailCssModule"],
	function() {
	return {
		methods: {
			/**
			 * Initializes parent entity.
			 */
			initParentEntity: function() {
				this.parentEntity = {};
				const entitySchemaName = this.entitySchema &amp;&amp; this.entitySchema.name || "";
				const parentSchemaName = entitySchemaName.replace("KtFilesConfirmingDiscount", "KtOpportunityProductInterest");
				const masterRecordId = this.get("MasterRecordId");
				this.parentEntity.EntityName = parentSchemaName;
				this.parentEntity.RecordId = masterRecordId;
			},
			/**
			 * ############## ####### "drag" # "drop" ##########.
			 * @private
			 */
			initDropzoneEvents: function() {
				const dropZone = document.getElementById("DragAndDropContainerOpportunityProductInterest");
				if (!dropZone) {
					return;
				}
				if (this.Terrasoft.Features.getIsEnabled("CheckMasterRecordEditRights") &amp;&amp;
						!this.get("CanEditMasterRecord")) {
					return;
				}
				this.Terrasoft.ConfigurationFileApi.initDropzoneEvents(dropZone, function(over) {
					if (over) {
						dropZone.classList.add("dropzone-hover");
					} else {
						dropZone.classList.remove("dropzone-hover");
					}
				}, function(files) {
					this.onFileSelect(files);
				}.bind(this));
			},
			getAddRecordButtonVisible: function() {
				return this.getToolsVisible() &amp;&amp; this.get("CanEditMasterRecord") &amp;&amp; this.get("IsEnabled");
			}
		},
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "merge",
				"name": "DragAndDrop Container",
				"parentName": "Detail",
				"propertyName": "items",
				"values": {
					"id": "DragAndDropContainerOpportunityProductInterest",
					"selectors": {"wrapEl": "#DragAndDropContainerOpportunityProductInterest"},
					"itemType": Terrasoft.ViewItemType.CONTAINER,
					"wrapClass": ["dropzone"],
					"items": [
						{
							"labelClass": ["DragAndDropLabel"],
							"itemType": Terrasoft.ViewItemType.LABEL,
							"caption": {"bindTo": "Resources.Strings.DragAndDropCaption"}
						}
					]
				}
			}
		]
		/**SCHEMA_DIFF*/
	};
});

Родительский объект "FileDetailV2 ( UIv2 )". Думаю CSS нет смысла прикладывать, он стандартный.

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

По рекомендации поддержки просмотрел методы сохранения и решил остановится на onFileComplete

 

на стороне детали:

messages: {
	"DiscountValueEnable": {
		"mode": Terrasoft.MessageMode.PTP,
		"direction": Terrasoft.MessageDirectionType.PUBLISH
	}
},
onFileComplete: function() {
	this.callParent(arguments);
	this.sandbox.publish("DiscountValueEnable", null, [this.sandbox.id]);
}

на стороне страницы:

messages: {
	"DiscountValueEnable": {
		mode: this.Terrasoft.MessageMode.PTP,
		direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE
	}
},
methods: {
	init: function() {
		this.callParent(arguments);
		this.sandbox.subscribe("DiscountValueEnable", function() {
				this.discountValueEnable();
			}, this, [this.sandbox.id + "_detail_KtFilesConfirmingDiscountDetailKtFilesConfirmingDiscount"]);
	},
	discountValueEnable: function(){
		this.set("discountValueEnable", true);
	}
}

 

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

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

 

Подключил Zoom Meeting connector for Creatio в систему, зарегистрировал все ка кположено, но при создании активности галочка создать встречу в Zoom засерена. 

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

Нравится

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

У меня было такое когда установил на сервер у которого не было прямого доступа в интернет, и система не могла скачать списки контактов с сервера zoom, потому и не становилось доступным для редактирования

Стас, добрый день!

 

Признак Create Zoom Meeting доступен только пользователям, которые указаны на детали Zoom Account User в разделе Zoom Accounts. 

Заполнение этой детали и сопоставление с пользователями Creatio по email выполняется автоматически. Проверьте данные на детали Zoom Account User и заполните поле Contact в проимпортированном списке пользователей Zoom.

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

Добрый день!Ф

такая задача:

есть фильтр по дате в формате с-по. Как сделать быстрый фильтр где из календаря можно выбрать 1 конкретную дату в 1 поле, не выбирая с и по?

Нравится

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

По идее, нужно примерно так, как с добавлением целочисленного или логического фильтра по полю, но там, где делают  filterCollection.add, вставлять два условия фильтрации, связанные and, по дате больше или равно начала тех суток, которые выбраны в календаре, и дате меньше начала следующих суток.

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

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

Функция getFilters не подходит?

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