По умолчанию система подгружает 15 записей в реестр.

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

this.methods.sayHello = function(){            
    this.pageRowsCount = 1000000;
    this.load(this.get('currentTabName'), 'QuickFilterChanged');
};
this.actions = [
{
    caption: 'getJSON_response',
    methodName: 'sayHello'
}
];

А вот пример того, как работать с коллекцией подгруженных данных (переопределяется базовая функция modifyItems (из SectionViewModelGenerator), в качестве параметра a - приходят нужные нам данные):

var actionStarted = false;
this.methods.modifyItems = function(a) {
    if(actionStarted) {
        alert(a.collection.items.length);
        //тут выполняете нужные вам действия с a.collection.items
    }
}
this.methods.sayHello = function(){
    actionStarted = true;
    this.pageRowsCount = 100;
    this.load(this.get('currentTabName'), 'QuickFilterChanged');
};
this.actions = [
{
    caption: 'getJSON_response',
    methodName: 'sayHello'
}
];

 

Нравится

Поделиться

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

Добрый день.

при работе с EntitySchemaQuery для реализации SQL конструкции CASE, WHEN, THEN, компания Террасофт реализовала класс EntitySchemaCaseNotNullQueryFunctionWhenItem . Прошу пожалуйста поделиться Примерами использования данного класса. Так называемыми Темплейтами. На Академии я данный примеров не нашел. Спасибо.

Нравится

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

Добрый день, Михаил!

С описанием класса можете ознакомится тут: https://academy.terrasoft.ru/api/SDKNETAPI/7.10.0/NetCoreAPI_Help.html#Terrasoft.Core~Terrasoft.Core.Entities.EntitySchemaCaseNotNullQueryFunctionWhenItem.html

Пример использования: 

 

Tsopa,

Спасибо огромное за предоставленный ответ. Только если бы вы внимательно читали мой вопрос, то вы бы увидели, что я прошу ссылку не на описание Класса. А привести пример использования данного класса. Реальный Пример из жизни. Так как я нашел описание Класса на Академии, но не нашел примеры его использования, вот и обратился на community. Спасибо.

Михаил, 

Существуют sql запросы вида: 

CASE WHEN (ID IS NULL) 
     THEN 'YES' 
     ELSE 'NO' 
END AS ID_Value,

Для реализации такого рода запросов используется класс EntitySchemaCaseNotNullQueryFunctionWhenItem.

Конкретных примеров использования в системе нет. Вы можете попробовать реализовать свой собственный пример.

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

Вопрос

Как установить сортировку (порядок отображения) нескольких страниц редактирования в выпадающем списке раздела

Ответ

define("AccountSectionV2", [], function() {
    return {
        entitySchemaName: "Account",
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        methods: {
            initEditPages: function() {
                this.callParent(arguments);
                var editPages = this.get("EditPages");
                editPages.sortByFn(this.editPagesSortFunction);
            },
            editPagesSortFunction: function(elA, elB) {
                var valueA = elA.values.SchemaName;
                var valueB = elB.values.SchemaName;
                var sortRule = function(schemaName) {
                    //the direction will be 1-2-3...
                    if (schemaName === "UsrAccount1Page") {//Partner (in my case)
                        return 3;
                    }
                    if (schemaName === "UsrAccount2Page") {//Our company
                        return 1;
                    }
                    if (schemaName === "UsrAccount3Page") {//Customer
                        return 2;
                    }
                    return 0;
                };
                return sortRule(valueA) > sortRule(valueB);
            }
        },
        diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
    };
});

 

Нравится

Поделиться

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

Скрипт:

DECLARE @TableName NVARCHAR(250)
SET @TableName = 'Activity' -- ЗДЕСЬ ВПИСЫВАЕТСЯ НАЗВАНИЕ ТАБЛИЦЫ
PRINT 'Start process ' + @TableName
EXEC ('
DELETE FROM Sys' + @TableName + 'Right;
DECLARE @TableSchemaUId UNIQUEIDENTIFIER;
SELECT top 1 @TableSchemaUId = UId FROM SysSchema WHERE [Name] = ''' + @TableName + '''
                                                        and [ExtendParent] = ''0''
/* Полный доступ автору записи */
INSERT INTO Sys' + @TableName + 'Right (CreatedOn, ModifiedOn, RecordId,
    SysAdminUnitId, Operation, RightLevel, Position, SourceId)
SELECT GETUTCDATE(), GETUTCDATE(), o.Id, au.Id, op.Id, 2, 0, ''{4220CFBA-0514-44CE-ADD0-109B54B52084}'' -- Источник: Автор
FROM ' + @TableName + ' o
JOIN SysAdminUnit au ON (au.ContactId = o.CreatedById)
CROSS JOIN (SELECT 0 Id UNION ALL SELECT 1 UNION ALL SELECT 2) op -- Операции: Чтение, Изменение, Удаление
WHERE NOT EXISTS(SELECT * FROM Sys' + @TableName + 'Right WHERE RecordId = o.Id AND
    SysAdminUnitId = au.Id AND Operation = op.Id);
/* Копирование прав по умолчанию */
INSERT INTO Sys' + @TableName + 'Right (CreatedOn, ModifiedOn, RecordId,
    SysAdminUnitId, Operation, RightLevel, Position, SourceId)
SELECT DISTINCT GETUTCDATE(), GETUTCDATE(), o.Id, dr.GranteeSysAdminUnitId,
    dr.Operation, dr.RightLevel, 0, ''{F41E0268-E324-4228-9E9E-5CB7CC906398}'' -- Источник: По умолчанию
FROM ' + @TableName + ' o
JOIN SysAdminUnit au ON (au.ContactId = o.CreatedById)
LEFT JOIN SysUserInRole uir ON (uir.SysUserId = au.Id)
JOIN SysEntitySchemaRecordDefRight dr ON (dr.AuthorSysAdminUnitId = uir.SysRoleId OR dr.AuthorSysAdminUnitId = au.Id OR
dr.AuthorSysAdminUnitId IN (SELECT Id FROM SysAdminUnit WHERE ParentRoleId IS NULL))
WHERE dr.SubjectSchemaUId = @TableSchemaUId AND
    NOT EXISTS(SELECT * FROM Sys' + @TableName + 'Right WHERE RecordId = o.Id AND
        SysAdminUnitId = dr.GranteeSysAdminUnitId AND Operation = dr.Operation);
')
PRINT @TableName + ' was processed'

 

Нравится

Поделиться

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

Добрый день. Спасибо. Отличный скрипт. Думаю, стоит приложить файлом, Т.к. при копировании почти все попадает в одну строку.

Я немного модифицировал скрипт.

Таким образом можно одним скриптом пробегаться по всем нужным объектам (список задается во второй строке скрипта).

DECLARE @myTableVariable TABLE (name varchar(250))
insert into @myTableVariable values('Account'),('Contact') --объекты для обновления прав добавлять сюда в аналогичном формате.
 
DECLARE @TableName VARCHAR(250)
DECLARE db_cursor CURSOR FOR SELECT name from @myTableVariable
OPEN db_cursor
 
FETCH NEXT FROM db_cursor INTO @TableName  
WHILE @@FETCH_STATUS = 0 
BEGIN 
PRINT 'Start process ' + @TableName
EXEC 
('
DELETE FROM Sys' + @TableName + 'Right;
DECLARE @TableSchemaUId UNIQUEIDENTIFIER;
SELECT @TableSchemaUId = UId FROM SysSchema WHERE [Name] = ''' + @TableName + '''
/* Полный доступ автору записи */
INSERT INTO Sys' + @TableName + 'Right (CreatedOn, ModifiedOn, RecordId,
    SysAdminUnitId, Operation, RightLevel, Position, SourceId)
SELECT GETUTCDATE(), GETUTCDATE(), o.Id, au.Id, op.Id, 2, 0, ''{4220CFBA-0514-44CE-ADD0-109B54B52084}'' -- Источник: Автор
FROM ' + @TableName + ' o
JOIN SysAdminUnit au ON (au.ContactId = o.CreatedById)
CROSS JOIN (SELECT 0 Id UNION ALL SELECT 1 UNION ALL SELECT 2) op -- Операции: Чтение, Изменение, Удаление
WHERE NOT EXISTS(SELECT * FROM Sys' + @TableName + 'Right WHERE RecordId = o.Id AND
    SysAdminUnitId = au.Id AND Operation = op.Id);
/* Копирование прав по умолчанию */
INSERT INTO Sys'+@TableName+'Right (CreatedOn, ModifiedOn, RecordId,
    SysAdminUnitId, Operation, RightLevel, Position, SourceId)
SELECT DISTINCT GETUTCDATE(), GETUTCDATE(), o.Id, dr.GranteeSysAdminUnitId,
    dr.Operation, dr.RightLevel, 0, ''{F41E0268-E324-4228-9E9E-5CB7CC906398}'' -- Источник: По умолчанию
FROM '+@TableName+' o
JOIN SysAdminUnit au ON (au.ContactId = o.CreatedById)
LEFT JOIN SysUserInRole uir ON (uir.SysUserId = au.Id)
JOIN SysEntitySchemaRecordDefRight dr ON (dr.AuthorSysAdminUnitId = uir.SysRoleId OR dr.AuthorSysAdminUnitId = au.Id OR
dr.AuthorSysAdminUnitId IN (SELECT Id FROM SysAdminUnit WHERE ParentRoleId IS NULL))
WHERE
	exists (
		select 1 from SysSchema where Name='''+@TableName+'''
		and dr.SubjectSchemaUId=UId
	)  AND
    NOT EXISTS(SELECT * FROM Sys'+@TableName+'Right WHERE RecordId = o.Id AND
        SysAdminUnitId = dr.GranteeSysAdminUnitId AND Operation = dr.Operation);
')
PRINT @TableName + ' was processed'
FETCH NEXT FROM db_cursor INTO @TableName 
 
END
CLOSE db_cursor  
DEALLOCATE db_cursor 

 

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

Задача

Реализовать подсчет времени активности в часах

Решение

1)      В замещающем объекте Активности, создаем новую числовую колонку (DurationInHours)

2)      В процессе объекта, в структуре CalculateDurationOnSaving

override void CalculateDurationOnSaving()

пишем:

base.CalculateDurationOnSaving();
Entity.DurationInHours = decimal.Round(decimal.Divide((int)Entity.DurationInMinutes, 60), 2);

3)      Сохраняем, публикуем.

Нравится

Поделиться

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

Добрый день.

Возможно ли реализовать механизм Webhooks на основании web-сервисов BPMonline?

Имеется в виду отправка запросов из сторонних сервисов на определённый url Bpmonline .

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

А внешний сервис со своей стороны может принять только один url для отправки запроса.

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

Нравится

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

Добрый день. В продукте Marketing был реализован функционал WebHooks для получения откликов, открытий от Mandrill.

Чубко Илья, добрый день

Если я не ошибаюсь, то описанный вами механизм работает в обратном порядке, т.е. в BPMonline вызываются Webhooks стороннего сервиса.

У меня же задача кардинально противоположная: вызывать webhooks bpmonline из стороннего сервиса.

 

вижу несколько способов:

1) Как вы  и написали в посте: сторонний сервис авторизуется и потом посылает данные в bpm. В данном случае надо всего лишь написать веб-сервис.

2) Веб-сервис без авторизации. Т.е всё то же самое, что и в 1 пункте, только надо перекопать web.config bpm и добавить в сервисы пару файлов. Ну и в итоге получается тот же веб-сервис, только к нему не надо авторизовываться.

3) web-to-object. Я так понял можно зарегистрировать внешнюю систему и создавать простые объекты(не полноценный сервис, но может кому-то нужен только функционал создания новых записей).

Коновалов Игорь,

Нет же, сервер Mandrill отправляет webhooks на систему. Зачем системе отправлять себе же и тем более как узнать статус webhooks, в отличии от Mandrill

Добрый день. Приведу пример настройки веб-сервиса без авторизации на примере настройки для нашего конвектора с Jivosite. https://drive.google.com/file/d/0B9WlZhrEuJlkaGlkZ194c3Utbmc/view?usp=s…

Посмотрите здесь. Данная инструкция открывает доступ без авторизации к созданному вами сервису (естественно его нужно сначала создать). В самом сервисе вы реализуете вызываемую логику и шлете данные с внешнего источника обычным post запросом.

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

https://academy.terrasoft.ua/documents/technic-sdk/7-16/kak-zapuskat-pr…

А в БП уже реализуете нужную логику. 

Как обработать данные только с определленного URL?

OLeg1020, добрый день!

 

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

Показать все комментарии
Идея
Одобрена

 

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

Идея заключается в следующем: можно добавлять в запрос Id SysAdminUnit'а (и любую другую полезную информацию) как комментарий.Это упростит поиск некоторых проблем, а реализация этой функции не требует серьезных доработок и никак не повлияет на выполнение самих запросов.

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

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

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

Спасибо большое)

Добрый день!

Спасибо, идея принимается. Планируем сделать в ближайших релизах.

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

Процесс работы с email-рассылкой от создания до отправки, а затем анализа результатов представляем в новом видеоуроке "Отправка email-рассылок из bpm'online"!

Видео доступно по ссылке.

Больше видеоуроков смотрите на сайте Академии Террасофт

Нравится

Поделиться

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

Добрый день.

Есть задача: настройка Landing Form в Wordpress с последующей передачей в BPM Online 7.10.

На Contact Form 7 все работает прекрасно при настройке по инструкции.

При использовании страницы с Gravity Forms есть вопросы:
- как "дописать логику в Submit". Пробовал через jQuery(document).bind('gform_confirmation_loaded', function(event, formId), а также пробовал gform_after_submission. В первом случае вроде норм, во втором случае "проскакивает"
- в любом случае есть проблемы с InitLanding. Такое впечатление, что селекторы не находят значения. Хотя сами селекторы указаны верно.

В нашем случае нужно настроить именно с помощью Gravity Forms.

Дмитрий.

Нравится

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

Добрый день!

Может кто сталкивался с подобной задачей.

1) на нажатие кнопки необходимо открыть окно выбора контактов и/или контрагентов
2) выбрать несколько контактов и несколько контрагентов
3) обработать выбранные записи.

пункты 1 и 2 я сделала. с пунктом 3 проблема.
допустим, я выбираю двух контрагентов и трех контактов.
Справа указано "Выбрано записей:5". все корректно.
нажимаю Выбрать и вызывается callback функция. проблема в том, что в аргументах мне приходят только те объекты, находясь на странице которых я нажала кнопку выбрать.
Например,
если я нажала, когда была на вкладке контрагентов, то в args.selectedRows.getItems() 2 контрагента если нажала, когда была на странице контактов - то в аргументах вернуться 3 контакта.

вопрос: как я могу получить все 5 выбранных записей?


Нравится

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

"Zaitova Liubov" написал:вопрос: как я могу получить все 5 выбранных записей?

Как и всегда - ломая стандартную логику:smile:
Вся проблема в LookupPageViewModelGenerator и методе selectButton. Он забирает 3 выбранные записи из грида текущей вкладки, в result складирует выбранные, в переменную notLoadedItems кладёт Id-шники тех 2-х, которые в соседней вкладке и дальше, тут феерия, делает esq запрос на выборку тех незагруженных элементов в entitySchema текущей вкладки.

Я вызывал мультивыбор так:

onButtonClick: function() {
	var config = {
		lookupPageName: "MultiLookupModule",
		multiLookupConfig: [{
			entitySchemaName:"Contact",
			multiLookupColumnName: "Contact",
			multiSelect: true
		}, {
			entitySchemaName:"Account",
			multiLookupColumnName: "Account",
			multiSelect: true
		}]
	};
	this.openLookup(config, this.onMyLookupResult, this);
},

Соответственно фиксил бы в таком порядке:
1) Сделал свой модуль MultiLookupExtendedModule, наследуется от "Terrasoft.MultiLookupModule"
2) Заместил бы копипастой функцию selectButton, в нужном месте надо сравнить значение активной вкладки (this.get("ActiveLookupTabName")) и вообще всей коллекции вкладок (this.get("LookupTabsCollection")). Исключаем активную, в values неактивной валяется нужная entitySchema, ну и делать запрос в нужную схему.
3) По кнопке вызывал бы свой модуль.

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