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

В объекты [Продукт в заказе] и [Продукт в счете] добавилось вычисляемое поле [Цена со скидкой]. Встала задача перенесения значения этого поля из продукта в заказе в продукт в счете при создании счета на основе заказа. Подскажите, пожалуйста, как это сделать? Заранее благодарю!

Нравится

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

Попробуйте с помощью бизнес процесса, который стартует по сигналу создания счета:
https://academy.terrasoft.ru/documents/technic-bpms/7-8-0/obzor-vozmozh…

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

перенос продуктов из Заказа в Счет происходит при выполнение бизнес-процесса "CreateInvoiceFromOrder". Если вы Дмитрий добавили новые вычисляемые поля в таблицы продуктов Заказа и Счета и вам требуется их переносить. Тогда мой совет скопировать бизнес-процесс "CreateInvoiceFromOrder" с новым названием и отредактировать элемент бизнес-процесса "Добавить продукты в счет", добавив свои новые созданные поля. После сохранить и опубликовать процесс. Далее вам требуется заместить страницу редактирования OrderPageV2 и добавить в Методы следующий замещающий код: (пример)

     /**
     * Запускает процесс создания счета по заказу.
     * @private
     */
     createInvoice: function() {
          ProcessModuleUtilities.executeProcess({
               sysProcessName: "NewCreateInvoiceFromOrder",
                    parameters: {
                                          CurrentOrder: this.get("Id")
                                     }
          });
     }

где "NewCreateInvoiceFromOrder" - это наш созданный новый бизнес-процесс. Если вы Дмитрий желаете выполнить перенос продуктов другим способом, то прошу озвучить как вам требуется? спасибо!!!

Благодарю, Михаил! Но данный способ подходит, если счет создается из действия "Создать счет на основании заказа". В нашем случае счет создается со вкладки "Паспорт заказа" с детали "График поставок и оплат": "+"-> 100% предоплата -> "Создать" счет на строке "Полная оплата товара". Как запустить процесс в этом случае?

В этом случае Дмитрий процесс запускать не требуется, а требуется заместить и отредактировать схему "SupplyPaymentDetailV2", метод "getInvoiceInsertQuery". В данном методе происходит создание счета и копирование продуктов из заказа в счет. так же требуется не забыть заместить метод "getSupplyPaymentProductEntitySchemaQuery" и добавить в него свой новые созданные колонки.

"Дмитрий Д." написал:В нашем случае счет создается со вкладки "Паспорт заказа" с детали "График поставок и оплат": "+"-> 100% предоплата -> "Создать" счет на строке "Полная оплата товара". Как запустить процесс в этом случае?

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

Спасибо, Михаил! Действительно, рабочее решение, только вместо метода getInvoiceInsertQuery() правильнее переопределить getInvoiceProductInsertQuery(). Вот что у меня получилось в SupplyPaymentDetailV2:

getSupplyPaymentProductEntitySchemaQuery: function() {
	var esq = this.callParent(arguments);
 
	esq.addColumn("Product.UsrPriceWithDiscount", "UsrPriceWithDiscount");
	return esq;
},
 
getInvoiceProductInsertQuery: function(config, i) {
	var insert = this.callParent(arguments);
 
	var product = config.products.getByIndex(i);
	insert.setParameterValue("UsrPriceWithDiscount", product.get("UsrPriceWithDiscount"), this.Terrasoft.DataValueType.MONEY);	
	return insert;
}

Пожалуйста Дмитрий. Сейчас все получилось, что вы хотели? или еще остались вопросы?

Да, есть еще вопрос. При добавлении к заказу продукта у него автоматически рассчитывается [Сумма], [Сумма налога] и [Итого]. Мне нужно сюда же добавить логику расчета поля [Цена со скидкой]. Где я могу это сделать? Можно, конечно, в методе onEntityInitialized() карточки редактирования OrderProductPageV2, но мне кажется, что этим занимается какой-то бизнес-процесс.

"Дмитрий Д." написал:

Да, есть еще вопрос. При добавлении к заказу продукта у него автоматически рассчитывается [Сумма], [Сумма налога] и [Итого]. Мне нужно сюда же добавить логику расчета поля [Цена со скидкой]. Где я могу это сделать? Можно, конечно, в методе onEntityInitialized() карточки редактирования OrderProductPageV2, но мне кажется, что этим занимается какой-то бизнес-процесс.

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

Если я правильно вас понял Дмитрий, то речь идет об обновление полей Заказа, после добавления продукта в Заказ, весь расчет перечисленных вами полей происходит в бизнес-процессе схемы таблицы Продукты в заказе ("OrderProduct"), метод "RecalculateOrderAmount".

Если нужно пересчитывать поля в продукте заказа после сохранение заказа, то за это отвечает бизнес-процесс схемы таблицы Заказы метод "SetOrderProductCurrency"

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

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

"Дмитрий Д." написал:не совсем понятно, в какой схеме искать указанный вами метод?

Как выше написал Михаил, в схеме [OrderProduct].
Прикрепил скриншот для наглядности.

У нас в схеме [OrderProduct] нет такого метода, зато он есть в схеме [Order]. Каким образом возможно переопределить и дополнить этот метод в кастомном пакете?

Нужно просто заместить нужный Вам объект (в Вашем случае это [Order]). А уже в замещенном объекте можете переопределять этот метод в зависимости от своих потребностей. Если уже есть замещенный объект в пакете Custom, то просто открыть двойным кликом по методу и переопределить нужным Вам образом.

Давайте еще раз по порядку. Я переопределил схему [OrderProduct], открыл соответствующий ей процесс. Там есть методы UpdatePrimaryAmounts() и RecalculateOrderAmount() (как на скриншоте). Куда я могу вставить логику расчета кастомного поля объекта [OrderProduct], которая должна сработать при создании объекта (то есть при добавлении продукта в заказ)?

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

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

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

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

Здравствуйте! Встала задача добавить для сущности Заказы вычисляемое поле, которое представляет собой разность полей Итого (Amount) и Суперкомиссия (UsrSuperFee). Создал такое поле по примеру из документации. Но так как это поле заполняется только в модели при выполнении метода onEntityInitialized() при загрузке карточки редактирования заказа, появляется кнопка "Сохранить" для сохранения этого значения в базу. Если же вынести вычисляемое поле в раздел Заказов, то там в этом поле будут, естественно, одни нули, потому что метод onEntityInitialized() здесь не выполняется.

Подскажите, пожалуйста, как правильно готовить вычисляемые поля? Не нажимать же на кнопку "Сохранить" на каждом заказе, чтобы заполнить его!

Нравится

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

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

по данной ссылки, что вы предоставили в своем обращение все правильно и верно описано как создать Вычисляемое поле. И в приведенном примере в документации Функция  this.calculateBalance исполняется в методе  onEntityInitialized для того чтобы при открытии карточки принудительно происходил расчет данного поля, что приведен в примере. Если вам этого не требуется выполнять а требуется чтобы расчет происходил, только к примеру при изменение какого-либо поля, то функцию  calculateBalance из метода  onEntityInitialized требуется исключить. И тогда при каждом открытии выполняться данная функция не будет. Или добавить условия при исполнение которого выполнялась бы данная функция.

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

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

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

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

Да, именно эту задачу мне требуется решить.

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

В [#Object#]SectionPageV2 нет метода onEntityInitialized(). По этой причине поле не считается, т.к. метод не вызывается.
В [#Object#]SectionPageV2 есть метод initData(), который Вы можете расширить для решения этой задачи.

"Демьяник Алексей" написал:В [#Object#]SectionPageV2 нет метода onEntityInitialized(). По этой причине поле не считается, т.к. метод не вызывается.

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

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

Алексей, не подскажете, как из initData() получить доступ к коллекции элементов заказов раздела, чтобы вставить логику расчета разности двух полей и поместить его в третье?

"Дмитрий Д." написал:Алексей, не подскажете, как из initData() получить доступ к коллекции элементов заказов раздела, чтобы вставить логику расчета разности двух полей и поместить его в третье?

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

при инициализации раздела и получение Потока Данных у вас не получится выполнить заполнение Вычисляемого поля. Для этого вам требуется создать отдельный бизнес-процесс который при срабатывание определенных условий на входе пересчитывал бы Одно данное поле в базе данных, а в разделе вы бы уже видели результат. Но и данный метод я бы сказал является ошибочным, так как если в Таблице будет Миллион записей, то на пересчет потребуется очень огромное количество времени и ресурсов. Это неверный подход. В опубликованной Вами ссылке Как добавить вычисляемое поле описан алгоритм создания вычисляемого поля для карточки редактирования. Рекомендую именно в карточки редактирования разместить данное вычисляемое поле. А в разделе еще раз повторюсь отображать только результат вычисления.

В дополнении к рекомендации заполнять данные в карточке, могу предложить для случаев, когда в карточке поле еще не рассчитано, но в реестре уже хочется видеть эту информацию:
1. Вывести в реестр данную физическую колонку, которую вы будете вычислять в карточке.
2. В схеме реестра, переопределить метод «addItemsToGridData», который срабатывает при загрузке порции данных в реестр. Т.к. реестр не отображает миллион строк, а только небольшими порциями (по 15 строк) удовлетворяющими фильтрацию, плюс при прокрутке вниз. Так же загружает все порциями, и в этот момент так же срабатывает метод «addItemsToGridData».
3. В методе для незаполненных строк, производить любые вычисления, и заполнять любые существующие колонки. (Важно: данные не уйдут в БД, а будут только информационными. В БД запись делайте при работе с карточкой.)
Пример переопределения метода, в котором я читаю и меняю поле Title строк. По аналогии можно читать и менять любое поле:

addItemsToGridData: function() {
   this.callParent(arguments);
 
   var gridDataItems = this.getGridData().getItems();
   gridDataItems.forEach(function(item) {
      var oldTitle = item.get("Title");
      item.set("Title", oldTitle + "!!!");
   }, this);
 
   console.log("new items loaded");
}

P.S. Так же думая об оптимизации при прокрутке реестра, не забудьте анализировать что поле уже заполнено к примеру так: if (item.get("Title")) { тут логика } что бы не выполнять лишние операции.
В моем случае это не имеет смысла, Title у меня и так всегда заполнен, и пример исключительно тестовый.

Еще немного оптимизации, анализ в методе только новой добавочной (15 строк) коллекции, зачем бегать по всему реестру, если там уже все рассчитано:

addItemsToGridData: function(dataCollection, options) {
	// forEach only new
	dataCollection.getItems().forEach(function(item) {
		var oldTitle = item.get("Title");
		item.set("Title", oldTitle + "!!!");
	}, this);
 
	this.callParent(arguments);
	console.log("new items loaded");
}

Спасибо Максим. Идея очень интересная. Попробую у себя так же протестировать. Только вот вопрос, что будет если колонка "Title" не будет добавлена в Реестр раздела. Ошибка будет или нет выдаваться. Попробую протестировать. Ведь пользователь любит добавлять и удалять преднастроенные колонки.

Максим, спасибо! Уже близко к истине. Только, насколько я понимаю, item в методе addItemsToGridData есть ViewModel, поэтому если какой-либо столбец не выводится в разделе, доступ к нему посредством метода item.get() невозможен. В этом случае нужно будет получать значения полей запросом к базе.

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

Благодарю.

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

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

как решить вашу задачу описал Илья Мотков в следующем инциденте. Последняя активность в реестре контрагентов посмотрите пожалуйста и по аналогии можно решить и вашу задачу.

Да, там всегда есть ID записи, по которой можно сделать esq, но в этом мало смысла, так как есть метод «initQueryColumns», который и определяет список загружаемых в модель колонок.
Можно заставить загружаться все колонки в модель, что несколько замедлит загрузку реестра:

initQueryColumns: function(esq) {
	this.callParent(arguments);
	this.addAllColumns(esq);
}

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

initQueryColumns: function(entitySchemaQuery) {
   this.callParent(arguments);
   if (!entitySchemaQuery.columns.contains("IntegrationId")) {
      entitySchemaQuery.addColumn("IntegrationId");
   }
},

Разом изменить все существующие записи, можете либо бизнес процессом, либо SQL запросом.
В первом случае логику будете писать на C#, во втором на Transact-SQL.
Это если вы имеете в виду все-все существующие записи, а не только те, что выведены в реестр. И имеете в виду физические данные в базе данных, а не только информационно в реестре. Так как напоминаю, что в реестр данные грузятся порционно.

"Щиголь Максим" написал:Разом изменить все существующие записи, можете либо бизнес процессом, либо SQL запросом.
В первом случае логику будете писать на C#, во втором на Transact-SQL.

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

Можете подсказать пример написания и выполнения SQL-скрипта в bpm'online 7.7? Что-то не нахожу подобного в документации.

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

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

"Дмитрий Д." написал:

Можете подсказать пример написания и выполнения SQL-скрипта в bpm'online 7.7? Что-то не нахожу подобного в документации.

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

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

"Дмитрий Д." написал:Собственно, необходимо для каждого Order вычесть из поля Amount поле UsrSuperFee и вставить результат в поле UsrAmountWithSuperFee.

вот Дмитрий сам запрос на обновление

update p set
p.UsrAmountWithSuperFee = p.Amount - p.UsrSuperFee
from Order as p

Спасибо, Алексей и Михаил, за помощь!
Я так решил: если нужно, чтобы вычисляемое поле объекта получало значение в зависимости от значений других полей, то сначала необходимо прогнать всю таблицу sql-запросом для заполнения вычисляемого поля, а уже в карточке редактирования объекта реализовывать логику пересчета его значения при необходимости.

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

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

Может ли кто-нибудь подсказать, есть ли возможность указать явный порядок пунктов меню Печать в карточке редактирования сущности (например, Заказа)? Когда пунктов меню становится много, сложно найти нужный.

Заранее спасибо!

Нравится

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

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

Такая возможность есть. Вам необходимо переопределить PrintReportUtilities, либо переопределить отдельные его методы на странице редактирования/в разделе нужного объекта.

Алексей, спасибо за ответ! Не могли бы вы привести пример? Или хотя бы ссылку на документацию по методам PrintReportUtilites?

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

Могу ответить точечно, но не по всему миксину:smile:

Рекомендую посмотреть тему http://www.community.terrasoft.ru/blogs/15581

Алексей, премного благодарен!

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

initSectionPrintForms: function(callback, scope) {
	var reportsEsq = this.getModulePrintFormsESQ();
	reportsEsq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
			"ShowInSection", true));
	reportsEsq.getEntityCollection(function(result) {
 
		if (result.success && !result.collection.isEmpty()) {
			// Коллекция пунктов меню
			var printFormsMenuCollection = result.collection;
 
			/* Тут можно анализировать свои «условия» и удалять те или иные элементы printFormsMenuCollection */
			printFormsMenuCollection.collection.items = printFormsMenuCollection.collection.items.sort(
				function(item1, item2) {
					if (item1.values.Caption > item2.values.Caption) {
						return 1;
					}
					if (item1.values.Caption < item2.values.Caption) {
						return -1;
					}
					return 0;
				});
 
			this.preparePrintFormsMenuCollection(printFormsMenuCollection);
			printFormsMenuCollection.each(function(item) {
				item.set("Click", {bindTo: "generateSectionPrintForm"});
			}, this);
			var printMenuItems = this.preparePrintButtonCollection(this.moduleSectionPrintFormsCollectionName);
			printMenuItems.loadAll(printFormsMenuCollection);
			this.set(this.moduleSectionPrintFormsCollectionName, printMenuItems);
			this.getSectionPrintButtonVisible();
		}
 
		if (callback) {
			callback.call(scope || this);
		}
	}, this);
}

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

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

Уточните, пожалуйста, в схеме раздела также добавлена сортировка печатных форм или такая сортировка выполняется только на странице редактирования?

Алексей, в разделе также добавлена сортировка. Я отключал на время сортировку в разделе, но описанное мною поведение сохранилось.

Здравствуйте, почему вы говорите о том, как ведет себя сортировка в карточке, и после обновления карточки. Если пишите метод «initSectionPrintForms». Так еще и речь заходит за написание этого кода в схеме секции.
Дело в том что, я было подумал что вы столкнулись с разницей работы кода в комбинированном режиме (когда слева видна часть секции, либо она спрятана за стрелочкой), и чистом режиме карточки (в который как раз можно попасть по F5).
Но метод initCardPrintForms, (CardPrint!) написанный в схеме страницы, отрабатывает как в комбинированном режиме, так и в чистом режиме карточки.
Вот к примеру чуть подправив ваш метод сортировки, написал его в initCardPrintForms, и в обоих режимах карточки, обратная сортировка работает:
Изначальный код метода брать необходимо из "PrintReportUtilities" т.к. от версии к версии он может разнится.

define("OpportunityPageV2", ["OpportunityPageV2Resources", "GeneralDetails", "StorageUtilities"],
function(resources, GeneralDetails, StorageUtilities) {
	return {
		entitySchemaName: "Opportunity",
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[
		]/**SCHEMA_DIFF*/,
		attributes: {},
		methods: {
			initCardPrintForms: function(callback, scope) {
				var reportsEsq = this.getModulePrintFormsESQ();
				var entitySchemaName = this.getEntitySchemaName();
				reportsEsq.filters.addItem(Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
					"ShowInCard", true));
				StorageUtilities.GetESQResultByKey({
					esq: reportsEsq,
					key: "ShowInCard_PrintForm_" + entitySchemaName,
					callback: function(result) {
						if (this.destroyed) {
							return;
						}
						if (result.success && !result.collection.isEmpty()) {
							var printFormsMenuCollection = result.collection;
 
							printFormsMenuCollection.collection.items = printFormsMenuCollection.collection.items.sort(
								function(item1, item2) {
									if (item1.values.Caption > item2.values.Caption) {
										return -1;
									}
									if (item1.values.Caption < item2.values.Caption) {
										return 1;
									}
									return 0;
								}
							);
 
							this.preparePrintFormsMenuCollection(printFormsMenuCollection);
							printFormsMenuCollection.each(function(item) {
								item.set("Click", {bindTo: "generateCardPrintForm"});
							}, this);
							var printMenuItems = this.preparePrintButtonCollection(this.moduleCardPrintFormsCollectionName);
							printMenuItems.loadAll(printFormsMenuCollection);
							this.set(this.moduleCardPrintFormsCollectionName, printMenuItems);
							this.getCardPrintButtonVisible();
						}
						if (callback) {
							callback.call(scope || this);
						}
					},
					scope: this
				});
			}
		},
		rules: {},
		userCode: {}
	};
});

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

Максим, прошу прощения за двусмысленность. Я привел код initSectionPrintForms секции, но вел речь о методе initCardPrintForms.

Ваш код я попробовал, результат тот же. Может, причина в различиях версии продукта (у нас BMP'Online Sales 7.7.0.2293)?

Скажите, а где я могу посмотреть код PrintReportUtilities?

Как ни странно, но в схеме PrintReportUtilities. :smile:

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

Всем спасибо за помощь! Решил проблему добавлением логики сортировки нужной колонки при составлении запроса к базе, переопределив метод getModulePrintFormsESQ() в OrderPageV2:

/**
 * Возвращает клиентский запрос для получения печатных форм.
 */
getModulePrintFormsESQ: function() {
	var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
		rootSchema: SysModuleReport,
		isDistinct: true,
		rowViewModelClassName: "Terrasoft.BasePrintFormViewModel"
	});
	esq.addColumn(SysModuleReport.primaryColumnName);
	var captionColumn = esq.addColumn("Caption", "NonLocalizedCaption");
 
	// Устанавливает порядок сортировки колонки
	captionColumn.orderPosition = 0;
	captionColumn.orderDirection = Terrasoft.OrderDirection.ASC;
	...
	return esq;
}

То же самое сделал в методе getModulePrintFormsESQ() в OrderSectionV2 для раздела.

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

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

Нравится

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

Олег, уточните, о каких именно ссылках идет речь?

Речь идет о ссылках ведущих в записи других разделов

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

Вам необходимо заместить соответствующий модуль. Для списка это DashboardGridModule.

Спасибо, еще небольшое уточнение - если для графика нажать показать данные - оттуда тоже можно перейти в другие разделы, за это тоже отвечает DashboardGridModule?

"Сафонов Олег" написал:

Спасибо, еще небольшое уточнение - если для графика нажать показать данные - оттуда тоже можно перейти в другие разделы, за это тоже отвечает DashboardGridModule?

Не совсем. У каждого типа итогов свой модуль.

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

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

Путём проб и ошибок выяснилось, что эта ошибка возникает после использования в элементе "Задача" и "Звонок" события "После сохранения записи"(Ошибка возникает даже если в указанное поле вписать только комментарий). Как быть с решением указанной проблемы?

И ещё один вопрос: Как обратиться к параметру в элементе Скрипт?
Обращение в виде LeadId(идентификатор Лида) - вызывает ошибку при публикации БП.

Нравится

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

Предположим у нас есть параметр процесса Text с типом "Строка".
В версии 760 (и более ранних) значение этого параметра можно было получить следующим кодом:
var leadId = LeadId;
В версии 770 этот код будет выглядеть по другому:
var leadId = Get("LeadId");

Что Вы хотите реализовать в событии "После сохранения записи"?

"Демьяник Алексей" написал:В версии 770 этот код будет выглядеть по другому:
var leadId = Get("LeadId");

"Демьяник Алексей" написал:В версии 770 этот код будет выглядеть по другому:
var leadId = Get("LeadId");

А как передать значение параметру? В документации информации не нашёл.

"Демьяник Алексей" написал:Что Вы хотите реализовать в событии "После сохранения записи"?

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

"Коновалов Игорь" написал:

А как передать значение параметру? В документации информации не нашёл.

Топики:

http://www.community.terrasoft.ru/forum/topic/16294
http://www.community.terrasoft.ru/forum/topic/16335
http://www.community.terrasoft.ru/forum/topic/16361
http://www.community.terrasoft.ru/forum/topic/11784
http://www.community.terrasoft.ru/forum/topic/13848
http://www.community.terrasoft.ru/forum/topic/12023
http://www.community.terrasoft.ru/forum/topic/9477

Академия:
http://academy.terrasoft.ru/documents/docs/technic/BPMS/7.7.0/BPMonline…
http://academy.terrasoft.ru/documents/docs/technic/BPMS/7.7.0/BPMonline…
http://academy.terrasoft.ru/documents/?product=BPMS&ver=7.7.0

"Коновалов Игорь" написал:

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

Насколько мне известно это исправлено в последних версиях 7.7 (для sales enterprise это 7.7.0.2875).

Спасибо за информацию.

Добрый день!
Подскажите, пожалуйста, можно ли с помощью стандартных инструментов в дизайнере построить бизнес-процесс, который бы вызывался кнопкой из карточки физ.лица и автоматически создавал продажу и продукт в продаже?
Общая схема такая:
1. Есть заявка на продукт с сайта, в которой уже указан продукт
2. Сотрудник call-Центра связывается с клиентом, редактирует карточку заявки и карточку физ.лица.
3. Запускает бизнес-процесс создания продажи и продукта в продаже из карточки физ.лица
4. Этот же бизнес-процесс привязывает заявку к продаже

Здравствуйте, Дарья!

Данную задачу можно реализовать, но не стандартными инструментами.
Вам необходимо:
1) Добавить кнопку на страницу редактирования. Подробнее
2) В обработчик кнопки добавить логику запуска процесса (за пример можно взять действие "Отправить на визирование" на странице редактирования раздела "Договоры"). В процесс необходимо передать Id открытой записи.
3) Собственно реализовать процесс

Алексей, спасибо за ответ!
Не отображается страница по ссылке "Подробнее" (ошибка 404, страница не найдена).

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

Поправил.

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

Подскажите, каким образом можно скопировать (создать по аналогии) раздел "Итоги"?

Нравится

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

Олег, уточните, какую бизнес задачу Вы хотите решить данным способом?

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

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

"Сафонов Олег" написал:создавать раздел, а потом удалять/скрывать стандартное представление

Этот способ будет намного менее трудоемким и более эффекстивным, чем создание еще одного раздела Итоги.

Этот раздел нестандартен, и не имеет такой гибкости в конфигурировании, как остальные разделы системы. bpm'online c несколькими разделами итогов еще не встречал.

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

В карточке задачи при нажатии на кнопку в CTI панели должно появляться уведомление с этой задачей. Делаю с помощью БП (добавляю запись в объект "Уведомления" с типом Notification). Но уведомление создается только если стоит галочка "Напомнить ответственному". Каким образом можно добавить уведомление, если напоминание в задаче отключено?

Нравится

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

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

Необходимо заполнять поля "Кому", "Время", "Заголовок", "Объект", "Уникальный заголовок". И уведомления должно быть по задаче не в конечном состоянии.

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

Здравствуйте, Олег!

Попробуйте заполнить дополнительно поле "Тип уведомления" (RemindingType). Выберите из справочника "Уведомление" (Reminding).

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

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

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

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

Сообщение нужно формировать на клиенте.

Версия BPM 7.7.0.2325

Нравится

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

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

Уведомления ленты приходят в трех случаях:
1) Пользователь был упомянут через @ (например, @Supervisor)
2) Комментарий пользователя был прокомментирован
3) Комментарий пользователя понравился другому пользователю.

В иных случаях уведомления ленты не приходят.
Для того, чтобы сообщение появилось в ленте пользователей, которые подписаны на запись, Вам достаточно просто создать новую запись в объекте "Сообщение/Комментарий" (SocialMessage). Поля, которые необходимо заполнить:
1) Схема - Uid схемы контрагент
2) Экземпляр объекта - Id записи в объекте "Контрагент"
3) Сообщение/комментарий - само сообщение.

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

"Дашкевич К." написал:

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

Теоретически - это возможно. Практически - нужно пробовать и экспериментировать. Можно сделать процессом (предполагаю, что 3 настраиваемых элемента будет достаточно).

1) Стартовый сигнал по событию добавления записи в объект "Сообщение/комментарий"
Условие: Родительское сообщение - не заполнено

2) Чтение данных по объекту "Сообщение/комментарий" с фильтром Id = Идентификатор стартового сигнала

3) Добавление данных в объект "Уведомления ленты" в режиме выборки из объекта "Подписка"
Фильтр выборки: Экземпляр объекта == Экземпляр объекта из чтения данных
Добавляем:
Владелец - Из выборки Пользователь.Контакт (как вариант Пользователь.Контакт.Id)
Сообщение - идентификатор стартового сигнала
Тип - выберите нужный тип из справочника "Тип уведомления ESN" (или предварительно добавьте его)
Прочитанное - false.

4) Конец процесс

Идея такая. Прошу Вас по факту реализации отписаться, что было изменено и получилось ли осуществить данную задачку.:smile:

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

Всего хватает. Используйте существующий тип из справочника "Тип уведомления ESN" (например, Ваша запись была прокомментирована). В результате уведомление придет.

Алексей, так и делаю. Напрямую смотрю в таблицу ESNNotification записи есть, не прочитанные, но оповещения по ним нет. Также попробовал прокоментировать записи и лайкнуть, по этим действия тоже не приходят оповещения.
Подскажите в чем может быть дело? и возможно ли проверить работает ли механизм оповещения? где найти его реализацию?

Посмотрите реализацию ESNNotificationProvider, как он отбирает уведомления, как реализован ESNNotificationProcess Алексей уже рассказал, но может посмотрев реализацию в системе удастся понять в чем проблема

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

Александр, спасибо.

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

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

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

Подскажите пожалуйста что имеется ввиду. Не нашел четкого определения корневого объекта и что конкретно значит сообщение в консоли.

Нравится

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

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

Для анализа данной ошибки необходимо проверить, как создан объект данной детали, а так же её схему.
Пожалуйста, обратитесь в техническую поддержку Террасофт.

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

Здравствуйте! Использую версию BPMOnline 7.7.
Подскажите пожалуйста, как можно объяснить, а главное исправить странное поведение webSockets:
При запуске BPM устанавливается подключение, в консоли, как положено, появляется сообщение

WebSocket-connection opened for url:ws://myServer:MyPort/0/Nui/ViewModule.aspx.ashx

Буквально через несколько секунд простоя появляется следующее сообщение:
 
Tue Mar 01 2016 21:07:43 GMT+0300 (RTZ 2 (зима)) Channel closed. Reconnect..

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

Подскажите, в какую сторону копать? В текущем режиме работать с системой невозможно.

Нравится

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

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

В данной ситуации необходимо проверить настройки WebSocket на сервере и в файлах Web.config. Также рекоммендую проверить, нет ли на этом порту других приложений, которые мешают поддержанию соединения.

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

Здравствуйте, Павел!
На сервере развернуто не одно приложение. Для каждого в TerrasoftWebAPP в конфиге указан свой сокет.

"Павел Баштовой" написал:В данной ситуации необходимо проверить настройки WebSocket на сервере и в файлах Web.config.

Сейчас настройки выглядят следующим образом:

<wsService type="Terrasoft.Messaging.SuperWSService.SuperWSService, Terrasoft.Messaging.SuperWSService" defaultPort="21850" encrypted="false" portForClientConnection="44310" maxConnectionNumber="100" clearIdleSession="false" clearIdleSessionInterval="120" />

Параметр defaultPort для всех сайтов разный, а portForClientConnection одинаковый.
Если возможно, предоставьте, пожалуйста, пример правильной настройки.

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

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

Здравствуйте.
Так, на вскидку сложно ответить. Попробуйте остановить проблемные приложения и "просканить" порты, которые используются их web-соккетами на предмет доступности.

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

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