Привет коллеги!

 

Иногда требуется отловить плавающий кейс в работе процесса или "отладить" процесс без использования VisualStudio. Большинство проблем можно решить с помощью трассировки процесса. Но если проблема в коде написанном в скриптаске или методах процесса, то самый простой способ - это добавить логирование.

Для этого необходимо:

1) в Using добавить

global::Common.Logging

2) в коде использовать

var _log = LogManager.GetLogger("BusinessProcess");
var processName = "MyProcess"; //Название процесса для простого поиска логов
_log.DebugFormat(@"{0}: Process was started", processName); //Уровень логирования Debug
_log.InfoFormat(@"{0}: Process was started", processName); //Уровень логирования Info
_log.WarnFormat(@"{0}: Process was started", processName); //Уровень логирования Warn
_log.ErrorFormat(@"{0}: Process was started", processName); //Уровень логирования Error

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

Если же сайт размещен на своих серверах (on-site), то логи необходимо искать по пути C:\Windows\TEMP\Creatio\SiteName\0\Log (этот путь может быть изменен в файле nlog.targets.config, параметр LogDir).

Для уровня логирования Debug и Info логи запишутся в файл Common.log, а для уровня Error - в файл Error.log

По умолчанию минимальный уровень логирования в on-site для логера "Common" указан Info. Изменить его можно в файле ..\Terrasoft.WebApp\nlog.config

<logger name="*" writeTo="commonAppender" minlevel="Info" maxlevel="Warn" />

 

Нравится

Поделиться

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

Добрый день,

 

Хочу создать бизнес-процесс "Отпуск". Суть в том, что сотрудник, уходя в отпуск запускает данный процесс, и на время его отсутствия активности передаются его заместителю.

 

Имеется "Автогенерируемая страница", в которой 4 поля (Отправитель, Получатель, Дата начала, Дата завершения). 

  1. Отправитель - сотрудник, уходящий в отпуск
  2. Получатель - заместитель
  3. Дата начала - с какого дня начинают передачу активностей на заместителя
  4. Дата завершения - когда закончить передачу и завершить бизнес-процесс.

 

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

Нравится

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

_KSL_,

 

В таком случае Вам нужно следующее.

1. В срм хранить информацию об отпусках сотрудников, например, реализовать деталь в разделе 'Сотрудники'. Структура её может быть следующей - сотрудник, дата начала отпуска, дата завершения отпуска, кому делегировать задачи. Для избежания путаницы я бы не давала сотрудникам самостоятельно вносить эту инфрмацию. Логично, что это должен делать либо ответственный за отпуска, либо HR-менеджер, либо бухгалтер.

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

Может быть проще использовать уже готовый бизнес-процесс по делегированию прав или модифицировать его? https://marketplace.terrasoft.ru/template/delegirovanie-prav-dostupa-na…

Сигнал не нужен, ведь данный БП запускается вручную.

После автогенерируемой страницы читаем первую запись Activity с нужными параметрами (от-до, где Ответственный = Сотрудник, ну и задача еще не завершена).

Если такая запись найдена (Id!=Guid.Empty), то модифицируем Activity, устанавливая Ответственный = Заместитель.

И снова возвращаемся к чтению записи Activity.



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



И, возможно, подумать, а как возвращать ещё не выполненные задачи после отпуска

Владимир Соколов,

 

Спасибо за ваши ответы.

 

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

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

_KSL_,

 

В таком случае Вам нужно следующее.

1. В срм хранить информацию об отпусках сотрудников, например, реализовать деталь в разделе 'Сотрудники'. Структура её может быть следующей - сотрудник, дата начала отпуска, дата завершения отпуска, кому делегировать задачи. Для избежания путаницы я бы не давала сотрудникам самостоятельно вносить эту инфрмацию. Логично, что это должен делать либо ответственный за отпуска, либо HR-менеджер, либо бухгалтер.

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

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

Спасибо за ответ 

 

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

_KSL_,

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

В любом случае, чтобы система могла выполнять какие-то действия, для неё нужно вносить вводные данные.

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

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

 

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

 

Сотрудник, который уходит в отпуск, должен запустить данный процесс. При запуске открывается "Автогенерируемая страница", в который имеется 4 поля (Отправитель - сотрудник, уходящий в отпуск, Получатель - кому будем переназначать активность, Дата начала и Дата завершения - с какого и до какого чисел будем переназначать).

 

Далее происходит чтение данных с объекта "Активность" и изменение данных "Активность" на основании условий, т.е. Ответственный = Отправитель, Дата завершения>Дата создания >= Дата начала. 

 

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

 

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

 

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

 

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

 

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

 

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

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

 

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

 

Правильно ли я понял, что я должен хранить к примеру в справочнике данные по отпускам(Сотрудник, Заместитель, Дата начала отпуска, Дата завершения).

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

 

Но тогда не совсем понимаю как нужно будет организовать процесс.

Как Вы можете переназначит новые, их же ещё нет?

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

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

 

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

 

Из полей Автогенерируемой страницу данные переходили в чтение данных, как условия (Ответственный=у кого, Завершения>Дата создания>=Начало). Далее шло изменение данных с такими же условиями, но меняли Ответственный=кому. Далее шел условный поток, в  котором сравнивалась текущая дата с завершением. Если текущая дата < Завершения, то возвращается к чтению.

 

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

 

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

Сначала попытайтесь понять, что вы вообще хотите сделать. Если задач ещё не существует, то Вы их не вычитаете и не измените.

 Если текущая дата < Завершения, то возвращается к чтению

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

_KSL_,

Если у Вас версия on-site Вы можете запустить SQL profiler и отследить запрос, который идет в базу, и понять, почему происходит зацикливание.

 

Покажите код, каким образом Вы реализовали, установку ответственных в задачах в Вашем бизнес-процессе.

Алла, он просто нарисовал в БП цикл, надеясь, что он будет постоянно до даты конца отпуска крутиться и обрабатывать появляющиеся задачи. Но так нельзя, количество повторений ограничено, а до того всё зависнет.

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

Ясно. Ну, ты же, знаешь, есть старая привычка докопаться до сути вопроса)))

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

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

Добрый день!

Руководствуясь статьей "Формулы" на Академии, пытаюсь создать в БП условный поток с проверкой заполненности поля, но при сохранении выдает ошибку:

Изображение удалено.

________________________________________________________________________________________

Изображение удалено.

Нравится

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

Вы пытаетесь сравнить Дату с Guid. Поэтому формула и выдает вам ошибку. Вам нужно сравнивать с DateTime.MinValue

Вы пытаетесь сравнить Дату с Guid. Поэтому формула и выдает вам ошибку. Вам нужно сравнивать с DateTime.MinValue

Сидоров Александр Валерьевич,

 благодарю, разобрался.

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

Обновил систему до 7.14.0, помимо решаемых проблем появилась одна нерешаемая, ТП морозится уже 1.5 недели, поэтому пытаюсь задать вопрос коммьюнити.

Итак, проблема с запуском БП, которые должны стартовать по таймеру.  Если запускать их вручную, они тупо не запускаются. В журнале появляется в статусе "Выполняется", но реально ничего не выполняется и просто "висит". Это баг, или фича новой версии?

В логах приложения ошибок нет. По таймеру запускаются и работают.

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

Кто-нибудь сталкивался? Куда можно поковырять?

Нравится

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

У нас возникало из-за переполнения очереди заданий в Quartz. Оказывается, что таймер в БП не приостанавливает процесс, а ставит его в очередь выполнения в определенное время. И если эта очередь переполнена, то и процесс по таймеру дальше не идет. Скорее всего у вас та же проблема. Если есть доступ к журналу Quartz - посмотрите там. 

Как вариант - вместо таймера поставьте скрипт-таск с Thread.Sleep.

У нас возникало из-за переполнения очереди заданий в Quartz. Оказывается, что таймер в БП не приостанавливает процесс, а ставит его в очередь выполнения в определенное время. И если эта очередь переполнена, то и процесс по таймеру дальше не идет. Скорее всего у вас та же проблема. Если есть доступ к журналу Quartz - посмотрите там. 

Как вариант - вместо таймера поставьте скрипт-таск с Thread.Sleep.

Ксензов Егор,

а это какая таблица?

Алексей-Карягин,

Добрый день! Вот скрипт на выборку данных из таблицы Quartz

SELECT [SCHED_NAME],
[TRIGGER_NAME]
,[TRIGGER_GROUP]
,[JOB_NAME]
,[JOB_GROUP]
,[DESCRIPTION]
,[dbo].[fn_QuartzTimeToDateTime]([NEXT_FIRE_TIME]) [NEXT_FIRE_TIME]
,[dbo].[fn_QuartzTimeToDateTime]([PREV_FIRE_TIME]) [PREV_FIRE_TIME]
,[PRIORITY]
,[TRIGGER_STATE]
,[TRIGGER_TYPE]
,[dbo].[fn_QuartzTimeToDateTime]([START_TIME]) [START_TIME]
,[dbo].[fn_QuartzTimeToDateTime]([END_TIME]) [END_TIME]
,[CALENDAR_NAME]
,[MISFIRE_INSTR]
,[JOB_DATA]
FROM [QRTZ_TRIGGERS]

 

Нигрескул Алексей,

у меня 27 записей. Не похоже, чтобы было какое-то переполнение.

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

Просто таймер. На 7.11 это прекрасно работало.

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

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

Добрый день!

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

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

БП просто валится в ошибку по тайм ауту. Пробовали установить признак выполнения процесса в фоновом режиме, но это только все сломало.

Может у кого есть опыт как можно увеличить тайм аут выполнения БП? Базовых методов не нашли.

Благодарю!

 

Нравится

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

Добрый день!

Скорее всего вы запускаете БП через стандартное действие "Запуск процесса". Если это так, то там вызывается метод _runProcess утилиты ProcessModuleUtilities, который наверняка вызывает метод _runProcessOld. В этом методе вызывается сервис ProcessEngineService.svc с передачей параметров. Но таймаут не передается.

Что можно сделать: реализовать отдельное действие запуска вашего БП (кнопку в каком-нибудь разделе, дизайнере), в котором будет вызываться сервис ProcessEngineService.svc с передачей таймаута.

Добрый день!

Скорее всего вы запускаете БП через стандартное действие "Запуск процесса". Если это так, то там вызывается метод _runProcess утилиты ProcessModuleUtilities, который наверняка вызывает метод _runProcessOld. В этом методе вызывается сервис ProcessEngineService.svc с передачей параметров. Но таймаут не передается.

Что можно сделать: реализовать отдельное действие запуска вашего БП (кнопку в каком-нибудь разделе, дизайнере), в котором будет вызываться сервис ProcessEngineService.svc с передачей таймаута.

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

Это не только уберёт зависание, но и ослабит нагрузку на сервер приложений и базу данных.

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

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

Сидоров Александр В.,

Александр, ваша идея нам очень очень помогла! Спасибо! будем еще тестировать).

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

При сохранении правок существующего бизнес-процесса возникает ошибка:

Изображение удалено.

 

Суть корректировок - нужно сделать так чтобы после прохождения 1-го уровня эскалации в обращении перед переходом на 2-ой уровень эскалации происходила проверка не находится ли обращение в состоянии паузы (OnHold), проще говоря нужно приостанавливать эскалацию в случае OnHold'а:

Изображение удалено.Изображение удалено.

 

Нравится

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

Видимо, речь о том, что из элемента «Исключающее “ИЛИ” по событиям» (жёлтый ромб слева сверху) нельзя непосредственно вызывать другие элементы, помимо получения событий (различных сообщенийсигналов либо таймеров), а Вы добавили ветку вниз, начинающуюся со чтения. Также нижний жёлтый ромб «Исключающее “ИЛИ”» с одним входом и одним выходом выглядит странно и непонятно его предназначение.

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

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

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

Нравится

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

Этот механизм реализован в схеме DesktopPopupNotification, функция из которой вместе с параметрами сообщения вызывается в том месте системы, где хотим что-то сообщить. Например, в SectionMergeHelper:

/**
 * Show popup message with the merge info.
 * @param {Number} mergeRecordsCount Count of records to merge.
 */
showMergePopup: function(mergeRecordsCount) {
	var config = this.getMergePopupConfig(mergeRecordsCount);
	DesktopPopupNotification.showNotification(config);
},
 
/**
 * Returns the config of the popup notification.
 * @param {Number} mergeRecordsCount Count of records to merge.
 * @return {Object} Config of the popup notification.
 */
getMergePopupConfig: function(mergeRecordsCount) {
	var bodyTemplate = this.getMergePopupBodyTemplate();
	return {
		id: this.Terrasoft.generateGUID(),
		title: resources.localizableStrings.MergeNotificationTitleTemplate,
		body: this.Ext.String.format(bodyTemplate, mergeRecordsCount),
		icon: this.getMergePopupIconUrl(),
		onShow: this.onShowPopup,
		ignorePageVisibility: true
	};
},

Соответственно, если хотите, чтобы в одних разделах что-то показывалось, а в других — нет, нужно в ненужных переопределить логику, закомментировав вызов showNotification.

Александр, спасибо за развёрнутый ответ! В частности интересуют уведомления об успешном запуске процессов, например при опубликовании обращения или очистки кэша Redis, в схемах процессов вызов данной функции не обнаружил

Похоже на функцию _showSuccessfullyRunProcessPopup в схеме ProcessModuleUtilities.

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

 Большое спасибо за помощь :3

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

Был создан БП с блоком отправки почты. В тело письма передается HTML-текст через параметр процесса. Всё работает корректно.

Но при повторном открытии и сохранении БП, параметр в графе "Тело Письма" сбрасывается, даже если не щелкать на блок отправки почты. Приходится при каждом изменении БП заново указывать параметр в тело письма. Иначе в письме содержится именно текст [#IsOwner....

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

 

Изображение удалено.

 

Нравится

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

Обратитесь в тех поддрежку Terrasoft (Creatio) не забыв указать номер версии используемой  у вас BpmOnline.

Обратитесь в тех поддрежку Terrasoft (Creatio) не забыв указать номер версии используемой  у вас BpmOnline.

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

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

Подскажите как можно из Бизнес процесса обратится к C# методу?

Нравится

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

Добрый день! Здесь -  http://prntscr.com/qr8kpl подключаем нам нужное пространство имен, затем объявляем экземпляр класса и вызываем метод - http://prntscr.com/qr8lqh&nbsp;

Добрый день! Здесь -  http://prntscr.com/qr8kpl подключаем нам нужное пространство имен, затем объявляем экземпляр класса и вызываем метод - http://prntscr.com/qr8lqh&nbsp;

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

Необходимо асинхронно запустить из одного БП другой. Использую элемент скрипт

var manager			= context.UserConnection.ProcessSchemaManager;
var processSchema	= manager.GetInstanceByName("ProcessDealerClaim");
var process			= processSchema.CreateProcess(context.UserConnection);
process.SetPropertyValue("FlipId", Get<Guid>("FlipId"));
process.Execute(context.UserConnection);

И всё бы было хорошо, если бы не версионность, а именно, у БП ProcessDealerClaim есть более новая версия ProcessDealerClaimNewBusiness1. Можно, конечно, вписать ее, но что будет, когда появится ProcessDealerClaimNewBusiness2 ? Переделывать?

В общем вопрос - как поддержать версионность, чтобы запускалась актуальная версия БП?

Нравится

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

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

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

Алла Савельева пишет: Где именно посмотреть? ДЛЛ декомпилировать?

Зачем dll, посмотрите в коде схем, где запускают процессы.

Например, в LeftPanelTopMenuModule фильтруют список процессов по IsMaxVersion:

openProcessPage: function() {
	var vwSysProcessFilters = Terrasoft.createFilterGroup();
	vwSysProcessFilters.name = "vwSysProcessFiler";
	var sysWorkspaceFilter = Terrasoft.createColumnFilterWithParameter(
		Terrasoft.ComparisonType.EQUAL, "SysWorkspace",
		Terrasoft.SysValue.CURRENT_WORKSPACE.value);
	vwSysProcessFilters.addItem(sysWorkspaceFilter);
	var businessProcessTagFilter = Terrasoft.createColumnFilterWithParameter(
		Terrasoft.ComparisonType.EQUAL, "TagProperty",
		ConfigurationConstants.SysProcess.BusinessProcessTag);
	vwSysProcessFilters.addItem(businessProcessTagFilter);
	var isMaxVersionFilter = Terrasoft.createColumnFilterWithParameter(
		Terrasoft.ComparisonType.EQUAL, "IsMaxVersion", true);
	vwSysProcessFilters.addItem(isMaxVersionFilter);
	var config = {
		entitySchemaName: "VwSysProcess",
		isRunProcessPage: true,
		captionLookup: resources.localizableStrings.processLookupCaption,
		multiSelect: false,
		columnName: "Caption",
		filters: vwSysProcessFilters,
		hideActions: true
	};
	var handler = function(args) {
		var activeItems = args.selectedRows.getItems();
		if (!this.Ext.isEmpty(activeItems)) {
			Terrasoft.ProcessModuleUtilities.executeProcess({
	sysProcessId: activeItems[0].Id
});
		}
	};
	LookupUtilities.Open(this.sandbox, config, handler, this, null, false, false);
},

Плюс есть сообщение ActiveProcessSchemaVersionChanged, на которое в некоторых схемах подписываются, например, в VwProcessLibSection.

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