Коллеги, добрый день!

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

Ну и соотвественно обратно снимать, если это условие перестает соблюдаться.

Каким способом лучше это сделать?

Спасибо!!)

 

 

 

Нравится

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

Бп. А в странице к описанию детали влепить subscriber и делать loadEntity (грубо говоря — аналогично стандартной логике в заказе)

Бп. А в странице к описанию детали влепить subscriber и делать loadEntity (грубо говоря — аналогично стандартной логике в заказе)

Можно и триггером в базе вместо БП. Особенно, если на деталь льют записи извне в обход движка EntitySchemaQuery.

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

Трефилов Павел Сергеевич,

ContactAnniversary: {
	schemaName: "ContactAnniversaryDetailV2",
	filter: {
		masterColumn: "Id",
		detailColumn: "Contact"
	},
	subscriber: {
		"methodName": "sendSaveCardModuleResponse"
	}
}

Вот, допустим, из базовой страницы контакта. Метод sendSaveCardModuleResponse располагается в BasePageV2. Встаньте туда дебаггером через консоль и попробуйте поудалять/подобавлять записей в деталь "знаменательные события". При каждом изменении чего-нибудь в детали - тут же отрабатывает метод. В идеале в нём же делать this.reloadEntity (чтобы обновились поля карточки, которые были перерасчитаны по бп)

Варфоломеев Данила,

Данила, спасибо огромное! Сделали. 

Только тут асинхронность проявилась. Сабскрайбер отрабатывает и обновляет страницу быстрее чем отрабатывает БП. Как послать сигнал из БП чтобы страница обновилась после завершения БП. Ну кроме, как таймаут ставить). Спасибо!!!

Елена К,

Ничего адекватного, кроме переделки всех пересчётов под клиентский esq, посоветовать в таком случае не могу (ну за исключением костыля - отправки сообщения по websocket в конце бп).

Варфоломеев Данила,

Да, так и сделали. Спасибо вам!!)

 

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

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

В элементе процесса "Открыть страницу редактирования" не стоит галочка "Выполнять в фоновом режиме". Согласно статье на академии в таком случае будет открываться страница этого шага, прерывая любые действия пользователя. Но это элемент выполниться только в том случае если перейти на него на вкладке [Задачи по бизнес-процессам] коммуникационной панели.

Как правильно настроить элемент, чтобы он открывался сразу при переходе на данный шаг процесса?

Нравится

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

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

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

Александр, в стартовом сигнале галочка тоже отсутствует, но все равно возникает такая ситуация.

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

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

Спасибо большое! Сейчас посмотрю.

Александр, Проверил все еще раз. Ответственный - текущий пользователь. Таймеров никаких нет, что может еще переводить процесс в фон?

 

Ещё он будет в фоне, если запускать из дизайнера процессов, поскольку в этот момент не активна вкладка, на которой должна появится страница.

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

Спасибо!

Так у Вас процесс или кейс?

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

 

Если не открывается только эта страница, то что-то не то в самой странице. Если любая — то в процессе. Попробуйте поэкспериментировать с другими страницами, со специально созданными маленькими процессами из 1 элемента, открывающего эту страницу.

odins41,

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

1. Процесс не выполняется в фоне, т.е:

- в расширенных свойствах стартового элемента не должна стоять галочка "выполнять в фоне"

- по ходе процесса не должно быть таймеров 

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

3. Пользователь должен быть ответственным за элемент

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



Если все описанные више условия выполняются, а страница все равно не открывается напишите, пожалуйста, на support@bpmonline.com

В версии 7.16 должно появиться восстановление контекста, то есть при одновременном запуске второго БП его интерактивные элементы будут тоже на экране, а не в фоне.

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

Добрый день, делаю звонок с кнопки:

 this.sandbox.publish("CallCustomer", {
                    number: mobNumber, 
                    customerId: userId, 
                    entitySchemaName: "SxCandidate",
                    callRelationFields: undefined
                });

Есть ли возможность как то узнать Id этого звонка? Той записи которая добавляется в таблицу "Call". Спасибо!

Нравится

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

Смотря какая телефония. У вебитела, например есть чудеснейшая функция UpdateDbCall в провайдере, которая делает запись в бд через insert (пока-пока событийные бп), и возвращает Id вставленной записи в onUpdateDbCall

Телефония Asterisk

mcNosferatum,

Есть у меня подозрение, что для asterisk-а интеграция встроена в dll в виде класса и звонок там вставляется через те же insert-ы. Тогда смотреть стоит в сторону обработчиков событий звонка в ctipanel. Мб там где-нибудь guid звонка приходит...

А что в Network'е? Какие запросы/ответы при звонке? Просто в стандартном Webitel запрос на звонок к серверу как раз возвращает в ответе Id звонка, может у Asterisk такая же логика.

На самый крайний случай можно просто сделать esq запрос в БД с таким количеством параметров, которые однозначно идентифицируют звонок.

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

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

Есть хорошая и простая функция для открытия мини-карточки:

this.openMiniPage({
	recordId: Terrasoft.GUID_EMPTY,
	operation: Terrasoft.ConfigurationEnums.CardOperation.ADD,
	entitySchemaName: "Case",
	valuePairs: defaultValues,
	isFixed: true,
	showDelay: 0,
	miniPageSchemaName: "UsrCaseMiniPage",
});

Всё отлично - и указание на операцию, и на схему объекта и страницы. Особо удобно здесь свойство valuePairs, позволяющее передать значения для презаполненных колонок.

Существуют ли подобные функции для открытия полноценной карточки добавления?

Нашёл openPage в PageUtilities, но не нашёл, чтобы там был аналог valuePairs.

PushHistoryState не подходит - с его помощью можно открыть существующую страницу, а интересует именно страница добавления.

Нравится

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

Смотрите, как сделано в базовой схеме раздела BaseSectionV2. Там в обработчике кнопки добавления если есть миникарточка, вызывается Ваша функция openAddMiniPage, а если нет — openCardInChain:

/**
 * Opens new record page.
 * @protected
 */
addRecord: function(typeColumnValue) {
	if (!typeColumnValue) {
		if (this.checkEditPagesCount()) {
			return false;
		}
		var tag = this.get("AddRecordButtonTag");
		typeColumnValue = tag || Terrasoft.GUID_EMPTY;
	}
	var schemaName = this.getEditPageSchemaName(typeColumnValue);
	if (!schemaName) {
		return;
	}
	if (this.hasAddMiniPage(typeColumnValue)) {
		this.openAddMiniPage({
			entitySchemaName: this.entitySchemaName,
			valuePairs: this.getAddMiniPageDefaultValues(typeColumnValue)
		});
	} else {
		this.openCardInChain({
			schemaName: schemaName,
			operation: ConfigurationEnums.CardStateV2.ADD,
			moduleId: this.getChainCardModuleSandboxId(typeColumnValue),
			instanceConfig: {
useSeparatedPageHeader: this.get("UseSeparatedPageHeader")
			}
		});
	}
},

 

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

Добрый день,

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

 

После решил попробовать заполнить справочник вручную нужными значениями

//attributes
"RIBDocType": {
    "dataValueType": Terrasoft.DataValueType.ENUM,
    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
    "caption": "RIBDocType"
},
"documentTypeList": {
    "dataValueType": Terrasoft.DataValueType.ENUM,
    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
    "isCollection": true
}
 
//diff
{
	"operation": "insert",
	"parentName": "Header1",
	"propertyName": "items",
	"name": "RIBDocType",
	"values": {
		"bindTo": "RIBDocType",
		"caption": "Тип документа",
		"classes": {"wrapperClass": ["base-edit"]},
		"layout": {"column": 0, "row": 3, "colSpan": 24},
		"textSize": "Default",
		"contentType": Terrasoft.ContentType.ENUM,
		"labelConfig": {
			"visible": true
		},
		"controlConfig": {
			"className": "Terrasoft.ComboBoxEdit",
			"list": {
				"bindTo": "documentTypeList"
			},
			"change": {
				"bindTo": "onMyValueChange"
			},
			"prepareList": {
				"bindTo": "prepareDocumentTypeList"
			}
		}
	},
	"index": 3
}
 
//methods
 
onRender: function() {
	if (!this.get("documentTypeList")) {
		this.set("documentTypeList", this.Ext.create("Terrasoft.Collection"));
	}
 
},
 
prepareDocumentTypeList: function(filter, list) {
	if (list === null) {
		return;
	}
	list.clear();
	var columns = {};
	var value1 = {
		displayValue: "Type1",
		value: "e8670398-603b-43ca-820d-03e5b03fc275"
	};
	var value2 = {
		displayValue: "Type2",
		value: "14fcef3a-7d9e-4737-810f-52d57db3673a"
	};
	var value3 = {
		displayValue: "Type3",
		value: "672606f8-da25-40bd-a4ef-95c958331743"
	};
	columns[1] = value1;
	columns[2] = value2;
	columns[3] = value3;
	list.loadAll(columns);
	console.log(list);
},
 
onMyValueChange: function(val) {
	if (val && val.displayValue) {
		console.log("you pick: ", val.displayValue);
	}
},

Однако таким образом данные не отображаются в выборке совсем, просто пустой справочник.

Изображение удалено.

 

Нравится

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

Сериков Асхат Кайратович,

Вот, например, код страницы с проекта. Если в attributes добавить lookupListConfig для поля Contact, всё подтянется

/*jshint ignore: start*/
define("UsrSchema", [],
	function() {
		return {
			mixins: {},
			messages: {},
			attributes: {},
			details: {},
			diff: /**SCHEMA_DIFF*/[
				{
					"operation": "insert",
					"name": "mainBoxContainer",
					"values": {
						"id": "mainBoxContainer",
						"itemType": Terrasoft.ViewItemType.CONTAINER,
						"items": []
					}
				},
				{
					"operation": "insert",
					"name": "mainBoxContainerGrid",
					"parentName": "mainBoxContainer",
					"propertyName": "items",
					"values": {
						"itemType": Terrasoft.ViewItemType.GRID_LAYOUT,
						"items": []
					}
				},
				{
					"operation": "insert",
					"parentName": "mainBoxContainerGrid",
					"propertyName": "items",
					"name": "Contact",
					"values": {
						"bindTo": "Contact",
						"caption": "Контакт",
						"contentType": Terrasoft.ContentType.ENUM,
						"layout": {
							"column": 0,
							"row": 0,
							"colSpan": 24
						}
					},
				}
			]/**SCHEMA_DIFF*/,
			methods: {
				init: function() {
					this.callParent(arguments);
				},
 
				getLookupQuery: function(filter, column) {
					var esq = this.callParent(arguments);
					var lookupListConfig = this.getLookupListConfig(column);
					if (lookupListConfig) {
						this.Terrasoft.each(lookupListConfig.columns, function(column) {
							if (!esq.columns.contains(column)) {
								esq.addColumn(column);
							}
						}, this);
					}
 
					var schemaColumn = this.getColumnByName(column);
					if (schemaColumn.lookupListConfig && schemaColumn.lookupListConfig.filter) {
						esq.filters.addItem(schemaColumn.lookupListConfig.filter());
					}
 
					return esq;
				},
				getLookupListConfig: function(columnName) {
					var schemaColumn = this.getColumnByName(columnName);
					if (!schemaColumn) {
						return null;
					}
					var lookupListConfig = schemaColumn.lookupListConfig;
					if (!lookupListConfig) {
						return null;
					}
					var excludedProperty = ["filters", "filter"];
					var config = {};
					this.Terrasoft.each(lookupListConfig, function(property, propertyName) {
						if (excludedProperty.indexOf(propertyName) === -1) {
							config[propertyName] = property;
						}
					});
					return config;
				}
			}
		};
	});
/*jshint ignore: end*/

 

1) Я бы попробовал 

columns[value1.value] = value1;
columns[value2.value] = value2;
columns[value3.value] = value3;

+ в каждом объекте продублировал 

var value1 = {
	displayValue: "Type1",
        name: "Type1",
	value: "e8670398-603b-43ca-820d-03e5b03fc275"
};

чисто на всякий случай

2) Если это своё модальное окно, не унаследованное от basePage, то придётся копировать логику из getLookupQuery (BasePageV2). Там как раз таки и идёт перебор аттрибутов на фильтры, доп колонки и т.п.

Варфоломеев Данила,

Спасибо, да не наследованное, пойду пробовать 

Сериков Асхат Кайратович,

Вот, например, код страницы с проекта. Если в attributes добавить lookupListConfig для поля Contact, всё подтянется

/*jshint ignore: start*/
define("UsrSchema", [],
	function() {
		return {
			mixins: {},
			messages: {},
			attributes: {},
			details: {},
			diff: /**SCHEMA_DIFF*/[
				{
					"operation": "insert",
					"name": "mainBoxContainer",
					"values": {
						"id": "mainBoxContainer",
						"itemType": Terrasoft.ViewItemType.CONTAINER,
						"items": []
					}
				},
				{
					"operation": "insert",
					"name": "mainBoxContainerGrid",
					"parentName": "mainBoxContainer",
					"propertyName": "items",
					"values": {
						"itemType": Terrasoft.ViewItemType.GRID_LAYOUT,
						"items": []
					}
				},
				{
					"operation": "insert",
					"parentName": "mainBoxContainerGrid",
					"propertyName": "items",
					"name": "Contact",
					"values": {
						"bindTo": "Contact",
						"caption": "Контакт",
						"contentType": Terrasoft.ContentType.ENUM,
						"layout": {
							"column": 0,
							"row": 0,
							"colSpan": 24
						}
					},
				}
			]/**SCHEMA_DIFF*/,
			methods: {
				init: function() {
					this.callParent(arguments);
				},
 
				getLookupQuery: function(filter, column) {
					var esq = this.callParent(arguments);
					var lookupListConfig = this.getLookupListConfig(column);
					if (lookupListConfig) {
						this.Terrasoft.each(lookupListConfig.columns, function(column) {
							if (!esq.columns.contains(column)) {
								esq.addColumn(column);
							}
						}, this);
					}
 
					var schemaColumn = this.getColumnByName(column);
					if (schemaColumn.lookupListConfig && schemaColumn.lookupListConfig.filter) {
						esq.filters.addItem(schemaColumn.lookupListConfig.filter());
					}
 
					return esq;
				},
				getLookupListConfig: function(columnName) {
					var schemaColumn = this.getColumnByName(columnName);
					if (!schemaColumn) {
						return null;
					}
					var lookupListConfig = schemaColumn.lookupListConfig;
					if (!lookupListConfig) {
						return null;
					}
					var excludedProperty = ["filters", "filter"];
					var config = {};
					this.Terrasoft.each(lookupListConfig, function(property, propertyName) {
						if (excludedProperty.indexOf(propertyName) === -1) {
							config[propertyName] = property;
						}
					});
					return config;
				}
			}
		};
	});
/*jshint ignore: end*/

 

Варфоломеев Данила,

Спасибо

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

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

Задача в общем такая: есть несколько страниц редактирования раздела (к примеру, обращения Case). То, какую страницу показывать зависит от значения специальной справочной колонки "Тип страницы редактирования", здесь всё стандартно.

Далее есть другая колонка обращения - например, "Сервис", при этом в данных сервиса указывается, какая страница редактирования соответствует выбранному сервису. Всё дело в том, что одна и та же страница редактирования может соответствовать нескольким сервисам, т.е. связь примерно такая:

Сервис 1 - Тип страницы 1
Сервис 2 - Тип страницы 1
Сервис 3 - Тип страницы 2

Соответственно, привязать вид страницы редактирования напрямую к сервису не получается, из-за чего и вводится та самая дополнительная колонка "Тип страницы".

Возможна ли реализация такого вариант: по клику на кнопку "Добавить" в разделе всплывает мини-карточка, в которой указывается сервис (и несколько других колонок, необходимых для настройки), после чего по нажатию на кнопку "Сохранить" в мини-карточке открывается уже полноценная страница соответствующего типа?

На практике такую конструкцию реализовали при помощи бизнес-процесса и преднастроенной страницы вместо мини-карточки. Вариант с мини-карточкой конечно смотрелся бы намного изящнее.

Нравится

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

Я так понимаю, у вас уже для раздела несколько страниц редактирования?

Тогда в теории: достаточно в onSaved методе министраницы делать вызов нужной страницы (в зависимости от типа) на редактирование.

Варфоломеев Данила,

да.

Проблема в том, как вызывать сразу миникарточку без выпадающего меню с типом страницы.

Инструкция на академии не помогла: https://academy.terrasoft.ru/documents/technic-sdk/7-12/kak-sozdat-mini…

Смородинов Денис пишет:

без выпадающего меню с типом страницы.

Вот тут даже интересно. У вас стоит галочка в мастере "использовать миникарточку на добавление"? Если да, то он открывает одну и ту же миникарточку, но только после выбора какого-либо типа из выпадающего меню?

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

Варфоломеев Данила,

это 7.11. Там ещё нет галочки и мастера дизайна миникарточки((

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

Варфоломеев Данила пишет:

перегрузить initEditPages

Не подскажете, где он определяется? В BaseSectionV2 уже следует вызов в init.

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

BaseSchemaViewModel. 

Кстати, вы можете остановись дебагером, навести на функцию, вам хром выдаст её определение, щёлкаете на него, попадаете в функцию(и соответственно в модуль где она определена)

Ясно, спасибо.

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

Изображение удалено.

О компании

Компания является застройщиком и занимается продажей недвижимости в жилом комплексе «Покровский» — уникальном по масштабу проекте с хорошо развитой инфраструктурой

 

Предпосылки внедрения bpmonline

До внедрения bpm’online сотрудники отдела продаж работали в Excel, что усложняло контроль за соблюдением выполнения бизнес-процессов. Поэтому компания искала инструмент автоматизации процессов продаж для повышения эффективности менеджеров и, как следствие, повышения удовлетворенности клиентов.

 

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

 

Выполненные настройки

На первом этапе Customer Success менеджер совместно с CRM-координатором со стороны клиента адаптировали карточки разделов [Лиды], [Контакты], [Продажи], [Активности]. В карточки лида и продажи внесли все необходимые поля для возможности фиксировать точные данные об интересующем клиента объекте недвижимости с указанием адреса, этажа и площади квартиры.

 

Далее были выполнены настройки по автоматизации процесса длинной продажи. Согласно процессу работы, клиенты обращаются в компанию ЖК «Покровский» по разным каналам связи (звонок и email). После получения информации по любому из указанных каналов менеджер фиксирует данные о потребности клиента в bpm’online в разделе [Лиды].

 

Дальнейшее взаимодействие с клиентом ведется по бизнес-процессу, который настроен в разделах [Лиды] и [Продажи]. В рамках этого процесса автоматически создаются активности, которые подсказывают менеджеру следующий шаг. После ряда встреч и проведения показа недвижимости существует возможность автоматического создания продажи на основании лида. Продажа содержит следующие стадии: Условия покупки, Заключение договора, Текущие платежи, Завершена с победой.

 

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

  • автоматическое формирование названия продажи на основании ранее введенного адреса квартиры;

Изображение удалено.

  • автоматический расчет стоимости квартиры на основании стоимости 1 м2, метража квартиры и курса валюты.

Изображение удалено.

Результат

Внедрение bpm’online позволило увеличить объемы продаж на 25% благодаря ускорению и повышению качества обработки потребностей клиентов. Унифицированный бизнес-процесс позволяет контролировать работу менеджеров отдела продаж. Также bpm’online позволяет анализировать эффективность каналов привлечения лидов благодаря наличию этой информации в системе, что способствует более целенаправленному распределению маркетингового бюджета.

Нравится

Поделиться

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

Добрый час суток. Когда на секции задаются фильтры - то соответственно появляется запись в таблице SysProfileData и при переходах по разделам и т.д. после захода вновь на эту секцию фильтры остаются - всё ок. Нужно реализовать "сохранение" фильтров на детали,чтобы при переходах они соответственно не терялись,а сохранялись. Переопределил setFilter и переписал метод saveFilter для BaseGridDetailV2. Запись теперь появляется в SysProfileData(когда ставишь фильтры на детали,до этого не появлялась). И поле Key = Имеет структуру [Имя_страницы][Имя_детали]+"Filters". Как следствие - фильтры все так же не появляются. Правильно ли формируется для этого Key? или нужно другой шаблон/способ? Может не только 1 запись должа вставляться в таблицу а какая то вспомогательная?

Переписанное на BaseGridDetailV2 имеет вид:

methods: {

            setFilter: function(key, value, filtersValue) {

                var filters = this.get("DetailFilters");

                if (key) {

                    if (filters.find(key)) {

                        filters.remove(filters.get(key));

                    }

                    filters.add(key, value);

                    // 

                    this.saveFilter(key, filtersValue, value);

                    //

                } else if (value) {

                    value.each(function(filter) {

                        this.setFilter(filter.key, filter);

                    }, this);

                }

            },

            saveFilter: function(filterKey, filterValue, filter) {

                    if (!filterValue) {

                        return;

                    }

                    var sessionFilters = this.getSessionFilters();

                    var profileFilters = this.getProfileFilters();

                    var serializableFilter = this.getSerializableFilter(filter);

                    switch (filterKey) {

                        case "CustomFilters":

                            Terrasoft.each(filterValue, function(item) {

                                var f = item.filter = item.value || "";

                                var isSerializedFilter = (typeof f === "string" && f.indexOf("[") >= 0 && f.indexOf("]") >= 0 &&

                                    f.indexOf("{") >= 0 && f.indexOf("}") >= 0);

                                if (!isSerializedFilter) {

                                    item.filter = Terrasoft.encode(serializableFilter);

                                }

                            });

                            if (this.isNotEmpty(filterValue)) {

                                sessionFilters[filterKey] = profileFilters[filterKey] = filterValue;

                            } else {

                                delete sessionFilters.CustomFilters;

                                delete profileFilters.CustomFilters;

                            }

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                            this.set("ProfileFilters", profileFilters);

                            break;

                        case "FolderFilters":

                            sessionFilters[filterKey] = profileFilters[filterKey] = filterValue;

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                            this.set("ProfileFilters", profileFilters);

                            break;

                        case "FixedFilters":

                            filterValue.filter = Terrasoft.encode(serializableFilter);

                            profileFilters[filterKey] = {Fixed: filterValue};

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                            this.set("ProfileFilters", profileFilters);

                            break;

                        case "TagFilters":

                            serializableFilter.tags = filterValue;

                            profileFilters[filterKey] = [serializableFilter];

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                            this.set("ProfileFilters", profileFilters);

                            break;

                        default:

                            sessionFilters[filterKey] = profileFilters[filterKey] = [

                                {

                                    filter: filter.serialize()

                                }

                            ];

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                    }

            },

            getSessionFilters: function() {

                var storage = Terrasoft.configuration.Storage.Filters = Terrasoft.configuration.Storage.Filters || {};

                var sessionFilters = storage[this.name] = storage[this.name] || {};

                return sessionFilters;

            },

            getProfileFilters: function() {

                    return this.get("ProfileFilters") || {};

            },

            getSerializableFilter: function(filter) {

                    filter.serializationInfo = {serializeFilterManagerInfo: true};

                    var serializableFilter = {};

                    filter.getSerializableObject(serializableFilter, filter.serializationInfo);

                    return serializableFilter;

            },

            getFiltersKey: function() {

                    var schemaName = this.name;

                    var cardName = this.values.CardPageName;

                    return cardName + schemaName + "Filters";

            }

        },

Нравится

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

как я понимаю фильтры должны подгружаться со Storage - вот весь код функционал перенес и метод loadProfileFilters в котором идет заргрузка со Storage

define("BaseGridDetailV2", ["BaseGridDetailV2Resources", "ConfigurationEnums", "RightUtilities","TagConstantsV2",

    "ProcessModuleUtilities", "GridUtilitiesV2", "WizardUtilities", "QuickFilterModuleV2", "ProcessEntryPointUtilities"

], function(resources, enums, RightUtilities, TagConstantsV2) {

    return {

        messages: {},

        mixins: {},

        attributes: {

            "ProfileFilters": {

                    dataValueType: Terrasoft.DataValueType.CUSTOM_OBJECT

            },

            "IsDetailFiltersLoaded": {

                    dataValueType: Terrasoft.DataValueType.BOOLEAN,

                    value: false

            },

            "DetailFilters": {

                    dataValueType: Terrasoft.DataValueType.COLLECTION

            }

        },

        methods: {

            subscribeSandboxEvents: function() {

                this.callParent(arguments);

                var editPages = this.getEditPages();

                editPages.each(function(editPage) {

                    var typeColumnValue = editPage.get("Tag");

                    var cardModuleId = this.getEditPageSandboxId(editPage);

                    this.sandbox.subscribe("getCardInfo", function() {

                        var detailInfo = this.getDetailInfo();

                        var cardInfo = {

                            valuePairs: detailInfo.defaultValues || []

                        };

                        var typeColumnName = this.get("TypeColumnName");

                        if (typeColumnName && typeColumnValue) {

                            cardInfo.typeColumnName = typeColumnName;

                            cardInfo.typeUId = typeColumnValue;

                        }

                        return cardInfo;

                    }, this, [cardModuleId]);

                }, this);

                this.sandbox.subscribe("CardSaved", this.onCardSaved, this, [this.sandbox.id]);

                this.subscribeGetModuleSchema();

                this.subscribeFiltersChanged();

                this.subscribeGetShortFilterFieldsVisible();

                this.sandbox.subscribe("GetRecordInfo", this.getRecordInfo, this,

                    [this.getRecordRightsSetupModuleId()]);

                this.sandbox.subscribe("GetExtendedFilterConfig", this.getExtendedFilterConfig, this,

                    [this.getQuickFilterModuleId()]);

            },

            init: function(callback, scope) {

                this.callParent([function() {

                    this.mixins.WizardUtilities.canUseWizard(function(result) {

                        this.set("IsDetailWizardAvailable", result);

                        callback.call(scope);

                    }, this);

                }, this]);

                this.registerMessages();

                this.initDetailFilterCollection();

                //

                //this.initDetailFiltersCollection();

                this.loadProfileFilters();

                //

                this.initFilterVisibility();

                this.isFilterAdded();

                var sandboxId = this.getQuickFilterModuleId();

                this.sandbox.subscribe("InitFilterFromStorage", function() {

                    this.sandbox.publish("LoadedFiltersFromStorage", null, [sandboxId]);

                }, this, [sandboxId]);

            },

            loadProfileFilters: function(callback, scope) {

                    var isDetailFiltersLoaded = this.get("IsDetailFiltersLoaded");

                    if (isDetailFiltersLoaded) {

                        Ext.callback(callback, scope);

                        return;

                    }

                    var profileKey = Ext.String.format("profile!{0}", this.getFiltersKey());

                    Terrasoft.require([profileKey], function(profile) {

                        this.onLoadProfileFilters(callback, scope, profile);

                    }, this);

            },

            onLoadProfileFilters: function(callback, scope, profile) {

                    this.loadFiltersContainersVisibility(profile);

                    this.initFilterAttributes(profile);

                    this.set("IsDetailFiltersLoaded", true);

                    Ext.callback(callback, scope);

            },

            loadFiltersContainersVisibility: function(profile) {

                    if (profile) {

                        if (Ext.isDefined(profile.isFoldersContainerExpanded)) {

                            this.set("IsFoldersVisible", profile.isFoldersContainerExpanded);

                        }

                        if (Ext.isDefined(profile.isExtendedFiltersContainerExpanded)) {

                            this.set("IsExtendedFiltersVisible", profile.isExtendedFiltersContainerExpanded);

                        }

                    }

            },

            initFilterAttributes: function(profile) {

                    var sessionFilters = this.getSessionFilters();

                    this.set("SessionFilters", sessionFilters);

                    var profileFilters = Terrasoft.deepClone(profile);

                    var fixedSessionFilters = this._getFixedSessionFilters();

                    Terrasoft.each(profileFilters, this.applyFilters, this);

                    Terrasoft.each(fixedSessionFilters, this.applyFilters, this);

                    this.set("ProfileFilters", profileFilters);

            },

            _getFixedSessionFilters: function() {

                    var sessionFilters = this.getSessionFilters();

                    var primaryDisplayColumn = this.entitySchema.primaryDisplayColumn;

                    var customFilters = sessionFilters.CustomFilters;

                    var customFiltersPrimaryDisplayColumn = customFilters && customFilters.primaryDisplayColumn;

                    if (customFiltersPrimaryDisplayColumn && primaryDisplayColumn) {

                        var sessionFiltersFixed = {};

                        sessionFiltersFixed.CustomFilters = {};

                        sessionFiltersFixed.CustomFilters[primaryDisplayColumn.name] = customFilters;

                        sessionFilters = sessionFiltersFixed;

                    }

                    return sessionFilters;

            },

            applyFilters: function(filterValue, key) {

                    if (key.match(/filters/i) && !this.isNotEmpty(filterValue)) {

                        return;

                    }

                    var detailFiltersValue = this.get("DetailFiltersValue");

                    if (!Ext.isString(filterValue)) {

                        detailFiltersValue.removeByKey(key);

                        this._chooseFilterProccesing(filterValue, key);

                    }

                    if (key !== "FixedFilters") {

                        detailFiltersValue.add(key, filterValue);

                    }

            },

            initDetailFiltersCollection : function(){

                    this.set("ProfileFilters", {});

                    this.set("DetailFilters", this.Ext.create("Terrasoft.FilterGroup"));

                    this.set("DetailFiltersValue", this.Ext.create("Terrasoft.Collection"));

            },

            _chooseFilterProccesing: function(filterValue, key) {

                    var detailFilters = this.get("DetailFilters");

                    Terrasoft.each(filterValue, function(item, propName) {

                        if (item.key === TagConstantsV2.TagFilterKey || key === TagConstantsV2.TagFilterKey) {

                            this.applyTagFilter(key, item);

                        }

                        if (propName === "Fixed") {

                            this._applyFixedFilter(key, item);

                        }

                        if (item.filter) {

                            var filter = Terrasoft.deserialize(item.filter);

                            if (!detailFilters.contains(key)) {

                                detailFilters.add(key, filter);

                            }

                        } else if (item.primaryDisplayColumn) {

                            this.applyPrimaryColumnFilter(key, item);

                        } else if (item.folderInfo || item.folderType) {

                            this.applyFolderFilter(key, item);

                        }

                    }, this);

            },

            //

            initFilterFromStorage: function() {

                    this.loadProfileFilters(function() {

                        this.sandbox.publish("LoadedFiltersFromStorage", null, this.getFilterModulesIds());

                    }, this);

            },

            initFilterVisibility: function() {

                this.set("IsDetailFilterVisible", true);

                this.set("IsFilterAdded", true);

            },

            setFilter: function(key, value, filtersValue) {

                var filters = this.get("DetailFilters");

                if (key) {

                    if (filters.find(key)) {

                        filters.remove(filters.get(key));

                    }

                    filters.add(key, value);

                    // 

                    this.saveFilter(key, filtersValue, value);

                    //

                } else if (value) {

                    value.each(function(filter) {

                        this.setFilter(filter.key, filter);

                    }, this);

                }

            },

            saveFilter: function(filterKey, filterValue, filter) {

                    if (!filterValue) {

                        return;

                    }

                    var sessionFilters = this.getSessionFilters();

                    var profileFilters = this.getProfileFilters();

                    var serializableFilter = this.getSerializableFilter(filter);

                    switch (filterKey) {

                        case "CustomFilters":

                            Terrasoft.each(filterValue, function(item) {

                                var f = item.filter = item.value || "";

                                var isSerializedFilter = (typeof f === "string" && f.indexOf("[") >= 0 && f.indexOf("]") >= 0 &&

                                    f.indexOf("{") >= 0 && f.indexOf("}") >= 0);

                                if (!isSerializedFilter) {

                                    item.filter = Terrasoft.encode(serializableFilter);

                                }

                            });

                            if (this.isNotEmpty(filterValue)) {

                                sessionFilters[filterKey] = profileFilters[filterKey] = filterValue;

                            } else {

                                delete sessionFilters.CustomFilters;

                                delete profileFilters.CustomFilters;

                            }

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                            this.set("ProfileFilters", profileFilters);

                            break;

                        case "FolderFilters":

                            sessionFilters[filterKey] = profileFilters[filterKey] = filterValue;

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                            this.set("ProfileFilters", profileFilters);

                            break;

                        case "FixedFilters":

                            filterValue.filter = Terrasoft.encode(serializableFilter);

                            profileFilters[filterKey] = {Fixed: filterValue};

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                            this.set("ProfileFilters", profileFilters);

                            break;

                        case "TagFilters":

                            serializableFilter.tags = filterValue;

                            profileFilters[filterKey] = [serializableFilter];

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                            this.set("ProfileFilters", profileFilters);

                            break;

                        default:

                            sessionFilters[filterKey] = profileFilters[filterKey] = [

                                {

                                    filter: filter.serialize()

                                }

                            ];

                            Terrasoft.saveUserProfile(this.getFiltersKey(), profileFilters, false);

                    }

            },

            getSessionFilters: function() {

                var storage = Terrasoft.configuration.Storage.Filters = Terrasoft.configuration.Storage.Filters || {};

                var sessionFilters = storage[this.name] = storage[this.name] || {};

                return sessionFilters;

            },

            getProfileFilters: function() {

                    return this.get("ProfileFilters") || {};

            },

            getSerializableFilter: function(filter) {

                    filter.serializationInfo = {serializeFilterManagerInfo: true};

                    var serializableFilter = {};

                    filter.getSerializableObject(serializableFilter, filter.serializationInfo);

                    return serializableFilter;

            },

            getFiltersKey: function() {

                    var cardName = this.values.CardPageName;

                    var schemaName = this.name;

                    return cardName + schemaName + "Filters";

            }

        },

        diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/

    };

});

 

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

Главное чтобы вы брали фильтр по тому ключу, который сформировали.

При отладке фильтр возвращается? Где именно ошибка возникает?

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

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

this.showBodyMask()

поверх модульного окна, или справочника?

Нравится

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

По идее можно прокинуть config в функцию, а в конфиге указать селектор.

Подробнее посмотрите тут, в функции show.

Небольшой оффтоп: Там в функции createMask можно накидать и caption для маски, и прозрачность менять, и бэкграунд... Почему это нигде не задокументировано - ума не приложу. Наиполезнейшая вещь иногда.

По идее можно прокинуть config в функцию, а в конфиге указать селектор.

Подробнее посмотрите тут, в функции show.

Небольшой оффтоп: Там в функции createMask можно накидать и caption для маски, и прозрачность менять, и бэкграунд... Почему это нигде не задокументировано - ума не приложу. Наиполезнейшая вещь иногда.

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

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

Изображение удалено.

О компании

Студия 3grafika специализируется на продаже полиграфической продукции, промышленной цифровой печати и широкоформатной печати.

Предпосылки внедрения bpmonlne

Имеющегося в компании уровня автоматизации обработки заказов было недостаточно для максимальной эффективности работы менеджеров и скорости обслуживания клиентов. Студия решила внедрить bpm’online, чтобы оптимизировать процесс обработки заказов, тем самым увеличить объемы продаж.

Задачи внедрения bpm’online:

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

Выполненные настройки:

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

Для персонального информирования клиента о состоянии его заказа в bpm’online реализованы бизнес-процессы, которые автоматически отправляют email-уведомление клиенту при изменении стадии лида. Стадии, в свою очередь, адаптированы под процесс работы студии с помощью кейсов раздела [Лиды]. В зависимости от стадии лида создается индивидуальная страница на сайте компании, куда автоматически с помощью макросов подставляется номер заказа и тип потребности из карточки лида, а в письме генерируется ссылка на эту страницу. Также email-уведомление содержит рекламную информацию. Взаимодействие с клиентом продолжается до готовности заказа.

 

Кроме продукта bpmonline sales commerce, “Студия 3графика” выполняет рассылки и маркетинговые кампании через bpmonline marketing. Это позволяет привлекать новых и усиливать интерес к компании существующих клиентов. С этой целью с помощью bpm’online выполняются рассылки промо-кодов для получения скидок. Код необходимо регистрировать на сайте, от скорости его регистрации зависит размер скидки клиента. После того как клиент зарегистрирует код на сайте компании, данные попадают в bpm’online.  И эта информация используется для расчета персональных скидок в дальнейшем.

Также настроен трекинг событий сайта. Все данные о поведении клиента на сайте компании попадают в карточку клиента в bpm’online с дальнейшим использованием при сегментации и построении коммуникации с клиентом.

Результат

Внедрение bpm’online позволило:

  • увеличить объем продаж на 20%;
  • повысить качество обслуживания клиентов;
  • повысить лояльность клиентов к компании;
  • получить аналитику, которая позволяет сегментировать клиентов в зависимости от их   поведения и таргетировать коммуникации.

Нравится

Поделиться

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