Добрый день, коллеги. Необходимо чтобы в разделе была сгенерирована деталь с полями (описание, тип оплаты, сумма,  файл (фото_чека.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);
                },

 

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

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

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

Спасибо!

Нравится

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);
},

 

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

Версия 7.11.3. Sales Team

Кейс для воспроизведения:

1. в детали с редактируемым реестром открыть существующую запись на редактирование (действия детали - Изменить)

2. Закрыть карточку записи.

При этом в консоли отобразится ошибка "Элемент с ключом [object Object] Не существует "



Анализ ошибки  показал, что в базовой схеме BaseGridDetailV2 (метод getActiveRow в строка primaryColumnValue = this.get("ActiveRow")) в атрибуте ActiveRow содержится объект а не строка с идентификатором, т.о. данный метод отрабатывает с ошибкой при попытке определить выделенную строку в редактируемом реестре. 

Также выявлено, что объект присваивается атрибуту ActiveRow в методе restoreActiveRow (схема BaseGridDetailV2 ).

Когда будет исправлена эта ошибка?

Нравится

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

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

Проверили описанное Вами поведение на базовых деталях с редактируемым реестром - ошибка не воспроизводится. 

Если у Вас есть точный кейс воспроизведения ошибки на чистой сборке, пожалуйста, опишите его нам, мы обязательно возьмем его в работу. Также мы можем рассмотреть данную ошибку на кастомной детали (для этого напишите нам на support@terrasoft.ru), но только при наличии оплаченного "Бизнес" или "Премиум" пакета поддержки, а также сертификата по разработке на платформе bpm’online уровня "Продвинутый".

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

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

Есть редактируемая деталь Материалы (аналог деталей Продукты). В карточку детали добавлено поле Изображение. 

Подскажите как вывести в реестр этой редактируемой детали картинку с карточки детали.

Спасибо!!)

 

Нравится

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

Здравствуйте, Елена

 

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

Я передал Ваш пост как пожелание аналитикам продукта на рассмотрение актуальности и возможности реализации такого функционала в будущих версиях приложения.

Denys Diachenko, А с привлечением разработчиков  думаете у нас получиться это сделать?)

 

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

Добрый день, Елена!

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

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

Был бы реестр нередактируемый, было, конечно, проще.

Вывести картинку можно и не одну.

Добавляем в diff 

{
	"operation": "merge",
	"name": "DataGrid",
	"values": {
		"activeRowActions":
		[
			{
				"className": "Terrasoft.ImageView",
				"imageSrc": { bindTo: "UsrPhotoLargeURL" },
				"visible": true,
				"wrapClasses": ["gallery-image"]
			}
		]
	}
}

Делаем функцию

clickAllRows: function() {
	var scope = this;
	this.getGridData().collection.keys.forEach(function(item) {
		scope.setActiveRow(item);
	});
 
	this.setActiveRow("");
 
},
 
onRender: function() {
	this.callParent(arguments);
 
	this.clickAllRows();
},

Т.е. в OnRender мы делаем "раскрываем" все строки.

Алексей-Карягин,

Но картинка-то будет только при выделении) Костыльно как-то получается. У меня была идея на основе детали с проектами сделать: рендерить кнопку с изображением в грид, а при выделении контрола в ряде - imageView. Но тоже хз что получится по итогу)

Золотарев Артем Андреевич,

Артем, добрый день! Можете посоветовать, что нам почитать из документации, чтобы сделать такую разработку? Спасибо!

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

Можно добавить поле с изображением, добавив в блок diff следующий код:

           diff: /**SCHEMA_DIFF*/[

                {

                    "operation": "merge",

                    "name": "DataGrid",

                    "values": {

                        useListedLookupImages: true,

                    }

                }

            ]/**SCHEMA_DIFF*/

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

Коллеги, добрый день! Подскажите, есть ли возможность выгружать в Ecxel (через кнопку Экспорт в Excel) картинки из реестра раздела?

Добрый день!

В настоящее время изображения нельзя экспортировать в Excel.

Мы передали пожелание команде разработки для анализа возможности внедрения функционала в будущих версиях. 

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