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

Нравится

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

В своём пакете заместить объект активности и во встроенном БП заменить две функции с этой логикой пустыми:

#region Methods: Public
 
//Не записывать в деталь Участников
public override void UpdateParticipantsByOwnerContact() {}
public override void CreateActivityParticipantsFromInsertedValues() {}
 
#endregion

 

Спасибо, попробую ваш вариант

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

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

// Добавить фильтр по типу Обращения
initFixedFiltersConfig: function() {
	this.callParent();
	var defvalue = [
		{value: "13fa5292-c957-4452-8bea-97e5cd381ed0",displayValue: "IT"}, 
		{value: "51c2810b-2c34-4046-a4bf-2cca62b3e10a",displayValue: "Maintenance"}
	];
	var ffc = this.get("FixedFilterConfig"); // Прошлые фильтры
	var fixedFilterConfig = {
		name: "KORUSLOOKUPCaseType",
		columnName: "KORUSLOOKUPCaseType",
		caption: "Тип",
		isCustomFilter: true,
		dataValueType: this.Terrasoft.DataValueType.LOOKUP,
		appendCurrentContactMenuItem: false,
        addNewFilterCaption: this.get("Resources.Strings.SelectFilterTypeCaption"), // Выбрать тип
        hint: this.get("Resources.Strings.SelectFilterTypeCaption"), // Выберите тип обращения
		buttonImageConfig: this.get("Resources.Images.SelectFilterTypeImage"),
		defValue: defvalue,
		//appendFilter: this.appendFixedCaseTypeFilter, - добавление фильтра ( не меняет визуал)
		//getFilter: this.appendFixedCaseTypeFilter
	};
	if (ffc != undefined) {
		ffc.filters.push(fixedFilterConfig);
		this.set("FixedFilterConfig", ffc);
	}
},

Фильтр работает как надо, но после последовала просьба очищать фильтр при выборе нового значения , по сути при нажатии на кнопку "Выбрать тип", необходимо реализовать сначала логику кнопки "Очистить"

При этом нельзя затрагивать логику прошлых фильтров. Так же не хотелось бы решать эту задачу методом добавления поля типа Lookup в шапку фильтров

Нравится

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

Добрый день,

 

Реализовать эту функциональность будет крайне сложно, если возможно впринципе, потому что замещения FixedFilterViewModelV2 с моей стороны ничего не дали. Необходимо завязываться на метод lookupSelecting в FixedFilterViewModelV2, потому что колбек функция в ней как раз отвечает за обновление фильтра. В контексте выполнения функции можно сохранить текущий фильтр (вычитать this.$Filters и проверить есть ли там что-то сейчас и если есть, то очищать этот фильтр). Когда в открытом попап окне выбирается новое условие, то колбек вызывает метод addNonPeriodFilterValue, который добавляет к существующей фильтрации ту, которую мы выбираем из попап окна, внутри которого срабатывает метод filterChanged, который обновляет фильтр на UI. То есть, отталкиваться нужно было бы от метода lookupSelecting, но, похоже, это придется полностью переписывать логику View модели и переподключать её к схеме раздела.

Спасибо за ваш ответ, попробую реализовать его или какие-то обходные решения

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

Я столкнулся с проблемой, что подпроцесс, который я вызываю из основного бизнес процесса не запускает вообще никаких элементов.
Дело было так: У меня есть основной процесс, который вызывает веб сервис и обрабатывает ответ. Я настроил метод для веб сервиса. Настроил обработку ответа с помощью инструмента "Быстрая настройка" и передаю параметры, которые получил от веб сервиса подпроцессу.

Изначально всё работало как часы. Подпроцесс запускался и обрабатывал параметры.
Далее мне потребовалось добавить ещё один  параметр в "Обработку ответа" для метода веб сервиса. Изначально я руками создал параметр и настроил его. Пусть к элементу (JSONpath) я указал верный!
Далее я перешёл в основной процесс и увидел, что только что добавленный параметр я не могу выбрать, потому что блок веб сервиса его попросту не имеет. Я пошёл обратно к веб сервису, удалил параметр и создал его уже с помощью инструмента "Быстрая настройка". Перешёл в бп и наконец-то увидел нужный мне параметр.
Далее я поставил этот параметр в подпроцесс и тут всё сломалось.
После сохранения и запуска подпроцесс запускается, ему ставиться состояние "Выполняется", но даже первый элемент процесса не запускается. В журнале процессов у него нет данных об элементов процесса, чего не может быть впринцыпе.
Я подумал что всё дело в "Задании-сценари" в моём подпроцессе. Я удалил его и сохранил. По непонятной мне причине подпроцесс начал работать.
Но возникла другая проблема с вызовом веб сервиса.

Мой веб сервис обращается к телеграм api с помощью метода "getUpdates", параметры ответа которого я обрабатываю в моём веб сервисе.
Если раньше ответ от нажатия на inline нопки в телеграмме я получал и всё работало прекрасно, то теперь, возникала ошибка:

Terrasoft.Common.UnsupportedTypeException: Тип "System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" не поддерживается

С этого момента я попробовал поменять работу с передаваемыми параметрами, но ничего не помогло. После я заново переопределил параметры ответа для параметра в веб сервисе, но после этого подпроцесс вновь перестал запускаться. Я пробовал с 0 создавать мои 2 процесса, но это не помогло. Что делать в такой ситуаци?

Нравится

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

Добрый день.

Данная ошибка может быть связана с некорректной обработкой массива параметров в ответе (Result) веб сервиса.
Попробуйте убрать масив параметров из ответа  веб сервиса.

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

Добрый день!

Есть задача: привязать условие определения родительского инцидента/обращения не к цепочке в хэдере, а к значению в теме письма. Не могу разобраться в том, в какой момент срабатывает логика, заполняющая CaseId у активности типа email (или соответственно ConversationId в EmailMessageData, т.к. насколько я вижу это связанные факторы и в дальнейшем именно на ConversationId построено разграничение связанных и не связанных email).
Где она запускается и можно ли как-то написать класс-расширение который переопределил бы эти методы?
Заранее спасибо!

Нравится

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

Добрый день,

 

Логика проверки активности на привязку к существующему обращению или создания нового обращения находится в бизнес процессе "IncidentRegistrationFromEmailProcess" (который запускается после каждой завершенной сессии синхронизации писем в системе). В элементе скрипт-таск процесса вызывается метод RegisterIncidentFromEmail, который в конце выполнения делает вызов:

 

result = helper.GetRegisterIncidentId(activityId);

 

helper - это класс IncidentRegistrationFromEmaillHelper.

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

 

Поэтому, если нужно изменить логику, нужно смотреть в сторону замещения метода GetRegisterIncidentId внутри IncidentRegistrationFromEmaillHelper и прописывать свою кастомную логику там.

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

Есть Си Шарповый код, который вызывает процессы через UserConnection.ProcessEngine.ProcessExecutor.Execute(), появилась необходимость не просто вызывать эти процессы, но и получать из них результат. Для этого, я так понял, нужно пользоваться методом ExecuteProcessWithResult(). Но где можно найти пример использования этого метода ? В идеале, и бизнес-процесс, и код, который вызывает этот БП, если такое есть.

Так же волнует то, что есть небходимость всегда получать какой-то ответ из процесса, будь то результат его действий или ошибка при их выполнении. Но, скажем, есть процесс из 10 элементов, в последнем мы возвращаем результат в этот метод вызова БП. Но если процесс сломается на каком-то из предидущих 9и элементов, то и результат мы никогда не получим, верно ? Что можно сделать, чтобы в такой ситуации всегда получать назад ответ(с результатом действий БП или с ошибкой при их выполнении) ?

Нравится

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

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

 

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

 

Насчет вопроса с ошибкой в бизнес-процессе, можете попробовать разобраться, как реализована логика работы раздела [Process log].

 

Ещё рекомендую посмотреть свойства и методы интерфейса ProcessEngine.

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

Использую EntitySchemaQuery, чтобы сделать селект данных, появилась необходимость одно из полей сравнить через регулярные выражения, но среди возможностей FilterComparisonType такого не вижу. Есть способ как-то обойти это ? Или остаётся только чистые SQL запросы писать, не используя EntitySchemaQuery ?

Нравится

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

Подскажите, в Вашей реализации можно записать результат ESQ в аттрибут, например, массивом, а потом пройтись по массиву из аттрибута и сделать нужную проверку?

Oleg Drobina,
Думаю, можно, но хотелось бы убедиться, что нельзя как-то сразу получить нужный результат ESQ, чтобы не было необходиомсти потом его сортировать допольнительно.

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

Есть БП, который создаёт объекты через

new Insert(userConnection).Into("UsrCards")

Нужно сразу после создания давать права на этот объект людям, у которых есть конкретная роль. Давать права через элемент БП Change access rights в нашем случае неудобно, поэтому надо через код. Пока вроде понял, что нужен UserConnection.DBSecurityEngine, но вот не пойму, где найти нужный мне метод для него.

Нравится

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

Пример раздачи прав через DBSecurityEngine есть в методе CheckTagTypeAndGrantAdditionalRights в процесе на объекте CampaignTag. Там пример такой:

 

UserConnection.DBSecurityEngine.SetEntitySchemaRecordRightLevel(TSConfiguration.BaseConsts.PortalUsersSysAdminUnitUId, 
                        Entity.Schema, Entity.PrimaryColumnValue, SchemaRecordRightLevels.All); 

 

то есть в метод аргументами передаются:

TSConfiguration.BaseConsts.PortalUsersSysAdminUnitUId - Id пользователя или роли;

Entity.Schema - название объекта;

Entity.PrimaryColumnValue - Id записи из этого объекта;

SchemaRecordRightLevels.All - уровень прав доступа.

 

Еще пример - процесс на объекте Activity из пакета Base (тот же метод SetEntitySchemaRecordRightLevel). Можете локально отладить (на запись маркетинговой кампании добавить тэг и посмотреть что в этом методе передается в аргументах).

 

Также можете попробовать использовать RightsManagerHelper пакета PRMBase или пример в SocialSubscriptionService пакета ESN, там аналогичные операции доступны.

Пример раздачи прав через DBSecurityEngine есть в методе CheckTagTypeAndGrantAdditionalRights в процесе на объекте CampaignTag. Там пример такой:

 

UserConnection.DBSecurityEngine.SetEntitySchemaRecordRightLevel(TSConfiguration.BaseConsts.PortalUsersSysAdminUnitUId, 
                        Entity.Schema, Entity.PrimaryColumnValue, SchemaRecordRightLevels.All); 

 

то есть в метод аргументами передаются:

TSConfiguration.BaseConsts.PortalUsersSysAdminUnitUId - Id пользователя или роли;

Entity.Schema - название объекта;

Entity.PrimaryColumnValue - Id записи из этого объекта;

SchemaRecordRightLevels.All - уровень прав доступа.

 

Еще пример - процесс на объекте Activity из пакета Base (тот же метод SetEntitySchemaRecordRightLevel). Можете локально отладить (на запись маркетинговой кампании добавить тэг и посмотреть что в этом методе передается в аргументах).

 

Также можете попробовать использовать RightsManagerHelper пакета PRMBase или пример в SocialSubscriptionService пакета ESN, там аналогичные операции доступны.

Oleg Drobina,

Спасибо, получилось сделать.

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

Предпологаю, что можно в 1м скрипет через сетеры сохранить значения на уровне переменных процесса, а потом во 2м скрипте через геттеры получить их значения. Но может есть ещё какие-то способы ?

Нравится

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

Добрый день,

 

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

Вот несколько примеров геттеров и сеттеров того, как это можно реализовать:

 

Скрипт 1

string s = "Test1";
Set<string>("ProcessSchemaParameter2", s);
 
return true;

Скрипт 2

string s2 = Get<string>("ProcessSchemaParameter2");
s2 += " and param 3";
Set<string>("ProcessSchemaParameter3", s2);
 
int i = Get<int>("ProcessSchemaParameter1");
i += 2;
Set<int>("ProcessSchemaParameter4", i);
return true;

В сеттерах и геттерах мы ставим «Код» параметра, а не его заголовок. Мы можем увидеть код параметра, если нажмем на него.

 

Здесь вы можете найти дополнительную информацию:

https://academy.terrasoft.ua/docs/user/biznes_processy/spravka_po_eleme…

 

С уважением,
Дарий

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

Есть у меня бизнес-процесс А, в нём есть элемент скрипт, который через код добавляет новые объекты, делает он это, примерно, так:
 

var insert = new Insert(userConnection).Into("UsrCard")
                .Set("Id", Column.Parameter("id"))
                .Set("Name", Column.Parameter("Name"))
                ...;
 
insert.Execute();

 

Есть бизнес-процесс Б, который стартует по сигналу создания этих объектов(Object signal, UsrCard, Record Added). Точнее он должен старовать, но этого не делает. Я так понимаю, что проблема в том, как именно я добавляю эти объекты. Естественно, если бы я это делал через элемент Add data, то всё работало бы, но мне надо добавлять именно через код, так как объектов создать надо много и так удобней.

Вопрос в том, как мне нужно поменять мой подход добавления объектов, чтобы процесс Б начал триггериться на эти новые объекты, можно ли вообще этого добиться, не используя элемент Add data ?

Нравится

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

Добрый день.

Для того, чтобы срабатывал вызов бизнес-процесса по сигналу, Вам нужно делать добавление через EntitySchema. Вот таким образом:

EntitySchema contactSchema = UserConnection.EntitySchemaManager.GetInstanceByName("Contact");
Entity contactEntity = contactSchema.CreateEntity(UserConnection);
contactEntity.SetDefColumnValues();
contactEntity.SetColumnValue("Name", "User01");
contactEntity.Save();

 

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

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

Хм, я заметил, что старт бизнес-процесса по сигналу всё таки срабатывает, но только, если запустить процесс создания объектов вручную(нажав Run). Но мне надо, чтобы этот процесс запускался автоматически(механизм этого есть и работает). Не пойму, что именно в автоматическом запуске первого процесса мешает позже запуститься второму процессу. Может, надо UserConnection как-то по-другому доставать ?

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

Добрый день!

 

Подскажите, пожалуйста, возможно ли добавление новых полей в system settings при помощи создания замещающего объекта или другим способом? Пробую добавить поле в замещающий объект, но тогда в system settings слетают все заполненные записи, поле не появляется.

 

Нравится

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

Добрый день,

 

У Вас не отображаются значения для полей, потому что, скорее всего, сваливается с 500 ошибкой SelectQuery на VwSysSettings. То есть, Вы добавили новую колонку в таблицу SysSettings, но не отобразили изменение во Vw по этой таблице. Еще необходимо поменять структуру Vw. Как трафарет, можете использовать SQL сценарий "VwSysSetting" из конфигурации (их там три, каждый для разной СУБД, все в пакете UIv2), в сценарий нужно добавить Вашу кастомную колонку. После выполнения сценария можно не перелогиниваться в систему и не обнолвять страницу, запросы должны проходить после этого.

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