Вопрос

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

Столкнулся с проблемой у детали с редактируемым реестром.

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

Делаю все по инструкции из https://academy.terrasoft.ru/documents/technic-sdk/7-14/detal-s-redaktiruemym-reestrom (включая регистрацию через sql-запрос)

+ пункт 3 из https://academy.terrasoft.ru/documents/technic-sdk/7-14/detal-so-stranicey-dobavleniya (включая регистрацию связи между схемой объекта детали и схемой страницы редактирования записи детали через sql-запрос и перекомпиляцию в конфигурации)

Так же пробовал на демо-стенде с грубо говоря копипастом из инструкции - результат тот же.

Что забыл\упустил? Заранее благодарю!

 

У меня такой же вопрос

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

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

Проверьте, действительно, ли добавилась нужная информация в SysDetails, SysModuleEntity и SysModuleEdit в базе данных Вашего сайта.

Это можно сделать с помощью sql-запроса к базе данных.

P.S. Обычно, чтобы не возиться с написанием специальных sql-запросов для регистрации детали, я сначала создаю стандартную деталь через мастер деталей, а потом вношу изменения в схему самой детали, чтобы она стала редактируемой.

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

Алла, добрый день!
По базе вроде бы все на своих местах. Но так или иначе ваш способ сработал, спасибо вам огромное)
Надо будет сравнить таблицы и разобраться с вариантом "вручную".

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

Добрый день, коллеги. Необходимо чтобы в разделе была сгенерирована деталь с полями (описание, тип оплаты, сумма,  файл (фото_чека.jpg/png/pdf)).

В разделе есть деталь "Файл и ссылка объекта Продажи". Добавляю колонки тип оплаты, сумма. Затем замещаю схему FileDetailV2 и добавляю в него код для того, чтобы была возможность настроить колонки для детали. Настраиваю колонки и они показываются на странице, но заполнить добавленные поля (тип оплаты, сумма) не получается потому что на карточке редактирования их нет (там только стандартные поля Название и описание).

Вопрос: как добавить созданные поля в карточку?

У меня такой же вопрос

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

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

Григорий Чех,

Не подскажите, как создать эту карточку?

Артём Иванов Иванович,

в мастере раздела создается новая страница редактирования на первой странице

Натали Вишня,

Это очевидно не то, что мне нужно.

Добавить нужные колонки и отобразить их получилось:

Но какую страницу заместить, чтобы добавить в эту карточку необходимые колонки (сумма) 

Похоже на LinkPageV2. Точно проверить можно, нажав в браузере «Inspect» и посмотрев в HTML-коде.

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

Имеется иерархическая деталь с редактируемым реестром. В ней возникает проблема при сохранении дробного числа. Появляется ошибка Cannot read property 'getAttribute' of null, которая возникает в результате того, что метод GetDomRow возвращает undefined. После этого я не могу больше сохранять дробные числа в реестре и приходится перезагружать страницу. Первое сохранение проходит удачно, хоть и успевает появиться ошибка. В результате чего возникает такая проблема? ниже представлен код детали

define("IDSBRefrigeratorInTMADetail",
    ["ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities", "ServiceHelper"],
    function (ConfigurationGrid, ConfigurationGridGenerator, ConfigurationGridUtilities, ServiceHelper) {
        return {
            messages: {
                "ReloadRefrigeratorsInTMAGrid": {
                    "mode": Terrasoft.MessageMode.BROADCAST,
                    "direction": Terrasoft.MessageDirectionType.SUBSCRIBE
                }
            },
            entitySchemaName: "IDSBRefrigeratorInTMA",
            attributes: {
                "IsEditable": {
                    dataValueType: Terrasoft.DataValueType.BOOLEAN,
                    type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    value: true
                }
            },
            mixins: {
                ConfigurationGridUtilities: "Terrasoft.ConfigurationGridUtilities"
            },
            details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "merge",
                    "name": "DataGrid",
                    "values": {
                        "hierarchical": true,
                        "hierarchicalColumnName": "IDSBParent",
                        "className": "Terrasoft.ConfigurationGrid",
                        "generator": "ConfigurationGridGenerator.generatePartial",
                        "generateControlsConfig": { "bindTo": "generateActiveRowControlsConfig" },
                        "changeRow": { "bindTo": "changeRow" },
                        "unSelectRow": { "bindTo": "unSelectRow" },
                        "onGridClick": { "bindTo": "onGridClick" },
                        "activeRowAction": { "bindTo": "onActiveRowAction" },
                        "initActiveRowKeyMap": { "bindTo": "initActiveRowKeyMap" },
                        "multiSelect": false
                    }
                },
                {
                    "operation": "remove",
                    "name": "AddRecordButton"
                }]/**SCHEMA_DIFF*/,
            methods: {
                generateActiveRowControlsConfig: function (id, columnsConfig, rowConfig) {
                    this.columnsConfig = columnsConfig;
                    var gridData = this.getGridData();
                    var activeRow = gridData.get(id);
                    var isEditableColumn;
                    if (activeRow.values.IDSBParent === "") {
                        isEditableColumn = this.ParentColumnIsEditable;
                    }
                    else {
                        isEditableColumn = this.ColumnIsEditable;
                    }
                    var gridLayoutItems = [];
                    var currentColumnIndex = 0;
                    Terrasoft.each(columnsConfig, function (columnConfig) {
                        var cellConfig = this.getActiveRowCellConfig(columnConfig, currentColumnIndex);
                        cellConfig.enabled = isEditableColumn(cellConfig.name);
                        if (!cellConfig.hasOwnProperty("isNotFound")) {
                            gridLayoutItems.push(cellConfig);
                        }
                        currentColumnIndex += cellConfig.layout.colSpan;
                    }, this);
                    this.applyBusinessRulesForActiveRow(id, gridLayoutItems);
                    var viewGenerator = Ext.create(this.getRowViewGeneratorClassName());
                    viewGenerator.viewModelClass = this;
                    var gridLayoutConfig = viewGenerator.generateGridLayout({
                        name: this.name,
                        items: gridLayoutItems
                    });
                    rowConfig.push(gridLayoutConfig);
                },
                ParentColumnIsEditable: function (columnName) {
                    return (columnName === "IDSBPlacementPrice" || columnName === "IDSBNumberOfDoors" || columnName === "IDSBProlongation");
                },
                ColumnIsEditable: function (columnName) {
                    return (columnName === "IDSBRBBottlePlan" || columnName === "IDSBRBBottleCurrent"
                        || columnName === "IDSBBRBottlePlan" || columnName === "IDSBBRBottleCurrent");
                },
                init: function () {
                    this.callParent(arguments);
                    this.set("IsPageable", false);
                    this.set("RowCount", 28000);
                    this.sandbox.subscribe("ReloadRefrigeratorsInTMAGrid", this.onReloadRefrigeratorsInTMAGrid, this);
                },
                onReloadRefrigeratorsInTMAGrid: function (args) {
                    var id = this.get("MasterRecordId");
                    debugger;
                    if (id === args) {
                        this.reloadGridData();
                    }
                },
                addGridDataColumns: function (esq) {
                    this.callParent(arguments);
                    if (!esq.columns.contains("IDSBParent")) {
                        esq.addColumn("IDSBParent");
                    }
                },
                getGridDataColumns: function () {
                    var gridDataColumns = this.callParent(arguments);
                    if (!gridDataColumns.IDSBParent) {
                        gridDataColumns.IDSBParent = {
                            path: "IDSBParent"
                        };
                    }
                    return gridDataColumns;
                },
                addToolsButtonMenuItems: function (toolsButtonMenu) {
                    this.addGridOperationsMenuItems(toolsButtonMenu);
                    if (this.useDetailWizard) {
                        this.addDetailWizardMenuItems(toolsButtonMenu);
                    }
                },
                prepareResponseCollection: function (collection) {
                    collection.each(function (item) {
                        var parent = item.get("IDSBParent");
                        var parentId = parent && parent.value;
                        if (parentId) {
                            item.set("IDSBParentId", parentId);
                        }
                        Terrasoft.each(item.columns, function (column) {
                            this.addColumnLink(item, column);
                            this.applyColumnDefaults(column);
                        }, this);
                    }, this);
                }
            }
        };
    });

У меня такой же вопрос

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

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

В любом случае вам может помочь только отладка кода!

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

saveRowChanges: function (row, callback, scope) {
                    scope = scope || this;
                    callback = callback || Terrasoft.emptyFn;
                    if (row && this.getIsRowChanged(row)) {
                        if (row.values.IDSBParent !== "") {
                            this.saveChildRow(row, callback, scope);
                        }
                        else {
                            this.saveParentRow(rowm, callback, scope);
                        }
                    } else {
                        callback.call(scope);
                    }
                },
saveChildRow: function (row, callback, scope) {
                    var changed = row.changedValues;
                    debugger;
                    if (!changed.hasOwnProperty("IDSBBRBottleCurrent")) {
                        changed.IDSBBRBottleCurrent = row.values.IDSBBRBottleCurrent;
                    }
                    if (!changed.hasOwnProperty("IDSBBRBottlePlan")) {
                        changed.IDSBBRBottlePlan = row.values.IDSBBRBottlePlan;
                    }
                    if (!changed.hasOwnProperty("IDSBRBBottlePlan")) {
                        changed.IDSBRBBottlePlan = row.values.IDSBRBBottlePlan;
                    }
                    if (!changed.hasOwnProperty("IDSBRBBottleCurrent")) {
                        changed.IDSBRBBottleCurrent = row.values.IDSBRBBottleCurrent;
                    }
                    callback = this.reloadGridData;
                    var serviceSaveData = {
                        RowId: row.values.Id,
                        bottles: changed
                    }
                    ServiceHelper.callService("IDSBPlacingREService", "SaveChildRow",
                        callback, serviceSaveData, scope);
                }

 

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

Создал иерархическую деталь с редактируемым реестром. Но появилась проблема при количестве дочерних элементов больше 8. Они почему не отображаются, выдается ошибка Cannot read property 'getAttribute' of null. В БД всё верно. 

Вот код детали

define("IDSBRefrigeratorInTMADetail",
    ["ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities"],
    function () {
        return {
            messages: {
                "ReloadRefrigeratorsInTMAGrid": {
                    "mode": Terrasoft.MessageMode.BROADCAST,
                    "direction": Terrasoft.MessageDirectionType.SUBSCRIBE
                }
            },
            entitySchemaName: "IDSBRefrigeratorInTMA",
            attributes: {
                "IsEditable": {
                    dataValueType: Terrasoft.DataValueType.BOOLEAN,
                    type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    value: true
                }
            },
            mixins: {
                ConfigurationGridUtilities: "Terrasoft.ConfigurationGridUtilities"
            },
            details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "merge",
                    "name": "DataGrid",
                    "values": {
                        "hierarchical": true,
                        "hierarchicalColumnName": "IDSBParent",
                        "maxColumns": 48,
                        "maxRowsCount": 10000,
                        "className": "Terrasoft.ConfigurationGrid",
                        "generator": "ConfigurationGridGenerator.generatePartial",
                        "generateControlsConfig": { "bindTo": "generateActiveRowControlsConfig" },
                        "changeRow": { "bindTo": "changeRow" },
                        "unSelectRow": { "bindTo": "unSelectRow" },
                        "onGridClick": { "bindTo": "onGridClick" },
                        "activeRowAction": { "bindTo": "onActiveRowAction" },
                        "initActiveRowKeyMap": { "bindTo": "initActiveRowKeyMap" },
                        "multiSelect": false
                    }
                },
                {
                    "operation": "remove",
                    "name": "AddRecordButton"
                }]/**SCHEMA_DIFF*/,
            methods: {
                generateActiveRowControlsConfig: function (id, columnsConfig, rowConfig) {
                    this.columnsConfig = columnsConfig;
                    var gridData = this.getGridData();
                    var activeRow = gridData.get(id);
                    var isEditableColumn;
                    if (activeRow.values.IDSBParent === "") {
                        isEditableColumn = this.isEditableParentColumn;
                    }
                    else {
                        isEditableColumn = this.isEditableColumn;
                    }
                    var gridLayoutItems = [];
                    var currentColumnIndex = 0;
                    Terrasoft.each(columnsConfig, function (columnConfig) {
                        var cellConfig = this.getActiveRowCellConfig(columnConfig, currentColumnIndex);
                        cellConfig.enabled = isEditableColumn(cellConfig.name);
                        if (!cellConfig.hasOwnProperty("isNotFound")) {
                            gridLayoutItems.push(cellConfig);
                        }
                        currentColumnIndex += cellConfig.layout.colSpan;
                    }, this);
                    this.applyBusinessRulesForActiveRow(id, gridLayoutItems);
                    var viewGenerator = Ext.create(this.getRowViewGeneratorClassName());
                    viewGenerator.viewModelClass = this;
                    var gridLayoutConfig = viewGenerator.generateGridLayout({
                        name: this.name,
                        items: gridLayoutItems
                    });
                    rowConfig.push(gridLayoutConfig);
                },
                isEditableParentColumn: function (columnName) {
                    return false;
                },
                isEditableColumn: function (columnName) {
                    return (columnName === "IDSBBottlePlan");
                }/*,
                init: function () {
                    this.callParent(arguments);
                    this.sandbox.subscribe("ReloadRefrigeratorsInTMAGrid", this.onReloadRefrigeratorsInTMAGrid, this);
                },
                onReloadRefrigeratorsInTMAGrid: function (args) {
                    this.reloadGridData();
                }*/
            }
	};
});

 

У меня такой же вопрос

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

Для упрощения отладки посмотрите SQL профайлером запросы которые отправляются в БД.

Григорий Чех, думаете нужно заместить метод addGridDataColumns?

Григорий имел в виду использование профайлера. Естественно, только для случаев, когда есть доступ к серверу БД.

посмотрел профайлер. Выполняется следующий запрос. Забил его сам в SQL Management. Выдал недостающие элементы, которые как раз невыведены на экран. Ошибка возникает когда нажимаю "Показать больше"

SELECT
	[IDSBRefrigeratorInTMA].[Id] [Id],
	[IDSBRefrigeratorInTMA].[IDSBStreet] [IDSBStreet],
	[IDSBRefrigeratorInTMA].[IDSBCustomerInTMAId] [IDSBCustomerInTMAId],
	[IDSBRefrigeratorInTMA].[ITTradeMarketId] [ITTradeMarketId],
	[ITTradeMarket].[ITName] [ITTradeMarket.ITName],
	[IDSBRefrigeratorInTMA].[MonthId] [MonthId],
	[Month].[Name] [Month.Name],
	[IDSBRefrigeratorInTMA].[IDSBBottlePlan] [IDSBBottlePlan],
	[IDSBRefrigeratorInTMA].[IDSBParentId] [IDSBParentId],
	[IDSBParent].[IDSBStreet] [IDSBParent.IDSBStreet],
	[ITTradeMarket].[ITTypeId] [ITTradeMarket.ITTypeId],
	[ITType].[Name] [ITType.Name],
	(
SELECT
	COUNT([SubEntryPoint].[Id]) [Count]
FROM
	[dbo].[EntryPoint] [SubEntryPoint] WITH(NOLOCK)
WHERE
	[SubEntryPoint].[EntityId] = [IDSBRefrigeratorInTMA].[Id]
	AND [SubEntryPoint].[IsActive] = 1) [SubEntryPoint],
	[IDSBRefrigeratorInTMA].[CreatedOn] [CreatedOn],
	[IDSBRefrigeratorInTMA].[CreatedById] [CreatedById],
	[CreatedBy].[Name] [CreatedBy.Name],
	[CreatedBy].[PhotoId] [CreatedBy.PhotoId],
	[IDSBRefrigeratorInTMA].[ModifiedOn] [ModifiedOn],
	[IDSBRefrigeratorInTMA].[ModifiedById] [ModifiedById],
	[ModifiedBy].[Name] [ModifiedBy.Name],
	[ModifiedBy].[PhotoId] [ModifiedBy.PhotoId],
	[IDSBRefrigeratorInTMA].[ProcessListeners] [ProcessListeners]
FROM
	[dbo].[IDSBRefrigeratorInTMA] [IDSBRefrigeratorInTMA] WITH(NOLOCK)
	LEFT OUTER JOIN [dbo].[ITTradeMarket] [ITTradeMarket] WITH(NOLOCK) ON ([ITTradeMarket].[Id] = [IDSBRefrigeratorInTMA].[ITTradeMarketId])
	LEFT OUTER JOIN [dbo].[Month] [Month] WITH(NOLOCK) ON ([Month].[Id] = [IDSBRefrigeratorInTMA].[MonthId])
	LEFT OUTER JOIN [dbo].[IDSBRefrigeratorInTMA] [IDSBParent] WITH(NOLOCK) ON ([IDSBParent].[Id] = [IDSBRefrigeratorInTMA].[IDSBParentId])
	LEFT OUTER JOIN [dbo].[ITITTradeMarketType1] [ITType] WITH(NOLOCK) ON ([ITType].[Id] = [ITTradeMarket].[ITTypeId])
	LEFT OUTER JOIN [dbo].[Contact] [CreatedBy] WITH(NOLOCK) ON ([CreatedBy].[Id] = [IDSBRefrigeratorInTMA].[CreatedById])
	LEFT OUTER JOIN [dbo].[Contact] [ModifiedBy] WITH(NOLOCK) ON ([ModifiedBy].[Id] = [IDSBRefrigeratorInTMA].[ModifiedById])
WHERE
	[IDSBRefrigeratorInTMA].[ITTradeMarketId] = '54368FDE-6D00-4BDE-BAAE-EDEA56EBAA33'
ORDER BY
	[Id] ASC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY

 

Может, 8 элементов видно как раз из-за выборки порциями по 10? Судя по окончанию SQL-запроса, это как раз вторая десятка, первая пропущена.

А где именно вылетает «Cannot read property 'getAttribute' of null», полный стек не видно?

Вылетает на этом методе. В строке var n = this.getDomRow(i) в n кладется undefined и далее соответственно вылетает ошибка. В i в этот момент родительская колонка

onCollectionDataLoaded: function(e, t, a) {
        if (this.theoreticallyActiveRows = null,
        !this.rows.length)
            return this.collection = this.collection || e,
            this.prepareCollectionData(),
            void this.safeRerender();
        if (!Ext.Object.isEmpty(t) && this.rendered) {
            var r = []
              , s = {
                rows: r
            };
            if (t.each(function(e) {
                this.prepareCollectionItem(e);
                var t = this.getRow(e);
                r.push(t),
                a && ("top" !== a.mode ? this.rows.push(t) : this.rows.splice(0, 0, t))
            }, this),
            this.hierarchical && !t.isEmpty()) {
                var i = t.getByIndex(0).get(this.hierarchicalColumnName);
                if (s[this.hierarchicalColumnName] = i,
                "listed" === this.type && i) {
                    var n = this.getDomRow(i)
                      , o = parseInt(n.getAttribute("level"), 10);
                    s.rowLevel = o + 1
                }
            }
            var l = [];
            this.renderGrid(l, s);
            for (var c = "", h = 0, u = l.length; h < u; h += 1)
                c += Ext.DomHelper.createHtml(l[h]);
            Ext.Object.isEmpty(a) && (a = {
                mode: "bottom"
            }),
            this.addRows(c, a),
            this.checkNeedLoadData()
        }
    },

 

Что-то не могу найти такой функции в «коробке».

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

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

Это логично, если сбой при превышении 8 потомков. В плоской детали никаких потомков нет. Сравните с другими иерархическими деталями, есть там такое ограничение или нет?

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

init: function () {
                    this.callParent(arguments);
                    this.set("IsPageable", false);
                    this.set("RowCount", 28000);
                    this.sandbox.subscribe("ReloadRefrigeratorsInTMAGrid", this.onReloadRefrigeratorsInTMAGrid, this);
                },

 

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

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

Добрый день.

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

Но почему-то при добавлении не чего не происходит.

Прикрепленные файлы
zadacha.png89.04 КБ
код.png49.45 КБ

У меня такой же вопрос

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

Должно выглядить вот так

Ужк обсуждалось тут

Григорий Чех пишет:

Ужк обсуждалось тут

Там не то что мне нужно. У меня реестр детали с 2 справочными полями. При нажатии на одно из них должно открыться окно с данными вкладками.

По поводу нестандартного окна выбора из справочника, см. это и это обсуждения.

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

Добрый день! подскажите пжлст, каким способом можно применить маску номера для строк на детали с редактируемым реестром. Методы, которые работают для нумерации строк для обычной детали, в данном случае не работают.

Спасибо!

У меня такой же вопрос

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

По идее если использовать формирование номер на событийном БП  (штатно как описано в документации) то после сохранения он должен отображатся на детали, посмотрите тут (Алгоритм реализации кейса на стороне сервера)

 

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

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

Наверное речь о формировании номера для объекта по маске по аналогии с тем как это делается в карточке редактирования открываемой из реестра. 

По идее если использовать формирование номер на событийном БП  (штатно как описано в документации) то после сохранения он должен отображатся на детали, посмотрите тут (Алгоритм реализации кейса на стороне сервера)

 

Добрый день, коллеги! Спасибо за обратную связь!  

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

Попробую еще объяснить. Нажатие Добавить запись на деталь у нас обращается к коду, который что то анализирует, чтобы сгенерировать код строки. Код сгенерирован. Далее схема детали должна передать этот номер на страницу редактирования детали, а страница в данном случае (редактируемый реестр) не активируется и получается передавать некуда. Именно в этом вопрос сейчас).

Я смотрю в решении Террасофта с маркета в Конструкторе отчетов даже это не сделано… там всегда проставляется по умолчанию просто 1… и далее ты сам сидишь и нумеруешь.

 

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

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

Добрый день.
Необходимо в редактируемом реестре добавить свойство enabled для поля по условию.
Атрибут условия вычисляется в методе onEntityInitialized Схемы редактирования детали.
Но при загрузке редактируемого реестра ни метод init, ни onEntityInitialized  ни бизнес-правила не отрабатывают.
Как быть в такой ситуации?
 

У меня такой же вопрос

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

Игорь, привет!

Была подобная ситуация - нужно было забиндить enabled поля на поле в связанном справочнике. Делал примерно так:

1. На странице редактирования добавил attribute с именем "{Имя_справочного_поля}.{Имя_колонки_в_справочнике}". Значение его проставлял в onEntityInitialized, и enebled колонки завязал бизнес-правилом на этот аттрибут.

2. На странице детали детали в методе addGridDataColumns добавлял колонку с таким же именем как и аттрибут на странице редактирования (у меня там было bool) и вауля.

 

Дело в том, что правила работают, но в редактируемом реестре происходит поиск свойства (на которое ты забиндил enabled) в колонках текущей строки, соответственно если такой колонки нет в строке, получается как получается.

Костыль, конечно, но попробовать стоит. Если есть более правильный способ - тоже интересно)

Игорь, привет!

Была подобная ситуация - нужно было забиндить enabled поля на поле в связанном справочнике. Делал примерно так:

1. На странице редактирования добавил attribute с именем "{Имя_справочного_поля}.{Имя_колонки_в_справочнике}". Значение его проставлял в onEntityInitialized, и enebled колонки завязал бизнес-правилом на этот аттрибут.

2. На странице детали детали в методе addGridDataColumns добавлял колонку с таким же именем как и аттрибут на странице редактирования (у меня там было bool) и вауля.

 

Дело в том, что правила работают, но в редактируемом реестре происходит поиск свойства (на которое ты забиндил enabled) в колонках текущей строки, соответственно если такой колонки нет в строке, получается как получается.

Костыль, конечно, но попробовать стоит. Если есть более правильный способ - тоже интересно)

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

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

Всем привет!

Столкнулся с проблемой реализации фильтра в справочном поле в детали с редактируемым реестром: нужно делать запрос в БД для получения значения из карточки и в зависимости от этого строить фильтр. Как победить асинхронность?

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

У меня такой же вопрос

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

Дмитрий, почти любую фильтрацию (даже сложную) справочного поля можно сделать с использованием атрибута filters колонки (подробнее в https://academy.terrasoft.ru/documents/technic-sdk/7-13/primenenie-filt…). Для отладки фильтра рекомендую отследить запросы в SQL Server Profiler

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

Дмитрий, почти любую фильтрацию (даже сложную) справочного поля можно сделать с использованием атрибута filters колонки (подробнее в https://academy.terrasoft.ru/documents/technic-sdk/7-13/primenenie-filt…). Для отладки фильтра рекомендую отследить запросы в SQL Server Profiler

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

На странице добавлены две детали с редактируемым реестром. Создал первую и понял, что неправильно. Потом создал вторую корректно и захотел первую удалить (создавал кодом). В мастере ее удалить нельзя. Открыл конфигурацию и удалил строки из схемы раздела, а именно details и diff, касающихся этой детали. Сохранил и очистил кэш. После этого перестали отображаться детали вообще и в консоли появилась ошибка cannot read property "findPrimary". После возвращения кода детали обе появились и работают. Как убрать первую деталь? 

У меня такой же вопрос

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

Очень похоже, что как-то не так удаляете деталь со страницы. Если корректно удалить из details и diff, делать должна удалиться.

Очень похоже, что как-то не так удаляете деталь со страницы. Если корректно удалить из details и diff, делать должна удалиться.

Тёскин Дмитрий Валерьевич,

Проблема в том, что даже ошибиться негде

Вот код страницы полностью:
define("UsrConcertProgram1Page", [],
function() {
    return {
        entitySchemaName: "UsrConcertProgram",
        attributes: {
            "UsrActiveEveryday": {
                    "dataValueType": Terrasoft.DataValueType.INTEGER,
                    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    "caption": "UsrActiveEveryday",
                    "value" : "0"
                }
        },
        modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
        details: /**SCHEMA_DETAILS*/{
            "Files": {
                "schemaName": "FileDetailV2",
                "entitySchemaName": "UsrConcertProgramFile",
                "filter": {
                    "masterColumn": "Id",
                    "detailColumn": "UsrConcertProgram"
                }
            },
            "UsrPerformanceDetail": {
                "schemaName": "UsrPerformanceDetail",
                "entitySchemaName": "UsrPerformance",
                "filter": {
                    "detailColumn": "UsrConcertProgram",
                    "masterColumn": "Id"
                },
            },
            "UsrSchema1Detail660d66ee": {
                "schemaName": "UsrSchema1Detail",
                "entitySchemaName": "UsrConcertPerformance",
                "filter": {
                    "detailColumn": "UsrConcertProgram",
                    "masterColumn": "Id"
                }
            }
        }/**SCHEMA_DETAILS*/,
        businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
        methods: {
            getActiveEverydayConcerts: function() {
                var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "UsrConcertProgram"
                });
                
                var filterGroup = this.Terrasoft.createFilterGroup();
                
                filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;
                filterGroup.add("concertsIsActive",
                this.Terrasoft.createColumnFilterWithParameter(this.Terrasoft.ComparisonType.EQUAL, "UsrIsActive", "1"));
                filterGroup.add("performancePeriodEveryday",
                this.Terrasoft.createColumnFilterWithParameter(this.Terrasoft.ComparisonType.EQUAL,
                "UsrPerformancePeriod", "85A8C133-FF83-4290-9F69-B34EAF627F8C"));
                
                esq.filters = filterGroup;
                
                esq.getEntityCollection(function(result) {
                    if (result.success)
                    {
                        this.set("UsrActiveEveryday", result.collection.getCount());
                    }
                }, this);
            },
            maxEverydayActive: function() {
                var invalidMessage = "";
                var maxActiveEverydayConcertCount = 0;
                var activeEverydayConcertCount = this.get("UsrActiveEveryday");
                this.Terrasoft.SysSettings.querySysSettingsItem("UsrMaxEverydayActiveProgram", function(value) {
                    maxActiveEverydayConcertCount = value;
                }, this);
                
                if (this.get("UsrPerformancePeriod").value == "85A8C133-FF83-4290-9F69-B34EAF627F8C".toLowerCase() &&
                this.get("UsrIsActive") && (activeEverydayConcertCount > maxActiveEverydayConcertCount) && !this.isAddMode()) {
                    invalidMessage = "Допускается не более " + maxActiveEverydayConcertCount +
                    " активных ежедневных концертных программ.";
                }
                if(this.get("UsrPerformancePeriod").value == "85A8C133-FF83-4290-9F69-B34EAF627F8C".toLowerCase() &&
                this.get("UsrIsActive") && (activeEverydayConcertCount >= maxActiveEverydayConcertCount) && this.isAddMode()) {
                    invalidMessage = "Допускается не более " + maxActiveEverydayConcertCount +
                    " активных ежедневных концертных программ.";
                }
                return {
                    fullInvalidMessage: invalidMessage,
                    invalidMessage: invalidMessage
                };
            },
            setValidationConfig: function() {
                this.callParent(arguments);
                this.addColumnValidator("UsrIsActive", this.maxEverydayActive);
                this.addColumnValidator("UsrPerformancePeriod", this.maxEverydayActive);
            },
            onEntityInitialized: function() {
                this.callParent(arguments);
                this.getActiveEverydayConcerts();
            }
        },
        dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
        diff: /**SCHEMA_DIFF*/[
            {
                "operation": "insert",
                "name": "UsrName9ed0e254-4ab5-4862-9e79-b18e052d92ab",
                "values": {
                    "layout": {
                        "colSpan": 24,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 0,
                        "layoutName": "ProfileContainer"
                    },
                    "bindTo": "UsrName"
                },
                "parentName": "ProfileContainer",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "STRING3bea7972-86d7-4d0e-b4d7-5731d5a6a6b6",
                "values": {
                    "layout": {
                        "colSpan": 24,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 1,
                        "layoutName": "ProfileContainer"
                    },
                    "bindTo": "UsrConcertCode",
                    "enabled": true
                },
                "parentName": "ProfileContainer",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "LOOKUP2c6c3d90-34b5-4a43-9b28-26c5c29c6c48",
                "values": {
                    "layout": {
                        "colSpan": 24,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 2,
                        "layoutName": "ProfileContainer"
                    },
                    "bindTo": "UsrOwner",
                    "enabled": true,
                    "contentType": 3
                },
                "parentName": "ProfileContainer",
                "propertyName": "items",
                "index": 2
            },
            {
                "operation": "insert",
                "name": "UsrIsActive3354c9f0-c35f-4c7c-85ec-0b3cc01376b8",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 0,
                        "layoutName": "Header"
                    },
                    "bindTo": "UsrIsActive"
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "CreatedOn770eb82e-0b06-4f93-be35-bdd0ddac28b8",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 12,
                        "row": 0,
                        "layoutName": "Header"
                    },
                    "bindTo": "CreatedOn"
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "UsrActiveEveryday",
                "values": {
                    "bindTo": "getActiveEverydayConcerts",
                    "caption": "UsrActiveEveryday",
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 1
                    }
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 2
            },
            {
                "operation": "insert",
                "name": "Tab75eff25dTabLabel",
                "values": {
                    "caption": {
                        "bindTo": "Resources.Strings.Tab75eff25dTabLabelTabCaption"
                    },
                    "items": []
                },
                "parentName": "Tabs",
                "propertyName": "tabs",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "Tab75eff25dTabLabelGroup46c8d52b",
                "values": {
                    "caption": {
                        "bindTo": "Resources.Strings.Tab75eff25dTabLabelGroup46c8d52bGroupCaption"
                    },
                    "itemType": 15,
                    "markerValue": "added-group",
                    "items": []
                },
                "parentName": "Tab75eff25dTabLabel",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "Tab75eff25dTabLabelGridLayoutd14f72b6",
                "values": {
                    "itemType": 0,
                    "items": []
                },
                "parentName": "Tab75eff25dTabLabelGroup46c8d52b",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "UsrTeama25e968a-f7f0-4c80-bde3-ed860af75538",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 0,
                        "layoutName": "Tab75eff25dTabLabelGridLayoutd14f72b6"
                    },
                    "bindTo": "UsrTeam"
                },
                "parentName": "Tab75eff25dTabLabelGridLayoutd14f72b6",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "UsrComment8c10205e-2bf8-42d0-b7fa-605cc32a37af",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 2,
                        "column": 12,
                        "row": 0,
                        "layoutName": "Tab75eff25dTabLabelGridLayoutd14f72b6"
                    },
                    "bindTo": "UsrComment",
                    "enabled": true,
                    "contentType": 0,
                    "labelConfig": {
                        "caption": {
                            "bindTo": "Resources.Strings.UsrComment8c10205e2bf842d0b7fa605cc32a37afLabelCaption"
                        }
                    }
                },
                "parentName": "Tab75eff25dTabLabelGridLayoutd14f72b6",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "UsrPerformancePeriod8fdfacd0-81ef-4bf3-9ccc-4cb9ab0f5b7b",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 1,
                        "layoutName": "Tab75eff25dTabLabelGridLayoutd14f72b6"
                    },
                    "bindTo": "UsrPerformancePeriod",
                    "enabled": true,
                    "contentType": 5
                },
                "parentName": "Tab75eff25dTabLabelGridLayoutd14f72b6",
                "propertyName": "items",
                "index": 2
            },
            {
                "operation": "insert",
                "name": "UsrSchema1Detail660d66ee",
                "values": {
                    "itemType": 2,
                    "markerValue": "added-detail"
                },
                "parentName": "TabsContainer",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "NotesAndFilesTab",
                "values": {
                    "caption": {
                        "bindTo": "Resources.Strings.NotesAndFilesTabCaption"
                    },
                    "items": []
                },
                "parentName": "Tabs",
                "propertyName": "tabs",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "Files",
                "values": {
                    "itemType": 2
                },
                "parentName": "NotesAndFilesTab",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "NotesControlGroup",
                "values": {
                    "itemType": 15,
                    "caption": {
                        "bindTo": "Resources.Strings.NotesGroupCaption"
                    },
                    "items": []
                },
                "parentName": "NotesAndFilesTab",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "Notes",
                "values": {
                    "bindTo": "UsrNotes",
                    "dataValueType": 1,
                    "contentType": 4,
                    "layout": {
                        "column": 0,
                        "row": 0,
                        "colSpan": 24
                    },
                    "labelConfig": {
                        "visible": false
                    },
                    "controlConfig": {
                        "imageLoaded": {
                            "bindTo": "insertImagesToNotes"
                        },
                        "images": {
                            "bindTo": "NotesImagesCollection"
                        }
                    }
                },
                "parentName": "NotesControlGroup",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "UsrPerformanceDetail",
                "values": {
                    "itemType": 2,
                    "markerValue": "added-detail"
                },
                //"parentName": "TabsContainer",
                "propertyName": "items",
                "index": 2
            }
        ]/**SCHEMA_DIFF*/
    };
});

 

Удаляю я все с деталью UsrPerformanceDetail

 

Можно подойти к решению с другой стороны: откатиться до стандартной страницы из «коробки» без обеих деталей, затем добавить вторую.

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

Коллеги доброго времени суток!

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

define("AbAccountProductDetail",
	["ConfigurationEnums", "ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities"],
	function (enums) {
		return {
			entitySchemaName: "AbAccountProduct",
			attributes: {
				"IsEditable": {
					dataValueType: Terrasoft.DataValueType.BOOLEAN,
					type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
					value: true
				}
			},
			mixins: {
				ConfigurationGridUtilities: "Terrasoft.ConfigurationGridUtilities"
			},
			methods:{
				init: function() {
					this.callParent(arguments);
					this.sandbox.subscribe("[AbAccountProductEntityEventListner]:[RequestToPlatform]:[Exception]", this.accountProductEntityListnerMsgHandler, this);
				},
 
				/*Overrided "BaseGridDetailV2"*/
				editRecord: function(record) {
					var activeRow = record || this.getActiveRow();
					if (!activeRow) {
						return;
					}
					if (!this.getIsCardValid()) {
						return;
					}
					var isCardChanged = this.getIsCardChanged();
					var primaryColumnValue = typeof activeRow === "object" ? activeRow.get(activeRow.primaryColumnName) : activeRow;
					var typeColumnValue = this.getTypeColumnValue(activeRow);
					this.setLastActiveRow(primaryColumnValue);
					if (isCardChanged) {
						this.set("CardState", enums.CardStateV2.EDIT);
						this.set("EditPageUId", typeColumnValue);
						this.set("PrimaryValueUId", primaryColumnValue);
						var args = {
							isSilent: true,
							messageTags: [this.sandbox.id]
						};
						this.sandbox.publish("SaveRecord", args, [this.sandbox.id]);
					} else {
						this.openCard(enums.CardStateV2.EDIT, typeColumnValue, primaryColumnValue);
					}
				},
 
				accountProductEntityListnerMsgHandler: function() {
					Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
					function(scope, message){
							if (!message || message.Header.Sender !== "[AbAccountProductEntityEventListner]:[RequestToPlatform]:[Exception]") {
							return;
						}
						var message2 = message.Body;
						if (!this.Ext.isEmpty(message2)) {
							window.console.info(message2);
							this.Terrasoft.showInformation(message2);
						}
					}, this);
				}
			},
			diff: [
				{
					"operation": "merge",
					"name": "DataGrid",
					"values": {
						"className": "Terrasoft.ConfigurationGrid",
						"generator": "ConfigurationGridGenerator.generatePartial",
						"generateControlsConfig": { "bindTo": "generateActiveRowControlsConfig" },
						"changeRow": { "bindTo": "changeRow" },
						"unSelectRow": { "bindTo": "unSelectRow" },
						"onGridClick": { "bindTo": "onGridClick" },
						"activeRowActions": [
							{
								"className": "Terrasoft.Button",
								"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
								"tag": "save",
								"markerValue": "save",
								"imageConfig": { "bindTo": "Resources.Images.SaveIcon" }
							},
							{
								"className": "Terrasoft.Button",
								"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
								"tag": "card",
								"markerValue": "card",
								"imageConfig": { "bindTo": "Resources.Images.CardIcon" }
							},
							{
								"className": "Terrasoft.Button",
								"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
								"tag": "cancel",
								"markerValue": "cancel",
								"imageConfig": { "bindTo": "Resources.Images.CancelIcon" }
							},
							{
								"className": "Terrasoft.Button",
								"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
								"tag": "remove",
								"markerValue": "remove",
								"imageConfig": { "bindTo": "Resources.Images.RemoveIcon" }
							}
						],
						"initActiveRowKeyMap": { "bindTo": "initActiveRowKeyMap" },
						"activeRowAction": { "bindTo": "onActiveRowAction" },
						"multiSelect": false
					}
				}
			]
		};
	});

Пришлось переопределить editRecord():
 

var primaryColumnValue = typeof activeRow === "object" ? activeRow.get(activeRow.primaryColumnName) : activeRow;

т.к. дальше не срабатывало.
сейчас работает - http://prntscr.com/lfe61n
но при переходе на страницу редактирования поле для связи не заполняется - http://prntscr.com/lfe6k4
Подскажите в чем может быть дело?
Заранее благодарен.

У меня такой же вопрос

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

Попробуйте например вызывать openCardInChain и передавать туда значения по умолчанию
 

addChildRecord: function(typeColumnValue, date) {
var selectedItem = this.get("ActiveRow");
var defaultValues = [];
defaultValues.push({
	name: "ParentId",
	value: typeColumnValue
});
defaultValues.push({
	name: "UsrDate",
	value: date
});
var config = {
	sandbox: this.sandbox,
	schemaName: this.getEditPageSchemaName(typeColumnValue),
	operation: ConfigurationEnums.CardStateV2.ADD,
	moduleId: this.getChainCardModuleSandboxId(typeColumnValue),
	defaultValues: defaultValues
};
this.openCardInChain(config);
},

 

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

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

Попробуйте например вызывать openCardInChain и передавать туда значения по умолчанию
 

addChildRecord: function(typeColumnValue, date) {
var selectedItem = this.get("ActiveRow");
var defaultValues = [];
defaultValues.push({
	name: "ParentId",
	value: typeColumnValue
});
defaultValues.push({
	name: "UsrDate",
	value: date
});
var config = {
	sandbox: this.sandbox,
	schemaName: this.getEditPageSchemaName(typeColumnValue),
	operation: ConfigurationEnums.CardStateV2.ADD,
	moduleId: this.getChainCardModuleSandboxId(typeColumnValue),
	defaultValues: defaultValues
};
this.openCardInChain(config);
},

 

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