Здравствуйте! Нужно добавить перенос строки в вручную заполненный строковый параметр, для того чтобы выводить в разных местах с этим переносом. Как можно это сделать? \n и
не работают

Нравится

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

Здравствуйте Андрей, обычный перенос текста делается следующим образом (в прикрепленных файлах пример), а более детальная информация находится по ссылке на Академии ( https://academy.terrasoft.ru/docs/user/biznes_processy/nastrojka_proces… ).

 

Если ваша бизнес-задача отличается от данного примера, опишите её более детальнее.

 

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

Ниже мы рассмотрим пример настройки процесса автоматической отправки письма с вложением с помощью бизнес-процесса. 

Для этого нам понадобятся два элемента процесса: “Обработать файл” и “Отправить Email”. 

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

С помощью элемента процесса «Обработать файл» мы можем вычитать из детали «Файлы и ссылки» раздела необходимые файлы. Либо же получить этот файл из параметра процесса или сгенерировать отчет. 

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

В элементе процесса «Отправить Email», помимо стандартных настроек (От кого – Кому, и т.д.), нас интересует поле «Добавить вложение». 

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



В данное поле мы и будем передавать полученный в элементе процесса «Обработать файл» файл в письмо. 

Перейдем к самому процессу. Например, нам необходимо отправить email с файлом, который находится в детали «Файлы и ссылки» из записи конкретного контакта.  

(о том как запустить процесс из раздела подробно тут

В элементе процесса «Обработать файл» мы указываем источник, откуда мы получаем файл. В нашем примере это деталь «Файлы и ссылки» объекта. 

После указываем этот самый объект: Файл и ссылка контакта, в нашем случае. 

Далее настраиваем фильтр для файла и указываем, как и по какой колонке сортировать записи. 

После выбираем какие действия мы будем выполнять далее с  отфильтрованным файлом: используем далее в процессе (наш вариант) или сохраняем на деталь «Файлы и ссылки» другого раздела. 

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

Далее, в элементе «Отправить email» мы настраиваем все необходимые параметры (от кого, кому, письмо по шаблону или произвольное и т.д.). После чего в поле «Добавить вложение» мы можем указать файл вычитанный в элементе «Обработать файл». 

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

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

Во вложении архив с описанным процессом.

Прикрепленные файлы

Нравится

Поделиться

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

Добрый день. Как создать бизнес процесс, который должен

открывать страницу новой записи в разделе и контролировать заполнены ли нужные поля в этой записи. (Без программирования). Я поняла, что нудно использовать элемент процесс "открыть страницу редактирования", но как контролировать заполнение нужных полей не понимаю.

 

Нравится

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

Попробуйте сделать так. Мне кажется должно сработать.

сделать эти поля обязательными , например

Попробуйте сделать так. Мне кажется должно сработать.

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

Добрый день. Помогите, пожалуйста!

При сохранении БП происходит бесконечная загрузка, при этом в консоли ошибки:

 

Uncaught DOMException: An attempt was made to use an object that is not, or is no longer, usable

 

user: Supervisor/7f3b869f-34f3-4f20-ab4d-7480a5fdf647

 file: http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

 line: 1201

 column: 0

 message: InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable

 date: Fri Jun 18 2021 14:29:12 GMT+0300 (Москва, стандартное время)

 stack: postMessage@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

callParent@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

postMessage@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

broadcastMessage@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

notify@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

onItemOutdated@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

saveProcess/<@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

save/<@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

f@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

applyChanges/<@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

callback@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

execute/<@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

callback@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

request/a.callback@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

callback@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

onComplete@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

onStateChange@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

bind/<@http://localhost/core/c575be1671135885e206c91cbf6b363b/combined/all-com…

 

Как можно решить данную проблему? Спасибо.

Нравится

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

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

в таких случаях помогает генерация исходного кода для бп

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

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

 

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

 

Заранее спасибо за помощь!

Нравится

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

Добрый день,

 

Как в БП с помощью элемента Изменить данные внести уникальные изменения в несколько уникальных записей, или каким иным элементом следует воспользоваться? 

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



"Для выполнения разных изменений в разных записях используйте несколько элементов [ Изменить данные ]. - таких уникальных записей будет 20-30 + со временем могут добавляться новые, прописывать вручную параметры каждой не вариант.

Нравится

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

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

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

 

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

 

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

Алексей Следь,

Добрый день,

 

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

Екатерина Пильгук,

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

Алексей Следь,



Спасибо, попробую сделать так.

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

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

 

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

Какие есть варианты решения данного вопроса и можно ли это сделать стандартными средствами предоставляемые Studio?

 

Заранее спасибо!

Нравится

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

Mykhailo Kozlenko,

Добрый день.

Можно в элементе 'Задание-сценарий' сформировать таблицу, которую нужно отправлять, и записать её в параметр бизнес-процесса. Например, я делала вот таким образом:

const string quote = "\"";
const string siteRef = "http://site_name";
 
var userConnection = Get&lt;UserConnection&gt;("UserConnection");
var softwareInventoryTableHTML = String.Empty;
 
var esqSoftwareInventory = new EntitySchemaQuery(userConnection.EntitySchemaManager, "SoftwareInventory");
esqSoftwareInventory.AddColumn("Id");
esqSoftwareInventory.AddColumn("Number");
esqSoftwareInventory.AddColumn("Software.Name");
esqSoftwareInventory.AddColumn("LicenseKey.Name");
var expirationDateColumn = esqSoftwareInventory.AddColumn("LicenseExpirationDate");
expirationDateColumn.OrderDirection = OrderDirection.Ascending;
expirationDateColumn.OrderPosition = 1;
esqSoftwareInventory.AddColumn("Equipment.Name");
esqSoftwareInventory.AddColumn("Equipment.Id");
esqSoftwareInventory.Filters.Add(esqSoftwareInventory.CreateFilterWithParameters(FilterComparisonType.Equal,
	"LicenseStatus", new Guid("CDD71003-D5BB-43E7-8E06-280FE40BEBF8")));
DateTime dueDate = DateTime.Today.AddMonths(2);
esqSoftwareInventory.Filters.Add(esqSoftwareInventory.CreateFilterWithParameters(FilterComparisonType.Less,
	"LicenseExpirationDate", dueDate));
var softwareInventories = esqSoftwareInventory.GetEntityCollection(userConnection);
if (softwareInventories.Count &gt; 0)
{
	var htmlTableBuilder = new StringBuilder();
	htmlTableBuilder.AppendLine("&lt;table border='1' width='100%' cellpadding='5'&gt;");
	var headerSB = new StringBuilder();
	headerSB.Append("&lt;tr&gt;");
	string[] columnNames = { "Номер", "Программное обеспечение", "Лицензионный ключ", "Дата окончания лицензии",
		"Оборудование" };
	foreach (string columnName in columnNames)
	{
		headerSB.Append("&lt;td&gt;" + columnName + "&lt;/td&gt;");
	}
    headerSB.Append("&lt;/tr&gt;");
    htmlTableBuilder.AppendLine(headerSB.ToString());
	foreach (var softwareInventory in softwareInventories)
	{
		var rowSB = new StringBuilder();
		rowSB.Append("&lt;tr&gt;");
		string Number = softwareInventory.GetTypedColumnValue&lt;string&gt;("Number");
		Guid recordId = softwareInventory.GetTypedColumnValue&lt;Guid&gt;("Id1");
		string softwareInventoryRef = siteRef + "/0/Nui/ViewModule.aspx#CardModuleV2/SoftwareInventory1Page/edit/" +
			recordId.ToString();
		string inventoryNumberRef = "&lt;a href=" + quote + softwareInventoryRef + quote +"&gt;" + Number + "&lt;/a&gt;";
		rowSB.Append("&lt;td width=\"44\"&gt;" + inventoryNumberRef + "&lt;/td&gt;");
		rowSB.Append("&lt;td width=\"120\"&gt;" + softwareInventory.GetTypedColumnValue&lt;string&gt;("Software_Name") + "&lt;/td&gt;");
		string licenseKey = softwareInventory.GetTypedColumnValue&lt;string&gt;("LicenseKey_Name");
		int licenseKeyLength = licenseKey.Length;
		int indexStr = 8;
		if (licenseKeyLength &lt;= 8)
		{
			indexStr = licenseKeyLength;
		}
		rowSB.Append("&lt;td width=\"110\"&gt;" + licenseKey.Substring(0, indexStr) + "&lt;/td&gt;");
		DateTime licenseExpirationDate = softwareInventory.GetTypedColumnValue&lt;DateTime&gt;(expirationDateColumn.Name);
		string licenseExpirationDateStr = "";
		if (licenseExpirationDate != DateTime.MinValue) {
			licenseExpirationDateStr = licenseExpirationDate.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture);
		}
		rowSB.Append("&lt;td width=\"83\"&gt;" + licenseExpirationDateStr + "&lt;/td&gt;");
		rowSB.Append("&lt;td width=\"106\"&gt;" +	softwareInventory.GetTypedColumnValue&lt;string&gt;("Equipment_Name") + "&lt;/td&gt;");
		rowSB.Append("&lt;/tr&gt;");
 
        htmlTableBuilder.AppendLine(rowSB.ToString());
	}
	htmlTableBuilder.AppendLine("&lt;/table&gt;");	
	softwareInventoryTableHTML = htmlTableBuilder.ToString();
}
Set&lt;string&gt;("SoftwareInventoryTableHTML", softwareInventoryTableHTML);
return true;

А потом этот параметр бизнес-процесса использовать в элементе 'Отправить email' в качестве макроса:

Обратите внимание, по данному программному обеспечению истек срок действия лицензии либо истечет в ближайшее время.
Пожалуйста, актуализируйте в срм информацию по этому ПО:
[#Software inventory table#]
 
С уважением,
Системный администратор crm

 

P.S. В скрипте, приведенном выше, ещё и гиперссылки на карточки сущностей в срм формируются.

 

 

 

 

Добрый день.

 

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

Добрый! Кроме данного дополнения больше никаких вариантов нет? Ибо при попытке работать с данным расширением оказалось, что оно не совсем рабочее. 

Mykhailo Kozlenko,

Добрый день.

Можно в элементе 'Задание-сценарий' сформировать таблицу, которую нужно отправлять, и записать её в параметр бизнес-процесса. Например, я делала вот таким образом:

const string quote = "\"";
const string siteRef = "http://site_name";
 
var userConnection = Get&lt;UserConnection&gt;("UserConnection");
var softwareInventoryTableHTML = String.Empty;
 
var esqSoftwareInventory = new EntitySchemaQuery(userConnection.EntitySchemaManager, "SoftwareInventory");
esqSoftwareInventory.AddColumn("Id");
esqSoftwareInventory.AddColumn("Number");
esqSoftwareInventory.AddColumn("Software.Name");
esqSoftwareInventory.AddColumn("LicenseKey.Name");
var expirationDateColumn = esqSoftwareInventory.AddColumn("LicenseExpirationDate");
expirationDateColumn.OrderDirection = OrderDirection.Ascending;
expirationDateColumn.OrderPosition = 1;
esqSoftwareInventory.AddColumn("Equipment.Name");
esqSoftwareInventory.AddColumn("Equipment.Id");
esqSoftwareInventory.Filters.Add(esqSoftwareInventory.CreateFilterWithParameters(FilterComparisonType.Equal,
	"LicenseStatus", new Guid("CDD71003-D5BB-43E7-8E06-280FE40BEBF8")));
DateTime dueDate = DateTime.Today.AddMonths(2);
esqSoftwareInventory.Filters.Add(esqSoftwareInventory.CreateFilterWithParameters(FilterComparisonType.Less,
	"LicenseExpirationDate", dueDate));
var softwareInventories = esqSoftwareInventory.GetEntityCollection(userConnection);
if (softwareInventories.Count &gt; 0)
{
	var htmlTableBuilder = new StringBuilder();
	htmlTableBuilder.AppendLine("&lt;table border='1' width='100%' cellpadding='5'&gt;");
	var headerSB = new StringBuilder();
	headerSB.Append("&lt;tr&gt;");
	string[] columnNames = { "Номер", "Программное обеспечение", "Лицензионный ключ", "Дата окончания лицензии",
		"Оборудование" };
	foreach (string columnName in columnNames)
	{
		headerSB.Append("&lt;td&gt;" + columnName + "&lt;/td&gt;");
	}
    headerSB.Append("&lt;/tr&gt;");
    htmlTableBuilder.AppendLine(headerSB.ToString());
	foreach (var softwareInventory in softwareInventories)
	{
		var rowSB = new StringBuilder();
		rowSB.Append("&lt;tr&gt;");
		string Number = softwareInventory.GetTypedColumnValue&lt;string&gt;("Number");
		Guid recordId = softwareInventory.GetTypedColumnValue&lt;Guid&gt;("Id1");
		string softwareInventoryRef = siteRef + "/0/Nui/ViewModule.aspx#CardModuleV2/SoftwareInventory1Page/edit/" +
			recordId.ToString();
		string inventoryNumberRef = "&lt;a href=" + quote + softwareInventoryRef + quote +"&gt;" + Number + "&lt;/a&gt;";
		rowSB.Append("&lt;td width=\"44\"&gt;" + inventoryNumberRef + "&lt;/td&gt;");
		rowSB.Append("&lt;td width=\"120\"&gt;" + softwareInventory.GetTypedColumnValue&lt;string&gt;("Software_Name") + "&lt;/td&gt;");
		string licenseKey = softwareInventory.GetTypedColumnValue&lt;string&gt;("LicenseKey_Name");
		int licenseKeyLength = licenseKey.Length;
		int indexStr = 8;
		if (licenseKeyLength &lt;= 8)
		{
			indexStr = licenseKeyLength;
		}
		rowSB.Append("&lt;td width=\"110\"&gt;" + licenseKey.Substring(0, indexStr) + "&lt;/td&gt;");
		DateTime licenseExpirationDate = softwareInventory.GetTypedColumnValue&lt;DateTime&gt;(expirationDateColumn.Name);
		string licenseExpirationDateStr = "";
		if (licenseExpirationDate != DateTime.MinValue) {
			licenseExpirationDateStr = licenseExpirationDate.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture);
		}
		rowSB.Append("&lt;td width=\"83\"&gt;" + licenseExpirationDateStr + "&lt;/td&gt;");
		rowSB.Append("&lt;td width=\"106\"&gt;" +	softwareInventory.GetTypedColumnValue&lt;string&gt;("Equipment_Name") + "&lt;/td&gt;");
		rowSB.Append("&lt;/tr&gt;");
 
        htmlTableBuilder.AppendLine(rowSB.ToString());
	}
	htmlTableBuilder.AppendLine("&lt;/table&gt;");	
	softwareInventoryTableHTML = htmlTableBuilder.ToString();
}
Set&lt;string&gt;("SoftwareInventoryTableHTML", softwareInventoryTableHTML);
return true;

А потом этот параметр бизнес-процесса использовать в элементе 'Отправить email' в качестве макроса:

Обратите внимание, по данному программному обеспечению истек срок действия лицензии либо истечет в ближайшее время.
Пожалуйста, актуализируйте в срм информацию по этому ПО:
[#Software inventory table#]
 
С уважением,
Системный администратор crm

 

P.S. В скрипте, приведенном выше, ещё и гиперссылки на карточки сущностей в срм формируются.

 

 

 

 

Я однажды делал подобное следующим образом:

в БП в элементе "Задание-сценарий" вычитывал в коллекцию какие-то значения.

После кодом формировал html-код в виде:

<table>

<tbody>

  <tr>

    <td >Номер</td>

    <td >Колонка 1</td>

    <td >Колонка 2</td>

  </tr>

  <tr>

    <td >1</td>

    <td >Значение 1</td>

    <td >Значение 2</td>

  </tr>

</tbody>

</table>

где Значение 1 и Значение 2 значения из коллекции.

После использовал элемент БП "Отправка письма", где в тело подсовывал html-код в виде строки.

После отправки получатель увидит заполненную html-таблицу

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

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

 

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

 

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

 

Может где-то есть настройки работы таймера, чтобы проверить, все ли корректно работает и сравнить с тестовой платформой? Заранее благодарю!

Нравится

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

Я бы посмотрел в сторону Quartz, возможно с ним какие-то проблемы https://academy.terrasoft.ru/docs/developer/elements_and_components/qua…

 

Для начала увеличить значение в веб конфигах на более высокое (по умолчанию там 5), затем перезапустить iis.

<add key="quartz.threadPool.threadCount" value="5" />

Добрый день, коллеги.

Есть вероятность что таймеры попадают на то время когда пул приложения спит, тут может помочь настройка согласно публикации https://community.terrasoft.ru/articles/bespereboynaya-rabota-zadaniy-q…

 

Но в целом что стоит сравнить так это внешний Web.config с обеих сред. Возможно достаточно будет их заполнить одинаково, или если у вас на прод среде в разы больше задач для Quartz может понадобится настройка согласно статье https://academy.terrasoft.ru/docs/7-17/developer/elements_and_component…

 

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

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

Добрый день!



Два вопроса по таймеру в процессах:



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



2. Можно ли задавать время запуска в системных настройках?

Нравится

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

Настройки для работы системы берутся из настроек ОС где устанавливается система и настроек часового пояса в ней. Так как в большинстве случаев администраторы ОС пренебрегают настройками часового пояса при установке системы, то я бы посоветовал обратить внимание для начала туда. А настройка часового пояса по умолчанию производится в системной настройке "Часовой пояс по умолчанию", но она все же больше сделана для настройки работы календаря и связанных с ней частей системы.

А зачем тогда настройка часового пояса в стартовом сигнале процесса Timer?

 

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

Добрый день!

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

 

Подобные примеры доступны в статьях на академии: 

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

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

Добрый день.

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

Т. е. при вхождении в него 2 и более активированных ветвей,  он ожидает завершение первой пришедшей ветки. 

Ожидаемое поведение (цитата из Википедии):

  • Оператор включающего «или» (inclusive gateway) активирует одну или более исходящих ветвей, в случае, когда осуществляется ветвление. Если оператор используется для синхронизации, то он ожидает завершения выполнения всех активированных ветвей и активирует выходной поток.
  • Оператор исключающего «или», управляемый данными (англ. data-based exclusive gateway). Если оператор используется для ветвления, то поток управления направляется лишь по одной исходящей ветви. Если оператор используется для синхронизации, то он ожидает завершения выполнения одной входящей ветви и активирует выходной поток.

Ниже привожу пример БП.

Прикрепленные файлы

Нравится

Поделиться

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