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



Вытащил json следующего фильтра из бд

{
  "className": "Terrasoft.FilterGroup",
  "items": {
    "572334d2-7d75-43e0-b60f-c2cdfca071ea": {
      "className": "Terrasoft.InFilter",
      "filterType": 4,
      "comparisonType": 3,
      "isEnabled": true,
      "trimDateTimeParameterToDate": false,
      "leftExpression": {
        "className": "Terrasoft.ColumnExpression",
        "expressionType": 0,
        "columnPath": "TestColumn"
      },
      "isAggregative": false,
      "key": "572334d2-7d75-43e0-b60f-c2cdfca071ea",
      "dataValueType": 10,
      "leftExpressionCaption": "TestColumn",
      "referenceSchemaName": "TestColumn",
      "rightExpressions": [
        {
          "className": "Terrasoft.ParameterExpression",
          "expressionType": 2,
          "parameter": {
            "className": "Terrasoft.Parameter",
            "dataValueType": 10,
            "value": {
              "Name": "Да",
              "Id": "3631ec86-e4cd-490c-9614-cea3bbf71187",
              "value": "3631ec86-e4cd-490c-9614-cea3bbf71187",
              "displayValue": "Да"
            }
          }
        }
      ]
    }
  },
  "logicalOperation": 0,
  "isEnabled": true,
  "filterType": 6,
  "rootSchemaName": "Contact",
  "key": "FolderFilters"
}

Далее с помощью этого метода пытаюсь создать esq фильтр

 

public static EntitySchemaQuery GetEsqByFilterData(UserConnection userConnection, string filterData)
        {
            if (userConnection is null) { throw new ArgumentNullException(nameof(userConnection)); }
 
            if (filterData is null) { throw new ArgumentNullException(nameof(filterData)); }
 
            var filters = Terrasoft.Common.ServiceStackTextHelper.Deserialize<Terrasoft.Nui.ServiceModel.DataContract.Filters>(filterData);
 
            string rootSchemaName = filters.RootSchemaName;
            if (string.IsNullOrEmpty(rootSchemaName))
            {
                return null;
            }
            IEntitySchemaQueryFilterItem esqFilters = filters.BuildEsqFilter(rootSchemaName, userConnection);
            var queryFilterCollection = esqFilters as EntitySchemaQueryFilterCollection;
            var esq = new EntitySchemaQuery(userConnection.EntitySchemaManager, rootSchemaName);
 
            if (queryFilterCollection != null)
            {
                if (queryFilterCollection.Count == 0)
                {
                    return esq;
                }
                esq.Filters.LogicalOperation = queryFilterCollection.LogicalOperation;
                esq.Filters.IsNot = queryFilterCollection.IsNot;
                esq.Filters.IsEnabled = queryFilterCollection.IsEnabled;
                foreach (IEntitySchemaQueryFilterItem filter in queryFilterCollection)
                {
                    esq.Filters.Add(filter);
                }
            }
            else
            {
                esq.Filters.Add(esqFilters);
            }
 
            return esq;
        }

При запуске получаю ошибку Expected hex 0x in '{0}'.

Проблему нашёл, она заключается в том что в json "value" является объектом, а не guid. Если "value": "3631ec86-e4cd-490c-9614-cea3bbf71187", то метод отрабатывает корректно. 



Единственный вариант исправления этой проблемы пока только замена с помощью регулярной строки value объект на value guid. Есть ли другие варианты решения данной проблемы.

Нравится

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

Добрый день,

 

В базовой реализации уже есть логика, которая вытаскивает из группы (папки) фильтры. Она находится в CommonUtilities, нужно смотреть в метод GetFolderEsqFilters, он в конце возвращает esqFilters (типа IEntitySchemaQueryFilterItem). Думаю это то что Вам нужно.

Добрый день,

 

В базовой реализации уже есть логика, которая вытаскивает из группы (папки) фильтры. Она находится в CommonUtilities, нужно смотреть в метод GetFolderEsqFilters, он в конце возвращает esqFilters (типа IEntitySchemaQueryFilterItem). Думаю это то что Вам нужно.

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

Хочу добавить в сотрудники в Карьеру фильтруемое справочное поле, не получается составить запрос

"DerivedClients": {

                                "dataValueType": Terrasoft.DataValueType.LOOKUP,

                                "lookupListConfig": {

                                     /* Массив фильтров, которые применяются к запросу для формирования данных поля-справочника. */

                                    "filters": [

                        function() {

                            var filterGroup = Ext.create("Terrasoft.FilterGroup");

                            filterGroup.add("IsUser", Terrasoft.createColumnIsNotNullFilter("[SysAdminUnit:Account].UsrLookup3"));

                            filterGroup.add("IsActive",

                                Terrasoft.createColumnFilterWithParameter(

                                    Terrasoft.ComparisonType.EQUAL,

                                    "[SysAdminUnit:Account].UsrLookup3",

                                    true));

                            return filterGroup;

                        }

                    ]

                              }

                        },

нужно сравнить со значением справочника "наш сотрудник" только не понимаю как, накорябал что-то но не уверен что это правильно

Нравится

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

Александр, добрый день!

Привожу пример построения фильтра по справочному полю.

Есть объект StTrip и необходимо отфильтровать справочное поле StTransport по определённому параметру:

"StTransport": {
                "dataValueType": Terrasoft.DataValueType.LOOKUP,
                "lookupListConfig": {
                    "filters": [
                        function() {
                            var filterGroup = Ext.create("Terrasoft.FilterGroup");
                            filterGroup.add("IsActive",
                                Terrasoft.createColumnFilterWithParameter(
                                    Terrasoft.ComparisonType.GREATER,
                                    "[StTransport:Id].StMaxWeight",
                                    this.get("StWeight")));
                            return filterGroup;
                        }
                    ]
                }
            }

Обратите внимание на формулировку StTransport:Id. Надеюсь данный пример поможет вам с вашей задачей.

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

В итоге я сделал как в документации, переопределил модуль EmployeeCareerPag

схему  

define("EmployeeCareerPage", [], function() {
    return {
        /* Название схемы объекта страницы записи. */
        "entitySchemaName": "Employee",
        /* Атрибуты модели представления. */
        "attributes": {
            /* Колонка модели представления. */
            "DerivedClients": {
                /* Тип данных колонки модели представления. */
                "dataValueType": Terrasoft.DataValueType.LOOKUP,
                /* Конфигурационный объект атрибута типа LOOKUP. */
                "lookupListConfig": {
                    /* Массив фильтров, которые применяются к запросу для формирования данных поля-справочника. */
                    "filters": [
                        function() {
                            var filterGroup = Ext.create("Terrasoft.FilterGroup");
                            //filterGroup.add("IsUser", Terrasoft.createColumnIsNotNullFilter("[Account:UsrLookup3].Id"));
                            filterGroup.add("IsUser", Terrasoft.createColumnIsNotNullFilter("[Account:AccountType].Name"));
                            filterGroup.add("IsUser",
                                Terrasoft.createColumnFilterWithParameter(
                                    Terrasoft.ComparisonType.EQUAL,
                                   "[Account:AccountType].Name" === "наш сотрудник",
                                    true));
                            return filterGroup;
                        }
                    ]
                }
            }
        }
    };
});

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

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

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

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

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

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

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

Нравится

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("&lt;здесь Id контакта&gt;", 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"
   )
);

 

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

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

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