Вопрос

Коллеги, привет. 

Не могу найти внятного мануала на тему использования фильтрация в БП. 

Хочу отфильтровать ответственного по тикету по группе ответственных. (Выбираем группу -> список ответственных уменьшается). 

Подскажите как реализовать "хотелку" или укажите на гайд, где подобная задача решается?

У меня такой же вопрос

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

Вашу задачу можно решить не только с помощью бизнес-правил.

Например, в базовой версии фильтрация поля 'Ответственный' настраивается через атрибуты таким образом:

"Owner": {
	"dataValueType": Terrasoft.DataValueType.LOOKUP,
	"lookupListConfig": {"filter": BaseFiltersGenerateModule.OwnerFilter}
}

Более того некоторые задачи по фильтрации данных с помощью бизнес-правил вообще не решаются.

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

Начните с просмотра этой статьи. В ней несколько ссылок на более подробное описание различных моментов связаных с БП. Так же просмотрите  статью СТРУКТУРА КЛИЕНТСКОЙ СХЕМЫ

 

 

 

Вашу задачу можно решить не только с помощью бизнес-правил.

Например, в базовой версии фильтрация поля 'Ответственный' настраивается через атрибуты таким образом:

"Owner": {
	"dataValueType": Terrasoft.DataValueType.LOOKUP,
	"lookupListConfig": {"filter": BaseFiltersGenerateModule.OwnerFilter}
}

Более того некоторые задачи по фильтрации данных с помощью бизнес-правил вообще не решаются.

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

Алла Савельева,  требуется следующую логику: 

1) При выборе ответственного, список доступных для выбора групп ответственных должен содержать только те группы, в которые входит ответственный

И обратное:

2) При выборе группы ответственных, список ответственных должен быть ограничен только теми специалистами, которые входят в данную группу. 

Sunrise challenge,

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

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

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

Нужно ли где-то определять BaseFiltersGenerateModule.OwnerFilter? 

Sunrise challenge,

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

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

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

Компилятор не выдаёт ошибок, схема сохраняется, при этом фильтрация не осуществляется

Sunrise challenge,

А в консоли браузера есть такие-то ошибки при выборе значения для этого поля?

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

Добрый день, нужна помощь, есть трудности с построением такого фильтра:
 

Select * from "Contact"
LEFT JOIN "SysAdminUnit" ON "Contact"."Id" = "SysAdminUnit"."ContactId"
where "SysAdminUnit"."Id" IN 
	(Select "SysUserId" from "SysUserInRole" where "SysRoleId" IN 
		(Select FuncRoleId from SysFuncRoleInOrgRole))

Для filterGroup, должно получится что-то вроде такого: (мой вариант не верный).
 

filterGroup.add("ContactList", Terrasoft.createExistsFilter("[SysAdminUnit:Contact].[SysUserInRole:SysUser].SysRole.[SysFuncRoleInOrgRole:FuncRole]"));

 

У меня такой же вопрос

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

Можно сначала вычитать все FuncRoleId из SysFuncRoleInOrgRole удовлетворяющие вашим условиям, а потом построить фильтр createColumnInFilterWithParameters, пример привел ниже (existsDocumentsCollection - массив с коллекциями которые нужно включить в запрос)

var filtersGroup = Terrasoft.createFilterGroup();
filtersGroup.logicalOperation = Terrasoft.LogicalOperatorType.AND;
var existsFilter = this.Terrasoft.createColumnInFilterWithParameters("Id",
	existsDocumentsCollection);
existsFilter.comparisonType = this.Terrasoft.ComparisonType.EQUAL;
existsFilter.Name = "existsFilter";
filtersGroup.addItem(existsFilter);
filtersGroup.addItem(discontListFilter);

 

Можно сначала вычитать все FuncRoleId из SysFuncRoleInOrgRole удовлетворяющие вашим условиям, а потом построить фильтр createColumnInFilterWithParameters, пример привел ниже (existsDocumentsCollection - массив с коллекциями которые нужно включить в запрос)

var filtersGroup = Terrasoft.createFilterGroup();
filtersGroup.logicalOperation = Terrasoft.LogicalOperatorType.AND;
var existsFilter = this.Terrasoft.createColumnInFilterWithParameters("Id",
	existsDocumentsCollection);
existsFilter.comparisonType = this.Terrasoft.ComparisonType.EQUAL;
existsFilter.Name = "existsFilter";
filtersGroup.addItem(existsFilter);
filtersGroup.addItem(discontListFilter);

 

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

Сделал следующие методы для валидации.

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

maxEverydayActive: function() {
                var invalidMessage = "";
                var activeEverydayConcertCount = 0;
                var maxActiveEverydayConcertCount = 0;
                Terrasoft.SysSettings.querySysSettingsItem("UsrMaxEverydayActiveProgram", function(value) {
                    maxActiveEverydayConcertCount = value;
                }, this);
                var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "UsrConcertProgram"
                });
                esq.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, "CountEntities",
                Terrasoft.AggregationEvalType.ALL);
                
                var filterGroup = this.Terrasoft.createFilterGroup();
                
                filterGroup.add("concertsIsActive",
                this.Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrIsActive", "1"));
                filterGroup.add("performancePeriodEveryday",
                this.Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
                "UsrPerformancePeriod", "85A8C133-FF83-4290-9F69-B34EAF627F8C"));
                
                esq.filters.addItem(filterGroup);
                
                esq.getEntity(function(result) {
                        if (result.success){
                            activeEverydayConcertCount = result.entity.get("CountEntities"); - здесь не присваивается значение. Должно быть 4. По БД проверил
                        }
                }, this);
                
                if (activeEverydayConcertCount >= maxActiveEverydayConcertCount) {
                    invalidMessage = this.get("Resources.Strings.MaximumActiveEverydayConcerts");
                }
                
                return {
                    invalidMessage: invalidMessage
                };
            },
            setValidationConfig: function() {
                this.callParent(arguments);
                this.addColumnValidator("UsrIsActive", this.maxEverydayActive);
                this.addColumnValidator("UsrPerformancePeriod", this.maxEverydayActive);
            }

У меня такой же вопрос

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

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

 

Paul_lgb,

Добрый день. Все дело в том, что у вас даже не вызывается callback вызова getEntity (если вызывается, то это странно, возможно в вашей версии еще есть такое поведение).

Функция getEntity имеет 3 параметра:

1. primaryColumnValue

2. callback

3. scope

Функция getEntity будет возвращать вам все колонки, относящиеся к этой entity.

Пример:

getEntity("<здесь Id контакта>", function(resullt) {}) //т.е. будет фильтрация по Id контакта

Для получения количества записей, без "фильтрации" нужно использовать функцию getEntityCollection(callback), но она асинхронна, поэтому это нужно учесть.

 

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

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

Пробовал передать просто объект filterGroup - параметр с объектом не передается в модуль.

Пробовал передать 

filterGroup.serialize() 

- при десериализации строки получаю совершенно другую структуру объекта

Terrasoft.deserialize(filterGroup)

При добавлении этого фильтра в ESQ-запрос
происходит ошибка:
"Uncaught TypeError: a.on is not a function"

Подскажите, как корректно:
1. передать объект в параметры модуль?
2. провести сериализацию группы фильтров с последующим 

 

У меня такой же вопрос

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

ага. упирался уже в данный нюанс. Не могу найти пример с проекта, но фишка в serializationInfo. Вот пример из дефолтной конфигурации:

var serializationInfo = sectionFilters.getDefSerializationInfo();
serializationInfo.serializeFilterManagerInfo = true;
var deserializedFilters = Terrasoft.deserialize(sectionFilters.serialize(serializationInfo));

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

В консоли по быстрому накидал. Посмотрите, как различаются 2 результата десериализации (в моём примере v=Terrasoft.createFilterGroup()):

Варфоломеев Данила,

Огромное спасибо! Всё получилось.

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

Добрый день, подскажите как осуществить фильтрацию в детали по колонке из третий таблицы?

Есть конструкция:

select * from UsrDocument
INNER JOIN UsrDocumentPackage on UsrDocument.UsrPackageCPId=UsrDocumentPackage.UsrCPId
where UsrDocumentPackage.UsrCodeId = 'e06c50cb-ac4c-41ce-9493-033e4b54ea14'

которую нужно вынести в filterGroup.

filterGroup.add(
                "UsrPackageFilterLogistics",
                Terrasoft.createColumnFilterWithParameter(
                Terrasoft.ComparisonType.EQUAL,
                "UsrDocumentPackage.UsrCode",
                "00e6efc8-cc7e-4ac7-af41-6310bb5110e8"));

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

 

 

У меня такой же вопрос

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

Вам необходимо использовать синтаксис ESQ-запроса во втором аргументе, для присоединения таблицы, см. https://academy.terrasoft.ru/sites/default/files/documents/docs/technic/SDK/7.9.0/BPMonline_development_guide.pdf

стр. 389 - 391
А лучше прямо с 371-ой страницы.
В Вашем случае строка ESQ запроса повторяющая ваш SQL-заспрос будет выглядеть так (Учитывая что текущая схема UsrDocument, а это может быть не так):
 

[UsrDocumentPackage:UsrCP:UsrPackageCP].UsrCode

суффиксы "Id" для справочных полей опускаются (вы запрашиваете поля объектов конфигурации а не колонки из БД, на это необходимо обращать внимание, т.е если в объекте у Вас поле называется "UsrCP" именно так вы и должны его использовать в запросах ESQ, в то время как в в БД(если поле справочное) оно будет именоваться  "UsrCPId")
В конечном варианте Ваш фильтр будет выглядеть вот так

filterGroup.add(
  "UsrPackageFilterLogistics",
   Terrasoft.createColumnFilterWithParameter(
      Terrasoft.ComparisonType.EQUAL,
      "[UsrDocumentPackage:UsrCP:UsrPackageCP].UsrCode",
      "00e6efc8-cc7e-4ac7-af41-6310bb5110e8"
   )
);

 

Севостьянов Илья Сергеевич,

Большое спасибо за пояснения, всё получилось.

Войдите или зарегистрируйтесь, чтобы комментировать