Уважаемые, форумчане.
Работаю в версии 7.8. Столкнулся со следующей проблемой: не могу создать шестое рабочее пространство. Ошибка вываливается: "Достигнуто максимальное количество конфигураций 5". Можно ли как-то увеличить лимит?

Нравится

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

Установите системной настройке [Максимальное количество рабочих пространств пользователя] (MaxWorkspaceCount) необходимое Вам значение

Спасибо

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

Доброго времени суток.

Версия 7.8 sales.

Есть стандартная деталь с реестром, добавлена на странице, вот такая, например: https://academy.terrasoft.ru/documents/technic-sdk/7-8/sozdanie-detali-s...

Возможно уже обсуждалось, не нашёл - можно ли для некоторых колонок задать свой цвет?

Нравится

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

Денис, здесь есть некоторая информация - http://www.community.terrasoft.ru/forum/topic/12359
А так просто не получиться, для всей записи в гриде детали –пожалуйста. А для конкретных колонок по умолчанию такого не предусмотрено, только с помощью «магии».
Например, можно написать CSS стиль на какую-то по счету колонку в реестре и запретить редактировать настройку колонок этой детали.

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

Здраствуйте
У меня есть деталь. Можно как то добавлять динамически колонки в деталь(чтобы эти колонки не были привязаные к таблице самой детали)?

Нравится

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

Здравствуйте, Дмитрий.

Для реализации данного функционала Вам необходимо смотреть в сторону замещения метода loadGridData из схемы GridUtilitiesV2 (или одного из вызываемых в нем методов). В данном методе и происходит подгрузка данных в деталь на основании фильтров, настроек детали и отображаемых колонок.

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

"Владимир Соколов" написал:

А можно подсказать, где реализована похожая функциональность?

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

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

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

Здравствуйте.
У меня такой вопрос: можно ли сделать кастомную страницу для отображения данных таблицы в виде реестра? Я попробовал использовать преднастроенную страницу в БП, но ничего у меня не вышло.

Нравится

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

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

"Мотков Илья" написал:

Виталий, опишите, пожалуйста, бизнес-задачу.

Так как по описанию не совсем понятно, что вы пытаетесь реализовать.


Здравствуйте. У меня в БП по определенным параметрам делается поиск контрагентов и результат заносится в новый объект. И вот, после поиска нужно отобразить этот результат в виде реестра (только отобразить, т.е. с этими данными ничего сделать нельзя).

Прилагаю также скриншот БП:

В пробовал работать с элементом "Преднастроенная страница 1", но ничего не вышло.

Здравствуйте, Виталий.

Для решения данной задачи вам стоит смотреть в сторону использования контрола Terrasoft.Grid. Пример его добавления и использования есть в схеме BaseSectionV2 (NUI), эелемент DataGrid (он и отвечает за реестр записей в разделе). Особое внимание обратите на миксин GridUtilitiesV2, т.к. он содержит основные методы для работы с данным контролом.

Так же, как вариант, вы можете динамически генерировать разметку основываясь на коллекции данных используя HTML тэги и ExtJs.

Так же обратите внимание, что базовая Пред настроенная страница не наследует ту же иерархию что и схемы редактирования карточек.

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

Здравствуйте, коллеги.

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

Кейс такой:
Есть отрендеренный контейнер через  Ext.create("Terrasoft.Container", _viewConfig) . Как в отрендеренный контейнер добавить еще контейнеры?

Нравится

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

Код вот такой.

createBody: function() {
      createBody: function() {
      var _model = {
       values: {},
       columns: {},
       methods: {
 
        init: function() {
         this.set("_id", Terrasoft.generateGUID());
         this.set("_items", []);
         this.set("_rows", new Terrasoft.Collection());
         this.setRendered(false);
        },
 
        setConfig: function(config) {
         this.set("_config", config || []);
        },
 
        getConfig: function() {
         return (this.get("_config"));
        },
 
        setRendered: function(f) {
         this.set("_isRendered", f);
        },
 
        isRendered: function() {
         return (this.get("_isRendered"));
        },
 
        getId: function() {
         return (this.get("_id"));
        },
 
        /**
         * @returns {Terrasoft.Collection}
         */
        getRowConfig: function() {
         var _items = new Terrasoft.Collection(),
          _config = this.getConfig();
         _config.forEach(function(confItem) {
          var _item = {
           name: confItem.name,
           dataValueType: confItem.dataValueType,
           caption: (Terrasoft.isUndefined(confItem.caption) ? "[N/D]" : confItem.caption),
           isRequired: (Terrasoft.isUndefined(confItem.isRequired) ? false : confItem.isRequired),
           visible: (Terrasoft.isUndefined(confItem.visible) ? true : confItem.visible)
          };
          if (confItem.hasOwnProperty("isLookup")) {
           _item.isLookup =  confItem.isLookup;
          }
          if (confItem.hasOwnProperty("referenceSchema")) {
           _item.referenceSchema =  confItem.referenceSchema;
          }
          if (confItem.hasOwnProperty("defaultValue")) {
           _item.defaultValue =  confItem.defaultValue;
          }
          _items.add(confItem.name, _item);
         });
         return (_items);
        },
 
        /**
         *
         * @returns {Terrasoft.Collection}
         */
        getRows: function() {
         return (this.get("_rows"));
        },
 
        getRowsViews: function() {
         var _items = [];
         this.getRows().each(function(row) {
          if (!row.isRendered()) {
           row.render();
          }
          _items.push(row.getView());
         });
         return (_items);
        },
 
        getView: function() {
         return (this.get("_container"));
        },
 
        getViewConfig2: function() {
         var _config = this.getViewConfig();
         _config.items = this.getRowsViews();
         return(_config);
 
        },
 
        getViewConfig: function() {
         var _id = "TableBody_" + this.getId();
         return ({
          id: _id,
          selectors: { wrapEl: "#" + _id },
          classes: {wrapClassName: ["im-table-body"]},
          items: this.get("_items")
         });
        },
 
        render: function() {
         var _container = null;
         if (!this.isRendered()) {
          this.set("_items", this.getRowsViews());
          var _viewConfig = this.getViewConfig();
          _container = Ext.create("Terrasoft.Container", _viewConfig);
          this.setRendered(true);
         }
         this.set("_container", _container);
        },
 
        reRender: function() {
         if (this.isRendered()) {
          this.set("_items", this.getRowsViews());
          this.getView().reRender();
         }
        },
 
        createRow: function() {
         var _config = this.getRowConfig().getItems();
         var _model = {
          values: {},
          columns: {},
          methods: {
 
           init: function(id) {
            id = id || Terrasoft.generateGUID();
            this.set("_id", id);
            this.set("_items", []);
            this.setConfig(_config);
            this.setEditMode(false);
            this.setRendered(false);
           },
 
           getId: function() {
            return (this.get("_id"));
           },
 
           setConfig: function(config) {
            this.set("_config", config);
           },
 
           getConfig: function() {
            return (this.get("_config"));
           },
 
           setEditMode: function(f) {
            this.set("_isEditMode", f);
           },
 
           isEditMode: function() {
            return (this.get("_isEditMode"));
           },
 
           setRendered: function(f) {
            this.set("_isRendered", f);
           },
 
           isRendered: function() {
            return (this.get("_isRendered"));
           },
 
           getData: function() {
 
           },
 
           getView: function() {
            return (this.get("_container"));
           },
 
           getViewConfig: function() {
            var _id = "TableRow_" + this.getId();
            return ({
             id: _id,
             selectors: { wrapEl: "#" + _id },
             classes: {wrapClassName: ["im-table-header"]},
             items: this.get("_items")
            });
           },
 
           getColumnModel: function(config) {
            var itemDataValueType = config.dataValueType;
            var itemName = config.name;
            var itemId = "Row" + this.getId() + "_" + itemName;
            var controlConfig = {};
            switch (itemDataValueType) {
             case Terrasoft.DataValueType.TEXT:
              controlConfig = {
               id: itemId + "Label",
               className: "Terrasoft.Label",
               caption: {bidTo: itemName},
               isRequired: config.isRequired
              };
              break;
            }
            return controlConfig;
           },
 
           getRowConfig: function() {
            var _config = this.getConfig(),
             _items = new Terrasoft.Collection();
            _config.forEach(function(confItem) {
             _items.add(this.getColumnModel(confItem));
            }, this);
            return (_items);
           },
 
           render: function() {
            var _container = null;
            if (!this.isRendered()) {
             this.set("_items", this.getRowConfig().getItems());
             var _viewConfig = this.getViewConfig();
             _container = Ext.create("Terrasoft.Container", _viewConfig);
             this.setRendered(true);
            }
            this.set("_container", _container);
           },
 
           reRender: function() {
            if (this.isRendered()) {
             this.set("_items", this.getRowConfig().getItems());
             this.getView().reRender();
            }
           }
          }
         };
 
         _config.forEach(function(confItem) {
          var _name = confItem.name,
           _column = {
            dataValueType: confItem.dataValueType,
            caption: confItem.caption,
            isRequired: confItem.isRequired,
            type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
           },
           _value = confItem.defaultValue || null;
          if (confItem.dataValueType === Terrasoft.DataValueType.LOOKUP) {
           _column.isLookup = confItem.isLookup || false;
           _column.referenceSchemaName = confItem.referenceSchemaName;
           _model.values[_name + "List"] = new Terrasoft.Collection();
          }
          _model.values[_name] = _value;
          _model.columns[_name] = _column;
         });
         var _rowViewModel = Ext.create("Terrasoft.BaseViewModel", _model);
         _rowViewModel.Ext = Ext;
         _rowViewModel.sandbox = sandbox;
         _rowViewModel.Terrasoft = Terrasoft;
         return _rowViewModel;
        },
 
        addRow: function(collection) {
         if (collection.getCount() > 0) {
          var _id = Terrasoft.generateGUID(),
           _row = this.createRow();
          _row.init(_id);
          _row.set("Id", _id);
          collection.eachKey(function(key, val) {
           _row.set(key, val);
          });
          this.getRows().add(_row);
          this.reRender();
         }
        }
       }
      };
 
      var _bodyViewModel = Ext.create("Terrasoft.BaseViewModel", _model);
      _bodyViewModel.Ext = Ext;
      _bodyViewModel.sandbox = sandbox;
      _bodyViewModel.Terrasoft = Terrasoft;
      return _bodyViewModel;
     }

Здравствуйте.
Какая версия приложения?

Извините, Илья, что так долго.
1. версия 7.7
2. "разрулил" вопрос через JQuery

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

Доброго времени суток.

Версия 7.8 sales.

Вопросы такие - в некоторый объект можно импортировать данные через Excel файл. Допустим, в нашем случае на странице Продаже создана деталь "Коммерческое предложение в продаже", с некоторыми колонками. В числе колонок есть и привязка к конкретной продаже (колонка типа справочник - см. скрин).

1. Возможно ли указать в файле Excel специальную колонку, обозначающую привязку к конкретной продаже. Может быть, указать там id продажи? Проще говоря, нужно, чтобы после импорта файла на конкретной продаже в детали автоматически показывались только те записи, которые относятся именно к этой продаже.

2. Начиная с какой версии идёт поддержка Excel? Допустим, файл сделанный в 2003 будет ли работать?

Нравится

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

1. В «продаже» есть первичное поле для отображения, в нём указан её номер или код. Вот его и можно указать в Excel-файле с данными с детали как поле для привязки к продаже.
2. Работает только с xlsx-файлами. 2003 так сохранять не умеет.

"Зверев Александр" написал:1. В «продаже» есть первичное поле для отображения, в нём указан её номер или код. Вот его и можно указать в Excel-файле с данными с детали как поле для привязки к продаже.

Первичное поле - это колонка id, как я понимаю? Т.е. в Excel файле нужно будет создать специальную колонку, где будет указан id продажи, вида 1a860305-e9c3-4f28-a4d6-05a07828f9fa ?

Нет, в любом разделе есть первичное поле для отображения. Для контакта это ФИО, для контрагента — название.

Александр, но ведь по идее могут быть разные продажи с одинаковым названием, так же как и контакты с одинаковым ФИО и т.д.

Уникальным ведь является только id.

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

Фактически система сравнивает значение из файла Excel со значением первичного для отображения поля объекта. Для объекта "продажа" по умолчанию первичное для отображения поле - "Название".

Для решения необходимо:
1) Создать поле с типом "Строка 50 символов"
2) Реализовать логику, которая будет переносить значение поля Id в созданное поле для новых записей, а также реализовать перенос для существующих записей
3) В расширенных свойствах объекта "Продажа" изменить первичное для отображения поле
4) Импортировать записи

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

Дорый день!

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

Нравится

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

Есть такой пример:


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

Добавить запись в таблицу DuplicateRule:

INSERT INTO DuplicatesRule
 
(Name,
 
IsActive,
 
ObjectId)
 
VALUES
 
('Account duplicates. Account name',
 
'1',
 
'25D7C1AB-1DE0-4501-B402-02E0E5A72D6E')

1

2. Изменить хранимую процедуру tsp_FindAccountDuplicate (если правило поиска дублей для контакта, то менять tsp_FindContactDuplicate)(во вложении находится пример измененной хранимой процедуры tsp_FindAccountDuplicate):
Объявить правило AccountName, указать Id с таблици DuplicatesRule:
2

Добавить описание работы правила AccountName:
3

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

Есть такой пример:

Цитата:

Добавление правила поиска Контрагентов по названию

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

Добавить запись в таблицу DuplicateRule:

INSERT INTO DuplicatesRule



(Name,



IsActive,



ObjectId)



VALUES



('Account duplicates. Account name',



'1',



'25D7C1AB-1DE0-4501-B402-02E0E5A72D6E')

1

2. Изменить хранимую процедуру tsp_FindAccountDuplicate (если правило поиска дублей для контакта, то менять tsp_FindContactDuplicate)(во вложении находится пример измененной хранимой процедуры tsp_FindAccountDuplicate):

Объявить правило AccountName, указать Id с таблици DuplicatesRule:

2

Добавить описание работы правила AccountName:

3

Прикрепленный файлРазмер

1.png
32.16 кб

2.png
46.68 кб

3.png
135.54 кб

tsp_findaccountduplicate.zip
2.45 кб


Спасибо! А это будет работать при добавлении новой записи контрагента?

Это 2 разных механизма, глобальный и локальный поиск. Эти правила — только для глобального. А для локального:


Поиск дублирующихся записей при сохранении страницы контрагента или контакта (локальный поиск дублей) производится по следующим полям:

•При сохранении нового контрагента — по полям [Название], [Альтернативное название] и детали [Средства связи].
•При сохранении нового контакта — по полям [ФИО], [Мобильный телефон], [Домашний телефон], [Skype], [Email].

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

Это 2 разных механизма, глобальный и локальный поиск. Эти правила — только для глобального. А для локального:

Цитата:

Поиск дублирующихся записей при сохранении страницы контрагента или контакта (локальный поиск дублей) производится по следующим полям:

•При сохранении нового контрагента — по полям [Название], [Альтернативное название] и детали [Средства связи].

•При сохранении нового контакта — по полям [ФИО], [Мобильный телефон], [Домашний телефон], [Skype], [Email].

А не подскажете, как при локальном поиске добавить еще свое поле?

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

Здравствуйте! Я на 3.x делаю доработки по дублям, процедуру я поменяла, в верхней таблице списка дубликатов сам список дублей хорошо отображается, изменила отображение деталей (фильтры не по равенству, а на включение (содержит ..)). Единственное что не получается - пересчитать количество дублей в верхней таблице. Буду благодарна советам ) спасибо!

Здравствуйте, Светлана!

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

Это окно в конфигурации называется wnd_ViewSearchResult.

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

Светлана, в этой теме обсуждается работа с дублями в 7.Х, она полностью отличается от того, что было в 3.4. Попробуйте задать свой вопрос в нужной ветке, подробно описав со скриншотами и листингами, где и что Вы меняете, что хотите получить, как работает сейчас и что в этом не устраивает.

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

В БП в элементе "Страница редактирования" в блоке "считать элемент выполненным" стоят условия - поле с датой не равно этому же полю из элемента "Читать данные" в начале БП. По сути условие - должна быть изменена дата. При сохранении карточки в журнале выдает ошибку "Неправильный синтаксис около конструкции ">"". Если извлечь из элемента текст запроса, то после ">" ничего нет. При сравнении даты с параметром - тоже самое.

Нравится

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

В версии 7.8.0 такого нет.

Возможно у чтения данных не установлен признак "Сериализовать в БД"

Признак "Сериализовать в БД" установлен.

Версия какая? Нами выявлены множественные ошибки при работе с параметрами в БП 7.8.2. Решение вырубить проверку корректности заполнения поля. Наибольшие проблемы с элементом "Читать данные". Проявляется, если используется несколько полей из "Читать данные" в рамках одного элемента БП. Есть скрипт, который надо пустить в консоли браузера. Побочный эффект - процесс станет обязательно компилируемым.

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

Доброго всем дня.

Версия 7.8 sales.

Задача следующая: есть данные по звонкам, в числе которых хранятся дата, кто кому звонил и т.д., ну и запись самого звонка в файле wav (хранится на стороннем сервере, в соответствующую колонку UsrLink записана только ссылка на этот файл).

Сделан свой небольшой контрол для проигрывания записи при помощи стандартного тега HTML audio.

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

А вот как сделать то же самое на списковой странице? Сейчас блок audio подставляется в схеме списковой CallSection следующим образом:

diff: /**SCHEMA_DIFF*/[
                        {
                                "operation": "insert",
                                "name": "UsrAudio",
                                "values": {
                                        "className": "Terrasoft.UsrAudioControl",
                                        "layout": {
                                                "colSpan": 12,
                                                "rowSpan": 1,
                                                "column": 0,
                                                "row": 0
                                        },
                                        "generator": "UsrAudioControlGenerator.generateUsrAudioControl",
                                        "visible": true,
                                        //"getAudioLink": "getAudioLink",
                                        "myParam": {"bindTo": "getAudioLink"},//"myParam" - собственно, в этот параметр должно быть записано значение UsrLink. Если я подставляю сюда произвольное значение - оно выводится. Как вытащить ссылку?
                                },
                                "parentName": "DataGrid",
                                "propertyName": "activeRowActions",
                                "index": 10
                        }
        ]/**SCHEMA_DIFF*/,

Также есть метод:

getAudioLink: function() {

                                return this.get("UsrLink");
                        },

Но он не работает.

Нравится

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

Функция this.get("UsrLink"); в контексте секции не вернет вам ваш линк из объекта, поставьте точку остановки на этом return вашего метода getAudioLink и посмотрите, что возвращает this.get("UsrLink"); и вместо этого используйте this.getActiveRow() который вернет модель всей текущей строки, в которой уже можно достать нужные вам данные.

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

Уважаемые коллеги!

Подскажите пжл., как добавить внутренние телефоны Webitel, если уже все пользователи созданы, а внутренние телефоны по не знанию были удалены?
Нужно заново удалять и создавать пользователей или есть другой способ?

Нравится

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

"Ифутин Юрий Борисович" написал:
если уже все пользователи созданы, а внутренние телефоны по не знанию были удалены?

Добрый день!

А внутренние номера удалены где именно? Речь идет о бесплатном collaboration или другом продукте?

Речь идет о бесплатном Webitel...

В bpm’online встроена интеграция с сервисом телефонии Webitel. Пользователи bpm’online
могут осуществлять внутренние звонки друг другу, используя гарнитуру, без установки
дополнительного программного обеспечения.
Телефония Webitel встроена в приложение bpm’online и доступна сразу при первом
использовании системы.
Чтобы сотрудники компании могли приступить к выполнению внутренних звонков
в приложении, необходимо зарегистрировать пользователей bpm’online.
При создании пользователя bpm’online ему автоматически добавляется внутренний телефон
Webitel. Он фиксируется на странице контакта на детали [Средства связи]. По умолчанию
нумерация номеров телефонов начинается с номера 100. Регистрируемым в системе
Настройка телефонии bpm’online sales 263 пользователям будут присваиваться последующие порядковые номера, например, 101, 102, 103 и т. д.

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

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