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



Вытащил 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). Думаю это то что Вам нужно.

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

Добрый день, есть такая задача:

На странице есть две вкладки "Позиции заказа" и "Документы по заказу". На этих вкладках есть детали, названия деталей соответствуют вкладкам. Детали основаны на разных объектах.

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

Вопрос: Как обновить значение колонки (какой-либо) в первой детали "позиции заказа"? 

Пыталась сделать это так:

Колонка в детали "Документы по заказу" обновляется через UpdateQuery, нашла инструкцию в документации.

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

Я пыталась сделать коллекцию через esq по позициям заказа. Устанавливаю значение через инструкцию this.set("NameColumn",value);

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

Нравится

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

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

 

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

var value = this.get('UsrChange') – новое значение, которое вы хотите записать в необходимую колонку;

updateQuery.setParameterValue("Name", value, this.Terrasoft.DataValueType.TEXT) – в значение "Name" ("Notes" во втором запросе) подставьте название поля из объекта, в которое хотите записать изменения;

Удостоверьтесь, что вы добавили в дизайнере нужные поля на страницу. "detailColumn" - “Where detail column”, "masterColumn" - “Equals to page column”, "entitySchemaName"  - “Detail”.

 

...
details: /**SCHEMA_DETAILS*/{"UsrTabSecond": {
        "schemaName": "OpportunityHistoryActivityDetail",
        "entitySchemaName": "Activity",
        "filter": {
        "detailColumn": "Priority",
        "masterColumn": "UsrLookup2"
        }
    },
    "UsrTabFirst": {
        "schemaName": "AccountContactsDetailV2",
        "entitySchemaName": "Contact",
        "filter": {
        "detailColumn": "Job",
        "masterColumn": "UsrLookup1"
        }
    }
}/**SCHEMA_DETAILS*/,
    businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
        methods: {
             onMyButtonClick: function() {
                   var value = this.get('UsrChange');
                   var IdValue = this.get('UsrLookup1');
                   var updateQuery = Ext.create("Terrasoft.UpdateQuery", {
                       rootSchemaName: "Contact"});
                   var filters = updateQuery.filters;
                   filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
                       this.Terrasoft.ComparisonType.EQUAL, "Job", IdValue));
                   updateQuery.setParameterValue("Name", value, this.Terrasoft.DataValueType.TEXT);
                   updateQuery.execute(function(result){
                       if(result.success) this.updateDetail({detail: "UsrTabFirst"});}, this);                                 
                                                          
                   var value1 = this.get('UsrChange');
                   var IdValue1 = this.get('UsrLookup2');
                   var updateQuery1 = Ext.create("Terrasoft.UpdateQuery", {
                       rootSchemaName: "Activity"});
                   var filters1 = updateQuery1.filters;
                   filters1.addItem(this.Terrasoft.createColumnFilterWithParameter(
                       this.Terrasoft.ComparisonType.EQUAL, "Priority", IdValue1));
                   updateQuery1.setParameterValue("Notes", value1, this.Terrasoft.DataValueType.TEXT);
                   updateQuery1.execute(function(result){
                       if(result.success) this.updateDetail({detail: "UsrTabSecond"});}, this);
        }
},
...

 

С уважением,

Ангелина

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

 

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

var value = this.get('UsrChange') – новое значение, которое вы хотите записать в необходимую колонку;

updateQuery.setParameterValue("Name", value, this.Terrasoft.DataValueType.TEXT) – в значение "Name" ("Notes" во втором запросе) подставьте название поля из объекта, в которое хотите записать изменения;

Удостоверьтесь, что вы добавили в дизайнере нужные поля на страницу. "detailColumn" - “Where detail column”, "masterColumn" - “Equals to page column”, "entitySchemaName"  - “Detail”.

 

...
details: /**SCHEMA_DETAILS*/{"UsrTabSecond": {
        "schemaName": "OpportunityHistoryActivityDetail",
        "entitySchemaName": "Activity",
        "filter": {
        "detailColumn": "Priority",
        "masterColumn": "UsrLookup2"
        }
    },
    "UsrTabFirst": {
        "schemaName": "AccountContactsDetailV2",
        "entitySchemaName": "Contact",
        "filter": {
        "detailColumn": "Job",
        "masterColumn": "UsrLookup1"
        }
    }
}/**SCHEMA_DETAILS*/,
    businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
        methods: {
             onMyButtonClick: function() {
                   var value = this.get('UsrChange');
                   var IdValue = this.get('UsrLookup1');
                   var updateQuery = Ext.create("Terrasoft.UpdateQuery", {
                       rootSchemaName: "Contact"});
                   var filters = updateQuery.filters;
                   filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
                       this.Terrasoft.ComparisonType.EQUAL, "Job", IdValue));
                   updateQuery.setParameterValue("Name", value, this.Terrasoft.DataValueType.TEXT);
                   updateQuery.execute(function(result){
                       if(result.success) this.updateDetail({detail: "UsrTabFirst"});}, this);                                 
                                                          
                   var value1 = this.get('UsrChange');
                   var IdValue1 = this.get('UsrLookup2');
                   var updateQuery1 = Ext.create("Terrasoft.UpdateQuery", {
                       rootSchemaName: "Activity"});
                   var filters1 = updateQuery1.filters;
                   filters1.addItem(this.Terrasoft.createColumnFilterWithParameter(
                       this.Terrasoft.ComparisonType.EQUAL, "Priority", IdValue1));
                   updateQuery1.setParameterValue("Notes", value1, this.Terrasoft.DataValueType.TEXT);
                   updateQuery1.execute(function(result){
                       if(result.success) this.updateDetail({detail: "UsrTabSecond"});}, this);
        }
},
...

 

С уважением,

Ангелина

Anhelina, 

большое спасибо за помощь!

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

Просьба помочь собрать такой запрос при помощи класса select

select count(ID)

   from [dbo].[Case] AS TI

WHERE DATEPART(HOUR, DATEADD(hh, 6, TI.[UsrDueDate])) >=9  and DATEPART(HOUR, DATEADD(hh, 6, TI.[UsrDueDate])) <12

and FORMAT(DATEADD(hh, 6, TI.[UsrDueDate]), N'yyyy.MM.dd') = FORMAT(cast(GETDATE() +1 as date), N'yyyy.MM.dd')

Заранее спасибооо! 

Нравится

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

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

 

Вы можете настроить SQL-представление (view) с нужным условием.

 

А потом из этого представления уже делать выборку с помощью класса select.

 

Или же попробовать сделать по аналогии с примерами запросов по этой ссылке.

Alla Savelieva,

Благодарю, будем пробовать.

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

В БД формируется такой запрос:

SELECT Name, Data FROM SysModuleReportTable

 

Колонки Data нет в таблице SysModuleReportTable, но это уже детали.

 

Как найти откуда в коде этот запрос генерируется?

Какие есть варианты?

Нравится

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

Евгений, добрый день!

Исходя из таблицы SysModuleReportTable, этот запрос связан с печатными формами. Не могу точно сказать когда именно он формируется, однако, можно поступить следующим образом. Если вы используете mssql, то в меню Manegement->Extended Events->Session и там создать свою сессию, которая будет отлавливать вес запросы уходящие в бд. После запуска этой сессии повыполняйте действия с печатными формами и посмотрите. после чего в бд появляется этот запрос.

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

Доброе день, возник вопрос как из функции, которая возвращает таблицу передать параметры и вернуть её в формате ESQ (либо же DataTable, который можно преобразовать в ESQ)?

Нравится

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

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

Ответил на Ваш предыдущий вопрос.

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

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

Добрый вечер, возникла задача:

Нужно отфильтровывать SQL-запрос и создавать из него xlsx отчёт.

Фильтрация реализована с помощью хранимой процедуры, в которую из БП передаются значения, выбранные пользователем, но выгрузка в xlsx с помощью ExportToExcel выгружает только esq.

Можно ли как-нибудь перевести StoredProcedure в ESQ? Если нет, то как выгрузить StoredProcedure в xlsx?

 

Нравится

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

Добрый вечер.

 

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

 

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

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

Спасибо. Не подскажите, а как потом хранимую функцию вызвать в БП и передать в esq?

Вашу хранимую процедуру можно реализовать сразу на ESQ, не нужно делать никаких процедур, которые только усложняют жизнь.

И стандартными механизмами работать дальше с ESQ.

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

var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "EDOSystem");

var edoSystemIdColumn = esq.AddColumn("Id");

esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "Name", "SomeVAlue"));

Как можно сделать подобный фильтр по колонке Name без учитывания регистра?

 

Нравится

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

А найти записи по другому условию не выйдет?

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

 

 

Ну стандартного типа я не нашел для сравнения без регистра, но наверное вы можеет создать группу фильтров

var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
	rootSchemaName: "qrtEventAddRule"
});
esq.addColumn("qrtEventShipping.Id", "idEvent");
 
 
 
var filterGroup1 = Ext.create("Terrasoft.FilterGroup");
var esqSecondFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Name", value);
filterGroup1.add("qrtIsInsuranceTrue", esqSecondFilter);
 
var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "qrtService", value.toLowerCase());
filterGroup2.add("esqFirstFilter", esqFirstFilter);	
filterGroup2.logicalOperation = Terrasoft.LogicalOperatorType.OR;
 
esq.filters.add("1",filterGroup1);
}

Я не уверен но можно посмотреть также в сторону CONTAINS. он может без регистра сравнивает

 

самый извращенный и долгий вариант это написать в теле выборки свой фильтр и пройтись по все записям

 

// Определение конфигурационного объекта.
				var config = {
					// Название схемы сущности.
					entitySchemaName: "Contact",
					// Убирать дубли в результирующем наборе данных.
					isDistinct: true
				};
				// Получение данных.
				Terrasoft.DataManager.select(config, function (collection) {
					// Сохранение полученных записей в локальное хранилище.
					collection.each(function (item) {
                       //тут пишешь свое условие
						//this.console.log(item.viewModel.values)//поля записи
						Terrasoft.DataManager.addItem(item);
					});
				}, this);

 

Показать все комментарии
using System;
using System.Collections.Generic;
using Terrasoft.Core;
using Terrasoft.Core.DB;
using Terrasoft.Core.Entities;
 
namespace Norbit.Crm.EsPlus.Common
{
    /// <summary>
    /// Методы расширения для ESQ.
    /// </summary>
    public static class EsqExtensions
    {
        /// <summary>
        /// Постраничное чтение ESQ запроса.
        /// </summary>
        /// <param name="esq">Запрос.</param>
        /// <param name="userConnection">Пользовательское подключение.</param>
        /// <param name="rowCount">Количество считываемых записей за один раз(по умолчанию 1000).</param>
        /// <returns>Коллекция объектов из запроса.</returns>
        public static List<Entity> GetEntityCollectionPaginatedReading(
            this EntitySchemaQuery esq,
            UserConnection userConnection,
            EntitySchemaQueryOptions options = null,
            int rowCount = 1000)
        {
            if (esq == null)
            {
                throw new ArgumentNullException(nameof(esq));
            }
 
            if (userConnection == null)
            {
                throw new ArgumentNullException(nameof(userConnection));
            }
 
            var entityCollection = new List<Entity>();
            esq.UseOffsetFetchPaging = true;                              /// Использовать постраничное чтение.
 
            var esqOptions = options ?? new EntitySchemaQueryOptions                     /// Настройки получения коллекции.
            {
                PageableRowCount = rowCount,                             /// Количество считываемых записей.
                RowsOffset = 0,                                          /// Количество записей, которые необходимо пропустить
                PageableDirection = PageableSelectDirection.Next,
                PageableConditionValues = new Dictionary<string, object>()
            };
 
            var entities = esq.GetEntityCollection(userConnection, esqOptions);
 
            while (entities.Count > 0)
            {
                foreach (var entity in entities)
                {
                    entityCollection.Add(entity);
                }
                esqOptions.RowsOffset += esqOptions.PageableRowCount;
                esq.ResetSelectQuery();                                     /// Обнуление результата запроса.
                entities = esq.GetEntityCollection(userConnection, esqOptions);
            }
 
            return entityCollection;
        }
 
    }
}

 

Нравится

Поделиться

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

Есть подозрение. что поможет 

PageableDirection = PageableSelectDirection.First  при первом запросе.

потом сменить на Next

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

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

where encode("InputArguments", 'escape') like '%identifierNo=cardnumber123%';



По той же логике пытался сделать фильтр через ESQ такого формата:

esq.Filters.Add(
    esq.CreateFilterWithParameters(
        FilterComparisonType.Contain,
        "InputArguments",
        Encoding.UTF8.GetBytes(inputArguments)
));



В результате получаю исключение:  "42883: function upper(bytea) does not exist". Есть ли обходные пути для реализации данного фильтра?

Нравится

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

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

К сожалению, наше приложение не поддерживает фильтр Contain с типом данных "массив байт". Мы передадим данную проблему разработчикам приложения для исправления в будущих версиях.

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

Добрый день,  коллеги. Помогите пожалуйста сделать ESQ запрос с фильтрацией. Вывести 

TOP1 номер который соответсвует критерию. 

Читал статьи так и не понял.  Данный запрос в разделе контакты.

Select T1."Number" From  "ContactCommunication" T1

LEFT JOIN "Contact" T2 ON T1.Contact=T2.Id

Where T1.CommunicationType='3DDDB3CC-53EE-49C4-A71F-E9E257F59E49'

 

onEntityInitialized: function() {

        this.callParent(arguments);

        this.helping();

    },

    helping: function() {

     // Получаем [Id] объекта карточки.

      // Получаем [Id] объекта карточки.

var recordId = this.get("Id");

// Создаем экземпляр класса Terrasoft.EntitySchemaQuery с корневой схемой [Contact].

var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {

    rootSchemaName: "Contact"

});

esq.addColumn("[ContactCommunication:Contact:Id].Number", "Number");

esq.addColumn("[ContactCommunication:Contact:Id].CommunicationType", "CommunicationType");

var esqFirstFilter= esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "CommunicationType", "3DDDB3CC-53EE-49C4-A71F-E9E257F59E49");

// Добавление созданных фильтров в коллекцию запроса. 

esq.filters.add("esqFirstFilter", esqFirstFilter);

// В данную коллекцию попадут объекты - результаты запроса, отфильтрованные по двум фильтрам.

esq.getEntityCollection(function (result) {

    if (result.success) {

      result.collection.each(function (item) {

      this.showInformationDialog(result.entity.get("Number"));

        });

    }

}, this);

        }

Нравится

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

Вот мой пример по копированию всех адресов электронной почты контакта, по аналогии можно выбрать топ1 нужного типа

/** Копирование почты */
copyEmail: function() {
	if (this.get("Contact")) {
		var contact = this.get("Contact");
		contact = contact.value;
		var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
			rootSchemaName: "ContactCommunication"
		});
		var email = "";
		esq.addColumn("Contact");
		esq.addColumn("CommunicationType");
		esq.addColumn("Number");
		// Создание экземпляра первого фильтра.
		var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Contact", contact);
		// Создание экземпляра второго фильтра.
		var esqSecondFilter =	esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
							"CommunicationType", "ee1c85c3-cfcb-df11-9b2a-001d60e938c6");
		// Фильтры в коллекции фильтров запроса будут объединяться логическим оператором OR. 
		esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
		// Добавление созданных фильтров в коллекцию запроса. 
		esq.filters.add("esqFirstFilter", esqFirstFilter);
		esq.filters.add("esqSecondFilter", esqSecondFilter);
		// В данную коллекцию попадут объекты - результаты запроса, отфильтрованные по двум фильтрам.
		esq.getEntityCollection(function(result) {
			if (result.success) {
				result.collection.each(function(item) {
					// Обработка элементов коллекции.
					email = email + " " + this.get("Number");
				});
				this.set("UsrEmail", email);
			}
		}, this);
}

 

Вот мой пример по копированию всех адресов электронной почты контакта, по аналогии можно выбрать топ1 нужного типа

/** Копирование почты */
copyEmail: function() {
	if (this.get("Contact")) {
		var contact = this.get("Contact");
		contact = contact.value;
		var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
			rootSchemaName: "ContactCommunication"
		});
		var email = "";
		esq.addColumn("Contact");
		esq.addColumn("CommunicationType");
		esq.addColumn("Number");
		// Создание экземпляра первого фильтра.
		var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Contact", contact);
		// Создание экземпляра второго фильтра.
		var esqSecondFilter =	esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
							"CommunicationType", "ee1c85c3-cfcb-df11-9b2a-001d60e938c6");
		// Фильтры в коллекции фильтров запроса будут объединяться логическим оператором OR. 
		esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
		// Добавление созданных фильтров в коллекцию запроса. 
		esq.filters.add("esqFirstFilter", esqFirstFilter);
		esq.filters.add("esqSecondFilter", esqSecondFilter);
		// В данную коллекцию попадут объекты - результаты запроса, отфильтрованные по двум фильтрам.
		esq.getEntityCollection(function(result) {
			if (result.success) {
				result.collection.each(function(item) {
					// Обработка элементов коллекции.
					email = email + " " + this.get("Number");
				});
				this.set("UsrEmail", email);
			}
		}, this);
}

 

Быстров Сергей, Спасибо, сейчас попробуем. 

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