Кейс

I added a contact and an event in the iPad version und synchronized. Then I opened the iPhone version and synchronized.

But the new data is not shown in the iPhone version.

Я добавил контакт и событие в версии на iPad и выполнил синхронизацию. Затем я открыл версию на iPhone и синхронизировал ее.

Но новые данные не отображаются на iPhone.

Цель

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

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

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

Выполнение

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

 

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

Такой эффект может быть вызван различными настройками времени на мобильных устройствах.

Нравится

Поделиться

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

Вопрос

Вызов хранимой процедуры из веб-сервиса.

Ответ

Создайте схему исходного кода:

namespace Terrasoft.Configuration.UsrTestStored
{
    using System;
    using System.Web;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using System.ServiceModel.Activation;
    using System.Linq;
    using System.Text;
    using System.Collections.Generic;
    using System.Collections.Concurrent;
    using System.Data;
    using Terrasoft.Common;
    using Terrasoft.Core;
    using Terrasoft.Core.DB;
    using Terrasoft.Core.Entities;
    using Terrasoft.Core.Factories;
    using Terrasoft.Core.Store;
    using Terrasoft.Nui;
 
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class UsrTestStored
    {
        [OperationContract]
        [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,
        ResponseFormat = WebMessageFormat.Json)]
        public string GetTest(string inputParam)
        {
            var userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];
            StoredProcedure storedProcedure = new StoredProcedure(userConnection, "tsp_Test");
            storedProcedure.PackageName = userConnection.DBEngine.SystemPackageName;
            using (var dbExecutor = userConnection.EnsureDBConnection()) {
               try {
                   dbExecutor.CommandTimeout = 0;
                   dbExecutor.StartTransaction();
                   storedProcedure.Execute(dbExecutor);
                   dbExecutor.CommitTransaction();
                   return "OK";
               } catch {
                   dbExecutor.RollbackTransaction();
                   return "NOT OK";
               }
            }
        }
    }
}

 

Нравится

Поделиться

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

Добрый день!

Приведите, пожалуйста, если возможно, пример вызова хранимой процедуры которая возвращает результат выполнения и пример обработки результата. Спасибо!

Вот пример вызова ХП с исходящим параметром:

 private const string SequenseNumberProcedureName = "tsp_GenerateSequenseNumber"; 
 public string GenerateNumber() {
   var number = string.Empty;
   var procedure = new StoredProcedure(UserConnection, SequenseNumberProcedureName);
   var dataValueTypeManager = (DataValueTypeManager)UserConnection.AppManagerProvider.GetManager("DataValueTypeManager");
   procedure.WithParameter(EntitySchema.Name);
   procedure.WithOutputParameter("result_value", dataValueTypeManager.GetInstanceByName("Text"));
   using (var dbExecutor = UserConnection.EnsureDBConnection()) {
    dbExecutor.StartTransaction(System.Data.IsolationLevel.ReadCommitted);
    try {
     procedure.Execute(dbExecutor);
     if (procedure.Parameters.Count > 0) {
      number = (string)procedure.Parameters[1].Value;
     }
    } catch {
     dbExecutor.RollbackTransaction();
     throw;
    }
    dbExecutor.CommitTransaction();
   }
   return number;
  }

А как потом вернуть из веб-сервиса, есть и в исходном примере. 

Спасибо, Александр! 

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

Добавляем действие перехода к контакту на деталь «Карьера контакта»

Чтобы добавить кнопку «Перейти к контакту» необходимо реализовать несложный замещающий модуль страницы детали «Деталь карьера контакта».

define('ContactCareerDetail', ['terrasoft', 'ContactCareer', 'ContactCareerDetailStructure',
'ContactCareerDetailResources'],
function(Terrasoft, ContactCareer, structure, resources) {
    structure.userCode = function() {
        //в этом методе можно работать со списком действий детали
        this.modifyUtilsButton = function(utilsButton) {
            //получаем список действий
            var utilsMenuItems = utilsButton.menu.items;
            //добавляем новый пункт в начало списка
            utilsMenuItems.unshift(actionGoToContact);
            return utilsButton;
        };
        var actionGoToContact = {
            caption: resources.localizableStrings.GoToContact,
            click: {
                bindTo: 'goToContact'
            },
            enabled: {
                bindTo: 'isAnySelected'
            }
        };
        this.methods.goToContact = function() {
            var selectedRows = this.GetSelectedItems();
            if (Ext.isEmpty(selectedRows)) {
                return;
            }
            var viewModel = this;
            var cardSchemaName;
            var moduleStructure = Terrasoft.configuration.ModuleStructure.Contact;
            var config = Terrasoft.configuration.EntityStructure[this.entitySchema.columns.Contact.name];
            if (config) {
                cardSchemaName = config.pages[0].cardSchema;
            }
            var gridData = this.get('gridData');
            var contactId;
            gridData.collection.items.forEach( function(item) {
                if (item.values.Id == selectedRows[0]) {
                    contactId = item.values.Contact.value;
                }
            });
            if (contactId) {
                var token = moduleStructure.cardModule + '/' + cardSchemaName + '/view/' + contactId;
                Terrasoft.Router.pushState(null, null, token);
            }
            else {
                return;
            }
        };
    };
return structure;
});

 

Нравится

Поделиться

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

,>=orwhenthesubqueryisusedasanexpression-Симптомы">Симптомы

После ввода логин и пароль получаем ошибку:

Exception Message: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

Exception Type: System.Data.SqlClient.SqlException

Exception Source: .Net SqlClient Data Provider

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

,>=orwhenthesubqueryisusedasanexpression-Причина">Причина

Данная ошибка может вонзинуть из-за обновления.

Дублирующие права с одинаковыми позициями.

,>=orwhenthesubqueryisusedasanexpression-Решение">Решение

С помощью запроса находим название (Code) дублирующихся прав:

select SAO.Code, SAOG.Position, count(sao.id) from sysadminoperationgrantee SAOG
 
join SysAdminOperation SAO on SAO.ID = SAOG.SysAdminOperationId
 
join SysAdminUnit SAU on SAU.ID = SAOG.SysAdminUnitId
 
group by SAO.Code, SAOG.Position
 
having count(sao.id) > 1

После того, как нашли название (например, "CanUseSharedMailBox"), необходимо найти список ID записи, которые являются дублями.

SELECT * FROM SysAdminOperationGrantee WHERE SysAdminOperationId = (SELECT Id FROM SysAdminOperation WHERE Code = 'CanUseSharedMailBox')

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

UPDATE SysAdminOperationGrantee SET Position = 1 WHERE Id = 'C3665747-F6F6-474F-8CEE-5A7678883F4B'

 

Нравится

Поделиться

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

Вопрос

Создаем новый тип связи, добавляем его в справочник, назначаем признак Web. Добавляем запись, но получается что себя эта запись ведет себя также, как обычное поле на странице без возможности перехода по гиперссылке. Подскажите, как можно настроить новый тип связи, чтобы он также вел себя как гиперссылка?

Ответ

В базой версии приложения функционал средств связей, например, с типом «E-mail» и «Web» реализован только для базовых значение (реализовано на уровне конкретных ID). Реализацию данного функционала можете посмотреть в схеме «BaseCommunicationViewModel».

Если Вы хотите, чтобы пользовательские поля с типом «Web» имел такую же логику как и базовая колонка, то попробуйте пожалуйста, следующее:

- заместить полностью «CommunicationUtils»;

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

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

define("CommunicationUtils", ["CommunicationUtilsResources", "ConfigurationConstants"],
    function(resources, ConfigurationConstants) {
        /**
         * Указывает является ли тип средства связи одним из типов соц. сетей.
         * @protected
         * @param {Object} communicationType Тип средства связи.
         * @return {boolean} Возвращает true если тип средства связи относиться к социальным сетям.
         */
        function isSocialNetworkType(communicationType) {
            if (!communicationType) {
                return false;
            }
            communicationType = communicationType.value || communicationType;
            return ConfigurationConstants.SocialNetworksCommunicationTypes.indexOf(communicationType) !== -1;
        }
        /**
         * Указывает является ли тип средства связи телефоном.
         * @protected
         * @param {Object} communicationType Тип средства связи.
         * @param {Object} phoneTypes Типы телефонов.
         * @return {Boolean} Возвращает true, если тип средства связи относится к телефонам.
         */
        function isPhoneType(communicationType, phoneTypes) {
            if (!communicationType) {
                return false;
            }
            communicationType = communicationType.value || communicationType;
            var phonesCommunicationTypes = phoneTypes || ConfigurationConstants.PhonesCommunicationTypes;
            return phonesCommunicationTypes.indexOf(communicationType) !== -1;
        }
        /**
         * Указывает является ли тип средства связи Web ссылкой.
         * @protected
         * @param {Object} communicationType Тип средства связи.
         * @return {boolean} Возвращает true если тип средства связи Web ссылка.
         */
        function isWebType(communicationType) {
            if (!communicationType) {
                return false;
            }
            var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "ComTypebyCommunication"
            });
            esq.addColumn('Communication', 'Communication');
            esq.filters.add("CommunicationCode", Terrasoft.createColumnFilterWithParameter(
                Terrasoft.ComparisonType.EQUAL,
                "[ComTypebyCommunication:CommunicationType:CommunicationType].Communication.Code",
                "Web"));
            var communicationId = '';
            esq.getEntityCollection(function(response) {
                        if (response.success) {
                            var entityCollection = response.collection;
                            var communication = entityCollection.getByIndex(0);
                            if (!Ext.isEmpty(communication)) {
                                communicationId = communication.get("Communication").value;
                            }
                        }
                    }, this);
            if (Ext.isEmpty(communicationId)) {
                return false;
            }
            return ConfigurationConstants.Communication.Web.indexOf(communicationId) !== -1;
        }
        /**
         * Указывает является ли тип средства связи Web ссылкой.
         * @protected
         * @param {Object} communicationType Тип средства связи.
         * @return {boolean} Возвращает true если тип средства связи Web ссылка.
         */
        function isEmailType(communicationType) {
            if (!communicationType) {
                return false;
            }
            communicationType = communicationType.value || communicationType;
            return ConfigurationConstants.CommunicationTypes.Email.indexOf(communicationType) !== -1;
        }
        /**
         * Указывает является ли тип средства связи адресом Skype.
         * @protected
         * @param {Object} communicationType Тип средства связи.
         * @return {boolean} Возвращает true если тип средства связи адрес Skype.
         */
        function isSkypeType(communicationType) {
            if (!communicationType) {
                return false;
            }
            communicationType = communicationType.value || communicationType;
            var skypeId = ConfigurationConstants.Communications.UseForContacts.Predefined.Skype.value;
            return skypeId.indexOf(communicationType) !== -1;
        }
        return {
            isSocialNetworkType: isSocialNetworkType,
            isPhoneType: isPhoneType,
            isEmailType: isEmailType,
            isWebType: isWebType,
            isSkypeType: isSkypeType
        };
    });

- почистить кэш браузера.

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

Нравится

Поделиться

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

Симптомы

Тип: Terrasoft.Exception%0D%0AСообщение: Текущее положение устройства не может быть определено %0D%0A%0D%0A 

Причина

Данное сообщение возникает в результате временного сбоя сети.

Решение

Следует убедиться в наличии стабильного интернет соединения и повторно выполнить действие.

Если сообщение возникает вновь, рекомендуем выполнить действие “Очистить кэш” в настройках мобильного приложения. После чего, необходимо синхронизироваться еще раз.

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

Стабильное интернет соединение.

Нравится

Поделиться

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

Вопрос

Как пользоваться функцией asyncValidate() из BasePageV2 для проверки заполнения полей на странице ?

Ответ

Увидеть реализацию данного метода можно в DocumentPageV2. Вы можете реализовать необходимый функционал по аналогии.

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

Потом вызвать его в asyncValidate.

Например:

asyncValidate: function(callback, scope) {
    this.callParent([function(response) {
        if (!this.validateResponse(response)) {
            return;
        }
        Terrasoft.chain(
            function(next) {
                this.myValidationMethod(function(response) {
                    if (this.validateResponse(response)) {
                        next();
                    }
                }this);
            },
            function() {
                callback.call(scope, response);
            },
        this);
    }this]);
}

 

 

Нравится

Поделиться

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

Вопрос

Каким образом убрать на заблокированных справочных полях?

Ответ

Пример есть в FieldForceMobileActivityModuleConfig

Terrasoft.sdk.RecordPage.configureColumn("Activity""VisitActionsDetailV2EmbeddedDetail",
   "Action.FieldForceActionType.Name",
   {
      isInPlaceEditingMode: false,
      customPreviewConfig: {
         xtype: "visitactionviewfield"
      }
   }
);

 

Нравится

Поделиться

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

Симптомы

У меня проблемы / вопросы с мобильной версией:

  1. Если я что-то добавлю (контакт, учетная запись и т. Д.) в bpm'online эти данные экспортируются в мобильное приложение после выполнения синхронизации (это нормально. Но когда я удаляю что-то в bpm'online, эти данные не удаляются  в мобильном приложении после синхронизации, почему?
  2. В Mobile Wizard у меня нет вкладки Dashboard, но в bpm'mobile у меня есть эта вкладка, почему?
  3. Во вкладке Продажи Супервизор не видит продажи. Как я помню, вы написали мне, что это нормально, но как я могу это изменить? Я хочу, чтобы супервизор увидел все продажи.

Решение

1. К сожалению, мобильное приложение не синхронизирует информацию об удаленных записях в bpm'online. Мы знаем об этой ошибке и планируем ее исправить в одном из будущих выпусков. 

2. Вы не можете настроить диаграмму Dashboard в Mobile Wizard, эта функция доступна только в планах.

3.  Если вы хотите, чтобы каждый пользователь видел все возможности, мы можем удалить текущий фильтр для вас (приложение получает возможность фильтровать их по колонке Владелец).

Нравится

Поделиться

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

Вопрос

Есть ли возможность на странице сделать группу полей по умолчанию "свернутой"?

Ответ

У групп полей есть свойство collapsed. При описании группы полей в секции diff необходимо задать этому свойству признак true:

 

Пример для схемы OrderPageV2 для группы полей "Информация о получателе":

diff: /**SCHEMA_DIFF*/[
    {
        "operation": "merge",
        "parentName": "OrderResultsTab",
        "name": "OrderReceiverInformationResultsControlBlock",
        "values": {
            "controlConfig": {"collapsed": true}
        }
    },
]/**SCHEMA_DIFF*/

 

Нравится

Поделиться

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