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

this.on("change:UsrProduct", function() {this.ProductChanged(); }, this);

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

Вопрос - как понять, что вызов происходит после нажатия Отмены???

Нравится

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

попробуйте использовать предоставляемый платформой механизм "зависимости".

attributes:{
...
"UsrProduct": {
	dependencies: [
		{
			columns: ["UsrProduct"],
			methodName: "ProductChanged"
		}
	]
}
...
},

Его реализация предусматривает Ваш и еще несколько кейсов, которые дополнительно придется отрабатывать при прямой подписке на Backbone model property.

Так будет еще хуже. Метод будет вызываться еще и при инициализации страницы.
Нужен какой-то onCancel, есть такой?

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

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

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


Да, так работает!
Спасибо!

"Алексей Карягин" написал:Метод будет вызываться еще и при инициализации страницы.

по какой причине он будет вызываться при ИНИЦИАЛИЗАЦИИ страницы ?
не должен и не вызывается :)
"Алексей Карягин" написал:Нужен какой-то onCancel, есть такой?

есть у BasePageV2 метод onCardAction

...
				onCardAction: function() {
					var action = arguments[0] || arguments[3];
					this[action]();
				},
...

через него проходит обработка вызова "действий карточки", если они не вызываются напрямую н/п

this.save()

он завязан в механике обработки тегов по нажатию на кнопках "Закрыть", "Отмена", "Сохранить".
Я думаю это то что Вам нужно.

PS:
через него кстати и вызов вышеупомянутого onDiscardChangesClick происходит

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

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

Заранее благодарю!

Нравится

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

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

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

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

В качестве супербредовой идеи:
1) Унаследоваться от базового объекта, сделать базовый объект с логом(там будет событие записи в базу кто и когда делал изменение в каком поле какого объекта). изменить родителя у основных объектов системы с базового объекта на новый.
2) В basesection на событие загрузки грида тоже прилепить логирование.(либо gridUtils, чтобы ещё и детали отслеживались).
3) скорее всего где-то в системе валяется таблица времени логина пользователя, её тоже можно откопать, вытащить данные.(деталь сеансы)

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

Что-то подобное мы реализовывали тригерами в БД, но в очень узком масштабе - 2 раздела, несколько объектов и некоторые поля в нем.
Ну и я так понимаю Вам необходим хронологический порядок, нас же интересовали удельные итоговые данные по временным интервалам.
Но "на вскидку" хронологию так-же можно "прикрутить".
Можете по-подробнее рассказать как вы видите методику учета "работы" менеджера, aka "Необходимо учитывать время с момента открытия карточки, до ее закрытия" или "необходимо учитывать как скоро после изменения одних данных произошло изменение других этим же пользователем" и т.д.

Илья, да, у нас стоит задача в фиксировании деятельности в хронологическом порядке, т.е. ка Вы правильно указали "Необходимо учитывать время с момента открытия карточки, до ее закрытия", сейчас же система считает сколько менеджер звонит в день или пишет email, фактическое время работы в разделах вовсе не учитывается. Есть одна идея, связанная с лидами или продажами (для данных разделов созданы "большие процессы" и по данным процессам видно, сколько времени процесс "управления лидом" или "корпоративная продажа" находится в активном статусе), быть может и в других разделах фиксацию можно реализовать с помощью процессов, так как с разработкой я "на Вы" и хочется (если это возможно) реализовать все с помощью внутренних инструментов

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

Добрый день!

В нашей компании реализована интеграция bpm'online sales c телефонией Манго Телеком (создан коннектор). Сервер Манго синхронизируется с bpm по защищенному протоколу HTTPS, все совершенные звонки автоматически загружаются в bpm. Менеджеры подключаются к bpm по rdp (удаленному рабочему столу). В компании для каждого менеджера развернута отдельная трубка с базой (радиотелефоны).Как настроить подключение гарнитуры (будь это проводные наушники или блютуз-гарнитура) к телефонии и bpm без использования стороннего ПО?

Заранее благодарю!

Нравится

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

Добрый день, Александр!

В профиле пользователя есть настройки Call Centre, где можно указать использовать "Веб телефон" или использовать "Гарнитуру"
Подробнее можно прочитать на академии тут -https://academy.terrasoft.ru/documents/sales-enterprise/7-10/kakie-nast…
Вы используете Webitel Any Voip Connector поэтому настройки должны быть похожи с Webitel.

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

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

Указав параметр в профиле "Использовать Web телефон" как подключить гарнитуру (через ноутбук 3.5 разъем или другой способ)?

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

У детали есть кнопки Вверх, Вниз, которые управляют позицией детали.
За это отвечает вот этот кусок кода.

setPosition: function(recordId, position, callback, scope) {
                                var data = {
                                        tableName: UsrWorkDR",
                                        primaryColumnValue: recordId,
                                        position: position,
                                        grouppingColumnNames: "
UsrWorkDId"
                                };
                                ServiceHelper.callService("
RightsService", "SetCustomRecordPosition", callback, data, scope);

использую его на своей страничке у детали.
Но выходит сообщение

em>message: Uncaught TypeError: ServiceHelper.callService is not a function em>

Что не так?

Нравится

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

Конкретно эта ошибка говорит о том что вы скорее всего не добавили переменную ServiceHelper или добавили её в неправильной последовательности в схеме:

Смешно...но ServiceHelper был последним, сделал первым и заработало...подсказку тут нашел тут

Максим спасибо.

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

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

создала деталь с редактируемым реестром по объекту Договор, зарегистрировала в деталь в БД в таблице sysdetail.

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

Версия 7.10.0.1742

Нравится

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

Здравствуйте, удалите все что связано с этой деталью кроме объекта детали.
Создайте деталь мастером разделов, обычную, на основании этого объекта, вывидите на страницу, настройте колонки, обязательно в списочном (не плиточном!) представлении, после чего, в схеме детали кодом сделайте её редатируемой.

Для того, чтобы сделать реестр детали редактируемым, в соответствующей схеме необходимо:
- Добавить зависимости от модулей ConfigurationGrid (Конфигурационный реестр), ConfigurationGridGenerator, ConfigurationGridUtilities;
- Подключить "миксин" ConfigurationGridUtilites;
- Установить атрибут IsEditable в значение true;
- Базовому реестру указать свойства:
className: "Terrasoft.ConfigurationGrid",
generator: "ConfigurationGridGenerator.generatePartial",
generateControlsConfig: {bindTo: "generateActiveRowControlsConfig"},
changeRow: {bindTo: "changeRow"},
unSelectRow: {bindTo: "unSelectRow"},
onGridClick: {bindTo: "onGridClick"},
initActiveRowKeyMap: {bindTo: "initActiveRowKeyMap"},
для добавления действий активной записи добавить:
activeRowActions: [...],
activeRowAction: {bindTo: "onActiveRowAction"}
Зависимости нужно указать не только параметром requirejs но и в настройках схемы, в конфигураторе.
Итоговый код простейшей редактируемой детали будет выглядеть следующим образом:

define("UsrSchema1Detail", ["ConfigurationGrid", "ConfigurationGridGenerator",
   "ConfigurationGridUtilities"], function() {
   return {
      entitySchemaName: "Contact",
      attributes: {
         "IsEditable": {
            dataValueType: Terrasoft.DataValueType.BOOLEAN,
            type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
            value: true
         }
      },
      details: {},
      diff: [
         {
            "operation": "merge",
            "name": "DataGrid",
            "values": {
               "className": "Terrasoft.ConfigurationGrid",
               "generator": "ConfigurationGridGenerator.generatePartial",
               "generateControlsConfig": {"bindTo": "generatActiveRowControlsConfig"},
               "changeRow": {"bindTo": "changeRow"},
               "unSelectRow": {"bindTo": "unSelectRow"},
               "onGridClick": {"bindTo": "onGridClick"},
               "activeRowActions": [
                  {
                     "className": "Terrasoft.Button",
                     "style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                     "tag": "save",
                     "markerValue": "save",
                     "imageConfig": {"bindTo": "Resources.Images.SaveIcon"}
                  },
                  {
                     "className": "Terrasoft.Button",
                     "style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                     "tag": "cancel",
                     "markerValue": "cancel",
                     "imageConfig": {"bindTo": "Resources.Images.CancelIcon"}
                  },
                  {
                     "className": "Terrasoft.Button",
                     "style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                     "tag": "remove",
                     "markerValue": "remove",
                     "imageConfig": {"bindTo": "Resources.Images.RemoveIcon"}
                  }
               ],
               "initActiveRowKeyMap": {"bindTo": "initActiveRowKeyMap"},
               "activeRowAction": {"bindTo": "onActiveRowAction"},
               "multiSelect": false
            }
         }
      ],
      mixins: {
         ConfigurationGridUtilites: "Terrasoft.ConfigurationGridUtilities"
      },
      methods: {}
   };
});
Показать все комментарии

Добрый день!
Подскажите в чем может быть проблема.
Не получается обратиться к нашему созданному сервису.
Выдает 403 ошибку - нету прав на чтение при попытке выполнить POST метод.
Может ли это быть как-то связано с https, так как на стенде разработке обыкновенный http и таких проблем не испытывали? Настройка прав один в один.

Нравится

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

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

403-я ошибка – означает отсутствие хедера с CSRF-токеном. Чтобы с помощью ARC сделать запрос нужно добавить header с валидным для текущей сессии csrf-токеном. Получить его можно, например, взяв любой post-запрос из вкладки network chrome-а. Лучше, также, положить хедер с Cookies.
Подробнее по CSRF в статье: https://academy.terrasoft.ru/documents/technic-sdk/7-9/zashchita-ot-csr…

"Сергей Кy6риш" написал:Подробнее по CSRF в статье: https://academy.terrasoft.ru/documents/technic-sdk/7-9/zashchita-ot-csrf...

С уважением,
Группа компаний Terrasoft


В примере который вы прикрепили https://academy.terrasoft.ru/documents/technic-sdk/7-10/zashchita-ot-cs… нет описания того что представляет из себя SendingRequestEventArgs.
Собственно дальше не получается продвинуться.

Пример из статьи взят из другой статьи: https://academy.terrasoft.ru/documents/technic-sdk/7-10/rabota-s-obekta…, там можно посмотреть более детально. На этом примере показали, что в целом важно просто получить значение куки “BPMCSRF”, и положить в headers request-а, который собираемся отправить.

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

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

Сделал обработчик для нажатия клавиши Enter вот таким образом:

onEntityInitialized: function() {
                                this.callParent(arguments);
                       
                                var keyMap = new Ext.util.KeyMap({
                                        target: Ext.select("тут id элемента"),
                                        key: Ext.EventObject.ENTER,
                                        fn: this.onSearchPressEnter,
                                        scope: this,
                                        binding: keyMap
                                });
                        },
                       
                        onSearchPressEnter: function() {
                                console.log("Test");
                        },

Инструкцию взял отсюда: https://community.terrasoft.ru/forum/topic/15140#comment-58515

Проблема в том Test выводится в консоль аж 5 раз. Возможно ли сделать этот вывод только один раз, и чтобы при этом сохранялась возможность сделать вызов onSearchPressEnter повторно?

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

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

UPD. Разобрался, элемент по id неправильно находился, из-за чего в target оказывалось сразу несколько элементов.

Нравится

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

Коллеги. Добрый день. Есть потребность управлять доступностью большого множества полей на карточке. Для примера имеем:

{
  "operation": "insert",
  "name": "UsrNumberField",
  "values": {
    "layout": {
      "colSpan": 12,
      "rowSpan": 1,
      "column": 0,
      "row": 0,
      "layoutName": "Header"
    },
    "bindTo": "UsrNumber",
    "labelConfig": {},
    "enabled": {"bindTo": "getEnablePropertyOfFields"}
  },
  "parentName": "Header",
  "propertyName": "items",
  "index": 0
},

methods: {
  getEnablePropertyOfFields: function(arg) {
    console.log(arg);
  },
}

При рендере страницы метод вызывается 4 раза подряд. Вывод такой:

UsrNumber
UsrNumber
undefined
undefined

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

Версия 7.8.2. Есть идеи? Писать на каждое поле свой метод - несколько безумно на мой взгляд.
Если вдруг есть инфа, что на 7.9.х это починили или такое не замечено, то тоже дайте знать.

Нравится

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

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

Биндинг на метод - идея плохая, 4-ре раза это Вам повезло, когда я задавался этим вопросом он вызывался 12-ть раз.
http://www.community.terrasoft.ru/forum/topic/25151
http://www.community.terrasoft.ru/forum/topic/25084

"Севостьянов Илья Сергеевич" написал:

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

Биндинг на метод - идея плохая, 4-ре раза это Вам повезло, когда я задавался этим вопросом он вызывался 12-ть раз.

http://www.community.terrasoft.ru/forum/topic/25151

http://www.community.terrasoft.ru/forum/topic/25084

Уже прочел Ваши темы. Заводить овер 60 атрибутов грустно. В методе планировалось сделать свич по имени колонки и для каждой свою логику делать. А теперь придется такой же метод писать, но для атрибутов и еще тонну атрибутов заводить.

"Темченко Кирилл Александрович" написал:А теперь придется такой же метод писать, но для атрибутов и еще тонну атрибутов заводить.

теги пробовали? (в values поля "tag": "testElement", в функции вставить дебаггер и посмотреть что в arguments приходит)

"Варфоломеев Данила" написал:

теги пробовали? (в values поля "tag": "testElement", в функции вставить дебаггер и посмотреть что в arguments приходит)

занятно.
теперь:

UsrNumber
UsrNumber
testElement
testElement

Этому поведению можно доверять теперь? Привязывать логику на тэги?

"Темченко Кирилл Александрович" написал:Привязывать логику на тэги?

Обычно в конфигурации клики через теги отлавливаются. Если и тут работает, то почему бы и нет)

"Темченко Кирилл Александрович" написал:Уже прочел Ваши темы. Заводить овер 60 атрибутов грустно. В методе планировалось сделать свич по имени колонки и для каждой свою логику делать. А теперь придется такой же метод писать, но для атрибутов и еще тонну атрибутов заводить.

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

arguments: {
...
"SomeColumn": {
	"dependencies": [
		{
			"columns": ["SomeColumn"],
			"methodName": "SomeColumnChangeHandler"
			"argument": "Что угодно"
		}
	]
},
...

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

Илья. Спасибо. Положу в копилку. Задачу уже решил. С помощью единственного метода и передачи в него тега.

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

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

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

Код детали

define("VwAccountOrdersProductsDetail", ["GridUtilitiesV2"], function(GridUtilities) {
        return {
                entitySchemaName: "VwAccountOrdersProducts",
                details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
                diff: /**SCHEMA_DIFF*/[
                                {
                                        "operation": "merge",
                                        "name": "DataGrid",
                                        "values": {
                                                "activeRowAction": {"bindTo": "onActiveRowAction"},
                                                "activeRowActions": []
                                        }
                                },
                                {
                                        "operation": "insert",
                                        "name": "AddToOrderProductAction",
                                        "parentName": "DataGrid",
                                        "propertyName": "activeRowActions",
                                        "values": {
                                                "className": "Terrasoft.Button",
                                                "style": this.Terrasoft.controls.ButtonEnums.style.DEFAULT,
                                                "visible": true,
                                                "caption": {"bindTo": "Resources.Strings.AddToOrderProductActionCaption"},
                                                "tag": "choose"
                                        }
                                }      
                ]/**SCHEMA_DIFF*/,

                methods: {

                        onActiveRowAction: function(buttonTag, primaryColumnValue) {
                                if(buttonTag == 'choose') {
                                        this.showInformationDialog(primaryColumnValue);
                                }
                        }              
                }
        };
});

Но кнопки не отображаются на гриде. При этом DOM элемент создается, но без привычных стилей t-btn. Подскажите что делать?

Нравится

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

у вас caption не проставляется (подгрузите ресурсы)

Судя по всему оно не видит "Resources.Strings.AddToOrderProductActionCaption", попробуйте caption записать не через байнд а напрямую "caption": "Текст кнопки".

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

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

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

Я создал свой раздел, данные в котором вытягиваються с внешнего API. Встал вопрос о том, как можно запретить редактировать и добавлять новые объекты? Достаточно ли будет придумать как скрыть кнопку "Добавить", а также кнопок "Открыть", "Копировать", "Удалить" при выделении конкретного объекта и в принципе запретить переход на старицу конкретного объекта? И как вообще можно такое сделать? В документации примеров не нашел

Нравится

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

Виталий, здравствуйте!

Встал вопрос о том, как можно запретить редактировать и добавлять новые объекты?
Вы можете ограничить действия в объекте правами доступа по операциям. Функционал описан по ссылке:
https://academy.terrasoft.ru/documents/sales-enterprise/7-10/detal-dostup-k-obektu-razdela-dostup-k-obektam-0

Достаточно ли будет придумать как скрыть кнопку "Добавить", а также кнопок "Открыть", "Копировать", "Удалить" при выделении конкретного объекта и в принципе запретить переход на страницу конкретного объекта?

Недостаточно. Есть обходные варианты для создания и копирования записи, если это не ограничено правами.
Пример, как запретить просмотр записи можно найти в реализации VwProcessLibSection (просмотр раздела регулируется системной операцией). Задается через атрибуты:

SecurityOperationName: {
	dataValueType: Terrasoft.DataValueType.STRING,
	value: "CanManageProcessDesign"
},

"Демьяник Алексей" написал:

Виталий, здравствуйте!

Встал вопрос о том, как можно запретить редактировать и добавлять новые объекты?

Вы можете ограничить действия в объекте правами доступа по операциям. Функционал описан по ссылке:

https://academy.terrasoft.ru/documents/sales-enterprise/7-10/detal-dostup-k-obektu-razdela-dostup-k-obektam-0

Достаточно ли будет придумать как скрыть кнопку "Добавить", а также кнопок "Открыть", "Копировать", "Удалить" при выделении конкретного объекта и в принципе запретить переход на страницу конкретного объекта?

Недостаточно. Есть обходные варианты для создания и копирования записи, если это не ограничено правами.

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

SecurityOperationName: {

        dataValueType: Terrasoft.DataValueType.STRING,

        value: "CanManageProcessDesign"

},


Cпасибо! А смогу ли я манипулировать объектами через службу DataService, если оставлю права только на чтение?

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