Вопрос

Добрый день. В клиентской схеме реализована фильтрация при помощи бизнес-правила. Например:

"RegionType": {
	"FiltrationRegionType": {
	ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
	autocomplete: true,
	autoClean: true,
	baseAttributePatch: "Level",
	comparisonType: Terrasoft.ComparisonType.EQUAL,
	type: BusinessRuleModule.enums.ValueType.CONSTANT,
        value: 1
	},

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

Существуют ли соответствующие параметры бизнес-правила?

У меня такой же вопрос

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

Здравствуйте! Вам необходимо самим написать бизнес правило типа FILTRATION и фильтровать по значению Id. Как работать с данным правилом описано в данной статье: https://academy.terrasoft.ru/documents/technic-sdk/7-14/primer-primeneniya-pravila-filtration

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

Добрый день!

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

У меня такой же вопрос

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

Данное поведение реализовано в последних версиях bpmonline, вы можете обновится.

Если нет возможности обновится то ищите в стилях  что то типа:

.grid-listed-row div {
	white-space: nowrap;
	text-overflow: ellipsis;
	overflow: hidden;
}

и убирайте (переопределяйте) для вашей страницы

Данное поведение реализовано в последних версиях bpmonline, вы можете обновится.

Если нет возможности обновится то ищите в стилях  что то типа:

.grid-listed-row div {
	white-space: nowrap;
	text-overflow: ellipsis;
	overflow: hidden;
}

и убирайте (переопределяйте) для вашей страницы

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

Подскажи, пожалуйста, с какой версии доступен этот функционал?

С 7.14:

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

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

Спасибо.

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

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

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

this.set("Country", {value: "a570b005-e8bb-df11-b00f-001d60e938c6", displayValue: "РОССИЯ"});

В результате значение поля выбора принимает соответствующее значение.

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

Понятно, что можно принудительно назначить атрибуту больше значений, но можно ли каким-то образом восстановить выбор значения из справочника по одному Guid ? Скажем, я знаю, что Guid нужной мне страны такой то. Я пишу что-то вроде this.set("Country, {value: такой-то}), и получаю доступ к любым строкам записи справочника?

У меня такой же вопрос

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

Добрый день.
Если я правильно понял, вам могут помочь две вещи:
1) Укажите в атрибутах колонки справочника, которые вам необходимы:

"Country": {
    "lookupListConfig": {
         "columns": ["Name", "CreatedOn", "CreatedBy"]
    }
}

2) Используйте метод loadLookupDisplayValue для установки справочных значений.

this.loadLookupDisplayValue("Country", valueId);

 

Добрый день!
Нет, предложенный вами способ не сработает.
Необходимо делать запрос в базу данных и вытаскивать атрибуты объекта.
Пример запроса:

var esqContract = Ext.create("Terrasoft.EntitySchemaQuery", {
	rootSchemaName: "Contract"
});
esqContract.addColumn('CreatedOn');
esqContract.addColumn('SignedOn');
 
esqContract.getEntity(contractId, function(responseContract)
{
	var createdOn = responseContract.entity.get('CreatedOn');
}, scope);

 

Добрый день.
Если я правильно понял, вам могут помочь две вещи:
1) Укажите в атрибутах колонки справочника, которые вам необходимы:

"Country": {
    "lookupListConfig": {
         "columns": ["Name", "CreatedOn", "CreatedBy"]
    }
}

2) Используйте метод loadLookupDisplayValue для установки справочных значений.

this.loadLookupDisplayValue("Country", valueId);

 

Сизов Андрей Андреевич,

доброе утро! Этого метода:

this.loadLookupDisplayValue("Country", valueId);

будет достаточно, чтобы заполнить все выбранные для атрибута колонки (в вашем случае "Name", "CreatedOn", "CreatedBy"), или он позволяет получить только displayValue по valueId?

Developer76,

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

 

Сизов Андрей Андреевич,

спасибо!

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

Здравствуйте, возможно ли открыть страницу записи детали по URL ссылке, используя Id записи?

Проблема, на странице редактирования "Контакта" есть деталь, хотелось бы получить url записей этой детали, при открытии детали в адресной строке браузера по прежнему такое 

http://[someSite]/Nui/ViewModule.aspx#CardModuleV2/ContactPageV2/edit/a36a54a2-3c6c-44eb-aa2f-a7e75305270a , 

не url детали.

Спасибо

У меня такой же вопрос

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

Добрый день!
Да, BPM не меняет адрес в адресной строке.
Адрес записи детали будет следующим:
ttp://[someSite]/Nui/ViewModule.aspx#CardModuleV2/[Страница редактирования записи детали]/edit/[Id записи детали]

Добрый день!
Да, BPM не меняет адрес в адресной строке.
Адрес записи детали будет следующим:
ttp://[someSite]/Nui/ViewModule.aspx#CardModuleV2/[Страница редактирования записи детали]/edit/[Id записи детали]

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

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

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

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

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

Вызываю обычный сервис так:

ServiceHelper.callService("ServiceName", "ServiceMethodPost", function(response) {
	window.console.log(response);
}, serviceData, this);

 

У меня такой же вопрос

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

Сериков Асхат Кайратович,
Данный вариант правильный

var config = {
		serviceName: "ServiceName",
		timeout: 100000
	};
var serviceData = {
	phoneNumber: phoneNumber ? phoneNumber : "",
	userName: contact.displayValue,
	email: email ? email : ""
};
ServiceHelper.callService(config, "ServiceMethodPost",  function(response) {
	window.console.log(response);
}, serviceData, this);

Логика ServiceHelper выглядит так:

define("ServiceHelper", ["ext-base", "terrasoft"], function(Ext, Terrasoft) {
 
	/**
	 * ######## ##### ###-#######.
	 * @param {String|Object} config ### ####### ### ######### ###### #######.
	 * @param {String} methodName ### ######.
	 * @param {Function} callback (optional) ####### ######### ######.
	 * @param {Object} data (optional) ###### # ####### #######.
	 * @param {Object} scope (optional) ######## ######.
	 * @return {Object} ######### #######.
	 */
	function internalCallService(config, methodName, callback, data, scope) {
		var serviceName;
		if (config && Ext.isObject(config)) {
			serviceName = config.serviceName;
			methodName = config.methodName;
			callback = config.callback;
			data = config.data;
			scope = config.scope;
		} else {
			serviceName = config;
		}
		var dataSend = data || {};
		var workspaceBaseUrl = Terrasoft.utils.uri.getConfigurationWebServiceBaseUrl();
		var requestUrl = workspaceBaseUrl + "/rest/" + serviceName + "/" + methodName;
		var requestConfig = {
			url: requestUrl,
			headers: {
				"Accept": "application/json",
				"Content-Type": "application/json"
			},
			method: "POST",
			jsonData: Ext.encode(dataSend),
			callback: function(request, success, response) {
				if (!callback) {
					return;
				}
				var responseObject = response;
				if (success) {
					responseObject = Terrasoft.decode(response.responseText);
				}
				callback.call(this, responseObject, success);
			},
			scope: scope || this
		};
		if (config && config.timeout) {
			requestConfig.timeout = config.timeout;
		}
		return Terrasoft.AjaxProvider.request(requestConfig);
	}
 
	return {
		callService: internalCallService
	};
});

 

Добрый день!
Timeout указывается в конфиге вызова сервиса (параметр timeout).
В вашем случае будет так:

var config = {
		serviceName: "ServiceName",
		timeout: 100000
	};
ServiceHelper.callService(config, "ServiceMethodPost",  function(response) {
	window.console.log(response);
}, serviceData, this);

 

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

var serviceData = {
	phoneNumber: phoneNumber ? phoneNumber : "",
	userName: contact.displayValue,
	email: email ? email : ""
};
ServiceHelper.callService("ServiceName", "MethodName", function(response) {
	window.console.log(response);
}, serviceData, this);

В моем случае в serviceData есть другие параметры веб сервиса, их нужно будет в отдельный объект выложить? Не совсем понимаю как БПМ определит что является обычным параметром, а что конфигурационным

Сериков Асхат Кайратович,
Данный вариант правильный

var config = {
		serviceName: "ServiceName",
		timeout: 100000
	};
var serviceData = {
	phoneNumber: phoneNumber ? phoneNumber : "",
	userName: contact.displayValue,
	email: email ? email : ""
};
ServiceHelper.callService(config, "ServiceMethodPost",  function(response) {
	window.console.log(response);
}, serviceData, this);

Логика ServiceHelper выглядит так:

define("ServiceHelper", ["ext-base", "terrasoft"], function(Ext, Terrasoft) {
 
	/**
	 * ######## ##### ###-#######.
	 * @param {String|Object} config ### ####### ### ######### ###### #######.
	 * @param {String} methodName ### ######.
	 * @param {Function} callback (optional) ####### ######### ######.
	 * @param {Object} data (optional) ###### # ####### #######.
	 * @param {Object} scope (optional) ######## ######.
	 * @return {Object} ######### #######.
	 */
	function internalCallService(config, methodName, callback, data, scope) {
		var serviceName;
		if (config && Ext.isObject(config)) {
			serviceName = config.serviceName;
			methodName = config.methodName;
			callback = config.callback;
			data = config.data;
			scope = config.scope;
		} else {
			serviceName = config;
		}
		var dataSend = data || {};
		var workspaceBaseUrl = Terrasoft.utils.uri.getConfigurationWebServiceBaseUrl();
		var requestUrl = workspaceBaseUrl + "/rest/" + serviceName + "/" + methodName;
		var requestConfig = {
			url: requestUrl,
			headers: {
				"Accept": "application/json",
				"Content-Type": "application/json"
			},
			method: "POST",
			jsonData: Ext.encode(dataSend),
			callback: function(request, success, response) {
				if (!callback) {
					return;
				}
				var responseObject = response;
				if (success) {
					responseObject = Terrasoft.decode(response.responseText);
				}
				callback.call(this, responseObject, success);
			},
			scope: scope || this
		};
		if (config && config.timeout) {
			requestConfig.timeout = config.timeout;
		}
		return Terrasoft.AjaxProvider.request(requestConfig);
	}
 
	return {
		callService: internalCallService
	};
});

 

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

Понял, пойду попробую спасибо,

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

В целом все так как вы и сказали, только раз присутствует конфиг, то все остальные параметры(данные, scope, callback) нужно так же перенести в него, иначе они перезатрутся при вызове. Спасибо!

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

Добрый день,

 

Столкнулся с проблемой фильтрации справочных полей при помощи бизнес правил,

есть Справочник улиц (Street) у которого соответственно есть принадлежность к выше стоящим элементам(Городам, Районам, Регионам и др.) 

Выглядит примерно следующим образом

╔══════════════╤═════════════════════╤══════════════════════════════════════╤══════════════════════════════════════╤══════════════════════════════════════╤══════════════════════════════════════╗
║ Name         │ TerritorialObjectId │ LocalityId                           │ DistrictId                           │ RegionId                             │ CountryId                            ║
╠══════════════╪═════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╣
║ ул. Королёва │ NULL                │ NULL                                 │ NULL                                 │ B0FDED10-AEE0-4F1B-9C8D-198F7C154257 │ 5A1FEFDA-56A4-48A2-BC77-E40C71EEC73B ║
╟──────────────┼─────────────────────┼──────────────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────╢
║ ул. Ф.Торо   │ NULL                │ 967FC3D7-EBBA-4B76-AEDD-FE1CA5B48157 │ 7B11D4CE-D3E2-487F-BE03-A620015FB4FA │ EED82307-32D6-47EF-BDD8-FA64FE399614 │ 5A1FEFDA-56A4-48A2-BC77-E40C71EEC73B ║
╚══════════════╧═════════════════════╧══════════════════════════════════════╧══════════════════════════════════════╧══════════════════════════════════════╧══════════════════════════════════════╝

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

Бизнес правило по улице заполнено следующим образом

"Street": {
	"FiltrationStreetByTerritorialObject": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "TerritorialObject",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "TerritorialObject"
	},
	"FiltrationStreetByLocality": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "Locality",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "Locality"
	},
	"FiltrationStreetByDistrict": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "District",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "District"
	},
	"FiltrationStreetByRegion": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "Region",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "Region"
	},
	"FiltrationStreetByCountry": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "Country",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "Country"
	}
}

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

Я что то упускаю?

У меня такой же вопрос

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

Сериков Асхат Кайратович,

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

Это решается также через другое свойство атрибута - dependencies.

Подробнее можно почитать здесь и посмотреть пример вот здесь.

Насколько мне известно, такой код работать не будет.

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

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

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

autocomplete: true,

должен был выполнять

Сериков Асхат Кайратович,

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

Это решается также через другое свойство атрибута - dependencies.

Подробнее можно почитать здесь и посмотреть пример вот здесь.

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

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

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

Подскажите пожалуйста, как передать данные в модальное окно, а также как и где получить их в модальном окне?

Вызов модального окна 
 

var sandbox = this.sandbox;
var config = {
	heightPixels: 300,
	widthPixels: 700
};
var moduleName = "GrsModalModule";
var moduleId = sandbox.id + "_" + moduleName;
var renderTo = ModalBox.show(config, function() {
	sandbox.unloadModule(moduleId, renderTo);
});
sandbox.loadModule(moduleName, {
	id: moduleId,
	renderTo: renderTo,
});

 

У меня такой же вопрос

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

Пример из  TagUtilitiesV2 (заполнение parameters) и вызов модуля

openTagModule: function(config) {
	var scope = config.scope;
	var sandbox = config.sandbox || scope.sandbox;
	var tagModulePageId = this.getTagModulePageId(sandbox);
	this.prepareModalBox();
	var tagModuleConfig = {
		renderTo: this.getGridContainer(),
		id: tagModulePageId,
		parameters: {
			TagSchemaName: config.entityTagSchemaName,
			InTagSchemaName: config.entityInTagSchemaName,
			RecordId: config.entityRecordId
		}
	};
	sandbox.loadModule("TagModule", tagModuleConfig);
},

Пример чтения переданных параметров в модуле TagModule 

createViewModel: function() {
	var viewModel = this.callParent(arguments);
	var parameters = this.parameters;
	if (parameters) {
		viewModel.set("TagSchemaName", parameters.TagSchemaName);
		viewModel.set("InTagSchemaName", parameters.InTagSchemaName);
		viewModel.set("RecordId", parameters.RecordId);
	}
	return viewModel;
}

 

Пример из  TagUtilitiesV2 (заполнение parameters) и вызов модуля

openTagModule: function(config) {
	var scope = config.scope;
	var sandbox = config.sandbox || scope.sandbox;
	var tagModulePageId = this.getTagModulePageId(sandbox);
	this.prepareModalBox();
	var tagModuleConfig = {
		renderTo: this.getGridContainer(),
		id: tagModulePageId,
		parameters: {
			TagSchemaName: config.entityTagSchemaName,
			InTagSchemaName: config.entityInTagSchemaName,
			RecordId: config.entityRecordId
		}
	};
	sandbox.loadModule("TagModule", tagModuleConfig);
},

Пример чтения переданных параметров в модуле TagModule 

createViewModel: function() {
	var viewModel = this.callParent(arguments);
	var parameters = this.parameters;
	if (parameters) {
		viewModel.set("TagSchemaName", parameters.TagSchemaName);
		viewModel.set("InTagSchemaName", parameters.InTagSchemaName);
		viewModel.set("RecordId", parameters.RecordId);
	}
	return viewModel;
}

 

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

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

Роли хранятся в таблице SysAdminUnit.

Привязка пользователя идет в таблице SysUserInRole где опять же мы получаем SysUserId которая ссылается на SysAdminUnit, где мы получаем ContactId.

У меня такой же вопрос

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

 Что-то наподобие этого в lookuplistconfig прописать

filter: function() {return Terrasoft.createColumnFilterWithParameter(3, "[SysAdminUnit:Contact].[SysUserInRole:SysUser].SysRole.Id", "id группы")}

 

Select * from "Contact" INNER JOIN "SysAdminUnit" ON "Contact"."Id" = "SysAdminUnit"."ContactId"
where "SysAdminUnit"."Id" IN (Select "SysUserId" from "SysUserInRole" where "SysRoleId" = 'Ваша функциональная роль')

 

 Что-то наподобие этого в lookuplistconfig прописать

filter: function() {return Terrasoft.createColumnFilterWithParameter(3, "[SysAdminUnit:Contact].[SysUserInRole:SysUser].SysRole.Id", "id группы")}

 

Варфоломеев Данила пишет:
function() {return Terrasoft.createColumnFilterWithParameter(3, "[SysAdminUnit:Contact].[SysUserInRole:SysUser].SysRole.Id", "id группы")}

Огромное спасибо. 

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

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

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

 

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

У меня такой же вопрос

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

Какие галочки? Можно скриншот, того, что нужно?

имеете в виду галки вместо true false? Посмотрите в академии пример на конфигурирование логических полей в печатной форме (макросы). Прям ваш случай описан. И кстати в последних версиях уже вроде сделал вендор в базовой поставке это (но могу ошибаться)

Колодяжный Владислав Эдуардович,

Дмитрий Степанов,

Спасибо

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

Добрый день.

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

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

Через командную строку так же не получается его запустить, т.к. его там нет.

У меня такой же вопрос

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

Ну наврядли ктото угадает что у вас происходит. Проверьте настройки синхронизации. Смотрите логи. Смотрите есть ли ошибки в журнале БП

Ну наврядли ктото угадает что у вас происходит. Проверьте настройки синхронизации. Смотрите логи. Смотрите есть ли ошибки в журнале БП

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