Публикация

Вопрос

Суть ошибки: не компилируется один из Package (пакет оракла, а не нашего приложения) с ошибкой, содержащей текст:

ORA-00932: inconsistent datatypes

или

После входа ошибка Authorization Failed

Ответ

Cсылка на багу оракла и патч, который нужно скачать и установить на сервер при возникновении ошибки. Воспроизводится точно на версии 11.2.0.4 (и, судя по описанию патча, еще и 11.2.0.3).

https://support.oracle.com/knowledge/Oracle%20Database%20Products/2003626_1.html

Дополнительно:

There's a known bug related to this see - MOS note 2003626.1. 

It's fixed in patch 18139621. 

https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9519164900346280654

https://stackoverflow.com/questions/43589677/ora-00932-expected-number-got/43591908

Нравится

Поделиться

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

Вопрос

После выбора необходимых значений они не отображаются в лукапе, хотя я их могу получить через this.get('ResponsibleLookUp').

Подскажите тогда как их отобразить в лукапе, чтобы пользователь видел что он выбрал.

Ответ

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

define("CasePage", ["CasePageResources", "terrasoft", "LookupUtilities"],
    function(resources, Terrasoft, LookupUtilities) {
        return {
            entitySchemaName: "Case",
            details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
            attributes: {
                "UsrVirtualCity": {
                    dataValueType: Terrasoft.DataValueType.TEXT,
                    type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
                },
                "UsrVirtualCityArray": {
                    dataValueType: Terrasoft.DataValueType.CUSTOM_OBJECT,
                    type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
                }
            },
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "insert",
                    "name": "Number",
                    "values": {
                        "layout": { "colSpan": 24, "rowSpan": 1, "column": 0, "row": 4 },
                        "bindTo": "UsrVirtualCity",
                        "caption": "virtual city",
                        "controlConfig": {
                            "className": "Terrasoft.TextEdit",
                            "rightIconClasses": ["custom-right-item", "lookup-edit-right-icon"],
                            "rightIconClick": {
                                "bindTo": "testClick"
                            }
                        }
                    },
                    "parentName": "SolutionTab_gridLayout",
                    "propertyName": "items",
                    "index": 6
                }
            ]/**SCHEMA_DIFF*/,
            methods: {
                onEntityInitialized: function() {
                    this.callParent(arguments);
                    // just for debug:
                    document.scope = this;
                },
                testClick: function() {
                    var config = {
                        entitySchemaName: "City",
                        multiSelect: true
                    };
                    LookupUtilities.Open(this.sandbox, config, this.onTestClickComplete, this, null, false, false);
                },
                onTestClickComplete: function(cities) {
                    if (cities.selectedRows.getCount() > 0) {
                        var citiesItems = cities.selectedRows.getItems();
                        var displayValue = "";
                        for (var i = 0; i < citiesItems.length; i++) {
                            displayValue = displayValue + citiesItems[i].displayValue + "; ";
                        }
                        displayValue = displayValue.substring(0, displayValue.length - 2);
                        this.set("UsrVirtualCity", displayValue);
                        var citiesKeys = cities.selectedRows.getKeys();
                        this.set("UsrVirtualCityArray", citiesKeys);
                    }
                }
            },
            rules: {}
        };
});

 

Нравится

Поделиться

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

Вопрос

Как создать вкладку "Лента" в разделе

Ответ

Пример реализации вкладки «Лента» Вы можете посмотреть открыв схему «BaseModulePageV2» (пакет «ESN»).

 

Примерный алгоритм реализации следующий:

- Перенести в пользовательскую схему карточки, например, в «CallPageV2» diff (Рис. 1);

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

Рис. 1

- добавить необходимые локализированные строки (Рис. 2);

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

Рис. 2

- добавить в «CallPageV2» весь необходимый функционал, который отвечает за вкладку «Лента». Как пример можно перенести следующие методы: (Рис. 3-4):

  1. loadESNFeed;

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

Рис. 3

  1. getSocialFeedSandboxId;
  2. initTabs и другие.

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

Рис. 4

- и добавьте необходимые messages (Рис. 5).

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

Рис. 5

Нравится

Поделиться

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

Вопрос

Каким образом устанавливается поле "Происхождение" при создании обращения на портале?

Ответ

Установка происхождения (поле Origin) происходит в PortalCasePage в следующем методе:

setPortalColumnValues: function() {
    if (this.isAddMode() || this.isCopyMode()) {
        if (this.Terrasoft.SysValue.CURRENT_USER_ACCOUNT.value !== this.Terrasoft.GUID_EMPTY) {
            this.set("Account", this.Terrasoft.SysValue.CURRENT_USER_ACCOUNT);
        }
        this.set("Contact", this.Terrasoft.SysValue.CURRENT_USER_CONTACT);
        this.Terrasoft.SysSettings.querySysSettingsItem("PortalCaseOriginDef", function(value) {
            this.set("Origin", value);
        }, this);
        this.set("Owner", null);
    }
}

Как видно из кода, значение поля определяется системной настройкой "PortalCaseOriginDef"(Происхождение обращения на портале по умолчанию")

Нравится

Поделиться

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

Вопрос

Необходимо открыть внешний доступ к bpm'online только для сервисов мобильного приложения.

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

Ответ

Интеграция осущевстляется через O'Data по порту сайта.

Сервисы используемые мобильным приложением в версии 7.8.2:

http://server/ServiceModel/AuthService.svc

http://server/0/Services/ProfileService.asmx

http://server/0/Mobile/Services/MobileDataService.ashx

http://server/0/Mobile/Services/MobileCodeService.ashx

http://server/0/ServiceModel/EntityDataService.svc

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

Нравится

Поделиться

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

Вопрос

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

Ответ

Пример.

Необходимо настроить следующие параметры:

LEADS: Only show leads with the LEAD STAGES: Registration and Qualification.

OPPORTUNITIES: Only show opportunities with the OPPS STAGES: Presentation, Proposal, Negotiation and Pending.

Используем следующий код (для Лида):

Terrasoft.sdk.Module.addFilter("Lead", Ext.create("Terrasoft.Filter", {
    type: Terrasoft.FilterTypes.Group,
    logicalOperation: Terrasoft.FilterLogicalOperations.Or,
    subfilters: [
        {
            property: "QualifyStatus",
            value: "d790a45d-03ff-4ddb-9dea-8087722c582c"
        },
        {
            property: "QualifyStatus",
            value: "14cfc644-e3ed-497e-8279-ed4319bb8093"
        }
    ]
}));

 - Для начала нам необходимо создать новые модули с кодом фильтрации отдельно для Лида, отдельно для Продажи:

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

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

 - Затем в конфигурациях выбираем рабочее место (если у клиента их несколько), к которому будем применять фильтр, в нашем случае MobileApplicationManifestOn_the_Road

Там нам необходимо добавить нами созданные модули с фильтрами в тех разделах, к которым относятся фильтры, в данном случае в Lead и Opportunity в PageExtentions

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

  - Сохраняем.

Нравится

Поделиться

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

Спасибо! Ваша статья очень помогла. Пробовал настроить фильтрацию в манифесте через SyncFilter и QueryFilter, но ничего не получилось (точнее фильтрация работала только в офлайн режиме). А когда перенес свои фильтры в модуль, то все заработало.

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

Вопрос

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

Ошибка:

"requestId":20,"status":200,"statusText":"OK","responseText":"{\"Code\":1,\"Message\":\"Either invalid login or password specified, or your user account is inactive.Verify that you have entered correct data or contact support service.\"

Ответ

Для bpm'online 7.5 мобильное приложение доступно только для Sales (Team, Commerce, Enterprise, Omnichannel).

Нравится

Поделиться

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

Задача

Вставить свой макрос в WORD для преобразования выводимых данных

Решение

1) Создать в конфигурации новую схему [Исходный код]

2) Содержимое этой схемы берем из схемы DateTimeExpressionConveter

3) С 22-ой строки меняем код на тот, который необходим:

ExpressionConverterAttribute("<MacrosName>")]
public class <MacrosName>ExpressionConveter : IExpressionConverter {
    public string Evaluate(object value, string arguments = "") {
        string dateFormat = "dd.MM.yyyy";
        if (!arguments.IsNullOrEmpty()) {
            dateFormat = arguments;
        }
        DateTime date;
        if (DateTime.TryParse((string)value, out date)) {
            return date.ToString(dateFormat);
        }
        return string.Empty;
    }
}

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

https://academy.terrasoft.ru/documents/technic-sdk/7-6-0/kak-sozdat-svoy-makros-dlya-pechatnoy-formy-ms-word

Нравится

Поделиться

0 комментариев
Показать все комментарии
define('ContactPage', ['terrasoft', 'Contact', 'ContactPageStructure', 'ContactPageResources'],
    function(Terrasoft, Contact, structure, resources) {
    structure.userCode = function() {
        var account;
        var accountPhone;
        var groupIndex = 0;
        var itemIndex = 0;
        var group = this.schema.leftPanel[groupIndex];
        var item = group.items[itemIndex];
        //перебором ищем нужный контрол по имени
        while (item.name !== 'Account') {
            if (itemIndex === group.items.length - 1) {
                groupIndex++;
                itemIndex = -1;
                group = this.schema.leftPanel[groupIndex];
            }
            itemIndex++;
            item = this.schema.leftPanel[groupIndex].items[itemIndex];
        }
        //пушим новую виртуальную колонку номера контрагента
        this.schema.leftPanel[groupIndex].items.push({
            type: Terrasoft.ViewModelSchemaItem.ATTRIBUTE,
            caption: "Account Phone",
            columnType: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
            name: 'AccountPhone',
            dataValueType: Terrasoft.DataValueType.TEXT,
            visible: true,
            customConfig: {
                enabled: false
            },
            dependencies: ['Account'],
            methodName: 'onAccountChange'
        });
        //описываем выборку из базы значения номера телефона по Id текущего контрагента
        //и заполняем добавленную виртуальную колонку
        var baseOnAccountChange = this.methods.onAccountChange;
        this.methods.onAccountChange = function() {
            if (Ext.isFunction(baseOnAccountChange)) {
                baseOnAccountChange.call(this);
            }
            account = this.get('Account');
            var esq = Ext.create('Terrasoft.EntitySchemaQuery', {
                rootSchemaName: 'Account'
            });
            esq.rowCount = 1;
            esq.addColumn('Id');
            esq.addColumn('Name');
            esq.addColumn('Phone');
            esq.getEntity(account.value, function(result) {
                var entity = result.entity;
                accountPhone = entity.get('Phone');
                this.set('AccountPhone', accountPhone);
            }, this);
        };
        //вызываем функцию заполнения колонки при первичной загрузке страницы
        var childOnAccountChange = this.methods.onAccountChange;
        var baseInit = this.methods.init;
        this.methods.init = function() {
            if (Ext.isFunction(baseInit)) {
                baseInit.call(this);
            }
            childOnAccountChange.call(this);
        };
    };
    return structure;
});

 

Нравится

Поделиться

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

Вопрос

Как отобразить данные на детали в виде иерархической (древовидной) структуры?

Ответ

Для реализации отображения детали в виде иерархического реестра необходимо выполнить следующие шаги:

1) в объекте детали должно быть поле, содержащее идентификатор родительской записи (например, Parent), ссылающееся на этот же объект. Это поле должно быть указано в свойстве "Родитель в иерархии" объекта детали;

2) в блоке diff схемы детали для элемента DataGrid необходимо добавить значения "hierarchical": true и "hierarchicalColumnName": "<Название родительской колонки>" (второе свойство необходимо указывать только если название родительской колонки отличается от Parent);

3) добавить свою кнопку (или модифицировать существующую) для возможности добавления новых элементов детали в корень иерархии либо как подчинённые к выбранной записи;

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

Для более подробной информации можно посмотреть прикрепленный файл.

Нравится

Поделиться

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

На самом деле

3) Замещаем метод addGridDataColumns добавив в него все нужные колонки (обязательно колонку родитель, ну и остальные по необходимости):

 

addGridDataColumns: function (esq) {

                this.callParent(arguments);

                if (!esq.columns.contains("UsrParent")) {

                    esq.addColumn("UsrParent");

                }

            }

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

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

А как запретить выбрать узлы для ИЕРАРХИЧЕСКОГО справочника ?

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