Добрый день!

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

Нравится

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

Здравствуйте, Александр.

Инструкцию по механизму привязки данных вы можете найти на Академии по следующей ссылке: https://academy.terrasoft.ru/documents/technic-sdkmp/7-9/privyazka-dann….

Для переноса настроек колонок создайте привязку данных на вкладке Данные в разделе Конфигурация. При создании привязки нужно настроить фильтрацию записей таблицы SysProfileData. Нажатием на кнопку Показать данные вы сможете увидеть какие именно данные будут привязаны. Обязательным условием фильтрации является условие по полю Ключ.

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

при вызове карточки через openCardInChain не удается передать значения для справочных полей.
Значения простых типов: строки, числа, булева - переносятся
справочные - нет

this.openCardInChain({
        id: "Id",
        schemaName: "Tender1Page",
        operation: "add",
        moduleId: this.sandbox.id + "_AddTenderSuccessAction",
        //Автоматически устанавливаем значения в открываемой карточке
        defaultValues: [
             //Справочное поле полученное из модели - не переносится
            {name: "KmProjects", value: this.get("Project")},
             //Компонуемый объект для заполнения справочного поля - не переносится
            {name: "Request", value: {
                value: this.get("Id"),
                id: this.get("Id"),
                displayValue: this.get("RequestNumber")
            }},
            //Число - переносится корректно
            {name: "CostPriceFromONIC", value: this.get("CostPriceFromOnicExcludingVat")},
            //Устанавливаем значение поля "Стоимость" из запроса в поле
            //Строка - переносится нормально
            {name: "AmountKPwithoutVAT", value: this.get("Cost")}
    ]
});

Что я делаю не так ?

При этом имеем ошибку во время открытия карточки:

Нравится

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

попробовал передавать ай-дишники... тоже не выходит

...
 defaultValues: [
             //Справочное поле полученное из модели - не переносится
            {name: "KmProjects", value: this.get("Project").value},
             //Компонуемый объект для заполнения справочного поля - не переносится
            {name: "Request", value: this.get("Id"),  
            //Число - переносится корректно
            {name: "CostPriceFromONIC", value: this.get("CostPriceFromOnicExcludingVat")},
            //Устанавливаем значение поля "Стоимость" из запроса в поле 
            //Строка - переносится нормально
            {name: "AmountKPwithoutVAT", value: this.get("Cost")}
    ]
...

о как...
Заработало в виде массивов как значений аттрибутов name и value

defaultValues: [
	{
		name: ["KmProjects", "Request", "AmountKPwithoutVAT"], 
		value: [this.get("Project").value, this.get("Id"), this.get("Cost")]
	}

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

Нашел один единственный пример в исходниках, такого формата вызова.

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

Добрый день, у нас в црм есть раздел “сделки”, куда попадают анкеты с формы на сайте, также вся эта форма преобразовывается в pdf и с помощью odata прикрепляется к той же сделке в црм в "файлы и примечания".
Подскажите, пожалуйста, можно ли как-то реализовать, чтобы в случае изменения полей сделки менеджером в црм полностью пересоздавался/изменялся фал pdf с новыми параметрами или же можно как-то из бизнес-процессов вызвать php скрипт для создания pdf, передавая необходимый id?

Нравится

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

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

В bpm'online можно реализовать процесс, который будет запускаться по изменению записи. Однако логику изменения/создания *.pdf файла необходимо будет реализовать на C#.

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

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

спасибо за ответ :smile:, а реально ли сделать, чтобы все файлы из детали автоматически упаковывались в zip архив и при добавлении новых архив обновлялся, чтобы пользователь мог скачать по нажатию кнопки архив со всеми pdf?

В системе напрямую такой возможности нет, можно попробовать переопределить эту логику и добавить модулю архиватора на Javascript или С#, например https://habrahabr.ru/post/133129/

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

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

Нравится

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

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

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

Илья, спасибо. Сработало.

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

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

define("CardModuleResponseInterceptor", ["terrasoft", "ext-base", "sandbox", "BaseModule"],
        function(Terrasoft, Ext, sandbox) {
                Ext.define("Terrasoft.configuration.CardModuleResponseInterceptor", {
                        alternateClassName: "Terrasoft.CardModuleResponseInterceptor",
                        extend: "Terrasoft.BaseModule",
                        Ext: null,
                        sandbox: Ext.create(sandbox),
                        Terrasoft: null,
                        viewModel: null,
                        view: null,
                        rootScope: null,
                        subscribe: function() {
                                this.sandbox.subscribe(
                                        "CardModuleResponse",
                                        function(args) {
                                                this.set("NewVar", args);
                                        },
                                        this.rootScope,
                                        [this.rootScope.sandbox.id + "_AddTenderSuccessAction"]
                                );
                        }
                });
                return Terrasoft.CardModuleResponseInterceptor;
        });

Как я только уже не пробовал:
this.sandbox.loadModule("CardModuleResponseInterceptor", {rootScope: this});
//или
this.sandbox.loadModule("CardModuleResponseInterceptor", {instanceConfig:{rootScope: this}});
//или
this.sandbox.loadModule("CardModuleResponseInterceptor", {parameters:{rootScope: this}});

результата нет.

Не до конца ясен комментарий к parameters и instanceConfig
в core.js

Used only for instantiated modules

Как это понять "инстанцированных модулях" ?
Какие модули "инстанцированные" а какие нет ?
Как сделать свой модуль соответвующим ?

Нравится

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

Вызов из страница контрагента:

callLicenseModule: function(arr) {
	var moduleId = this.sandbox.id + "_reasonsChooser";
	this.modalBoxContainer = ModalBox.show({
		minHeight: "1",
		minWidth: "1",
		maxHeight: "100",
		maxWidth: "100"
	});
	ModalBox.setSize(650, 130);
	var chooseModuleConfig = {
		renderTo: this.modalBoxContainer,
		id: moduleId,
		parameters: {
			Collection: arr,
			Record: this.get("MasterRecordId")
		}
	};
	this.sandbox.loadModule("TmLicenseModule", chooseModuleConfig);
}

Модуль:

define("TmLicenseModule", ["BaseSchemaModuleV2"], function() {
	Ext.define("Terrasoft.configuration.TmLicenseModule", {
		extend: "Terrasoft.BaseSchemaModule",
		alternateClassName: "Terrasoft.TmLicenseModule",
 
 
		generateViewContainerId: false,
 
 
		initSchemaName: function() {
			this.schemaName = "TmLicenseModuleSchema";
		},
 
 
		initHistoryState: Ext.emptyFn,
 
 
		createViewModel: function() {
			var viewModel = this.callParent(arguments);
			var parameters = this.parameters;
			if (parameters) {
				viewModel.set("Licenses", parameters.Collection);
				viewModel.set("Record", parameters.Record);
			}
			return viewModel;
		}
	});
	return Terrasoft.TmLicenseModule;
});

Под модулем лежит страница TmLicenseModuleSchema, в ней 2 аттрибута (Licenses и Record). Соответственно они заполняются при вызове модуля

Добрый день, Илья.

Для передачи параметров в загружаемы модуль, необходимо воспользоваться свойством instanceConfig. Скорей всего проблема связана с тем, что в конструктор модуля можно передавать только литералы объектов. this же является уже созданным экземпляром класса.

В вашем варианте это модуль элемента граф.интерфейса, со вьюхой и т.д.
наследник "Terrasoft.BaseSchemaModule"

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

Да и в любом случае - я воспроизвел свой юзкейс наследуясь от Terrasoft.BaseSchemaModule
В init модуля все равно нет ничего ни через instanceConfig ни через parameters

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

"Мотков Илья" написал: что в конструктор модуля можно передавать только литералы объектов. this же является уже созданным экземпляром класса.

т.е. теоретически должно помочь "оборачивание" this в массив или объект ?

this.sandbox.loadModule("CardModuleResponseInterceptor", {instanceConfig:{
       rootScope: [this]
}});

а в последствии получить к нему доступ по rootScope[0] внутри init метода

PS: Если "не секрет" с чем связанно ограничение на экземпляры класса в параметрах для конструктора - как то не ясна суть.

Скорей всего это архитектурное решение, ведь даже инстанс sandbox в загружаемом модуле инциализируется отдельно. Также можно кешировать scope в свойствах глобального объекта браузера.

"Мотков Илья" написал:Также можно кешировать scope в свойствах глобального объекта браузера.

Так это и решается сейчас, но это "костыль".
С враппингом пока не проверял... как проверю - отпишусь обязательно.

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

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

define("CardModuleResponseInterceptor", ["terrasoft", "ext-base", "sandbox", "BaseModule"],
        function(Terrasoft, Ext, sandbox) {
                Ext.define("Terrasoft.configuration.CardModuleResponseInterceptor", {
                        alternateClassName: "Terrasoft.CardModuleResponseInterceptor",
                        extend: "Terrasoft.BaseModule",
                        sandbox: Ext.create(sandbox),
                        CardModuleResponseSUBSCRIBER: function(scope) {
                                this.sandbox.subscribe(
                                        "CardModuleResponse",
                                        function(args) {
                                                this.set("NewVar", args);
                                        },
                                        scope,
                                        [scope.sandbox.id + "_AddTenderSuccessAction"]
                                );
                        }
                });
                return Terrasoft.CardModuleResponseInterceptor;
        });

Так же в самом модуле, добавлена подписка на событие:
в схеме некоей карточки я добавляю модуль в зависимости, объявляю его экземпляр,
но когда дело доходит
define("LeadPageV2", ["UserUtilsMixin", "CardModuleResponseInterceptor"],
        function(UserUtilsMixin, CardModuleResponseInterceptor) {
...
        "onEntityInitialized": function() {
...
                //Объявляем экземпляр модуля-перехватчика события "CardModuleResponse"
                this.CardModuleResponseInterceptor = Ext.create("Terrasoft.CardModuleResponseInterceptor");
...

И в какой-то момент выполнения логики я вызываю
this.CardModuleResponseInterceptor.CardModuleResponseSUBSCRIBER(this);

Код внутри модуля исполняется успешно, во всех случаях кроме непосредственной подписки на события
В конечном итоге имеем ошибку
"Cannot read property 'messages' of null "
внутри bootstrap.js
...
getEventDescriptor: function(eventName) {
        var moduleDynamicMessages = this.getCurrentModuleDynamicMessages();
        if (moduleDynamicMessages[eventName]) {
                return moduleDynamicMessages[eventName];
        }
        var moduleDescriptor = core.getModuleDescriptor(this.moduleName);
        return (moduleDescriptor.messages) ? moduleDescriptor.messages[eventName] || null : null;
},
...

this.moduleName - оказывается в состоянии undefined

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

Нравится

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

Делал модальное окно с общением между ним и карточкой из которой оно открывается через песочницу. Возможно будет полезно, вот здесь код и описание:
http://www.community.terrasoft.ru/forum/topic/17970#comment-63544
Т.к. модальное окно по сути тоже модуль и песочница там работала.

Ext.create(sandbox) - это что?

как создать модуль
https://academy.terrasoft.ru/documents/technic-sdk/7-10/dobavlenie-mini…

"Андросов Дмитрий" написал:Ext.create(sandbox) - это что?

Эксперимент после которого, собственно подписка уже двинулась дальше, изначального фейла в котором this.sandbox = undefined
Подглядел где-то в исходниках.
...
Переработал модуль, переосмыслив, почитав статью.

define("CardModuleResponseInterceptor", ["terrasoft", "ext-base", "sandbox", "BaseModule"],
	function(Terrasoft, Ext, sandbox) {
		Ext.define("Terrasoft.configuration.CardModuleResponseInterceptor", {
			alternateClassName: "Terrasoft.CardModuleResponseInterceptor",
			extend: "Terrasoft.BaseModule",
			Ext: null,
			sandbox: null,
			Terrasoft: null,
			viewModel: null,
			view: null,
			rootSope: {},
			init: function() {
				// Вызывает выполнение логики метода init() класса-родителя.
				this.callParent(arguments);
				this.sandbox.subscribe(
					"CardModuleResponse",
					function(args) {
						this.set("NewVar", args);
					},
					this.rootSope,
					[this.rootSope.sandbox.id + "_AddTenderSuccessAction"]
				);
			}
		});
		return Terrasoft.CardModuleResponseInterceptor;
	});

теперь собственно в карточке вызываю

Ext.create("Terrasoft.CardModuleResponseInterceptor", {rootSope: this});

но метод init не выполняется по какой-то причине.
Надо использовать метод loadModule ?

да, а вот создавать экземпляр вашего модуля на LeadPage не надо

"Андросов Дмитрий" написал:

да, а вот создавать экземпляр вашего модуля на LeadPage не надо


На правах, связанного вопроса...
Если я не могу/не надо создавать, как же я смогу передать контекст, при Ext.create(
я планировал передавать его - перегружая динамическое свойство, в объекте (2-ой аргумент конструктора)
Я так понимаю во время загрузки модуля, такой возможности уже не предоставляется
Или есть ?

PS: В двух словах, если можно, а в каких юзкейсах потребуется явное объявление экземпляра через Ext.create(?

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

this.CardModuleResponseInterceptor = Ext.create("Terrasoft.CardModuleResponseInterceptor", {rootScope: this});
this.sandbox.loadModule(this.CardModuleResponseInterceptor, {id: "someModuleId"});

?
Конкретно такой способ не работает к сожалению.
Еще попробовал так

this.sandbox.loadModule("CardModuleResponseInterceptor", {
	instanceConfig: {
		rootScope: this
	}
});

и так

this.sandbox.loadModule("CardModuleResponseInterceptor", {
        id: "CustomIdvalue"
	instanceConfig: {
		rootSope: this
	}
});

При загрузке модуля - ошибка " Cannot read property 'id' of undefined"
в core.js:581

По факту же отладка показывает что перегрузка "rootScope" не попадает в конструктор, через instanceConfig:

Ка-же все таки передать аргументы в конструктор ?

нет времени, только скриншоты


alternateClassName: "Terrasoft.CardModuleResponseInterceptor"

вот это имя в loadmodule и пишите

"Terrasoft.CardModuleResponseInterceptor" использовать невозможно.
Вызов кода модуля, и его метода init происходит через его имя "модуля" а не класса, Вы второпях ошиблись.
т.е.

define("CardModuleResponseInterceptor",  ...

Вызов модуля, происходит по

this.sandbox.loadModule("CardModuleResponseInterceptor");

Что же касается instanceConfig, его я нашел и попробовал сразу.

this.sandbox.loadModule("CardModuleResponseInterceptor", {
	instanceConfig: {
		rootScope: this
	}
});

Но по неизвестной причине - мне не удается получить значения в контексте init метода.
При этом инициируя через Ext.create и явный вызов init метода у экземпляра
как раз аргументы конструктора передаются корректно, но зато не функционирует sandbox
С этого собственно все и началось.

Не до конца ясен комментарий к parameters и instanceConfig

Used only for instantiated modules

Как это понять "инстанцированных модулях" ?
Какие модули "инстанцированные" а какие нет ?
Как сделать свой модуль соответвующим ?

function loadModule(moduleName, config) {
	if (!config) {
		config = {};
	}
	if (!config.id) {
		config.id = moduleName;
	}
	performanceCounterManager.start(config.id + "_loadModule");
	config.moduleName = moduleName;
	var module = getModuleDescriptor(moduleName);
	var cssDeps = module.css ? bootstrap.mapResourcesToPath(module.css, module.path, "css") : [];
	var lessDeps = module.less ? bootstrap.mapResourcesToPath(module.less, module.path, "less") : [];
	createContext(moduleName, config);
	require(["ext-base", moduleName].concat(cssDeps).concat(lessDeps), function(Ext, exportedModule) {
		if (typeof exportedModule === "function") {
// инстанцируемый модуль, это модуль, функция-фабрика которого возвращает функцию (Ext-класс), у вас как раз такой
//https://academy.terrasoft.ru/documents/technic-sdk/7-10/koncepciya-amd-ponyatie-modulya
			createModuleInstance(exportedModule, moduleName, config);
		} else {
			processModule(exportedModule, config);
			exportedModule.isDestroyed = false;
			exportedModule.instanceId = Terrasoft.generateGUID();
			loadedModules[config.id] = exportedModule;
		}
	});
	return config.id;
}
function createModuleInstance(modulesFactory, moduleName, config) {
	var moduleId = config.id;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//чтобы модуль проинстанцировался нужно, чтобы не существовало инстанса с таким ИД
	if (!requirejs.defined(moduleId)) {
		var factoryName = moduleName + "_factory";
		if (!(factoryName in contexts)) {
			contexts[factoryName] = contexts[moduleId];
		}
		delete contexts[moduleId];
		requirejs.undef("sandbox_" + moduleId);
		requirejs.undef("ext_" + moduleId);
		requirejs.undef("terrasoft_" + moduleId);
		createContext(moduleId, config);
		define(moduleId, ["ext-base", "terrasoft", "sandbox"], function(Ext, Terrasoft, sandbox) {
			var context = {};
			var instanceConfig = config.instanceConfig;
			if (instanceConfig && (typeof instanceConfig === "object")) {
				context = prepareParameters(instanceConfig);
			}
			if (config.parameters && (typeof config.parameters === "object")) {
				context.parameters = prepareParameters(config.parameters);
			}
			context.Ext = Ext;
			context.sandbox = sandbox;
			context.Terrasoft = Terrasoft;
			var Constructor;
			var moduleInstance;
			if (modulesFactory.$isClass === true) {
				Constructor = modulesFactory;
				moduleInstance = new Constructor(context);
			} else {
				Constructor = safeExecute({
					fn: modulesFactory,
					scope: modulesFactory,
					args: [context],
					errorInfo: {
						moduleName: moduleName,
						contexts: contexts,
						chain: chain,
						moduleId: moduleId
					}
				});
				moduleInstance = new Constructor();
			}
			moduleInstance.isDestroyed = false;
			loadedModules[moduleId] = moduleInstance;
			return moduleInstance;
		});
	}
	require([moduleId], function(module) {
		processModule(module, config);
	});
}

в результате проследите, чтобы ИД модуля был уникален и делайте destroy модуля, когда он больше не нужен

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

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

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

Select accountSelect = GetAccountSelectQuery(accountId, additionalColumnNames);
var hierarhicalOptions = new HierarchicalSelectOptions {
PrimaryColumnName = "AccountId",
ParentColumnName = "ParentAccountId",
SelectType = HierarchicalSelectType.Parents,
MaxDepthParameter = select.Parameters.GetByName("MaxDepth"),
IncludeLevelColumn = true
};
QueryCondition startingCondition = hierarhicalOptions.StartingPrimaryColumnCondition;
startingCondition.LeftExpression = new QueryColumnExpression("AccountId");
startingCondition.IsEqual(select.Parameters.GetByName("RootAccountId"));
string sqlText = UserConnection.DBEngine.GetQuerySqlText(accountSelect, hierarhicalOptions);
using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection()) {
using (IDataReader reader = dbExecutor.ExecuteReader(sqlText, accountSelect.Parameters)) {
while (reader.Read()) {
ancestors.Add(reader.GetColumnValue("AccountId"););
}

Нравится

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

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

Идея Ваша ясна, но реализовать вот прямо как код написан вряд ли удастся, только если писать какие-то костыли. Допустим, а) если количество предков или наследников или наследников будет строго меньше N, можно сделать N полей, но это плохо с той стороны, что большое количество полей будет просто излишним, б) сделать какое-то поле, в котором будут сконкатенированы, допустим, через запятую id`шники предков, и потом его парсить, но это нарушение реляционности, да и в принципе очень проблематично. Рекомендую все же пересмотреть иерархию и подобрать другое решение.

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

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

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

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

Нравится

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

Добрый день, Илья.

За функционал открытия новой карточки при добавлении записи в справочное поле отвечает метод actionButtonClick из LookupPageViewModelGenerator. Также Вам стоит посмотреть в метод defaultModeActionButtonClick из того же модуля.

Основная "магия" происходит в момент публикации сообщения PushHistoryState.


А можете помочь, поточнее определить/разобрать "магию".
Каким-то образом ведь должно быть определено что в открываемой карточке, во-первых надо ее закрывать при сохранении (если открыть карточку просто через OpenCardInChain такого не происходит),
во-вторых указать в какое поле искомой карточки - устанавливать значением - вновь созданную запись.

Мне необходимо добиться аналогичного поведения, только не из окна справочника, а по пункту меню "Действия"... например для карточки объекта "У" - пункт меню "Создать X"
Должна открываться карточка "X" и после ее сохранения, необходимо вернуть пользователя "на исходную карточку "Y", где специализированное поле для связи "Связанный объект Х" (Являясь справочным полем для "X") будет заполнено значением только что созданного "X".

"килочасы" отладки, позволили определить наилучшего кандидата, это событие "CardModuleResponse"
(Прямо то что нужно в атрибуты события передаются данные по уже успешно сохраненному объекту)
При условии помещения в "PushHistoryState" текущей карточки с признаком "isInChain: true"
И дальнейшим открытием карточки нового объекта через openCardInChain, "Сохранить" или "Отмена" в открываемой карточке, естественным образом вернут пользователя на страницу помещенную в PushHistoryState. При сохранении карточки обязательно произойдет публикация CardModuleResponse в который будет переданы данные о созданной записи
Казалось бы - проблем нет, подписываемся на событие и счастливы...
но нет....
На событие "CardModuleResponse" подписаться в карточке нельзя, так как в ее контексте на уровне BasePageV2 это событие уже объявлено в направлении "PUBLISH"

Как же можно обойти такое ограничение и все таки подписаться на это событие ?
(В случае с выбором из справочника, подписка происходит в рамках схемы LookupPageViewModelGenerator).
Может быть можно как-то выкрутиться через модуль, в который передавать контекст карточки, а в нем произвести подписку, т.к. там не будет зависимости от BasePageV2 ?

Здравствуйте,
Рекомендую вам написать БП в котором открывать карточку создания нужной вам сущности, после чего, из скрипт-таска послать веб сокет сообщение с id созданной записи в карточку, из которой через действия вы запустите данный процесс:
http://www.community.terrasoft.ru/forum/topic/11784#comment-56699
В карточке услышав данное веб-сокет сообщение вы просто нужное поле, заполните значением по id полученным из процесса.
Информация о том, как запустить из JS процесс есть на академии.

Ну есть же механизм который используется в LookupPageViewModelGenerator
событие CardModuleResponse которое встроено в штатное платформенное поведение.
Неужели его никак нельзя использовать в собственных сценариях ?

"Севостьянов Илья Сергеевич" написал:Неужели его никак нельзя использовать в собственных сценариях ?

если вы хотите его использовать на наследниках BaseEntityPage, то не выйдет - нельзя на одного и то же сообщение подписаться в обе стороны. Вам придется реализовывать собственную пару для передачи сообщения между карточкой и карточкой. В случае со справочником [если я ничего не путаю] - LookupPage служит передатчиком между одной карточкой и другой

ПС. я вижу вы уже пошли по этому пути)

"Андросов Дмитрий" написал:В случае со справочником [если я ничего не путаю] - LookupPage служит передатчиком между одной карточкой и другой

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

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

Передать значение можно через свойство defaultValues. Свойство defaultValues должно содержать массив объектов вида {name: "", value: ""}. В открывшейся карточке переданные значения можно считать с атрибута DefaultValues.

Возвращать Id сохраняемой записи уже через sandbox заместив BasePageV2.

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

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

Error: Script error for "НазваниеРаздела"
http://requirejs.org/docs/errors.html#scripterror

Был создан новый раздел, протестирован, всё работало, выгружен в svn и установлен на другой машине.

Раздел добавлен в рабочее место. При попытке открыть реестр раздела в консоли выдаётся такая вот ошибка.

Нравится

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

Помогла генерация исходных кодов для требующих перегенерации и последующая полная компиляция.

Хотя в настройках web.config указана автоматическая установка и компиляция пакетов.

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

Коллеги, приветствую.

Подскажите, пожалуйста, как можно перенести набор системных настроек через svn?

Во вкладке Данные переносимого пакета я создал новую схему для всех созданных системных настроек с фильтром "Код начинается на ...", схема показала 3 нужные записи.

Попробовал создать схему привязки Значений системной настройки (с фильтром Системная настройка.Код начинается на ... - т.е. зеркально предыдущему фильтру), при показе данных отображает 3 корректных значения, но при сохранении выдаётся ошибка для всех трёх значений: "Не привязаны данные для связанного объекта "SysSettings" по колонке "SysSettings"" и дальше Id системных настроек.

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

Подскажите, пожалуйста, корректный способ переноса настроек.

Нравится

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

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

Правда до этого я указал один раз в фильтре конкретное значение записи в режиме фильтра "равно".

Теперь изменения фильтров на И или ИЛИ не отменяют успешность привязки данных к пакету.

Похоже на ошибку в работе привязки данных...

"Фёдоров Александр. Афлекс" написал:Подскажите, пожалуйста, как можно перенести набор системных настроек через svn?

Наиболее гарантированный, а так же с наиболее ожидаемым поведением - это SQL-скрипт.

"Севостьянов Илья Сергеевич" написал:
Наиболее гарантированный, а так же с наиболее ожидаемым поведением - это SQL-скрипт.

Это всё-таки хардкор без поддержки логики приложения...

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

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

"Фёдоров Александр. Афлекс" написал:Если есть штатные рабочие инструменты, хочется сначала пользоваться ими, пока не будет доказано, что они неработоспособны.

Они не предназначаются для переноса:
1) Системных настроек и их значений
2) Настройки колонок и их значений
3) Организационной структуры
4) Пользовательских прав.

Об этом, не однократно заявляли специалисты тех.поддрежки.

Если Вы хотите "надежно" переносить Ваши системные настройки - Вам необходимо написать SQL-сценарий, при этом желательно с логикой проверки предварительного существования, а так же проверкой - возможно, связанных данных.
ИМХО самый подходящий вариант (для TSQL) это MERGE скрипт, я о нем писал.

PS: Через данные, нормально переносятся группы системных настроект, включение настроек в группы, но самими значениями настроек - иногда бывают проблемы.

"Севостьянов Илья Сергеевич" написал:

Они не предназначаются для переноса:

1) Системных настроек и их значений

...

Об этом неоднократно заявляли специалисты тех.поддержки.

...

Это утверждение входит в противоречие с рекомендацией (которые звучали в том числе и на форуме Террасофт): при разработке новых объектов для задания значений по умолчанию использовать системные переменные.

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

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

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

1. Создать привязку на системную настройку
2. Создать привязку на само значение System settings value
Скриншот примера во вложении.

да нормально они переносятся - привяжите нужные данные для таблиц
SysSettings (обязательно)
SysSettingsFolder (группы настроек)
SysSettingsFolderLcz (локализация групп настроек)
SysSettingsGrantor (вхождение пользователей, если настройка "персональная")
SysSettingsInFolder (вхождение настройки в группу настроек)
SysSettingsLcz (локализация настроек)
SysSettingsReferenceSchema (не знаю, что это, вроде не нужно)
SysSettingsValue (обязательно)

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

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

"Мотков Илья" написал:
1. Создать привязку на системную настройку

2. Создать привязку на само значение System settings value


Илья, да, я так и сделал. В первоначальном моём сообщении я писал про то, что не сработала привязка данных из-за группового фильтра. После указания прямого фильтра всё заработало.

Дмитрий, спасибо за столь развёрнуты ответ. За "Обязательно для обновления" - отдельное спасибо.

"Фёдоров Александр. Афлекс" написал:За "Обязательно для обновления" - отдельное спасибо.

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

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