Здравствуйте сообщество,

Подскажите, пожалуйста, способ запуска серверного кода (C#) со страницы клиента (JS).
Бизнес-процесс имеет задержку при запуске, поэтому данный способ не лучшее решение.

 

Заранее благодарю.
Мария.

Нравится

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

Возникла необходимость редактирования детали "Средства связи" в разделе контакты.  Через мастер деталей это невозможно, т.к деталь неизменяема. Остается вариант с изменением исходного кода. Как можно заместить/редактировать необходимый модуль? В частности необходимо изменить код (или заместить на другой модуль) в модуле ContactCommunicationDetailV2.  

Нравится

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

Доброе утро.

 

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

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

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

Спасибо за ответ! И все таки: каким образом будет грамотнее заменить существующий клиентский модуль  на кастомный? С сохранением ключевых зависимостей, но изменением кода.

Тимур Макаев,

 

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

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

А чтобы отобразить уже внесенные данные, их можно перенести в новую таблицу с помощью запросов на уровне базы данных.

Всё зависит от того, насколько сильно будет изменена базовая логика.

Создаем новый модуль, например:

define("UsrBaseCommunicationViewModel", ["ext-base",
	"terrasoft", "UsrBaseCommunicationViewModelResources",
	"BaseCommunicationViewModel",],
	function(Ext, Terrasoft, resources, BaseCommunicationViewModel) {
		Ext.define("Terrasoft.configuration.UsrBaseCommunicationViewModel", {
			extend: "Terrasoft.BaseCommunicationViewModel",
			alternateClassName: "Terrasoft.UsrBaseCommunicationViewModel",
			methodName: function(value) { //метод, который нужно заместить в базовой логике
 
			},
		});
	});

Подключаем этот модуль в базовую деталь (создав замещающую страницу):

define("BaseCommunicationDetail", ["UsrBaseCommunicationViewModel"], function(UsrBaseCommunicationViewModel) {
	return {
		attributes: {
		},
		methods: {
			init: function(callback, scope) {
				this.set("BaseCommunicationViewModelClassName", "Terrasoft.UsrBaseCommunicationViewModel");
				this.callParent(arguments);
			},
		},
		diff: /**SCHEMA_DIFF*/[
		]/**SCHEMA_DIFF*/
	};
});

Естественно делаем все на свой страх и риск.

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

Здравствуйте community,

 

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

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

 

 

Заранее спасибо за ваши идеи.

Нравится

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

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

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

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

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

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

Коллеги подскажите пожалуйста есть необходимость в окружение добавить пользовательский компонент и получать к нему доступ через Terrasoft.{пользовательский компонент}. 

Трудность заключается в том, что данные компонента находятся в БД и на данный момент получаются с помощью конфигурационного сервиса. Сам компонент заполняется  в callback функции. То есть доступен не сразу, а только после получения ответа от сервиса.

Каким образом можно создать компонент например при инициализации сессии пользователя либо при первичной загрузки интерфейса?

Нравится

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

Егор, а в чём отличие Вашего компонента от какой-то стандартной функциональности, например, AcademyUtilities? Там тоже в функции getAcademyUrlFromLookup получают данные из базы по SQ, что происходит не мгновенно.

/**
 * Gets academy URL from lookup.
 * @private
 * @param {Object} config Configuration object.
 * @param {Function} config.callback Callback function.
 */
getAcademyUrlFromLookup: function(config) {
	var cacheItemName = "AcademyURL_" + Terrasoft.currentUserCultureName;
	var getLmsUrlQuery = Ext.create("Terrasoft.EntitySchemaQuery", {
		rootSchemaName: "AcademyURL",
		rowCount: 1,
		serverESQCacheParameters: {
			cacheLevel: Terrasoft.ESQServerCacheLevels.WORKSPACE,
			cacheGroup: "AcademyUtilities",
			cacheItemName: cacheItemName
		}
	});
	getLmsUrlQuery.clientESQCacheParameters = {cacheItemName: cacheItemName};
	getLmsUrlQuery.addColumn("Description", "Description");
	getLmsUrlQuery.getEntityCollection(function(response) {
		var collection = response.collection;
		var academyRootUrl = "";
		if (collection.getCount()) {
			academyRootUrl = collection.first().get("Description");
		}
		Ext.callback(config.callback, this, [academyRootUrl]);
	}, this);
}

Или под компонентом имеете в виду что-то другое, вроде виджета в итогах или iframe на главной странице?

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

Приветствую! 

Недавно занялся изучением и работой с платформой Creatio. По тому по коду прошу не ругать ;) 
 

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

Код реализации с getEntity:

var message;
 
var recordId = this.get("Id");
 
if(recordId) {
		var esq1 = this.Ext.create("Terrasoft.EntitySchemaQuery", {
						rootSchemaName: "UsrSwimmProgramm"
		});
 
		var filterA = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPBooleanActive" , 1);
		var filterP = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPLookupPeriod.Name" , "Ежедневно");
		esq1.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
		esq1.filters.add("filterA",filterA);
		esq1.filters.add("filterP",filterP);
 
		esq1.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, 
						"NumberDayLesson", Terrasoft.AggregationEvalType.ALL);
 
 
				esq1.getEntity(recordId, function(result) {
					if (!result.success) {
						this.showInformationDialog("Ошибка запроса");
						return;
					}
					message = result.entity.get("NumberDayLesson") + "\n";
				this.showInformationDialog(message);
				}, this);
 
				}

Код реализации с getEntityCollection:

var message;
var recordId = this.get("Id");
 
if(recordId) {
			var esq1 = this.Ext.create("Terrasoft.EntitySchemaQuery", {
						rootSchemaName: "UsrSwimmProgramm"
				});
 
				var filterA = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPBooleanActive" , 1);
				var filterP = esq1.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrSPLookupPeriod.Name" , "Ежедневно");
				esq1.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
				esq1.filters.add("filterA",filterA);
				esq1.filters.add("filterP",filterP);
 
				esq1.addAggregationSchemaColumn("Id", Terrasoft.AggregationType.COUNT, 
						"NumberDayLesson", Terrasoft.AggregationEvalType.ALL);
 
				esq1.getEntityCollection( function(result){
					message = result.collection.getByIndex(0).get("NumberDayLesson");
					this.showInformationDialog(message);
				},this);
 
	}

 

Так вот, почему при всех равных метод getEntity выдает не определенной значение, а вот с getEntityCollection все работает норм ? 

 

 

Нравится

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

Добрый вечер.

 

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

И в Вашем случае этот метод не срабатывает, потому что в заданном наборе данных не находит запись по этому recordId. Фактически, при использовании этого метода Вы добавляете ещё один фильтр по полю Id записи.

 

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

Добрый вечер.

 

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

И в Вашем случае этот метод не срабатывает, потому что в заданном наборе данных не находит запись по этому recordId. Фактически, при использовании этого метода Вы добавляете ещё один фильтр по полю Id записи.

 

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

Спасибо большое, Алла. Уже смотрю.

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

Доброго времени суток!
Допустим, у меня есть раздел "Автомобили" с возможностью добавления новых автомобилей. В клиентской части мне необходимо отловить событие после добавления новой записи в этот раздел и добавить дополнительную логику на фронте. Думаю, должно быть что-то вроде "onItemInserted". Подскажите, пожалуйста,  как это лучше реализовать или какое название метода, который отрабатывает после вставки. Заранее благодарен.

Нравится

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

Добрый день!

 

На клиентской части в карточке редактирования Вы можете переопределить метод BasePageV2#onSaved

onSaved: function() {
	this.callParent(arguments);
},

Обратите внимание, если Вам нужно производить какие-то манипуляции с данными (пересчеты/обновления в других объектах и т.д.), то лучше использовать подход сигналов/событий объекта, тк при обработке на клиенте обрабатываться будет только "ручной" ввод, а во время импортов/интеграций/БП это логика останется "за бортом"

Добрый день!

 

На клиентской части в карточке редактирования Вы можете переопределить метод BasePageV2#onSaved

onSaved: function() {
	this.callParent(arguments);
},

Обратите внимание, если Вам нужно производить какие-то манипуляции с данными (пересчеты/обновления в других объектах и т.д.), то лучше использовать подход сигналов/событий объекта, тк при обработке на клиенте обрабатываться будет только "ручной" ввод, а во время импортов/интеграций/БП это логика останется "за бортом"

Если учитывать изменения на объекте процессами, интеграциями (или одновременно разными пользователями), лучше реализовать логику на событии вставки на уровне БП, а затем на сторону браузера передавать по ClientMessageBridge.

Лопатин Константин, Благодарю за совет! 

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

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

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

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

Есть ли возможность динамически изменить свойство "parentName" у детали? (или как получить объектное представление детали для изменения свойства)

define("SomeModuleName", [], function() {
    return {
    details: {
        "DetailName": {
            "schemaName": "schemaName",
            "entitySchemaName": "entitySchemaName",
            "filter": {
                "detailColumn": "detailColumn",
                "masterColumn": "Id"
            }
        }
    },
    diff: /**SCHEMA_DIFF*/[ 
        {
            "operation": "insert",
            "name": "AddedTabName",
            "values": {
                "items": [],
                "caption": {
                    "bindTo": "Resources.Strings.AddedTabNameCaption"
                },
            },
            "parentName": "Tabs",
            "propertyName": "tabs",
            "index": 1
        },
    {
        "operation": "insert",
        "name": "CardDetail",
        "values": {
            "itemType": this.Terrasoft.ViewItemType.DETAIL,
            "visible": { "bindTo": "CardDetailVisible" }
        },
        "parentName": "AddedTabName",
        "propertyName": "items",
        "index": 0
        },
    ]/**SCHEMA_DIFF*/,
    methods: {
        onEntityInitialized: function() {
            this.callParent(arguments);
            // myMethodToUpdateVisibility();
        },
        }
    };
});

Вкладка (tab) на которую надо перенести деталь также динамически (также из кода клиентского модуля) добавляется сторонним пакетом.

Спасибо

Нравится

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

Добрый день! Возможно, проще добавить 2 детали на разные вкладки, и в зависимости от условий ненужное скрывать, чем динамически вставлять\перемещать

Добрый день! Возможно, проще добавить 2 детали на разные вкладки, и в зависимости от условий ненужное скрывать, чем динамически вставлять\перемещать

Лопатин Константин,

Спасибо за ваш вариант, попробую такой подход.

или как предложил Лопатин Константин или технически есть возможность закидывать и изымать элемент через ext, если вам вдруг не хватает геморроя в вашем проекте)

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

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

Нравится

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

Вы можете по аналогии с существующим модулем реализовать свой клиентский модуль с нужным методом.

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

Вы можете по аналогии с существующим модулем реализовать свой клиентский модуль с нужным методом.

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

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

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

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

Нравится

7 комментариев
Лучший ответ
PostMessage отправляет конкретному юзеру. Поэтому надо быть уверенным, что бп запущен от нужного пользователя и он на нужной странице(где есть код для обработки обратного сигнала). 
Если не подходит, можно воспользоваться PostMessageToAll(string sender, string message). Рассылает сообщение по всей конфигурации всем пользователям.

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

В конце БП в элементе Задание-сценарий вставляете следующую строку:
 

MsgChannelUtilities.PostMessage(UserConnection, "MyMessage", "UpdateDetail");

В клиентском модуле детали реализовать следующий код:
 

init: function () {
				this.callParent(arguments);
				this.subscriptionFunction();
			},
subscriptionFunction: function() {
				Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
				this.bpListenerMessage, this);
			},
bpListenerMessage: function(scope, message) {
				if (!message || message.Header.Sender !== "MyMessage") {
					return;
				}
				var message2 = message.Body;
				if (!this.Ext.isEmpty(message2) && message2 === "UpdateDetail") {
					this.updateDetail();
				}
			}

Примерно так.

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

 

Не обновляет, уже и не знаю в чем дело может быть

В БП

var userConnection = Get<UserConnection>("UserConnection");
Terrasoft.Configuration.MsgChannelUtilities.PostMessage(userConnection, "ReloadDetailConcert", "UpdateDetail");
return true;

На клиенте

init: function () {
	this.callParent(arguments);
	this.subscriptionFunction();
},
subscriptionFunction: function() {
	Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
	this.bpListenerMessage, this);
},
bpListenerMessage: function(scope, message) {
	if (!message || message.Header.Sender !== "ReloadDetailConcert") {
		return;
	}
	var message2 = message.Body;
	if (!this.Ext.isEmpty(message2) && message2 === "UpdateDetail") {
		this.updateDetail();
	}
},

 

PostMessage отправляет конкретному юзеру. Поэтому надо быть уверенным, что бп запущен от нужного пользователя и он на нужной странице(где есть код для обработки обратного сигнала). 
Если не подходит, можно воспользоваться PostMessageToAll(string sender, string message). Рассылает сообщение по всей конфигурации всем пользователям.

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

Изменил на 

Terrasoft.Configuration.MsgChannelUtilities.PostMessageToAll("ReloadDetailConcert", "UpdateDetail");
return true;

не помогло

Нужно ли еще прописать?

messages: {
	"ReloadDetailConcert": {
		mode: Terrasoft.MessageMode.BROADCAST,
		"direction": Terrasoft.MessageDirectionType.SUBSCRIBE
	}
},

 

Prime Source,

Да нет. Должно и так работать. Даже subscriptionFunction не вызывается?

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

По дебагу срабатывает, и сообщение правильно ловит, и выполняет this.updateDetail(); ,но почему нет данных в детали не пойму. Может что в процессе не так? Вот его скрин, там идет цикл который делает 8 проходов, и когда в таблице 8 записей становится он выполняет скрипт сообщения и завершает

 

Prime Source,

//Relationships - название детали из details.
//пример:
this.updateDetail({detail: "Relationships"});

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

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

Подскажите, где можно хранить значение на странице. Например, как глобальная переменная в C#. Если есть такой способ, то как его реализовать? Спасибо

Нравится

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

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

 

За пример можете брать существующую логику в приложении либо использовать следующие статьи: 

https://academy.terrasoft.ru/search?search_api_fulltext=VIRTUAL_COLUMN&f%5B0%5D=ss_site_name%3AAcademy&page=0
https://academy.terrasoft.ru/documents/technic-sdk/7-13/dobavlenie-multivalyutnogo-polya
https://academy.terrasoft.ru/documents/technic-sdk/7-13/kak-dobavlyat-polzovatelskuyu-logiku-v-sushchestvuyushchie-elementy-upravleniya

Как добавить виртуальную колонку описано на Community - https://community.terrasoft.ru/articles/virtualnoe-virtualcolumn-lukap-lookup-pole.
https://community.terrasoft.ru/questions/uslovnoe-zapolnenie-virtualnyh-polei-v-prednastroennoi-stranice

Как вариант Вам нужно реализовать виртуальную колонку в аттрибутах:

                "Test": {
                    dataValueType: this.Terrasoft.DataValueType.LOOKUP,
                    type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    isRequired: true,
                    initMethod: "initTest"

И затем реализовать свой метод.

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