Добрый день. Необходимо написать функцию, которая подсчитывает количество значений в записи. Проблема в том, что из-за того что esq выполняется асинхронно, функция всегда возвращает undefined. Нужно как-то вернуть из нее значение, так как функция будет использоваться повторно. Как это пофиксить? Спасибо.

 

             /**
             * Подсчет количества продуктов в детали.
             */
            checkProductsCount: function() {
                var select = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "OpportunityProductInterest"
                });
                    
                var esqRestaurantFilter = Terrasoft.createColumnFilterWithParameter(
                Terrasoft.ComparisonType.EQUAL, "Opportunity.Id", this.get("Id"));
                select.filters.add("selectFilter", esqRestaurantFilter);
                
                var selectedProductsCount = select.getEntityCollection(function(result) {
                    try {
                        if (!result.success) {
                            throw new Error("Ошибка запроса данных");
                        }
                    
                        return result.collection.getCount();
                    }
                    catch (e) {
                        Terrasoft.showErrorMessage(e.message);
                    }
                }, this);
                return selectedProductsCount;
            }

Нравится

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

Результат функции вы можете записать в атрибут либо сразу в поле через this.set

this.set("Filed", value)

Если после вычитки значений нужные еще какие-то действия, можно на атрибут повесить метод-обработчик по изменению атрибута (свойство dependencies). Подробнее про вычисляемые поля тут:  https://academy.terrasoft.ru/documents/technic-sdk/7-16/dobavlenie-vych…

Так же вы можете столкнуться с тем, что в callback'е от вызова функции getEntityCollection не будет доступа к полям (на самом деле просто другой контекст в this будет), в этом случае следует перед выполнением запроса записать this в другую переменную:

var self = this.

 

var self = this;
 
//ну и далее
var selectedProductsCount = select.getEntityCollection(function(result) {
                   if (result && result.success) {
                    self.set("Filed", value);
                        }
                }, this);

 

 

Результат функции вы можете записать в атрибут либо сразу в поле через this.set

this.set("Filed", value)

Если после вычитки значений нужные еще какие-то действия, можно на атрибут повесить метод-обработчик по изменению атрибута (свойство dependencies). Подробнее про вычисляемые поля тут:  https://academy.terrasoft.ru/documents/technic-sdk/7-16/dobavlenie-vych…

Так же вы можете столкнуться с тем, что в callback'е от вызова функции getEntityCollection не будет доступа к полям (на самом деле просто другой контекст в this будет), в этом случае следует перед выполнением запроса записать this в другую переменную:

var self = this.

 

var self = this;
 
//ну и далее
var selectedProductsCount = select.getEntityCollection(function(result) {
                   if (result && result.success) {
                    self.set("Filed", value);
                        }
                }, this);

 

 

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

Приветствую! 

Недавно занялся изучением и работой с платформой Creatio. По тому по коду прошу не ругать ;) 
 

Задача популярная: выбрать из таблицы записи по фильтру, посчитать кол-во совпадений и сравнить с системной настройкой. 

Код реализации с getEntity:

var message;
 
var recordId = this.get("Id");
 
if(recordId) {
		var esq1 = this.Ext.create("Terrasoft.EntitySchemaQuery", {
						rootSchemaName: "UsrSwimmProgramm"
		});
 
		var filterA = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPBooleanActive" , 1);
		var filterP = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPLookupPeriod.Name" , "Ежедневно");
		esq1.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
		esq1.filters.add("filterA",filterA);
		esq1.filters.add("filterP",filterP);
 
		esq1.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, 
						"NumberDayLesson", Terrasoft.AggregationEvalType.ALL);
 
 
				esq1.getEntity(recordId, function(result) {
					if (!result.success) {
						this.showInformationDialog("Ошибка запроса");
						return;
					}
					message = result.entity.get("NumberDayLesson") + "\n";
				this.showInformationDialog(message);
				}, this);
 
				}

Код реализации с getEntityCollection:

var message;
var recordId = this.get("Id");
 
if(recordId) {
			var esq1 = this.Ext.create("Terrasoft.EntitySchemaQuery", {
						rootSchemaName: "UsrSwimmProgramm"
				});
 
				var filterA = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPBooleanActive" , 1);
				var filterP = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPLookupPeriod.Name" , "Ежедневно");
				esq1.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
				esq1.filters.add("filterA",filterA);
				esq1.filters.add("filterP",filterP);
 
				esq1.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, 
						"NumberDayLesson", Terrasoft.AggregationEvalType.ALL);
 
				esq1.getEntityCollection( function(result){
					message = result.collection.getByIndex(0).get("NumberDayLesson");
					this.showInformationDialog(message);
				},this);
 
	}

 

Так вот, почему при всех равных метод getEntity выдает не определенной значение, а вот с getEntityCollection все работает норм ? 

 

 

Нравится

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

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

 

Метод getEntity используется для получения одной строки набора данных по заданному первичному ключу.

И в Вашем случае этот метод не срабатывает, потому что в заданном наборе данных не находит запись по этому recordId. Фактически, при использовании этого метода Вы добавляете ещё один фильтр по полю Id записи.

 

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

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

 

Метод getEntity используется для получения одной строки набора данных по заданному первичному ключу.

И в Вашем случае этот метод не срабатывает, потому что в заданном наборе данных не находит запись по этому recordId. Фактически, при использовании этого метода Вы добавляете ещё один фильтр по полю Id записи.

 

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

Спасибо большое, Алла. Уже смотрю.

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

Добрый день коммьюнити,

Просто оставлю это здесь, чтобы самому потом не забыть как этим пользоваться)

Итак, у нас есть запрос с двумя where in или exists. В приведенном ниже примере он должен выбрать из перечня схем в SysSchema только те, UId которых есть в таблице SysModuleEntity в поле SysEntitySchemaUid и при этом сами значения SysModuleEntity должны быть в таблице SysModule и там признак IsSystem не должен быть false.

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

select * 
from sysschema 
where uid in (
    select sysentityschemauid from sysmoduleentity 
    where id in (
        select sysmoduleentityid from sysmodule
        where issystem = 'false'
    )
)
 
--он же, только через exists
select * 
from sysschema 
where exists (
    select id from sysmoduleentity 
    where sysentityschemauid = uid and exists(
        select id from sysmodule 
        where sysmoduleentityid = sysmoduleentity.id
        and issystem = 'false'
    )
)

Выполнить его нужно на клиентской части и по каким-то причинам нужно выполнить только через ESQ и лучше всего одним запросом. Например, мне это было нужно, чтобы вставить свой фильтр справочного поля в уже существующий экземпляр esq вместо того, чтобы городить тонны замещающей логики.
Чтобы это выполнить, нам нужно внимательно руководствоваться вот этой великолепной статьей https://community.terrasoft.ru/articles/kak-sdelat-filtraciu-pola-po-exists-filtru-s-parametrom-znacenie-drugogo-pola и проявить немного смекалочки) 
Сколько ни бейтесь у вас не выйдет сделать подобным образом:
 

esq.filters.addItem(Terrasoft.createExistsFilter("[SysModule:SysModuleEntity:SysEntitySchemaUId:UId].Id")

а жаль, было бы удобно)

Вместо этого нам нужно сделать сразу несколько вложенных фильтров, вот так:
 

var subSubFilters = Terrasoft.createFilterGroup();
subSubFilters.addItem(Terrasoft.createColumnFilterWithParameter(
    Terrasoft.ComparisonType.EQUAL,
    "IsSystem", false));
var subFilters = Terrasoft.createFilterGroup();
subFilters.addItem(Terrasoft.createExistsFilter("[SysModule:SysModuleEntity].Id", subSubFilters));
esq.filters.addItem(Terrasoft.createExistsFilter("[SysModuleEntity:SysEntitySchemaUId:UId].Id", subFilters));

Фух, работа сделана, можно наградить себя чем-то вкусным и лучше всего очень вредным :)

Нравится

Поделиться

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

А почему бы вообще не вывернуть наизнанку, написав запрос к SysModule, связанным при помощи inner join с SysModuleEntity и затем с SysSchema?

select distinct sysschema.* from sysmodule 
inner join sysmoduleentity on sysmodule.sysmoduleentityid = sysmoduleentity.id
inner join sysschema on  sysmoduleentity.sysentityschemauid = sysschema.uid
where issystem  = 'false'

 

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

выглядит интересно, но как это написать с помощью фильтра в esq?)

Как добавляются join разных типов, см. тут. А distinct включается в конструкторе ESQ при помощи isDistinct: true (через запятую после значения rootSchemaName).

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

Для отладки необходимо получить SQL текст ESQ запроса на front-end

Нравится

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

Насколько мне известно, такой возможности нет.

В случае с фронтендом можно смотреть запрос через SQL профайлер.

Насколько мне известно, такой возможности нет.

В случае с фронтендом можно смотреть запрос через SQL профайлер.

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

Если не использую фильтр, то все работает, но без фильтрации
Если использую, то null на выходе

В чем может быть причина?

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
        rootSchemaName: "GeneralForm"
    });
    
    esq.addColumn("Id");
    esq.addColumn("UsrCode");
    esq.addColumn("UsrInfoId.Name");
    esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
    Terrasoft.ComparisonType.EQUAL, "UsrInfoId.Name", "Инфо"));
    
    var rowsCount = 0;
    var rowsCount1 = "";
    esq.getEntityCollection(function(result) {
        if (result.success) {
            
            
            result.collection.each(function (item) {
                rowsCount = rowsCount + 1;
                rowsCount1 += item.get("UsrCode") + "#" + item.get("UsrInfoId.Name") + 
                    "(" + rowsCount + ")" + "\n";
            });
            this.set("UsrCount", rowsCount1);
        }
    }, this);

Нравится

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

Посмотрите профилировщиком какой sql запрос отправляется в БД, это поможет определить проблему

Посмотрите профилировщиком какой sql запрос отправляется в БД, это поможет определить проблему

Ошибка в том, что Вы неправильно построили связи - нужно писать UsrInfo.Name, а у Вас UsrInfoId.Name.

Вот корректный код:

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
        rootSchemaName: "GeneralForm"
    });
    
    esq.addColumn("Id");
    esq.addColumn("UsrCode");
    esq.addColumn("UsrInfo.Name");
    esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
    Terrasoft.ComparisonType.EQUAL, "UsrInfo.Name", "Инфо"));
    
    var rowsCount = 0;
    var rowsCount1 = "";
    esq.getEntityCollection(function(result) {
        if (result.success) {
            
            
            result.collection.each(function (item) {
                rowsCount = rowsCount + 1;
                rowsCount1 += item.get("UsrCode") + "#" + item.get("UsrInfo.Name") + 
                    "(" + rowsCount + ")" + "\n";
            });
            this.set("UsrCount", rowsCount1);
        }
    }, this);

Ну, и на будущее смотрите, какая ошибка возвращается в браузере и выполняете отладку клиентского кода, тогда сразу становится понятно, в какой строке кода допущена ошибка.

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

пытаюсь реализовать запрос:

select 
    q1.UsrCode
    , q2.Name
from 
    GeneralForm q1 
    join UsrInfoList q2 
on 
    q1.UsrInfoId = q2.Id

При моей текущей реализации этот кусок работает:
esq.addColumn("UsrInfoId.Name");
Проблема с фильтром. 

Григорий Чех,

Ок. Разбираюсь с тем как его использовать.

Григорий Чех,

а как корректно этот механизм объявить в коде?
добавил:
//перед esq
var performanceManagerLabel = "";
performanceManager.start(performanceManagerLabel + "_Init");
//сразу после фильтрации
performanceManager.stop(performanceManagerLabel + "_Init");
пишет:
'performanceManager' is not defined
 

Григорий Чех,

Нашел. 

performanceManager указать надо было.

Григорий Чех,

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

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

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

select 
    q1.Id
    q1.UsrCode
    , q2.Name
from 
    GeneralForm q1 
    join UsrInfoList q2 
on 
    q1.UsrInfoId = q2.Id

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
    rootSchemaName: "GeneralForm"
esq.addColumn("Id");
esq.addColumn("UsrCode");
esq.addColumn("UsrInfoId.Name");
esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
Terrasoft.ComparisonType.EQUAL, "UsrInfoId.Name", "Инфо"));

Посмотрите в профайлере, что за SQL-запрос идёт в базу при выполнении последнего кода и потом запустите в Management Studio  его отдельно, чтобы выяснить, почему у него пустой результат.

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

система в yазвании таблицы, которую пробую подцепить добавляет в начале и конце названия еще символы

SysUsrInfoListLcz. А нужна таблица была UsrInfoList. Это фича такая?

Хотя нет. Не в ней дело. Тут все хорошо.

SysUsrInfoListLcz — это автоматически сгенерированная таблица переводов названий для UsrInfoList.

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

Добрый день!

Пробую реализовывать запрос к данных через ESQ таким образом:

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "UsrTbl1"
                });
                esq.addColumn("Id");
                esq.addColumn("UsrPar1");esq.addColumn("UsrInfoId");
                esq.addColumn("UsrValueList.Name");//вот с такими строками уже начинается проблема

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrValueList.Name", "значение1"));//и с такими фильтрами

 

Если нужно получить значение колонок с таблицы - rootSchemaName, то не вопрос.

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

GUID  видимо со String плохо понимают друг друга. Если ли примеры их нормального совместного использования в рамках ESQ?

Можно ли как-то понять причины неработоспособности прямых ссылок? Или хотя бы понять как с GUID быть? Даже если я значение GUID пытаюсь вставлять так, то не работает:

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfoId", "337ED96B-B658-48B0-BBB6-7FACF918C735"));

Нравится

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

Eсли нужно получить справочную колонку, то её название нужно указывать без приставки "Id", как в схеме таблицы:

esq.addColumn("UsrInfo")

Аналогично и с фильтрами:

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfo", "337ED96B-B658-48B0-BBB6-7FACF918C735"));

Но обратите внимание, что, если у Вас фильтр построен по обратным связям, то можно писать 2 способами.

1. Через Id и тогда в качестве значения фильтра указываем Id:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment.Id", shipment.value));

2. Через справочное поле и тогда в качестве значения указывать значение справочного поля:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment", shipment));

А вообще, чтобы понять причину ошибки нужно отладиться на стороне клиента, если запрос уходит в базу данных, то посмотреть в SQL profiler, какой запрос идет в базу и какой результат работы этого запроса.

 

В js все Guid преобразуйте к нижнему регистру

те в вашем случае напишите что то типа esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfoId", "337ed.....

Eсли нужно получить справочную колонку, то её название нужно указывать без приставки "Id", как в схеме таблицы:

esq.addColumn("UsrInfo")

Аналогично и с фильтрами:

esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrInfo", "337ED96B-B658-48B0-BBB6-7FACF918C735"));

Но обратите внимание, что, если у Вас фильтр построен по обратным связям, то можно писать 2 способами.

1. Через Id и тогда в качестве значения фильтра указываем Id:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment.Id", shipment.value));

2. Через справочное поле и тогда в качестве значения указывать значение справочного поля:

var shipment = this.get("BTShipment");

sampleESQ.filters.addItem(sampleESQ.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.EQUAL, "[BTSampInShipment:BTSampleID].BTShipment", shipment));

А вообще, чтобы понять причину ошибки нужно отладиться на стороне клиента, если запрос уходит в базу данных, то посмотреть в SQL profiler, какой запрос идет в базу и какой результат работы этого запроса.

 

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

Добрый день,подскажите пожалуйста,а в мобильном приложении есть функция автозаполнения поля ? Если да,то как это можно организовать ? Чтобы при создании новой записи в разделе,поле автоматически заполнялось значением,что то вроде счетчика записей. Например у меня в разделе есть 10 записей - запись 1,запись 2,запись 3 ... 10. При создании новой чтобы поле Название сразу заполнялось как запись 11. Подскажите примерный ход действий(на данный момент беру запросом с базы,сортируя и беру следующее число,но такой подход не очень хороший). Может быть есть более правильный вариант ? Спасибо!

Нравится

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

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

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

Terrasoft.sdk.Model.setModelEventHandler("ActivitySKU", 
    Terrasoft.ModelEvents[Terrasoft.ModelEventKinds.Before].update,
    function(config) {
        var record = config.scope.eventConfig.records[0];
        record.set("UsrIsChecked", true);
        Ext.callback(config.success, config.scope);
});

Или с помощью Custom бизнес правила:

Terrasoft.sdk.Model.addBusinessRule("ModelName", {
    name: "RuleName",
    ruleType: Terrasoft.RuleTypes.Custom,
    events: [Terrasoft.BusinessRuleEvents.Load, Terrasoft.BusinessRuleEvents.ValueChanged],
    executeFn: function(record, rule, column, customData, callbackConfig) {
        record.set("UsrColumn", "some value");
        Ext.callback(callbackConfig.success, callbackConfig.scope);
    }
})

Третий вариант - в кастомной странице повесить на загруженную запись дополнительный обработчик на изменение записи:

onLoadRecord: function(loadedRecord) {
    this.callParent(arguments);
    loadedRecord.on("columnchanged", this.onRecordColumnChanged, this);
},

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

var control = Ext.getCmp("control_id");
control.setValue("some value");

 

Такое есть смысл на стороне сервера. Есть специальное действие в БП для получения номера по порядку.

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

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

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

Terrasoft.sdk.Model.setModelEventHandler("ActivitySKU", 
    Terrasoft.ModelEvents[Terrasoft.ModelEventKinds.Before].update,
    function(config) {
        var record = config.scope.eventConfig.records[0];
        record.set("UsrIsChecked", true);
        Ext.callback(config.success, config.scope);
});

Или с помощью Custom бизнес правила:

Terrasoft.sdk.Model.addBusinessRule("ModelName", {
    name: "RuleName",
    ruleType: Terrasoft.RuleTypes.Custom,
    events: [Terrasoft.BusinessRuleEvents.Load, Terrasoft.BusinessRuleEvents.ValueChanged],
    executeFn: function(record, rule, column, customData, callbackConfig) {
        record.set("UsrColumn", "some value");
        Ext.callback(callbackConfig.success, callbackConfig.scope);
    }
})

Третий вариант - в кастомной странице повесить на загруженную запись дополнительный обработчик на изменение записи:

onLoadRecord: function(loadedRecord) {
    this.callParent(arguments);
    loadedRecord.on("columnchanged", this.onRecordColumnChanged, this);
},

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

var control = Ext.getCmp("control_id");
control.setValue("some value");

 

Спасибо!

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

Всем привет.

Ввиду не внятности документации прошу помощи.

Как составить такой запрос используя ESQ на клиенте?

SELECT account.UsrINN,(SELECT TOP(1) ModifiedOn FROM Activity activity WHERE activity.AccountId=account.Id ORDER BY ModifiedOn) AS LastComunicationDate  FROM Account account  WHERE account.UsrINN = '7730616959' 

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

 

 

Нравится

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

Последовский Роман,

А так?

var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "Account" });
esq.addColumn("UsrINN");
esq.addAggregationSchemaColumn("[Activity:Account].ModifiedOn", 5, "MaxModifiedOn");
esq.filters.addItem(esq.createColumnFilterWithParameter(3, "UsrINN", "7730616959"));
esq.getEntityCollection(function (result) {
	if (result.success && result.collection.getCount() > 0) {
		result.collection.collection.each(function(item) {
			//some logic
		}, this);
	}
}, this);

 

Роман, приветствую,

А у вас проблема в подзапросе или в сортировке?

Есть в сортировке, то возможно вам поможет вот это: https://community.terrasoft.ru/questions/entityschemaquery-order

Если в подзапросе, то можно

1. Сделать один запрос, а в его колбэке (или в цикле foreach, если это C# сделать еще один запрос).

2. Судя по всему подзапрос можно заменить обычным джойном.

На клиенте? Тогда как-то так:

var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "Activity" });
 
esq.addColumn("Account.UsrINN", "AccountINN");
var column = esq.addColumn("ModifiedOn");
column.orderDirection = Terrasoft.OrderDirection.ASC; //asc по modifiedOn
 
esq.rowCount=1; //top1
 
esq.filters.addItem(esq.createColumnFilterWithParameter(3, "Account.UsrINN", "7730616959")); //фильтр по INN
 
esq.getEntityCollection(function (result) {
	if (result.success && result.collection.getCount() > 0) {
		var item = result.collection.getByIndex(0);
		var INN = item.get("AccountINN");
		var modOn = item.get("ModifiedOn");
	}
}, this);

 

Мне кажется, тут сам SQL-запрос надо вывернуть наизнанку:

SELECT max(ModifiedOn) FROM Activity activity
left join Account account on activity.AccountId=account.Id 
WHERE account.UsrINN = '7730616959'

То есть получим запрос с одной колонкой и одним фильтром по прямой связи. Заодно вместо TOP 1 можно просто максимум при помощи addAggregationSchemaColumn. А затем фильтруем, применив createColumnFilterWithParameter к колонке «Account.UsrINN».

 

Спасибо большое, вариант Данилы работает, но

Затык как раз в том что мне нужно вывести именно список контрагентов(UsrINN), а уже к каждому из них привязать дату последней работы с активностью.

 

 

 

Судя по исходному вопросу, код контрагента известен и равен 7730616959, следовательно, в списке всегда будет одна строка. Если таких номеров несколько, можно получить этим кодом в цикле для каждого.

Это часть системы поиска дублей.

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

ИНН:123

10 контрагентов, но у 5ти из них есть активности.

Если я сначала полезу в таблицу активности, то мне выведется на экран только 5ть контрагентов, а реально их 10.

В самом начале я указал именно тот SQL запрос, который нужно изобразить с помощью ESQ.

Конечно можно это сделать двумя циклами, но хочется понять можно ли это сделать одним запросом

 

Такое есть смысл делать на сервере. В классе Select можно делать почти то же, что в SQL-запросах, плюс дубли могут быть недоступны через ESQ из-за прав доступа текущего пользователя, а Select работает в обход них.

Последовский Роман,

А так?

var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "Account" });
esq.addColumn("UsrINN");
esq.addAggregationSchemaColumn("[Activity:Account].ModifiedOn", 5, "MaxModifiedOn");
esq.filters.addItem(esq.createColumnFilterWithParameter(3, "UsrINN", "7730616959"));
esq.getEntityCollection(function (result) {
	if (result.success && result.collection.getCount() > 0) {
		result.collection.collection.each(function(item) {
			//some logic
		}, this);
	}
}, this);

 

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

Памятник поставить мало! Спасибо)

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

Приветы, помогите как написать запрос на esq или select

SELECT TOP 1000 aa.[Id]
      ,aa.[AddressTypeId]
      ,aa.[Address]
      ,aa.[AccountId]
      ,aa.[SxSubwayStationId]
  FROM [BetaPressBPM].[dbo].[AccountAddress] aa, [BetaPressBPM].[dbo].[Account] a
  aa.AccountId = a.Id and a.Id = 'AcountId_Value' 
  and aa.AddressTypeId='FB7A3F6A-F36B-1410-6F81-1C6F65E50343'
 

Нравится

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

Тут зависит от того, где будет писаться запрос: на сервере или у клиента. 

Если у клиента: https://academy.terrasoft.ru/documents/technic-sdk/7-11/ispolzovanie-entityschemaquery-dlya-chteniya-dannyh-iz-bd

Если на сервере: https://academy.terrasoft.ru/documents/technic-sdk/7-11/crud-operacii-na-servere

Для TOP 1000 нужно использовать RowCount на сервере или rowCount на клиенте.

Все остальное достаточно подробно и с примерами описано на академии по ссылкам выше.

Золотарев Артем Андреевич,

Спасибо,

Мы нашли вот такую возможность https://prnt.sc/ix4znc

Покажите пример как сие настроить кодом?? 

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

 

Вот ссылка, где описаны бизнес-правила, создаваемые из кода, а не мастера: https://academy.terrasoft.ua/documents/technic-sdk/7-12/biznes-pravila-i-ih-primenenie Там еще 5 вложенных статей (посмотрите в левой части в содержимом).

Там достаточно подробно описано применение с примерами.

Золотарев Артем Андреевич,

Посмотрел, спасибо. В коде не разобрался как указать что справочник и конкретное значение справочника. И есть вот такая задача (хак нужен):

Дано

 

Есть самописная страница на которую добавлена ссылка из cti panel и вроде как удобно пользователям

 

Найти

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

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

У обычной самописной страницы не получится вызвать визуальный редактор. Мастер разделов работает со связкой Объект-Раздел-Страница. 

Золотарев Артем Андреевич,

Вид адреса у нее

http://practice-clone.local/0/Nui/ViewModule.aspx#CardModuleV2/SxCandid…

подменили все как положено, но из меню <вид> -> <открыть дизайнер страницы>  ничего не открывается, хотя вроде как связка соблюдена

Вероятнее всего страница редактирования не привязана к сущности.

Посмотрите подобный вопрос по ссылке: https://community.terrasoft.ua/questions/registracia-stranicy-redaktirovania-obekta

Там в комментариях достаточно хорошо описали порядок действий.

Золотарев Артем Андреевич,

Да, там не соответствие корневых схем... 

https://prnt.sc/j1pqw3 вот как такое кодом сделать в rules? есть пример

Пример бизнес-правил есть тут: https://academy.terrasoft.ru/documents/technic-sdk/7-12/primer-primeneniya-pravila-filtration, а пути к колонкам пишуться как в EntitySchemaQuery

Золотарев Артем Андреевич,

Угу, спасибо

 

Вот у меня есть БП созданное мастером, такое же нужно перенести на самописную страницу

                "BpDicWorkAddr": {
                    "efe924fb-a8b5-4522-870f-ca545fe50156": {
                    "uId": "efe924fb-a8b5-4522-870f-ca545fe50156",
                    "enabled": true,
                    "removed": false,
                    "ruleType": 1,
                    "baseAttributePatch": "AddressType",
                    "comparisonType": 3,
                    "type": 0,
                    "value": "fb7a3f6a-f36b-1410-6f81-1c6f65e50343",
                    "dataValueType": 10
                    }
                }

 

"efe924fb-a8b5-4522-870f-ca545fe50156" - это наверно произвольное имя, а вот дальше какие гуиды не так очевидно???

QArt,

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

Золотарев Артем Андреевич,

Это бизнес правило, код которого создан мастером, уже разобрался, можно просто уникализировать

efe924fb-a8b5-4522-870f-ca545fe50156, например, efe924fb-a8b5-2222-870f-ca545fe50156 и вставить этот код в другую схему самописной страницы и оно заработало :)

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

Доброго времени суток,

Я бы хотел попросить помощи в реализации подобного SQL запроса через entitySchemaQuery на фронт енде

Select id,
       name
from TableA 
where 
    accountId = '777' 
    and (name <> 'Igor' 
         OR name <> 'Alex') 

Из того что я пробовал

var esQuery = this.Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "TableA" });
				esQuery.addColumn("Id");
				esQuery.addColumn("Name");
 
var esqMainFilter = esQuery.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "account", "777");
 
var esqFirstFilter = esQuery.createColumnFilterWithParameter(Terrasoft.ComparisonType.NOT_EQUAL, "Name", "Igor");
var esqSecondFilter = esQuery.createColumnFilterWithParameter(Terrasoft.ComparisonType.NOT_EQUAL, "Name", "Alex");
 
 
var secondaryFilter = Terrasoft.createFilterGroup();
secondaryFilter.logicalOperation = Terrasoft.LogicalOperatorType.OR;
secondaryFilter.add("esqFirstFilter", esqFirstFilter);
secondaryFilter.add("esqSecondFilter", esqSecondFilter);
 
 
esQuery.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
esQuery.filters.add("esqMainFilter", esqMainFilter);
esQuery.filters.add("esqSecondaryFilter", secondaryFilter);

Спасибо!

Нравится

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

Добрый день, 

Вот пример похожего запроса через entitySchemaQuery на клиенте

esQuery = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "Contact" });
esQuery.addColumn("Name");
 
var esqMainFilter = this.Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Account", "b3f737a4-d95b-4c87-9082-8d0deb421882");
esQuery.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
esQuery.filters.addItem(esqMainFilter);
 
var esqFirstFilter = this.Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.NOT_EQUAL, "Name", "test2");
var esqSecondaryFilter = this.Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.NOT_EQUAL, "Name", "test3");
 
var filterCollection = this.Terrasoft.createFilterGroup();
filterCollection.logicalOperation = Terrasoft.LogicalOperatorType.OR;
filterCollection.addItem(esqFirstFilter);
filterCollection.addItem(esqSecondaryFilter);
 
esQuery.filters.addItem(filterCollection);
esQuery.getEntityCollection();

используем this.Terrasoft.createFilterGroup() для того что бы добавить группу фильтров с OR.

выполнив этот запрос в консоли браузера профайлером отловила запрос который пришел в БД, выглядит он следующим образом:

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