Добрый день, Коллеги!

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

Однако столкнулся со следующей трудностью:

Контейнер, в котором отображается реестр представляет из себя:

"operation": "insert",
"name": "DataGrid",
"parentName": "gridContainer",
"propertyName": "items",
"values": {
		"itemType": Terrasoft.ViewItemType.CONTAINER,
		"className": "Terrasoft.ContainerList"
........
}

Судя по описанию класса сам по себе он не поддерживает иерархию

Однако, существует расширение класса "HierarchicalContainerList"

Возникают следующие вопросы:

1) Актуален ли класс HierarchicalContainerList на текущий момент. Если ли примеры его явного использования? Сможет ли он поддержать иерархическую структуру?

2) При попытке обращения к нему в виде:

"generator": "ConfigurationItemGenerator.generateHierarchicalContainerList"

Не совсем понимаю как именно задать нужные свойства

nestedItemsAttributeName и nestedItemsContainerId:

generateHierarchicalContainerList: function(config, generatorConfig) {
			var containerListConfig = this.generateContainerList(config, generatorConfig);
			containerListConfig.className = "Terrasoft.HierarchicalContainerList";
			Ext.merge(containerListConfig, {
				nestedItemsAttributeName: config.nestedItemsAttributeName,
				nestedItemsContainerId: config.nestedItemsContainerId
			});
			return containerListConfig;
		}

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

А вот nestedItemsContainerId, не совсем понятно. Похоже что этот атрибут должен принимать сам Id родительской записи.

 

Коллеги, буду благодарен за любую информацию, спасибо!

Нравится

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

Титаев Александр Николаевич,

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

 

Реализовывал такую же задачу, но не нашел, как сделать ContainerList иерархичестим. Я полностью менял контрол страницы подбора из ContainerList на Grid а точнее на HierarchialGrid.







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







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

 

Александр, судя по упоминаниям в коде, HierarchicalContainerList  используется для отображения параметров в карточке настройки элемента БП (например, вызова подпроцесса и веб-сервиса). Случаев его применения для реестра не вижу.

 

Для реализации древовидных реестров есть дополнение, но оно платное. Вот обсуждение с тех времён, когда ещё было бесплатным.

 

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

 

В «коробке» есть древовидная деталь структуры проекта, реализованная в схеме ProjectStructureDetailV2:

{
	"operation": "merge",
	"name": "DataGrid",
	"values": {
		"id": "StructureGrid",
		"type": "listed",
		"hierarchical": true,
		"sortColumnDirection": {"bindTo": "disableGridSorting"},
		"hierarchicalColumnName": "ParentId",
		"updateExpandHierarchyLevels": {
			"bindTo": "onExpandHierarchyLevels"
		},
		"expandHierarchyLevels": {
			"bindTo": "expandHierarchyLevels"
		},

Там же приведены функции onExpandHierarchyLevels, clearExpandHierarchyLevels, removeExpandHierarchyLevel и другие, реализующие логику древовидности.

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

Спасибо за подсказку! Да, со схемами и сервисами детали ознакамливался в процессе анализа.

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

Дополнение или очевидное задание иерархии при использовании "Terrasoft.ContainerList" на сколько я понял, не возможно (уже пробовал).

Буду думать как выходить из ситуации. Ещё раз спасибо!

 

Титаев Александр Николаевич,

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

 

Реализовывал такую же задачу, но не нашел, как сделать ContainerList иерархичестим. Я полностью менял контрол страницы подбора из ContainerList на Grid а точнее на HierarchialGrid.







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







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

 

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

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

Да. CSS поможет с этим.

Но мне не нравится чекбокс так же. В контейнерлисте были видны сразу все чекбоксы и отмечал, что мне нужно. А в гриде просто Да/Нет видно. И только при активации строки появляется чекбокс.

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

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

Вроде незначительно, но для пользователя менее удобно

Владислав, галочки и да/нет в реестре обсуждались тут, также ранее заведена идея об этом.

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

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



На странице обращений располагается грид - http://joxi.ru/LmGg9DxUJdJ1dm

В отображении грида была проставлена галочка в фильтре-флаге "Отображать закрытое".

При редактировании дашбордов секции (были добавлены две цифры 5 в конце) http://joxi.ru/LmGg9DxUJdJzdm и последующем сохранении



Случается следующее:



При переключении на отображение грида данные из колонок будто бы "пропадают" - http://joxi.ru/zANMzV8F6O6Ln2



Данная проблема наблюдается только при включенном флаге "Отображать закрытые".



В консоли разработчика никаких ошибок не наблюдается, запросы уходят корректно. 

Алгоритм действий при отключенном флаге-фильтре корректно отрабатывает.



Кто-нибудь сталкивался с подобным? Является ли это ошибкой\недоработкой в базовом коде клиентского модуля Creatio?

Нравится

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

Отправили запрос в тех. поддержку - назвали багом, в итоге получили фикс. Фикс вошел в состав 7.16.1

Отправили запрос в тех. поддержку - назвали багом, в итоге получили фикс. Фикс вошел в состав 7.16.1

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

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

Как унаследовать конфигурацию Grid и столбцов из DocumentDetail, чтобы Grid каждой группы выглядел идентично гриду детали? Т.е, 1)Имел идентичный набор столбцов. 2) Имел идентичные настройки внешнего вида, стилизацию.

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

 

//diff:

            {               

                "operation": "merge",

                "name": "Detail",

                "values": {

                    }

                }

            },                        

            {

                "operation": "insert",

                "parentName": "Detail",

                "name": "DocumentsTestList",

                "propertyName": "items",

                "values": {

                    "generator": "ConfigurationItemGenerator.generateContainerList",

                    "idProperty": "Id",

                    "itemPrefix": "BorrowerDocGroup",

                    "collection": "BorrowerDocGroupsCollection",

                    "onGetItemConfig": "getDocsControlGroupConfig"

                }

            }

//methods:

getDocsControlGroupConfig: function (itemConfig, item) {             

               

                var itemId = item.get("Id");

                var testItemGroupConfig = {

                    "className": "Terrasoft.ControlGroup",                    

                    "caption": {

                        "bindTo": "Caption"

                    },

                    "collapsed": true,

                    "id": "DocsGroup" + itemId,

                    "items": [{                        

                        "className": "Terrasoft.Grid",

                        "type": "listed",                        

                        "id": itemId,

                        "idProperty": "Id",

                        "itemPrefix": "Id",

                        "collection": {

                            "bindTo": "Collection"

                        },

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

//здесь мне хотелось бы написать "columnsConfig": { "bindTo: "...?????"}

                        "columnsConfig": [                            

                            {

                                cols: 1,

                                key: [

                                    {

                                        "name": {

                                            "bindTo": "MDocument"

                                        }

                                    } 

                                ]

                            }

                        ],

                        "captionsConfig": [

                            {

                                cols: 1,

                                name: "document caption"

                            }                            

                        ],

                        //"onGetItemConfig": {

                        //    "bindTo": "getDocItemViewConfig"

                        //},                                               

                        "dataItemIdPrefix": "document-item"                        

                    }]

                };               

                itemConfig.config = testItemGroupConfig;                

            },

   

Нравится

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

Ты создаешь внутри одной детали несколько гридов?

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



 

Ext.define("Terrasoft.controls.Название_твоего_грида", {

    alternateClassName: "Terrasoft.Название_твоего_грида",

    extend: "Terrasoft.ConfigurationGrid", // или Terrasoft.Grid

и переопределить методы 

/**
	 * Инициализирует начальное значение конфигурации колонок.
	 * @param {Object} gridConfig
	 * @return {Array}
	 */
	initColumnsConfig: function(gridConfig) {
		var type = gridConfig.type;
		var config = this[type + "Config"];
		var columnsConfig = (config ? config.columnsConfig : gridConfig.columnsConfig) || [];
		if (!gridConfig.columnsConfig) {
			gridConfig.columnsConfig = columnsConfig;
		}
		return columnsConfig;
	},

	/**
	 * Инициализирует начальное значение конфигурации заголовков.
	 * @param {Object} gridConfig
	 * @return {Array}
	 */
	initCaptionsConfig: function(gridConfig) {
		var type = gridConfig.type;
		var config = this[type + "Config"];
		var captionsConfig = (config ? config.captionsConfig : gridConfig.captionsConfig) || [];
		if (!gridConfig.captionsConfig) {
			gridConfig.captionsConfig = captionsConfig;
		}
		return captionsConfig;
	}

Если хочешь ещё и из детали получить конфигурацию, то встроенной реализации механизма сообщений нет. Придется в зависимостях прописать sandbox и инициализировать его в методе конструктора

constructor: function (config) {
    this.sandbox = new sandbox();
    this.sandbox.moduleName = "имя_модуля";

    this.sandbox.registerMessages({
        "имя_сообщения": {
            "direction": Terrasoft.MessageDirectionType.PUBLISH,
            "mode": Terrasoft.MessageMode.PTP
        }

    });

    this.callParent(arguments);
},

Как вариант, можно попробовать перехватить Profile в котором находятся конфиги на отображение в списочном и плиточном отображении (listedConfig и tiledConfig).

К примеру в методе initProfile после вызова this.callParent(arguments) взять this.get("Profile") и динамически изменить listedConfig и tiledConfig для изменения конфигуарации колонок грида.

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

Для примера вот как можно добавить колонку ответсственного в запрос детали с документами (DocumentDetailV2):

addProfileColumns: function(esq) {
  //берем колонки
  var profileColumns = this.getProfileColumns();
  //добавляем новую
  profileColumns.Owner = {
    aggregationType: undefined,
    caption: "Ответстсвенный",
    dataValueType: undefined,
    path: "Owner",
    subFilters: undefined,
    type: "text"
  };
  //а это взято из метода addProfileColumns из GridUtilitiesV2
  Terrasoft.each(profileColumns, function(column, columnName) {
    if (!esq.columns.contains(columnName)) {
      if (column.aggregationType) {
        this.addProfileAggregationColumn(esq, column, columnName);
      } else {
        esq.addColumn(columnName);
      }
    }
  }, this);
}

Таким образом в запросе уйдет и колонка отвественного.

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

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

Добрый день, возникла ошибка при попытке добавить левый грид с заказами в раздел "Заказы", по аналогии с "Активностями"

Возникает ошибка на строке "gridData.insert(0, key, item);"

addItemsToGridData: function(dataCollection, options) {
var gridData = this.getGridData();
debugger;
dataCollection = this.clearLoadedRecords(dataCollection);
dataCollection.eachKey(function(key, item) {
gridData.insert(0, key, item);
});
}

"all-combined.js:228 Uncaught Terrasoft.UnsupportedTypeException: null is unsupported type"

код модуля и детали в приложении.

Нравится

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

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

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

Добрый день!

Столкнулся со следующей проблемой. На гриде детали добавил поле числового типа с названием "MinPurchaseAmountEdit". Мне необходимо при переходе на эту страницу детали этому полю задавать некоторое значение. Делаю я это в событии "PageLoadComplete" (пробовал также в "Init"):

0

Код следующий:

Page.MinPurchaseAmountEdit.Value = 10m;

Компилируется всё отлично. Дебажится тоже. Присваиваемое значение "10" в формате "decimal" присваивается! Но, на самой странице в консоли возникает странное уведомление:

Uncaught ReferenceError: PageContainer_DetailGridContainer8021c0aacccf410e8f1da5c600f5d6ad_MinPurchaseAmountEdit is not defined

Насколько я понял, то система не видит это поле. Собственно, по этой причине карточка моей детали не открывается, т.е. она пустая:

2

Я так ранее делал - всё получалось без проблем. Сейчас - не понятно поведение системы. Прошу помощи!

Нравится

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

Можно ещё попробовать присваивать значение контролу при помощи метода:

Page.MinPurchaseAmountEdit.SetValue(10m);

Или же писать в поле источника данных:

Page.DataSource.ActiveRow.SetColumnValue("MinPurchaseAmount", 10m);

Спасибо, Александр, что подсказали, но:
- в первом варианте ошибка та же: система не видит контрола на странице (та же ошибка в консоли браузера);
- во втором случае даже страница не открылась, а система выдала ошибку:

Exception Message: Ссылка на объект не указывает на экземпляр объекта.
Exception Type: System.NullReferenceException
Exception Source: TSBpm

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

3

Возможно, дело в том, что это деталь с гридом, а не карточка.
И на момент PageLoadComplete её источник данных ещё не привязан к конкретной записи. А поле привязано к источнику.

Не знаю, что именно хотите сделать, но, может, надо было вязать к событию смены записи на самом гриде (детали) DataSourceActiveRowChanged или событию смены записи в основном реестре (разделе) GridPageRefreshRow.

У меня задача в том, чтобы заполнять это поле "MinPurchaseAmountEdit" данными из БД, и заполняться она должна в момент первого обращения к странице детали, а именно в момент перехода на неё после открытия карточки, к которой привязана деталь. Здесь событие смены записи на самом гриде или в основном реестре точно не подойдут.

Дело в том, что для всех записей этого грида значение "MinPurchaseAmountEdit" одинаково и мне нужно выводить это значение (если оно отлично от нуля!) и присваивать это значение контролу. Это всё при первом переходе на грид детали. Непонятно, почему кнопки, которые на этой детали находятся ("Добавить", "Изменить" и др.) обнаруживаются и на них система не ругается, а при добавлении контрола в этот же контейнер к кнопкам BPM его (контрол) не видит...

Кроме того, "на момент PageLoadComplete её источник данных ещё не привязан к конкретной записи" - тут дело даже не в источнике данных, т.к. я просто работаю с элементами на странице:

Page.MinPurchaseAmountEdit.SetValue(10m);

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

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

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

"они могут вызываться и при первом выборе записи." - но ведь поле должно обновляться при первичном открытии страницы этой детали. Неужели такой возможности нет в функционале BPM?

Сделал поле без привязки к БД:

4

Ошибка та же самая - система не видит моего контрола. Куда ещё "копать"?

P.S.: Значение "UId" на скринах разное, т.к. я удалял элемент, компилировал и добавлял новый такой же, чтобы убрать его привязку к БД, иначе система ругается - NullReferenceException...

Попробуйте найти в других разделах такую же логику — поле ввода на странице реестра.
Если такое не встречается, то, вероятно, и не предусматривалось. Деталь служит для вывода информации в табличном виде, а не ввода. Можете добавить кнопку и по ней открывать окно с этим полем или что-то подобное.

Странно... Просто возникает тогда другой вопрос: если после события завершения загрузки страницы (см. скрин бизнес-процесса) система не видит все контролы на этой странице, то...... когда же они там инициализируются? Вопрос, видимо, философский((

Всё равно спасибо, Александр, что поучаствовали в обсуждении. Хорошего Вам дня!

Да, действительно странно. А Вы пробовали именно с полем ввода, если выводить в название кнопки или простой надписи, то отрабатывает нормально?

Попробовал добавить надпись с названием "Label1" и заголовком "Надпись 1", предварительно удалив поле ввода дробного числа и скомпилировав модуль. После этого в то же событие "PageLoadComplete" добавил код:

Page.Label1.Caption = "etqtert";

Когда скомпилировал модуль и открыл страницу детали, она открылась!!!! Но:

5

Вопрос: откуда там взялся контрол, который я до этого удалил - непонятно... И в структуре он тоже был. Но самое приятное то, что "Caption" у надписи поменялся (заметить по картинке трудно, но возможно)! При этом код:

Page.MinPurchaseAmountEdit.SetValue(10m);

был закомментирован.

Я удалил поле ввода дробного числа снова, удалил надпись, закомментировал код по переприсвоению "Caption" в надписи и раскомментировал код по установке значения в "MinPurchaseAmountEdit". Скомпилировал. Страница детали не открылась... :cry: Ошибка та же.

ВЫВОД: Изменение поля ввода дробного числа нельзя изменять ни в одном событии страницы до того пока она хотя бы один раз не прорисуется (ну или лыжи не едут...). Но это не применимо к остальным контролам. К сожалению(

А для поля ввода строки такое же самое поведение, что и для поля ввода числа?

Да, эти контролы ведут себя одинаково: поле ввода строки тоже не определено в событии "MinPurchaseAmountEdit". Ошибка та же.

Судя по сообщению:

Uncaught ReferenceError: PageContainer_DetailGridContainer8021c0aacccf410e8f1da5c600f5d6ad_MinPurchaseAmountEdit is not defined

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

Контрол идентифицируется браузером как:
http://i.piccy.info/i9/d0f1d2f7db16bc88df4890afcb8e71e5/1458115070/2764…

ПРИ ЭТОМ! Если никаких обращений к этому контролу ни в каком событии не писать, типа:

Page.MinPurchaseAmountEdit.SetValue(10m);

то, контрол система обнаруживает НОРМАЛЬНО! А если написать к нему обращение в виде предыдущего кода, то система разводит руками и говорит, что не знает, чего я от неё хочу. Похоже, она женского пола...

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

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

Коллеги, доброго дня!
Возможно, кто-то сталкивался с необходимостью скрывать/отображать кнопки в реестре по условию? Пример из документации SDK не получилось адаптировать:

isCategory: function() {
        var activeRow = this.get("ActiveRow");
        if (activeRow)
                    {
                        var cat = this.get("GridData").get(activeRow).get("Category");
                        return (cat == "ID_нужной_категории") ? true : false;
                    }
       return false;
}

Необходимо в зависимости от категории и состояния Активности скрывать и отображать различные кнопки

Нравится

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

Антон, у Вас в в переменной cat хранится объект с value и displayValue.
Для сравнения с "ID_нужной_категории" нужно брать cat.value.
Также важно, что если у вас не будет выведена колонка в реестр, то вы не сможете получить ее значение.
Для того, чтобы необходимая колонка всегда тянулась в ActiveRow можете переопределить следующий метод:

getGridDataColumns: function(){
                var gridDataColumns = this.callParent(arguments);
                gridDataColumns.Category= gridDataColumns.Category|| {path: "Category"};
                return gridDataColumns;
            }

Александр, спасибо, однако это не помогло, к сожалению. Как только делаю привязку свойства visible к функции isComplectationCategory, так сразу кнопка пропадает независимо от категории выбранной активности. Изменение условия проверки (с "==" на "!=") не помогает, кнопка в любом случае скрыта.

Вот полный код ActivitySectionV2:

define("ActivitySectionV2", ['ConfigurationConstants', 'ProcessModuleUtilities'],
	function(ConfigurationConstants, ProcessModuleUtilities) {
		return {
			entitySchemaName: "Activity",
			methods: {
						// добавляем новые пункты в меню "Действия"
				getSectionActions: function() {
					var actionMenuItems = this.callParent(arguments);
					actionMenuItems.addItem(this.getButtonMenuItem({
						Type: "Terrasoft.MenuSeparator",
						Caption: "Задачи на комплектацию"
					}));
					actionMenuItems.addItem(this.getActionsMenuItem({
						Caption: "Взять в работу",
						Click: {bindTo: "Get2Work"}
				}));
					return actionMenuItems;
				},
						// отработка нажатия пункта "Взять в работу" в "Действиях"
				Get2Work: function() {
					debugger;
					var processArgs = {
						sysProcessName: "UsrProcessGet2Work",
							parameters: {
							IncomingActivitiesList: this.getSelectedItems()
								}
					};
					ProcessModuleUtilities.executeProcess(processArgs);
				},
						// выбор функций для отработки нажатий кнопок в реестре
				onActiveRowAction: function(buttonTag, primaryColumnValue) {
					switch (buttonTag) {
						case "ComplectationFinished":
							this.ComplectationFinishedProcess(primaryColumnValue);
							break;
						case "Sended":
							this.SendedProcess(primaryColumnValue);
							break;
						case "SamplesReceived":
							this.SamplesReceivedProcess(primaryColumnValue);
							break;
						default:
							this.callParent(arguments);
							break;
					}
				},
						// отработка кнопки "Скомплектовано"
				ComplectationFinishedProcess: function(recordId) {
					debugger;
					var activeRow = this.get("ActiveRow");
					var processArgs = {
						sysProcessName: "UsrComplectationFinishedProcess",
							parameters: {
								recordId: activeRow
							}
					};
					ProcessModuleUtilities.executeProcess(processArgs);
				},
						// отработка кнопки "Отправлено"
				SendedProcess: function(recordId) {
					debugger;
					var activeRow = this.get("ActiveRow");
					var processArgs = {
						sysProcessName: "UsrSendedProcess",
							parameters: {
								recordId: activeRow
							}
					};
					ProcessModuleUtilities.executeProcess(processArgs);
				},
						// отработка кнопки "Образцы получены"
				SamplesReceivedProcess: function(recordId) {
					debugger;
					var activeRow = this.get("ActiveRow");
					var processArgs = {
						sysProcessName: "UsrSamplesReceivedProcess",
							parameters: {
								recordId: activeRow
							}
					};
					ProcessModuleUtilities.executeProcess(processArgs);
				},
						// установка видимости кнопки "Скомплектовано", если категория активности == "Комплектация"
				isComplectationCategory: function() {
					var activeRow = this.get("ActiveRow");
					if (activeRow) {
						var cat = this.get("GridData").get(activeRow).get("ActivityCategory");
						return (cat.value != "4b9497c0-e794-40bc-81e0-5f46c9bde343") ? true : false;	// 4b9497c0-e794-40bc-81e0-5f46c9bde343 категория "Комплектация"
					}
					return false;
				},
				getGridDataColumns: function() {
					var gridDataColumns = this.callParent(arguments);
					gridDataColumns.ActivityCategory= gridDataColumns.ActivityCategory|| { path: "ActivityCategory" };
					return gridDataColumns;
				}
			},
			diff: /**SCHEMA_DIFF*/[
						// вставка кнопки "Скомплектовано"
				{ 
					"operation": "insert",
					"name": "ComplectationFinishedAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"caption": "Скомплектовано",
						"style": Terrasoft.controls.ButtonEnums.style.GREEN,
						"tag": "ComplectationFinished",
						"visible": {"bindTo": "isComplectationCategory"}
					}
				},
						// ставка кнпоки "Отправлено"
				{ 
					"operation": "insert",
					"name": "SendedAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"caption": "Отправлено",
						"style": Terrasoft.controls.ButtonEnums.style.GREEN,
						"tag": "Sended"
					}
				},
						// вставка кнопки "Образцы отправлены"
				{ 
					"operation": "insert",
					"name": "SamplesReceivedAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"caption": "Образцы получены",
						"style": Terrasoft.controls.ButtonEnums.style.GREEN,
						"tag": "SamplesReceived"
					}
				}
			]/**SCHEMA_DIFF*/
		};
	}
);

При установке внутрь функции isComplectationCategory точек остановки или уведомлений ничего не происходит - ощущение, что при выборе текущей строки реестра эта функция не срабатывает. Может, что-то ещё упустил в коде?

И ещё бы весьма признателен за подсказку, как скрыть стандартные кнопки в реестре

Попробуйте создать атрибут и забиндить видимость на него. Изменять состояние атрибута можно при изменении активного столбца, например.
А какие именно стандартные кнопки нужно скрыть? Они либо в diff по названию удаляются,либо методы, которые их формируют нужно сделать пустыми.
В этой теме есть пример:
http://www.community.terrasoft.ru/forum/topic/15106

Снова не помогло:

define("ActivitySectionV2", ['ConfigurationConstants', 'ProcessModuleUtilities'],
	function(ConfigurationConstants, ProcessModuleUtilities) {
		return {
			entitySchemaName: "Activity",
			attributes: {
				'isComplectationCategoryAttribut': {
					type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
					dataValueType: Terrasoft.DataValueType.BOOLEAN,
					dependencies: [{
						columns: ["ActivityCategory"],
						methodName: "isComplectationCategoryAttributSet"
					}]
				}
			},
			methods: {
						// добавляем новые пункты в меню "Действия"
				getSectionActions: function() {
					var actionMenuItems = this.callParent(arguments);
					actionMenuItems.addItem(this.getButtonMenuItem({
						Type: "Terrasoft.MenuSeparator",
						Caption: "Задачи на комплектацию"
					}));
					actionMenuItems.addItem(this.getActionsMenuItem({
						Caption: "Взять в работу",
						Click: {bindTo: "Get2Work"}
				}));
					return actionMenuItems;
				},
				isComplectationCategoryAttributSet: function() {
					var activeRow = this.get("ActiveRow");
					var cat = this.get("GridData").get(activeRow).get("ActivityCategory");
					this.set('isComplectationCategoryAttribut', cat.value === "4b9497c0-e794-40bc-81e0-5f46c9bde343")
					return true;	// 4b9497c0-e794-40bc-81e0-5f46c9bde343 категория "Комплектация"
				},
						// отработка нажатия пункта "Взять в работу" в "Действиях"
				Get2Work: function() {
					debugger;
					var processArgs = {
						sysProcessName: "UsrProcessGet2Work",
							parameters: {
							IncomingActivitiesList: this.getSelectedItems()
								}
					};
					ProcessModuleUtilities.executeProcess(processArgs);
				},
						// выбор функций для отработки нажатий кнопок в реестре
				onActiveRowAction: function(buttonTag, primaryColumnValue) {
					switch (buttonTag) {
						case "ComplectationFinished":
							this.ComplectationFinishedProcess(primaryColumnValue);
							break;
						case "Sended":
							this.SendedProcess(primaryColumnValue);
							break;
						case "SamplesReceived":
							this.SamplesReceivedProcess(primaryColumnValue);
							break;
						default:
							this.callParent(arguments);
							break;
					}
				},
						// отработка кнопки "Скомплектовано"
				ComplectationFinishedProcess: function(recordId) {
					debugger;
					var activeRow = this.get("ActiveRow");
					var processArgs = {
						sysProcessName: "UsrComplectationFinishedProcess",
							parameters: {
								recordId: activeRow
							}
					};
					ProcessModuleUtilities.executeProcess(processArgs);
				},
						// отработка кнопки "Отправлено"
				SendedProcess: function(recordId) {
					debugger;
					var activeRow = this.get("ActiveRow");
					var processArgs = {
						sysProcessName: "UsrSendedProcess",
							parameters: {
								recordId: activeRow
							}
					};
					ProcessModuleUtilities.executeProcess(processArgs);
				},
						// отработка кнопки "Образцы получены"
				SamplesReceivedProcess: function(recordId) {
					debugger;
					var activeRow = this.get("ActiveRow");
					var processArgs = {
						sysProcessName: "UsrSamplesReceivedProcess",
							parameters: {
								recordId: activeRow
							}
					};
					ProcessModuleUtilities.executeProcess(processArgs);
				},
						// установка видимости кнопки "Скомплектовано", если категория активности == "Комплектация"
				/*isComplectationCategory: function() {
					debugger;
					var activeRow = this.get("ActiveRow");
					debugger;
					if (activeRow) {
						var cat = this.get("GridData").get(activeRow).get("ActivityCategory");
						debugger;
						return (cat.value === "4b9497c0-e794-40bc-81e0-5f46c9bde343") ? true : false;	// 4b9497c0-e794-40bc-81e0-5f46c9bde343 категория "Комплектация"
					}
					return false;
				},*/
				getGridDataColumns: function() {
					var gridDataColumns = this.callParent(arguments);
					gridDataColumns.ActivityCategory= gridDataColumns.ActivityCategory|| { path: "ActivityCategory" };
					return gridDataColumns;
				}
			},
			diff: /**SCHEMA_DIFF*/[
						// вставка кнопки "Скомплектовано"
				{ 
					"operation": "insert",
					"name": "ComplectationFinishedAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"caption": "Скомплектовано",
						"style": Terrasoft.controls.ButtonEnums.style.GREEN,
						"tag": "ComplectationFinished",
						"visible": {"bindTo": "isComplectationCategoryAttribut"}
					}
				},
						// ставка кнпоки "Отправлено"
				{ 
					"operation": "insert",
					"name": "SendedAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"caption": "Отправлено",
						"style": Terrasoft.controls.ButtonEnums.style.GREEN,
						"tag": "Sended"
					}
				},
						// вставка кнопки "Образцы отправлены"
				{ 
					"operation": "insert",
					"name": "SamplesReceivedAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"caption": "Образцы получены",
						"style": Terrasoft.controls.ButtonEnums.style.GREEN,
						"tag": "SamplesReceived"
					}
				}
			]/**SCHEMA_DIFF*/
		};
	}
);

Кнопка теперь всегда скрыта. Подозреваю, что для Section некорректно писать type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN, или вообще где-то глобально ошибаюсь?

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

{
				"operation": "remove",
				"name": "DataGridActiveRowDeleteAction"
}

где "DataGridActiveRowDeleteAction" это название кнопки, взятое из BaseSectionV2

Антон, для наглядности оставил только 1 кнопку и соответствующие методы.
Обратите внимание на метод addColumnLink. Без него зависимость видимости не срабатывает.
Пример найден в LeadSectionV2.

define("ActivitySectionV2", ["terrasoft",'ConfigurationConstants', 'ProcessModuleUtilities'],
    function(Terrasoft,ConfigurationConstants, ProcessModuleUtilities) {
        return {
            entitySchemaName: "Activity",
            attributes: {},
            methods: {
 
                addColumnLink: function(item) {
                    var self = this;
                    item.isComplectationCategoryAttributSet= function() {
                        return self.isComplectationCategoryAttributSet.call(self, this.get(this.primaryColumnName));
                    };
                    return this.callParent(arguments);
                },
 
                isComplectationCategoryAttributSet: function(activeRow) {
                    if (!activeRow) return true;
                    var cat = this.get("GridData").get(activeRow).get("ActivityCategory");
                    return cat&&cat.value === "f51c4643-58e6-df11-971b-001d60e938c6"; //категория = выполнить. Для теста
                    //return cat&&cat.value === "4b9497c0-e794-40bc-81e0-5f46c9bde343"; //категория "Комплектация"
 
                }
            },
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "insert",
                    "name": "ComplectationFinishedAction",
                    "parentName": "DataGrid",
                    "propertyName": "activeRowActions",
                    "values": {
                        "className": "Terrasoft.Button",
                        "caption": "Скомплектовано",
                        "style": Terrasoft.controls.ButtonEnums.style.GREEN,
                        "tag": "ComplectationFinished",
                        "visible": {"bindTo": "isComplectationCategoryAttributSet"}
                    }
                }
            ]/**SCHEMA_DIFF*/
        };
    }
);

Александр, прекрасно! Ваше решение работает, большое спасибо

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

Есть деталь "Регион проведения мероприятия" с полями "Страна" и "Регион". На странице детали так же есть еще одна деталь "Города". Стоит задача выводит в реестр детали страну, регион и список городов. Подскажите, как лучше реализовать данный функционал?

Нравится

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

Здравствуйте, Олег!

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

На самом деле особой надобности выводить список городов нет. Только в целях удобства. Можно поподробнее про вывод агрегируемой ф-ей? Или может эта тема есть в SDK? А там уже видно будет - стоит задачу решать, или оставить стандартный функционал.

Олег,
Агрегирующие функции производят вычисление одного «собирающего» значения (суммы, среднего, максимального, минимального значения и т. п.) для заданных групп строк таблицы.
То есть, вывести значения по городам невозможно, возможно лишь посчитать кол-во городов.

http://academy.terrasoft.ru/documents/docs/product/bpm'online%20real%20estate/real%20estate/7.6.0/BPMonlineHelp/chapter_list_setting/chapter_list_setting_columns.htm

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

Добрый день!
Столкнулся с такой проблемой:
При попытке раскрасить грид (LeadSection, переопределил onLoadData) новые стили (customStyle) успешно применяются только к первой видимой выборке в 15 записей, остальные же при прокрутке имеют дефолтный фон. Подскажите как решить эту проблему?
Версия 7.2

Нравится

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

Иван, добрый день!

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

Ок, прикреплен файл с кодом секции..
В коде (метод loadSelect) увеличен объем выборки данных до 500, как временное решение.

Добрый день!

Для решения задачи следует переопределить два метода - «onLoadData» и «loadGridCollectionItems». Пример кода во вложении.
examplesolution.txt

Спасибо, но такой подход решает проблему порождая другую. В методе "loadSelect" добавлены фильтры по ответственному и статусу лида для определенной роли. При переопределении метода «loadGridCollectionItems» этот фильтр перестает отрабатывать...

Спс, проблема решилась (фильтры убрал, сделал БП права на запись).

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

Добрый день!
Подскажите пожалуйста как сделать редактируемый реестр детали не редактируемым по условию в родительской записи (к примеру деталь продуты в заказе, состояние заказа == выполнен) в версии BPM 7.6?
Заранее благодарен...

Нравится

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

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

Редактируемый реестр довольно сильно отличается от обычного: это отдельный компонент системы, который хоть и является расширением Terrasoft.Grid, но многие его методы переопределены и работают совсем по-другому.

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

Если подобные варианты не подходят, и задача заключается именно в динамической подмене контрола обычного реестра (Terrasoft.Grid) на редактируемый (Terrasoft.ConfigurationGrid), можно попробовать следующий вариант: добавить на деталь два разных реестра и в зависимости от условия изменять видимость этих реестров, чтобы видимым всегда оставался только один из них. Возможно, придётся переопределить некоторые из методов, которые выполняют действия над строками реестра. Должен предупредить, что примеров решения подобных задач у нас пока не было.

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

Здравствуйте, Олег.

Это возможно сделать с помощью натсройки прав доступа [Администрируется по колонкам]

http://academy.terrasoft.ua/documents/docs/product/bpm'online%20sales/t…

Я имел ввиду блокировать их редактирование по условию, а не перманентно.

Блокирование отдельных ячеек записи в редактируемом реестре можно осуществить с помощью бизнес правил:
http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/AddBusines…

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

При добавлении, удалении или изменении записи детали "Бонусы", поле "Бонус по плану" каждой записи пересчитывается относительно суммы полей "Доля" всех записей. Пересчет реализован на сервере при событиях onSaved и onDeleted. Обновление грида детали происходит при помощи subscriber:

"SxProjectTeamBonus": {
"schemaName": "SxProjectTeamBonusDetailV2",
"entitySchemaName": "SxProjectTeamBonus",
"filter": {
"detailColumn": "SxProject",
"masterColumn": "Id"
},
subscriber:function(){
this.updateDetail(
{
detail: "SxProjectTeamBonus",
reloadAll: true
}
);
}
}
При удалении или изменении записи, в гриде детали на странице проекта отображаются верные значения. Но при добавлении правильные значения только у добавленной записи. Остальные же не обновляются. В базу заносятся правильные значения, но деталь просто отказывается обновляться.
Пробовал и this.updateDetail({detail: "SxProjectTeamBonus"}) и this.updateDetails() и при помощи SUBSCRIBE/PUBLISH.
Как заставить грид детали обновиться при добавлении новой записи?

Нравится

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

Решил проблему с помощью reloadEntity()
Но, может быть, все-таки есть способ обновить грид детали не обновляя страницу проекта?
Интересный факт - при нажатии на колонку грида, чтобы отсортировать по ней записи - данные обновляются.

Олег, добрый день!

Уточните, пожалуйста, версию, которую Вы используете.

Версия BPMOnline 7.5

Здравствуйте, Олег!

Рекомендую посмотреть процессы, реализованные в объекте "Продукт в заказе" - при добавлении или удалении записи запускается процесс, которые пересчитывает поле "Итого".
Аналогичным образом может быть реализована Ваша задача.

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

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