Добрый день!

При вызове скрипта генерирования печатной формы в бизнес-процессе он падает с ошибкой:

System.NullReferenceException: Object reference not set to an instance of an object.

   at Terrasoft.Configuration.ReportService.ReportService.GetSchemaNameByTemplateId(Guid templateId)

Определили, что это возникает только когда бизнес-процесс вызывается сигналом или событием, т.е. только тогда когда процесс запускается от имени Supervisor. Запускаем вручную - всё работает отлично.

Вопросы: как можно заменить Supervisor на другого пользователя? Или может посоветуете как получить UserConnection другого пользователя для выполнения ReportService? Возможно ли обойтись в ReportService без UserConnection?

Спасибо!

Нравится

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

а как происходит инициализация ReportService в бп?

Ранее тема обсуждалась тут и тут. В ReportService в логике функций GenerateMSWordReport или GenerateDevExpressReport есть фрагменты, которые позволяют его запускать только при работе из браузера, но не в фоновом режиме с сервера, когда UserConnection нет. В комментариях один из участников рассказал, что в итоге переделал этот сервис, чтобы не использовать UserConnection. А другой предложил запускать от имени какого-то пользователя посредством ProcessEngineService, так работает нормально.

Варфоломеев Данила,

Процесс запускается через задание-сценарий вызовом 

GenerateMSWordReport, в который передаются параметры бизнес-процесса и UserConnection

 

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

Спасибо вам за информацию!

Мы заметили, что новый функционал в 7.13.2 "Фоновое выполнение операции" предназначен для запуска фоновых задач, которые требуют UserConnection. Я правильно понимаю, что с помощью этого функционала можно создать UserConnection для передачи в GenerateMSWordReport? (https://academy.terrasoft.ru/documents/technic-sdk/7-13/fonovoe-vypolne…)

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

и может вы знаете как на время изменить в процессе системную настройку текущего системного пользователя по умолчанию с Supervisor на другого пользователя, чтобы таким образом взять его UserConnection?

Дело не в том, что это конкретно Supervisor. Если под Supervisor зайти в систему и по действию построить отчёт, всё отработает.

Варианты по ссылкам предлагались ещё до появления 7.13.2, можете проверить и этот механизм.

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

Добрый день!

Установил расширение, которое по таймеру показывает всплывающие изображения (https://marketplace.terrasoft.ru/app/new-year-motivation-bpmonline)

Изменил скрипт, который сейчас показывает изображения пользователю, запустившему процесс:

var sender = "ShowImageScreen";

var userConnection = Get("UserConnection");

var messageText = string.Format("\"number\":{0}", UsrNumber.ToString());

messageText = '{' + messageText + '}';

            MsgChannelUtilities.PostMessage(userConnection, sender, messageText);

return true;

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

Заранее благодарю!

Нравится

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

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

В клиентском модуле необходимо подписаться на данное сообщение. Например данное сообщение необходимо выводить в карточке контакта ContactPageV2

Тогда в данном модуле необходимо прописать следующее:

 

define("ContactPageV2", [],
function() {
	return {
		entitySchemaName: "Contact",
		attributes: {},
		modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
		messages:{},
		methods: {
			init: function () {
				this.callParent(arguments);
				this.subscriptionFunction();
			},			
			subscriptionFunction: function() {
				this.callParent(arguments);
				Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
				this.onWebSocketListener, this);
			},
			onWebSocketListener: function(scope, message) {
				if (message && message.Header.Sender === "ShowImageScreen") {
					var message2 = message.Body;
					if (!this.Ext.isEmpty(message2)) {
						this.Terrasoft.showInformation(message2);
					}
					return;
				} 
			},
 
		},
		dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
	};
});

 

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

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

Насколько понимаю, MsgChannelUtilities.PostMessage взаимодействует только с текущим пользователем, выполняющим процесс. Ещё есть MsgChannelUtilities.PostMessageToAll(string sender, string message), см. обсуждение.

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

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

Столкнулся с такой проблемой при разработке в ФС сжирается все ОЗУ и ПК тупо зависает.

ОЗУ 16 Гб. При компиляции загружается под 100%. Где можно настроить ограничение ресурсов ОЗУ при компиляции?

Заранее благодарен.

Нравится

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

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

- ос

- версия нет фрєймворка

- версия sql сервера (для MS SQL то что возвращает select @version)

- как компилируете (если через VS то версия и обновления установленные) если через консоль то параметры и желательно логи компиляции

- какие доп сборки включены в конфигурацию

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

- ос

- версия нет фрєймворка

- версия sql сервера (для MS SQL то что возвращает select @version)

- как компилируете (если через VS то версия и обновления установленные) если через консоль то параметры и желательно логи компиляции

- какие доп сборки включены в конфигурацию

Григорий Чех,

ОС: Windows 10, версия 1803

.Net framework: http://prntscr.com/mpr4ys

версия sql сервера: Microsoft SQL Server 2016 (RTM) - 13.0.1601.5 (X64)   Apr 29 2016 23:23:58   Copyright (c) Microsoft Corporation  Enterprise Edition (64-bit) on Windows 10 Pro 6.3 <X64> (Build 17134: ) 

Компилировал и через VS и через конфигурацию, память загружается под 100%

 Сборки: Sales, Marketing, Service

 

Нажал публикацию объекта:

http://prntscr.com/mpruc6

данный процесс съедает почти 4 гб озу

У меня компилятор 3 Гб выедает. Но при 64-х воткнутых в сервер это не проблема :)

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

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

VBCSCompiler.exe — это компилятор от Microsoft. Сайт bpm'online его просто запускает с нужными параметрами.

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

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

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

Отключен файл подкачки т.к. использую SSD

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

Поставил файл подкачки проблема пропала

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

Добрый день!

Настроил систему на разработку в файловой системе. Все делал по инструкции с академии. Но при отладки когда проставляю точку останова то она не работает - http://prntscr.com/mon7s3

Второй метод дебага что описан в статье мне не подходит.

Подскажите из- за чего может быть такое поведение?

Заранее благодарен

Нравится

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

Как вариант - посмотреть настройки отладчика в VS.

 

 

Как вариант - посмотреть настройки отладчика в VS.

 

 

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

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

Столкнулся с проблемой интеграции с Google Analytics. Написал сервис с с ипользованием следующих библиотек - https://prnt.sc/mmm8kd

Но при вызове сервиса вываливаются следующие ошибки -https://prnt.sc/mmm98e

Я понял что идет конфликт встроенных библиотек Google и тех что добавили в кастомном пакете.

Что можете посоветовать? 

Нравится

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

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



Приносим свои извинения за неудобства. Версии библиотек Google API планировали обновлять с версии 7.13.0, но в результате тестирования возникли технические проблемы. На данный момент ответственная команда занимается решением  этого вопроса. Обновления версии библиотек Google API запланировано на ближайшие релизы.



Спасибо за понимание!

Мотков Илья,

Благодарю!

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

добрый день.

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

Например для конфигурационной единицы. Автоматически генерировать Название КЕ по формуле Тип КЕ + Производитель КЕ (собственное поле) + Модель КЕ. 

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

Подскажите в каком направлении идти.

Нравится

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

Это можно сделать с помощью зависимостей атрибутов. Более подробно посмотрите пример настройки вычисляемого поля на Академии.

Исходя из Ваших требований, вариант с БП не подойдет.

Это можно сделать с помощью зависимостей атрибутов. Более подробно посмотрите пример настройки вычисляемого поля на Академии.

Исходя из Ваших требований, вариант с БП не подойдет.

Что не работает. Сделал как описано в примере. Для начала решил сделать просто заполнение текстовым значением, потом переделать на заполнение значениями из справочника. Но даже так поле не заполняется. Что не так сделал?

define("ConfItemPage", [], function() {
	return {
		entitySchemaName: "ConfItem",
		attributes: {
			"EpmName": {
				dataValueType: Terrasoft.DataValueType.TEXT,
				dependencies: [
					{
						columns: ["TypeId", "ModelId", "EPMManufacturerId", "Name"],
						methodName: "generateNewName"
					}
					]
			}
		},
		methods: {
			onEntityInitialized: function() {
				this.callParent(arguments);
				this.generateNewName();
			},
			generateNewName: function() {
				var result = this.get("Name") + " Hello word!";
				this.set("EpmName", result);
			}
		},
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"name": "EpmName",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 5,
						"layoutName": "Header"
					},
					"bindTo": "EPMName",
					"labelConfig": {
						"caption": {
							"bindTo": "Resources.Strings.EpmNameCaption"
						}
					},
					"enabled": true
				},
				"parentName": "Header",
				"propertyName": "items"
			}
		]/**SCHEMA_DIFF*/
	};
});

 

Разобрался. 

В разделе attributes указывается поле страницы Оно у меня записано как EmpName

А вот в методе в строке this.set("EPMName", result); надо писать уже имя поля куда сохраняем значение bindTo. У меня было записано как имя поля EpmName.  А такого поля в схеме нет. Поменял на EPMName или все заработало.

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

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



Есть следующая ситуация:



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

Поэтому возникает необходимость актуализировать данные в карточке, к примеру, при помощи метода this.reloadEntity(), но непонятно как отправить message из БП в схему карточки и там уже запустить обновление.



Есть идеи?

Нравится

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

На сервере через Элемент скрипты делаете так:

 

string messageText = "{\"любой текст, если хотите\"}";
string sender = "NeedUpdatedGrid";
MsgChannelUtilities.PostMessageToAll(sender, messageText);

Затем создаете клиентский модуль, такого содержания:

 

define("ClientMessageBridge", ["ConfigurationConstants"],
function(ConfigurationConstants) {
    return {
        messages: {
            "NeedUpdatedGrid": {
                "mode": Terrasoft.MessageMode.BROADCAST,
                "direction": Terrasoft.MessageDirectionType.PUBLISH
            }
        },
        methods: {
            init: function() {
                this.callParent(arguments);
                this.addMessageConfig({
                    sender: "NeedUpdatedGrid",
                    messageName: "NeedUpdatedGrid"
                });
            },
            afterPublishMessage: function(
                sandboxMessageName,
                webSocketBody,
                result,
                publishConfig) {
                if (sandboxMessageName === "NeedUpdatedGrid") {
                    var name = webSocketBody.name;
                }
            }
        }
    };
});

А там, где хотите обновить грид, делаете так:

init: function() {
  this.callParent(arguments);
  this.sandbox.subscribe("NeedUpdatedGrid", this.myNameMethod, this);
},
myNameMethod: function(args) {
    this.reloadEntity();
}

Ну и соответственно не забудьте в схеме дописать 

блок messages, сообщение можете принимать как BROADCAST

 

На сервере через Элемент скрипты делаете так:

 

string messageText = "{\"любой текст, если хотите\"}";
string sender = "NeedUpdatedGrid";
MsgChannelUtilities.PostMessageToAll(sender, messageText);

Затем создаете клиентский модуль, такого содержания:

 

define("ClientMessageBridge", ["ConfigurationConstants"],
function(ConfigurationConstants) {
    return {
        messages: {
            "NeedUpdatedGrid": {
                "mode": Terrasoft.MessageMode.BROADCAST,
                "direction": Terrasoft.MessageDirectionType.PUBLISH
            }
        },
        methods: {
            init: function() {
                this.callParent(arguments);
                this.addMessageConfig({
                    sender: "NeedUpdatedGrid",
                    messageName: "NeedUpdatedGrid"
                });
            },
            afterPublishMessage: function(
                sandboxMessageName,
                webSocketBody,
                result,
                publishConfig) {
                if (sandboxMessageName === "NeedUpdatedGrid") {
                    var name = webSocketBody.name;
                }
            }
        }
    };
});

А там, где хотите обновить грид, делаете так:

init: function() {
  this.callParent(arguments);
  this.sandbox.subscribe("NeedUpdatedGrid", this.myNameMethod, this);
},
myNameMethod: function(args) {
    this.reloadEntity();
}

Ну и соответственно не забудьте в схеме дописать 

блок messages, сообщение можете принимать как BROADCAST

 

Литвинко Павел,

Спасибо, попробую.

А зачем эта функция?

afterPublishMessage: function(
                sandboxMessageName,
                webSocketBody,
                result,
                publishConfig) {
                if (sandboxMessageName === "NeedUpdatedGrid") {
                    var name = webSocketBody.name;
                }
                }

И модуль этой же функции должен от кого-то наследоваться?

Литвинко Павел,

На сервере через Элемент скрипты делаете так:

Под - "...Элемент скрипты..." , вы имели ввиду элемент задание сценарий?

Если это так, то следующий код там неприменим:

MsgChannelUtilities.PostMessageToAll(sender, messageText);

Так как объект MsgChannelUtilities отсутствует в данном контексте.

Андреев Андрей Сергеевич пишет:

Литвинко Павел,

На сервере через Элемент скрипты делаете так:

Под - "...Элемент скрипты..." , вы имели ввиду элемент задание сценарий?

Если это так, то следующий код там неприменим:

MsgChannelUtilities.<span>PostMessageToAll</span><span>(</span>sender, messageText<span>)</span><span>;</span>

Так как объект MsgChannelUtilities отсутствует в данном контексте.

ЕщеСвернуть

Да, задание сценарий 

Андреев Андрей Сергеевич пишет:

Литвинко Павел,

Спасибо, попробую.

А зачем эта функция?


 
afterPublishMessage: function(
                sandboxMessageName,
                webSocketBody,
                result,
                publishConfig) {
                if (sandboxMessageName === "NeedUpdatedGrid") {
                    var name = webSocketBody.name;
                }
                }

И модуль этой же функции должен от кого-то наследоваться?

https://academy.terrasoft.ua/documents/technic-sdk/7-13/clientmessagebr…;

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

Добрый день!

Создал шаблон email, при отправке коммерческого предложения данный шаблон подтягивается в следующем виде:

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

При нажатии на одну из ссылок (например, Тест) клиенту автоматически открывается ответное письмо по следующему шаблону:

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

Вопрос 1 - Как в шаблон ответного письма можно вставить макрос с номером заказа, чтобы при анализе входящего письма оно привязалось к заказу?

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

P.S. Вообще в принципе стоит цель создания в bpm sales функционала, подобному оценке удовлетворенности по шкале, который сейчас есть bpm service.

Нравится

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

Это обычная гиперссылка на URL «mailto:test@example.com?subject=sss&body=bbb», её обрабатывает выбранный на компьютере почтовый клиент. Формировать гиперссылки с макросами можно аналогично другим шаблонам со ссылкой (например, письмам с уведомлениями по инцидентам).

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

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

 

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

Александр, большое количество шаблонов перелопатил, но к сожалению, так и не понял, как формировать гиперссылку с макросом. Не могли бы вы написать пример?

В маркете есть БП, который для задач формирует письма-уведомления с гиперссылкой на их карточку. В стандартной версии нашёл подобный «Шаблон уведомления о новой визе счета (US)».

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

Понял, спасибо.

Это обычная гиперссылка на URL «mailto:test@example.com?subject=sss&body=bbb»

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

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

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

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

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

Коллегу, у меня такой вопрос.

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

Ну и вопрос в следующем, каким образом можно сделать подобный функционал в кастомном разделе и детали? Что бы при изменении карточки раздела происходила отправка сообщения во все карточки детали. Подписка в init в карточки детали (___productPage) не работает.

Нравится

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

Посмотрите в объекте Invoice процесс InvoiceSaving. В методе OnSaving устанавливается признак необходимости пересчета (при изменении курса).



А в процессе InvoiceSaved в методе OnSaved уже вызывается сам пересчёт

Посмотрите в объекте Invoice процесс InvoiceSaving. В методе OnSaving устанавливается признак необходимости пересчета (при изменении курса).



А в процессе InvoiceSaved в методе OnSaved уже вызывается сам пересчёт

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

Привет!

 

Подскажите как в схеме с типом "Исходный код" прочитать значение ключа, добавленного мной в web.config в раздел appSettings?

<appSettings>
    <add key="MyKey" value="MyValue" />
</appSettings>

 

Нравится

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

Попробуйте при помощи WebConfigurationManager.AppSettings или ConfigurationManager.AppSettings. Например, в схеме LDAPUtilities есть:

var timeout = WebConfigurationManager.AppSettings["RequestTimeout"];

 

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

да, 

WebConfigurationManager.AppSettings работает

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