Фильтры

Как создать задачу на визирование в коде?

Нравится

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

EntitySchema invoiceVisaSchema = UserConnection.EntitySchemaManager.GetInstanceByName("InvoiceVisa");
Entity invoiceVisa = invoiceVisaSchema.CreateEntity(UserConnection);
invoiceVisa.SetDefColumnValues();
invoiceVisa.SetColumnValue("Objective", "Требуется утверждение");
invoiceVisa.SetColumnValue("VisaOwnerId", new Guid("7F3B869F-34F3-4F20-AB4D-7480A5FDF647"));
invoiceVisa.SetColumnValue("StatusId", new Guid("3462594D-77A7-4B0A-874A-6D8B54B293BC"));
invoiceVisa.SetColumnValue("InvoiceId", new Guid("3C2B6D9F-4C1E-4364-99F2-53956562B606"));
invoiceVisa.Save();

 

аналог элемент процесса

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

Имеется расширенный фильтр. Мне необходимо отобразить его лишь на чтение.

Как скрыть кнопку удаления строки и добавления нового условия?

"Действия" скрываются путем передачи в модуль конфига с параметром actionsVisible: false.

В модуле FilterEditModule не нашел подобного функционала для добавления или удаления условий. 

Нашел в классе Terrasoft.controls.FilterEdit.Filter метод, возвращающий как раз таки права на удаление, выделение и т.д.

/**
	 * @inheritdoc Terrasoft.FilterEdit.Item#getAllowedManageOperations
	 * @protected
	 * @override
	 */
	getAllowedManageOperations: function() {
		var filterManager = this.filterManager;
		if (!filterManager) {
			return {
				canViewEnabled: true,
				canEditEnabled: true,
				canEditLeftExpression: true,
				canEditRightExpression: true,
				canEditComparisonType: true,
				canRemove: true,
				canSelect: true
			};
		}
		var filterManageOperations = filterManager.getAllowedFilterManageOperations(this.instance);
		var isEnableComparisonType = this._isEnableComparisonType();
		if (isEnableComparisonType !== undefined) {
			filterManageOperations.canEditComparisonType = isEnableComparisonType;
		}
		return filterManageOperations;
	},

Как я могу переопределить этот метод, если мне нужно расширить логику лишь для одного модуля, а не во всю систему.

 

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

Нравится

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

У кейса есть 2 способа решения:

1) Расширить класс  BaseFilterProvider.

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

 

Пример расширенного модуля (комментарии для понимания разницы)

define("BpFilterReadonlyProvider", [],
	function() {
		/**
		 * @class Terrasoft.data.filters.FilterReadonlyProvider
		 * Readonly filters provider.
		 */
		Ext.define("Terrasoft.data.filters.FilterReadonlyProvider", {
				extend: "Terrasoft.BaseFilterProvider",
			alternateClassName: "Terrasoft.FilterReadonlyProvider",
 
			rootSchemaName: "",
 
			canDisplayId: false,
 
			sandbox: null,
 
			// Управление операциями внутри фильтра (для каждого фильтра по отдельности).
			getAllowedFilterManageOperations: function() {
				return {
					// Видимость признака "Активен".
					canViewEnabled: true,
					// Возможность изменения признака "Активен".
					canEditEnabled: false,
					// Возможность изменения левой части выражения.
					canEditLeftExpression: false,
					// Возможность изменения правой части выражения.
					canEditRightExpression: false,
					// Возможность изменения условия сравнения.
					canEditComparisonType: false,
					// Видимость кнопки удаления ('X').
					canRemove: false,
					// Возможность выбрать отдельный фильтр.
					canSelect: false
				};
			},
 
			// Управление группами фильтров.
			getAllowedFilterGroupManageOperations: function() {
				return {
					// Видимость признака "Активен".
					canViewEnabled: true,
					// Возможность изменения признака "Активен".
					canEditEnabled: false,
					// Видимость типа группы ("И" / "ИЛИ").
					canViewGroupType: true,
					// Возможность редактирования типа группы.
					canEditGroupType: false,
					// Видимость кнопки "Добавить условие".
					canAddFilters: false,
					// Видимость кнопки удаления ('X').
					canRemove: false,
					// Возможность выбора группы фильтра.
					canSelect: false
				};
			}
 
		});
		return Terrasoft.FilterReadonlyProvider;
	}
);

 

Передача конфига модулю

updateFilterModule: function() {
    this.sandbox.publish("SetFilterModuleConfig", this.getRequirementsModuleConfig(), [this.modules.FilterModule.moduleId]);
},
 
...
 
getRequirementsModuleConfig: function() {
    return {
        // Объект
	    rootSchemaName: "SxCandidate",
        // Колонка со значением фильтра
		filters: this.$RequirementFilterValue,
        // Видимость кнопки "Действия"
		actionsVisible: false,
        // Имя класса-провайдера (не забудьте подключить в зависимостях свой модуль с этим классом)
		filterProviderClassName: "Terrasoft.FilterReadonlyProvider"
   };
}

 

2) Второй вариант более быст и удобен. Подойдет, если такой кейс единичный в системе.

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

updateFilterModule: function() {
    this.sandbox.publish("SetFilterModuleConfig", this.getRequirementsModuleConfig(), [this.modules.FilterModule.moduleId]);
},
 
...
 
getRequirementsModuleConfig: function() {
    return {
	    rootSchemaName: "SxCandidate",
		filters: this.$RequirementFilterValue,
		actionsVisible: false,
        entitySchemaFilterProviderConfig: {
		    canDisplayId: true,
		    shouldHideLookupActions: true,
			isColumnSettingsHidden: true,
			getAllowedFilterManageOperations: function() {
			    return {
				    canViewEnabled: true,
					canEditEnabled: false,
					canEditLeftExpression: false,
					canEditRightExpression: false,
					canEditComparisonType: false,
					canRemove: false,
					canSelect: false
				};
			},
			getAllowedFilterGroupManageOperations: function() {
				return {
					canViewEnabled: true,
					canEditEnabled: false,
					canViewGroupType: true,
					canEditGroupType: false,
					canAddFilters: false,
					canRemove: false,
					canSelect: false
				};
			}
		}
   };
}

 

В обоих случаях результат будет идентичен.

Можно наложить фильтр в раздел и пользователь его вообще не увидит в расширенных фильтрах.

https://community.terrasoft.ru/questions/interesuet-kak-sozdat-filtr-v-…

https://community.terrasoft.ru/questions/vidimost-sotrudnikov-v-kontakt…

https://community.terrasoft.ru/questions/bystryy-filtr-po-celochislenno…

Полозюков Евгений Петрович,

задача в другом. Допустим, менеджер заполняет фильтрацию внутри карточки (аналогично фильтрам в карточке раздела "Модели машинного обучения"). Затем, этот фильтр мне нужно отобразить  оператору только для чтения уже в совершенно другом месте.

 

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

Подкопаев Михаил Олегович,

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

У кейса есть 2 способа решения:

1) Расширить класс  BaseFilterProvider.

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

 

Пример расширенного модуля (комментарии для понимания разницы)

define("BpFilterReadonlyProvider", [],
	function() {
		/**
		 * @class Terrasoft.data.filters.FilterReadonlyProvider
		 * Readonly filters provider.
		 */
		Ext.define("Terrasoft.data.filters.FilterReadonlyProvider", {
				extend: "Terrasoft.BaseFilterProvider",
			alternateClassName: "Terrasoft.FilterReadonlyProvider",
 
			rootSchemaName: "",
 
			canDisplayId: false,
 
			sandbox: null,
 
			// Управление операциями внутри фильтра (для каждого фильтра по отдельности).
			getAllowedFilterManageOperations: function() {
				return {
					// Видимость признака "Активен".
					canViewEnabled: true,
					// Возможность изменения признака "Активен".
					canEditEnabled: false,
					// Возможность изменения левой части выражения.
					canEditLeftExpression: false,
					// Возможность изменения правой части выражения.
					canEditRightExpression: false,
					// Возможность изменения условия сравнения.
					canEditComparisonType: false,
					// Видимость кнопки удаления ('X').
					canRemove: false,
					// Возможность выбрать отдельный фильтр.
					canSelect: false
				};
			},
 
			// Управление группами фильтров.
			getAllowedFilterGroupManageOperations: function() {
				return {
					// Видимость признака "Активен".
					canViewEnabled: true,
					// Возможность изменения признака "Активен".
					canEditEnabled: false,
					// Видимость типа группы ("И" / "ИЛИ").
					canViewGroupType: true,
					// Возможность редактирования типа группы.
					canEditGroupType: false,
					// Видимость кнопки "Добавить условие".
					canAddFilters: false,
					// Видимость кнопки удаления ('X').
					canRemove: false,
					// Возможность выбора группы фильтра.
					canSelect: false
				};
			}
 
		});
		return Terrasoft.FilterReadonlyProvider;
	}
);

 

Передача конфига модулю

updateFilterModule: function() {
    this.sandbox.publish("SetFilterModuleConfig", this.getRequirementsModuleConfig(), [this.modules.FilterModule.moduleId]);
},
 
...
 
getRequirementsModuleConfig: function() {
    return {
        // Объект
	    rootSchemaName: "SxCandidate",
        // Колонка со значением фильтра
		filters: this.$RequirementFilterValue,
        // Видимость кнопки "Действия"
		actionsVisible: false,
        // Имя класса-провайдера (не забудьте подключить в зависимостях свой модуль с этим классом)
		filterProviderClassName: "Terrasoft.FilterReadonlyProvider"
   };
}

 

2) Второй вариант более быст и удобен. Подойдет, если такой кейс единичный в системе.

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

updateFilterModule: function() {
    this.sandbox.publish("SetFilterModuleConfig", this.getRequirementsModuleConfig(), [this.modules.FilterModule.moduleId]);
},
 
...
 
getRequirementsModuleConfig: function() {
    return {
	    rootSchemaName: "SxCandidate",
		filters: this.$RequirementFilterValue,
		actionsVisible: false,
        entitySchemaFilterProviderConfig: {
		    canDisplayId: true,
		    shouldHideLookupActions: true,
			isColumnSettingsHidden: true,
			getAllowedFilterManageOperations: function() {
			    return {
				    canViewEnabled: true,
					canEditEnabled: false,
					canEditLeftExpression: false,
					canEditRightExpression: false,
					canEditComparisonType: false,
					canRemove: false,
					canSelect: false
				};
			},
			getAllowedFilterGroupManageOperations: function() {
				return {
					canViewEnabled: true,
					canEditEnabled: false,
					canViewGroupType: true,
					canEditGroupType: false,
					canAddFilters: false,
					canRemove: false,
					canSelect: false
				};
			}
		}
   };
}

 

В обоих случаях результат будет идентичен.

У вас настройка фильтра хранится в поле? Может, можно закрыть оператору доступ к данному полю на уровне прав доступа?

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

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

Но как создать на C# (не в бизнес процессе) уведомление без этой ссылки, как это реализовано например у уведомлений об синхронизации с LDAP?

Нравится

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

Создаете в с# в таблице Remindings запись, вот и будет вам текст без ссылки. Откройте таблицу Remindings и посмотрите запись у которой дата 24.02.2021 в 17:57 и увидите какие поля должны быть заполнены чтобы получить такое уведомление.

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

Александр Тыра,

Мне эти ссылки не нужны. Приложите код которым создаете уведомление и скриншоты с полями в двух записях бд, та которая у вас создается уведомление и уведомление с ldap. 

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

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

Развернул стенд на сервере, настроил https, редирект на https, локально работает все идеально, но при попытке зайти через https://.... локально иди  удаленно перенаправляет на страницу https://www.terrasoft.ru/Login/NuiLogin.aspx?ReturnUrl=%2f, с ошибкой, страница не найдена

Нравится

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

Не думаю что terrasoft.ru это ваш сайт. 

При перенастройке на https я проблем не встречал, это простое действие. Верните на http и проверьте нормально ли вы развернул систему. Потом заново сделайте по этой статье https://academy.terrasoft.ru/docs/user/ustanovka_i_administrirovanie/ra…

Стенд случайно не из бекапа базы с облачной среды взят?  На облачных стендах заполнена системная настройка "DomainToRedirect". Если заходить на такой стенд с локалки, то все ок. Но если зайдете с внешнего адреса, например mytestsite.ru - вас автоматически перекинет на terrasoft.ru.

Чтобы такого не было, нужно очистить указанную системную настройку зайдя через localhost или скриптом:

 

delete SysSettingsValue where SysSettingsId = (select id from SysSettings where code = 'DomainToRedirect')

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

Ковыряюсь потихоньку с задачей, для которой нужен доступ к данным, хранимым в облаке Creatio, по протоколу OData. И наткнулся на регулярные сообщения сервера о внутренних ошибках:

Обращаюсь по URL https:// ... .terrasoft.ru/0/odata/ - работает

https:// ... .terrasoft.ru/0/odata/Case - работает

https:// ... .terrasoft.ru/0/odata/Case( какой-то Id, который я ранее узнал ) - работает

https:// ... .terrasoft.ru/0/odata/Case( ... )/Subject - работает. И для других свойств тоже работает

https:// ... .terrasoft.ru/0/odata/Case( ... )/ModifiedBy - работает (хотя в описании объектов OData это не "Property", а "NavigationProperty")

https:// ... .terrasoft.ru/0/odata/Case( ... )/CaseMessageHistoryCollectionByCase (это уже не просто NavigationProperty, а NavigationProperty с установкой "Type=Collection( ... )") - не работает. Возвращает статус "500 Internal Server Error " и сообщение " An error has occurred."

Ситуация стабильная. Ошибка возникает всегда, вне зависимости от того, к какой конкретно записи в Case я обращаюсь. Более того, ошибка возникает при обращении к любому свойству, которое должно вернуть коллекцию.

 

И аналогичная ошибка возникает при обращении https:// ... .terrasoft.ru/0/odata/CaseMessageHistory?$filter=CaseId eq ... Опять же, возникает стабильно.

 

Вопрос: как со всем этим бороться?

 

Нравится

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

Григорий, все примеры по работе с OData в Creatio есть тут. Возможно, что-то делаете не так, как предложено использовать.

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

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

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

За ссылки на примеры спасибо. Но при сравнении их со своими попытками я не увидел никакой разницы.

Так что вопрос остается в силе.

Например, вот рабочий запрос с eq:

/0/odata/SysSchema?$filter=ManagerName%20eq%20%27EntitySchemaManager%27

Аналогично можно выбрать из CaseMessageHistory, отфильтровав по CaseId:

/0/odata/CaseMessageHistory?$filter=Case/Id%20eq%20ceef8012-3806-4431-b62b-102270f6fcc9

 

Зверев Александр, За пример с CaseMessageHistory огромное спасибо. Так сработало. А вот аналогичная (по смыслу) конструкция

 

/0/odata/CaseMessageHistory?$filter=CaseId eq ceef8012-3806-4431-b62b-102270f6fcc9

 

(отличается отсутствием слэша между "Case" и "Id") приводит к внутренней ошибке сервера

Значит, надо ставить слэш.

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

 поставить слэш вполне можно. (Хотя и непонятно, на каком основании он там нужен, и почему без него не работает). А мне, кстати говоря, интересно стало: у Вас без слэша что будет - нормальная работа или ошибка?

Вам нужно получить данные или таки отладить/взломать систему?

В примерах слэш есть.

У меня на таком же запросе будет ровно то же, что и у Вас.

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

 в первую очередь мне нужно получить данные.

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

Григорий Шпаков,

На документацию можете не полагаться, надо разбираться самому методом проб и ошибок.

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

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

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