Вопрос

В клиентской схеме редактирования добавлен модуль. В схеме модуля есть метод, который необходимо заместить. Каким образом это можно реализовать?

У меня такой же вопрос

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

Вы можете по аналогии с существующим модулем реализовать свой клиентской модуль с нужным методом.

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

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день.
Есть Данные, хранящиеся в json-строке
Есть Объект, со структурой полей соответствующей Данным в json.
Есть Модуль с DataGrid, в котором нужно отобразить реестр записей.
Наполняю коллекцию GridData: 
 

prepareDataGridViewModule: function(dataList){
    //Наполнить GridData
    var gridData = this.get("GridData");
    var entityConfig = this.getEntityConfig(this.$MasterEntityName);
    this.Terrasoft.each(dataList, function(item) {
        var itemData = Ext.JSON.decode(item.Data);
        var itemModel = this.Ext.create("Terrasoft.BaseViewModel", {
              columns: entityConfig.columns, //Коллекция полей Объекта
              values: itemData   //Коллекция значений полей
         });
         gridData.add(item.Id, itemModel);
      }, this);
}

В итоге получаю отображение: 
https://yadi.sk/i/XUkp2kMCWWB4KQ

Кто сталкивался?
Как можно наполнить плиточное представление реестра в каждой строке своими динамическими полями?

У меня такой же вопрос

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

Игорь, добрый день!

Вы можете разработать формирование всей информации на уровне базы данных в представление, по которому в конфигурации создан объект. Как работать с JSON в MS SQL, описано в этой статье.

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

Игорь, эта логика самостоятельно разработана Вами, поэтому причину такого её поведения можете установить только Вы, например, применив отладку. 

Перефразирую:
В каком виде я должен передать свою коллекцию значений и полей в GridData, чтобы Базовыми средствами отрисовать поля реестра?

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

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

Я и нашёл. в LocalDuplicateSearchPageV2 и его миксине DuplicatesSearchUtilitiesV2, где в методе loadElasticDuplicates в модель реестра передаются поля (columns) и значения (values).
В итоге в реестре глобального поиска строки реестра отображаются корректно с набором полей и значений, а в моём модуле в строках полоски.

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

Ошибок нет. я бы с удовольствием протестировал.
Только не могу понять какой метод обрабатывает передаваемую коллекцию и отрисовывает реестр.

Произведите отладку Вашего кода и работающего на странице дублей. Также Вы можете заказать такие доработки у компаний-партнёров.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Ошибка при сохранении клиентской схемы: Ошибка сохранения: Элемент <Название модуля> не найден.

Данное поведение встречается на версии 7.14.3

1.При создании нового модуля/миксина
2. При переименовании клиентской схемы (детали) после создания мастером деталей

 

У меня такой же вопрос

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

Здравствуйте! Попробуйте сгенерировать коды для данного модуля и скомпилировать сборку затем перелогинится в системе с очисткой кэша в браузера. Мне такие действия помогали. Если локально система развернута, помогало еще перезапуск пула в IIS.

Помогла фиксация в SVN с последующим восстановлением из хранилища.
Но что-то мне подсказывает, что это не совсем корректное поведение. И появилось оно на версии 7.14.3

Добрый день, Игорь.

Для временного устранения надо в Web.config загрузчика, выключить фичу Feature-OptimizeManagersSynchronization = false и после переименования сохранять два раза.
При первом сохранении сообщение будет появляться, после второго ошибки не будет, а схема будет сохранена.
В новых версиях будет предоставлено решение такого поведения системы.

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

Коновалов Игорь,

Коновалов Игорь пишет:
И появилось оно на версии 7.14.3

Замечала и на версии 7.14.2, а вот раньше такого не помню. 

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Привет всем !
Возник такой вопрос, как сделать модальное окно с нужными полями и чекбоксами ?
нужно что то вроде:
Ответственному - (Логический тип), Время - (Дата/Время) 

Нашёл различные статьи, но там написано как сделать просто окно или вообще что то другое или вообще не чего, вообщем всё не то.
Я так понимаю нужно сделать что то вроде ModalBox после чего передать параметры поля размер и т.д . Но как это сделать не знаю.
Если кто знает подскажите.

У меня такой же вопрос

3 комментария
Лучший ответ

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

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

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

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

Григорий Чех,

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

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

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

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

У меня такой же вопрос

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

День добрый! 

Скрипт по апдейту значений из продукта в заказе продуктов в счете (через график поставок и оплат) лежит в схеме OrderAmountHelper.

Удачи!

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день, коллеги!
Помогите решить следующую задачу:

bpm'online 7.5
Мне нужно создать модуль, который будет являть собой страницу с таблицей. Таблицу необходимо заполнить данными, сгенерированными в том же модуле (например, статично заданные демо-данные; в дальнейшем будет выполняться запрос к веб-сервису для получения данных).
На странице, например, контрагента я создам вкладку, и в эту вкладку мне нужно загрузить этот модуль с таблицей.

У меня такой же вопрос

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

Здравствуйте, Евгений!
В целом Вам необходимо создать модуль, расширяющий BaseSchemaModuleV2, в который будет загружаться страница с содержимым. Затем загрузить этот модуль в контейнер. Пример модуля:

define("ModuleName", ["BaseSchemaModuleV2"], function() {
 
	Ext.define("Terrasoft.configuration.ModuleName", {
		alternateClassName: "Terrasoft.ModuleName",
		extend: "Terrasoft.BaseSchemaModule",
 
		/**
		 * Инициализирует название схемы.
		 * @protected
		 * @overridden
		 */
		initSchemaName: function() {
			this.schemaName = "PageName";
		},
 
 
		/**
		 * Заменяет последний элемент в цепочке состояний, если его идентификатор модуля отличается от текущего.
		 * @protected
		 * @overridden
		 */
		initHistoryState: Ext.emptyFn
 
	});
	return Terrasoft.ModuleName;
});

На странице "PageName" необходимо реализовать отображение таблицы.
Загружать модуль в контейнер можно следующим образом:

var schemaName = "PageName";
var pageId = this.sandbox.id + schemaName;
this.showBodyMask();
this.sandbox.loadModule("ModuleName", {
	renderTo: "ModuleNameContainer", //Id контейнера
	id: pageId,
	keepAlive: true
});

Андрей, спасибо за ответ. К сожалению, с указанным способом возникли затруднения, и я реализовал модуль по-другому:

q1

define("VisualModule", ["VisualModuleResources", "ViewUtilities", "ServiceHelper", "BaseModule", "ContainerList", "css!VisualModule"],
    function(resources, ViewUtilities, ServiceHelper) {
        Ext.define("Terrasoft.configuration.VisualModule", {
            alternateClassName: "Terrasoft.VisualModule",
            extend: "Terrasoft.BaseModule",
 
            Ext: null,
            sandbox: null,
            Terrasoft: null,
 
            getContainer: function() {
                var itemsContainer = ViewUtilities.getContainerConfig("itemsContainer",
                    ["items-container-class"]);
                itemsContainer.items.push({
                    className: "Terrasoft.Button",
                    style: Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                    classes: {textClass: ["cancel-all-class"]},
                    caption: "AddToCollection",
                    click: {bindTo: "onButtonClick"}
                });
                itemsContainer.items.push({
                    className: "Terrasoft.ContainerList",
                    id: "CON1",
                    idProperty: "Id",
                    selectors: {wrapEl: "#CON1"},
                    collection: {bindTo: "itemsCollection"},
                    defaultItemConfig: this.getItemConfig()
                });
                return itemsContainer;
            },
            getItemConfig: function() {
                var itemConfig;
                itemConfig = ViewUtilities.getContainerConfig("ItemContainer",
                    ["item-container"]);
                var itemTopContainer = ViewUtilities.getContainerConfig("itemTopContainer",
                    ["item-top-container"]);
 
                itemTopContainer.items.push({
                    className: "Terrasoft.Label",
                    caption: {bindTo: "displayValue"},
                    classes: {labelClass: ["button-caption-labelClass"]}
                });
                itemConfig.items.push(itemTopContainer);
 
                return itemConfig;
            },
            getView: function() {
                var viewItems = [];
                var textEdit = {
                    className: "Terrasoft.TextEdit",
                    width: 100,
                    value: {"bindTo": "textValue"}
                };
                var bindedContainer = this.getContainer();
 
                viewItems.push(textEdit);
                viewItems.push(bindedContainer);
 
                return this.Ext.create("Terrasoft.Container", {
                    id: "mainContainer",
                    selectors: {wrapEl: "#mainContainer"},
                    classes: {wrapClassName: ["main-container-style"]},
                    items: viewItems
                });
            },
 
            getViewModel: function() {
                var scope = this;
                var sandbox = scope.sandbox;
                var Terrasoft = scope.Terrasoft;
                var viewModel = Ext.create("Terrasoft.BaseViewModel", {
                    values: {
                        textValue: "Some text",
                        itemsCollection: new Terrasoft.Collection()
                    },
                    methods: {
                        onButtonClick: function(){
                            var collection = this.get("itemsCollection");
                            var item = { value: "Id1", displayValue: "Name1"};
                            this.decorateItem(item)
                            collection.add(this.newGuid(), item);
 
                        },
                        decorateItem: function(item) {
                            item.sandbox = sandbox;
                            item.Terrasoft = Terrasoft;
                        },
                        newGuid: function() {
                            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
                                function(c) {
                                    var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
                                    return v.toString(16); })
                        }
                    }
                });
                viewModel.Ext = this.Ext;
                viewModel.Terrasoft = this.Terrasoft;
                viewModel.sandbox = this.sandbox;
                return viewModel;
            },
 
            render: function(renderTo) {
                var view = this.getView();
                var viewModel = this.getViewModel();
                view.bind(viewModel);
                view.render(renderTo);
            }
        });
        return Terrasoft.VisualModule
    });

Загружаю модуль так:

var schemaName = "PageName";
var pageId = this.sandbox.id + schemaName;
this.sandbox.loadModule("VisualModule", {
renderTo: "SmrMediaplanPage6Tab", //Id контейнера
id: pageId,
keepAlive: true
});

На страницу успешно загружается модуль, и даже текстовое поле получает привязку:
2

В коде добавлен контейнер типа Terrasoft.ContainerList, и сделана привязка к коллекции itemsCollection из ViewModel (itemsCollection: new Terrasoft.Collection())

При попытке добавить элемент в эту коллекцию:

var collection = this.get("itemsCollection");
var item = { value: "Id1", displayValue: "Name1"};
this.decorateItem(item)
collection.add(this.newGuid(), item);

происходит ошибка в ContainerList.js:
не видит метода get()

123

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

Как правильно забиндить ContainerList?

День добрый!
Так а откуда в Вашем item должен появиться метод get?
По идее, item должен быть экземпляром класса Terrasoft.BaseViewModel, а у Вас - это просто объект, в который добавлены несколько свойств.
Попробуйте так:

var item = this.Ext.create("Terrasoft.BaseViewModel", {
	values: {
		Id: "Id1",
		Name: "Name1"
	}
});

И еще проверьте, есть ли значение в this.idProperty. Там должна быть строка с названием колонки-идентификатора.
Вместо вот этого страха:

newGuid: function() {
                            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
                                function(c) {
                                    var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
                                    return v.toString(16); })
                        }

Можно использовать метод Terrasoft.generateGUID().

Андрей, спасибо, это то, что нужно! :)
Сделал item как Terrasoft.BaseViewModel, и всё получилось.

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

А знаете ли вы, уважаемые любители быстро перенести готовый стандартный модуль из одной системы в другую в замечательный модуль Custom, что теперь такая возможность у вас пропала?
Не будем говорить о переносе Проектов, Документов и прочая в Sales, так как это нехорошо:cool:, и необходимость в таком разделе должна толкать покупателя к приобретению более дорогого продукта, а не стимулировать программистов к работе.

А приведем пример законопослушный вполне - берем у клиента старенький Terrasoft 3.2.1 x25, в котором был модуль "Склад" - простенький совсем по нынешним меркам, но все же был и использовался. И попробуем перевести такого клиента на 3.4 XRM, в котором склада понятное дело нету. Ну нету и нету, наше дело сервисы выгрузить да в Custom залить, вот он и появится - но не тут то было. Уже при попытке сохранения сервиса таблицы tbl_OfferingMovement всякого хитреца ждет сообщение, что "Service 'tbl_OfferingMovement' must be located only in the module 'OfferingMovement'".
В итоге запрос не запустится, и так далее... Путь решения в общем-то простой, но требует усидчивости и внимательности - переименовываем таблицу в tbl_BestOfferingMovement:smile: и затем все упоминания, связи... в итоге получаем загруженный работающий модуль.
Или об этой особенности не знал только я? :wink:

Поделиться

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

Кстати в нелегком труде переименования поможет прекрасная бесплатная утилита от http://tr.infortech.ru/ под названием @Text Replacer.
Выгружаем все сервисы несчастного модуля в XML в некоторую папку, и запускаем @Text Replacer, говорим ему название этой папки и запускаем автоматическую замену по содержимому XML, например "Movement" на "BestMovement".
В этом случае поменяется и USI, и названия таблицы, и запросы подправятся, и так далее... останется только загрузить все сервисы обратно и скрипты поправить - уже в Администраторе, поиском/заменой "Movement" на "BestMovement" штатными средствами. Так будут исправлены названия обработчиков событий, переменные, названия сервисов, упомянутых в скриптах.

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

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

Данная библиотека использует для полученного документа стандартную закладку "файлы". При этом для добавления сканирования Вам будет необходимо добавить всего одну строку кода!

Например:
function btnScanOnClick(Control) {
Scan('iq_FileInDocument', 'DocumentID', dlData.Dataset.Values('ID'));
}

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

Поделиться

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

Как можно получить эту библиотеку?

Приложил библиотеку к сообщению в блоге. Также информация по сканированию (альтернативный вариант) доступна по ссылке: http://community.terrasoft.ua/node/2324

Горелов Виталий
Компания Лабитек

Виталий,
а библиотека от Лабитек потдерживает какие-то определённые сканеры?
Просто хотелось бы определится с выбором (Лабитек или WIA).
В компании три сканера, два новеньких самсунга и один древненький МФУ XEROХ...
--------------------
UPDATE:
В первом посте вложена версия для X15
Покопавшись немного выкладываю адаптированный сервис под 3.3.х

Позволю себе ответить за Виталия - библиотека использует TWAIN, а со сканерами обычно ставится драйвер поддержки, скорее всего и для древненького есть :) В общем пробуйте.
--------------------------------------------
Лабитек
Центр разработки приложений

2Валерий, спасибо большое)
Уже разобрался когда копался с переделкой...
---
Конфигурация:
TSCRM 3.3.1.59
Firebird 2.0 (v.2.0.3.12981)
ClientOS: Vista Home Premium
ServerOS: Windows 2003 Server

А, извиняюсь, не сообразил :)
--------------------------------------------
Лабитек
Центр разработки приложений

Войдите или зарегистрируйтесь, чтобы комментировать