Добрый день!

При переходе с версии 7.15 на версию 7.16 возникли вопросы связанные с настройкой кластера kubernetes и Exchange Listener. Коллеги поделитесь своим опытом? обилие материалов в интернете не дает конкретного решения. На текущий момент создал 3 виртульные машины на Centos 8 (master+node1+node2), объединил ВМ в  кластер

есть вопросы по дальнейшим шагам :

1. по настройке Redis? интересен пример конфигурационного файла redis_deployment_name.

helm install --namespace  --set usePassword=false --set=slave.persistence.enabled=false --set master.persistence.enabled=false --set cluster.enabled=false  stable/redis

2. необходимо ли устанавливать Ingress и какой вариант более демократичен. 

Нравится

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

Здравствуйте, Игорь!



K8s развернул на одной VM по этой инструкции без Docker'а https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/c…



Redis вообще не разворачивал, использовал уже установленный на сервере, пока работает все.

Здравствуйте, Игорь!

 

Для отказоустойчивости Redis рекомендуется другой подход, Redis Sentinel.

 

А в целом по работе с Kubernetes рекомендуют доклады  Дмитрия Столярова, особенно этот.

Здравствуйте, Игорь!



K8s развернул на одной VM по этой инструкции без Docker'а https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/c…



Redis вообще не разворачивал, использовал уже установленный на сервере, пока работает все.

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

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

Всё компилил, рэдис чистил.

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

Нравится

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

Отключил в кейсах "использовать системный контекст безопасности" и всё заработало

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

 

Точно ли есть все стадии кейса и права доступа на них у обычного пользователя?

Под Supervisor тоже такая ошибка?

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

Приветствуют, коллеги.

Необходимо создать экземпляр UserConnection в Unit тестах, поиск привели меня к классу TestSystemUserConnection в пространстве имён Terrasoft.TestFramework. Только подключить пространство имён мне не удается в проекте тестов и с ошибкой тесты не запускаются. Кто нибудь сталкивался с такой проблемой?

Нравится

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

Линар, обратите внимание на тему «Тестирование работы запросов через AppConnection», там есть примеры кода тестов.

Нашёл в папке Terrasoft.WebApp\bin библиотеку Terrasoft.TestFramework.dll, подключил в проект тестов. Пространство имён подключилось, буду пока двигаться дальше

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

Создал миникарточку, опираясь на https://academy.terrasoft.ru/documents/technic-sdk/7-16/kak-sozdat-mini-kartochku-dobavleniya. Только в моём случае это было редактирование имени существующего объекта. 

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

onButtonClick: function () {
				debugger;
				var activeRowId = this.get("ActiveRow");
				if (activeRowId) {
					this.openMiniPage({
						recordId: activeRowId,
						operation: Terrasoft.ConfigurationEnums.CardOperation.EDIT,
						entitySchemaName: this.entitySchemaName,
						isFixed: true,
						showDelay: 0,
						miniPageSchemaName: "MyUsrMorpheusMiniPage",
					});
				}
			}

Вот код миникарточки, название сущности MyUsrCar2

define("MyUsrMorpheusMiniPage", [
	"terrasoft",
	"MyUsrCar2File",
	"ConfigurationConstants",
	"css!MyUsrMorpheusMiniPageCss"
], function (Terrasoft, MyUsrCar2File, ConfigurationConstants) {
	return {
		entitySchemaName: "MyUsrCar2",
		attributes: {
			"MiniPageModes": {
				"value": [this.Terrasoft.ConfigurationEnums.CardOperation.EDIT]
			}
		},
		methods: {},
		diff: [
			{
				"operation": "insert",
				"parentName": "MiniPage",
				"propertyName": "items",
				"name": "Name",
				"values": {
					"isMiniPageModelItem": true,
					"layout": {
						"column": 0,
						"row": 0,
						"colSpan": 24
					},
					"controlConfig": {
						"focused": true
					}
				}
			}
		]
	};
 
});

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

 

1. Заголовок для подписи "Name" не был найден.

2. Невозможно найти колонку по конфигурации: "{"layout":{"colSpan":24,"rowSpan":1,"column":0,"row":0},"controlConfig":{"focused":true},"name":"Name"}" .

 

3. MiniPageViewGenerator.js:308 Uncaught TypeError: Cannot read property 'name' of undefined

    at i.getNeedGenerateHyperLink (MiniPageViewGenerator.js:308)

core-base.js:704 user: Supervisor/7f3b869f-34f3-4f20-ab4d-7480a5fdf647

 file: http://localhost:82/0/configuration/6560b43f8738c260f612822f729cc099ru-…

 line: 308

 column: 82



 4. message: Uncaught TypeError: Cannot read property 'name' of undefined 

 date: Tue Jul 07 2020 11:19:54 GMT+0300 (Москва, стандартное время)

 stack: TypeError: Cannot read property 'name' of undefined

    at i.getNeedGenerateHyperLink

 

Пытался решить, как описано тут https://community.terrasoft.ua/questions/dobavlenie-email-kontakta-v-kartocku-obrasenia - не помогло.

Нравится

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

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

Там для других случаев есть статьи Создание мини-карточки и Добавление мини-карточки к произвольному модулю.

 

Судя по сообщению, ошибка в функции getNeedGenerateHyperLink в схеме MiniPageViewGenerator. Эта схема есть в конфигурации, её код виден:

/**
 * @private
 * @param {Object} clonedConfig
 * @returns {Boolean}
 */
getNeedGenerateHyperLink: function(clonedConfig) {
	var itemDataValueType = this.getItemDataValueType(clonedConfig);
	var viewModelColumn = this.findViewModelColumn(clonedConfig);
	var primaryDisplayColumnName = this.getPrimaryDisplayColumnName();
	var isEditable = this.isSchemaEditable(viewModelColumn);
	var isLookup = itemDataValueType === Terrasoft.DataValueType.LOOKUP;
	var isSimpleLookup = viewModelColumn && viewModelColumn.isSimpleLookup;
	var isPrimaryDisplayColumnName = primaryDisplayColumnName === viewModelColumn.name;
	return isPrimaryDisplayColumnName || (isLookup && isEditable && !isSimpleLookup);
 
},

Видимо, в третьей строчке в переменную viewModelColumn попадает не объект, а пустое или объект без свойства name, из-за чего третья с конца строка падает при обращении к нему.

 

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

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

Приветствую. Я новичок в Creatio. В мастере разделов создал развел с полями, которые имеют тип "Справочник". Но у созданных справочников есть дефолтные поля. как переопределить\добавить свои поля в справочнике?

Нравится

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

В конфигураторе найти объект справочника, добавить нужные поля

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

В конфигураторе найти объект справочника, добавить нужные поля

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

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

Добрый день.

Например имеется объект UsrEntity. Хочу открыть справочник для добавления элемента на деталь с возможностью выбора из списка этого объекта. Но, чтобы в списке НЕ БЫЛО тех элементов, которые удовлетворяют условию UsrEntity.UsrA in existedA && UsrEntity.UsrB in existedB && UsrEntity.UsrC in existedC. Пока вижу только один путь это создать представление в SQL и открывать это представление. А возможно ли сделать подобный фильтр на фронте? Может быть есть возможность сделать кастомный фильтр и вставить в конфиг при открытии справочника?

Нравится

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

Решил задачу. Можно же просто UsrEntity.UsrA not in existedA || UsrEntity.UsrB not in existedB || UsrEntity.UsrC not in existedC.

Но так как по колонке A, я уже фильтровал, достаточно было только B и C. А ещё засунул в группу фильтров, другую группу фильтров. Не знал, что так можно

addRecord: function () {
					let activeRowId = this.get("ActiveRow");
					if (!activeRowId) {
						return;
					}
 
					const gridData = this.getGridData();
					let rowData = gridData.get(activeRowId).values;
					if (rowData.IDSBParent){
						activeRowId = rowData.IDSBParent.value;
						rowData = gridData.get(activeRowId).values;
					}
 
					let filterCollection = Terrasoft.createFilterGroup();
					const productFilter = Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
						"IDSBProductId", rowData.IDSBProduct.value);
					filterCollection.add("productFilter", productFilter);					
 
					let existed = [];
					gridData.collection.items.forEach(function(item){
						if (!item.values.IDSBParent){
							return;
						}
 
						if (item.values.IDSBParent.value !== activeRowId){
							return;
						}
 
						existed.push(item.values);
					}, this);
 
					let notExistedFilterCollection = Terrasoft.createFilterGroup();
					notExistedFilterCollection.logicalComparisonTypes = Terrasoft.LogicalOperatorType.OR;
 
					let existsWarehouseFilter = Terrasoft.createColumnInFilterWithParameters("IDSBWarehouseId", existed.map(item => item.IDSBWarehouse.value));
					existsWarehouseFilter.comparisonType = Terrasoft.ComparisonType.NOT_EQUAL;
					notExistedFilterCollection.add(existsWarehouseFilter);
 
					let existsPercentFilter = Terrasoft.createColumnInFilterWithParameters("IDSBPercent", existed.map(item => item.IDSBPercent));
					existsPercentFilter.comparisonType = Terrasoft.ComparisonType.NOT_EQUAL;
					notExistedFilterCollection.add(existsPercentFilter);
 
					filterCollection.add("notExistedFilterCollection", notExistedFilterCollection);
 
					const config = {
						entitySchemaName: "IDSBVwExpiredRemaining",
						multiSelect: true,
						columns: ["IDSBWarehouseId", "IDSBProductId", "IDSBPercent"],
						filters: filterCollection
					};
 
					this.openLookup(config, this.IDSBAddSelectedProducts, this);
				},

 

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

Добрый день,

 

может кто-то уже сделал эту задачу. У меня есть 3 мультивалютных поля, взял пример BaseOrderPage,и https://academy.terrasoft.ru/documents/technic-sdk/7-16/dobavlenie-multivalyutnogo-polya. Но когда я меняю в одной поле, меняются все 3, но мне надо что бы у каждого поле было свое отдельное валюта. 

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

Нравится

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

Тот кто ищет - тот всегда найдет. Решение не мое, а найдено на просторах англоязычного community.

Суть в том, чтобы повторить логику для каждого из полей. Что делаем:

1. Заменяем prepareCurrencyMenu из MultiCurrencyEditUtilities

prepareCurrencyMenu: function() {
	this.mixins.MultiCurrencyEditUtilities.prepareCurrencyMenu.call(this);
	var currencyRateList = this.get("CurrencyRateList");
	if (!currencyRateList) {
		return;
	}
	var columnsList = ["NavDamageSize", "NavSumCurrency"];
	this.Terrasoft.each(columnsList, function(column) {
		var menu = this.Ext.create(this.Terrasoft.BaseViewModelCollection);
		currencyRateList.each(function(item) {
			var menuItem = Ext.create("Terrasoft.BaseViewModel", {
				values: {
					Id: item.value,
					Caption: item.Symbol || item.displayValue,
					MarkerValue: item.Symbol || item.displayValue,
					Tag: item.value,
					//Click: {"bindTo": "onCurrencyMenuItemClick"}
					Click: {"bindTo": "on" + column + "CurrencyMenuItemClick"}
				}
			});
			menu.addItem(menuItem);
		}, this);
		//this.set("CurrencyButtonMenuList", menu);
		this.set(column + "CurrencyButtonMenuList", menu);
	}, this);
},

2. делаем для каждого поля свой "on" + column + "CurrencyMenuItemClick" и column +"CurrencyButtonMenuList"

3. Переопределяем generateCurrencyButton из MultiCurrencyEditViewGenerator. я создал весьб свой класс на основе MultiCurrencyEditViewGenerator

generateCurrencyButton: function(config) {
	var buttonConfig = {
		id: "multiCurrencyButton-currency" + config.name,
		className: "Terrasoft.Button",
		classes: {
			wrapperClass: ["currency-button"]
		},
		style: Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
		menu: {
			//items: {"bindTo": "CurrencyButtonMenuList"}
			items: {"bindTo": config.name + "CurrencyButtonMenuList"}//
		},
		enabled: true,
        markerValue: config.name + " MultiCurrencyButton"
	};
	return this.generateButton(buttonConfig);
},

4. Виртуальную колонку Currency и её метод убираем.

Результат:

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

Минусы: потеряли треугольник у поля. По каким причинам не могу понять.

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

Я так полагаю проблема не в том, что на страницу добавлено одно кастомное поле валюта. Их скорее всего добавлено 3. А в том, что надо создавать виртуальную колонку Currency для совместимости с модулем MultiCurrencyEditUtilities.

Далее при инициализации страницы мы его заполняем. 

this.set("Currency", this.get("UsrCurrency"), {silent: true});

А Сама колонка Currency при изменении вызывает метод onVirtualCurrencyChange, который собственно меняет кастомное поле валюта.

onVirtualCurrencyChange: function() {
	var currency = this.get("Currency");
	this.set("UsrCurrency", currency);
}

Итого получаем, что для одного Мультивалютного поля все замечательно работает, а если их более одного, то как создавать поле Currency. 2 и более таких полей не создашь. 

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

Тот кто ищет - тот всегда найдет. Решение не мое, а найдено на просторах англоязычного community.

Суть в том, чтобы повторить логику для каждого из полей. Что делаем:

1. Заменяем prepareCurrencyMenu из MultiCurrencyEditUtilities

prepareCurrencyMenu: function() {
	this.mixins.MultiCurrencyEditUtilities.prepareCurrencyMenu.call(this);
	var currencyRateList = this.get("CurrencyRateList");
	if (!currencyRateList) {
		return;
	}
	var columnsList = ["NavDamageSize", "NavSumCurrency"];
	this.Terrasoft.each(columnsList, function(column) {
		var menu = this.Ext.create(this.Terrasoft.BaseViewModelCollection);
		currencyRateList.each(function(item) {
			var menuItem = Ext.create("Terrasoft.BaseViewModel", {
				values: {
					Id: item.value,
					Caption: item.Symbol || item.displayValue,
					MarkerValue: item.Symbol || item.displayValue,
					Tag: item.value,
					//Click: {"bindTo": "onCurrencyMenuItemClick"}
					Click: {"bindTo": "on" + column + "CurrencyMenuItemClick"}
				}
			});
			menu.addItem(menuItem);
		}, this);
		//this.set("CurrencyButtonMenuList", menu);
		this.set(column + "CurrencyButtonMenuList", menu);
	}, this);
},

2. делаем для каждого поля свой "on" + column + "CurrencyMenuItemClick" и column +"CurrencyButtonMenuList"

3. Переопределяем generateCurrencyButton из MultiCurrencyEditViewGenerator. я создал весьб свой класс на основе MultiCurrencyEditViewGenerator

generateCurrencyButton: function(config) {
	var buttonConfig = {
		id: "multiCurrencyButton-currency" + config.name,
		className: "Terrasoft.Button",
		classes: {
			wrapperClass: ["currency-button"]
		},
		style: Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
		menu: {
			//items: {"bindTo": "CurrencyButtonMenuList"}
			items: {"bindTo": config.name + "CurrencyButtonMenuList"}//
		},
		enabled: true,
        markerValue: config.name + " MultiCurrencyButton"
	};
	return this.generateButton(buttonConfig);
},

4. Виртуальную колонку Currency и её метод убираем.

Результат:

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

Минусы: потеряли треугольник у поля. По каким причинам не могу понять.

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

Здравствуйте! При выполнении любого запроса в SQL Executor на демостенде(тестдрайв) версии 7.16.0.4461 выдаётся ошибка.

Например делаю такой запрос:

select * from Contact

Сама ошибка такая:

Npgsql.PostgresException (0x80004005): 42P01: relation "contact" does not exist
at Npgsql.NpgsqlConnector.d__157.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Npgsql.NpgsqlConnector.d__156.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Npgsql.NpgsqlConnector.d__156.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Npgsql.NpgsqlConnector.d__163`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Npgsql.NpgsqlDataReader.d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Npgsql.NpgsqlDataReader.NextResult()
at Npgsql.NpgsqlCommand.d__71.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Npgsql.NpgsqlCommand.d__92.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at Polly.Policy.<>c__DisplayClass119_0`1.b__0(Context ctx, CancellationToken ct)
at Polly.Policy.<>c__DisplayClass129_0`1.b__0(Context ctx, CancellationToken ct)
at Polly.Policy.<>c__DisplayClass103_0.b__1(Context ctx, CancellationToken ct)
at Polly.NoOp.NoOpEngine.Implementation[TResult](Func`3 action, Context context, CancellationToken cancellationToken)
at Polly.Policy.<>c.b__103_0(Action`2 action, Context context, CancellationToken cancellationToken)
at Polly.Policy.ExecuteInternal[TResult](Func`3 action, Context context, CancellationToken cancellationToken)
at Polly.Policy.Execute[TResult](Func`3 action, Context context, CancellationToken cancellationToken)
at Polly.Policy.Execute[TResult](Func`1 action)
at Terrasoft.Core.DB.DBExecutor.FailoverExecuteReader(DbCommand command, Func`1 func)
at Terrasoft.Core.DB.DBExecutor.ExecuteCommand[TResult](Func`2 commandExecutionCallback, String sqlText, QueryParameterCollection queryParameters, CancellationToken cancellationToken)
at Terrasoft.Core.DB.DBExecutor.ExecuteReader(String sqlText, QueryParameterCollection queryParameters, CommandBehavior behavior, CancellationToken cancellationToken)
at Terrasoft.DB.PostgreSql.PostgreSqlExecutor.ExecuteReader(String sqlText, QueryParameterCollection queryParameters, CommandBehavior behavior, CancellationToken cancellationToken)
at Terrasoft.Core.DB.DBExecutor.ExecuteReader(String sqlText)
at Terrasoft.Configuration.SqlConsoleService.SqlConsoleService.ExecuteSqlScript(String sqlScript, Boolean logging)

В чём может быть проблема?

Нравится

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

Дополнение «SQL Executor» делается компанией «Программные Технологии», лучше уточнить у них. Судя по сообщению, у Вас демка на Postgres. Возможно, под эту базу ещё не адаптировали (хотя указано, что СУБД независимо) или просто в этой базе другой синтаксис выполнения запросов. Попробуйте название таблицы в кавычках.

 

И что за версия 4.16.0.4461, Вы имели в виду 7.16?

Дополнение «SQL Executor» делается компанией «Программные Технологии», лучше уточнить у них. Судя по сообщению, у Вас демка на Postgres. Возможно, под эту базу ещё не адаптировали (хотя указано, что СУБД независимо) или просто в этой базе другой синтаксис выполнения запросов. Попробуйте название таблицы в кавычках.

 

И что за версия 4.16.0.4461, Вы имели в виду 7.16?

Зверев Александр, ковычки помогли. Благодарю. С версией действительно ошибся. Уже исправил.

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

 

День добрый!

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

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

 

Собственно, вопросы следующие:

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

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

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

 

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

 

Версия 7.16.0.4461 (в списке версий не нашел)

Нравится

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

1) Да, мы выкладываем. Например, https://marketplace.terrasoft.ru/app/konnektor-k-onlayn-chatu-jivosite

2) Да, сможет. Вы в личном кабинете маркетплейса положите файлик с веб сервисом и инструкцией для саппорта.

3) Нет, вариантов других нет из-за авторизации

1) Да, мы выкладываем. Например, https://marketplace.terrasoft.ru/app/konnektor-k-onlayn-chatu-jivosite

2) Да, сможет. Вы в личном кабинете маркетплейса положите файлик с веб сервисом и инструкцией для саппорта.

3) Нет, вариантов других нет из-за авторизации

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

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

Использую для запуска БП ProcessModuleUtilities.executeProcess

Нужно подавить уведомление об успешном запуске.

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

Каким штатным образом это можно сделать? Параметр передать?

Нравится

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

Эта функция выглядит так:

/**
 * Launches business process by identifier or name.
 * @param {Object} config Configuration object.
 * @param {String} [config.sysProcessName] Name of the process schema.
 * @param {String} [config.sysProcessId] Unique identifier of the process schema.
 * @param {Object} [config.parameters] Process parameters.
 * @param {Function} [config.callback] Callback function.
 * @param {Object} [config.scope] Callback scope.
 */
executeProcess: function(config) {
	const callback = config.callback || this._executeProcessCallback.bind(this, config);
	const scope = config.scope || this;
	if (config.sysProcessName) {
		this._executeProcessByName(config, callback, scope);
	} else {
		this._executeProcessById(config, callback, scope);
	}
},

Она вызывает вторую, которая и показывает сообщение:

/**
 * @private
 */
_executeProcessCallback: function(config, request, success, response) {
	if (!this.responseCallback(request, success, response)) {
		this.loadSchemaCaptionByName(config.sysProcessName, function(caption) {
	this._showSuccessfullyRunProcessPopup(caption);
		}, this);
	}
},

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

То есть можно попробовать передать в параметре callback пустую функцию или с какими-то своими действиями. 

Пример вызова процесса с добавлением обработчика есть в схеме SystemDesigner, где он выглядит: 

/**
 * Starts OpportunityManagement actualization process.
 * @private
 */
runActualizeOpportunityManagementProcess: function(callback) {
	var processUtils = this.getProcessModuleUtilities();
	this.showBodyMask();
	processUtils.executeProcess({
		sysProcessName: "ActualizeOpportunityManagement",
		callback: function() {
			this.hideBodyMask();
			callback.call(this);
		},
		scope: this
	});
},

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

Эта функция выглядит так:

/**
 * Launches business process by identifier or name.
 * @param {Object} config Configuration object.
 * @param {String} [config.sysProcessName] Name of the process schema.
 * @param {String} [config.sysProcessId] Unique identifier of the process schema.
 * @param {Object} [config.parameters] Process parameters.
 * @param {Function} [config.callback] Callback function.
 * @param {Object} [config.scope] Callback scope.
 */
executeProcess: function(config) {
	const callback = config.callback || this._executeProcessCallback.bind(this, config);
	const scope = config.scope || this;
	if (config.sysProcessName) {
		this._executeProcessByName(config, callback, scope);
	} else {
		this._executeProcessById(config, callback, scope);
	}
},

Она вызывает вторую, которая и показывает сообщение:

/**
 * @private
 */
_executeProcessCallback: function(config, request, success, response) {
	if (!this.responseCallback(request, success, response)) {
		this.loadSchemaCaptionByName(config.sysProcessName, function(caption) {
	this._showSuccessfullyRunProcessPopup(caption);
		}, this);
	}
},

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

То есть можно попробовать передать в параметре callback пустую функцию или с какими-то своими действиями. 

Пример вызова процесса с добавлением обработчика есть в схеме SystemDesigner, где он выглядит: 

/**
 * Starts OpportunityManagement actualization process.
 * @private
 */
runActualizeOpportunityManagementProcess: function(callback) {
	var processUtils = this.getProcessModuleUtilities();
	this.showBodyMask();
	processUtils.executeProcess({
		sysProcessName: "ActualizeOpportunityManagement",
		callback: function() {
			this.hideBodyMask();
			callback.call(this);
		},
		scope: this
	});
},

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

Зверев Александр,не уверен , что так сработает, я делал , что в калл бэеке показывал маску, а сообщением по заверешению бп ее скрывал

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

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