Симптомы

Мобильное приложение не синхронизируется в онлайн режиме (в офлайн режиме – все ОК).

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

Причина

По результатам анализа, в некоторых конфигурациях IIS и .NET Framework ASP.NET обрабатывает URL (адрес сайта) таким образом, что экранируются спецсимволы. При интеграции средствами OData (мобильное приложение bpm'online) используются URL содержащие $.

Эту особенность можно выключить специальной опцией в файле «web.config».

Решение

Для этого Вам необходимо (ниже пункты, которые должен выполнить пользователь с правами системного администратора):

  1. Перейти к папке с исходными файлами приложения (например, C:\bpm\7.8.0.1681_SalesEnterprise_Softkey_MSSQL_ENU). Путь к папке произвольный. Данной информацией должен владеть системный администратор приложения;
  2. Далее в корневой папке открыть блокнотом  файл web.config;
  3. Найти секцию   (например, быстрее можно найти через поиск в блокноте (Ctrl + F);
  4. В эту секцию добавить строку:





     
  5. Сохранить изменения (просьба перепроверить, что изменения сохранились);



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

     
  6. Далее открыть второй web.config, который находится в папке с приложением «Terrasoft.WebApp» (C:\bpm\7.8.0.1681_SalesEnterprise_Softkey_MSSQL_ENU\Terrasoft.WebApp) и повторить пункты 2-5.



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



     
  7. Далее перезапустить приложение на IIS и почистить Redis.

Просьба перед внесением изменений сделать копии файлов web.config.

Хотелось бы отметить, что данная ситуация возникает только при использовании Online режима - https://academy.terrasoft.ru/documents/mobile/7-8-0/specifika-raboty-v-online-i-offline-rezhimah

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

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

Нравится

Поделиться

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

Метод, реализующий выделение всех загруженных записей.

this.methods.selectAll = function() {
    var grdData = this.get('gridData');
    if (!this.get('multiSelect')){
        this.switchGridMode();
    }
    this.set('selectedRows', grdData.collection.keys);
}

 

Нравится

Поделиться

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

Вопрос

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

Ответ

Реализовать данный кейс не представляется возможным, для системы крайне важным является условие 1 контакт=1 запись в SysAdminUnit.

Нравится

Поделиться

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

Вопрос

На детали Email отображаются записи других типов активностей.

Ответ

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

define("EmailDetailV2", ["terrasoft", "ProcessModuleUtilities", "ConfigurationConstants"],
    function(Terrasoft, ProcessModuleUtilities, ConfigurationConstants) {
        return {
            /**
            * Имя схемы объекта
            * @type {String}
            */
            entitySchemaName: "Activity",
            messages: {},
            attributes: {},
            methods: {
                getFilters: function() {
                    var parentfilters = this.callParent(arguments);
                    parentfilters.add(
                        "EmailFilter",
                        this.Terrasoft.createColumnFilterWithParameter(
                            this.Terrasoft.ComparisonType.EQUAL,
                            "Type",
                            ConfigurationConstants.Activity.Type.Email
                        )
                    );
                    return parentfilters;
                }
            },
            diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
        };
});

 

Нравится

Поделиться

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

Вопрос

Как скрыть поле с детали "Средства связи"

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

Ответ

Данный вопрос необходимо решать на уровне конфигурации.

Рассмотрим реализацию на примере.

Кейс:

необходимо скрыть поле «E-mail» из секции «Запрет на использование» в разделе «Контакты».

Решение:

  1. Необходимо заместить схему (Управление конфигурацией – Конфигурация – кнопка «Добавить» - пункт «Замещающий клиентский модуль»).
  2. В открывшимся окне в поле «Родительский объект» указать «Средства связи контакта (устаревшая версия)» (Рис. 1).

ВАЖНО. Необходимо использовать устаревшую версию схемы «Средства связи».

    3. В замещающую схему вставить следующий код:

define("ContactCommunicationDetail", ["ContactCommunicationDetailResources", "terrasoft"],
    function(resources, Terrasoft) {
        return {
            entitySchemaName: "ContactCommunication",
            methods: {
                /**
                * Возвращает запреты на использование.
                * @protected
                * @return {Object} Объект, который содержит свойства запретов на использование.
                */
                getRestrictions: function() {
                    return {
                        "DoNotUseEmail": { /*Не использовать E-mail*/
                            "RestrictCaption": this.get("Resources.Strings.DoNotUseEmail"),
                            "Caption": this.get("Resources.Strings.DoNotUseEmailCaption")
                        },
                        "DoNotUseCall": { /*Не использовать телефон*/
                            "RestrictCaption": this.get("Resources.Strings.DoNotUseCall"),
                            "Caption": this.get("Resources.Strings.DoNotUseCallCaption")
                        },
                        "DoNotUseSms": { /*Не использовать SMS*/
                            "RestrictCaption": this.get("Resources.Strings.DoNotUseSms"),
                            "Caption": this.get("Resources.Strings.DoNotUseSmsCaption")
                        },
                        "DoNotUseFax": { /*Не использовать факс*/
                            "RestrictCaption": this.get("Resources.Strings.DoNotUseFax"),
                            "Caption": this.get("Resources.Strings.DoNotUseFaxCaption")
                        },
                        "DoNotUseMail": { /*Не использовать почту*/
                            "RestrictCaption": this.get("Resources.Strings.DoNotUseMail"),
                            "Caption": this.get("Resources.Strings.DoNotUseMailCaption")
                        }
                    };
                }
            },
            diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/
        };
    });

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

Рис. 1

4. Затем выделяем с помощью компьютерной мышки часть кода, которая изображен на рисунке 2 (начиная от названия "DoNotUseEmail" и заканчивая }, ).

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

Рис. 2

5. В итоге должно выглядеть как рисунке 3. Затем мы сохраняем схему.

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

Рис. 3

6. Затем очищаем кэш браузера и проверяем результат.

 7. В результате поле "E-mail" не отобразиться (Рис. 4).

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

Рис. 4

Примечание. Скрытие других полей или реализация в разделе «Контрагенты» происходит аналогичным путем. 

Нравится

Поделиться

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

Вопрос

Каким образом можно хранить URL (в каком поле) и как возможно (если это возможно в принципе) сделать так, чтобы на форме это поле стало "кликабельным"?

Ответ

URL можно хранить в текстовом поле.

Основные нюансы реализации описаны в ответе на комьюнити: http://www.community.terrasoft.ru/forum/topic/9686#comment-54881

Для поля необходимо добавить следующие свойства в свойство values элемента массива diff:

"showValueAsLink": true,
"href": {
        "bindTo": "UsrFieldName",
        "bindConfig": {"converter": "getUsrFieldNameLink"}
},
"controlConfig": {
        "className": "Terrasoft.TextEdit",
        "linkclick": { bindTo: "onUsrFieldNameLinkClick"}
}

Где UsrFieldName - название поля, которое мы хотим отображать как гиперссылку.

Также необходимо реализовать два метода, с которыми мы связали наше поле:

getUsrFieldNameLink: function(value) {
    return {
        "url": value,
        "caption": value
    };
},
onUsrFieldNameLinkClick: function(url) {
    if (url != null) {
        window.open(url, "_blank""height=" + this.get("WindowHeight") + ",width=" + this.get("WindowWidth"));
        return false;
    }
}

Необходимо также следить за тем, чтобы значение данного поля начиналось с http или https, иначе система будет добавлять к содержимому путь к приложению. Можно также анализировать значение входящего параметра value в первом методе и в случае необходимости добавлять эту приставку.

Полный пример элемента diff:

{
    "operation": "insert",
    "name": "UsrURLpage22872546-f334-4b46-a445-112b532455c4",
    "values": {
        "layout": {
            "colSpan": 12,
            "rowSpan": 1,
            "column": 0,
            "row": 3,
            "layoutName": "Header"
        },
        "labelConfig": {},
        "enabled": true,
        "bindTo": "UsrURLpage",
        "showValueAsLink": true,
        "href": {
            "bindTo": "UsrURLpage",
            "bindConfig": {"converter": "getUsrURLpageLink"}
        },
        "controlConfig": {
            "className": "Terrasoft.TextEdit",
            "linkclick": { bindTo: "onUsrURLpageLinkClick"}
        }
    },
    "parentName": "Header",
    "propertyName": "items",
    "index": 6
}

 

Нравится

Поделиться

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

Вопрос

Мобильное приложение.

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

Список заказов не отображается в нужной последовательности. Как следует настроить приложение, чтобы шла последовательность по дате регистрации? И вначале (сверху) показывался последний заказ?

 В чём была причина хаотичного расположения заказов?

Ответ

Для сортировки по определенной колонке необходимо в манифеесте прописать дополнительно логику.

Пример:

Terrasoft.sdk.GridPage.setOrderByColumns("Order", {
    column: "CreatedOn",
    orderType: Terrasoft.OrderTypes.DESC
});

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

Ниже пример:

 

- добавляет объект «UsrTestOrderMobile» с нужными колонками 

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

- регистрируем деталь в мастере деталей;

- добавляем деталь в мастере мобильного приложения

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

- далее нам необходимо настроить сортировку. Создаем новую клиентскую схему, например, «UsrMobileUsrTestOrderMobileModuleConfig» с необходимым кодом:

 

Terrasoft.sdk.GridPage.setOrderByColumns("UsrTestOrderMobile", {
    column: "UsrName",
    orderType: Terrasoft.OrderTypes.DESC
});

- сохраняем изменения;

- подключаем в манифест в секции «Models» нужного объекта детали в «PagesExtensions»

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

- очищаем кэш и заново синхронизируется (чтобы получить актуальные настройки) и проверяем.

 

Важные моменты:

- убедиться, что в настройках импорта (ModelDataImportConfig) синхронизируете все необходимые колонки

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

- была первичная колонка (которая используется в сортировке) для отображения в объекте либо на уровне кода (ниже пример):

 

Terrasoft.sdk.GridPage.setPrimaryColumn("UsrTestOrderMobile", "UsrName");

Terrasoft.sdk.RecordPage.addColumn("UsrTestOrderMobile", {

        name: "UsrName",

        position: 1

    }, "primaryColumnSet");

 

Проверили на последней сборке 7.11.3 и все работает корректно.



Также используйте следующую документацию:

https://academy.terrasoft.ru/documents/technic-sdk/7-11/manifest-mobilnogo-prilozheniya;

https://academy.terrasoft.ru/documents/technic-sdk/7-11/kak-dobavit-polzovatelskiy-razdel-v-mobilnoe-prilozhenie;

https://academy.terrasoft.ru/documents/technic-sdk/7-11/sdk-reestra.

Нравится

Поделиться

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

Кейс

Добавил кастомное поле «Проект» в Активность, которое является обязательным.

Из за этого не могу теперь внеси Активность через мобильное приложение.  Можно ли это исправить оставив поле «Проект» обязательным?

Причина

Настройка полей в меню [Мастер мобильного приложения] для разделов Активности/Контрагенты работает некорректно. Исправлено в последних релизных версиях.

Цель

Добавить пользовательское поле в раздел Активность для мобильного приложения.

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

Доступ в систему с правами администратора.

Выполнение

1. Обновить систему до последней релизной версии, выпущенной после 01.05.2015.

2. В [Мастер мобильного приложения] настроить соответствующие колонки.

В настройке мобильного приложения важно:

1. Сохранить изменение на странице раздела.

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

2. Сохранить изменения для мобильного приложения в целом.

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

 3. Выполнить повторную синхронизацию.

Нравится

Поделиться

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

Основные причины потери производительности:

  1. IIS
  2. Процесс приложения
  3. SQL
  4. Redis
  5. Сеть

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

2. Проверить загруженность системы (ЦП и память). Процесс W3wp. Утилиты DotMemory, DotTrace и др.

3. Проверка выполнения скорости запросов в БД.

В профайлере настроить по условию время выполнения больше 2000 мс, так как большая часть запросов выполняются очень быстро можно отсеять только те, что могут тормозить наше приложение. Также можна проверить выполнение запросов напрямую в БД. Может быть проблема с индексами или не оптимизирован запрос.

4. Проверить Редис. При достаточно больших объёмах данных и неправильное работы, редис часть данных сохраняет на диск. Очевидным становится проблема медленных дисков, ибо при не нахождении в оперативной памяти начинает искать на медленном диске.

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

Нравится

Поделиться

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

Симптомы

Вопрос по обработке часовых поясов.

В карточке торговой точки есть поля "Воемя доставки от" и "Время доставки до" с типом Время. При создании точки на планшете ставим в них 17:00 и 18:00, в базу они синхронизируются как 14:00 и 15:00. Более того, после синхронизации и на планшете в этих полях оказываются значения 14:00 и 15:00.

В интерфейсе веб-версии они тоже видны как 14:00 и 15:00

Причина

Исправлено в версии 7.8 

Решение

Ниже предоставлен фикс, исправляющие проблему без переноса серверных изменений 7.8 по часовым поясам.

 

Порядок действий следующий:

 

- создать схему UsrSyncExtension (тип «Модуль») в пользовательском пакете;

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

- добавить в нее следующий код:

 

var sysAdminUnitStore = Ext.create("Ext.data.Store", {model: "SysAdminUnit"});
sysAdminUnitStore.setProxy("odata");
sysAdminUnitStore.load({
    queryConfig: Ext.create("Terrasoft.QueryConfig", {
        modelName: "SysAdminUnit",
        autoSetProxy: false,
        columns: ["TimeZoneId"]
    }),
    filters: Ext.create("Terrasoft.Filter", {
        property: "Contact",
        value: Terrasoft.CurrentUserInfo.contactId
    }),
    callback: function(records, operation, success) {
        if (success === true && records.length > 0) {
            var firstRecord = records[0];
            var timeZoneCode = firstRecord.get("TimeZoneId");
            if (!Ext.isEmpty(timeZoneCode)) {
                var timeZoneStore = Ext.create("Ext.data.Store", {model: "TimeZone"});
                timeZoneStore.setProxy("odata");
                timeZoneStore.load({
                    queryConfig: Ext.create("Terrasoft.QueryConfig", {
                    modelName: "TimeZone",
                    autoSetProxy: false,
                    columns: ["Offset"]
                }),
                filters: Ext.create("Terrasoft.Filter", {
                    property: "Code",
                    value: timeZoneCode
                }),
                callback: function(timeZoneRecords, timeZoneOperation, timeZoneSuccess) {
                    if (timeZoneSuccess === true && timeZoneRecords.length > 0) {
                        var timeZoneRecord = timeZoneRecords[0];
                        var offset = timeZoneRecord.get("Offset");
                        var offsetValue = 0;
                        if (!Ext.isEmpty(offset)) {
                            offset = offset.replace("GMT", "");
                            if (!Ext.isEmpty(offset)) {
                                var sign = (offset.substring(0, 1) === "-") ? 1 : -1;
                                var hours = parseInt(offset.substr(1, 2));
                                var minutes = parseInt(offset.substr(4, 2));
                                offsetValue = sign * (hours * 60 + minutes);
                            }
                        }
                        Terrasoft.Configuration.CurrentUserTimeZoneOffset = offsetValue;
                    }
                },
                scope: this
            });
        }
    }
},
scope: this
});
 
if (!Terrasoft.Configuration.processColumn) {
                Terrasoft.Configuration.processColumn = Terrasoft.OData.ResponseParser.processColumn;
}
 
Terrasoft.OData.ResponseParser.processColumn = function(data, queryConfig, record, columnName) {
                var model = record.self;
                var columnConfig = model.ColumnConfigs.get(columnName);
                var columnValue = data[columnName];
                if ((columnConfig.columnType === Terrasoft.ColumnTypes.date ||
                               columnConfig.columnType === Terrasoft.ColumnTypes.datetime) &&
                               !Ext.isEmpty(Terrasoft.Configuration.CurrentUserTimeZoneOffset)) {
                               if (columnValue.indexOf("/") !== -1) {
                                               var timeZoneOffset = Terrasoft.Configuration.CurrentUserTimeZoneOffset;
                                               columnValue = new Date(parseInt(columnValue.substr(6)));
                                               columnValue = new Date(columnValue.getTime() + timeZoneOffset * 60 * 1000);
                               } else {
                                               columnValue = Terrasoft.util.convertISOStringToDate(columnValue);
                               }
                               record.set(columnName, columnValue);
                } else {
                               Ext.callback(Terrasoft.Configuration.processColumn, Terrasoft.OData.ResponseParser, arguments);
                }
};

- добавить в текущий пакет манифест мобильного приложения (манифест соответствующего рабочего места) и в нем прописать схему UsrSyncExtension, а именно добавить ее в SyncExtensions и CustomSchemas:

"SyncExtensions": [
                               "UsrSyncExtension"
                ],
                "CustomSchemas": [
                               "UsrSyncExtension"
                ],

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

Что делает вышеуказанный код:

- получает из SysAdminUnit часовой пояс текущего пользователя;

- при получении дат во время синхронизации использует этот часовой пояс.

Нравится

Поделиться

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