Исходные данные.

Два типа пользователей системы: сотрудник компании, пользователь портала.

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

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

Вопрос.

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

Нравится

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

Дамиан, эта логика реализована в схеме HtmlEditModule, в функции:

updateToolbar: function() {
	var id = this.id;
	var toolbar = this.toolbar;
	var memo = this.memo;
	if (!toolbar || !memo) {
		return;
	}
	var plainTextMode = this.plainTextMode;
	var enabled = this.enabled;
	var enabledInRichTextMode = !plainTextMode && enabled;
	var enabledInPlainTextMode = plainTextMode && enabled;
	var hideModeButtons = this.hideModeButtons;
	toolbar.fontFamily.setEnabled(enabledInRichTextMode);
	toolbar.fontSize.setEnabled(enabledInRichTextMode);
	toolbar.fontStyleBold.setEnabled(enabledInRichTextMode);
	toolbar.fontStyleItalic.setEnabled(enabledInRichTextMode);
	toolbar.fontStyleUnderline.setEnabled(enabledInRichTextMode);
	toolbar.fontColor.setEnabled(enabledInRichTextMode);
	toolbar.hightlightColor.setEnabled(enabledInRichTextMode);
	toolbar.numberedList.setEnabled(enabledInRichTextMode);
	toolbar.bulletedList.setEnabled(enabledInRichTextMode);
	toolbar.maximized.setEnabled(enabledInRichTextMode);
	toolbar.indentList.setEnabled(enabledInRichTextMode);
	toolbar.outdentList.setEnabled(enabledInRichTextMode);
	toolbar.justifyLeft.setEnabled(enabledInRichTextMode);
	toolbar.justifyCenter.setEnabled(enabledInRichTextMode);
	toolbar.justifyRight.setEnabled(enabledInRichTextMode);
	toolbar.image.setEnabled(enabledInRichTextMode);
	toolbar.link.setEnabled(enabledInRichTextMode);
	toolbar.htmlMode.setEnabled(enabledInPlainTextMode);
	toolbar.plainMode.setEnabled(enabledInRichTextMode);
	toolbar.htmlMode.setPressed(enabledInRichTextMode);
	toolbar.plainMode.setPressed(enabledInPlainTextMode);
	toolbar.htmlMode.setVisible(!hideModeButtons);
	toolbar.plainMode.setVisible(!hideModeButtons);
	memo.setReadonly(!enabled);
	var extToolbar = Ext.get(id + "-" + this.controlElementPrefix + "-toolbar");
	if (extToolbar) {
		extToolbar.dom.style.display = !enabled ? "none" : "table-cell";
	}
	var extHtmlEdit = Ext.get(id + "-" + this.controlElementPrefix + "-htmltext");
	if (extHtmlEdit) {
		extHtmlEdit.dom.style.display = plainTextMode ? "none" : "table-cell";
	}
	var extPlainText = Ext.get(id + "-" + this.controlElementPrefix + "-plaintext");
	if (extPlainText) {
		extPlainText.dom.style.display = !plainTextMode ? "none" : "table-cell";
	}
	var editor = this.editor;
	if (editor) {
		// TODO: 200083
		try {
			editor.setReadOnly(!enabled);
		} catch (e) {
			if (editor.document) {
				editor.document.getBody().$.contentEditable = enabled;
			}
		}
		if (extHtmlEdit) {
			extHtmlEdit.dom.style.backgroundColor = enabled ? "#ffffff" : "#f9f9f9";
		}
	}
},

Проверка условий видимости панели делается в 10 и 11 строках. То есть либо у поля установлено свойство plainTextMode, либо он неактивен. Если у Вас не было никаких доработок, вероятнее всего, вторая причина. По умолчанию в разделе базы знаний для портальных пользователей записи доступны только для чтения, и это, и другие поля просто заблокированы. В таком случае панель форматирования и не нужна. Чтобы она появилась, надо портальным пользователям дать права на создание/изменение статей БЗ:

Выставил права доступа согласно рекомендациям - не помогло.

Дамиан, как оказалось, свойство «enabled» не относится к правам, а задаётся непосредственно кодом в схеме карточки.

 

В PortalKnowledgeBasePage у трёх полей (название, тип и заметки) оно определено как false:

{
	"operation": "merge",
	"name": "Name",
	"values": {
		"enabled": false
	}
},
{
	"operation": "merge",
	"name": "Type",
	"values": {
		"enabled": false
	}
},
{
	"operation": "merge",
	"name": "Notes",
	"values": {
		"layout": {
			"column": 0,
			"row": 0,
			"colSpan": 24,
			"rowSpan": 1
		},
		"enabled": false
	}
},

Если в пакете Custom переопределить эту страницу, поменять на true, то поля (или только заметки, если менять лишь последнее) разблокируются. 

Спасибо, то что нужно. Разобрался с этим только сейчас.

Создал замещающую схему страницы портального раздела "Базы знаний" (PortalKnowledgeBasePage). Внутри неё в блоке diff прописал ваш код для заметок. Всё заработало, панель с кнопкой "развернуть во весь экран" появилась.

diff: /**SCHEMA_DIFF*/[
// Заметки.
{
  "operation": "merge",
  "name": "Notes",
  "values": {
    "layout": {
      "column": 0,
      "row": 0,
      "colSpan": 24,
      "rowSpan": 1
    },
    "enabled": true
  }
},
]/**SCHEMA_DIFF*/

 

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

Добрый день!

В конструкторе есть элемент "Выполнить действия процесса". А где можно почитать что там за действия такие и как их можно использовать?

Может есть действие, что процесс обновли страницу после расчетов на детали или самой страницы?)

Нравится

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

Почитать можно тут.

 

Действие процесса — это схема с названием ...UserTask (иногда для сложных часть кода вынесена во вспомогательную схему ...UserTaskPartial), где есть основная функция на C#, запускаемая с параметрами, передаваемыми в действие извне и могут быть вспомогательные функции, которые она вызывает. Ещё у действия могут быть страницы для настройки их свойств в дизайнере БП.

 

Пример несложного действия — ChangeDataUserTask (элемент изменения данных). Так выглядит в дизайнере:

Свои тоже можно создавать:

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

 

Такого, как Вы хотите, видимо, нет. Действие «Обновить запись в реестре», похоже, осталось от интерфейса 5.Х и в 7.Х не сработает. Можно сделать своё и взаимодействовать с нужной страницей по ClientMessageBridge.

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

Добрый день! После прочтения инструкции Как управлять подписками на разные типы рассылок остались непонятны следующие моменты:

Конкретно про пункт 1:

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

Как однозначно сопоставить пользователя Creatio, который пришёл отписаться от конкретной рассылки и того, кто на этой странице лендинга?

Можно ли, чтобы ссылка работала ограниченное время?

Спасибо.

Нравится

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

Здравствуйте, Сергей!

 

Как однозначно сопоставить пользователя Creatio, который пришёл отписаться от конкретной рассылки и того, кто на этой странице лендинга?

 

Если указать собственный адрес страницы  отписки, то во время отписки на неё прийдеёт запрос вида:

https://www.google.com/?contactId=29b86521-2357-41a0-8070-8ffa36a33c94&bulkEmailRecipientId=9ae70df0-cc21-11ea-ac9f-00505689fb16&emailId=1c9a5d9c-0d06-4d29-a368-f86f2abcee13&success=True&emailaddress=pupkinv%40gmail.com

Где:  https://www.google.com – значение системной  настройки redirectUnsubscribersTo. Как видно из ссылки, мы получаем параметры contactId, bulkEmailRecipientId, emailId, что даёт возможность идентифицировать  получателя рассылки как в системе Creatio так и в конкретной рассылке, из которой потом можно узнать её тип.

 

Можно ли, чтобы ссылка работала ограниченное время?

 

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

 

Сейчас в академии в статье написано:

 

Настройка подписки на разные типы рассылок не предусмотрена в базовой конфигурации Creatio. Для ее реализации требуются доработки с участием разработчика.

 

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

Здравствуйте, Сергей!

 

Как однозначно сопоставить пользователя Creatio, который пришёл отписаться от конкретной рассылки и того, кто на этой странице лендинга?

 

Если указать собственный адрес страницы  отписки, то во время отписки на неё прийдеёт запрос вида:

https://www.google.com/?contactId=29b86521-2357-41a0-8070-8ffa36a33c94&bulkEmailRecipientId=9ae70df0-cc21-11ea-ac9f-00505689fb16&emailId=1c9a5d9c-0d06-4d29-a368-f86f2abcee13&success=True&emailaddress=pupkinv%40gmail.com

Где:  https://www.google.com – значение системной  настройки redirectUnsubscribersTo. Как видно из ссылки, мы получаем параметры contactId, bulkEmailRecipientId, emailId, что даёт возможность идентифицировать  получателя рассылки как в системе Creatio так и в конкретной рассылке, из которой потом можно узнать её тип.

 

Можно ли, чтобы ссылка работала ограниченное время?

 

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

 

Сейчас в академии в статье написано:

 

Настройка подписки на разные типы рассылок не предусмотрена в базовой конфигурации Creatio. Для ее реализации требуются доработки с участием разработчика.

 

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

Понятно, спасибо!

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

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

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

Как\где поменять иконки кастомно или кодом?Изображение удалено.

Нравится

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

Если нажать правой кнопкой на иконке и посмотреть в исходниках веб-страницы, видно, что она загружается из EntityConnectionLinksResourceUtilities. Там кода почти нет, зато все эти картинки в дереве справа: ContactExistIcon, AccountExistIcon и др., а для неизвестных — цепь в DefaultIcon. 

 

А логика подстановки в зависимости от названия колонки реализована в EntityConnectionLinksUtilities (и аналогичными по смыслу в EntityConnectionLinksPanelItemUtilities) функциями:

/**
 * Returns menu of connections type buttons.
 * @protected
 * @param {Object} column Connection column.
 * @return {Terrasoft.BaseViewModel} View model menu item.
 */
generateRelationMenuItemConfig: function(column) {
	var imageConfig = this.getRelationImageConfig(column.name);
	var config = {
		"click": {"bindTo": "onRelationMenuItemClick"},
		"caption": column.caption,
		"imageConfig": imageConfig,
		"tag": column.name,
		"visible": {
			"bindTo": column.name,
			"bindConfig": {
	"converter": "isEmptyColumnValue"
}
		},
		"markerValue": column.caption
	};
	return config;
},
 
...
/**
 * Returns object config with button icon parameters.
 * @param {String} columnName Column name.
 * @return {Object}
 */
getRelationImageConfig: function(columnName) {
	var resourceName = columnName + "ExistIcon";
	var image = EntityConnectionLinksResourceUtilities.resources.localizableImages[resourceName] ||
		EntityConnectionLinksResourceUtilities.resources.localizableImages.DefaultIcon;
	return image;
},

То есть если для нового раздела колонка и иконка одна и та же и дополнительных условий проверять не требуется, можно без изменений в коде, только добавить в EntityConnectionLinksResourceUtilities новую картинку с названием название_раздела + ExistIcon, желательно в том же размере и формате.

 

PS: уже была такая тема.

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

т.е надо заместить схему? Что-то слышал, что уже нельзя замещать какие-то схемы?

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

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

Доброго дня, коллеги! Есть два вопроса:

 

  1. Возникла такая потребность, что в справочнике необходимо отобразить изображение и как его правильно загрузить в элемент справочника? 
  2. Как мне реализовать связь один к одному и один ко многим в справочниках? Мне необходимо вытягивать id-поле из одного справочника и присваивать его в другом. Есть ли какой-то способ?

 

Нравится

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

Добрый день. По первому пункту такое реализовано в справочнике "Приоритеты обращений" CasePriority (есть в продукте Service). Там можно провалиться в запись справочника и загрузить картинку.

Общий порядок действий примерно таков:

1) создать объект. назовем его BCActivityColor. Наследуем его от базового справочника и добавляем колонку BCImage (Ссылка на изображение).

Не забываем в настройках объекта установить "Изображение" - нашу колонку. запомним UID объекта

2) Создадим для справочника страницу редактирования (я взял коробочную CasePriorityLookupEditPageV2 и выкинул лишнее).  Реализуем там загрузку картинок.

страницу наследуем от Базовая страница справочника ( UIv2 ). пример: CasePriorityLookupEditPageV2

запомним UID странички

3) зарегистрируем нашу страницу редактирования для объекта (sql). 

Привяжем BCActivityColor_SysModuleEntity (указывается UId объекта который создали в п.1) и BCActivityColor_SysModuleEdit (указывается UId схемы странички которую создали в п.2)

не забыть перезайти в почистить кэш.

Пример регистрации страницы справочника CaseCasePriority_SysModuleEdit и CaseCasePriority_SysModuleEntity

4) после заполнения справочника не забыть привязать SysImage и значения нашего нового справочника.

Добрый день. По первому пункту такое реализовано в справочнике "Приоритеты обращений" CasePriority (есть в продукте Service). Там можно провалиться в запись справочника и загрузить картинку.

Общий порядок действий примерно таков:

1) создать объект. назовем его BCActivityColor. Наследуем его от базового справочника и добавляем колонку BCImage (Ссылка на изображение).

Не забываем в настройках объекта установить "Изображение" - нашу колонку. запомним UID объекта

2) Создадим для справочника страницу редактирования (я взял коробочную CasePriorityLookupEditPageV2 и выкинул лишнее).  Реализуем там загрузку картинок.

страницу наследуем от Базовая страница справочника ( UIv2 ). пример: CasePriorityLookupEditPageV2

запомним UID странички

3) зарегистрируем нашу страницу редактирования для объекта (sql). 

Привяжем BCActivityColor_SysModuleEntity (указывается UId объекта который создали в п.1) и BCActivityColor_SysModuleEdit (указывается UId схемы странички которую создали в п.2)

не забыть перезайти в почистить кэш.

Пример регистрации страницы справочника CaseCasePriority_SysModuleEdit и CaseCasePriority_SysModuleEntity

4) после заполнения справочника не забыть привязать SysImage и значения нашего нового справочника.

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

Добрый день . 

Я создал раздел для портальных пользователей.

Есть два поля , Заказчик и Орг.ДИИС.

Два поля основаны на встроенных справочниках в система  : Контакты и Контрагент.

Как через БП сделать так , что при выборе Заказчика , заполнялось поле Орг.ДИИС в соответствии с контрагентом к которому принадлежит  Заказчик ? 

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

Есть идеи  ? 

Нравится

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

Марк, с версии 7.16.2 это можно настроить на уровне бизнес-правил фильтрации:

Появилась возможность с помощью бизнес-правил настроить автоматическое заполнение и очистку значения в поле. Например, при создании бизнес-правила для фильтрации города по стране можно настроить, чтобы страна автоматически указывалась при выборе города, а поле [Город] очищалось при изменении страны.

business_rule.png

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

Добрый день!

При переходе с версии 7.15 на версию 7.16 возникли вопросы связанные с настройкой кластера kubernetes и Exchange Listener. Коллеги поделитесь своим опытом? обилие материалов в интернете не дает конкретного решения. На текущий момент создал 3 виртульные машины на Centos 8 (master+node1+node2), объединил ВМ в  кластер

есть вопросы по дальнейшим шагам :

1. по настройке Redis? интересен пример конфигурационного файла redis_deployment_name.

helm install --namespace  --set usePassword=false --set=slave.persistence.enabled=false --set master.persistence.enabled=false --set cluster.enabled=false  stable/redis

2. необходимо ли устанавливать Ingress и какой вариант более демократичен. 

Нравится

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

Здравствуйте, Игорь!



K8s развернул на одной VM по этой инструкции без Docker'а https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/c…



Redis вообще не разворачивал, использовал уже установленный на сервере, пока работает все.

Здравствуйте, Игорь!

 

Для отказоустойчивости Redis рекомендуется другой подход, Redis Sentinel.

 

А в целом по работе с Kubernetes рекомендуют доклады  Дмитрия Столярова, особенно этот.

Здравствуйте, Игорь!



K8s развернул на одной VM по этой инструкции без Docker'а https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/c…



Redis вообще не разворачивал, использовал уже установленный на сервере, пока работает все.

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

Добрый день!

Вопрос: Как работать с массивом?

Работаю с API Telegram через Веб-сервисы

Настроил отправку сообщений через метод sendMessage

Так же настроил обработку ответа через Быструю настройку по примеру ответа

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

Настраиваю получение сообщений через метод getUpdates

Там основная задача это обработать ответ, так же по примеру ответа, все хорошо распознает

создает все переменные с которыми можно работать

Но через какой-то массив.

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

И все эти переменные недоступны для работы в редакторе процесса

А доступен массив целиком

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

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

Собственно вопрос, как работать с этим?

Нравится

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

Если в параметр БП реально попадает строка с массивом, сериализированным в JSON, его можно разбирать программно в блоке-скрипте.

 

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

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

Зверев Александр, создало все хорошо, только я не могу понять как с ними работать в редакторе БП, там доступен только этот массив "Тело ответа сервиса" (3 скрин)

Если в параметр БП реально попадает строка с массивом, сериализированным в JSON, его можно разбирать программно в блоке-скрипте.

 

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

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

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

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

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

Как добавить пользовательскую кнопку (чтобы начать процесс для данной активности) в панель действий только для одного раздела (например, для Case)?Изображение удалено.

 

Заранее благодарю за ваши ответы.

Нравится

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

Мария, этот механизм реализован во многих схемах. Для плитки активности интерфейс описан в схеме BaseDashboardItemViewConfig, а логика — в ActivityDashboardItemViewModel и её родителях EntityDashboardItemViewModel и BaseDashboardItemViewModel. В них можно увидеть кнопку «Завершить» (Execute) и её логику заголовка, видимости и нажатия. А сами названия этих схем прописаны в схеме SectionActionsDashboard в пакете ActionsDashboard в функции:

/**
 * @inheritdoc Terrasoft.BaseActionsDashboard#initDashboardConfig
 * @override
 */
initDashboardConfig: function() {
	this.callParent(arguments);
	const dashboardConfig = this.get("DashboardConfig");
	const processItemsConfig = {
		"VwProcessDashboard": {
			masterColumnName: "Id",
			referenceColumnName: "EntityId",
			viewModelClassName: "Terrasoft.ProcessDashboardItemViewModel",
			viewConfigClassName: "Terrasoft.BaseDashboardItemViewConfig"
		}
	};
	const activityItemsConfig = {
		"Activity": {
			viewModelClassName: "Terrasoft.ActivityDashboardItemViewModel",
			viewConfigClassName: "Terrasoft.BaseDashboardItemViewConfig"
		}
	};
	const approvalItemsConfig = this._getApprovalItemsConfig();
	const extendedConfig = this.values.dashboardConfig || {};
	Ext.merge(dashboardConfig, processItemsConfig);
	Ext.merge(dashboardConfig, activityItemsConfig);
	Ext.merge(dashboardConfig, extendedConfig);
	Ext.merge(dashboardConfig, approvalItemsConfig);
	this.set("DashboardConfig", dashboardConfig);
},
 
/**
 * Returns approval items config.
 * @private
 * @return {Object}
 */
_getApprovalItemsConfig: function() {
	const config = {};
	const approvalSchemaName = this.get("ApprovalSchemaName");
	if (approvalSchemaName) {
		config[approvalSchemaName] = {
			masterColumnName: "Id",
			referenceColumnName: this.get("ApprovalReferenceColumnName"),
			viewModelClassName: "Terrasoft.ApprovalDashboardItemViewModel",
			viewConfigClassName: "Terrasoft.ApprovalDashboardItemViewConfig"
		};
	}
	return config;
},

Соответственно, Вам надо будет делать свои схемы-наследники этих, добавлять там кнопку и заместить SectionActionsDashboard на версию с их упоминанием. Для примера, для виз в схемах ApprovalDashboardItemViewModel и ApprovalDashboardItemViewConfig сделана своя логика с несколькими кнопками, а те схемы унаследованы от тех же EntityDashboardItemViewModel и BaseDashboardItemViewConfig.

 

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

Здравствуйте! На 7.16.1 необходимо настроить поиск дублей в Контрагенте по кастомному полю (ИНН). Добавил хранимую процедуру и зарегистрировал её, как описано в данной статье: https://academy.terrasoft.ru/documents/technic-sdk/7-11/dobavlenie-pravila-poiska-dubley?_ga=2.85605657.1051876412.1592819009-1256785345.1592483512. Установил признак "Использовать при сохранении", но при сохранении не отрабатывает, хотя при массовом поиске дубли находит. При этом стандартные правила отрабатывают при сохранении, если включить этот признак. 

Название кастомного поля: InfTIN

Ссылка на код процедуры: https://pastebin.com/Gwir4eDg

Ссылка на код регистрации правила: https://pastebin.com/L9uVR8kR

Нравится

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

Константин, на первый взгляд, Ваши хранимки отличаются от примера только названиями полей. Но это инструкция к 7.11, это очень старая версия. Сейчас функциональность поиска дублей завязана на на работу сервиса глобального поиска.

 

Что интересно, если в Вашей ссылке поменять версию на 7.16, заголовок сменится на Добавление правила массового поиска дублей | Creatio Academy и содержит примечание:

Описанный процесс добавления правила массового поиска дублей актуален для Creatio версий 7.13.2 и ниже. Для версий системы 7.13.4 и выше функциональность поиска дублей описана в статье “Поиск и объединение дублей”, а работа с правилами поиска дублей при сохранении записи — в статье "Добавление правила поиска дублей при сохранении записи".

Поскольку у Вас 7.16.1, эта статья не подходит, выберите подходящую статью.

 

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

В самом начале данной статьи есть предупреждение:

Описанный процесс добавления правила поиска дублей актуален для Creatio версий 7.13.2 и ниже. Для версий системы 7.13.4 и выше функциональность поиска дублей описана в статье “Поиск и объединение дублей”, а работа с правилами массового поиска дублей — в статье "Добавление правила массового поиска дублей".

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

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

Для версии 7.16 поиск дублей описан в статьях «Как выполнить поиск дублей», «Как работает поиск дублей» и «Правила поиска дублей», там хранимки уже не упоминаются. Уверены, что те стандартные способы, с которыми сравниваете, используют такие хранимки?

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

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

При этом, стандартные правила используют такие же хранимые процедуры. Например, правило поиска дублей контрагента по имени: https://pastebin.com/iKnzi8Nm

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

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

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



Но по статье для 7.16 необходимо замещение модулей, а с версии 7.13 оно запрещено

Где именно? Статья «Добавление правила поиска дублей при сохранении записи», несмотря на адрес с цифрой 16, тоже, похоже, относится к версии до 7.13.2.

 

По изначальному вопросу: если у Вас 7.16.1, те правила поиска, которые с хранимкой и наподобие которых Вы хотите сделать своё, точно ли отрабатывают или остались от старых версий?

 

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



Да, я именно про эту статью. 



Они, скорее всего, остались от старых версий, но они отрабатывают.

В DuplicatesRuleManager в функции проверяются условия для правил:

/// <inheritdoc cref="IDuplicatesRuleManager.GetDuplicatesRules(string)"/>
public IEnumerable<DuplicatesRuleDTO> GetDuplicatesRules(string schemaName) {
	return GetAllDuplicatesRules()
		.Where(rule => rule.SchemaName == schemaName &&
			(schemaName == LeadSchemaName ? rule.IsActive : rule.UseAtSave) &&
			(string.IsNullOrEmpty(rule.SearchSchemaName) || rule.SearchSchemaName == schemaName));
}

Проверьте, все ли они выполняются для Вашего.

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

А когда вызывается этот класс? При локальном и массовом поиске не получилось просмотреть.

Функция вызывается из DeduplicationManager:

/// <inheritdoc cref="IDeduplicationManager.FindDuplicates"/>
public DuplicatesCollection FindDuplicates(FindDuplicatesRequest findDuplicatesOnSaveRequest) {
	var timer = new Stopwatch();
	try {
		timer.Start();
		var entityRules = _duplicatesRuleManager
			.GetDuplicatesRules(findDuplicatesOnSaveRequest.SchemaName);
		return FindSimilarRecords(entityRules.ToList(), findDuplicatesOnSaveRequest);
	}
	finally {
		timer.Stop();
		_metricReporter.Gauge(DuplicationSearchDurationMetricName, timer.ElapsedMilliseconds);
	}
}
 
/// <inheritdoc cref="IDeduplicationManager.FindSimilarRecordsFromStored"/>
public DuplicatesCollection FindSimilarRecordsFromStored(FindSimilarRecordsFromStoredRequest request) {
	var entityRules = request.SchemaName == request.SourceSchemaName
		? _duplicatesRuleManager.GetDuplicatesRules(request.SchemaName)
		: _duplicatesRuleManager.GetDuplicatesRules(request.SourceSchemaName, request.SchemaName);
	var searchSimilarRecordsRequest = _findSimilarRecordsRequestBuilder.BuildRequest(request);
	return FindSimilarRecords(entityRules.ToList(), searchSimilarRecordsRequest);
}

 

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