Добрый день. Появилась задача добавить кнопку, аналогичную кнопке "Обработать" в почте. 

 

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

 

Пример кода, который получился:

generateEmailButtonsContainerConfig: function() {
	var buttonItems = [];
	var processEmailButtonConfig = this.generateEmailProcessedButtonConfig();
	buttonItems.push(processEmailButtonConfig);
	/** Добавляем новую кнопку */
	var skipEmailButtonConfig = this.generateSkipEmailButtonConfig();
	buttonItems.push(skipEmailButtonConfig);
	var deleteEmailButtonConfig = this.generateDeleteEmailButtonConfig();
	buttonItems.push(deleteEmailButtonConfig);
	var emailButtonContainerConfig = {
		"className": "Terrasoft.Container",
		"classes": {"wrapClassName": ["entity-item-relation-container"]},
		"items": buttonItems
	};
	return emailButtonContainerConfig;
},
/** НОВАЯ КНОПКА */
generateSkipEmailButtonConfig: function() {
	return {
		"className": "Terrasoft.Button",
		"style": Terrasoft.controls.ButtonEnums.style.RED,
		"caption": "SKIP",
		"click": {bindTo: "onSkipEmail"},
		"markerValue": "skipingEmail"
	};
},
/** Метод обработчик кнопки*/
onSkipEmail: function (model) {
	window.console.log("It's working");
}

Но при нажатии на кнопку - появляется ошибка:

Возможно надо использоваться что-то похожее на fireEvent, но за все время не было необходимости в подобном функционале - поэтому плохо понимаю как и что делать. Вроде в этой статье https://community.terrasoft.ru/articles/kak-sozdat-polzovatelskii-eleme… о чем-то, что мне поможет, говорится. Но без понимая как это все устроено - это какое-то гадание на кофейной гуще.

 

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

 

Может кто-то реализовывал мой кейс или нечто подобное и сможет поделиться советом?

Нравится

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

Сергей, насколько понимаю, Вы пытаетесь сделать как для зелёной кнопки EmailProcessedButton, которая описана в CommunicationPanelEmailSchema:

/**
 * Creates email message action buttons container config.
 * @protected
 * @return {Object} Email message action buttons container config.
 */
generateEmailButtonsContainerConfig: function() {
	var buttonItems = [];
	var processEmailButtonConfig = this.generateEmailProcessedButtonConfig();
	buttonItems.push(processEmailButtonConfig);
	var deleteEmailButtonConfig = this.generateDeleteEmailButtonConfig();
	buttonItems.push(deleteEmailButtonConfig);
	var emailButtonContainerConfig = {
		"className": "Terrasoft.Container",
		"classes": {"wrapClassName": ["entity-item-relation-container"]},
		"items": buttonItems
	};
	return emailButtonContainerConfig;
},
 
/**
 * Creates "process message" button config.
 * @protected
 * @return {Object} "Process message" button config.
 */
generateEmailProcessedButtonConfig: function() {
	return {
		"className": "Terrasoft.Button",
		"caption": {"bindTo": "Resources.Strings.MarkAsProcessed"},
		"style": Terrasoft.controls.ButtonEnums.style.GREEN,
		"imageConfig": {"bindTo": "Resources.Images.ApplyButtonImage"},
		"enabled": {"bindTo": "IsProcessingButtonEnabled"},
		"visible": {
			"bindTo": "IsNeedProcess",
			"bindConfig": {
				"converter": "getProcessButtonVisible"
			}
		},
		"click": {bindTo: "setIsNeedProcessFalse"},
		"markerValue": "setNeedProcessFalse"
	};
},

Но там обработчик setIsNeedProcessFalse в EmailItemSchema не просто одна функция, а несколько в цепочке, одна вызывает другие:

/**
 * Sets and saves IsNeedProcess value for message.
 * @param {Function} [callback] Callback function.
 * @param {Object} [scope] Callback function scope.
 */
setIsNeedProcessFalse: function(callback, scope) {
	this.set("IsProcessingButtonEnabled", false);
	var chain = [];
	chain.push(this.updateIsNeedProcess);
	chain.push(this._onSetIsNeedProcessFalse, function() {
		this.Ext.callback(callback, scope);
	});
 
	this.set("IsNeedProcess", false);
	this.Terrasoft.chain.apply(this, chain);
},
...
/**
 * Updates IsNeedProcess value for current user EmailMessageData instances.
 * @param {Function} [callback] Callback function.
 * @param {Object} [scope] Callback function scope.
 */
updateIsNeedProcess: function(callback, scope) {
	var update = this.getIsNeedProcessUpdate();
	if (this.Ext.isEmpty(update)) {
		this.Ext.callback(callback, scope);
		return;
	}
	update.execute(function() {
		this.Ext.callback(callback, scope);
	}, this);
},
...
/**
 * Handle response of save entity request.
 * @private
 * @param {Object} [response] Response of save entity request.
 * @param {Function} [callback] Callback function.
 * @param {Object} [scope] Callback function scope.
 */
_handleSaveRequestResponse: function(response, callback, scope) {
	if (response && response.success) {
		this.fireEvent("entitySaved", this);
		this.set("CurrentColumnValue", null);
	}
	this.Ext.callback(callback, scope);
},
/**
 * Set IsNeedProcess to false.
 * @private
 * @param {Function} [callback] Callback function.
 * @param {Object} [scope] Callback function scope.
 */
_onSetIsNeedProcessFalse: function(callback, scope) {
	this.saveEntity(function(response) {
		this._handleSaveRequestResponse(response, callback, scope);
	}, this);
},

Если ругается на .apply, видимо, ожидает для Вашей кнопки аналогичной логики. Хотя, там же рядом справа DeleteEmailButton, там без этого всего:

/**
 * Creates "delete" button config.
 * @protected
 * @return {Object} "Delete" button config.
 */
generateDeleteEmailButtonConfig: function() {
	return {
		"className": "Terrasoft.Button",
		"style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
		"imageConfig": {"bindTo": "Resources.Images.DeleteEmailButtonImage"},
		"click": {bindTo: "onDeleteEmail"},
		"markerValue": "deleteEmail"
	};
},
...
/**
 * Removes email message from emails collection.
 * @param {Terrasoft.BaseViewModel} model Email message model instance.
 */
onDeleteEmail: function(model) {
	this.unsubscribeModelEvents(model);
	var collection = this.get("EmailCollection");
	collection.remove(model);
},

Не сравнивали в отладке Вашу кнопку с кнопкой удаления?

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

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

CommunicationPanelEmailSchema. Проверю свою догадку и отпишусь о происходящем. Просто изначально не заметил эту привязку. Даже не осознал до конца как я натолкнулся на нее. Но теперь уже немного понятно куда идти

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

Если просто Вашу функцию onSkipEmail перенести в EmailItemSchema, то всё работает, пишет в консоли «It's working».

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

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

CommunicationPanelEmailSchema (потому что надо было работать с коллекцией писем, не был уверен что смогу это провернуть в EmailItemSchema)

 

Если кому-то поможет - полученный код ниже

 

EmailItemSchema:

messages: {
	"MessageSkipEmail": {
		mode: Terrasoft.MessageMode.BROADCAST,
		direction: Terrasoft.MessageDirectionType.BIDIRECTIONAL
	}
},
methods: {
	/**
	 * Initializes starter values.
	 * @protected
	 * @overridden
	 */
	init: function () {
		this.callParent(arguments);
		// Регистрация сообщения.
		this.sandbox.registerMessages(this.messages);
	},
	onSkipEmail: function() {
		// Регистрация сообщения.
		var EmailId = this.get("Id");
		this.sandbox.publish("MessageSkipEmail", {Id: EmailId}, ["EmailItemSchema"]);
	}
},

CommunicationPanelEmailSchema

messages: {
	"MessageSkipEmail": {
		mode: Terrasoft.MessageMode.BROADCAST,
		direction: Terrasoft.MessageDirectionType.BIDIRECTIONAL
	}
},
methods: {
	init: function () {
		this.callParent(arguments);
		// Регистрация сообщения.
		Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE, this.onMyBpFinish, this);
		this.sandbox.subscribe("MessageSkipEmail", function(args) { this.skipingEmail(args.Id);},
			this, ["EmailItemSchema"]);
	},
	skipingEmail: function(EmailId) {
		var collection = this.get("EmailCollection");
		var foundItem = collection.collection.items.find(item => item.id === EmailId);
		var args = {
		// Имя процесса, который необходимо запустить.
			sysProcessName: "UsrSkipEmail",
		// Объект со значением входящего параметра ContactParameter для процесса CustomProcess.
			parameters: {
				ID: EmailId
			}
		};
				// Запуск пользовательского бизнес-процесса.
		ProcessModuleUtilities.executeProcess(args);
		collection.remove(foundItem); /** Выкидываем уже обработанное письмо из списка*/
	},
	generateEmailButtonsContainerConfig: function() {
		var buttonItems = [];
		var processEmailButtonConfig = this.generateEmailProcessedButtonConfig();
		buttonItems.push(processEmailButtonConfig);
		/** Добавляем новую кнопку */
		var skipEmailButtonConfig = this.generateSkipEmailButtonConfig();
		buttonItems.push(skipEmailButtonConfig);
		var deleteEmailButtonConfig = this.generateDeleteEmailButtonConfig();
		buttonItems.push(deleteEmailButtonConfig);
		var emailButtonContainerConfig = {
			"className": "Terrasoft.Container",
			"classes": {"wrapClassName": ["entity-item-relation-container"]},
			"items": buttonItems
		};
		return emailButtonContainerConfig;
	},
	/** НОВАЯ КНОПКА */
	generateSkipEmailButtonConfig: function() {
		return {
			"className": "Terrasoft.Button",
			//"style": 
			"caption": "Игнорировать",
			"click": {bindTo: "onSkipEmail"},
			"markerValue": "skipingEmail",
			"enabled": {"bindTo": "IsProcessingButtonEnabled"},
			"visible": {
				"bindTo": "IsNeedProcess",
				"bindConfig": {
					"converter": "getProcessButtonVisible"
				}
			},
		};
	},

А в самом БП происходит магия изменения БД, чтобы не запустились скрытые процессы, привязанные к "IsNeedProcess" в EmailMessageData

 

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

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

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

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

Нравится

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

В самом процессе, который привязан к кнопке на панели, можно создать блок «автогенерируемая страница» и вывести на неё нужные поля. Или «Преднастроенная страница», там возможности дизайна шире: можно создать новую страницу с полями или указать интересующую мини-карточку. То есть нужно в конфигурации или библиотеке процессов найти нужный БП и доработать.

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

Автогенерируемая страница не подойдет, нужна именно миникарточка.
Если использовать "преднастроенную страницу" и туда указывать мини карточку, то из CTI панели мини карточка не открывается. Просто по нажатию проставляется url типа CallMiniPage/add/GUID и ничего больше не происходит.

А какие-то ошибки при этом пишутся в консоли?

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

Добрый день!
 

У меня в CTI панели есть два поля:

Линия соединения и Тематика. В Тематике есть справочная колонка Линия соединения. Мне необходимо фильтровать справочник 2 по значению в поле 1.

Я попробовал сделать это тремя способами:

1. lookupListConfig. Не работает, в фильтр даже дебаггер не проваливается.

2. Бизнес правила. Тоже не работают.


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

В итоге и в этот метод не могу провалиться дебаггером.

Скрины по каждому варианту во вложении.
Кто сталкивался? Что происходит? В других карточках все методы работают, именно в CTI панели - нет.

 

Нравится

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

У Вас какая версия? У меня так же не работает код фильтрации в разделе активностей на поле "Ответственный" - версия Sales 7.15.2 для СУБД Oracle

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

 

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

scr_section_service_requests_buttons_on_call.png

Александр Тыра,

В обычных страницах у меня работает. Версия такая же только Service.

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

Да, на крайний случай так и сделаю

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

Подскажите как можно экспортировать пользователей с номерами IP телефонии что занесены в настройки пользователя?

Нравится

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

Вот пример формата поля ConnectionParams - {"debugMode":false,"disableCallCentre":true,"ExtensionName":"123"}

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

Ещё, как вариант, можно написать стандартный sql-запрос insert.

Для выгрузки данных реализуйте sql-запрос.

Если у Вас bpm'online on-site, то можно выполнить запрос прямо на сервере баз данных через Microsoft SQL Server Management Studio.

Если on-demand, то можно установить Модуль для выполнения SQL - скриптов "SQL Executor" и выполнить запрос из него.

И оттуда, и оттуда можно информацию выгрузить в MS Excel.

Алла Савельева,

а в какой таблице хранятся данные о номерах ip телефонии что прикреплены к пользователю? Мне нужно выгрузить таблицу с колонками "контакт; номер телефона avaya"

Александр Тыра,

Сделайте, пожалуйста, скриншот, чтобы я точно понимала о каких именно настройках идет речь.

Подозреваю, что речь о настройках телефонии Avaya, которые хранятся в части записей таблицы SysMsgUserSettings сериализированными в формате JSON в поле ConnectionParams. И в SQL-запросе придётся этот JSON парсить, вычленяя номер.

Как вариант, те же номера могут также вестись на детали средств связи в разделе контактов. Если они там есть у контактов этих пользователей, проще выгрузить оттуда.

Вот пример формата поля ConnectionParams - {"debugMode":false,"disableCallCentre":true,"ExtensionName":"123"}

Для разных систем телефонии формат ещё и разный.

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

Доброго дня, Коллеги! Наткнулся на кое что непонятное. На панели телефонии почему то не отображаются процессы. Кто нибудь сталкивался с подобным? 

Как должно быть:

И как на самом деле:

 

Нравится

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

Оказалось, что нужно назначить пользователю организационную роль "Операторы КЦ", что бы он видел процессы. Ну или вообще нафиг убрать проверку, создав замещающую схему CtiPanel и переопределив метод loadProcessActions закомментировать if (!actions.isEmpty() || !this.get("IsCurrentUserContactCenterOperator"))

Показать все комментарии
Идея
Обсуждение

При звонке (входящем или исходящем) давать возможность пользователю оперативно ввести содержание звонка в той же CTI панели.

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

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

Передали данное пожелание команде разработки для анализа возможности внедрения данного функционала в будущих версиях системы.

Интересует, когда планируется реализация данной функциональности?

Сейчас, например, при входящем звонке отображается только имя контакта, а все остальные связанные записи, в том числе и контрагент контакта - нет(

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

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

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

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

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

Можно нажать на имя контакта и откроется его карточка, где посмотреть контрагента и остальную информацию.

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

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

Мой вопрос заключается в том, планируется ли такая доработка и, если планируется, то когда?

Алла, узнать о планах на будущие версии можно на соответствующей странице. Пока там вижу улучшение при входящем звонке только для iOS:

АВТООПРЕДЕЛЕНИЕ НОМЕРА КОНТАКТА

При входящем звонке у пользователей мобильного приложения для iOS появится возможность автоматического определения номеров, которых нет в их телефонной книге, из базы контактов bpm'online.

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

Добрый день.
Необходимо создать всплывающее окно при нажатии на кнопку "Отправить смс" на CTI панели.
В всплывающем окне необходимо разместить Справочник, Текстовое поле, и две кнопки Отправить и Отмена. И реализовать Логику отправки XML на некий урл.
Похожее окно есть в мастере раздела при добавлении нового поля(например). Скрин прикреплю.
И похоже при добавлении адреса доставки в "Заказе". Как вызвать его я не очень понимаю.

Подскажите как правильно(легче) это реализовать(любое из этих двух окон)?
В каком направлении вообще искать?

Нравится

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

Добрый день Дмитрий!!!

судя по скриншотам у вас версия 7.7. на первой картинке изображено Модальное окно созданное вручную. Базового инструмента в 7.7 генерирующие Модальные окна нет, как это к примеру сделано с Базовой схемой карточки редактирования. На втором скриншоте изображено PopUp окно. и данное окно можно привязать к любой кнопке, к любому событию. Легче реализовать 2 скриншот, так как все инструменты для генерации данного окна в системе есть. И там его не так сложно создавать вручную. Нужно только разобраться как работает данное окно при Добавление адреса, на карточки редактирования Заказа. Но еще раз повторюсь сложностей там никаких нет.

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

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

Василий сам код вам ничего не даст. Если разбирать вызов окна по кнопке "Добавить адрес" на детали "Адрес доставки", то могу ответить, что метод с помощью которого происходит открытие PopUp окна это   showCard: . Данный метод вызывается и отрабатывается, когда пользователь нажимает на Радио-кнопку "Добавить адрес".

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

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

Бесплатные звонки - звучит как рекламный лозунг! :smile: Нет, это не реклама (хотя...).

Рады представить сообществу Terrasoft Community новый продукт Webitel Community, который позволяет бесплатно совершать видео и аудио звонки между пользователями bpmonline 7 с использованием технологии WebRTC. Каждой компании, которая оставит заявку на сайте, будут предоставлены 5 лицензий Webitel Community.

Что предлагает Webitel Community?

  • Бесплатные звонки между пользователями
  • Видеозвонки
  • Определение статусов сотрудников
  • Перевод звонка и удержание

Если Вас у Вас есть пожелания - пишите в комментариях.

PS: небольшое видео, как это все работает: https://vimeo.com/97131875

PPS: если Вы установите на свой bpmonline 7 пакет Webitel Community и в другой компании сделано то же самое, то Вы сможете позвонить им тоже бесплатно. Вот оно - Community! :lol:

Нравится

Поделиться

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

Круто :)

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