Здравствуйте!

Существует ли инструмент, с помощью которого в мобильном приложении можно изменить тип поиска с "Начинается с" на "Содержит"?

Нравится

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

Алексей, здравствуйте!

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



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



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



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

Вам необходимо:

- если не создан, то создать пользовательский манифест мобильного приложения (информация есть на SDK - https://academy.terrasoft.ru/documents/technic-sdk/7-11/manifest-mobilnogo-prilozheniya, просьба ознакомиться). Проще всего будет его создать если зайти в мастер мобильного приложения и сохранить текущие настройки;

- прописать в корне манифеста, в отдельную секцию - http://prntscr.com/hfwdpf:

 

"PreferedFilterFuncType": 'Terrasoft.FilterFunctions.SubStringOf',

 

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

- очистить кэш и провести первичную синхронизацию;

- в результате должно работать согласно бизнес-задаче - http://prntscr.com/hgci19.

 

По умолчанию название манифеста MobileApplicationManifestDefaultWorkspace, но если это пользовательское рабочее место, то приблизительное имя в конфигурации будет MobileApplicationManifest[название рабочего места].

Примечание. Заметьте, какое рабочее место Вы используете в мобильном устройстве и в какой манифест Вы добавляете код. Убедитесь, что Вы просинхронизированы с тем рабочим местом.



Также об этом параметре ("Terrasoft.FilterFunctions.SubStringOf") было описано на Академии -https://academy.terrasoft.ru/documents/technic-sdkmob/7-12/manifest-svoystva-dannyh-i-biznes-logiki.

Дмитрий, огромное спасибо!

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

Здравствуйте!

В web-клиенте реализован бизнес-процесс. Как обеспечить запуск данного процесса в мобильном клиенте?

Нравится

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

На мобильном процессы не запускаются. После синхронизации записи с телефона в основную базу процесс запустится там.

Бизнес процессы запускаются и выполняются на сервере, а не на клиенте. А запустить БП из мобилки можно попробовать при помощи ProcessEngineService.svc - это сервис, который позволяет запускать БП сторонним приложениям. По ссылке статья в Академии по этому сервису.

https://academy.terrasoft.ru/documents/technic-sdk/7-12/web-servis-proc…

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

Terrasoft.AuthService.login({
    name: Terrasoft.CurrentUserInfo.login,
    password: Terrasoft.CurrentUserInfo.password,
    success: function () {
 
        Ext.Ajax.request({
            method: "POST",
            url: Terrasoft.CurrentUserInfo.serverUrl + '/0/rest/ServiceName/MethodName',
            scope: this,
            jsonData: { 
                // Параметры. Названия такие же, как и названия параметров в методе сервиса.
            },
            success: this.onRequestSuccess,
            failure: this.onRequestFailure
        });
    },
    failure: function (e) {
        Terrasoft.Mask.hide();
        Terrasoft.MessageBox.showMessage("Не удалось выполнить авторизацию.");
    },
    scope: this
});

 

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

Помогите решить проблему. Пытаюсь зайти в мобильное приложение под тестовым пользователем, с лицензиями и правами все в порядке. Но, после нажатия кнопки "войти" выдаёт следующую ошибку:

"В процессе синхронизации произошла ошибка"

Отчет прикрепляю:

Model Name: Benefit_M503

Platform: Android

Platform Version: 5.1

Resolution: 360x640

UIVersion: UIV2

ApplicationVersion: 7.12.9

ApplicationMajorVersion: 7.12

BackgroundSyncMode: Always

ServerUrl: https://bpmstest.abiconnect.ru/

ContactId: a0469676-80b4-4b52-a740-8a5a1f72c5c2

CultureName: ru-RU

ApplicationRevision: null

WorkplaceCode: NPD01

ProductInfo: {"ProductName":"bpm'online","ProductEdition":"studio","CustomerId":"201712251022","Version":{"Major":7,"Minor":12,"Build":1,"Revision":924,"MajorRevision":0,"MinorRevision":924}}

CurrentDateTime: Tue Jul 17 2018 15:24:47 GMT+0300 (MSK)

Type: Terrasoft.SyncException 

Message: В процессе синхронизации произошла ошибка 

Stack trace: 

Function.Ext.define.statics.handleException(Terrasoft.Mobile.Combined.js:32396:34) 

Object.Ext.apply.callback(sencha-touch-all-debug.js:10397:26) 

Ext.define.callUserErrorHandler(Terrasoft.Mobile.Combined.js:26185:7) 

Object.Ext.apply.callback(sencha-touch-all-debug.js:10397:26) 

Ext.define.callFailure(Terrasoft.Mobile.Combined.js:25724:8) 

Object.Ext.apply.callback(sencha-touch-all-debug.js:10397:26) 

Function.Terrasoft.RequestManager.issueRequest.requestFnConfig.failure(Terrasoft.Mobile.Combined.js:40521:11) 

Object.Ext.apply.callback(sencha-touch-all-debug.js:10397:26) 

Object.config.requestItemFailure(Terrasoft.Mobile.Combined.js:39654:11) 

Ext.define.onRequestFailure(Terrasoft.Mobile.Combined.js:39422:12) 

Object.Ext.apply.callback(sencha-touch-all-debug.js:10397:26) 

null.(Terrasoft.Mobile.Combined.js:39658:9) 

Object.Ext.apply.callback(sencha-touch-all-debug.js:10397:26) 

Ext.define.executeCallbackIfNotCanceled(Terrasoft.Mobile.Combined.js:39903:8) 

Ext.define.failureHandler(Terrasoft.Mobile.Combined.js:39925:8) 

Object.Ext.apply.callback(sencha-touch-all-debug.js:10397:26) 

Ext.define.onComplete(sencha-touch-all-debug.js:36402:17) 

Ext.define.onStateChange(sencha-touch-all-debug.js:36338:18) 

XMLHttpRequest.(sencha-touch-all-debug.js:3233:27) 

Type: Terrasoft.ServerException 

Message: Запрос на сервер вернул ошибку 

AdditionalInfo: {"request":{"id":27,"headers":{"Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie","X-Terrasoft-Mobile":true,"X-Requested-With":"XMLHttpRequest"},"options":{"isCancelable":true,"url":"https://bpmstest.abiconnect.ru/0/Mobile/Services/MobileCodeService.ashx…","success":null,"failure":null,"scope":{"asyncOperation":{"initConfig":null,"initialConfig":{"isCancelable":true,"asyncQueueId":null},"config":{"isCancelable":true,"asyncQueueId":null},"_isCancelable":true,"_asyncQueueId":null,"asyncManagerIsDisabled":true},"initialConfig":{"isCancelable":true,"url":"https://bpmstest.abiconnect.ru/0/Mobile/Services/MobileCodeService.ashx…","success":null,"failure":null,"scope":null,"onRequestCreate":null,"headers":{"Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie","X-Terrasoft-Mobile":true},"method":"GET","disableCaching":false},"performanceCounterKey":"d94e002c-ed82-4549-8981-2404db92e317"},"onRequestCreate":null,"headers":{"Accept":"application/json","Content-Type":"application/json","Authorization":"Cookie","X-Terrasoft-Mobile":true},"method":"GET","disableCaching":false},"async":true},"requestId":27,"status":500,"statusText":"Internal Server Error","getResponseHeader":null,"getAllResponseHeaders":null,"responseText":"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\nhttp://www.w3.org/1999/xhtml\">\r\n\r\n\r\n500 - \u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044f\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.\r\n\r\n\r\n\r\n\r\n\r\n\u041e\u0448\u0438\u0431\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\r\n\r\n \r\n 

500 - \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044f\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.

\r\n 

\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u043c; \u0440\u0435\u0441\u0443\u0440\u0441 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d.

\r\n \r\n\r\n\r\n\r\n","responseXML":null,"responseBytes":null} 

Нравится

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

По результатам анализа, у Вас в приложении настроена аутентификация по NTLM-протоколу. К сожалению, на данный момент в мобильном приложении нет возможности работать при сквозной аутентификации по NTLM-протоколу (https://academy.terrasoft.ru/documents/studio/7-12/kak-nastroit-autentifikaciyu-windows#XREF_44889_NTLM) при открытии bpm'online приложения, так как в мобильной версии идет переход на страницу логина, а не на "ntlmlogin". Для работы в мобильной версии необходимо отключить (признак false) использование ключа "UsePathThroughAuthentication". Перед правками убедитесь, что в providerNames используется LDAP (https://academy.terrasoft.ru/documents/studio/7-12/chasto-zadavaemye-voprosy-po-sinhronizacii-s-ldap#XREF_37112)

Примечание. Рекомендуем изменять настройки приложения в нерабочее время. К сожалению, также отсутствует возможность в мобильном приложении использовать одновременно сквозную аутентификацию, минуя страницу входа, и вход по ссылке "Войти под доменным пользователем". Со своей стороны мы зафиксировали пожелание на доработку данной функциональности.

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

Добрый час суток!

Немного не могу понять как построить запрос на UPDATE в мобильном приложении.

Например я хочу сделать такой запрос SQL

UPDATE TEST SET IsChecked = 1 WHERE Question = '' and Answer = ''

Я делаю так:

        var filters = Ext.create("Terrasoft.Filter", {

                type: Terrasoft.FilterTypes.Group,

                logicalOperation: Terrasoft.FilterLogicalOperations.And

            });

        filters.addFilter(Ext.create("Terrasoft.Filter", {

                property: "Question ",

                value: multiAnswerId // тут Id Question (для фильтра как выше)

        }));

        filters.addFilter(Ext.create("Terrasoft.Filter", {

                property: "Answer ",

                value: answerVariantId // тут Id Answer(для фильтра как выше)

        }));

        var sql = Terrasoft.Sql.UpdateBuilder.build({

                model: "Test", //Таблица в которую хочу сделать запрос

                queryConfig: queryConfig, //что это ?

                record: record, // что это?

                filter: filters,// это у меня есть

                includeOnlyModifiedColumns: true // что это?

        });

        sqls.push(sql);

        

Подскажите пожалуйста,как мне в мой обьект который я бросаю (var sql = ...) добавить по сути SET IsChecked =1 ? Ведь фильтры я уже сделал,а как сформировать немного не пойму.. может мне даже QueryConfig и includeOnlyModifiedColumns вообще ну нужны ? и достаточно как то константами сделать ? Спасибо заранее!

Нравится

12 комментариев

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

Вот пример фильтрации и перебора:

// Создание экземпляра хранилища для данных модели Contact.
var store = Ext.create('Terrasoft.store.BaseStore', {
    model: 'Contact'
});
 
// Создание конфигурационного объекта с дополнительными параметрами запроса на выборку данных.
var queryConfig = Ext.create('Terrasoft.QueryConfig', {
    // Определение колонок, которые будут возвращены в запросе.
    columns: ['Name', 'Id', 'Account'],
    // Имя модели, к которой выполняется запрос.
    modelName: 'Contact'
});
 
// Загрузка данных в хранилище. Будет возвращена первая страница данных.
store.loadPage(1, {
    queryConfig: queryConfig,
    // Дополнительно указывается фильтрация возвращаемых данных по колонке Name.
    filters: Ext.create('Terrasoft.Filter', {
        // Имя колонки, по которой выполняется фильтрация.
        property: 'Name',
        // Значение для фильтрации.
        value: 'Test Name'
    }),
    // Функция обработки результатов выполнения запроса.
    callback: function(records, operation, success) {
        // Получение первой записи возвращенного набора.
        var loadedRecord = records[0];
        if (loadedRecord) {
            // Получение значения поля Account.
            var contactAccount = loadedRecord.get('Account');                                                                                                    
            if (contactAccount) {                                                                                                                   
                // Выполнение действий с полученным значением.
            }
        }
    },
    scope: this
});

Вот пример изменения и сохранения записи (но новой, а не существующей):

var record = Ext.create('Contact');
record.phantom = true;
//свойство модели phantom указывает на то, новая ли это запись или существующая
record.set('Name', 'New Contact');
 
record.save({
    success: function() {
        ...
    },
    failure: function(exception) {
        Terrasoft.MessageBox.showException(exception);
    },
    queryConfig: Ext.create('Terrasoft.QueryConfig', {
        modelName: record.self.modelName,
        columns: ['Name']
    }
}, this);

 

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

var store = Ext.create('Terrasoft.store.BaseStore', {

            model: 'SuInterviewAnswerChoice'

        });

        var queryConfig = Ext.create('Terrasoft.QueryConfig', {

            columns: ['SuInterviewQuestion', 'SuAnswer', 'SuIsChecked'],

            modelName: 'SuInterviewAnswerChoice'

        });

        

        store.loadPage(1, {

            queryConfig: queryConfig,

            filters: Ext.create('Terrasoft.Filter', {

                property: 'SuInterviewQuestion',

                value: multiAnswerId

            }),

            callback: function(records, operation, success) {

                for(var i =0; i<records.length;i++){

                    if(records[i].data.SuAnswer === answerVariantId){

                        var isChecked = records[i].get('SuIsChecked');

                        if(!isChecked){

                            records[i].set('SuIsChecked',true);

                            records[i].save({

                                success: function() {

                                    console.log('Successfully');

                                },

                                failure: function(exception) {

                                    Terrasoft.MessageBox.showException(exception);

                                },

                                queryConfig: Ext.create('Terrasoft.QueryConfig', {

                                    modelName: records[i].self.modelName,

                                    columns: ['SuIsChecked']

                                })

                            }, this);

                            return;

                        }

                    }

                    

                }

            },

            scope: this

        });

 

 

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

Зверев Александр,

да,меняет. Поле ModifiedOn меняется. Подскажите пожалуйста еще,как правильно написать Insert,спасибо!

Зверев Александр, Просто документации по мобилке в плане этого очень мало.обрываю исходники пишу по примерам +- но синхронизация так и не появляется.

Зверев Александр пишет:

Вот пример изменения и сохранения записи (но новой, а не существующей):


 
var record = Ext.create('Contact');
record.phantom = true;
//свойство модели phantom указывает на то, новая ли это запись или существующая
record.set('Name', 'New Contact');
 
record.save({
    success: function() {
        ...
    },
    failure: function(exception) {
        Terrasoft.MessageBox.showException(exception);
    },
    queryConfig: Ext.create('Terrasoft.QueryConfig', {
        modelName: record.self.modelName,
        columns: ['Name']
    }
}, this);

или я так понимаю вот это можно использовать вместо InsertBuilder?

 

Да, лучше вместо InsertBuilder использовать редактирование и сохранение записи.

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

Зверев Александр,

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

Зверев Александр пишет:

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

Вот пример фильтрации и перебора:


 
// Создание экземпляра хранилища для данных модели Contact.
var store = Ext.create('Terrasoft.store.BaseStore', {
    model: 'Contact'
});
 
// Создание конфигурационного объекта с дополнительными параметрами запроса на выборку данных.
var queryConfig = Ext.create('Terrasoft.QueryConfig', {
    // Определение колонок, которые будут возвращены в запросе.
    columns: ['Name', 'Id', 'Account'],
    // Имя модели, к которой выполняется запрос.
    modelName: 'Contact'
});
 
// Загрузка данных в хранилище. Будет возвращена первая страница данных.
store.loadPage(1, {
    queryConfig: queryConfig,
    // Дополнительно указывается фильтрация возвращаемых данных по колонке Name.
    filters: Ext.create('Terrasoft.Filter', {
        // Имя колонки, по которой выполняется фильтрация.
        property: 'Name',
        // Значение для фильтрации.
        value: 'Test Name'
    }),
    // Функция обработки результатов выполнения запроса.
    callback: function(records, operation, success) {
        // Получение первой записи возвращенного набора.
        var loadedRecord = records[0];
        if (loadedRecord) {
            // Получение значения поля Account.
            var contactAccount = loadedRecord.get('Account');                                                                                                    
            if (contactAccount) {                                                                                                                   
                // Выполнение действий с полученным значением.
            }
        }
    },
    scope: this
});

 

Работайте асинхронно, через callback.

Зверев Александр,

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

Основная логика bpm'online реализуется в веб-версии, мобильная имеет вспомогательное применение, её SDK не настолько подробен и не включает всех возможных сценариев. Если у Вас есть необходимость в какой-то логике, которую не реализовать иначе, можете завести идею, описать там подробно своё пожелание и, возможно, в новых версиях такое реализуют.

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

Всем доброго времени суток. Версия 7.12.

В своё время работал с настройкой мобильного приложения, в т.ч. с добавлением кастомных элементов на страницы. Вроде тогда всё работало (в 7.10 и эмуляторе приложения для 7.10) - https://community.terrasoft.ru/questions/dobavlenie-kastomnyh-elementov…

Хотелось бы ещё раз разобрать задачу замещения страниц и добавления своих элементов по пунктам.

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

Есть схема MobileContactPreviewPage, которая подключена в MobileApplicationManifestDefaultWorkplace у контакта в Models:

"Contact": {
			"Preview": "MobileContactPreviewPage",
			"RequiredModels": [
				"Account",
				"Contact",
				"ContactCommunication",
				"CommunicationType",
				"Department",
				"ContactAddress",
				"AddressType",
				"Country",
				"Region",
				"City",
				"ContactAnniversary",
				"AnniversaryType",
				"Activity",
				"SysImage",
				"FileType",
				"ActivityPriority",
				"ActivityType",
				"ActivityCategory",
				"ActivityStatus",
				"Job"
			],
			"ModelExtensions": [],
			"PagesExtensions": [
				"MobileContactRecordPageSettingsDefaultWorkplace",
				"MobileContactGridPageSettingsDefaultWorkplace",
				"MobileContactActionsSettingsDefaultWorkplace",
				"MobileContactModuleConfig"
			]
		}

Я заместил схему MobileContactPreviewPage, перенёс содержимое из оригинальной реализации полностью, добавил свою небольшую доработку-  просто добавление кнопки на страницу:

/* globals Contact: false */
Terrasoft.LastLoadedPageData = {
	controllerName: "ContactPreviewPage.Controller",
	viewXType: "contactpreviewpageview"
};
 
Ext.define("ContactPreviewPage.View", {
	extend: "Terrasoft.view.BasePreviewPage",
	xtype: "contactpreviewpageview",
	config: {
		id: "ContactPreviewPage"
	}
});
 
Ext.define("ContactPreviewPage.Controller", {
	extend: "Terrasoft.controller.BasePreviewPage",
 
	statics: {
		Model: Contact
	},
 
	config: {
		refs: {
			view: "#ContactPreviewPage"
		}
	},
 
	/**
	 * @inheritdoc
	 * @protected
	 * @overridden
	 */
	onCallPhoneStarted: function() {
		this.callParent(arguments);
		Terrasoft.PhoneCallLogUtils.openPage({
			activityLinkColumnNames: [
				{
					parentColumnName: "Id",
					activityColumnName: "Contact"
				},
				{
					parentColumnName: "Account",
					activityColumnName: "Account"
				}
			],
			record: this.record
		});
	},
 
	onLoadRecord: function(loadedRecord, callback) {
      this.callParent([loadedRecord, function() {
        Terrasoft.MessageBox.showMessage("onLoadRecord");
         var panelItems = this.getView().getPanel().getItems();
         var primaryColumnSet = panelItems.first();
 
		//Кнопка
		var controlbutton = this.getOurCustomButton(loadedRecord);
        controlbutton.on("tap", function () {
    		loadedRecord.set("UsrImgData","");
        }, this);
 
        primaryColumnSet.add(controlbutton); //если добавляем в конце панели
 
      }]);
    },
    getOurCustomButton: function(record) {
        return Ext.create('Ext.Button', {
              xtype: "button",
              cls: "x-button x-button-primary-blue",
              text: "Очистить"
            });
    },
 
});

 

Собственно, кнопки так и не появилось, сообщение showmessage тоже отсутствует. Версия приложения последняя, установил прямо с GooglePlay, проверяю всё непосредственно с телефона.

 

И ещё общий вопрос - что собственно, представляет собой приложение? Могу ли я туда выводить непосредственно html- или нативный javascript-код как в браузер? Будет ли при этом работать javascript-код на всех видах устройств?

Нравится

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

Добрый день, Денис!

А вы смотрели в dom дереве кнопка создалась? Может она есть, но просто не видна. Тогда придется поработать со стилями.

Приложение собой представляет одностраничное веб-приложение, т.е. html можно разве что в iframe'е попробовать вставить. А нативный JavaScript должен работать без проблем.

Золотарев Артем Андреевич,

Артём, спасибо за ответ.

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

html как-то добавляли в той теме по ссылке.

Ещё пробовал вместо MobileContactPreviewPage создавать свою версию с названием UsrMobileContactPreviewPage и аналогичным содержимым и подключать её на место оригинала в манифесте - тогда в приложении страница контакта вообще перестаёт открываться.

https://sun9-5.userapi.com/c830309/v830309684/143865/aieJi10t5ks.jpg (MobileContactPreviewPage)

https://sun9-7.userapi.com/c834401/v834401309/18b001/y7z3N8IY2FQ.jpg (UsrMobileContactPreviewPage)

Смородинов Денис,

тогда вам лучше обратиться в тех.поддержку, там по запросу предоставляют эмулятор и будет намного проще разрабатывать =)

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

Здравствуйте!

Интересует функционал проверки дублей в моб.приложении в объектах: "контакты", "контрагенты", "лиды".



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

Нравится

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

Роман, добрый день!

Если менеджеры работают в мобильном приложении в режиме "оффлайн", то поиск дублей отрабатывает после синхронизации: новые записи попадают в реестр записей в десктопе, реестр изменяется в соответствии с настроенными правилами поиска и удаления дублей (данный процесс можно автоматизировать - https://academy.terrasoft.ru/documents/studio/7-12/nastroyka-pravil-i-raspisaniya-poiska-dubley#XREF_31918), после выполнения поиска и объединения дублей, в результате повторной синхронизации реестр изменится.

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

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

Мне нужно, чтобы при выборе колонки в справочнике подгружались и ещё дополнительные значения по этой колонке. В основной версии я это могу сделать, перечислив нужные мне колонки в columns в lookupListConfig в настройке соответствующей справочной колонки в attributes. Как мне сделать аналогичное в мобильном приложении? Скажем, мне нужно в активности получить колонку Account.UsrParentAccount.UsrCode или что-то подобное.

Нравится

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

Добрый день!

Если необходимо отобразить дополнительную колонку в реестре, это можно сделать с помощью SDK реестра - https://academy.terrasoft.ru/documents/technic-sdkmob/7-12/sdk-reestra. Если задача другая, опишите, пожалуйста, ее подробнее, а также с какой целью необходимо ее реализовать.

Одеяненко Юлия,

Нет, это совсем не то.

Впрочем, сам уже разобрался. Делается это через sdk страницы, например так:

Terrasoft.sdk.RecordPage.addColumn("Activity", {
    name: "Account.UsrCode",
    hidden: true
}, "primaryColumnSet");

Тогда и нужная колонка будет подгружаться. Только если это доп. поле нужно на странице детали и зависит от родительской колонки, например, Activity.Account.UsrCode, то нужно добавлять колонку к родительскому объекту, чтобы получить доступ к нужной колонке при создании записи.

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

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

Нравится

5 комментариев

Здравствуйте!

Реестр справочника и так открывается если нажать на значение - http://prntscr.com/jixl4c

Как вариант можете реализовать пользовательское действие - https://www.dropbox.com/s/80xtv5f8ngqviru/%D0%9F%D0%BE%D0%BB%D1%8C%D0%B…

Вильшанский Дмитрий,

Мне нужно открывать справочник, не связанный со страницей, и перед этим ещё могут потребоваться доп. действия. Просто справочным полем не получится это реализовать.

Есть возможность поместить кнопку именно где-то посреди страницы? Дейсвтие для пользователя будет довольно неудобным. Или это принципиально невозможно?

Бершеда Д. Н.,

Можете посмотреть алгоритм реализации в похоже топике:

https://community.terrasoft.ru/questions/dobavlenie-kastomnyh-elementov-v-mobilnom-prilozenii

Если нужно открыть пикер для выбора значения, то посмотрите MobileActivityGridPageControllerV2. Там много пример открытия пикеров. Например, для выбора «Ответственного» (метод getEmployeePicker()

) или выбора режима расписания (метод getGridModePicker()).

Вильшанский Дмитрий,

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

Бершеда Д. Н.,

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

Используйте отладку для выяснения причины - https://academy.terrasoft.ru/documents/technic-sdkmob/7-12/otladka-mobi…

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

Добрый день. Возникла необходимость скрыть стандартную деталь на странице мобильного приложения. Есть ли возможность это реализовать?

Нравится

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

Добрый день. Вот тут предоставили хороший ответ: https://community.terrasoft.ru/questions/skrytie-standartnoi-detali-v-k…

Парамонов Роман,

благодарю. Всё получилось.

Здравствуйте! 



Один из вариантов реализации этой задачи - перекрыть в контроллерах страниц метод onBusinessRuleExecuted, который отрабатывает после выполнения бизнес-правил и в котором можно найти нужный элемент у panel-а и скрыть\показать его.

Ext.define("CustomUsrHaulPreviewPage.Controller", {

    override: "UsrHaulPreviewPage.Controller",

 

    onBusinessRuleExecuted: function(record, rule, ruleResult) {

        this.callParent(arguments);

        var view = this.getView();

        var panel = view.getPanel();

        var type = record.get("UsrDriverCheckType");

        var isNeededType = (type && type.getId() === "079acedd-585f-4a0e-aff0-eb419ec09925");

        var panelItems = panel.getItems();

        for (var i = 0, ln = panelItems.getCount(); i < ln; i++) {

            var item = panelItems.items[i];

            if (item instanceof Terrasoft.ViewEmbeddedDetail &&

                    item.getName() === "UsrSchema11DetailEmbeddedDetail") {

                var isItemHidden = item.getHidden();

                if (type && isNeededType) {

                    if (!isItemHidden) {

                        item.setHidden(true);

                    }

                } else if (type) {

                    if (isItemHidden) {

                        item.setHidden(false);

                    }

                }

            }

        }

    }

 

});

Ext.define("CustomUsrHaulEditPage.Controller", {

    override: "UsrHaulEditPage.Controller",

 

    onBusinessRuleExecuted: function(record, rule, ruleResult) {

        this.callParent(arguments);

        var view = this.getView();

        var panel = view.getPanel();

        var type = record.get("UsrDriverCheckType");

        var isNeededType = (type && type.getId() === "079acedd-585f-4a0e-aff0-eb419ec09925");

        var panelItems = panel.getItems();

        for (var i = 0, ln = panelItems.getCount(); i < ln; i++) {

            var item = panelItems.items[i];

            if (item instanceof Terrasoft.EditEmbeddedDetail &&

                    item.getName() === "UsrSchema11DetailEmbeddedDetail") {

                var isItemHidden = item.getHidden();

                if (type && isNeededType) {

                    if (!isItemHidden) {

                        item.setHidden(true);

                    }

                } else if (type) {

                    if (isItemHidden) {

                        item.setHidden(false);

                    }

                }

            }

        }

    }

 

});

Либо же 

Создаем новую схему UsrMobileAccountPreviewPage (с типом «Модуль»)

/* globals Account: false */

Terrasoft.LastLoadedPageData = {

&nbsp;&nbsp;&nbsp;&nbsp;controllerName:&nbsp;"UsrAccountPreviewPage.Controller",

&nbsp;&nbsp;&nbsp;&nbsp;viewXType:&nbsp;"usractivitypreviewpageview"

};

Ext.define("UsrAccountPreviewPage.View", {

&nbsp;&nbsp;&nbsp;&nbsp;extend:&nbsp;"AccountPreviewPage.View",

&nbsp;&nbsp;&nbsp;&nbsp;xtype:&nbsp;"usractivitypreviewpageview",

&nbsp;&nbsp;&nbsp;&nbsp;config: {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id:&nbsp;"AccountPreviewPage"

&nbsp;&nbsp;&nbsp;&nbsp;},

&nbsp;&nbsp;&nbsp;&nbsp;/**

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @inheritdoc

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @protected

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @overridden

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/

&nbsp;&nbsp;&nbsp;&nbsp;shouldHidePanelItem:&nbsp;function(loadedRecord, component) {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var detailName = component.config.name;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (detailName ===&nbsp;"ActivityDetailV2StandartDetail") {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var categoryId = loadedRecord.get("AccountCategory.Id");

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return categoryId !== Terrasoft.Configuration.AccountCategory.DoctorVisit;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.callParent(arguments);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;}

});

Ext.define("UsrAccountPreviewPage.Controller", {

&nbsp;&nbsp;&nbsp;&nbsp;extend:&nbsp;"AccountPreviewPage.Controller",

&nbsp;&nbsp;&nbsp;&nbsp;statics: {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Model: Account

&nbsp;&nbsp;&nbsp;&nbsp;},

&nbsp;&nbsp;&nbsp;&nbsp;config: {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;refs: {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;view:&nbsp;"#AccountPreviewPage"

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;}

});

Прописываем ее в манифесте

"Models": {

&nbsp;&nbsp;&nbsp;&nbsp;"Account": {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Preview":&nbsp;"UsrMobileAccountPreviewPage",

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...

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

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

Нравится

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

Здравствуйте! 

В базовой версии предусмотрена работа только с цифровыми, дробными и булевскими полями. Ниже базовый метод схемы EditListItem: 

createEditComponentByColumnName: function(columnName) {

        var model = this.getModel();

        var columnConfig = model.ColumnConfigs.get(columnName);

        var config = {

            name: columnName,

            markerValue: columnName

        };

        switch (columnConfig.columnType) {

            case Terrasoft.ColumnTypes.number:

                config.xtype = "tsintegerfield";

                break;

            case Terrasoft.ColumnTypes.decimal:

                config.xtype = "tsfloatfield";

                break;

            case Terrasoft.ColumnTypes.bool:

                config.xtype = "tstoggle";

                break;

            default:

                return null;

        }

        return this.createFieldComponent(config);

    },

 

Мы зафиксируем Ваше пожелание для рассмотрения аналитиками продукта.

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