Здравствуйте!
Можно ли узнать Id контакта, который является пользователем BPM, по Id, который я получаю в коде как

UserConnection.CurrentUser.Id

Решено. Id пользователя и связь с контактом находится в таблице SysAdminUnit

Нравится

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

"Эмин Юнусов" написал:UserConnection.CurrentUser.Id

Добрый день.
UserConnection.CurrentUser.ContactId

Можно проще:

UserConnection.CurrentUser.ContactId;

а ещё есть:

UserConnection.CurrentUser.ContactName;
Показать все комментарии

Добрый день.
Возникла следующая проблема:
Существовал бизнес процес, по которому было много документов.
Процесс изменили вместе с изменением внутренней логики, соответственно изменился порядок и количество задач в процессе.
Вопрос:
1. Как можно корректно завершить старые процессы (т.е. сохранить процесс_old) и паралельно запускать новые процессы.
2. Как изменить текущий процесс со старого на новый.

По пункту 1 сделал так:
- создал копию процесса = процесс_new и опубликовал, в таблице SysSchemaInSolution откатился до предыдущей версии процесса.
- Переименовал процесс в процесс_old и опубликовал.
- Переименовал процесс_new в процесс и опубликовал.
- в таблице [SysModuleAction] изменил ссылку действия на новый процесс.
Все заработало.

Но проблема по пункту 2 осталась. как изменить ID процессов запущенных с момента обновления сервиса до изменения его ID

Нравится

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

Здравтсвуйте, Илья!
При старте процесса он сериализуется в БД, таким образом, при внесении изменений в схему процесса, запущенный процесс будет выполниться по тому сценарию, который был на момент его запуска и корректно подменить эти данные не представляется возможным.

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

Илья, можете попробовать поменять [SysSchemaId] и [Name] в таблице [SysProcess], но не уверен, что изменение [SysSchemaId] не приведет к нарушению работы процесса.
Во всяком случае, при изменении [Name] Вы будете видеть, где какой процесс.

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

Использую вот такой вот скрипт, где FileID - id нашего файла

EntitySchemaManager esqManager = UserConnection.EntitySchemaManager;
var esqResult = new EntitySchemaQuery(esqManager, "File");
esqResult.AddAllSchemaColumns();
esqResult.AddColumn("Data");
Entity currentFile = esqResult.GetEntity(UserConnection, FileID);
       
//файл должен появиться
while (currentFile == null) {
        currentFile = esqResult.GetEntity(UserConnection, FileID);     
}
var currentFileName = currentFile.GetTypedColumnValuestring>("Name");
var currentFileData = currentFile.GetBytesValue("Data");

var Response = Page.Response;

Response.AddHeader("Content-Disposition", "attachment; filename=\""" + System.Web.HttpUtility.UrlPathEncode(currentFileName) + ""\"""");

Нравится

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

Здравствуйте, Александр!
Думаю, стоит воспользоваться готовым решением из процесса "Скачать шаблон для импорта контрагентов", например:

public virtual bool DownloadTemplateScriptExecute(ProcessExecutingContext context) {
			var entitySchemaManager = UserConnection.EntitySchemaManager;
var entitySchema = entitySchemaManager.GetInstanceByName("File"); 
var entitySchemaQuery = new EntitySchemaQuery(entitySchemaManager, entitySchema.Name);
 
var dataColumn = entitySchemaQuery.AddColumn("Data");
entitySchemaQuery.Filters.Add(
	entitySchemaQuery.CreateFilterWithParameters(
		FilterComparisonType.Equal, "[KnowledgeBaseFile:FileId].KnowledgeBase", new object[] {new Guid("edb71f06-f46b-1410-e980-20cf30b39373")}));
entitySchemaQuery.Filters.Add(
	entitySchemaQuery.CreateFilterWithParameters(
		FilterComparisonType.Equal, "Name", new object[] {FileName.ToString()}));
 
var entityCollection = entitySchemaQuery.GetEntityCollection(UserConnection);
if (entityCollection.Count > 0) {
	var data = entityCollection[0].GetBytesValue(dataColumn.Name)  as byte[];    
	var response = HttpContext.Current.Response; 
	TSConfiguration.PageResponse.Write(response, data, FileName, TSConfiguration.ContentType.XmlType);
}
 
return true;
		}

К сожалению у меня TSConfiguration не знает методов PageResponse и ContentType, и в процессе "Скачать шаблон ..." вместо TSConfiguration стоит скрипт

Response.AddHeader("Content-Disposition", "attachment; filename=\"" + System.Web.HttpUtility.UrlPathEncode(FileName) + ""\"""");

Александр, какая у Вас версия ядра?
Попробую воспроизвести.
По поводу загрузки данных попробуйте перед вызовом LoadRows() установить

Page.DataSource.PageRowsCount = -1; //или заведомо вольшое числ
Показать все комментарии

Добрый день.
Подскажите пожалуйста, можно ли указать страницу объекта при действии "Открыть страницу выбора из справочника"

Нравится

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

Здравствуйте, Илья!
Пример Вам в помощь.
Открытие окна выбора элемента из справочника (с фильтрами)
Создать Действие процесса (UserTask). Действие = Открыть страницу выбора из справочника

Создать скрипт подготовки перед действием и написать в нем следующее:

var SSDocumentOfferingtId = new Guid(SysSettings.GetValue(UserConnection, "SSDocumentOfferingtId").ToString());//UID Объекта
Collection<Dictionary<string, object>> filters = new Collection<Dictionary<string, object>>(); 
filters.Add(new Dictionary<string, object> { 
    {"comparisonType", FilterComparisonType.Equal},
    {"leftExpressionColumnPath", "Document"},
    {"useDisplayValue", false},
    {"rightExpressionParameterValues", new object[] {ParentDocumentSpecificationId}}
});
filters.Add(new Dictionary<string, object> { 
    {"comparisonType", FilterComparisonType.NotEqual},
    {"leftExpressionColumnPath", "IsVsat"},
    {"useDisplayValue", false},
    {"rightExpressionParameterValues", new object[] {true}}
});
filters.Add(new Dictionary<string, object> { 
    {"comparisonType", FilterComparisonType.IsNull},
    {"leftExpressionColumnPath", "[ProductsParts:DocumentOffering].Parent"},
    {"useDisplayValue", false},
    {"rightExpressionParameterValues", new object[] {}}
});
 
OpenSpecOfferingLookupUserTask.ProcessKey = InstanceUId;
OpenSpecOfferingLookupUserTask.PageParameters = new Dictionary<string, object>() {
    {"LookupFilters", filters},
    {"schemaUId", SSDocumentOfferingtId},
    {"customClosedEvent", "SpecOfferingLookupPageClosed"} //Сообщение при закрытии окна
};
OpenSpecOfferingLookupUserTask.UseCurrentActivePage = true;
return true;

Создать скрипт обработки после действия и написать в нем следующее:

var offerings = OpenSpecOfferingLookupUserTask.GetSelectedValues(UserConnection) as Dictionary <string, object>;
var offeringId = Guid.Empty;
foreach (var offering in offerings) {
    offeringId = new Guid(offering.Key.ToString());
    break;
}
if (offeringId == Guid.Empty) {
    return true;
}
return true;

Здравствуйте Андрей.
В этом примере используется стандартный справочник, а мне нужно использовать свою собственную страницу отображения справочника. Вопрос как в Действие = Открыть страницу выбора из справочника подставить свою страницу отображения?

Илья, насколько я вижу из кода действия, то за то, какая страница будет открыта отвечает параметр "lookupPageSchemaUId". Попробуйте добавить его в PageParameters с соответсвующим UId страницы.

Андрей, создал страницу справочника. Изменил вызов действия "Открыть страницу выбора из справочника" добавив

  pageParameters.Add("lookupPageSchemaUId", "dff16a7e-027f-45aa-8662-1a4f01c4238c");

Страница не открывается. И никакой ошибки не возникает. Этот параметр убираю, открывается стандартная страница справочника.

Илья, здравствуйте.

А сам справочник у Вас зарегистрирован с кастомной страницей редактирования, которая унаследована от базовой страницы редактирования справочника?

Можно получить сервисы обьекта справочника, страницы справочника и сам бизнес процесс?

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

Здравствуйте! С помощью веб-сервиса осуществляется запуск БП. По логике БП, необходимо открытие карточки контакта. При запуске процесса через веб-сервис, карточка не открывается, но если запустить процесс из BPM, то все работает корректно. Помогите разобраться!

Нравится

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

Эмин,

Работа с визуальными элементами при запущенном с помощью веб-сервиса процессе будет возможна только в 7.х, доработка в планах.
На 5.х она спускаться не будет, ввиду больших трудозатрат на адаптацию.

"Maxim Gritsenko" написал:

Эмин,

Работа с визуальными элементами при запущенном с помощью веб-сервиса процессе будет возможна только в 7.х, доработка в планах.

На 5.х она спускаться не будет, ввиду больших трудозатрат на адаптацию.


Тогда подскажите, пожалуйста, как можно реализовать работу с визуальными элементами в BPM 5.4 по сигналу из другого приложения без использования веб-сервиса?
И еще вопрос. Возможен ли следующий алгоритм?
Процесс 1 создает запись о контакте в базе через EntitySchemaQuery при запуске по веб-сервис
Процесс 2 подписан на событие создание контакта с условием, и если условие совпадает, то открывается карточка созданного контакта.
Как нужно добавлять запись в БД, чтобы был запущен процесс по событию?

Эмин,

Риквест процессу2 приходит не от страницы, соотв. нет страницы и рендерить некуда, поэтому никак не получится вызвать визуальный элемент "извне".
Максимум, как можно известить пользователя - это установить ему задачу в расписание.

"Maxim Gritsenko" написал:
Максимум, как можно известить пользователя - это установить ему задачу в расписание.

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

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

"Maxim Gritsenko" написал:

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


Огромное спасибо! Подскажите пожалуйста, как нужно добавить код, который будет затем вызван ajax'ом из javascript'a

Я условие создавал на c# - больше возможностей. А потом просто собирал строку с кодом и вставлял в переменную со скриптом.

"Maxim Gritsenko" написал:

Я условие создавал на c# - больше возможностей. А потом просто собирал строку с кодом и вставлял в переменную со скриптом.


Немного не то)
Опишу ситуацию подробнее. По веб-сервису запускается процесс, который сохраняет задачу и связывает ее с контактом и ответственным. Теперь для пользователя необходимо открыть карточку задачи. Мы выяснили, что визуализация процессов через веб-сервис не возможна.
И появилась следующая идея, дописаться в яваскрипт на MainPage, и каждые n сек вызывать метод, а уже данный метод будет запускать процесс, который найдет новую задачу для пользователя и откроет карточку этой задачи.
Возможно ли это?
Подскажите, пожалуйста, как правильно добавить такой метод, чтобы затем вызвать его из яваскрипта по ajax

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

var manager = UserConnection.ProcessSchemaManager;
var processSchema = manager.GetInstanceByName("MyProcess");
var process = processSchema.CreateProcess(UserConnection);
process.Execute(Page.UserConnection);

Так что получится уведомлять активных пользователей, которые "ходят" по системе.

"Maxim Gritsenko" написал:

В 5.х нет таймера, так что раз в n секунд не получится. PageLoadComplete мейнпейджа отрабатывает при его загрузке, то есть, при переходе между разделами.

...

Так что получится уведомлять активных пользователей, которые "ходят" по системе.


Спасибо!
В javascript коде, который добавляется на PageLoadComplete есть функция checkRemindingExists() и функция setInterval (checkRemindingExists, " + remindingsCheckInterval + @");
Как я понимаю, данные функции осуществляют проверку напоминаний по интервалу. Мне по аналогии необходимо запустить БП из javascript. Как я могу это сделать?

Эмин,

Нашел такую штуку:

Из клиентского кода можно отправить сообщение в процесс страницы:

window.Terrasoft.AjaxMethods.ThrowClientEvent(processUId, message);

В процессе можно создать событийный подпроцесс, в нем начальное сообщение и задание-сценарий, в котором вызов бизнес процесса:

var manager = UserConnection.ProcessSchemaManager;
var processSchema = manager.GetInstanceByName("MyProcess");
var process = processSchema.CreateProcess(UserConnection);
process.Execute(Page.UserConnection);

На PageLoadComplete в ScriptManager передавать вызов своей функции с интервалом вызова:

По идее, это то, что вам нужно. Но, мне кажется, открывать окна юзерам - не лучшая практика.

Спасибо огромное! Все работает!
P.S. Не все обращают внимание на колокольчик, а если там уже были какие-то цифры, то иногда не очевидно поступила новая задача или нет. А окно привлечет внимание.

Вам решать =)

"Maxim Gritsenko" написал:

Добрый день, Максим!
Подскажите пожалуйста где в BPMOnline 7.X осуществляется обновление счетчика уведомлений. Насколько я понял, страница MainPage теперь не осуществляет данный функционал (там закомментирован js-код для счетчика)

Также вы писали, что в 7.X планируется открытие страницы через веб-сервис. Реализован ли данный функционал в 7.1. Если да, то как его можно прмиенить. Т.к. при открытие карточки в БП, который запускается по веб-сервису, БП отрабатывает, но страница не открывается.

Здравствуйте, Эмин.

В 7.x расчет счетчика уведомлений действительно изменился. Стало немного запутанней, но работает быстрее.
Теперь это представление в БД (VwRemindingsCount), которое хранит данные по уведомлениям. Из модуля панельки (LeftPanelTopMenuModule) отправляется запрос сервису напоминаний (RemindingService), который запускает процесс (GetRemindingCounters) выполняющий выборку из представления раз в минуту и передающий ответным запросом модулю панельки, который подписан на сообщения от этого процесса и получив сообщение обновляет счетчик.

По открытию страницы через веб-сервис ориентировок нет, это не приоритетная задача и в спринтах разработчиков я ее пока вообще не вижу.

"Maxim Gritsenko" написал:

Здравствуйте, Эмин.

В 7.x расчет счетчика уведомлений действительно изменился. Стало немного запутанней, но работает быстрее.

Теперь это представление в БД (VwRemindingsCount), которое хранит данные по уведомлениям. Из модуля панельки (LeftPanelTopMenuModule) отправляется запрос сервису напоминаний (RemindingService), который запускает процесс (GetRemindingCounters) выполняющий выборку из представления раз в минуту и передающий ответным запросом модулю панельки, который подписан на сообщения от этого процесса и получив сообщение обновляет счетчик.


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

Из процесса открыть в новой вкладке/окне не выйдет. Можно попробовать открыть страницу, которая при загрузке открывает страницу активности в новой вкладке. Правда, пахнет костылем.
Или можно переопределить модуль панельки, чтобы он при получении сообщения кроме изменения счетчика еще и открывал страницу активности в новой вкладке. Но это тоже костыль, потому что при накатке обновлений они не доедут на переопределенный модуль.

"Maxim Gritsenko" написал:

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

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


Я так понимаю, что при переопределении модуля необходимо полностью перенести код из базового LeftPanelTopMenuModule в новый. Все перенес, но не могу добавить Images(где хранятся картинки этих иконок?)
Возможно ли уменьшить время запуска счетчика активностей?

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

"Maxim Gritsenko" написал:

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


Спасибо за помощь, Максим!

Подскажите, КАК запустить процесс по веб-сервису.

Акмаль, вот ссылка на статью в SDK:
http://www.terrasoft.ru/bpmonlinesdk/WorkWithBpmByWebServices.html

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

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

Нравится

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

Здравствуйте, Александр!

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

Подобная тема уже подымался на нашем портале. Найти ее Вы можете тут -
http://www.community.terrasoft.ru/forum/topic/9894

Спасибо

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

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

Есть страница с 2-мя Lookup'ами - "Объекты" и "Поля". Пользователь в первом выбирает объект системы, например Контакт, а во втором нужно в выпадающем списке отобразить все поля этого объекта. Вобщем что-то подобное построителю фильтров.

Подозреваю, что можно выудить эту всю информацию из таблицы SysSchema из колонки MetaData аналогичным способом, как описывалось тут. Или все-таки есть более грамотные варианты?

Нравится

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

Грамотный вариант именно на вашу проблему не скажу (нет сейчас под рукой BPM), но я находил все поля объекта так.
Как привязать к lookup-полю не знаю, ибо lookup-полю нужно id и таблица, которых у нас. Если как-то можно получить column.id, то может это вам и подойдет. (возможно надо создать справочник, а также скрипт, который будет добавлять все недостающие поля по объектам в этот справочник).
Ну вообщем вот небольшая подсказка, которая может пригодиться, а может и нет.

Благодарю, в принципе вариант, ИМХО, более изящный, чем я указывал.

Constantine, в качестве примера Вы можете использовать Страницу редактирования графика.
Поле EntityLookupEdit - используется для вывода объектов, OrderByFieldEdit и OrderByFieldToolButton - для выбора поля объекта из списка полей.
Обратите внимание, для выбора поля используется не Lookup, а текстовое поле и кнопка. Логика обработки нажатия на кнопку в подпроцессе OrderByFieldToolButtonClickEventSubProcess.

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

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

Нравится

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

Здравствуйте, Александр!

Для изменения вида отображения колонок для всех пользователей необходимо внести изменения в страницу реестра раздела (на файлах во вложениях приведен пример на разделе "Контакты").

Вам необходимо перейти в "Инструменты" -> в раздел "Конфигурации", из элементов раздела Вам необходимо выбрать страницу реестра необходимого раздела (см. файл во вложении) и выполнить команду изменить.
В открывшемся окне Вы увидите общий реестр записей раздела, который можно изменить (добавить новые колонки, изменить ширину колонок и т.д). После внесения изменений, сохраните и опубликуйте страницу.

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

Спасибо за оперативный ответ.

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

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

Очистка профиля администратора очистит только персональные настройки данного администратора.

Спасибо

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

Alexander, выполните дополнительно следующие действия:
1. В странице реестра установите для колонки элемента DataSource признак "Отображать в реестре":
/system/files/14-01-2014_19-23-41.png
2. Опубликуйте изменения. Очистите профиль.

Наталия, спасибо. Все получилось.

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

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

Получается, что первоначальный вариант - вносить изменения через настройки колонки (см.вложенный файл), не будет работать? Или я что-то неправильно понимаю?

Первоначальный вариант предназначен для редактирования визуального представления реестра записей в разделе (ширина столбцов, их порядок и т.п.). Добавление новых колонок в области структуры и свойств элемента DataSource определяет, какие данные из таблиц БД будут загружены для раздела (GridPage).

Теперь понял. Смутил пункт контекстного меню "Настройка колонки".
Спасибо.

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

Хочу, чтобы по двойному клику в реестре "Базовая страница файла и ссылки" сразу открывался файл, а не карточка.

Поправил процесс. На событие двойного клика по строке реестра поставил скрипт, который отрабатывает по кнопке "Сохранить файл".

Ругается.......

Action: DblClick
ControlId: PageContainer_DocumentsModulePage_DetailGridContainer278769742881e011bfea00155d04320c_TreeGrid
SubmitAjaxEventConfig: {"config":{"viewStateMode":"include","extraParams":{}}}

Нравится

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

Александр, нужно добавить свойство IsUpload = true для Page.TrreGrid.AjaxEvents на Init'e, как это сделано для кнопки.

Да, именно так, Дмитрий.

Page.TreeGrid.AjaxEvents.DblClick.IsUpload = true;

Всё заработало.
Большое спасибо.

Гм......по каким то причинам стала параллельно открываться и карточка файла.....
Я так понимаю, параллельно отрабатывает событие базовой страницы реестра.....
Как бы этого избежать.......

Всё. Разобрался.
Забыл переопределить метод GetRegisterTreeGridDblClickScript чтобы он String.Empty возвращал...
Спасибо.

Александр, не за что. Обращайтесь.

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

Подскажите, пожалуйста, как можно в странице карточки динамически сделать, что бы некоторые поля были не обязательны, либо обязательны. Аналог свойства из Terrasoft 3.x Dataset.Datafileds.ItemsByName('...').IsRequired = false;
Просто у меня такая ситуация, что обязательность задана на уровне объекта в документах, а я создал новый тип и карточку к нему, где нет некоторых обязательных полей. Теперь хочу отменить эту обязательность при работе с этой карточкой.
Спасибо!

Нравится

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

Можно, я так и делаю.
Например, в обработчике события изменения значения поля

Page.SomeFieldLookupEdit.Enabled = true;
Page.SomeFieldLookupEdit.SetRequired( true );

Ну или false......все от вас зависит :wink:

У контрола есть свойство Required и метод SetRequired(). В чём их отличие и когда какой работает, см. тут.

Спасибо всем за помощь!

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