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

Возникла такая проблема: на странице реестра записей Юр. Лица реализовали действие, по нажатию на которое появляется окно выбора справочного значения, и при выборе нужного значения, оно меняется у всех Юр. Лиц, отфильтрованных в реестре. Теперь надо добавить окно подтверждения для пользователя. Я вижу решение двумя способами, но не знаю как реализовать:
1) Добавить дополнительное pop up окно с вопросом-подтверждением действия и выбором из двух значений, либо подтвердить, либо не подтвердить.
Но, с созданием таких окон проблемы и код получится большим на мой взгляд.
Если есть похожие реализованные кейсы, поделитесь пожалуйста :)
2) Добавить маленький процесс с 1-2 двумя элементами: Вопрос пользователю. И если пользователь выбирает "Да", то запускать код, который описан в начале.
Этот вариант предпочтительнее, но я не знаю как передать значение/параметр из процесса в код, описанный в начале.
Если кто сможет подсказать как передать значение из процесса, помогите плиз :)

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

Нравится

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

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

Алгоритм решения задачи:
1. В рамках процесса сгенерировать сообщение по WebSocket (элемент ScriptTask).
2. На целевой карточке подписаться на сообщение.
3. В обработчике реализовать интересующую логику.
Пункт 1 и 2 рассмотрены тут: http://www.community.terrasoft.ru/forum/topic/11784

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

Версия
7.9.1.3284
Нужно добавить в БП звонок-элемент чтобы его привязать к активностям и другим объектам.

Нравится

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

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

Опишите подробней ожидаемый результат выполнения такого элемента и какие бизнес-задачи вы хотите решить.
Запись можно добавить с помощью элемента [Добавить данные], указать целевой объект и заполнить связи с другими объектами.

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

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

Вы можете настроить процесс:
1. Стартовый сигнал по изменению записи в звонке, где Активность заполнена.
2. Читать данные в активности, где Id = Пункт 1. Активность.
3. Раздать права доступа на активность, где Id = Пункт 2. Id
4. Открыть страницу редактирования активности, где Id = Пункт 2. Id

Хорошо, это сделаю, но как настроить видимость кнопок звонка и эмейла в миникарточке активности, они создаются динамически. (две кнопки ля контакта и две для контрагента)

Добрый день!

Не могли бы Вы прикрепить скриншот Вашей миникарточки и код создания данных кнопок?


Вот карточка, кнопки базовые(есть еще емейл но в контакте его нет и тут его не видно)

Здравствуйте, Виталий!

Логика данной миникарточки находится в UIv2.ActivityMiniPage. Кнопки добавляются при ее создании(методы init и onEntityInitialized). Логика отображения кнопок находится в UIv2.MiniPageEntityConnectionsUtils и NUI.EmailExtendedMenu и работает именно так как Вы описали - при создании миникарточки формируется EntitySchemaQuery запрос в базу данных, и если у данного контака(контрагента) заполнена колонка телефон(e-mail) кнопка будет добавлена. Если таких данных нет - не будет и кнопки.

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

Коллеги, добрый день!
Не удается вызвать бизнес-процесс из С# кода.
Из сценария пользователя в бизнес-процессе происходит вызов другого бизнес-процесса. Код бизнес-процесса следующий

var userConnection = GetUserConnection>("UserConnection");
var caseStatusNew = "AE5F2F10-F46B-1410-FD9A-0050BA5D6C38";
var caseStatusInWork = "7E9F1204-F46B-1410-FB9A-0050BA5D6C38";
using (DBExecutor dbExecutor = userConnection.EnsureDBConnection())     {
            Select caseDeadlineResponseSelect = new Select(userConnection).
                Column("Case", "id").As("CaseId").
                From("Case").
                Where("Case", "StatusId").IsEqual(Column.Parameter(caseStatusNew)) as Select;
                using (var dr = caseDeadlineResponseSelect.ExecuteReader(dbExecutor)) {
                        while (dr.Read())
                        {
                                var caseId = dr.GetColumnValue("CaseId").ToString();
                                var utils = new TestUtils();
                                        utils.SendReminding(Guid.Parse(caseId.ToString()));
                                        Update updateCase = new Update(userConnection, "Case").
                                                Set("NrbSentDeadlineResponse", Column.Parameter(true)).
                                                Where("Id").IsEqual(Column.Parameter(caseId)) as Update;
                                        updateCase.Execute();
                        }
                }
   }
   return true;

Для вызова бизнес-процесса был реализован отдельный модуль исходного кода, со следующим наполнением:
namespace Terrasoft.Configuration.UsrUtilities
{
        using System;
        using Core;
        using Common;
        using System.Web;
        using Core.Process;

        public class TestUtils
        {
                private UserConnection _userConnection;
                public UserConnection userConnection
                {
                        get
                        {
                                if (_userConnection != null)
                                {
                                        return _userConnection;
                                }
                                _userConnection = HttpContext.Current.Session["UserConnection"] as UserConnection;
                                if (_userConnection != null)
                                {
                                        return _userConnection;
                                }
                                var appConnection = (AppConnection)HttpContext.Current.Application["AppConnection"];
                                _userConnection = appConnection.SystemUserConnection;
                                if (_userConnection != null)
                                {
                                        return _userConnection;
                                }
                                return null;
                        }
                        set
                        {
                                _userConnection = value;
                        }
                }

                private void Authenticate()
                {
                        if (userConnection == null)
                        {
                                throw new System.Security.Authentication.AuthenticationException();
                        }
                }
                public TestUtils()
                {
                        Authenticate();
                }

                public void SendReminding(Guid caseId)
                {
                        var processSchemaManager = (ProcessSchemaManager) userConnection.GetSchemaManager(@"ProcessSchemaManager");

                        var processSchema = processSchemaManager.GetInstanceByName(@"UsrSendDeadlineEmail");
                        var process = processSchema.CreateProcess(_userConnection);

                        process.SetPropertyValue(@"CaseId", caseId);
                        process.Execute(_userConnection);
                }
        }
}

Сохранение и компиляция кода происходит успешно. Но при вызове данного бизнес-процесса в журнале процесса, данный процесс отображается с ошибкой:
System.NotImplementedException: Метод или операция не реализована. в Terrasoft.Core.Process.ProcessSchema.CreateProcess(UserConnection userConnection) в Terrasoft.Configuration.NrbUtilities.NorbitUtils.SendReminding(Guid caseId) в Terrasoft.Core.Process.NrbCheckTimingMethodsWrapper.ScriptTask2Execute(ProcessExecutingContext context) в Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context)

Нравится

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

Странно. А можете потестить вот так:

namespace Terrasoft.Configuration.UsrUtilities
{
	using System;
	using Core;
	using Common;
	using System.Web;
	using Core.Process;
 
	public static class TestUtils
	{
		public static void SendReminding(Guid caseId, UserConnection user)
		{
			var processSchemaManager = (ProcessSchemaManager)user.GetSchemaManager(@"ProcessSchemaManager");
 
			var processSchema = processSchemaManager.GetInstanceByName(@"UsrSendDeadlineEmail");
			var process = processSchema.CreateProcess(user);
 
			process.SetPropertyValue(@"CaseId", caseId);
			process.Execute(user);
		}
	}
}

В бп:

using Terrasoft.Configuration.UsrUtilities

Вызов:

TestUtils.SendReminding(Guid.Parse(caseId.ToString()), userConnection);

"Варфоломеев Данила" написал:

Странно. А можете потестить вот так:

namespace Terrasoft.Configuration.UsrUtilities

{

        using System;

        using Core;

        using Common;

        using System.Web;

        using Core.Process;



        public static class TestUtils

        {

                public static void SendReminding(Guid caseId, UserConnection user)

                {

                        var processSchemaManager = (ProcessSchemaManager)user.GetSchemaManager(@"ProcessSchemaManager");



                        var processSchema = processSchemaManager.GetInstanceByName(@"UsrSendDeadlineEmail");

                        var process = processSchema.CreateProcess(user);



                        process.SetPropertyValue(@"CaseId", caseId);

                        process.Execute(user);

                }

        }

}

В бп:

using Terrasoft.Configuration.UsrUtilities

Вызов:

TestUtils.SendReminding(Guid.Parse(caseId.ToString()), userConnection);

Ошибка осталась в том же виде.

Добрый вечер, Дмитрий.

Ошибка System.NotImplementedException свидетельствует что Вы используете не верную реализацию класса.

Пример кода для запуска БП из скрипт таска:

var userConnection = Get<UserConnection>("UserConnection");
var manager = userConnection.ProcessSchemaManager;
var processSchema =  (ProcessSchema)manager.FindInstanceByName("SyncExchangeActivitiesProcess");
if (processSchema == null) 
{
	return true;
}
var moduleProcess = processSchema.CreateProcess(userConnection);
moduleProcess.Execute(userConnection);
return true;

"Мотков Илья" написал:

Добрый вечер, Дмитрий.

Ошибка System.NotImplementedException свидетельствует что Вы используете не верную реализацию класса.


Ваша реализация преполагает вообще не вызывать процесс, если процесс не является объектов класса ProcessSchema. Но это неправильно, БП должен запускаться, а не игнорироваться.
Я нашел данное решение:

	var processSchema = manager.GetInstanceByName("NrbSendDeadlineEmail");
	var flowEngine = new FlowEngine(userConnection);
	Dictionary<string, string> parameter = new Dictionary<string, string>();
	parameter.Add("Case", caseId.ToString());
	flowEngine.RunProcess(processSchema, parameter);

На данный момент, процесс запускает другой процесс, но не более 1 экземпляра, после чего отображает ошибку:

System.Data.SqlClient.SqlException (0x80131904): New transaction is not allowed because there are other threads running in the session

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

string userName = Get<string>("ManagerUserName"); //- Имя пользователя
var userConnection = Get<UserConnection>("UserConnection");
string schedulerJobGroupName = "MyProcessGroup";//- Любое имя группы
string jobProcessName = "MyBusinessProcess"; //- Название процесса
string schedulerJobName = "MyJobName"; //- Любое имя
 
IDictionary<string, object> parameters = new Dictionary<string, object>();
parameters["ContactNum"] = Get<string>("ContactNum");
parameters["ManagerNum"] = Get<string>("ManagerNum");
parameters["Direction"] = Get<string>("Direction");
 
AppScheduler.RemoveJob(schedulerJobName, schedulerJobGroupName);
AppScheduler.ScheduleImmediateProcessJob(schedulerJobName, schedulerJobGroupName, jobProcessName, userConnection.Workspace.Name, userName, parameters);
return true;
using Terrasoft.Core.Scheduler
using Quartz.Impl
using Quartz
using Quartz.Impl.Triggers

"Мотков Илья" написал:

Добрый вечер, Дмитрий.

Ошибка System.NotImplementedException свидетельствует что Вы используете не верную реализацию класса.

Пример кода для запуска БП из скрипт таска:

var userConnection = Get<UserConnection>("UserConnection");

var manager = userConnection.ProcessSchemaManager;

var processSchema =  (ProcessSchema)manager.FindInstanceByName("SyncExchangeActivitiesProcess");

if (processSchema == null)

{

        return true;

}

var moduleProcess = processSchema.CreateProcess(userConnection);

moduleProcess.Execute(userConnection);

return true;


7.10.1 проверено и не работает. Никаких ошибок нет, но не инициирует запуск передаваемого БП.

Проверил на 7.10.1 Отработали оба процесса. Столкнулся и с System.NotImplementedException. Ошибка возникает если вызываемый бизнес процесс не содержит элементов, требующих компиляции и решается установленным чекбоксом "Компилировать".

Вам же необходимо провести отладку, скорей всего условие processSchema == null выполняется и происходит выход из ScriptTask.

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

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

Добрый вечер, подскажите, пожалуйста, как можно реализовать задачу с помощью бизнес-процессов: допустим, если активность была создана в чт после 17:00, то установить время завершения активности и запуск блока “Изменить данные” на след. день на в 11:00.

Нравится

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

Мария, добрый день!
Для решения задачи вам помогут такие свойства:
https://msdn.microsoft.com/ru-ru/library/system.datetime.dayofweek(v=vs…
https://msdn.microsoft.com/en-us/library/system.datetime.minute(v=vs.11…
Можно разделить Дату создания на составляющие и записать результат в параметры процесса.
1. Первый параметр (условно CreatedOnDayOfWeek) будет хранить день недели, когда создана активность.
Примечание! Можно получить день недели в виде числа: Convert.ToInt32(currentDateTime.DayOfWeek), где вместо currentDateTime - подставить параметр с датой создания активности
2. Второй параметр (условно Hour) будет хранить час.

Дизайен процесса:
1. Стартовый сигнал по добвлению активности.
2. Читать данные в активности, где Id = Пункт 1. Id
После пунтк 2 добавить условный поток. В условном потоке проверять: (CreatedOnDayOfWeek ==4) && (Hour> 17)
3. Изменить данные в активности, где Id = Пункт 2. Id. Установить новую дату завершения

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

Добрый день!
Пользуемся Вашим продуктом (Sales) второй год, разрабатываем собственные схемы бизнес-процессов под нужды предприятия. Назрела проблема с отработкой бизнес-процессов пользователями, а именно в их желании вернуться на предыдущий этап (активность) в связи с тем, что завершили ее "случайно", либо ситуация требует корректировки бизнес-процесса "задним числом".
Можете поделиться какими-нибудь наработанными решениями по данному вопросу?
Нами было проработано два варианта решения задачи.
1. С помощью стадий, как в процессе «Управление лидом».
Выявленные минусы:
- отсутствие наглядности схемы бизнес-процесса, если процесс нелинейный
- при большом количестве стадий процесс становится трудоемким в разработке (стандартный процесс содержит 15-17 стадий-активностей)
2. Реализация возвратов на предыдущий этап с помощью соответствующего результата в Активности.
Выявленные минусы:
- утяжеление схемы бизнес-процесса из-за дополнительных связей
- необходимость дополнительных условий в случае, если процесс имеет несколько веток, в итоге соединяющихся в один результирующий элемент
- отсутствие возможности вернуться на любую стадию процесса
В идеале хотелось бы по сигналу запускать бизнес-процесс, который бы менял активный элемент в конкретном экземпляре уже запущенного бизнес-процесса. Однако возможно ли реализовать такой подход, чтобы при этом приложение работало стабильно?
P.S. прошу прощения, если подобный вопрос уже был. Если так, прошу указать на него ответ. Заранее спасибо.

Нравится

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

Катерина, здравствуйте!

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

Рекомендую углубится в первый предложенный вариант – “ 1. С помощью стадий, как в процессе «Управление лидом»”.
“стандартный процесс содержит 15-17 стадий-активностей” – разделить на несколько логических блоков. Каждый блок привязать к определенной стадии. Каждый блок в результате будет состоять условно из 3-4 активностей.
Далее реализовать один из подходов:
Вариант 1. С помощью модели: Один родительский процесс и множество подпроцессов. (пример – базовый процесс управления лидом).
Вариант 2. С помощью модели: Стартовый сигнал по изменению стадии – в конце БП изменять стадию на следующую.
Вариант 3. С помощью DCM/Кейс менеджмента (вариант доступен начиная с версии 7.9)

Такая модель, которая привязана к стадиям, позволяет:
1. Легко переключаться между стадиями. В результате не придётся проходить все этапы от создания записи до перевода в конечное состояние. Можно повторно продолжить с интересующего места, достаточно выбрать предыдущую стадию в дашборде или изменить вручную.
2. Легче отслеживать на каком этапе произошел сбой при выполнении.

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

Добрый день!

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

Спасибо

Нравится

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

Добрый!

Ниже метод реализующий отправку E-mail с вложением, файл берется из детали файлы и ссылки раздела.

		public static bool SendMail(string mailto, string caption, string message, Guid FileId, string SchemaName, UserConnection userConn) {
			SchemaName+="File";
			string smtpServer = Terrasoft.Core.Configuration.SysSettings.GetValue(userConn, "SFsmtpServer").ToString();
			string from = Terrasoft.Core.Configuration.SysSettings.GetValue(userConn, "SFFrom").ToString();
			string password = Terrasoft.Core.Configuration.SysSettings.GetValue(userConn, "SFPassword").ToString();
			Stream FileA = null;
			string Fname = "";
			var esq = new EntitySchemaQuery(userConn.EntitySchemaManager, SchemaName);
			esq.AddAllSchemaColumns();
			esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "Id",FileId));
			var coll = esq.GetEntityCollection(userConn);
			foreach(var ent in coll) {
				FileA = ent.GetStreamValue("Data");
				Fname = ent.GetTypedColumnValue<string>("Name");
				break;
			}
			try {
				MailMessage mail = new MailMessage();
				mail.From = new MailAddress(from);
				mail.To.Add(new MailAddress(mailto));
				mail.Subject = caption;
				mail.Body = message;
				mail.IsBodyHtml = true;
				if (FileA != null)
					mail.Attachments.Add(new Attachment(FileA, Fname));
				SmtpClient client = new SmtpClient();
				client.Host = smtpServer;
				client.Port = 587;
 
				client.EnableSsl = true;
				client.Credentials = new NetworkCredential(from.Split('@')[0], password);
				client.DeliveryMethod = SmtpDeliveryMethod.Network;
 
				client.Send(mail);
				mail.Dispose();
				return true;
			} catch(Exception e) {
				throw new Exception("Mail.Send: " + e.Message);
			}
		}
Показать все комментарии

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

Нравится

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

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

Как реализовать бизнес-процесс, при запуске которого будет открываться страница с проводником. В проводнике на ПК выбирается файл (txt , xls, xml). В результате появляется на странице содержимое файла.

Интересует программная реализация

BPMOnline 7.7

Нравится

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

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

Использование бизнес-процесса для решения данной задачи будет не самым оптимальным варинантом. Рекомендую Вам смотреть в сторону использования JavaScript кода для вызова "окна выбора" файла, саму же обработку файла реализовать в вэб сервисе.

Пример реализации Вы можете посмотреть в коде детали "Файлы и ссылки" (FileDetailV2). Так же обратите внимание на сервис FileApiService и схему FileUploader.

Если же данный функционал необходимо встроить в бизнес-процесс/, рекомендую Вам воспользоваться элементом бп "Преднастроенная страница".

"Мотков Илья" написал:

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

Использование бизнес-процесса для решения данной задачи будет не самым оптимальным варинантом. Рекомендую Вам смотреть в сторону использования JavaScript кода для вызова "окна выбора" файла, саму же обработку файла реализовать в вэб сервисе.

Пример реализации Вы можете посмотреть в коде детали "Файлы и ссылки" (FileDetailV2). Так же обратите внимание на сервис FileApiService и схему FileUploader.

Если же данный функционал необходимо встроить в бизнес-процесс/, рекомендую Вам воспользоваться элементом бп "Преднастроенная страница".


Здравствуйте.
Спасибо большое.

Подскажите, в коде детали "Файлы и ссылки" (FileDetailV2) есть строки :
/**
* Обработчик события нажатия кнопки "Добавить файл".
* @private
*/
onAddFileClick: Terrasoft.emptyFn,

Не совсем понятно что здесь происходит. А где конкретно описывается обработчик кнопки "Добавить файл" ? Чтобы я мог использовать листинг обработчика для своей кнопки.

Код onAddFileClick: Terrasoft.emptyFn добавляет заглушку (пустую функцию). Это нужно для того, что бы событие onClick кнопки не отрабатывало.

Обратите внимание на строки

"fileUpload": true,
"filesSelected": {"bindTo": "onFileSelect"},

в описании элемента AddRecordButton.

Первая добавляет окно вызова файла при клике, filesSelected - отрабатывает после выбора файла.

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

Уважаемые коллеги!

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

Нравится

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

Здравствуйте, Юрий!

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

Большое спасибо!

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

Когда начал применять Ваш совет, получилось следующее:
1. Страница обновилась и получился соответствующий результат - отлично, то что нам и нужно было!...
2. Но, активировалась задача, указанная в "Рекомендации по заполнению станицы" - эта активность нам не нужна...

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

Юрий, здравствуйте!

Элементы Вопрос пользователю/Страница редактирования при выполнении создают служебную активность, которая выполняет переадресацию пользователя на целевую страницу. Это базовый механизм работы процессов, изменить его не получится.
Примечание! Элемент “Страница редактирования” по умолчанию считается выполненным после того, как пользователь нажимает кнопку “Сохранить” на этой странице, иначе процесс не продолжит выполнение.

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

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

Юрий, добрый день!

Как вариант можно удалять служебную активность после выполнения элемента “Страница редактирования”. Например:
1. Элемент “Страница редактирования”.
2. Элемент “Удалить данные” в активностях, где Id = Пункт 1. Уникальный идентификатор активности

Большое спасибо, Олег!

Получилось!...

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

Здравствуйте, коллеги, подскажите, пожалуйста, как можно в запустить стандартный элемент процесса в цикле? Например есть коллекция e-mail и для каждого из них нужно выполнить стандартные элемент процесса "Создать задачу" или "Отправить е-mail"

Нравится

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

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

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