Вопрос

Можно ли сделать так, чтобы срок реакции/разрешения считался от момента назначения ответственного? (сейчас он считается от момента регистрации обращения)

Ответ

Расчет дат происходит во время изменения Сервиса в методе onServiceItemChanged() при создании обращения. Вы можете создать метод, который будет обрабатывать изменение ответственного и проводить расчет срока, однако все необходимы поля должны быть уже заполнены(в частности поле Сервис).

Нравится

Поделиться

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

Вопрос

Можно ли убрать эту всплывающую подсказку New ... ?

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

правильно ли я понимаю, что getPreventQuickAddSchemaNames нужно добавлять в конкретные страницы карточек, откуда необходимо исключить добавление новых элементов справочников?



Нельзя ли это исключить один раз в LookupQuickAddMixin ?

Ответ

Если во всем приложении, то можете попробовать перекрыть метод onLookupDataLoaded

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

(код ниже и UsrLookupQuickAddMixin - название пользовательской схемы):

 

define("UsrLookupQuickAddMixin", ["LookupQuickAddMixin"], function() {
    Ext.define("Terrasoft.UsrLookupQuickAddMixin", {
        override: "Terrasoft.LookupQuickAddMixin",
 
        onLookupDataLoaded: Terrasoft.emptyFn
    });
});





и затем подключить модуль в BootstrapModulesV2 (необходимо заместить)

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

 

define("BootstrapModulesV2", ["UsrLookupQuickAddMixin"], function() {
    return {};
});

после этого очистить кэш.

Нравится

Поделиться

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

А как это делать после 7.13, когда нельзя замещать модули?

Владимир, BootstrapModulesV2 замещать как раз можно.

 

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

 

Это часто используется как замена запрещённому замещению модулей, когда делают свой аналог в схеме с другим названием, замещают им стандартный при помощи override, а затем подключают в BootstrapModulesV2, чтобы доработанная версия грузилась при старте.

 

Ещё один пример этого подхода для доработки стандартных элементов есть тут в нижнем комментарии.

Можно, например, вместо onLookupDataLoaded,  заместить getPreventQuickAddSchemaNames добавим нужные сущности, например Продажи - "Opportunity":

 

define("UsrLookupQuickAddMixin", ["LookupQuickAddMixin"], function() {

    Ext.define("Terrasoft.UsrLookupQuickAddMixin", {

        override: "Terrasoft.LookupQuickAddMixin",

        getPreventQuickAddSchemaNames: function() {

            return ["SysAdminUnit", "VwSysSchemaInfo", "VwQueueSysProcess", "Opportunity"];

        },

    });

});

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

Симптомы

Суть инцидента: пытаемся войти в мобильное приложение – происходит ошибка синхронизации.

Часть полученного баг-репорта:

ENG

Terrasoft-Mobile":"true","Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie"},"method":"GET","disableCaching":false},"performanceCounter":{"startDate":"2015-07-24T08:26:56.702Z"}},"headers":{"X-Terrasoft-Mobile":"true","Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie"},"method":"GET","disableCaching":false},"async":true},"requestId":8,"status":500,"statusText":"Internal Server Error","responseText":"Terrasoft.Mobile.MobileModelLoopException: Models specified in the mobile application manifest have circular relationships\r\n   at Terrasoft.Mobile.MobileModelTopologicalSorter.Sort()\r\n   at Terrasoft.Mobile.MobileModelGraph.Build()\r\n   at Terrasoft.Mobile.MobileManifest.BuildModelGraph()\r\n   at Terrasoft.Mobile.MobileUtilities.GetAppMetadata(HttpContextBase context)\r\n   at Terrasoft.WebApp.Mobile.Services.MobileCodeService.ProcessRequest(HttpContext context)\r\nЦикл: [Account,KnowledgeBase]","responseXML":null,"responseBytes":null} 

Calls sequence:

RUS

Type: Terrasoft.SyncException

Message: An error occurred while synchronizing

Type: Terrasoft.ServerException

Message: Server request returned error

Additional information: 

{"request":{"id":4,"headers":{"X-Terrasoft-Mobile":"true","Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie","X-Requested-With":"XMLHttpRequest"},"options":{"url":"https://xxx.xxxxxx.xxx/0/Mobile/Services/MobileCodeService.ashx?functionName=getAppMetadata&workplaceCode=","scope":{"initialConfig":{"url":"https://xxx.xxxxxx.xxx/0/Mobile/Services/MobileCodeService.ashx?functionName=getAppMetadata&workplaceCode=","scope":{},"headers":{"X-Terrasoft-Mobile":"true","Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie"},"method":"GET","disableCaching":false},"performanceCounter":{"startDate":"2015-07-23T09:41:43.803Z"}},"headers":{"X-Terrasoft-Mobile":"true","Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie"},"method":"GET","disableCaching":false},"async":true},"requestId":4,"status":500,"statusText":"InternalServer Error","responseText":"Terrasoft.Mobile.MobileModelLoopException: Модели, указанные в манифесте мобильного приложения, имеют циклические связи\r\n at Terrasoft.Mobile.MobileModelTopologicalSorter.Sort()\r\n at Terrasoft.Mobile.MobileModelGraph.Build()\r\n at Terrasoft.Mobile.MobileManifest.BuildModelGraph()\r\n at Terrasoft.Mobile.MobileUtilities.GetAppMetadata(HttpContextBase context)\r\n at Terrasoft.WebApp.Mobile.Services.MobileCodeService.ProcessRequest(HttpContext context)\r\nЦикл: [Invoice,Contract]","responseXML":null,"responseBytes":null}

Решение

Для решения необходимо создать (Добавить - Исходный код) кастомный манифест (например, MobileApplicationManifestCustom) и указать язык "Javascript"

Для версии 7.6 и выше, в случае если MobileApplicationManifest в Custom нет - нужно замещать родительскую схему манифеста. Для этого можно войти в мастер мобильного приложения, выбрать "Настройку разделов" для рабочего места и нажать кнопку "Сохранить".

Если кастомный манифест уже присутствует, то открываем имеющий и добавляем следующий код:

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

{
    "Loops": [
        ["Account", "KnowledgeBase"],
    ]
}

, где

["Account", "KnowledgeBase"], - связи, которые необходимо указать. Значение прописывается из значения.

Например (из баг-репорта):

Цикл: [Invoice,Contract]","responseXML":null,"responseBytes":null}

То, прописывать надо:

 

{
    "Loops": [
        ["Invoice”,”Contract "],                   
    ]
}

Если версия 7.5 и ниже, то также необходимо манифест (например,  MobileApplicationManifestCustom ) прописать в системной настройке MobileApplicationManifest:

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

И проверить синхронизацию. Если с ошибкой, то скорее всего еще необходимо указать связи в кастомном манифесте. В результате в манифест добавляет до тех пор пока синхронизация не произойдет успешно.

Нравится

Поделиться

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

Вопрос

Как отобразить другую колонку в реестре "Контрагенты" в мобильном приложении? Например, колонку "Адрес".

Ответ

Для реализации, так как базовую схему MobileAccountModuleConfig нельзя изменять, то Вам необходимо создать свою схему UsrMobileAccountModuleConfig (в пользовательском пакете создать схему расширения страницы соответствующего раздела. Для этого в разделе [Конфигурация] выбрать Добавить  > Исходный код. Для схемы заполнить свойства[Заголовок], [Название], [Пакет]. В качестве языка для схемы выбрать JavaScript) и подключить ее в манифесте.

"Models": {
"Account": {
"RequiredModels": [
. . .
],
"ModelExtensions": [
. . .
],
"ModelExtensions": [],
            "PagesExtensions": [
                "MobileAccountRecordPageSettingsDefaultWorkplace",
                "MobileAccountGridPageSettingsDefaultWorkplace",
                "MobileAccountActionsSettingsDefaultWorkplace",
                "MobileAccountModuleConfig",
                "UsrMobileAccountModuleConfig"
            ]

В ней прописать такой код:

Terrasoft.sdk.GridPage.setSecondaryColumn("Account", {
    columns: ["Address"],
    convertFunction: function(values) {
        return values.Address;
    }
});

В манифесте для импорта прописать необходимые колонки:

{
            "Name": "Account",
            "SyncColumns": [
                "Address"
            ]
        }

После этого желательно перегенерировать исходный код и скомпилировать конфигурацию.

Для наглядности прикрепил на деталь «Файлы» скриншот и примеры с полным листингом кода.

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

Нравится

Поделиться

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

Вопрос

При нажатии на кнопку "добавить" детали "Продукты в заказе" возникала следующая ошибка.

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

Аналогичная ошибка возникала про попытке добавить "График поставок и оплат" 

Ответ

Проблема в следующем: при попытке добавить продукт предварительно выполняется сохранение страницы, однако по неизвестным причинам был изменен базовый спрвочник "OrderStatus". Во время сохранения выполняется проверка на равенство сумм и код страницы OrderPageV2 пакета Passport отрабатывает некорректно:

validateOrderStatus: function(callback, scope) {
    var result = {
        success: true
    };
    var status = this.get("Status");
    var primaryAmount = this.get("PrimaryAmount");
    var OrderStatus = OrderConfigurationConstants.Order.OrderStatus;
    if (status && (status.value === OrderStatus.InPlanned || status.value === OrderStatus.Canceled)) {
        callback.call(scope || this, result);
        return;
    }
    var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
        rootSchemaName: "SupplyPaymentElement"
    });
    esq.addAggregationSchemaColumn("PrimaryAmountPlan", Terrasoft.AggregationType.SUM,
"PrimaryAmountPlanSum");
    var filters = Terrasoft.createFilterGroup();
    filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
"Order", this.get("Id")));
    filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
"Type", OrderConfigurationConstants.SupplyPaymentElement.Type.Payment));
    esq.filters = filters;
    esq.getEntityCollection(function(response) {
        if (response.success) {
            var collection = response.collection;
            if (collection.getCount() > 0 && primaryAmount !==
collection.getByIndex(0).get("PrimaryAmountPlanSum")) {
                result.message = this.get("Resources.Strings.ValidateOrderStatus");
                result.success = false;
            }
        } else {
            return;
        }
        callback.call(this, result);
    }, scope);

Инструкция

var status = this.get("Status"); - возвращает undefined

collection.getByIndex(0).get("PrimaryAmountPlanSum"))  - возвращает 0

Из-за это не проходит проверка и выдается предупреждения для статуса "В планах"

Для решения необходимо заместить модуль OrderConfigurationConstant и указать в нем корректные id, тогда код:

if (status && (status.value === OrderStatus.InPlanned || status.value === OrderStatus.Canceled)) {
    callback.call(scope || this, result);
    return;
}

будет выполняться корректно.

 

Нравится

Поделиться

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

Вопрос

Не даёт из активностей удалить участника,

Пишет, что ответственного удалить нельзя, но он НЕ ЯВЛЯЕТСЯ ответственным.

Ответ

-- понижение для не ответственных до учасника
SELECT ac.Id, Title, OwnerId, ap.ParticipantId, ap.Id as ApId FROM Activity ac
LEFT JOIN ActivityParticipant ap on ap.RoleId = '53fc4a92-b0ea-e111-96c4-00165d094c12'
AND ac.Id = ap.ActivityId
WHERE OwnerId <> ap.ParticipantId
--
UPDATE ActivityParticipant SET RoleId = '1a8324e8-a6e1-df11-971b-001d60e938c6'
WHERE Id In (
SELECT ap.Id FROM Activity ac
LEFT JOIN ActivityParticipant ap on ap.RoleId = '53fc4a92-b0ea-e111-96c4-00165d094c12'
AND ac.Id = ap.ActivityId
WHERE OwnerId <> ap.ParticipantId
)
-- повышение ответственных до ответственного
SELECT ac.Id, Title, OwnerId, ap.ParticipantId, ap.Id as AppId, ap.RoleId FROM Activity ac
LEFT JOIN ActivityParticipant ap on ac.Id = ap.ActivityId
WHERE ac.OwnerId = ap.ParticipantId AND
ap.RoleId <> '53fc4a92-b0ea-e111-96c4-00165d094c12'
--
UPDATE ActivityParticipant Set RoleId = '53fc4a92-b0ea-e111-96c4-00165d094c12'
WHERE Id In (
SELECT ap.Id FROM Activity ac
LEFT JOIN ActivityParticipant ap on ac.Id = ap.ActivityId
WHERE ac.OwnerId = ap.ParticipantId AND
ap.RoleId <> '53fc4a92-b0ea-e111-96c4-00165d094c12'
)

 

Нравится

Поделиться

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

1) Типизировать страницы редактирования раздела.

Предположим при типизации раздела "Х" была создана новая пустая страница с названием OldPage.

2) Перейди в конфигурацию.

3) Создать свою схему в конфигурации, назвав ее нужным именем (например – NewPage).

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

define("NewPage", [], function() {
    return {
        entitySchemaName: "NewPageEntity",//название раздела Х. Можно посмотреть название в обьекте этого раздела.
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
        methods: {},
        rules: {}
    };
});

5) Сохранить изменения.

КОМПИЛИРОВАТЬ ВСЁ

6) Выполнить запрос:

update SysModuleEdit
set CardSchemaUId = (select Uid from SysSchema where name = 'NewPage' and ExtendParent = 0)
where CardSchemaUId = (select Uid from SysSchema where name = 'OldPage' and ExtendParent = 0)

КОМПИЛИРОВАТЬ ВСЁ

7) Очистить кэш. Проверить.

Нравится

Поделиться

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

Вопрос

В версии 7.7.0.2293 SalesEnterprise + Marketing + CustomerCenter в редактируемом реестре все поля изменяемой записи доступны для изменений. Как можно заблокировать от изменений отдельные поля? 

Ответ

1) Создать деталь с помощью мастера деталей, на закладке страницы вывести хотя бы несколько полей. Сохранить.

2) Зарегистрировать мастером разделов деталь на странице в разделе. Настроить колонки.

3) Для того, чтобы деталь стала редактируемой, добавляем зависимости, миксин, атрибут и мердж грида в блоке дифф как показано в примере ниже:

define("UsrSchema1Detail", ["ConfigurationGrid", "ConfigurationGridGenerator",
"ConfigurationGridUtilities"], function() {
    return {
        entitySchemaName: "UsrTestContactDetail",
        attributes: {
            "IsEditable": {
                dataValueType: Terrasoft.DataValueType.BOOLEAN,
                type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                value: true
            }
        },
        mixins: {
            ConfigurationGridUtilites: "Terrasoft.ConfigurationGridUtilities"
        },
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[
            {
            "operation": "merge",
            "name": "DataGrid",
            "values": {
               "className": "Terrasoft.ConfigurationGrid",
               "generator": "ConfigurationGridGenerator.generatePartial",
               "generateControlsConfig": {"bindTo": "generatActiveRowControlsConfig"},
               "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": "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
            }
         }
        ]/**SCHEMA_DIFF*/,
        methods: {}
    };
});

5) В схеме страницы редактирования детали описываем бизнес-правило по правилам написания бизнес-правил - http://academy.terrasoft.ua/documents/docs/technic/SDK/7.6.0/BlockingFieldByCondition.html

define("UsrUsrTestContactDetail1Page", ["BusinessRuleModule"], function(BusinessRuleModule) {
    return {
        entitySchemaName: "UsrTestContactDetail",
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[
            {
                "operation": "insert",
                "name": "UsrContact",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 0,
                        "layoutName": "Header"
                    },
                    "bindTo": "UsrContact"
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "UsrTestInt1",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 12,
                        "row": 0,
                        "layoutName": "Header"
                    },
                    "bindTo": "UsrTestInt1"
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "UsrTestInt2",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 1,
                        "layoutName": "Header"
                    },
                    "bindTo": "UsrTestInt2"
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 2
            },
            {
                "operation": "insert",
                "name": "CreatedBy",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 12,
                        "row": 1,
                        "layoutName": "Header"
                    },
                    "bindTo": "CreatedBy"
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 3
            }
        ]/**SCHEMA_DIFF*/,
        methods: {},
        rules: {
            "UsrTestInt1": {
                "EnabledUsrTestInt1": {
                    "ruleType": BusinessRuleModule.enums.RuleType.BINDPARAMETER,
                    "property": BusinessRuleModule.enums.Property.ENABLED,
                    "conditions": [
                        {
                            "leftExpression": {
                                "type": BusinessRuleModule.enums.ValueType.CONSTANT,
                                "value": true
                            },
                            comparisonType: Terrasoft.ComparisonType.NOT_EQUAL,
                            rightExpression: {
                                type: BusinessRuleModule.enums.ValueType.CONSTANT,
                                value: true
                            }
                        }
                    ]
                }
            }
        }
    };
});

В результате поле заблокировано. Если же деталь существующая, и у нее нет страницы редактирования, то необходимо либо удалить информацию в таблице SysDetail и SysModuleEdit по данной детали, и пересоздать ее мастером деталей, либо страницу редактирования создать и зарегистрировать в таблице SysModuleEdit по аналогии с существующими. Затем написать в схеме страницы редактирования детали необходимый для блокировки код.

Нравится

Поделиться

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

Симптомы

На странице "Заказ" у пользователя на всех вкладках отображаются поля "Состояние оплаты", "Состояние доставки" и итоги по валютам. Мастером разделов данные поля отредактивать возможности нет, в мастере они отображаются в том же виде что и на странице.

Причина

Страница OrderPageV2 была разработана партнером и содержала следующий код для указанных элементов (пример для состояния доставки):

{
    "operation": "merge",
    "name": "PaymentStatus",
    "values": {
        "layout": {
            "column": 0,
            "row": 1,
            "colSpan": 12,
            "rowSpan": 1
        },
        "caption": {
            "bindTo": "Resources.Strings.PaymentStatusCaption"
        },
        "enabled": true
    }
},
{
    "operation": "remove",
    "name": "PaymentStatus",
    "properties": [
        "contentType",
        "parentName",
        "propertyName"
    ]
},
{
    "operation": "move",
    "name": "PaymentStatus",
    "index": 1
}

Решение

Изменить код страницы для указанных элементов, убрав партнерскую логику, например на:

{
    "operation": "insert",
    "name": "PaymentStatus",
    "values": {
        "bindTo": "PaymentStatus",
        "layout": {
            "column": 0,
            "row": 6,
            "colSpan": 12,
            "rowSpan": 1
 },
        "contentType": Terrasoft.ContentType.ENUM,
        "caption": {
            "bindTo": "Resources.Strings.PaymentStatusCaption"
 },
        "enabled": true
 },
    "parentName": "Header",
    "propertyName": "items",
    "index": 9
}

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

Частный случай, индивидуальное решение

Нравится

Поделиться

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

Вопрос

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

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

Ответ

Для реализации подобного функционала необходимо изменять базовую логику приложения с помощью. Вам необходимо заместить (например, «OpportunityProductPageV2») и для желаемой колонки в секции diff добавить параметр «prepareList», который будет ссылаться пустую функцию (например, «preparelistemptyFn»). Функцию также необходимо объявить на странице редактирования.

controlConfig": {
    "prepareList": { "bindTo": " preparelistemptyFn" }
}

Полный Source Code

define("OpportunityProductPageV2", ["MoneyModule"],
        function(MoneyModule) {
            return {
                entitySchemaName: "OpportunityProductInterest",
                attributes: {},
                details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
                methods: {
 
                    preparelistreturnfalse: function() {
                        return false;
                    },
                },
                diff: /**SCHEMA_DIFF*/[
                    {
                        "operation": "merge",
                        "parentName": "Header",
                        "propertyName": "items",
                        "name": "Product",
                        "values": {
                            "bindTo": "Product",
                            "controlConfig": {
                                "prepareList": { "bindTo": "preparelistreturnfalse" }
                            }
                        }
                    },
                ]/**SCHEMA_DIFF*/
            };
        });

Наглядный пример ниже (рис. 1).

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

Рис. 1

Нравится

Поделиться

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