Код добавляется на ту страницу редактирования, где выведены детали. Например, AccountPageV2

ВАЖНО! Если мы пишем свои фильтры, то первым делом необходимо прописать основной фильтр для связи детали. Аналог того, что мы выбираем в мастере при выводе детали на страницу.

ПОСЛЕДОВАТЕЛЬНОСТЬ ДЕЙСТВИЙ:

1. Объявить метод фильтрации в месте вывода детали на странице. Пример ниже

"ContractDetailV20ddfbca0": {
    "schemaName": "ContractDetailV2",
     "entitySchemaName": "Contract",
     "filter": {
        "detailColumn": "Account",
         "masterColumn": "Id"
    },   //не забываем здесь поставить запятую
    "filterMethod": "ContractFilter" // добавляем такую строчку. Название (справа) может быть любым.
},

Описать сам метод в блоке methods{}. Примеры ниже.

ПРИМЕРЫ:

2.1 Стандартный фильтр для связи детали. В данном примере на странице Контрагента наполняет деталь Договоры записями, в которых в поле "Account" указан текущий Контрагент.

ContractFilter: function() {
    var filterGroup = new this.Terrasoft.createFilterGroup(); //создаем группу фильтров
    filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND; //определяем тип фильтра AND или OR
    filterGroup.add("ByAccountFilter"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.EQUAL"Account"this.get("Id"))
    ); //Собственно, само условие
    return filterGroup;
},

"ByAccountFilter" - название элемента группы фильтров. Может быть любым

Возможные ComparisonType можно посмотреть в консоле, введя Terrasoft.ComparisonType и нажав Enter

Общий вид примерно такой: this.Terrasoft.ComparisonType.EQUAL, Памаметр1, Параметр2

2.2 Фильтр по типу. Выводит записи, у которых Тип НЕ равняется заданным (используем ID нужных нам типов)

ContractFilter: function() {
    var filterGroup = new this.Terrasoft.createFilterGroup();
    filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;
    filterGroup.add("ByAccountFilter"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.EQUAL"Account"this.get("Id"))
    );
    filterGroup.add("ByTypeFilter1"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.NOT_EQUAL"Type""009c6fa7-2e35-4a94-afd5-03ad8c3eff38")
    );
    filterGroup.add("ByTypeFilter2"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.NOT_EQUAL"Type""42b49a15-1d6c-4fa3-b24a-45711ba90cb3")
    );
    return filterGroup;
},

Также, если нужно фильтровать запись по значению колонки внутри справочника нашего обьекта(например фильтровать договора, по колонке категории продукта в договоре), можно использовать такой синтаксис в кавычках: вместо "Type" пишем "Product.Category".

2.3 Фильтр по незаполненному полю. Выводит записи, у которых не заполнено заданное поле

ContractFilter: function() {
    var filterGroup = new this.Terrasoft.createFilterGroup();
    filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;
    filterGroup.add("ByAccountFilter"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.EQUAL"UsrAccount"this.get("Id"))
    );
    filterGroup.add(this.Terrasoft.createIsNullFilter(
        this.Ext.create("Terrasoft.ColumnExpression", {columnPath: "UsrEndDate"}) // UsrEndDate - колонка детали, которая пустая
    ));
    return filterGroup;
},

2.4 Фильтр по дате. Выводит записи, у которых дата лежит в пределах от "сегодня" до "сегодня + 60 дней" (значения в миллисекундах)

GraphicFilter: function() {
    var now = new Date();
    var filterGroup = new this.Terrasoft.createFilterGroup();
    filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;
    filterGroup.add("ByAccountFilter"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.EQUAL"UsrAccount"this.get("Id"))
    );
    filterGroup.add("ByDateFilter1"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.GREATER_OR_EQUAL"UsrDATE"this.Terrasoft.startOfDay(now))
    );
    filterGroup.add("ByDateFilter2"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.LESS_OR_EQUAL"UsrDATE"this.Terrasoft.endOfDay(new Date(new Date().getTime() + 5184000000)))
    );
    return filterGroup;
},

2.5 Пример вложенности групп фильтров. Выводит связанные записи, у которых Стадия или 1я, или 2я.

Создаем две группы фильтров с операторами AND и OR. Перечисляем все элементы групп в произвольном порядке. В конце вкладываем группу OR в группу AND

OppFilter: function() {
    var filterGroupAnd = new this.Terrasoft.createFilterGroup();
    filterGroupAnd.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;
    var filterGroupOr = new this.Terrasoft.createFilterGroup();
    filterGroupOr.logicalOperation = this.Terrasoft.LogicalOperatorType.OR;
    filterGroupAnd.add("ByAccountFilter"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.EQUAL"Account"this.get("Id"))
    );
    filterGroupOr.add("ByStageFilter1"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.EQUAL"Stage""c2067b11-0ee0-df11-971b-001d60e938c6")
    );
    filterGroupOr.add("ByStageFilter2"this.Terrasoft.createColumnFilterWithParameter(
        this.Terrasoft.ComparisonType.EQUAL"Stage""325f0619-0ee0-df11-971b-001d60e938c6")
    );
    filterGroupAnd.addItem(filterGroupOr);
    return filterGroupAnd;
},

 

Нравится

Поделиться

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

Можете добавить пример, если колонкой детали и объекта является контрагент, а так же необходима дополнительная фильтрация по логическому полю "Оплата поступила". 

Evgenyi пишет:

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

ContractFilter: function() {

    var filterGroup = new this.Terrasoft.createFilterGroup();

    filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;

    filterGroup.add("ByAccountFilter", this.Terrasoft.createColumnFilterWithParameter(

        this.Terrasoft.ComparisonType.EQUAL, "Account", this.get("Account").value)

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

Вопрос

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

Ответ

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

Нравится

Поделиться

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

Вопрос

Как сделать обязательным поле "Решение" карточки обращение?

Ответ

Проблема состоит в том, что HTML-контролл типа RICHTEXT, которым является поле "Решение" не поддерживает  функциональность бизнесс-правил. 

Однако, можно использовать обходное решение. Переопределить метод save() и в нем проверять заполнено ли указанное поле, например вот так:

save: function () {
    if (this.get("Solution")) {
        this.callParent(arguments);
    } else {
        this.showInformationDialog("Необходимо заполнить поле решение");
    }
}

 

Нравится

Поделиться

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

Вопрос

Как на страницу "Контакты" можно добавить элемент-меню с флажком, такой, как на странице "Продажи", по которому можно создавать активности выбранного типа в привязке к разделу "Контакты" ?

Ответ

Для того, чтобы добавить кнопку "Связанная активность" необходимо в замещенной страницы редактировании (например,"ContactPageV2") и вставить метод:

​​​​​​​/**
 * Получает признак отображения меню добавления.
 * @overridden
 * @return {Boolean}
*/
    getAddButtonMenuVisible: function() {
        return true;
    },

Примерно должно выглядить как изображено на рисунке 1.

Изображение удалено.

Рис .1

Затем очистите кэш. В результате кнопк отобразиться (Рис. 2).

Изображение удалено. 

Рис. 2

Хотелось бы отметить, что Вы можете добавлять активности через деталь "Активности" (вкладка "История") (Рис. 3).

 Изображение удалено.

Рис. 3

Нравится

Поделиться

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

Симптомы

Uncaught TypeError: Cannot read property 'PrimaryColumnName'

Причина

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

Решение

Необходимо внести правки в раздел "Продукты", а именно решается пересохранением настроек реестра и карточки

Необходимые условия и возможные ограничения

Права администратора

Нравится

Поделиться

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

Симптомы

Настраиваю мобильное приложение, все объекты работают,кроме Активностей, при попытке зайти в Активность выходит сообщение:Uncaught TypeError:Cannot read property “modelName”

of undefined. Пробовала все колонки удалить, заново добавить, думала проблема в колонке Тип, не помогло ее удаление (после изменения настроек, заново раздавала права пользователям, чистила кэш и заново проводила синхронизацию с базой).

Изображение удалено.

Решение

В карточке активности была убрана часть полей, а главное – убрана деталь «Участники активности». Почему «главное». На эту деталь есть завязки при работе самого раздела. В частности, по умолчанию, когда при синхронизации забираются активности из bpm’online, то забираются только те активности, в детали «Участники активности» которых есть текущий пользователь.

Как раз из-за того, что была удалена группа колонок «Связи» и деталь «Участники», возникала ошибка, поскольку мы на них завязались. 

Убрав эту деталь, возможно, не будут «правильно» забираться активности.

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

Создать кастомную схему (Исходный код) (например, "MobileUtilitiesCustom")

Ext.define("Terrasoft.sdk.RecordPageMetadataApplier.Override", {
 
                override: "Terrasoft.sdk.RecordPageMetadataApplier",
 
 
 
                addEmbeddedDetail: function(modelName, operation) {
 
                               this.embeddedDetails[operation.name] = operation.values;
 
                               var values = operation.values;
 
                               var filter = values.filter;
 
                               var detailName = operation.name;
 
                               Terrasoft.sdk.RecordPage.addEmbeddedDetail(modelName, {
 
                                               name: detailName,
 
                                               title: values.caption,
 
                                               position: values.position,
 
                                               modelName: values.entitySchemaName,
 
                                               primaryKey: filter.masterColumn,
 
                                               foreignKey: filter.detailColumn,
 
                                               hidden: values.hidden
 
                               });
 
                },
 
 
 
                applyMetadata: function() {
 
                               this.callParent(arguments);
 
                               for (var itemName in this.removedMetadataItems) {
 
                                               if (!Terrasoft.util.isGuid(itemName) && Terrasoft.util.String.contains(itemName, "EmbeddedDetail")) {
 
                                                               this.addEmbeddedDetail(this.modelName, {
 
                                                                              name: itemName,
 
                                                                              values: {
 
                                                                                              entitySchemaName: itemName.substring(0, itemName.indexOf("Detail")),
 
                                                                                              filter: {
 
                                                                                                              masterColumn: "Id",
 
                                                                                                              detailColumn: "Id"
 
                                                                                              },
 
                                                                                              hidden: true
 
                                                                              }
 
                                                               });
 
                                               }
 
                               }
 
                }
 
});
 
 
 
Terrasoft.sdk.RecordPage.configureColumn = function(model, columnSetName, columnName, columnConfig) {
 
                var modelConfig = Terrasoft.ApplicationConfig.getModelConfig(model);
 
                var columnSetConfig = modelConfig.columnSets.get(columnSetName);
 
                if (!columnSetConfig) {
 
                               return;
 
                }
 
                var columnSetColumns = Terrasoft.sdk.RecordPage.getColumns(model, columnSetName);
 
                if (!columnSetColumns) {
 
                               return;
 
                }
 
                var columnSetColumn = columnSetColumns.get(columnName);
 
                var columnOriginalConfig;
 
                if (columnSetColumn) {
 
                               columnOriginalConfig = columnSetColumn.columnOriginalConfig;
 
                } else {
 
                               columnOriginalConfig = {};
 
                               columnConfig.hidden = true;
 
                               var modelInstance = Ext.ClassManager.get(columnSetConfig.modelName || model);
 
                               var realModelColumnConfig = modelInstance.ColumnConfigs.get(columnName);
 
                               columnConfig.columnType = realModelColumnConfig.columnType;
 
                               columnConfig.name = columnName;
 
                }
 
                Ext.merge(columnOriginalConfig, columnConfig);
 
                var contextModel = columnSetConfig.modelName || model;
 
                if (columnConfig.hidden) {
 
                               var columns = this.getColumnSetColumns(model, columnSetName);
 
                               columns.remove(columnName);
 
                } else {
 
                               var resolvedColumnConfig = this.resolveColumnConfig(contextModel, columnOriginalConfig,
 
                                                               !!columnSetConfig.modelName);
 
                               columnSetConfig.columns.configure(columnName, resolvedColumnConfig);
 
                }
 
};
 
 
 
Terrasoft.sdk.RecordPage.addColumn = function(model, columnConfig, columnSetName) {
 
                var modelConfig = Terrasoft.ApplicationConfig.getModelConfig(model);
 
                if (!columnSetName) {
 
                               columnSetName = modelConfig.primaryColumnSetName;
 
                }
 
                var columnSetConfig = modelConfig.columnSets.get(columnSetName);
 
                if (!columnSetConfig) {
 
                               return;
 
                }
 
                var contextModel = columnSetConfig.modelName || model;
 
                var isEmbeddedDetail = !!columnSetConfig.modelName;
 
                if (!columnConfig.hidden) {
 
                               columnSetConfig.columns.add(this.resolveColumnConfig(contextModel, columnConfig, isEmbeddedDetail));
 
                }
 
                this.addColumnToQueryConfig(model, columnConfig.name, columnSetName, isEmbeddedDetail);
 
                if (columnConfig.displayColumn) {
 
                               this.addColumnToQueryConfig(model, columnConfig.displayColumn, columnSetName, isEmbeddedDetail);
 
                }
 
};

В манифесте мобильного приложения (например, "UsrMobileApplicationManifestCustomMobile") указать кастомную схему

{
 
"CustomSchemas": [
"MobileUtilitiesCustom"
]
}

 

Нравится

Поделиться

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

Вопрос

Не работает прием сообщения. Версия 7.7.

methods: {
    editRecord: function(editPageUId) {
        this.callParent(arguments);
        var text = "Schema6Detail";
        this.sandbox.publish("PublishDetailName", text);
    }
},
messages: {
    "PublishDetailName": {
        "mode": this.Terrasoft.MessageMode.BROADCAST,
        "direction": this.Terrasoft.MessageDirectionType.PUBLISH
    }
}
methods: {
    subscribeSandboxEvents: function() {
        this.callParent(arguments);
        this.sandbox.subscribe("PublishDetailName", this.getDetailNameFromWhoOpen, this); 
    },
    getDetailNameFromWhoOpen: function(detailName) {
        var a = 5;
    }
},
messages: {
    "PublishDetailName": {
        "mode": this.Terrasoft.MessageMode.BROADCAST,
        "direction": this.Terrasoft.MessageDirectionType.SUBSCRIBE
    }
}

Метод getDetailNameFromWhoOpen() не вызывается.

Ответ

Проблема в том, что Вы делаете паблиш сообщения, в момент до(!) того как страница редактирования детали будет открыта, после чего открывается страница редактирования, и там вы делаете подписку. Но момент уже упущен. Вы подписываетесь на сообщение тогда, когда его уже никто не опубликует.

Вам необходимо делать publish на странице редактирования, принимая результат в переменную.



В то время как в схеме детали, делать subscribe, обработчиком которого делать функцию возвращающую значение.

Пример.

Схема детали:

define("Schema6Detail", [], function() {
    return {
        entitySchemaName: "Recomendation",
        details: /**SCHEMA_DETAILS*/{
        }/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[
        ]/**SCHEMA_DIFF*/,
        methods: {
            addRecord: function(editPageUId) {
                this.callParent(arguments);
            },
            init: function() {
                this.callParent(arguments);
                console.log("id in detail: " + this.sandbox.id);
                this.sandbox.subscribe("PublishDetailName",
                    this.getDetailNameFromWhoOpen, this,
                    [this.sandbox.id]
                );
            },
            getDetailNameFromWhoOpen: function() {
                return {
                    param: "test!"
                };
            }
        },
        messages: {
            "PublishDetailName": {
                mode: Terrasoft.MessageMode.PTP,
                direction: Terrasoft.MessageDirectionType.SUBSCRIBE
            }
        }
    };
});

Схема страницы:

define("Recomendation1Page", [], function() {
    return {
        entitySchemaName: "Recomendation",
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[
        ]/**SCHEMA_DIFF*/,
        methods: {
            onEntityInitialized: function() {
                this.callParent(arguments);
                var res = this.sandbox.publish("PublishDetailName",
                    null,
                    [this.getDetailId()]
                );
                alert(res.param);
            },
            getDetailId: function() {
                var index = this.sandbox.id.indexOf("Recomendation1Page");
                var newId = this.sandbox.id.substring(0, index);
                console.log("id in page: " + newId);
                return newId;
            },
        },
        rules: {},
        messages: {
            "PublishDetailName": {
                mode: Terrasoft.MessageMode.PTP,
                direction: Terrasoft.MessageDirectionType.PUBLISH
            }
        },
        attributes: {
        }
    };
});

 

Нравится

Поделиться

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

Задача

Как разблокировать для редактирования поля для определенных групп пользователей? 

Решение

Выполните следующую последовательность действий:

1. В разделе "Opportunity" выберите ‘Open section wizard’:

 Изображение удалено.

2. Выберите ‘Page’:

 Изображение удалено.

3. Затем выберите поле, которое должно быть редактируемым и нажмите "Edit":

 Изображение удалено.

4. Затем снимите отметку с чекбокса "Read-only":

 Изображение удалено.

После этого поле станет редактируемым.

Теперь необходимо сделать его редактируемым только для определенных групп. 

1. Для этого идите в "System designer":

 Изображение удалено.

2. Выберите "Object permissions":

 Изображение удалено.

3. Выберите пункт "Sections":

 Изображение удалено.

4. Найдите строку "Opportunity" и если "Managed by columns" отмечено "X", кликните на него. В итоге должно получится следующее:

 Изображение удалено.

5. Затем выберите строку "Opportunity" и внизу страницы найдите "Columns permissions". Вам следует найти поле, которое должно быть редактирумым для определенных групп (в этом примере используется поле "Type"):

 Изображение удалено.

6. Справа вы увидите роли и уровнидоступа для ролей:

 Изображение удалено.

7. Нажмите "New" чтобы добавить права для пользователя или роли, а затем кликните на иконку в колонке "Access level" . Иконка с глазом позволяет только чтение данных, с ручкой - разрешает редактирование,  а знак X не допускает никакой доступ к колонке. 

Вам следует установить его как на скрине:

 Изображение удалено.

Необходимые условия

Права системного администратора.

Нравится

Поделиться

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

Проблема

При сохранении записи в разделе "Контрагенты" ошибка - Invalid object name 'dbo.SysAccountLog'.

Причина

Данная ошибка была связана с тем, что у замещенного объекта «Account» был проставлен признак «Ввести журнал изменений», т.е. некорректно был настроен журнал изменений по данному объекту.

Решение

Открыть замещенный объект, снять признак «Ввести журнал изменений» и опубликовать объект.

Если необходимо, чтобы был объект «Account» логировался, то настройте соответствующий объект в разделе «Журнал изменений».

Более подробную информацию Вы можете прочитать в руководстве пользователя https://academy.terrasoft.ru/documents/administration/7-12/razdel-zhurnal-izmeneniy?document=team.

Необходимые условия и возможные ограничения

Права администратора

Нравится

Поделиться

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

Проблема

Есть поле

{
   "operation": "insert",
   "name": "UsrJob",
   "values": {
      "layout": {"column": 0, "row": 0, "colSpan": 12},
      "bindTo": "UsrJob"
   },
   "parentName": "Header",
   "propertyName": "items"
}



В атрибутах идет подписка на событие

"Job": {
   dependencies: [{ 
      columns: ["UsrJob"],
      methodName: "jobChanged"
   }]
}



В метод jobChanged() при изменении поля UsrJob не заходит. Схема карточки наследуется от BasePageV2.

Причина

Пользователь в созданной схеме переопределил метод родительской схемы onEntityInitialized() следующим образом:

onEntityInitialized: function() {
   this.set("IsChanged", true);
   if (this.isAddMode()) {
      this.hideBodyMask();
      return;
   }
   var forecastId = (this.isCopyMode())
   ? this.get("SourceEntityPrimaryColumnValue")
   : this.get("Id");
   if (!Ext.isEmpty(forecastId)) {
      var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
      rootSchemaName: "UsrForecastDimension",
      rowCount: 1
   });
   esq.addColumn("Id");
   esq.addColumn("UsrDimension");
   esq.filters.add("ForecastFilter", Terrasoft.createColumnFilterWithParameter(
      Terrasoft.ComparisonType.EQUAL, "UsrForecast", forecastId));
   esq.getEntityCollection(function(response) {
      if (response && response.success) {
         var collection = response.collection;
         if (collection.getCount() > 0) {
            var collectionItems = collection.getItems();
            var dimensionItem = collectionItems[0];
            var dimension = dimensionItem.get("UsrDimension");
            this.set("UsrDimension", dimension);
         }
      }
      this.hideBodyMask();
      }, this);
   }
},

При этом не был вызван метод onEntityInitialized() базовой схемы.

Решение

Добавить в замещающий метод вызов замещенного метода строкой: 

this.callParent(arguments);

 

Нравится

Поделиться

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