Получил данные через ESQ, как отредактировать поле и сохранить это в БД
А ещё как добавить новую стороку в таблицу в БД
Как на зло в Академии умер поиск

Нравится

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

Для внесения изменений используйте Terrasoft.UpdateQuery.
Примеры можно посмотреть по ссылке https://academy.terrasoft.ru/documents/technic-sdk/7-10/obrabotka-vybor….
Для добавления новой записи используйте Terrasoft.InsertQuery. Здесь на Community есть много примеров, например, http://www.community.terrasoft.ru/forum/topic/25101.

Также на всякий случай ссылка на SDK.

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

Добрый день,

Хочу использовать фичу элемента Выполнить задачу выполнения кода после сохранения активности.
Например хочу взять последнюю созданную задачу и изменить значение колонки:

var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Activity");
esq.AddColumn("CreatedOn").OrderByDesc();
esq.AddAllSchemaColumns();
esq.RowCount = 1;
esq.AddColumn("isDetailedResultRequired");
var entities = esq.GetEntityCollection(UserConnection);
        foreach(var entity in entities){
    entity.SetColumnValue("isDetailedResultRequired", true);
        }
entities.Save();

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

Может кто подскажет в чем может быть проблема и как работать с этой фичей ?

Второй вопрос:

В исходниках видно, что в этот метод передается параметр в виде экземпляра созданной активности Entity activity. Можно ли поменять значения некоторых колонок и сохранить эту активность еще раз?
Если да, кто где взять доступные методы работы с Entity?

С уважением.

Нравится

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

Добрый день, Дмитрий!

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

Касательно второго вопроса не совсем понял, про какой конкретно метод идет речь. Информацию касательно ядровых методов можно найти на SDK:
https://academy.terrasoft.ru/api/SDKNETAPI/7.10.0/NetCoreAPI_Help.html#…
Или же поискать по конфигурации готовые примеры.

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

Спасибо за ответ.
Уже разобрался - код почему-то не работал именно в этом БП. Сделал тоже самое в другом БП и всё заработало.

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

Помогите решить тривиальную проблему новичку:

Есть сущность, которая имеет разные поля.

Задача: при очистке значения "ПОЛЕ1" автоматически очищать "ПОЛЕ2". Данные поля хранят в себе ссылки на значения разных таблиц.

С чего начинать? Куда смотреть?

Нравится

4 комментария
attributes: {
	"ChangeManager": {   //название колонки "менеджер изменения"
		dependencies: [
			{
				columns: ["ChangePath"],     //Название колонки "Направление изменения"
				methodName: "onPathChanged"
			}
		]
	}
},
methods: {
	onPathChanged: function {
		if (Ext.isEmpty(this.get("ChangePath"))) {
			this.set("ChangeManager", null);
		}
	}
}

а параметр "autoClean": true не работает?

Владимир, здравствуйте.

Данный параметр применяется в бизнес-правилах типа FILTRATION. Допустим, фильтрация города по стране. autoClean при смене страны очищает значение поля город, autocomplete при заполнении города автоматически заполняет страну. Отдельно от данного правила они вроде не работают.

Отработало! Спасибо огромное...

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

Не удается реализовать те приёмы что описаны в топике https://community.terrasoft.ru/forum/topic/25071#comment-68913.

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

Самая частая ошибка о том что у UserConnection.ProcessSchemaManager нет такого метода как GetInstanceByName.

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

Нравится

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

var processSchema = manager.GetInstanceByName("NrbSendDeadlineEmail");
var flowEngine = new FlowEngine(userConnection);
Dictionary parameter = new Dictionary();
parameter.Add("Case", caseId.ToString());
flowEngine.RunProcess(processSchema, parameter);

Так же этот прием не работает, который был указан в топике что выше постом.

Итак на данный момент сложилась вот такая ситуация.
Из БП-1 вызывается БП-2 (листинг кода ниже) -

string schedulerJobGroupName = "CreateOtkActivityProcessGroup";//- Любое имя группы триггеров
string jobProcessName = "CreateOtkActivityProcess"; //- Название процесса, который нужно запустить
string schedulerJobName = "CreateOtkActivityJobName"; //- Любое имя
 
IDictionary<string, object> parameters = new Dictionary<string, object>();
parameters["AccountId"] = Guid.Parse("9f1b2cce-f98c-4f52-b4da-04cae9e307ad"); //AccountId это параметр в БП-2 с типом Уникальный идентификатор
 
var job = AppScheduler.CreateProcessJob(schedulerJobName,
										schedulerJobGroupName,
										jobProcessName,
										UserConnection.Workspace.Name,
										UserConnection.CurrentUser.Name,
										parameters);
var trigger = new SimpleTriggerImpl(schedulerJobName + "Trigger", schedulerJobGroupName, DateTime.UtcNow);
AppScheduler.Instance.ScheduleJob(job, trigger);
 
return true;

БП-2 в свою очередь начинает выполняться и завершается, но есть одно НО.
Ни один из элементов этого БП так и не начал выполняться, т.е. БП-2 завершился без выполнения каких либо действий.
Скрины для данного поведения:
http://prntscr.com/fk1173
http://prntscr.com/fk11gu

Но как только мы сами запускаем БП-2 то наблюдаем его реальный процесс жизни, т.е. те элементы что в нём присутствуют отрабатывают согласно логике.
http://prntscr.com/fk127z

Что вобще происходит и что не так то? Уже все возможные статьи изучены и просмотрены, но понимание сути никак не приходит.

var processSchemaManager = (ProcessSchemaManager)UserConnection.GetSchemaManager(@"ProcessSchemaManager");
var processSchema = processSchemaManager.GetInstanceByName(@"CreateOtkActivityProcess");
 
var process = processSchema.CreateProcess(UserConnection);
process.SetPropertyValue(@"AccountId", accountCollection[accountIndex]);
process.SetPropertyValue(@"OwnerId", contactCollection[contactIndex]);
process.Execute(UserConnection);

Тему можно считать закрытой.

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

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

Интересуют подходы которые можно применить в BPM для расширения логики существующих классов.
В Ext.JS 4 существовало, ИМХО, несколько подходов к реализации такого кейса:

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

2) Есть перехватчики Ext.Function.createInterceptor и Ext.Function.createInterceptor, но это прямое "трогание" компонентов и применение таких хуков никогда не приветствовалось и считалось крайней мерой.

Как же следует поступать в BPM в соответствии с его парадигмой, когда требуется расширить методы/свойства существующего класса ?

Нравится

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

Ext.override можно использовать, но почему-то не рекомендуется и не встречается у Terrasoft.
Я через override полностью копировал весь модуль со всеми методами и изменял какие были необходимы

define("ITScheduleItem", [],
    function() {
 
        Ext.define("Terrasoft.controls.ITScheduleItem", {
            alternateClassName: "Terrasoft.ITScheduleItem",
            override: "Terrasoft.ScheduleItem",
 
            getTimePosition: function(date, isExact) {
                var timeItemHeight = this.timeItemHeight;
                var minutes = Terrasoft.getMinutesFromMidnight(date);
                return this.getTimeItemNumber(minutes, isExact) * timeItemHeight;
            }
        })
    });

Добрый день!
Для расширения логики ext.js необходимо:
1. Создать новый модуль, в котором зарегистрировать новый модуль, расширяющий базовый

define("UsrModule", [],
    function() {
        Ext.define("Terrasoft.configuration.UsrModule", {
            extend: "Terrasoft.SomeBaseModule",
            alternateClassName: "Terrasoft.UsrModule",
 
            init: function () {
                this.callParent(arguments);
                // какая-то логика
            }
 
        })
 
    });               

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

this.viewModelClassName = "Terrasoft.SomeBaseModule";

необходимо в замещающем методе исправить на

this.viewModelClassName = "Terrasoft.UsrModule";

"Чубко Илья" написал:2. Найти и переопределить схему, в котором используется данный модуль и заменить на новое название и указав его в dependence,
т.е. если в методы было

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

Должен же быть способ расширять логику уже объявленных классов не наследуясь и не заменяя логику использования по имени, для этого и придуманы, плагины, хуки, override

Переформулирую свой вопрос, как можно использовать Ext.override в парадигме платформы?

Ext.override можно использовать, но почему-то не рекомендуется и не встречается у Terrasoft.
Я через override полностью копировал весь модуль со всеми методами и изменял какие были необходимы

define("ITScheduleItem", [],
    function() {
 
        Ext.define("Terrasoft.controls.ITScheduleItem", {
            alternateClassName: "Terrasoft.ITScheduleItem",
            override: "Terrasoft.ScheduleItem",
 
            getTimePosition: function(date, isExact) {
                var timeItemHeight = this.timeItemHeight;
                var minutes = Terrasoft.getMinutesFromMidnight(date);
                return this.getTimeItemNumber(minutes, isExact) * timeItemHeight;
            }
        })
    });
Показать все комментарии

Достаточно простой вопрос, мне нужно сделать INSERT && SELECT из созданной мною таблицы
Если я правильно понял, я создал в пакете объект, дал ему имя скажем UsrTest
http://joxi.ru/RmzkDq7s0Z3vE2
Унаследовался от BaseObject Туда подтянулись базовые колонки id created modified
У меня есть WebService который слушает GET параметр, и вставляет его в базу данных.
Вопрос как сделать вставку и выборку на сороне сервера
В доках присуствует некий UserConnection который я хз как получить или откуда его взять

public string callback(string data)
                {
                        var request = HttpContext.Current.Request;
                        //NEED TO INSERT request["param"] to DB UsrTest to field "name"

                        //NEED TO SELECT ALL FROM TABLE AND RETURN
                }

UPD: Field name вымышлен, но не суть важно

Нравится

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

Здравствуйте. Вам должна помочь эта ссылка
https://academy.terrasoft.ru/documents/technic-sdk/7-10/crud-operacii-n…
Есть два подхода
Использование методов Select и Insert
Использование EntitySchemaQuery

"Роман Симута" написал:

Здравствуйте. Вам должна помочь эта ссылка

https://academy.terrasoft.ru/documents/technic-sdk/7-10/crud-operacii-na...

Есть два подхода

Использование методов Select и Insert

Использование EntitySchemaQuery

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

[OperationContract]
		[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public string set(string data)
		{
			var userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];
			var insert = new Insert(userConnection).Into("UsrTest")
			.Set("UsrAccessTokenString", Column.Const("SOME_TOKEN"))
			.Set("UsrAccessTokenRefresh", Column.Const("SOME_REFRESH_TOKEN"));
			return "Hello";
		}
 
		[OperationContract]
		[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
		public string get(string data)
		{
			var text = "Data: ";
			var userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];
			Select selectQuery = new Select(userConnection)
				.Column("UsrAccessTokenString")
				.Column("UsrAccessTokenRefresh")
				.From("UsrTest");
			// Выполнение запроса к базе данных и получение результирующего набора данных.
			using (DBExecutor dbExecutor = userConnection.EnsureDBConnection())
			{
				using (IDataReader reader = selectQuery.ExecuteReader(dbExecutor))
				{
					while (reader.Read())
					{
						text = "TOKEN: " + reader.GetString(0) + " REFRESH: " + reader.GetString(1) + "; ";
					}
				}
			}
			return text;
		}

У меня создан обьект с именем UsrTest и там соответственно колонки, но когда я стучусь на get() я получаю exception: The exception message is 'Invalid object name 'dbo.UsrTest'.'
Объект назван так как указано в запросе

И сразу еще один вопрос, можно ли посмотреть данные в БД (если разработка идет on-cloud)

UPD: Ошибка пропала когда в пакете кликнул по объекту проавкой кнопкой мыши и выбрал обновление структуры базы

Посмотреть данные в БД, если разработка на on-cloud, можно используя партнерский модуль для работы с SQL запросами. Подробнее информация по ссылке: http://samarasoft.com/sql-console/?utm_source=community&utm_medium=web

при создании объекта вы его публиковали? если нет, то не была создана таблица в бд

Добрый день.

Ошибка свидетельствует о том, что таблицы с именем UsrTest нет. Скорей всего объект не был опубликован или же поле 'Название' не содержит 'UsrTest'.

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

Добрый день!

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

Нравится

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

Пока такой возможности нет.
В теории можно добавить такое пожелание в 'Идеи' и, возможно, в одной из следующих версий она будет реализована :wink:

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

Пожелание зарегистрировали.

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

Есть потребность на страницу редактирования добавить поле, по которому будет выполняться фильтрация в детали.
Добавлять текстовое поле в EntitySchemа страницы неправильно, так как это значение нужно только для поиска и хранится в таблице не должно.
1. Каким образом я могу добавить такое поле, в которое можно вводить текст, но в тоже время оно не будет связано с полем в EntitySchemа?
2. Корректно ли для этого использовать Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN?
3. Какие ещё есть варианты реализации?
+ Для наглядности хотелось бы пример добавления такого поля :smile:

Нравится

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

1. Просто добавить и привязать под атрибут нужного типа.
2. Именно так.
3. Да собственно никаких, атрибут и диф под него.

Пример:

define("ContactAddressPageV2", [],
    function() {
        return {
            attributes: {
                "UsrKladrStreet": {
                    dataValueType: Terrasoft.DataValueType.LOOKUP
                },
                "UsrVirtualKladrStreet": {
                    "dataValueType": Terrasoft.DataValueType.LOOKUP,
                    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    isLookup: true,
                    caption: "virtual street",
                    referenceSchemaName: "UsrKladrStreet"
                }
            },
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "insert",
                    "parentName": "Header",
                    "propertyName": "items",
                    "name": "UsrKladrStreet",
                    "values": {
                        bindTo: "UsrKladrStreet",
                        "caption": {"bindTo": "Resources.Strings.UsrKladrStreetCaption"},
                        layout: {column: 0, row: 8, colSpan: 12}
                    }
                },
                {
                    "operation": "insert",
                    "parentName": "Header",
                    "propertyName": "items",
                    "name": "UsrVirtualKladrStreet",
                    "values": {
                        bindTo: "UsrVirtualKladrStreet",
                        "caption": "virtual street",
                        layout: {column: 0, row: 9, colSpan: 12}
                    }
                }
            ]/**SCHEMA_DIFF*/
        };
    }
);
Показать все комментарии

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

Есть пакет UsrPkg, который установлен как текущий пакет и все доработки хранятся в нем. пакет зависит от SalesEnterpriseSoftKey_RUS, SalesEnterpriseSoftKey, от пакета UsrPkg зависит Custom.

При попытке зафиксировать пакет UsrPkg в хранилище svn выходит ошибка "Пользовательский пакет не может быть зафиксирован в хранилище".
Я думала, что при попытке установки UsrPkg тянет за собой Custom, так как изначально в Custom были несколько доработок, но сейчас они удалены. перезапуск iis, очистка redis, очистка кэша проводились.
при открытии окна свойств пакета, где указаны название, версия и пр. для пакета usrPkg нет поля Хранилище системы контроля версий, для всех остальных пакетов это поле есть.
в базе данных у пакета usrPkg в поле sysrepositoryid прописан гуид нужного хранилища

Подскажите, пожалуйста, в чем может быть дело

Версия 7.10.0.1742

Нравится

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

Дополнительная информация: при открытии окна свойств пакета, где указаны название, версия и пр. для пакета usrPkg нет поля Хранилище системы контроля версий, для всех остальных пакетов это поле есть.
в базе данных у пакета usrPkg в поле sysrepositoryid прописан гуид нужного хранилища

Добрый день, Любовь.

Данное поведение пожет наблюдаться в случае если пакет UsrPkg указан в системной настройке [Идентификатор пользовательского пакета] (CustomPackageUId). В данной настройке должен быть указан пакет Custom.

Дополнительно прилагаю инструкцию по работе с пользовательскими пакетами (https://academy.terrasoft.ru/documents/technic-sdk/7-10/sozdanie-polzov…) и ссылку на статью об особенностях пакета Custom (https://academy.terrasoft.ru/documents/technic-sdk/7-10/paket-custom).

"Мария Ватулина" написал:Данное поведение пожет наблюдаться в случае если пакет UsrPkg указан в системной настройке [Идентификатор пользовательского пакета] (CustomPackageUId). В данной настройке должен быть указан пакет Custom

Большое спасибо! дело и правда оказалось в этом

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

Всем доброго времени суток.
Версия 7.10.

В схеме CtiPanelModelUtilities есть метод звонка callByNumber, внутри которого есть вызов метода this.makeCall(number);

Где определён метод makeCall? Никак не могу найти.

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

Нравится

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

Денис, здравствуйте!

Метод функция makecall зависит от используемой библиотеки интеграции с телефонией, один из примеров можно найти в WebitelModule в пакете WebitelCore.

P.S.: Карточка звонка появляется не только при исходящем звонке, но и при входящем.

Илья, метод нашёл.

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

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

Денис, думаю описание существующих интеграций в SDK должно помочь - https://academy.terrasoft.ru/documents/technic-sdk/7-10/integraciya-s-t…

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

Решили сделать свою карточку, тем более, что там предполагаются ещё некоторые изменения. Создал свою карточку в ctiPanel, забиндил её на виртуальную колонку myIdentificationPanelVisible (по умолчанию false):

{
					"operation": "insert",
					"name": "myIdentificationPanelWrap",
					"parentName": "ctiPanelMainContainer",
					"index": 1,
					"propertyName": "items",
					"values": {
						"id": "MyIdentificationPanelWrap",
						"selectors": {"wrapEl": "#IdentificationPanelWrap"},
						"itemType": Terrasoft.ViewItemType.CONTAINER,
						//"wrapClass": ["identification-panel"],
						"visible": {"bindTo": "myIdentificationPanelVisible"},
						"items": []
					}
				},

Есть ещё атрибуты Имени контакта и Номера, выведенные под них блоки, а также кнопки - взять трубку и положить, всё как обычно. Далее в той же схеме ctiPanel в onCallCustomer (для примера тестирую там) делаю вызовы

onCallCustomer: function(numberInfo) {
 
					this.sandbox.publish("SelectCommunicationPanelItem", {selectedItem: "CtiPanel"});
 
					//Показываем панельку
					this.set("myIdentificationPanelVisible",true);
					this.set("myContactNumber",numberInfo.number);					
}

То есть по сути даём задание - показать карточку, и вывести номер контакта. Номер контакта выводится внутрь блока:

{
					"operation": "insert",
					"name": "mySubscriberName",
					"parentName": "myIdentificationDataPanel",
					"propertyName": "items",
					"values": {
						"id": "mySubscriberName",
						"itemType": Terrasoft.ViewItemType.BUTTON,
						"caption": {"bindTo": "myContactName"},
						"tag": "Name",
						"visible": true,
						"style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
					}
				},

На практике по вызову onCallCustomer панель показывается, но в консоль вываливается ошибка: Элемент не создан (см. скрин). Соответственно, также не работают кнопки (подвесил на click bindTo функцию - не вызывается), и т.д.

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

UPD: Даже если я изначально в дифф у myIdentificationPanelWrap ставлю visible:true и после его вообще не трогаю - ошибка пропадает, но ни подстановка, ни кнопки всё равно не работают.

Вроде разобрался что-то с вложением блоков не то.

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