Уважаемые форумчане.
Вопрос по версии 7.6
Не получается сделать фильтрацию на детали.
Создал деталь активностей связанных контрагентов Activity на странице контрагента. Она похожа на деталь
Ативности в контрагенте, только она должна выдавать перечень активностей не текущего контрагента,
а активности контрагентов, которые связаны с текущим контрагентом. Связи контрагентов хранятся во
вьюхе VwAccountRelationship. В ней есть колонки AccountId и RelatedAccountId.
Сделал запрос

 SELECT * FROM Activity
INNER JOIN VwAccountRelationship ON Activity.AccountId = VwAccountRelationship.RelatedAccountId
WHERE VwAccountRelationship.AccountId = 'a40cfdfb-cd46-4c63-9448-44110861c12c'

a40cfdfb-cd46-4c63-9448-44110861c12c - Id текущего контрагента.
Этот запрос выдает верный результат. Там всего одна запись.
Но сделать с помощью фильтра на js не получается.
Пробовал следующий код, но он выдает кучу ненужных записей.
"Activity": {
                "schemaName": "SuSchema1Detail",
                "entitySchemaName": "Activity",
                "filter": {
                        "detailColumn": "Account",
                        "masterColumn": "Id"           
                },
                filterMethod: "activityFilter"
        }
methods: {
                        activityFilter: function() {
                                var currentAccount = this.get("Id");
                                var filterGroup = Ext.create("Terrasoft.FilterGroup");
                                filterGroup.add("CurrentAccountRelatedAccounts", Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
                                        "=[VwAccountRelationship:RelatedAccount:Account].Account", currentAccount));
                                return filterGroup;
                        }                              
                }

Заранее благодарен.

Нравится

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

Добрый день.

Создала деталь с выбором из справочника [ConfigItemModel] (создавала на основе примера: создание детали...)
Для детали был создан объект [UsrModelCIInSupplies].
Возникли ошибки при вызове окна справочника

1 ошибка
изображение 1
При этом окно справочника открывается, закрывается, дает фильтровать и дает возможность множественного выбора

2 ошибка. Вы выборе данных, они не вставляются в объект [UsrModelCIInSupplies].
изображение 2

Сам код детали

define("UsrSchema5Detail", ["ConfigurationEnums"],
        function(enums) {
        return {
                entitySchemaName: "UsrModelCIInSupplies",
                attributes: {},
                messages: {},
                methods: {
                        //колонки выбираемые запросом
                        getGridDataColumns: function() {
                                return {
                                        "Id": {path: "Id"},
                                        "UsrConfigItemModel": {path: "UsrConfigItemModel"},
                                        "UsrConfigItemModel.Name": {path: "UsrConfigItemModel.Name"}
                                };
                        },
                        //конфигурирует и отображает модальное окно справочника
                        openUsrConfigItemModelLookup: function() {
                                //конфигурирует объект
                                var config = {
                        //название схемы объекта, записи которого будут отображены в справочнике
                                        entitySchemaName: "ConfigItemModel",
                                        //множественный выбор
                                        multiSelect: true,
                                        //колонки, которые будут отображены в справочнике
                                        columns: ["Name"]
                                };
                                var UsrConsumablesId = this.get("MasterRecordId");
                                if (this.Ext.isEmpty(UsrConsumablesId)) {
                                        return;
                                }
                                //экземпляр класса [EntitySchemaQuery]
                                var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                                        //установка корневой схемы
                                        rootShemaName: this.entitySchemaName
                                });
                                //добовление колонки [Id]
                                esq.addColumn("Id");
                                //добавление колонки [id] из схемы [UsrConfigItemModel]
                                esq.addColumn("UsrConfigItemModel.Id", "UsrConfigItemModelId");
                                //Создание и добаление фильтров в коллекцию запроса
                                esq.filters.add("filterUsrConsumables",
                                this.Terrasoft.createColumnFilterWithParameter(
                                        this.Terrasoft.ComparisonType.EQUAL, "UsrConsumables", UsrConsumablesId));
                // Получение всей коллекции записей и отображение ее в модальном окне справочника.
                                esq.getEntityCollection(function(result) {
                                        var existsUsrConfigItemModelCollection = [];
                                        if (result.success) {
                                                result.collection.each(function(item) {
                                                        existsUsrConfigItemModelCollection.push(item.get("UsrConfigItemModelId"));
                                                });
                                        }
                                        // Добавление фильтра в конфигурационный объект.
                                        if (existsUsrConfigItemModelCollection.length > 0) {
                                                var existsFilter = this.Terrasoft.createColumnInFilterWithParameters("Id",
                                                        existsUsrConfigItemModelCollection);
                                                existsFilter.comparisonType = this.Terrasoft.ComparisonType.NOT_EQUAL;
                                                existsFilter.Name = "existsFilter";
                                                config.filters = existsFilter;
                                        }
                                        // Вызов модального окна справочника
                                        this.openLookup(config, this.addCallBack, this);
                                }, this);
                        },
                        //обработчик события сохранения страницы редактирвоания
                        onCardSaved: function() {
                                this.openUsrConfigItemModelLookup();
                        },
//открывает справочник МКЕ в случае если странца была редактирвоания РМ была ранее сохранена
                        addRecord: function() {
                                var masterCardState = this.sandbox.publish("GetCardState", null, [this.sandbox.id]);
                                var isNewRecord = (masterCardState.state === enums.CardStateV2.ADD ||
                                masterCardState.state === enums.CardStateV2.COPY);
                                if (isNewRecord === true) {
                                        var args = {
                                                isSilent: true,
                                                messageTags: [this.sandbox.id]
                                        };
                                        this.sandbox.publish("SaveRecord", args, [this.sandbox.id]);
                                        return;
                                }
                                this.openUsrConfigItemModelLookup();
                        },
                        //добавление выбранных продуктов
                        addCallBack: function(args) {
                                //экземпляр класса пакетного запроса BatchQuery
                                var bq = this.Ext.create("Terrasoft.BatchQuery");
                                var UsrConsumablesId = this.get("MasterRecordId");
                                //коллекция выбранных в справочнике данных
                                this.selectedRows = args.selectedRows.getItems();
                                //колекция, передаваемая в запрос
                                this.selectedItems = [];
                                // Копирование необходимых данных.
                                this.selectedRows.forEach(function(item) {
                                        item.UsrConsumablesId = UsrConsumablesId;
                                        item.UsrConfigItemModelId = item.values;
                                        bq.add(this.getUsrConfigItemModelInsertQuery(item));
                                        this.selectedItems.push(item.values);
                                }, this);
                                //выполнение пакетного запроса, если он не пустой
                                if (bq.queries.length) {
                                        this.showBodyMask.call(this);
                                        bq.execute(this.onUsrConfigItemModelInsert, this);
                                }
                        },
                        //возвращает запрос на добавление текущего объекта
                        getUsrConfigItemModelInsertQuery: function(item) {
                                var insert = Ext.create("Terrasoft.InsertQuery", {
                                        rootShemaName: this.entitySchemaName
                                });
                                insert.setParameterValue("UsrConsumables", item.UsrConsumablesId,
                                this.Terrasoft.DataValueType.GUID);
                                insert.setParameterValue("ConfigItemModel", item.UsrConfigItemModelId,
                                this.Terrasoft.DataValueType.GUID);
                                return insert;
                        },
                        //метод, вызываемый при добавлении записей в реестр детали
                        onUsrConfigItemModelInsert: function(response) {
                                this.hideBodyMask.call(this);
                                this.beforeLoadGridData();
                                var filterCollection = [];
                                response.queryResults.forEach(function(item) {
                                        filterCollection.push(item.id);
                                });
                                var esq = Ext.cteate("Terrasoft.EntitySchemaQuery", {
                                        rootShemaName: this.entitySchemaName
                                });
                                this.initQueryColumns(esq);
                                esq.filters.add("recordId",
                                Terrasoft.createColumnInFilterWithParameters("Id", filterCollection));
                                esq.getEntityCollection(function(response) {
                                        this.afterLoadGridData();
                                        if (response.success) {
                                                var responseCollection = response.collection;
                                                this.prepareResponseCollection(responseCollection);
                                                this.getGridData().loadAll(responseCollection);
                                        }
                                }, this);
                        },
                        //метод, вызываемый при удалении выбранных записей детали
                        deleteRecords: function() {
                                var selectedRows = this.getSelectedItems();
                                if (selectedRows.length > 0) {
                                        this.set("SelectedRows", selectedRows);
                                        this.callParent(arguments);
                                }
                        },
                        //скрыть пункт меню [Копировать]
                        getCopyRecordMenuItem: Terrasoft.emptyFn,
                        //скрыть пункт меню [Изменить]
                        getEditRecordMenuItem: Terrasoft.emptyFn,
                        //возвращает имя колонки по умолчанию для фильтра
                        getFilterDefaultColumnName: function() {
                                return "UsrConfigItemModel";
                        }
                },
                        // Массив модификаций.
                diff: /**SCHEMA_DIFF*/[
                                {
                                        // Тип операции — слияние.
                                        "operation": "merge",
                                        // Название элемента схемы, над которым производится действие.
                                        "name": "DataGrid",
                                // Объект, свойства которого будут объединены со свойствами элемента схемы.
                                        "values": {
                                                "rowDataItemMarkerColumnName": "UsrConfigItemModel"
                                        }
                                },
                                {
                                        // Тип операции — слияние.
                                        "operation": "merge",
                                        // Название элемента схемы, над которым производится действие.
                                        "name": "AddRecordButton",
                                // Объект, свойства которого будут объединены со свойствами элемента схемы.
                                        "values": {
                                                "visible": {"bindTo": "getToolsVisible"}
                                        }
                                }
                        ]/**SCHEMA_DIFF*/
                };
});

Задача стоит, сделать деталь такой же как, например: деталь [ConfItemUserDetail] в КЕ.

Версия продукта: service enterprise 7.8.2

Нравится

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

Где и как правильно поправить код?

Добрый вечер, Алеся.

Исходя из ошибки - у Вас неправильно строится запрос к базе данных в методе openUsrConfigItemModelLookup. На первом скриншоте явно видно, что запрос не был построен корректно. Проверьте правильность имен колонок, а также правильность связей. SDK.

Ошибка на втором скриншоте результат первой ошибки. Метод addCallBack получил не правильный параметр args и затем у несуществующего свойства selectedRows попытался вызвать метод forEach.

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

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

// Получение всей коллекции записей и отображение ее в модальном окне справочника.
				esq.getEntityCollection(function(result) {
					var existsUsrConfigItemModelsCollection = [];
					if (result.success) {
						result.collection.each(function(item) {
							existsUsrConfigItemModelsCollection.push(item.get("UsrConfigItemModelId"));
						});
					}

изображение 1

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

Здравствуйте. Не нашел в академии информации по сабджу. Подскажите, как реализовать такую деталь. Вид детали во вложении.

Нравится

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

Нам программисты из Softex реализовали довольно универсальную родительскую страницу детали. Правда, на 7.8 пока не перевелись (на 7.5 работает), но думаю, что они смогут и на 7.8 сделать

К чему ваш комментарий, Владимир?

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

Инструкции по созданию такой детали нет, но Вы можете взять за основу существующую деталь "Средства связи контакта" (ContactCommunicationDetailV2) и сделать по аналогии свою.

"Олег Кречетов" написал:К чему ваш комментарий, Владимир?

К тому, что я знаю, кто знает, как её сделать :) И с вами поделился

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

Добрый день, форумчане.

Задача: сделать деталь "Продукты в продаже" в виде иерархии. За основу решил взять деталь "Структура организации" из раздела "Контрагенты".

Создал свой объект SuOpportunityProductInterest. В качестве родителя указал объект "Продукт в продаже ( Opportunity )". В него
добавил справочное поле SuParent, где в качестве справочника указал SuOpportunityProductInterest.

Создал свою деталь на основе объекта SuOpportunityProductInterest.

На странице детали SuOpportunityProductDetailV2 написал следующий код:

define("SuOpportunityProductDetailV2", [/*"terrasoft"*/], function(/*Terrasoft*/) {
        return {
                entitySchemaName: "SuOpportunityProductInterest",
                details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
                        methods: {
                        /**
                                 * Открывает страницу добавления детали
                                 * @protected
                                 * @overridden
                                 * @param {String} editPageUId Значение колонки типа
                                 * @param {Boolean} keepParentId (optional) Не удалять из DefaultValues элемент с ключем Parent
                                 */

                                addRecord: function(editPageUId, keepParentId) {
                                        if (!keepParentId) {
                                                var defaultValues = this.get("DefaultValues");
                                                var result = this.Ext.Array.filter(defaultValues, function(item) {
                                                        return (item.name !== "SuParent");
                                                }, this);
                                                this.set("DefaultValues", result);
                                        }
                                        this.callParent(editPageUId);
                                },
                               
                                /**
                                 *Получает колонки, которые всегда выбираются запросом
                                 *@protected
                                 *@overridden
                                 *@return {Object} Возвращает колонки, которые всегда выбираются запросом
                                 */

                                getGridDataColumns: function() {
                                        var gridDataColumns = this.callParent(arguments);
                                        if (!gridDataColumns.SuParent) {
                                                gridDataColumns.SuParent = {
                                                        path: "SuParent"
                                                };
                                        }
                                        return gridDataColumns;
                                },
                       
                               
                                prepareResponseCollection: function(collection) {
                                        collection.each(function(item) {
                                                var parent = item.get("SuParent");
                                                var parentId = parent && parent.value;
                                                if (parentId) {
                                                        item.set("SuParentId", parentId);
                                                }
                                                Terrasoft.each(item.columns, function(column) {
                                                        this.addColumnLink(item, column);
                                                        this.applyColumnDefaults(column);
                                                }, this);
                                        }, this);
                                },

                               
                                getHideQuickFilterButton: function() {
                                        return false;
                                },
                               
                                getShowQuickFilterButton: function() {
                                        return false;
                                },
                               
                                updateDetail: function(config) {
                                        config.reloadAll = true;
                                        this.callParent([config]);

                                },

                               
                                getAddChildElementButtonEnabled: function() {
                                        return !this.Ext.isEmpty(this.getSelectedItems());
                                },
                               
                                addChildElementRecord: function() {
                                        var selectedItems = this.getSelectedItems();
                                        if (this.Ext.isEmpty(selectedItems)) {
                                                return;
                                        }
                                        var parentId = selectedItems[0];
                                        var defaultValues = this.get("DefaultValues");
                                        var result = this.Ext.Array.filter(defaultValues, function(item) {
                                                return (item.name !== "SuParent");
                                        }, this);
                                        result.push({
                                                        name: "SuParent",
                                                        value: parentId
                                                });
                                        this.set("DefaultValues", result);
                                        this.addRecord(null, true);
                                },
                               
                                clearSelection: function() {
                                        this.set("activeRow", null);
                                        this.set("selectedRows", null);
                                },

                               
                                onDeleteAccept: function() {
                                        var selectedRows = this.getSelectedItems();
                                        var batch = this.Ext.create("Terrasoft.BatchQuery");
                                        Terrasoft.each(selectedRows, function(recordId) {
                                                this.deleteItem(recordId, batch, this);
                                        }, this);
                                        if (batch.queries.length > 0) {
                                                batch.execute(this.onDeleted, this);
                                        }
                                },

                               
                                onDeleted: function(response) {
                                        if (response && response.success) {
                                                this.clearSelection();
                                        } else {
                                                this.showConfirmationDialog(
                                                        this.get("Resources.Strings.OnDeleteError"));
                                        }
                                },

                               
                                deleteItem: function(recordId, batch, scope) {
                                        var grid = scope.getGridData();
                                        var toDelete = new Terrasoft.Collection();
                                        grid.each(function(item) {
                                                var parent = item.get("SuParent");
                                                if (parent && parent.value === recordId) {
                                                        toDelete.add(item);
                                                }
                                        }, grid);

                                        Terrasoft.each(toDelete.getItems(), function(item) {
                                                this.deleteItem(item.get("Id"), batch, this);
                                        }, scope);
                                        if (grid.find(recordId)) {
                                                var selfDelete = grid.get(recordId);
                                                grid.remove(selfDelete);
                                                var query = this.Ext.create("Terrasoft.DeleteQuery", {
                                                        rootSchema: scope.entitySchema
                                                });
                                                var filter = Terrasoft.createColumnFilterWithParameter(
                                                        Terrasoft.ComparisonType.EQUAL, "Id", recordId);
                                                query.filters.addItem(filter);
                                                batch.add(query);
                                        }
                                }
                               
                },
                diff: /**SCHEMA_DIFF*/[
                                {
                                   "operation": "merge",
                                   "name": "DataGrid",
                                   "values": {
                                          "type": "listed",
               
                                                  //включает иерархичность реестра детали
                                      "hierarchical": true,
                                      "hierarchicalColumnName": "SuParent"
                                                }                          
                                },
                                {
                                        "operation": "merge",
                                        "name": "AddRecordButton",
                                        "values": {
                                                visible: false
                                        }
                                },
                                {
                                        "operation": "insert",
                                        "name": "AddRecord",
                                        "parentName": "Detail",
                                        "propertyName": "tools",
                                        "index": 1,
                                        "values": {
                                                itemType: Terrasoft.ViewItemType.BUTTON,
                                                menu: [],
                                                "imageConfig": {"bindTo": "Resources.Images.AddButtonImage"},
                                        //      "caption": {"bindTo": "Resources.Strings.AddButtonCaption"},
                                                "visible": {"bindTo": "getToolsVisible"}
                                        }
                                },
                                {
                                        "operation": "insert",
                                        "name": "AddParentRecordButton",
                                        "parentName": "AddRecord",
                                        "propertyName": "menu",
                                        "values": {
                                                "caption": {"bindTo": "Resources.Strings.AddRootElementButtonCaption"},
                                                "click": {"bindTo": "addRecord"}
                                        }
                                },
                                {
                                        "operation": "insert",
                                        "name": "AddChildElementButton",
                                        "parentName": "AddRecord",
                                        "propertyName": "menu",
                                        "values": {
                                                "caption": {"bindTo": "Resources.Strings.AddChildElementButtonCaption"},
                                                "click": {"bindTo": "addChildElementRecord"},
                                                "enabled": {"bindTo": "getAddChildElementButtonEnabled"}
                                        }
                                },
                                {
                                        "operation": "remove",
                                        "name": "FiltersContainer"
                                }
                ]/**SCHEMA_DIFF*/
       
        };
});

Если я добавляю корневой элемент, то все хорошо, запись отображается. Если добавляю подчиненный элемент, то запись не отображается.
Причина в том, что при добавлении подчиненного элемента не записываются значения в колонки
OpportunityId и SuParentId в таблице SuOpportunityProductInterest. Если в них вручную добавить значения, то подчиненная запись отобразится.

В чем может быть проблема? Заранее благодарен

Нравится

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

Здравствуйте!
Работаю в версии 7.7. Столкнулся со следующей проблемой:
мастером на странице редактирования Лида в истории добавил свою деталь. Она располагается в самом низу. Мне нужно её вверх поднять, расположить её между первой и второй базовыми деталями. Мастером не получается это сделать. Как сделать вручную. Где настройки расположения изменить?

Заранее благодарен.

Нравится

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

Здравствуйте, Кирилл.

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

Пример перемещения детали вниз:

define('ContactPageV2', ['ContactPageV2Resources', 'GeneralDetails'],
function(resources, GeneralDetails) {
	return {
		entitySchemaName: 'Contact',
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[
	{
		"operation": "move",
		"name": "ContactCommunication",
		"parentName": "GeneralInfoTab",
		"propertyName": "items",
 
		"index": 4
	}
]/**SCHEMA_DIFF*/,
		attributes: {},
		methods: {},
		rules: {},
		userCode: {}
	};
});

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

Доброго дня!
Столкнулся со след. задачей:
Имеется 2 раздела: "Заказы" и "Инженерная спецификация"
Оба раздела имеют свою древовидную деталь "Продукты"
Мне необходимо скопировать выделенные продукты из раздела "Инженерная спецификация" в раздел "Заказы". Копироваться должны только определенные поля.
Подскажите пожалуйста, как это можно реализовать?

Нравится

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

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

У каждого грида есть свойство SelectedIDs - возвращаемое массив идентификаторов выделенных записей. Зная идентификатор записи, можете выполнить обновление продуктов в древовидном реестре другого реестре. Обновление можно реализовать несколькими способами:

  1. 1. Используя датасет
  2. 2. Используя запрос на обновление
  3. 3. Используя хранимую процедуру

Рекомендую использовать первый способ, выполнить обновление через датасет.
Как за пример, можете взять логику обновления данных детали [Средства связи] раздела [Контрагент] реализованной в функции ActualizeCommunication сервиса scr_Account.

Cпасибо, сейчас попробую!

Можно еще посмотреть реализацию копирования дерева продуктов в scr_DocumentUtils...
Функция CopyOfferingInItemDetail. И далее из нее вызовы...

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

Создали делать2 в детали1.
Деталь2 самописная.

в Карточки схемы детали1

details: /**SCHEMA_DETAILS*/{
                        "UsrContragentOperation": {
                                "schemaName": "UsrContragentOperationDetailV2",
                                "entitySchemaName": "UsrContragentOperation",
                                filter: {
                                                masterColumn: "Id",
                                                detailColumn: "UsrTranspPlanLine"   //деталь2
                                                }
                        }

Но при добавлении записи в деталь2 Id пуст.
Т.е. получается что мы передаем id.
Что не так?
Как отловить в отладчике это значение?

Нравится

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

Здравствуйте,
При объявлении второй детали в детали, пишите "useRelationship": true

"UsrDetail2": {
				"schemaName": "UsrSchema2Detail",
				"entitySchemaName": "UsrDetail2",
				"filter": {
					"detailColumn": "UsrDetail1",
					"masterColumn": "Id"
				},
				"useRelationship": true
			}

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

Пример всей реализации, деталь в контрагентах. А в ней вторая деталь:

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

define("UsrUsrDetail11Page", [], function() {
	return {
		entitySchemaName: "UsrDetail1",
		details: /**SCHEMA_DETAILS*/{
			"UsrDetail2": {
				"schemaName": "UsrSchema2Detail",
				"entitySchemaName": "UsrDetail2",
				"filter": {
					"detailColumn": "UsrDetail1",
					"masterColumn": "Id"
				},
				"useRelationship": true
			}
		}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"name": "UsrString",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 0,
						"row": 0,
						"layoutName": "Header"
					},
					"bindTo": "UsrString"
				},
				"parentName": "Header",
				"propertyName": "items",
				"index": 0
			},
			{
				"operation": "insert",
				"name": "UsrAccount",
				"values": {
					"layout": {
						"colSpan": 12,
						"rowSpan": 1,
						"column": 12,
						"row": 0,
						"layoutName": "Header"
					},
					"bindTo": "UsrAccount"
				},
				"parentName": "Header",
				"propertyName": "items",
				"index": 1
			},
			{
				"operation": "insert",
				"name": "Detail1GeneralTabContainer",
				"parentName": "Tabs",
				"propertyName": "tabs",
				"values": {
					"caption": "Tab",
					"items": []
				}
			},
			{
				"operation": "insert",
				"name": "UsrDetail2",
				"values": {
					"itemType": Terrasoft.ViewItemType.DETAIL
				},
				"parentName": "Detail1GeneralTabContainer",
				"propertyName": "items"
			}
		]/**SCHEMA_DIFF*/,
		methods: {},
		rules: {}
	};
});

Результат:

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

Добрый день, коллеги!
Подскажите, в продукте версии 7.8 есть деталь "Структура" , в разделе "Проекты".
Хочу сделать со своей кастомной деталью тоже самое, иерархию.

Пока что добавил вот такой код, к старнице детали:

define("UsrReportingDetailV2", ["ConfigurationEnums", "css!ProjectCSSModule"], function(enums) {
        return {
                entitySchemaName: "UsrReporting",
                attributes: {
                        /**
                         * Отвечает за загруженные уровни иерархии
                         */

                        "expandedElements": {
                                dataValueType: Terrasoft.DataValueType.CUSTOM_OBJECT,
                                type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
                        },
                        /**
                         * Отвечает за список развернутых элементов,
                         * хранит массив уникальных идетификаторов записей
                         */

                        "expandHierarchyLevels": {
                                dataValueType: Terrasoft.DataValueType.CUSTOM_OBJECT,
                                type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
                        },

                        /**
                         * Отвечает за хранение разворачиваемого элемента иерархии
                         */

                        "ExpandItemId": {
                                dataValueType: Terrasoft.DataValueType.GUID,
                                type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
                        }
                },
                methods: {
                        /**
                         * @overridden
                         */

                        disableGridSorting: Ext.emptyFn,

                        /**
                         * @overridden
                         */

                        sortColumn: Ext.emptyFn,

                        /**
                         * Обнавляет страницы редактирования проекта
                         * @overridden
                         * @private
                         */

                        initEditPages: function() {
                                this.callParent(arguments);
                                debugger;
                                var editPages = this.get("EditPages");
                                var workPage = editPages.collection.items[0];
                                workPage.set("Click", {"bindTo": "addToRootRecord"});
                                workPage.set("Caption", "Super");
                                workPage.set("Visible", true);
                                var childItemId = Terrasoft.utils.generateGUID();
                                var config = {
                                        "Id": childItemId,
                                        "Caption": "Sub",
                                        "Click": {"bindTo": "addToChildRecord"},
                                        "Enabled": {"bindTo": "isSingleSelected"},
                                        "Tag": childItemId,
                                        "SchemaName": "UsrReportingPageV2"
                                };
                                var addToChildMenuItem = this.getActionsMenuItem(config);
                                editPages.add(childItemId, addToChildMenuItem);
                        },
                        /**
                         * Открывает страницу Работы для добавления элемента дочернего элемента выбранной записи
                         * @protected
                         * @virtual
                         */

                        addToChildRecord: function() {
                                var scope = this;
                                var selectedItems = this.getSelectedItems();
                                this.set("ExpandItemId", selectedItems[0]);
                                this.replaceDefaultValue("UsrParent", selectedItems[0]);
                                var masterRecordId = this.get("MasterRecordId");
                                this.addRecord();
                        },
                        /**
                         * Устанавливает значение по умолчанию для параметра страницы редактировани новой записи
                         * @protected
                         * @virtual
                         * @param {String} key Имя параметра
                         * @param {*} value значение параметра
                         */

                        replaceDefaultValue: function(key, value) {
                                var defaultValues = this.get("DefaultValues");
                                var oldValue = defaultValues.filter(function(item) {
                                        return item.name === key;
                                });
                                if (Ext.isEmpty(oldValue)) {
                                        defaultValues.push({
                                                name: key,
                                                value: value
                                        });
                                } else {
                                        Terrasoft.each(oldValue, function(item) {
                                                item.value = value;
                                        });
                                }
                        },
                        /**
                         * Открывает страницу Проекта или Работы для добавления элемента в текущий уровань иерархии
                         * @protected
                         * @virtual
                         * @param {String} typeUId Уникальный идентификатор типа записи проекта
                         */

                        addToRootRecord: function(typeUId) {
                                var masterRecordId = this.Terrasoft.GUID_EMPTY;
                                this.replaceDefaultValue("UsrParent", masterRecordId);
                                this.addRecord();
                        },
                        /**
                         * Обработчик загрузки дочерних элементов. Осуществляет проверку загружености
                         * дочерних элеметов выбранной записи. Запускает загрузку нового уровня.
                         * @protected
                         * @virtual
                         * @param {String} primaryColumnValue Уникальный идентификатор записи
                         * @param {Boolean} isExpanded Признак того, разворачивает или сворачивает пользователь дочерние элеметы
                         * true - если разворачивает, false в обратном случае
                         */

                        onExpandHierarchyLevels: function(primaryColumnValue, isExpanded) {
                                if (!isExpanded || this.isItemExpanded(primaryColumnValue)) {
                                        return;
                                }
                                this.setExpandedItem(primaryColumnValue);
                                this.set("ExpandItemId", primaryColumnValue);
                                this.loadGridData();
                        },

                        /**
                         * Удаляет логику постраничности если загружаются дочерние объекты
                         * @protected
                         * @overridden
                         */

                        initQueryOptions: function() {
                                var parentItem = this.get("ExpandItemId");
                                if (!parentItem) {
                                        var isClearGridData = this.get("IsClearGridData");
                                        if (isClearGridData) {
                                                this.clearExpandHierarchyLevels();
                                        }
                                        this.callParent(arguments);
                                }
                        },
                        /**
                         * Удаляет логику постраничности если загружаются дочерние объекты
                         * @protected
                         * @overridden
                         */

                        initCanLoadMoreData: function() {
                                var parentItem = this.get("ExpandItemId");
                                if (!parentItem) {
                                        this.callParent(arguments);
                                }

                                this.get("expandedElements")["EB64FD9A-DF42-4275-8F1B-0A32ABB68AD5"] = {
                                        page: 0
                                };
                        },
                        /**
                         * Инициализирует параметры детали
                         * @protected
                         * @overridden
                         */

                        initData: function() {
                                this.callParent(arguments);
                                this.set("expandedElements", {});
                                this.set("expandHierarchyLevels", []);
                        },
                },
                diff: /**SCHEMA_DIFF*/[
                        {
                                "operation": "merge",
                                "name": "DataGrid",
                                "values": {
                                        "type": "listed",
                                        "hierarchical": true,
                                        "sortColumnDirection": {"bindTo": "disableGridSorting"},
                                        "hierarchicalColumnName": "ParentId",
                                        "updateExpandHierarchyLevels": {
                                                "bindTo": "onExpandHierarchyLevels"
                                        },
                                        expandHierarchyLevels: {
                                                "bindTo": "expandHierarchyLevels"
                                        },
                                        "listedConfig": {
                                                "name": "DataGridListedConfig",
                                                "items": [
                                                        {
                                                                "name": "UsrFileNameListedGridColumn",
                                                                "bindTo": "UsrFileName",
                                                                "position": {
                                                                        "column": 1,
                                                                        "colSpan": 12
                                                                }
                                                        },
                                                        {
                                                                "name": "UsrDisplayPortalListedGridColumn",
                                                                "bindTo": "UsrDisplayPortal",
                                                                "position": {
                                                                        "column": 21,
                                                                        "colSpan": 4
                                                                }
                                                        }
                                                ]
                                        },
                                        "tiledConfig": {
                                                "name": "DataGridTiledConfig",
                                                "grid": {
                                                        "columns": 24,
                                                        "rows": 3
                                                },
                                                "items": [
                                                        {
                                                                "name": "UsrFileNameTiledGridColumn",
                                                                "bindTo": "UsrFileName",
                                                                "position": {
                                                                        "row": 1,
                                                                        "column": 1,
                                                                        "colSpan": 12
                                                                }
                                                        },
                                                        {
                                                                "name": "UsrDisplayPortalTiledGridColumn",
                                                                "bindTo": "UsrDisplayPortal",
                                                                "position": {
                                                                        "row": 1,
                                                                        "column": 21,
                                                                        "colSpan": 4
                                                                }
                                                        }
                                                ]
                                        }
                                }
                        },
                        {
                                "operation": "insert",
                                "name": "UpButton",
                                "parentName": "Detail",
                                "propertyName": "tools",
                                "index": 0,
                                "values": {
                                        "itemType": Terrasoft.ViewItemType.BUTTON,
                                        "tag": -1,
                                        "imageConfig": {
                                                "bindTo": "Resources.Images.UpImage"
                                        },
                                        "click": {"bindTo": "changePosition"},
                                        "visible": {"bindTo": "getToolsVisible"},
                                        "enabled": {"bindTo": "canChangeSelectedItemPosition"},
                                        "hint": {"bindTo": "Resources.Strings.ChangePositionUpButtonCaption"}
                                }
                        },
                        {
                                "operation": "insert",
                                "name": "DownButton",
                                "parentName": "Detail",
                                "propertyName": "tools",
                                "index": 1,
                                "values": {
                                        "itemType": Terrasoft.ViewItemType.BUTTON,
                                        "tag": 1,
                                        "imageConfig": {
                                                "bindTo": "Resources.Images.DownImage"
                                        },
                                        "click": {"bindTo": "changePosition"},
                                        "visible": {"bindTo": "getToolsVisible"},
                                        "enabled": {"bindTo": "canChangeSelectedItemPosition"},
                                        "hint": {"bindTo": "Resources.Strings.ChangePositionDownButtonCaption"}
                                }
                        },
                        {
                                "operation": "remove",
                                "name": "ViewSortMenu",
                                "parentName": "ViewButton",
                                "propertyName": "menu"
                        }
                ]/**SCHEMA_DIFF*/
        };
});

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

Нравится

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

Может кто то делал подобное

Или как и когда , правильно добавлять в эти объекты ('expandHierarchyLevels', 'expandedElements') Id дочерних записей ?

Роман, все вычисляется напрямую запросом к колонкам UsrPosition и UsrParent.

Пример кода рабочей пользовательской детали:

define("UsrSchema2Detail", ["XRMConstants", "terrasoft", "css!ProjectCSSModule"], function(XRMConstants, Terrasoft) {
	return {
		entitySchemaName: "UsrTestTest",
		messages: {
			"CardModuleEntityInfo": {
				"mode": Terrasoft.MessageMode.PTP,
				"direction": Terrasoft.MessageDirectionType.SUBSCRIBE
			}
		},
		attributes: {
			"expandedElements": {
				dataValueType: Terrasoft.DataValueType.CUSTOM_OBJECT,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
			},
			"expandHierarchyLevels": {
				dataValueType: Terrasoft.DataValueType.CUSTOM_OBJECT,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
			},
			"ExpandItemId": {
				dataValueType: Terrasoft.DataValueType.GUID,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
			}
		},
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[
				{
					"operation": "merge",
					"name": "DataGrid",
					"values": {
						"type": "listed",
						"hierarchical": true,
						"sortColumnDirection": {"bindTo": "disableGridSorting"},
						"hierarchicalColumnName": "ParentId",
						"updateExpandHierarchyLevels": {
							"bindTo": "onExpandHierarchyLevels"
						},
						expandHierarchyLevels: {
							"bindTo": "expandHierarchyLevels"
						}
					}
				},
				{
					"operation": "insert",
					"name": "UpButton",
					"parentName": "Detail",
					"propertyName": "tools",
					"index": 0,
					"values": {
						"itemType": Terrasoft.ViewItemType.BUTTON,
						"tag": -1,
						"imageConfig": {
							"bindTo": "Resources.Images.UpImage"
						},
						"click": {"bindTo": "changePosition"},
						"visible": {"bindTo": "getToolsVisible"},
						"enabled": {"bindTo": "canChangeSelectedItemPosition"},
						"hint": {"bindTo": "Resources.Strings.ChangePositionUpButtonCaption"}
					}
				},
				{
					"operation": "insert",
					"name": "DownButton",
					"parentName": "Detail",
					"propertyName": "tools",
					"index": 1,
					"values": {
						"itemType": Terrasoft.ViewItemType.BUTTON,
						"tag": 1,
						"imageConfig": {
							"bindTo": "Resources.Images.DownImage"
						},
						"click": {"bindTo": "changePosition"},
						"visible": {"bindTo": "getToolsVisible"},
						"enabled": {"bindTo": "canChangeSelectedItemPosition"},
						"hint": {"bindTo": "Resources.Strings.ChangePositionDownButtonCaption"}
					}
				},
				{
					"operation": "remove",
					"name": "ViewSortMenu",
					"parentName": "ViewButton",
					"propertyName": "menu"
				}
		]/**SCHEMA_DIFF*/,
		methods: {
				disableGridSorting: Ext.emptyFn,
				sortColumn: Ext.emptyFn,
				init: function() {
					this.callParent(arguments);
				},
				initData: function() {
					this.callParent(arguments);
					this.set("expandedElements", {});
					this.set("expandHierarchyLevels", []);
				},
				onDeleted: function(result) {
					this.callParent(arguments);
					if (result.Success) {
						this.reloadGridData();
					}
				},
				clearExpandHierarchyLevels: function() {
					this.set("expandedElements", {});
					this.set("expandHierarchyLevels", []);
					var grid = Ext.getCmp("ProjectDetailV2DataGridGrid");
					if (grid) {
						grid.expandHierarchyLevels = [];
					}
				},
				removeExpandHierarchyLevel: function(itemId) {
					var expandHierarchyLevels = this.get("expandHierarchyLevels");
					this.set("expandHierarchyLevels", Terrasoft.without(expandHierarchyLevels, itemId));
					var grid = Ext.getCmp("ProjectDetailV2DataGridGrid");
					if (grid) {
						grid.expandHierarchyLevels = Terrasoft.without(grid.expandHierarchyLevels, itemId);
					}
				},
				addGridDataColumns: function(esq) {
					this.callParent(arguments);
					this.putParentColumn(esq);
					this.putNestingColumn(esq);
					this.putPositionColumn(esq);
				},
				putParentColumn: function(esq) {
					var parentItem = this.get("ExpandItemId");
					if (parentItem && !esq.columns.contains("ParentId")) {
						esq.addColumn("UsrParent.Id", "ParentId");
					}
				},
				putPositionColumn: function(esq) {
					if (!esq.columns.contains("UsrPosition")) {
						esq.addColumn("UsrPosition");
					}
				},
				putNestingColumn: function(esq) {
					var aggregationColumn = this.Ext.create("Terrasoft.AggregationQueryColumn", {
						aggregationType: Terrasoft.AggregationType.COUNT,
						columnPath: "[UsrTestTest:UsrParent].Id"
					});
					if (!esq.columns.contains("HasNesting")) {
						esq.addColumn(aggregationColumn, "HasNesting");
					}
				},
				getParents: function(primaryValues) {
					var parentPrimaryValues = [];
					var gridData = this.getGridData();
					if (Ext.isEmpty(primaryValues)) {
						return parentPrimaryValues;
					}
					primaryValues.forEach(function(primaryColumnValue) {
						var project = gridData.get(primaryColumnValue);
						var parentPrimaryColumnValue = project.get("ParentId");
						if (parentPrimaryColumnValue) {
							parentPrimaryValues.push(parentPrimaryColumnValue);
						}
					});
					return parentPrimaryValues;
				},
				removeGridRecords: function(primaryColumnValues) {
					var updateNestingCollection = this.getParents(primaryColumnValues);
					this.callParent(arguments);
					var gridData = this.getGridData();
					Terrasoft.each(updateNestingCollection, function(projectId) {
						var count = gridData.filterByFn(function(item) {
							return item.get("ParentId") === projectId;
						}, this).getCount();
						if (gridData.contains(projectId)) {
							this.removeExpandHierarchyLevel(projectId);
							var parent = gridData.get(projectId);
							parent.set("HasNesting", count);
						}
					}, this);
				},
				getExpandedItems: function() {
					return this.get("expandedElements");
				},
				setExpandedItem: function(primaryColumnValue) {
					(this.getExpandedItems()[primaryColumnValue]) = {"page": 0};
				},
				isItemExpanded: function(primaryColumnValue) {
					return Boolean(this.getExpandedItems()[primaryColumnValue]);
				},
				addItemsToGridData: function(dataCollection, options) {
					if (dataCollection.isEmpty()) {
						return;
					}
					var firstItem = dataCollection.getByIndex(0);
					var parentId = firstItem.get("ParentId");
					if (parentId) {
						options = {
							mode: "child",
							target: parentId
						};
						var gridData = this.getGridData();
						var parentObj = gridData.get(parentId);
						if (parentObj) {
							parentObj.set("HasNesting", 1);
						}
						if (!this.isItemExpanded(parentId)) {
							return;
						}
					} else {
						this.set("LastRecord", dataCollection.getByIndex(dataCollection.getCount() - 1));
					}
					this.callParent([dataCollection, options]);
					if (options && (options.mode === "child" || options.mode === "top")) {
						var gridDataChild = this.getGridData();
						var tempCollection = this.Ext.create("Terrasoft.Collection");
						tempCollection.loadAll(gridDataChild);
						this.sortCollection(tempCollection);
						gridDataChild.clear();
						gridDataChild.loadAll(tempCollection);
					}
					this.set("ExpandItemId", null);
				},
				onExpandHierarchyLevels: function(primaryColumnValue, isExpanded) {
					if (!isExpanded || this.isItemExpanded(primaryColumnValue)) {
						return;
					}
					this.setExpandedItem(primaryColumnValue);
					this.set("ExpandItemId", primaryColumnValue);
					this.loadGridData();
				},
				initQueryOptions: function() {
					var parentItem = this.get("ExpandItemId");
					if (!parentItem) {
						var isClearGridData = this.get("IsClearGridData");
						if (isClearGridData) {
							this.clearExpandHierarchyLevels();
						}
						this.callParent(arguments);
					}
				},
				initCanLoadMoreData: function() {
					var parentItem = this.get("ExpandItemId");
					if (!parentItem) {
						this.callParent(arguments);
					}
				},
				changeSorting: function() {
					this.clearExpandHierarchyLevels();
					this.callParent(arguments);
				},
				initQuerySorting: function(esq) {
					var sortedColumn = esq.columns.get("UsrPosition");
					sortedColumn.orderPosition = 0;
					sortedColumn.orderDirection = Terrasoft.OrderDirection.ASC;
				},
				getFilters: function() {
					var parentItem = this.get("ExpandItemId");
					if (parentItem) {
						var parentProjectFilterGroup = this.Terrasoft.createFilterGroup();
						parentProjectFilterGroup.addItem(this.Terrasoft.createColumnFilterWithParameter(
							this.Terrasoft.ComparisonType.EQUAL,
							"UsrParent",
							parentItem,
							Terrasoft.DataValueType.GUID
						));
						return parentProjectFilterGroup;
					} else {
						var filters = this.callParent(arguments);
						if (this.get("DetailColumnName") !== "UsrParent") {
							var group = this.Terrasoft.createFilterGroup();
							group.addItem(filters);
							group.addItem(
								Terrasoft.createColumnIsNullFilter(this.entitySchema.hierarchicalColumnName)
							);
							filters = group;
						}
						return filters;
					}
				},
				isProjectsInRoot: function() {
					return (this.get("DetailColumnName") !== "UsrParent");
				},
				isWorkInRoot: function() {
					return !this.isProjectsInRoot();
				},
				initEditPages: function() {
					this.callParent(arguments);
					var editPages = this.get("EditPages");
					var workPage = editPages.collection.items[0];
					workPage.set("Click", {"bindTo": "addToRootRecord"});
					workPage.set("Caption", "Add");
					workPage.set("Visible", true);
					var childItemId = editPages.collection.items[0].imstanceId;
					var config = {
						"Id": childItemId,
						"Caption": "New",
						"Click": {"bindTo": "addToChildRecord"},
						"Enabled": {"bindTo": "isSingleSelected"},
						"Tag": childItemId,
						"SchemaName": "UsrTestTest1Page"
					};
					var addToChildMenuItem = this.getActionsMenuItem(config);
					editPages.add(childItemId, addToChildMenuItem);
				},
				replaceDefaultValue: function(key, value) {
					var defaultValues = this.get("DefaultValues");
					var oldValue = defaultValues.filter(function(item) {
						return item.name === key;
					});
					if (Ext.isEmpty(oldValue)) {
						defaultValues.push({
							name: key,
							value: value
						});
					} else {
						Terrasoft.each(oldValue, function(item) {
							item.value = value;
						});
					}
				},
				getDetailInfo: function() {
					var detailInfo = this.sandbox.publish("GetDetailInfo", null, [this.sandbox.id]) || {};
					var defaultValues = this.get("DefaultValues");
					detailInfo.defaultValues = defaultValues;
					return detailInfo;
				},
				addToRootRecord: function(typeUId) {
					var masterRecordId = (typeUId === XRMConstants.Project.EntryType.Project)
						? this.Terrasoft.GUID_EMPTY
						: this.get("MasterRecordId");
					this.replaceDefaultValue("UsrParent", masterRecordId);
					this.addRecord(typeUId);
				},
				addToChildRecord: function() {
					var scope = this;
					var selectedItems = this.getSelectedItems();
					this.set("ExpandItemId", selectedItems[0]);
					this.replaceDefaultValue("UsrParent", selectedItems[0]);
					var masterRecordId = this.get("MasterRecordId");
					if (masterRecordId !== null) {
						var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "UsrTestTest"});
						var filter = Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
							"Id", masterRecordId, Terrasoft.DataValueType.GUID);
						esq.filters.add("filter", filter);
						esq.getEntityCollection(function(response) {
							if (!response || !response.success) {
								return;
							}
							var result = response.collection;
							result.each(function(resultItem) {
								scope.addRecord('c485c4e3-c0a1-4008-a8fe-054f167d5068');
							});
						}, this);
					} else {
						this.addRecord('c485c4e3-c0a1-4008-a8fe-054f167d5068');
					}
				},
				canChangeSelectedItemPosition: function() {
					var selectedItems = this.getSelectedItems();
					return (!Ext.isEmpty(selectedItems) && (selectedItems.length <= 1));
				},
				changePosition: function() {
					var shift = arguments[3];
					var activeRow = this.getActiveRow();
					var projectId = activeRow.get("Id");
					this.updateProjectPosition(projectId, shift, this.onPositionChanged, this);
				},
				onPositionChanged: function(result) {
					if (!result) {
						return;
					}
					var activeRow = this.getActiveRow();
					var parentId = activeRow.get("ParentId");
					if (!parentId) {
						parentId = this.get("MasterRecordId");
					}
					var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchema: this.entitySchema});
					esq.addColumn("UsrPosition");
					var filter = Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
						"UsrParent", parentId, Terrasoft.DataValueType.GUID);
					esq.filters.add("filter", filter);
					esq.getEntityCollection(function(response) {
						if (!response || !response.success) {
							return;
						}
						var gridData = this.getGridData();
						var result = response.collection;
						result.each(function(resultItem) {
							var resultItemId = resultItem.get("Id");
							var newPosition = resultItem.get("UsrPosition");
							var gridRecord = gridData.get(resultItemId);
							gridRecord.set("UsrPosition", newPosition);
						});
						var tempCollection = this.Ext.create("Terrasoft.Collection");
						tempCollection.loadAll(gridData);
						this.sortCollection(tempCollection);
						gridData.clear();
						gridData.loadAll(tempCollection);
					}, this);
				},
				sortCollection: function(collection) {
					collection.sortByFn(function(a, b) {
						var positionA = a.get("UsrPosition");
						var positionB = b.get("UsrPosition");
						var q = positionA - positionB;
						return q === 0 ? 0 : (q) / Math.abs(q);
					});
				},
		}
	};
});

Доброго времени суток.
Недавно столкнулся с такой же задачкой. Вот примерный алгоритм:
1) Отрубить в системных настройках ненавистный префикс "Usr" (необяз. пункт).
2) Создать Объект (род. объект - Базовый объект), заполнить его нужными полями, сохранить, опубликовать.
3) Еще раз открыть объект на редактирование и создать там справочник Parent, род. объект - ставим ссылку на только что созданный объект. В свойствах объекта (справа кнопка списка-свойства-все) в графе "Родитель в иерархии" ставим поле Parent. Сохраняем, Публикуем.
4) Когда заполнять таблицу - решаете сами. Либо в схеме (через InsertQuery), либо через хранимку, либо через С# код. Без разницы (в крайнем случае - this.reloadGridData()). Главное у нужных записей заполнять поле Parent айдишником записи-родителя (тем самым формируя иерархию)
5) Теперь сама схема. Создаем схему. Род. объект - Базовая схема детали с реестром. Код приложу. Там надо поменять название схемы в define, ссылку на entitySchemaName (объект, который мы создали ранее) и ссылку на колонку объекта в putNestingColumn.
6) Все. Теперь добавляем деталь на страницу (из кода. в дизайнере не отобразится, т.к. не зарегистрирована). Если все сделано правильно и карточка загрузилась без ошибок, последний шаг - настроить вывод информации в гриде. Это можно сделать через ToolButton прямо в карточке.

[quote="Мотков Илья"]

Роман, все вычисляется напрямую запросом к колонкам UsrPosition и UsrParent.

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

 message: Uncaught Terrasoft.ItemNotFoundException: Item with key f5695207-a45d-4975-a484-92384cb438d1 Does not exist 

Виртуальный обьект и коллекцию, проверил, все корректно добавляет и удаляет. Уже несколько раз сравниваю с разделом "Проекты" , не могу найти разницу ...
Код схемы:

define("UsrReportingDetailV2", ["XRMConstants","ConfigurationGrid", "ConfigurationGridGenerator", "ProcessModuleUtilities", "ConfigurationGridUtilities", "ConfigurationEnums"], 
	function(XRMConstants, ProcessModuleUtilities, ConfigurationGridUtilities, enums) {
	return {
		entitySchemaName: "UsrReporting",
		messages: {
			"CardModuleEntityInfo": {
				"mode": Terrasoft.MessageMode.PTP,
				"direction": Terrasoft.MessageDirectionType.SUBSCRIBE
			}
		},
		attributes: {
			"isPortal": {
				"dataValueType": Terrasoft.DataValueType.BOOLEAN,
				"value":  false
			},
			"isCRM": {
				"dataValueType": Terrasoft.DataValueType.BOOLEAN,
				"value":  true
			},
			/**
			 * Отвечает за загруженные уровни иерархии
			 */
			"expandedElements": {
				dataValueType: Terrasoft.DataValueType.CUSTOM_OBJECT,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
			},
			/**
			 * Отвечает за список развернутых элементов,
			 * хранит массив уникальных идетификаторов записей
			 */
			"expandHierarchyLevels": {
				dataValueType: Terrasoft.DataValueType.CUSTOM_OBJECT,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
			},
			/**
			 * Отвечает за хранение разворачиваемого элемента иерархии
			 */
			"ExpandItemId": {
				dataValueType: Terrasoft.DataValueType.GUID,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
			}
		},
		mixins: {
			ConfigurationGridUtilites: "Terrasoft.ConfigurationGridUtilities"
		},
		methods: {
			disableGridSorting: Ext.emptyFn,
			sortColumn: Ext.emptyFn,
			init: function() {
				this.callParent(arguments);
			},
			initData: function() {
				this.callParent(arguments);
				this.set("expandedElements", {});
				this.set("expandHierarchyLevels", []);
			},
			onDeleted: function(result) {
				this.callParent(arguments);
				if (result.Success) {
					this.reloadGridData();
				}
			},
			clearExpandHierarchyLevels: function() {
				this.set("expandedElements", {});
				this.set("expandHierarchyLevels", []);
				var grid = Ext.getCmp("ProjectDetailV2DataGridGrid");
				if (grid) {
					grid.expandHierarchyLevels = [];
				}
			},
			removeExpandHierarchyLevel: function(itemId) {
				var expandHierarchyLevels = this.get("expandHierarchyLevels");
				this.set("expandHierarchyLevels", Terrasoft.without(expandHierarchyLevels, itemId));
				var grid = Ext.getCmp("ProjectDetailV2DataGridGrid");
				if (grid) {
					grid.expandHierarchyLevels = Terrasoft.without(grid.expandHierarchyLevels, itemId);
				}
			},
			addGridDataColumns: function(esq) {
				this.callParent(arguments);
				this.putParentColumn(esq);
				this.putNestingColumn(esq);
				this.putPositionColumn(esq);
			},
			putParentColumn: function(esq) {
				var parentItem = this.get("ExpandItemId");
				if (parentItem && !esq.columns.contains("ParentId")) {
				esq.addColumn("UsrParent.Id", "ParentId");
				}
			},
			putPositionColumn: function(esq) {
				if (!esq.columns.contains("UsrPosition")) {
					esq.addColumn("UsrPosition");
				}
			},
			putNestingColumn: function(esq) {
				var aggregationColumn = this.Ext.create("Terrasoft.AggregationQueryColumn", {
				aggregationType: Terrasoft.AggregationType.COUNT,
					columnPath: "[UsrReporting:UsrParent].Id"
				});
				if (!esq.columns.contains("HasNesting")) {
					esq.addColumn(aggregationColumn, "HasNesting");
				}
			},
			getParents: function(primaryValues) {
				var parentPrimaryValues = [];
				var gridData = this.getGridData();
				if (Ext.isEmpty(primaryValues)) {
					return parentPrimaryValues;
				}
				primaryValues.forEach(function(primaryColumnValue) {
					var project = gridData.get(primaryColumnValue);
					var parentPrimaryColumnValue = project.get("ParentId");
					if (parentPrimaryColumnValue) {
						parentPrimaryValues.push(parentPrimaryColumnValue);
					}
				});
				return parentPrimaryValues;
			},
			removeGridRecords: function(primaryColumnValues) {
				var updateNestingCollection = this.getParents(primaryColumnValues);
				this.callParent(arguments);
				var gridData = this.getGridData();
				Terrasoft.each(updateNestingCollection, function(projectId) {
				var count = gridData.filterByFn(function(item) {
				return item.get("ParentId") === projectId;
				}, this).getCount();
				if (gridData.contains(projectId)) {
				this.removeExpandHierarchyLevel(projectId);
				var parent = gridData.get(projectId);
				parent.set("HasNesting", count);
				}
				}, this);
			},
			getExpandedItems: function() {
				return this.get("expandedElements");
			},
			setExpandedItem: function(primaryColumnValue) {
				(this.getExpandedItems()[primaryColumnValue]) = {"page": 0};
			},
			isItemExpanded: function(primaryColumnValue) {
				return Boolean(this.getExpandedItems()[primaryColumnValue]);
			},
			addItemsToGridData: function(dataCollection, options) {
				if (dataCollection.isEmpty()) {
					return;
				}
				var firstItem = dataCollection.getByIndex(0);
				var parentId = firstItem.get("ParentId");
				if (parentId) {
					options = {
						mode: "child",
						target: parentId
					};
					var gridData = this.getGridData();
					var parentObj = gridData.get(parentId);
					if (parentObj) {
						parentObj.set("HasNesting", 1);
					}
					if (!this.isItemExpanded(parentId)) {
						return;
					}
				} else {
					this.set("LastRecord", dataCollection.getByIndex(dataCollection.getCount() - 1));
				}
				this.callParent([dataCollection, options]);
				if (options && (options.mode === "child" || options.mode === "top")) {
					var gridDataChild = this.getGridData();
					var tempCollection = this.Ext.create("Terrasoft.Collection");
					tempCollection.loadAll(gridDataChild);
					this.sortCollection(tempCollection);
					gridDataChild.clear();
					gridDataChild.loadAll(tempCollection);
				}
				this.set("ExpandItemId", null);
			},
			onExpandHierarchyLevels: function(primaryColumnValue, isExpanded) {
				if (!isExpanded || this.isItemExpanded(primaryColumnValue)) {
					return;
				}
				this.setExpandedItem(primaryColumnValue);
				this.set("ExpandItemId", primaryColumnValue);
				this.loadGridData();
			},
			initQueryOptions: function() {
				var parentItem = this.get("ExpandItemId");
				if (!parentItem) {
					var isClearGridData = this.get("IsClearGridData");
					if (isClearGridData) {
						this.clearExpandHierarchyLevels();
					}
					this.callParent(arguments);
				}
			},
			initCanLoadMoreData: function() {
				var parentItem = this.get("ExpandItemId");
				if (!parentItem) {
					this.callParent(arguments);
				}
			},
			changeSorting: function() {
				this.clearExpandHierarchyLevels();
				this.callParent(arguments);
			},
			initQuerySorting: function(esq) {
				var sortedColumn = esq.columns.get("UsrPosition");
				sortedColumn.orderPosition = 0;
				sortedColumn.orderDirection = Terrasoft.OrderDirection.ASC;
			},
			getFilters: function() {
				var parentItem = this.get("ExpandItemId");
				if (parentItem) {
					var parentProjectFilterGroup = this.Terrasoft.createFilterGroup();
					parentProjectFilterGroup.addItem(this.Terrasoft.createColumnFilterWithParameter(
						this.Terrasoft.ComparisonType.EQUAL, "UsrParent", parentItem, Terrasoft.DataValueType.GUID));
					return parentProjectFilterGroup;
				} else {
					var filters = this.callParent(arguments);
					if (this.get("DetailColumnName") !== "UsrParent") {
						var group = this.Terrasoft.createFilterGroup();
						group.addItem(filters);
						group.addItem(Terrasoft.createColumnIsNullFilter(this.entitySchema.hierarchicalColumnName));
						filters = group;
					}
					return filters;
				}
			},
			isProjectsInRoot: function() {
				return (this.get("DetailColumnName") !== "UsrParent");
			},
			isWorkInRoot: function() {
				return !this.isProjectsInRoot();
			},
			initEditPages: function() {
				this.callParent(arguments);
				var editPages = this.get("EditPages");
				var workPage = editPages.collection.items[0];
				workPage.set("Click", {"bindTo": "addToRootRecord"});
				workPage.set("Caption", "Add");
				workPage.set("Visible", true);
				var childItemId = editPages.collection.items[0].instanceId;
				var config = {
					"Id": childItemId,
					"Caption": "New",
					"Click": {"bindTo": "addToChildRecord"},
					"Enabled": {"bindTo": "isSingleSelected"},
					"Tag": childItemId,
					"SchemaName": "UsrReportingPageV2"
				};
				var addToChildMenuItem = this.getActionsMenuItem(config);
				editPages.add(childItemId, addToChildMenuItem);
			},
			replaceDefaultValue: function(key, value) {
				var defaultValues = this.get("DefaultValues");
				var oldValue = defaultValues.filter(function(item) {
					return item.name === key;
				});
				if (Ext.isEmpty(oldValue)) {
					defaultValues.push({
						name: key,
						value: value
					});
				} else {
					Terrasoft.each(oldValue, function(item) {
						item.value = value;
					});
				}
			},
			getDetailInfo: function() {
				var detailInfo = this.sandbox.publish("GetDetailInfo", null, [this.sandbox.id]) || {};
				var defaultValues = this.get("DefaultValues");
				detailInfo.defaultValues = defaultValues;
				return detailInfo;
			},
			addToRootRecord: function(typeUId) {
				var masterRecordId = (typeUId === XRMConstants.Project.EntryType.Project)
					? this.Terrasoft.GUID_EMPTY
					: this.get("MasterRecordId");
				this.replaceDefaultValue("UsrParent", masterRecordId);
				this.addRecord(typeUId);
			},
			addToChildRecord: function() {
				var scope = this;
				var selectedItems = this.getSelectedItems();
				this.set("ExpandItemId", selectedItems[0]);
				this.replaceDefaultValue("UsrParent", selectedItems[0]);
				var masterRecordId = this.get("MasterRecordId");
				if (masterRecordId !== null) {
					var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "UsrReporting"});
					var filter = Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.EQUAL, "UsrAccount", masterRecordId, Terrasoft.DataValueType.GUID);
					esq.filters.add("filter", filter);
					esq.getEntityCollection(function(response) {
						if (!response || !response.success) {
							return;
						}
						var result = response.collection;
						result.each(function(resultItem) {
							scope.addRecord('c485c4e3-c0a1-4008-a8fe-054f167d5068');
						});
					}, this);
				} else {
					this.addRecord('c485c4e3-c0a1-4008-a8fe-054f167d5068');
				}
			},
			canChangeSelectedItemPosition: function() {
				var selectedItems = this.getSelectedItems();
				return (!Ext.isEmpty(selectedItems) && (selectedItems.length <= 1));
			},
			changePosition: function() {
				var shift = arguments[3];
				var activeRow = this.getActiveRow();
				var projectId = activeRow.get("Id");
				this.updateProjectPosition(projectId, shift, this.onPositionChanged, this);
			},
			onPositionChanged: function(result) {
				if (!result) {
					return;
				}
				var activeRow = this.getActiveRow();
				var parentId = activeRow.get("ParentId");
				if (!parentId) {
					parentId = this.get("MasterRecordId");
				}
				var esq = Ext.create("Terrasoft.EntitySchemaQuery", {rootSchema: this.entitySchema});
				esq.addColumn("UsrPosition");
				var filter = Terrasoft.createColumnFilterWithParameter(
					Terrasoft.ComparisonType.EQUAL, "UsrParent", parentId, Terrasoft.DataValueType.GUID);
				esq.filters.add("filter", filter);
				esq.getEntityCollection(function(response) {
					if (!response || !response.success) {
						return;
					}
					var gridData = this.getGridData();
					var result = response.collection;
					result.each(function(resultItem) {
						var resultItemId = resultItem.get("Id");
						var newPosition = resultItem.get("UsrPosition");
						var gridRecord = gridData.get(resultItemId);
							gridRecord.set("UsrPosition", newPosition);
						});
						var tempCollection = this.Ext.create("Terrasoft.Collection");
						tempCollection.loadAll(gridData);
						this.sortCollection(tempCollection);
						gridData.clear();
						gridData.loadAll(tempCollection);
				}, this);
			},
			sortCollection: function(collection) {
				collection.sortByFn(function(a, b) {
					var positionA = a.get("UsrPosition");
					var positionB = b.get("UsrPosition");
					var q = positionA - positionB;
					return q === 0 ? 0 : (q) / Math.abs(q);
				});
			},
		},
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "merge",
				"name": "DataGrid",
				"values": {
					"type": "listed",
					"hierarchical": true,
					"sortColumnDirection": {"bindTo": "disableGridSorting"},
					"hierarchicalColumnName": "ParentId",
					"updateExpandHierarchyLevels": {
						"bindTo": "onExpandHierarchyLevels"
					},
					expandHierarchyLevels: {
						"bindTo": "expandHierarchyLevels"
					}
				}
			},
			{
				"operation": "insert",
				"name": "OpenReportButton",
				"parentName": "Detail",
				"propertyName": "tools",
				"values": {
					"itemType": Terrasoft.ViewItemType.BUTTON,
					"click": {"bindTo": "openReport"},
					"visible": {"bindTo": "isPortal"},
					"enabled": {"bindTo": "isPortal"},
					"caption": "Open"
				},
				"index": 0
			},
			{
				"operation": "remove",
				"name": "AddRecordButton",
				"values": {
					"visible": {"bindTo": "isCRM"}
				}
			},
			{
				"operation": "insert",
				"name": "UpButton",
				"parentName": "Detail",
				"propertyName": "tools",
				"index": 0,
				"values": {
					"itemType": Terrasoft.ViewItemType.BUTTON,
					"tag": -1,
					"imageConfig": {
						"bindTo": "Resources.Images.UpImage"
					},
					"click": {"bindTo": "changePosition"},
					"visible": {"bindTo": "getToolsVisible"},
					"enabled": {"bindTo": "canChangeSelectedItemPosition"},
					"hint": {"bindTo": "Resources.Strings.ChangePositionUpButtonCaption"}
				}
			},
			{
				"operation": "insert",
				"name": "DownButton",
				"parentName": "Detail",
				"propertyName": "tools",
				"index": 1,
				"values": {
					"itemType": Terrasoft.ViewItemType.BUTTON,
					"tag": 1,
					"imageConfig": {
						"bindTo": "Resources.Images.DownImage"
					},
					"click": {"bindTo": "changePosition"},
					"visible": {"bindTo": "getToolsVisible"},
					"enabled": {"bindTo": "canChangeSelectedItemPosition"},
					"hint": {"bindTo": "Resources.Strings.ChangePositionDownButtonCaption"}
				}
			}
		]/**SCHEMA_DIFF*/
	};
});

Ошибка Uncaught Terrasoft.ItemNotFoundException: Item with key f5695207-a45d-4975-a484-92384cb438d1 Does not exist говорит, что не был найден какой-то элемент.

Уточните, пожалуйста, Вы не удаляли колонки из объекта?

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

Попробуйте заместить метод addItemToGridData следующим образом:

	addItemsToGridData: function(dataCollection, options) {
					if (dataCollection.isEmpty()) {
						return;
					}
					var firstItem = dataCollection.getByIndex(0);
					var parentId = firstItem.get("ParentId");
					if (parentId) {
						options = {
							mode: "child",
							target: parentId
						};
						var gridData = this.getGridData();
						var parentObj = gridData.contains(parentId) ? gridData.get(parentId) : undefined;
						if (parentObj) {
							parentObj.set("HasNesting", 1);
						}
						if (!this.isItemExpanded(parentId)) {
							return;
						}
					} else {
						this.set("LastRecord", dataCollection.getByIndex(dataCollection.getCount() - 1));
					}
					this.callParent([dataCollection, options]);
					if (options && (options.mode === "child" || options.mode === "top")) {
						var gridDataChild = this.getGridData();
						var tempCollection = this.Ext.create("Terrasoft.Collection");
						tempCollection.loadAll(gridDataChild);
						this.sortCollection(tempCollection);
						gridDataChild.clear();
						gridDataChild.loadAll(tempCollection);
					}
					this.set("ExpandItemId", null);
				},

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

define("UsrReportingPageV2", [],
	function() {
		return {
			entitySchemaName: "UsrReporting",
			messages: {},
			attributes: {
				"enabledForPortal": {
					"dataValueType": Terrasoft.DataValueType.BOOLEAN,
					"value":  true
				},
				"visibleEnablePortalBool": {
					"dataValueType": Terrasoft.DataValueType.BOOLEAN,
					"value":  true
				}
			},
			details: /**SCHEMA_DETAILS*/{
				Files: {
					schemaName: "FileDetailV2",
					entitySchemaName: "UsrReportingFile",
					filter: {
						masterColumn: "Id",
						detailColumn: "UsrReporting"
					}
				}
			}/**SCHEMA_DETAILS*/,
 
			mixins: {},
			methods: {
				init: function () {
					var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
						"rootSchemaName": "SysAdminUnit"
					});
					esq.addColumn("Id");
					esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.EQUAL, "Id", Terrasoft.SysValue.CURRENT_USER.value));
					esq.filters.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.EQUAL, "[SysAdminUnitInRole:SysAdminUnit:Id].SysAdminUnitRoleId",
						"720B771C-E7A7-4F31-9CFB-52CD21C3739F"));
					esq.getEntityCollection(function(result) {
						var isPortalUser = result.success && (result.collection.getCount() === 1);
						this.set("enabledForPortal", !isPortalUser);
						this.set("visibleEnablePortalBool", !isPortalUser);
						if (isPortalUser) this.checkEnabled();
					}, this);
					this.callParent(arguments);
				},
				checkEnabled: function () {
					if (this.get("UsrEnablePortal")) {
 
					}
				},
				onSaved: function() {
					if (Terrasoft.configuration.Storage.hasOwnProperty("newChildReport")) {
						var accountID, parentID;
						var defValues = this.get("DefaultValues");
						for (var i = 0; i < defValues.length; i++) {
							switch (defValues[i].name) {
								case "UsrAccount":
									accountID = defValues[i].value;
									break;
								case "UsrParent": 
									parentID = defValues[i].value;
									break;
							}
						}
						var update = Ext.create("Terrasoft.UpdateQuery", {
							rootSchemaName: "UsrReporting"
						});
						update.setParameterValue("UsrAccount", accountID, Terrasoft.DataValueType.GUID);
						update.setParameterValue("UsrParent", parentID, Terrasoft.DataValueType.GUID);
						var filter = update.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Id" , this.get("Id"));
						update.filters.add("FilterId", filter);
 
						update.execute(function(result) {
 
						});
						delete Terrasoft.configuration.Storage.newChildReport;
					}
					this.callParent(arguments);
				}
			},
			diff: /**SCHEMA_DIFF*/[
	{
		"operation": "insert",
		"name": "UsrDisplayPortal",
		"values": {
			"layout": {
				"colSpan": 12,
				"rowSpan": 1,
				"column": 12,
				"row": 1,
				"layoutName": "Header"
			},
			"enabled": {"bindTo": "enabledForPortal"},
			"visible": {"bindTo": "visibleEnablePortalBool"},
			"bindTo": "UsrDisplayPortal"
		},
		"parentName": "Header",
		"propertyName": "items",
		"index": 0
	},
	{
		"operation": "insert",
		"name": "UsrFileName",
		"values": {
			"layout": {
				"colSpan": 12,
				"rowSpan": 1,
				"column": 0,
				"row": 0,
				"layoutName": "Header"
			},
			"bindTo": "UsrFileName",
			"enabled": {"bindTo": "enabledForPortal"},
			"visible": true
		},
		"parentName": "Header",
		"propertyName": "items",
		"index": 1
	},
	{
		"operation": "insert",
		"name": "HistoryTabContainer",
		"values": {
			"caption": {
				"bindTo": "Resources.Strings.HistoryTabCaption"
			},
			"items": []
		},
		"parentName": "Tabs",
		"propertyName": "tabs",
		"index": 0
	},
	{
		"operation": "insert",
		"name": "Files",
		"values": {
			"itemType": 2
		},
		"parentName": "HistoryTabContainer",
		"propertyName": "items",
		"index": 0
	},
	{
		"operation": "remove",
		"name": "ESNTab"
	},
	{
		"operation": "remove",
		"name": "ESNFeedContainer"
	},
	{
		"operation": "remove",
		"name": "ESNFeed"
	}
]/**SCHEMA_DIFF*/
	};
});
Показать все комментарии

Добрый день.

Проблема с обновлением грида детали после добавления элемента в деталь. Элемент не появляется в гриде сразу после выбора.

1. Выбор элементов в детали реализован с помощью LookupUtilities:

        var lookupConfig = {
                entitySchemaName: "BankingService",
                columnName: "Name",
                columns: ["ClientType"],
                multiSelect: true,
                filters: filters
        };
           
        LookupUtilities.ThrowOpenLookupMessage(
            sandbox,
            lookupConfig,
            this.addBankingServiceItemsCallback,
            this,
            this.getCardModuleSandboxId()
        );

2. Собственно callback-функция для обработки выбора пользователя:

                this.methods.addBankingServiceItemsCallback = function(args) {
                        if (!args || args.selectedRows.getCount() === 0) {
                                return;
                        }
                       
                        var selectedIds = args.selectedRows.getKeys();
                        var synchronizedRule = this.filterValue;
                        var batchQuery = Ext.create('Terrasoft.BatchQuery');
                        Terrasoft.each(selectedIds, function(item) {
                                var insert = Ext.create('Terrasoft.InsertQuery', {
                                        rootSchemaName: this.entitySchema.name
                                });
                                var newGuid = Terrasoft.generateGUID();
                                insert.setParameterValue(
                                        'Id',
                                        newGuid,
                                        Terrasoft.DataValueType.GUID
                                );
                                insert.setParameterValue(
                                        'BankingService',
                                        item,
                                        Terrasoft.DataValueType.GUID
                                );
                                insert.setParameterValue(
                                        'SynchronizedRule',
                                        synchronizedRule,
                                        Terrasoft.DataValueType.GUID
                                );
                                batchQuery.add(insert);
                        }, this);
                        batchQuery.execute();
                        sandbox.publish('DetailChanged', {detailName: this.entitySchema.name}, [this.getSenderSandboxId()]);
                };

3. Обработчик события DetailChanged на странице редактирования объекта с деталью:

                this.methods.detailChangedSubscriber = function(args) {
                        viewModel.reloadDetail(args.detailName + 'Detail');
                };

Однако, после нажатия кнопки "Выбрать", выбранные записи в гриде детали не отображаются. Если нажать "Сохранить" на странице редактирования объекта и потом открыть заново этот объект для редактирования, то в детали выбранные записи видны.

Как обновить грид детали, чтобы выбранные элементы отображались непосредственно после выбора?

Заранее благодарен за помощь!

Нравится

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

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

уточните пожалуйста версию и конфигурацию BPMOnline. Спасибо!!!

"Власов Михаил Викторович" написал:

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

уточните пожалуйста версию и конфигурацию BPMOnline. Спасибо!!!

Михаил, версия 7.2; конфигурация вроде "lending"

Здравствуйте, я не воссоздавал на тестовом примере batchQuery, это не суть вопроса, сразу менял данные детали в базе данных, через sql management studio. Самое главное здесь в вашем вопросе, это вызов «viewModel.reloadDetail(args.detailName + 'Detail');»

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

Во-вторых, почему viewModel? Данный метод же есть прямо в главном скоупе страницы. Я закешировал для теста скоуп страницы в инит методе:

structure.userCode = function() {
   this.methods.init = function() {
      document.scp = this;
   };
};

И вот видно наш метод для обновления детали:

Во вторых, имя, передаваемое как аргумент должно соответствовать именно «name» свойству детали, а не «schemaName». Вот, к примеру, деталь опыта работы контакта:

И вот такой её вызов, отлично обновляет содержимое грида:

document.scp.reloadDetail("contactCareer");

где «document.scp» по сути this скоуп страницы контакта.

Вывод: Отладьте метод, проверьте имена.

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

Добрый день!

Бизнес-кейс:
Необходимо у контакта делать пометки к средствам связи. Например, "конкретный телефон - телефон бабушки" или "по этому номеру не звонить после 21.00".

Как возможно добавить комментарий к каждому средству связи в детали communication options стандартным функционалом (не отказываясь от этой детали)?

Спасибо!

Нравится

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

Деталь «Средства связи является» не простой деталью так как она формируется динамически и кардинально отличается от обычных деталей. Мы не рекомендуем вносить исправления в данную деталь, так как Вы можете нарушить логику ее заполнения.
Для внесения изменений в деталь средства связи Вам необходимо будет заместить объект "ContactCommunication" и добавить текстовое поле с произвольным названием. Расширить страницу ContactCommunicationDetailV2, переопределить метод getItemViewConfig.
Ниже, как пример (в случае если новое поле назвать Comment). Изменения выделены комментариями. Можете также попробовать сделать по другому с вызовом родительского метода.

getItemViewConfig: function(itemConfig) {
var itemViewConfig = this.get("itemViewConfig");
if (itemViewConfig) {
itemConfig.config = itemViewConfig;
return;
}
var config = ViewUtilities.getContainerConfig("item-view",
["detail-edit-container-user-class", "control-width-15"]);
var typeMenuItems = [];
var communicationTypes = this.get("CommunicationTypes");
communicationTypes.each(function(item) {
var name = item.get("Name");
var value = item.get("Id");
typeMenuItems.push({
id: value,
caption: name,
tag: value,
click: { bindTo: "typeChanged" }
});
}, this);
var typeButtonConfig = {
id: "type",
className: "Terrasoft.Button",
classes: {
wrapperClass: ["label-wrap", "detail-type-btn-user-class"],
textClass: ["detail-type-btn-inner-user-class"]
},
style: Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
selectors: {wrapEl: "#type"},
caption: {
bindTo: "CommunicationType",
bindConfig: { converter: "typedStringValueConverter" }
},
menu: { items: typeMenuItems }
};
var deleteButtonConfig = {
id: "delete",
className: "Terrasoft.Button",
classes: {
wrapperClass: "detail-delete-btn-user-class",
imageClass: ["detail-delete-btn-image-user-class", "close-button-background-no-repeat"]
},
imageConfig: resources.localizableImages.DeleteIcon,
style: Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
selectors: {wrapEl: "#delete"},
click: {bindTo: "deleteItem"}
};
var editConfig = {
id: "edit",
className: "Terrasoft.TextEdit",
classes: {wrapClass: ["communication-lookup-img-user-class", "detail-edit-user-class"]},
rightIconClasses: ["lookup-edit-right-icon"],
value: { bindTo: "Number" },
readonly: {
bindTo: "CommunicationType",
bindConfig: { converter: "isSocialNetworkType" }
},
enableRightIcon: {
bindTo: "CommunicationType",
bindConfig: { converter: "isSocialNetworkType" }
},
rightIconClick: { bindTo: "onLookUpClick" }
};
//Начало исправления
var commentConfig = {
id: "comment",
className: "Terrasoft.TextEdit",
value: { bindTo: "Comment" },
};
//Завершение исправления
config.items.push(typeButtonConfig, editConfig, deleteButtonConfig, commentConfig); //добавляем commentConfig

itemConfig.config = config;
this.set("itemViewConfig", config);
},

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