Есть такой пример в Документации:
Для раздела [Заказы] реализовать выделение тех записей реестра, которые находятся на стадии [Исполнение].
Подскажите: как определять другие стадии? Где находятся эти константы?
В этом примере стадия Исполнение.

if (running.value === OrderConfigurationConstants.Order.OrderStatus.Running)

Нравится

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

Добрый день!!!

все константные значения Статусы заказов находятся в схеме константы "OrderConfigurationConstants". вот выкладка из данной схемы:

OrderStatus: {
	InPlanned: "1f3ad326-effd-4ac3-a3e2-957e7def3684",
	InProgress: "29fa66e3-ef69-4feb-a5af-ec1de125a614",
	Running: "c8742634-ea8b-46d9-ba71-1989b951772d",
	Postprocessing: "5ab26d74-2fd1-4674-bae0-7622aa8383995",
	Closed: "40de86ee-274d-4098-9b92-9ebdcf83d4fc",
	Canceled: "8ab0f830-908b-40d7-80a3-7f49ef70ce70"
},

обратиться из кода к данным константам можно следующим образом:

var orderIsPlanned = OrderConfigurationConstants.Order.OrderStatus.InPlanned;

только незабываем добавить схему констант "OrderConfigurationConstants" в зависимости замещающей схемы.

При добавлении через Справочник "Состояние заказа" новой стадии Заказа (к примеру я добавил стадию 6. На доработку), как определить (назначить) константу?

Добрый день!!!

по образу и подобию схемы констант "OrderConfigurationConstants" можете создать свои константы. После создания подключаем в зависимости замещаемой схемы Заказа новые константы и работаем с ними.

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

Здравствуйте подскажите пожалуйста каким образом можно заблокировать все элементы на карточке редактирования активности (поля, определенные кнопки, детали) т.е. что-бы пользователь мог посмотреть но не мог вносить изменения. Сделать это нужно именно кодом.! какой метод за это отвечает, ? т.е наверное при загрузке страницы есть какая то коллекция элементов , которую можно заблокировать?

Нравится

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

Добрый день Андрей!!!

я предлагаю вам ничего не кодировать, а выполнить вашу задачу путем разграничения прав "по колонкам". Для выполнения данной задачи прошу ознакомиться с документацией по Администрированию и настройки прав. Ссылка на Академию террасофт: Раздел [Доступ к объектам] Прошу обратить внимание "Администрирование по колонкам", "Администрирование по записям". именно данный метод вам подойдет для решения вашей задачи. Будут вопросы пишите.

Михаил спасибо за ответ, но так наверное, решить задачу не получиться, т.к поля должны блокироваться и разблокироваться по условию :
(поля должны быть заблокированы если с момента даты завершения Активности прошло более 10 дней и соответственно поля должны быть доступны если прошло менее 10 дней )

Тогда вам Андрей требуется доработка и переработка всей карточки редактирования. Но здесь возникает вопрос и определенная сложность. А если Задача (Активность) участвует в бизнес-процессе, тогда как вы будете использовать данную карточку? Ведь тогда Бизнес-процесс просто будет зависший. Это один момент. Второй момент во время исполнения Бизнес-процесса на карточки редактирования могут появляться Генерируемые поля. С ними что вы будите делать. Я думаю вы слишком замудреную поставили задачу. Ее решить можно но нужно будет предусмотреть все. А это переписать и заместить придется не только карточку редактирования Активности. Может вы как-то упростите задачу. И тогда я вам подскажу как правильно ее решить.

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

Стикнувся з такою проблемою що деякі сторінки не можуть загрузити обєкт entitySchema(ContactSection, AccountSection, LookupPage)
Цей обєкт загружається раз через раз(тобто якщо відлагоджувати то можна побачити, що для прикладу схема ContactSection з define не приходить обєкт Contact = undefined і врезультаті код this.entitySchema = Contact(undefined)) і видається така помилка(рис.1) на всіх вказаних сторінках(деякі сторінки взагалі не загружають добре entitySchema)
А після рефрешу сторінки все загружається(рис.2)

Нравится

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

Здравствуйте, данное поведение не воспроизводится на других сайтах, и будет решено для Вашего сайта в рамках инцидента созданного Романом.

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

Добрый день коллеги!
Пытаюсь написать запрос на EntitySchemaQuery

select sum( d.projektsumm )
from dpzzayvki d ,BorrowerCo c
where
d.id=c.string
and c.borrowerId='6C693A17-6447-4205-9BE5-A98C17AD4FF8'
and c.borrowerstatusId='16C3B22A-BE4A-4436-B536-9750B7273FD2'

не получается условие where (использую фильтрацию )

var accid ='6C693A17-6447-4205-9BE5-A98C17AD4FF8';
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "DPZzayvki"});

esq.addAggregationSchemaColumn("projektsumm", Terrasoft.AggregationType.SUM,"projektsumm", Terrasoft.AggregationEvalType.ALL);

var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,"BorrowerCo:borrower", accid);
esq.filters.add("esqFirstFilter", esqFirstFilter);

esq.getEntityCollection (function(result)

подскажите где допустил неточность?
Спасибо!

Нравится

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

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

вот реализация вашего запроса на EntitySchemaQuery:

var borrowerId =  "6C693A17-6447-4205-9BE5-A98C17AD4FF8";
var borrowerstatusId =  "16C3B22A-BE4A-4436-B536-9750B7273FD2";
var select = this.Ext.create("Terrasoft.EntitySchemaQuery", {
     rootSchemaName: "dpzzayvki"
});
select.addAggregationSchemaColumn("projektsumm", this.Terrasoft.AggregationType.SUM, "SumProject");
var filterGroup = new this.Terrasoft.createFilterGroup();
filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;
filterGroup.add("BorrowerFilter", this.Terrasoft.createColumnFilterWithParameter(
     this.Terrasoft.ComparisonType.EQUAL, "[BorrowerCo:string:Id].borrower", borrowerId));
filterGroup.add("BorrowerStatusFilter", this.Terrasoft.createColumnFilterWithParameter(
     this.Terrasoft.ComparisonType.EQUAL, "[BorrowerCo:string:Id].borrowerstatus", borrowerstatusId));
select.filters = filterGroup;

так же рекомендую ознакомиться с документацией по разработки на платформе BPMOnline, размещенной на Академии террасофт: Документация по разработке bpm’online

"Власов Михаил Викторович" написал:

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

вот реализация вашего запроса на EntitySchemaQuery:

var borrowerId =  "6C693A17-6447-4205-9BE5-A98C17AD4FF8";

var borrowerstatusId =  "16C3B22A-BE4A-4436-B536-9750B7273FD2";

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

     rootSchemaName: "dpzzayvki"

});

select.addAggregationSchemaColumn("projektsumm", this.Terrasoft.AggregationType.SUM, "SumProject");

var filterGroup = new this.Terrasoft.createFilterGroup();

filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;

filterGroup.add("BorrowerFilter", this.Terrasoft.createColumnFilterWithParameter(

     this.Terrasoft.ComparisonType.EQUAL, "[BorrowerCo:string:Id].borrower", borrowerId));

filterGroup.add("BorrowerStatusFilter", this.Terrasoft.createColumnFilterWithParameter(

     this.Terrasoft.ComparisonType.EQUAL, "[BorrowerCo:string:Id].borrowerstatus", borrowerstatusId));

select.filters = filterGroup;

так же рекомендую ознакомиться с документацией по разработки на платформе BPMOnline, размещенной на Академии террасофт: Документация по разработке bpm’online


Михаил спасибо!
получилось

коллеги добрый день!

В SDK не могу найти примеры как в EntitySchemaQuery описать условие IN

select name
from table1
where id in (selec id2
from table2 where ... )

есть только метод createInFilter без подробностей,
буду благодарен за конкретные работающие примеры.

это пример не совсем то что мне нужно, мне нужен сравнение IN

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

выложите свой текст SQL запроса где применяется IN. я вам в ответ напишу запрос в EntitySchemaQuery, но и не забываем читать документацию по EntitySchemaQuery для обучения и саморазвития. вот ссылка: Использование EntitySchemaQuery для чтения данных из БД

Михали вот запрос

select sum (d.projektsumm)

from dpzzayvki d

where
d.accountId in ( select b.borrowerId
from dpzzayvki d ,BorrowerCo b
where d.id=b.STRING
and d.accountId='6C693A17-6447-4205-9BE5-A98C17AD4FF8')

спасибо

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

чтобы исполнить ваш запрос с помощью EntitySchemaQuery вам потребуется его разделить на две части. Первый запрос:

select b.borrowerId
from dpzzayvki d ,BorrowerCo b
where d.id=b.STRING
and d.accountId='6C693A17-6447-4205-9BE5-A98C17AD4FF8'

Данный запрос исполняете и сохраняете в коллекцию. И уже второй запрос который вам требуется выполнить это:

select sum (d.projektsumm)
from dpzzayvki d
where
d.accountId in (COLLECTION)

вот при таком подходе вы сможете исполнить свой запрос с помощью EntitySchemaQuery.

Добрый день Михаил!
В таком ключе и пытался действовать, вот

var select = Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "BorrowerCo"});

select.addColumn("borrower", "borrowerID");
var selectFirstFilter = select.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,"[DPZzayvki:Id:STRING].account",accid);
select.filters.add("selectFirstFilter", selectFirstFilter); Эта часть работает!!

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "DPZzayvki"
});
esq.addAggregationSchemaColumn("projektsumm", Terrasoft.AggregationType.SUM,"projektsumm", Terrasoft.AggregationEvalType.ALL);

var esqFirstFilter = esq.createInFilter("account", select);

// Добавление созданных фильтров в коллекцию запроса.
esq.filters.add("esqFirstFilter", esqFirstFilter);

но результат никакого нет((
думаю что не верно описываю условие IN
можете подсказать где именно ошибка ?
спасибо!

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

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

var select = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "BorrowerCo"});
 
select.addColumn("borrower", "borrowerID");
var selectFirstFilter = select.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
     "[DPZzayvki:Id:STRING].account",accid);
select.filters.add("selectFirstFilter", selectFirstFilter);
select.getEntityCollection(function(result) {
     var existsCollection = [];
     if (result.success) {
          result.collection.each(function(item) {
               var record = item.get("borrowerID");
               existsCollection.push(record.value);
          }, this);
     }
     // TODO: И вот здесь ниже пишем второй запрос. В который вставляем результат первого в виде коллекции
 
     var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "DPZzayvki"});
     esq.addAggregationSchemaColumn("projektsumm", Terrasoft.AggregationType.SUM, "projektsumm", Terrasoft.AggregationEvalType.ALL);
     var esqFirstFilter = this.Terrasoft.createColumnInFilterWithParameters("account", existsCollection);
     esq.filters.add("esqFirstFilter", esqFirstFilter);
 
     ....
 
    // TODO: И ниже уже исполняем свой основной запрос и получаем результат
}, this);

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

Михаил запрос отрабатывает,
но почему то если первый запрос возвращает результат, тогда во втором сумма считается правильно,
а если в результате первого запроса пусто (записей нет), тогда второй запрос считает сумму во всех записях по всей таблице.
Почему , ведь если запустить SQL запрос прямо в базе то отрабатывает правильно.
Это особенности EntitySchemaQuery и как можно исправить этот момент?

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

для того чтобы 2 запрос не выполнялся, при условии, что 1 запрос вернул NULL записей, вам требуется вставить условие проверки  if (existsCollection.length > 0) . Вот как получается в результате добавления условия.

var select = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "BorrowerCo"});
 
select.addColumn("borrower", "borrowerID");
var selectFirstFilter = select.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
     "[DPZzayvki:Id:STRING].account",accid);
select.filters.add("selectFirstFilter", selectFirstFilter);
select.getEntityCollection(function(result) {
     var existsCollection = [];
     if (result.success) {
          result.collection.each(function(item) {
               var record = item.get("borrowerID");
               existsCollection.push(record.value);
          }, this);
     }
     // TODO: И вот здесь ниже пишем второй запрос. В который вставляем результат первого в виде коллекции
 
     if (existsCollection.length > 0) {
          var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "DPZzayvki"});
          esq.addAggregationSchemaColumn("projektsumm", Terrasoft.AggregationType.SUM, "projektsumm", Terrasoft.AggregationEvalType.ALL);
          var esqFirstFilter = this.Terrasoft.createColumnInFilterWithParameters("account", existsCollection);
          esq.filters.add("esqFirstFilter", esqFirstFilter);
 
          ....
 
         // TODO: И ниже уже исполняем свой основной запрос и получаем результат
     }
}, this);

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

select 1
.....
union

select 2
.......
union

select 3
........
чем лучше воспользоваться EntitySchemaQuery,
классом SELECT или через хранимую процедуру (SQL сценарии )

на Ваш взгляд и практический опыт каким путем проще пойти?

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

Конструктором  new Select() лучше пользоваться если запрос Достаточно большой и его требуется обработать на серверной уже стороне, а клиенту вернуть результат в виде Массива данных или в единственном значение.

Вьюверами лучше пользоваться если создаете Отчет и запрос нетривиальный.

Все что вы описали выше я бы обработал бы уже на серверной стороне на Си шарпе, а клиенту бы вернул результат.

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

Евгений документацию, что нашел на Академии террасофт: Назначение EntitySchemaQuery. Отличие от Select, ссылка на SDK класса Select: Select - класс По Select классу где-то видел примеры на Академии, но сходу не смог найти. Можете Евгений примеры найти и в своей конфигурации, если включите настройку "Выгружать C# код при компиляции", и обычным "Far manager-om" выполнить поиск в файлах, где искомый текст указать "new Select". Как настроить выгрузку Исходного кода, можно прочесть здесь: Отладка серверного кода Если после прочитанного будут вопросы Евгений пишите. Если будет совсем сложно создать самому запрос, тогда прошу сначала прочесть, попробовать сделать самому, и если не получиться, вот тогда прошу выложить Текст SQL запроса, и я вам его помогу создать на C# с помощью класса "Select"

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

удалось справиться с написанием SQL запроса с помощью конструктора "SELECT"?

Добрый день Михаил!!
теоретически изучил ,к сожалению маловато примеров в SDK.
Написал простенький запрос,

Select selectQuery = new Select(UserConnection)
.Column("number")
.From("DPZzayvki");

using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection())
{
using (IDataReader reader = selectQuery.ExecuteReader(dbExecutor))
{
while (reader.Read())
{
this.showInformationDialog(number);
// Обработка результатов запроса.
}
}
}
когда сохраняю код ругается на
using (DBExecutor dbExecutor is not defined не совсем понятно какие дополнительные модули и ссылки подключать,
а также правильность использования результата запроса.

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

как вам и говорил предоставьте SQL запрос я вам его конвертирую в конструкцию SELECT на C#, чтобы вам легче было начинать изучение данного конструктора. Конструктор если разобраться очень мощный и с помощью него можно выполнять достаточно сложные и нетривиальные SQL запросы. это первое второе ваш пример попробуйте исполнить следующим образом:

namespace Terrasoft.Configuration {
   using System;
   using System.Data;
   using System.Collections.Generic;
   using System.ServiceModel;
   using System.ServiceModel.Web;
   using System.ServiceModel.Activation;
   using Terrasoft.Common;
   using System.Web;
   using Terrasoft.Core;
   using Terrasoft.Core.Entities;
   using Terrasoft.Core.DB;
   using System.Runtime.Serialization;
   using System.Linq;
   using Newtonsoft.Json;
   using Newtonsoft.Json.Linq;
 
   ....
 
   Select selectQuery = new Select(UserConnection)
   .Column("number")
   .From("DPZzayvki");
 
   using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection()) {
        using (var reader = selectQuery.ExecuteReader(dbExecutor)) {
             while (reader.Read()) {
                  this.showInformationDialog(number);
                  // Обработка результатов запроса.
             }
        }
   }
 
   ...
}

Михаил написал код который вы отправили, все равно выходит ошибка, вот как я у меня получилось

define('DPZzayvkiSection', ['GridUtilitiesV2', 'GeneralDetails', 'BusinessRuleModule', "GoogleIntegrationUtilities",
"RightUtilities", "ConfigurationConstants", "GoogleIntegrationUtilitiesV2", "DataUtilities"],
function(resources, GoogleUtilities,DataUtilities) {
return {
entitySchemaName: 'DPZzayvki',
contextHelpId: '1001',
diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
messages: {},
methods: { getSectionActions: function() {
var actionMenuItems = this.callParent(arguments);
actionMenuItems.addItem(this.getButtonMenuItem({
//Type: "Terrasoft.MenuSeparator",
Caption: "Проверить суммy на лимит 3",
Enabled: { "bindTo": "isAnySelected" },
Click: { bindTo: 'poisksumselect'},
}));

return actionMenuItems;
},

poisksumselect: function()
{
namespace Terrasoft.Configuration {
using System;
using System.Data;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Activation;
using Terrasoft.Common;
using System.Web;
using Terrasoft.Core;
using Terrasoft.Core.Entities;
using Terrasoft.Core.DB;
using System.Runtime.Serialization;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

Select selectQuery = new Select(UserConnection)
.Column("number")
.From("DPZzayvki");

using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection()) {
using (var reader = selectQuery.ExecuteReader(dbExecutor)) {
while (reader.Read()) {
this.showInformationDialog(number);
// Обработка результатов запроса.
}
}
}

namespace is not define и т д

JS != C# :smile:

Вы попытались в JS схеме написать код на c#, так нельзя. Если Вы пишите в JS то используйте клиентский esq.
https://academy.terrasoft.ru/documents/technic-sdk/7-7-0/ispolzovanie-r…

Стоп стоп стоп Евгений. Пример кода и конструктор SELECT работает только на C#. вы пишите данный запрос на C# в отдельном PUBLIC классе и обращаетесь к нему уже из Javascripta. хоть раз это делали?

к сожалению нет (
только начинаю писать на С и JS

Давайте так Евгений. Как я и писал выше, предоставьте в тестовике текст SQL запроса и какие входящие данные должны быть, какие данные получаем в результате выполнения запроса на выходе из Класса C#. Я подготовлю вам сервис на C#. И так же кусок кода на ява-скрипте как его вызвать. Далее вы сможете вставить его к себе в код.

Михаил нужно выполнить (запрос в файле) входящие параметры
var activeRow = this.get("ActiveRow");
var item = this.get("GridData").get(activeRow);
var activeRow = this.get("ActiveRow");
var item = this.get("GridData").get(activeRow);
var accid = item.get("account").value;
var borrowerId = item.get("account").value;
var borrowerstatusId = "16C3B22A-BE4A-4436-B536-9750B7273FD2";

на выходе получить набора данных Name , ProjektSumm
вторым этапом при помощи метода, отвечающий за экспорт в Excel, ( ExportToExcel.DataUtilities:)
выгрузить в Excel.
Делаю это все поэтапно чтобы на этих примерах получить практический опыт работы с системой.

Евгений если успею напишу ответ вам сегодня вечером, Если не успею то завтра утром. помогу вашему вопросу.

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

Подскажите пожалуйста, как правильно настроить администрирование. Создал новый раздел для вывода данных из новой таблицы. Все работает корректно. Но при создании динамической группы выбивает ошибку: Предупреждение
Выбранный элемент изменить невозможно, так как у Вас нет прав на изменение этого элемента.

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

Нравится

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

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

подскажите пожалуйста в схеме таблицы, что вы создали ранее, какие галочки установлены "Администрирование по операциям", "Администрирование по записям"? Так же рекомендую ознакомиться с документацией по администрированию, что находится на Академии Террасофт. Вот ссылки: Раздел [Доступ к объектам], Раздел [Доступ к операциям]

"Власов Михаил Викторович" написал: Здравствуйте Михаил. Установил галочку для "Администрирование по операциям" для всех пользователей. Галочка в "Администрирование по записям" тоже не принесла никаких результатов. Спасибо.

Так вам как требуется в вашей задачи? Администрировать по операциям или Администрировать по записям. Я вам не просто так дал ссылку на документацию. Чтобы вы прочитав поняли, для чего придумано понятие Администрирование по операциям, А для чего придумано понятие Администрирование по записям. И далее вы бы уже решили как правильно вам требуется. И уже от этого как написано в документации настроили бы свою таблицу. Прочтите документацию, вам сразу больше ясности появиться в голове.

"Власов Михаил Викторович" написал:

Так вам как требуется в вашей задачи? Администрировать по операциям или Администрировать по записям. Я вам не просто так дал ссылку на документацию. Чтобы вы прочитав поняли, для чего придумано понятие Администрирование по операциям, А для чего придумано понятие Администрирование по записям. И далее вы бы уже решили как правильно вам требуется. И уже от этого как написано в документации настроили бы свою таблицу. Прочтите документацию, вам сразу больше ясности появиться в голове.


Спасибо большое. Проблема была в валидации колонки в БД. А именно превысил лимит символов(>22)

"Ивченко Александр Сергеевич" написал:Спасибо большое. Проблема была в валидации колонки в БД. А именно превысил лимит символов(>22)

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

видимо я вас неправильно понял, и повел совсем в другом направлении. По "Валидации" могу сказать только одно, BPMOnline на уровне "Модели" сначала проводит Валидацию, проверяет правильность типов колонок. Проверке здесь подлежат все колонки, созданные в схеме Таблицы, созданные "как Виртукльные" на схемах страниц. Многие как я заметил не обращают внимание на Типы виртуальных колонок, что создают, а зря система Именно из-за Типов колонок иногда появляются ошибки в консоли. Так как при валидации еще раз повторюсь, сначало идет проверка на уровне Модели, а уже потом система поднимаемся выше на уровень Страниц. Так что прошу на это обратить внимание. Спасибо!!!

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

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

Есть две сущности: Arrears - задолженности, PromisesArrears - обещания.
Суть задачи в следующем: необходимо чтобы при добавлении нового обещания, когда открываем справочник задолженностей, чтобы отображались только те задолженности по которым еще не созданы обещания. Итак, на странице PromisesArrearsPage в свойство attributes добавляем

"Arrears": {
                dataValueType: Terrasoft.DataValueType.LOOKUP,
                dependencies: [
                                {
                                        columns: ["Arrears"],
                                        methodName: "arrearsFunction"
                                }
                        ],                             
                lookupListConfig: {
                                filters: [
                                        function() {
                                                var filterGroup = Ext.create("Terrasoft.FilterGroup");
                                                var notHaveOtherPromisesFilter = Terrasoft.createColumnIsNullFilter("[PromisesArrears:Arrears].Id");
                                                filterGroup.add("notHaveOtherPromisesFilter", notHaveOtherPromisesFilter);
                                                return filterGroup;
                                        }
                                ]
                        }
                },

Но в результате открывается пустой справочник. Пробовал также указывать явно левосторонний join ">[PromisesArrears:Arrears].Id", но это ничего не дало. К сожалению, не знаю как получить sql текст на JS, поэтому для получения текста запроса создал esq на c# с идентичным как мне представляется фильтром и join.
Код с#

var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Arrears");
        esq.AddColumn("[PromisesArrears:Arrears].Id");
       
        var esqFirstFilter = esq.CreateIsNullFilter("[PromisesArrears:Arrears].Id");
        esq.Filters.Add(esqFirstFilter);       
       
        resultSQLText = esq.GetSelectQuery(UserConnection).GetSqlText();

return true;

Полученный в результате запрос
SELECT
        [PromisesArrears].[Id] [PromisesArrears.Id]
FROM
        [dbo].[Arrears] [Arrears] WITH(NOLOCK)
        LEFT OUTER JOIN [dbo].[PromisesArrears] [PromisesArrears] WITH(NOLOCK) ON ([PromisesArrears].[ArrearsId] = [Arrears].[Id])
WHERE
        [PromisesArrears].[Id] IS NULL

^^И это именно тот запрос, что возвращает мне то что нужно (в части фильтрации и join).

Поэтому пара вопросов:
1) Что не так в lookupListConfig?
2) Как получить SQL текст на JS ?

Нравится

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

Добрый день Андрей!!!

вы сами в условии задачи описали открывать Справочник "Задолженности" по которым нет "Обещаний". Вижу у вас здесь неправильно составленный SQL запрос. Вот я как вижу правильный SQL запрос:

SELECT
        [PromisesArrears].[Id] [PromisesArrears.Id]
FROM
        [dbo].[Arrears] [Arrears] WITH(NOLOCK)
        LEFT OUTER JOIN [dbo].[PromisesArrears] [PromisesArrears] WITH(NOLOCK) ON ([PromisesArrears].[ArrearsId] = [Arrears].[Id])
WHERE
        [PromisesArrears].[ArrearsId] IS NULL

При вашем условии вы всегда получите пусто.

поэтому на Яваскрипте у вас должно быть написано следующее:

"Arrears": {
     dataValueType: Terrasoft.DataValueType.LOOKUP,
     dependencies: [
     {
          columns: ["Arrears"],
          methodName: "arrearsFunction"
     }],
     lookupListConfig: {
          filters: [function()
          {
               var filterGroup = Ext.create("Terrasoft.FilterGroup");
               var notHaveOtherPromisesFilter = Terrasoft.createColumnIsNullFilter("[PromisesArrears:Arrears].Arrears");
               filterGroup.add("notHaveOtherPromisesFilter", notHaveOtherPromisesFilter); 
               return filterGroup;
          }]
     }
},

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

Добрый день Андрей!!!

совсем заработался сегодня уже стал неправильный код выдавать :)

вот правильный запрос на ваши условия:

SELECT
        COUNT([Arrears].[Id]) as CountArrearsId
FROM
        [dbo].[Arrears] [Arrears] WITH(NOLOCK)
WHERE [Arrears].[Id] NOT IN (SELECT [PromisesArrears].[ArrearsId]
                                          FROM [dbo].[PromisesArrears] [PromisesArrears] WITH(NOLOCK))

Да и тот запрос, что в моем первом сообщении возвращает те задолженности, по которым нет обещаний, то есть соответствует моим условиям. Конечно его нужно подправить в части SELECT (на SELECT [Arrears].[Id] вместо SELECT [PromisesArrears].[Id]), но это ведь не имеет отношения к свойству lookupListConfig.filters, где не фигурируют выбираемые колонки, а только колонки, по которым идет фильтрация (то есть, те что попадают в запрос в частях Where и Join).

Но суть вопроса ведь даже не в самом запросе, а в том как его представить в JavaScript и чтобы работало.

Я в общем-то нашел решение, которое меня устроило в этой теме в конце http://www.community.terrasoft.ua/forum/topic/12500

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

filter: function() {
                        var Contact = this.get("Contact");
                        var filterGroup1 = this.Terrasoft.createFilterGroup();
                        filterGroup1.add("ContactFilter1",	Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 
"[PromisesArrears:Arrears].Contact", Contact.value));
 
                        var filterGroup2 = this.Terrasoft.createFilterGroup();
 
                        var notHaveOtherPromisesFilter = this.Terrasoft.createNotExistsFilter("Id", filterGroup1);
                        filterGroup2.addItem(notHaveOtherPromisesFilter);
 
                        filterGroup2.add("ContactFilter",
			Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Contact", Contact.value)); 
 
                        return filterGroup2;							
 } 

А вот как отобразить все задолженности (не привязываясь к конкретному контакту) по которым нет обещаний ?

И, кстати, для метода createNotExistsFilter в статье на академии представлен только вариант с одним параметром - columnPath, а не тот вариант, что использован в примере выше и о существовании которого оставалось только догадываться.

Добрый день Андрей!!!

вы в своем сообщение привели ссылку на статью Комьюнити где описывается как создать "createNotExistsFilter". Чем он вас не устраивает? Это такой же запрос, что я приводил выше, только переделанный на EXISTS. В чем у вас возникли сложности?

Да и вправду createNotExistsFilter возвращает требуемые задолженности. Код

filter: function() {
 
									var filterGroup1 = this.Terrasoft.createFilterGroup();
									filterGroup1.add("ArrearsInPromisesFilter1", Terrasoft.createNotExistsFilter("[PromisesArrears:Arrears].Id"));
 
 
									return filterGroup1;							
} 

Сейчас у вас Андрей получилось выполнить Фильтрацию по вашим условиям задачи? или еще остались вопросы?

Да, получилось то что нужно с последним кодом.

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

Прошу прощения, если такая тема уже была. По поиску не нашла.

Мне надо отключить фильтрацию по Account для поля Contact на странице ContractPageV2 - т.е. в Документах. Как это можно сделать?

Нравится

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

Здравствуйте,
Здесь рассматривалось несколько вариантов:
http://www.community.terrasoft.ru/forum/topic/13671
В том числе ссылка на этот ответ:
http://www.community.terrasoft.ru/forum/topic/12017#comment-52036

Так же ContractPageV2 это договоры, а не документы. Но суть приблизительно одинакова:

1. Необходимо что бы была замещающая страница ContractPageV2 в пакете Custom, для этого вы можете создать её сами, либо воспользоваться мастером разделов, и поменять что-нибудь на странице (добавить, переместить, и.т.д.), в результате будет создана замещающая страница в конфигураторе.
2. Посмотреть имя правила что вы хотите отключить, в базовых схемах ContractPageV2, к примеру для ContractPageV2 фильтрация контакта по контрагенту называется FiltrationContactByAccount и написана впервые в пакете CoreContracts.
3. В замещающей схеме в блоке rules перекрыть правило по имени:

define("ContractPageV2", ["ContractPageV2Resources", "GeneralDetails"],
function(resources, GeneralDetails) {
	return {
		entitySchemaName: "Contract",
		details: /**SCHEMA_DETAILS*/{
		}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[
		]/**SCHEMA_DIFF*/,
		attributes: {},
		methods: {},
		rules: {
			"Contact": {
				"FiltrationContactByAccount": {
					"ruleType": 999
				}
			}
		},
		userCode: {}
	};
});

4. Почистить кеш браузера, перезайти на сайт.

Спасибо! Работает!

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

Здравствуйте, коллеги!

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

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

Прошу помочь с реализацией следующей функции.

Имеется веб-сервис, имеющий корректное wsdl-определение. Сервис получает от процесса GET-команду (с параметром type ['jpeg', 'pdf', 'xml']) и в зависимости от параметра возвращает:
1) jpeg - изображение
2) pdf - файл документа
2) xml - со значениями полей в строках и изображениями в кодировке base64

по получении ответа процесс должен:
1) сохранить jpeg-файл в карточку контакта (например, фото контакта)
2) сохранить pdf-файл вложением в карточку контакта (например, цифровая копия подписанного договора обслуживания)
3) разобрать полученный xml-файл, создать новую карточку контакта и сохранить значения в соответствующие поля, включая закодированное base64 изображение (например, паспортные данные контакта с изображением подписи, фото и скана паспорта)

Буду благодарен за примеры кода.

Нравится

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

Добрый день!
Пока такого элемента, который бы вызывал внешние сервисы нет.
Для решения подобной задачи нужно писать в ScriptTask’е на .Net обработчик http запросов и в пространство имен (Usings) подключать нужные классы.
Примеры кода можно загуглить.

Спасибо, Олег!

Я посмотрел в дизайнере процессов установленного у нас экземпляра bpm'online 7.8. Там действительно нет того элемента, что я имел ввиду. Жаль, что я не помню его названия. Но в бета-версии, которую нам демонстрировали на мероприятии в Сколково в этом году в рамках сессии для администраторов, был такой элемент, который позволял вызывать внешние web-сервисы, при условии, что они оформлены в соответствии со стандартами по протоколу SOAP.

Очень прошу перепроверить с теми, кто делал ту презентацию. Юлия Старун там была, насколько я помню.

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

Добрый день !!!

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

Здравствуйте! Я зашел в дизайнер процессов из конфигурации системы. Элемент, который я имел ввиду называется "Выполнить действие процесса". В его настройках нужно указать Пользовательское действие "Вызвать веб-сервис" или "Вызвать Web-сервис".

Если выбрать первый вариант - "Вызвать веб-сервис", то во вкладке Параметров нужно указать следующие параметры:
- RequestBodyInternal
- RequestParameters
- URL сервиса
- Вернуть запрос и ответ действия
- Запрос
- Метод сервиса
- Ответ
- Параметры запроса
- Результат запроса
- Сервис
- Статус выполнения вызова

Если выбрать второй вариант - "Вызвать Web-сервис", то во вкладке Параметров нужно указать следующие параметры:
- URL web-сервиса
- Метод
- Название
- Параметры метода

Мой SOAP сервис вызывается (из локальной сети) по адресу:
http://[ip_address]/soap?format=pdf
http://[ip_address]/soap?format=jpg
http://[ip_address]/soap?format=xml

Его описание доступно по
http://[ip_address]/soap?wsdl

Текст WSDL во вложении (нужно изменить расширение с txt на xml).

Пример XML-ответа - во вложении (нужно изменить расширение с txt на xml).
Пример PDF-ответа - во вложении.
Пример JPG-ответа - во вложении.

Это была вводная. Сама задача была описана в исходном сообщении темы. Подозреваю, что мне нужно использовать первый вариант ("Вызвать веб-сервис") - у него вроде больше настраиваемых параметров. Теперь вопрос знатокам (или "подсказка зала" - уж как повезет :) :

Кто подскажет, как использовать этот элемент? Если можно - с практическими примерами.

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

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

Добрый день!

Предусмотрена ли адаптивная верстка писем в редакторе?

Шаблоны, сверстанные средствами MailChimp, адаптированы и для моб.устройств.

Тест писем со стандартными шаблонами в bpm показал, что не все так гладко.

Подскажите, пожалуйста, как сделать письмо адаптивным? Через css? И если только так, то где конкретно это прописывается?

Нравится

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

Добрый день!

Для писем, сверстанных через базовый дизайнер контента, адаптивная верстка не предусмотрена в текущей версии продукта. Для того, чтобы шаблон письма был адаптивным, рекомендуется использовать html-блок дизайнера контента, в котором Вы можете самостоятельно прописать стили inline(в том числе и адаптивность).

Однако, Ваш запрос будет отправлен команде разработки и будет рассмотрен при планировании следующих версий продукта.

Анастасия, спасибо!

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

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

При создании поля, не был добавлен пункт "Отслеживать изменения". Поле заполнялось, а когда понадобилось отслеживать изменения не удается добавить в datagrid данное поле. В таблице (tbl_TestLog) данное поле есть и изменения записываются, но в datagrid не отображаются. Подскажите что делать?

Проделывал все несколько раз и из клиента и из ts admin, снимал и устанавливал признак "Отслеживать изменения". Так же из таблицы tbl_TestLog удалял данное поля и проделывал вышеперечисленные действия, но результат нулевой.

Версия продукта 3.3.2

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

Нравится

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

Здравствуйте, Евгений!

1. Уточните, пожалуйста, где Вы смотрите, что не был добавлен пункт [Отслеживать изменения]?
2. Каким образом Вы создавали поле?
3. Полное название Вашей версии (после 3.3.2 ещё есть цифры).
4. Продемонстрируйте проблему с помощью скриншотов.

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

в разделе "Журнал изменений БД" есть действие (Вызывается из меню "Действия") - "Настройка журнала изменений БД". Нажав на данное действие открывается окно:

Нажав в данном окне "Добавить" и выбрав требуемую таблицу. Появляется окно:

В появившемся окне "Добавление таблицы" - отмечаем галочками по каким полям "Отслеживать изменения", а какие поля "Отображать в реестре". Вот как раз галочка "Отображать в реестре" и говорит о том, что вы увидите данное поле в Гриде "Журнал изменений БД". Так как можно вести отслеживание изменения по 10 полям, а видеть я хочу для анализа только 5 полей в реестре.

Версия 3.3.2.311.

Поле добавлял с помощью Terrasoft Administrator, а после заполнения поля данными, поставил пункт "Отслеживать изменения" в Terrasoft Administrator.

Пункта "Отображать в реестре"(скриншот 2) нету.

Стоит только переименовать поле, в Журнале изменений сразу же появляется.

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

к сожалению скриншота нет, чтобы понять о чем идет речь.
Рекомендую ознакомиться с документацией по настройке логирования изменений, смт. на странице 147, глава [Логирование изменений].

Первые три скриншота это пример того как не отображается.

Последние три скриншота, это после изменения названия поля в таблице контактов.

Для устранения этой проблемы необходимо в функции BuildChangesLogWindow сервиса scr_DatabaseLogUtils заменить код

			if ((TableField.SQLName.search(/ID$/ig) > -1) &&
				(TableField.SQLDataType != sdtEnum)) {	// Enums accepted
				continue;
			}

на

			if (((TableField.SQLDataType == sdtGUID) ||
				(TableField.SQLDataType == sdtIdentity)) &&
				(TableField.SQLDataType != sdtEnum)) {  // Enums accepted
				continue;
			}

Павел, спасибо огромное, вы меня спасли

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