Добрый день,
Есть деталь, необходимо чтобы на ней отображались лишь записи подходящие под определенные условия (по значениям полей записей), как добавить подобный фильтр?

Нравится

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

Олег, фильтрация настраивается путем указания соответствующих masterColumn и detailColumn при добавлении детали на страницу

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

define("CorrespondencePageV2", [],
	function() {
		return {
			entitySchemaName: "Document",
			details: /**SCHEMA_DETAILS*/{
				Order: {
					schemaName: "OrderDetailV2",
					entitySchemaName: "Order",
					filter: {
						masterColumn: "Id", // Id текущего Document
						detailColumn: "[OrderInDocument:Order:Id].Document" // Все Document, которые связаны с Order детали через таблицу OrderInDocument
					}
				}
			}/**SCHEMA_DETAILS*/,
			diff: /**SCHEMA_DIFF*/[
				{
					"operation": "insert",
					"parentName": "HistoryTabContainer",
					"propertyName": "items",
					"name": "Order",
					"values": { "itemType": Terrasoft.ViewItemType.DETAIL }
				}
			]/**SCHEMA_DIFF*/
		};
	});

Если же фильтрация сложная или требует предварительных вычислений, то лучше наверное воспользоваться filterMethod:

details: /**SCHEMA_DETAILS*/{
	OpportunityAccount: {
		schemaName: "OpportunityDetailV2",
		filter: {
			masterColumn: "Account",
			detailColumn: "Account"
		},
		filterMethod: "opportunityAccountFilter",
		captionName: "AccountOpportunitiesCaption"
	},
}/**SCHEMA_DETAILS*/,
methods: { 
	/**
	 * Метод фильтрации детали Продукты контрагента
	 * @protected
	 * @virtual
	 * @return {Terrasoft.FilterGroup} Возвращает группу фильтров
	 */
	opportunityAccountFilter: function() {
		var account =  this.get("Account");
		var accountId = this.Terrasoft.GUID_EMPTY;
		if (account && account.value) {
			accountId = account.value;
		}
		var opportunityId = this.get("Id");
		var filterGroup = new this.Terrasoft.createFilterGroup();
		filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;
		filterGroup.add("AccountFilter", this.Terrasoft.createColumnFilterWithParameter(
				this.Terrasoft.ComparisonType.EQUAL, "Account", accountId));
		filterGroup.add("OpportunityFilter", this.Terrasoft.createColumnFilterWithParameter(
				this.Terrasoft.ComparisonType.NOT_EQUAL, "Id", opportunityId));
		return filterGroup;
	},
}

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

"Толмачев Дмитрий Юрьевич" написал:

Олег, фильтрация настраивается путем указания соответствующих masterColumn и detailColumn при добавлении детали на страницу

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

define("CorrespondencePageV2", [],

        function() {

                return {

                        entitySchemaName: "Document",

                        details: /**SCHEMA_DETAILS*/{

                                Order: {

                                        schemaName: "OrderDetailV2",

                                        entitySchemaName: "Order",

                                        filter: {

                                                masterColumn: "Id", // Id текущего Document

                                                detailColumn: "[OrderInDocument:Order:Id].Document" // Все Document, которые связаны с Order детали через таблицу OrderInDocument

                                        }

                                }

                        }/**SCHEMA_DETAILS*/,

                        diff: /**SCHEMA_DIFF*/[

                                {

                                        "operation": "insert",

                                        "parentName": "HistoryTabContainer",

                                        "propertyName": "items",

                                        "name": "Order",

                                        "values": { "itemType": Terrasoft.ViewItemType.DETAIL }

                                }

                        ]/**SCHEMA_DIFF*/

                };

        });

Дмитрийпредоставил правильную рекомендацию.
За подобную бизнес-задачу отвечает masterColumn и detailColumn.

Спасибо, добавил filterMethod, работает, только одна проблема как мне сравнивать значение дат.
Необходимо отфильтровывать и выводить только те записи у которых ValidTill больше текущей даты.
Пробовал значение сравнивать с текущей датой в разных форматах (yyyy-mm-dd и dd/mm/yyyy), фильтр не отрабатывает

filterGroup.add("ValidTillGreaterFilter", this.Terrasoft.createColumnFilterWithParameter(
                                this.Terrasoft.ComparisonType.GREATER, "ValidTill", today));

Также вопрос, как фильтровать логические значение, сравнивать их с true или 1 ?

С датами, по-моему, так:

filterGroup.add("ValidTillGreaterFilter", this.Terrasoft.createColumnFilterWithParameter(
                                this.Terrasoft.ComparisonType.GREATER, "ValidTill", new Date()));

"Глобин Олег" написал:Также вопрос, как фильтровать логические значение, сравнивать их с true или 1 ?

Сравнивать с true.

Спасибо за помощь, добавил метод

productPriceFilter: function() {
    var filterGroup = new this.Terrasoft.createFilterGroup();
    filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.OR;
    filterGroup.add("ValidTillNullFilter", this.Terrasoft.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.IS_NULL, "UsrValidTill"));
    filterGroup.add("ValidTillGreaterFilter", this.Terrasoft.createColumnFilterWithParameter(
                    this.Terrasoft.ComparisonType.GREATER, "UsrValidTill", new Date()));
    return filterGroup;
},

и добавил деталь

"ProductPriceDetail": {
	"schemaName": "ProductPriceDetailV2",
	"filter": {
		"masterColumn": "Id",
		"detailColumn": "Product"
	},
	"filterMethod": "productPriceHistoryFilter"
},

Фильтрация по дате заработала, но теперь не работает базовая фильтрация по Id продукта и значению Product в детали.
Вопрос как добавить в filterMethod условие Id equal Product И (ValidTill > newDate() ИЛИ ValidTill isNull)
Т.е. добавить срази условие И и ИЛИ в один фильтр, т.к. изменение

filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.OR;

меняет отношения сразу между всеми условиями

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

Вам необходимо создать дополнительную группу фильтров, а существующую filterGroup использовать внутри неё:

productPriceFilter: function() {
	var filterGroup = new this.Terrasoft.createFilterGroup();
	filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.OR;
	filterGroup.add("ValidTillNullFilter", this.Terrasoft.createColumnFilterWithParameter(
		this.Terrasoft.ComparisonType.IS_NULL, "UsrValidTill"));
	filterGroup.add("ValidTillGreaterFilter", this.Terrasoft.createColumnFilterWithParameter(
		this.Terrasoft.ComparisonType.GREATER, "UsrValidTill", new Date()));
	var mainFilterGroup =  new this.Terrasoft.createFilterGroup();
	mainFilterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;
	mainFilterGroup.addItem(filterGroup);
	// добавляете фильтр по Id продукта
	return mainFilterGroup;
},

Спасибо

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

Добрый день!

Скажите, пожалуйста, какими способами в BPM Online ITIL можно настроить автоматическое заведение заявок из электронной почты ( и можно ли вообще).

Спасибо

Нравится

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

Добрый день, Дарья!

В bpm’online ITIL service реализована функциональность автоматической отправки email-сообщений по обращениям.
Email-сообщение отправляется клиенту при регистрации, взятии в работу, разрешении, отмене, отклонению по SLA и закрытии его обращения.
Для отправки сообщений выполните предварительную настройку:

• В системной настройке“E-mail службы поддержки” укажите почтовый ящик, который будет использоваться для автоматической отправки email-сообщений

У меня вопрос в другом был совсем) - я спрашивала про автоматическое заведение заявок из электронной почты.

Для автоматического создания обращения по входящему е-mail, в системной настройке “E-mail службы поддержки” укажите почтовый ящик поддержки.

Затем, необходимо ввести пароль от общего ящика и поставить галку в графе «Использовать как общий ящик»
[IMG]http://s020.radikal.ru/i701/1507/9e/17b4df9c6094.jpg[/IMG]
Таким образом, при входящем e-mail на указанный ящик будет автоматически создано новое обращение.

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

Добрый день.
Делаю все также но Обращение не создается.
Письмо продолжает после получения находиться "Не обработанным" в папке "Входящие"
В письме определен Контрагент и Контакт. А Активность/Обращение не подлинковано.
Может есть еще настройки?

Для автоматической регистрации обращения по входящему email для версии продукта 7.6 необходимо выполнение следующих условий:
1. В справочнике «Список почтовых ящиков для регистрации обращений» указать email, при поступлении письма на который, будет формироваться обращение в системе.
2. В системной настройке «E-mail службы поддержки» указать тот же ящик, что указан при выполнении пункта 1. Если Вы в справочнике указали несколько email, то в системной настройке укажите тот ящик, который будет использоваться по умолчанию.
3. В системной настройке «Автоматический запуск процесса "Регистрация инцидента по входящему email"» необходимо проставить признак активности в графе «Значение по умолчанию».
Если данные введены корректно, то их должно быть достаточно для автоматической регистрации обращения по входящему email.

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

Получилось.
Спасибо.

Скажите а Обращения создаются с категорией "инцидент". Как то можно изменить это в уже созданном Обращении на "Запрос на обслуживание"?
Возможно ли настроить чтоб было "Запрос на обслуживание" при автоматическом создании из письма?

Добрый день, Павел!

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

Еще добавлю описание принципиального отличия между ними:
• ЗАПРОС НА ОБСЛУЖИВАНИЕ — обращение, поступающее в службу поддержки в рамках нормального функционирования сервиса. Например, запрос на установку нового рабочего места или настройку телефонной линии.
• ИНЦИДЕНТ — событие, которое не является частью стандартной работы сервиса и которое может повлечь за собой прерывание либо ухудшение качества сервиса. Например, запрос на ремонт оборудования или восстановление телефонной связи после сбоев.

Спасибо.
Я так и думал и этого очень недостаточно на данный момент.
А работы по реализации данного функционала идут? Есть какие то планы по срокам?

Добрый день, Павел! Данный функционал, реализован в 7.7. При регистрации обращения, поле остается пустым, а Вы самостоятельно сможете выбрать "инциндент" это, либо "запрос на обслуживание"

Добрый день, Павел!
Данный функционал, реализован в 7.7. При регистрации обращения, поле остается пустым, а Вы самостоятельно сможете выбрать "инцидент" это, либо "запрос на обслуживание"

Добрый день!

Версия bpm online 7.9.1
Почта приходит, письма отображаются, но обращения не регистрируются.
Почтовый провайдер Exchange
В "Журнале процессов" по процессу Регистрация обращения по входящему письму:
Подпись Состояние Дата начала Описание ошибки
Email to support Завершен 04.05.2017 13:58
Завершен 04.05.2017 13:58
Register incident Завершен 04.05.2017 13:58

Настроено все как в видео уроке "Настройка обработки обращений по каналу Email в bpm’online".
Раньше был настроен IMAP, все работало.
Потом необходимо было изменить почтовый ящик.
Сейчас перевели почту на Exchange (по рекомендации техподдержки Террасофт)

Ольга, добрый день!
В версии продукта 7.9.0 и выше есть много нового функционала по работе с нежелательной почтой.
Необходимо проверить активность (письмо) не является ли данное письмо автоответом и не попадает ли оно под параметры указанные в справочнике "Черный список email адресов и доменов для регистрации обращений".
Так же, прошу обратить Ваше внимание, что регистрация обращения происходит только от имени пользователей у которых есть лицензия на продукт Service. Процесс регистрации запускается от имени пользователя, который выполняет синхронизацию с почтой, если не корректно настроена синхронизация (ее может запустить любой пользователь), то есть вероятность что пользователь у которого нет лицензий и запустит процесс, который в свою очередь упадет с ошибкой.

Отправьте тестовое письмо со своего личного или рабочего ящика и проверьте функционал регистрации. И, обязательно, проверьте корректность указанного email в справочнике "Список почтовых ящиков для регистрации обращений".

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

Здравствуйте, Коллеги!

Есть деталь, добавленная на несколько страниц. Необходимо реализовать разную клиентскую JavaSdcript логику в зависимости от того, на какую странице добавлена деталь. Подскажите, пожалуйста, как это сделать из JS.

Спасибо, Коллеги!

Нравится

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

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

Для решения задачи следует:
// Взять информацию о детали
var detailInfo = this.sandbox.publish("GetDetailInfo", null, [this.sandbox.id]) || {};
// Имя карточки, на которой размещена деталь
var cardPageName = detailInfo.cardPageName;

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

Спасибо за ответ!
Однако вылетает исключение на строчке

var detailInfo = this.sandbox.publish("getDetailInfo", null, [this.sandbox.id]) || {};

Текст исключения

Uncaught i {message: "Message getDetailInfo is not defined in undefined module"}

Сокращенный код детали:

define("UsrUsrVacancyCandidates1PageV2", ["GeneralDetails", "BusinessRuleModule", "ConfigurationConstants",
	"LookupUtilities"
], function(GeneralDetails, BusinessRuleModule, ConfigurationConstants, LookupUtilities) {
	return {
		entitySchemaName: "UsrVacancyCandidates",
		details: /**SCHEMA_DETAILS*/ {} /**SCHEMA_DETAILS*/ ,
		diff: /**SCHEMA_DIFF*/ [{
			"operation": "insert",
			"name": "UsrVacancies0084c888-fcc2-467b-b586-53b355ca0765",
			"values": {
				"layout": {
					"colSpan": 12,
					"rowSpan": 1,
					"column": 0,
					"row": 0,
					"layoutName": "Header"
				},
				"bindTo": "UsrVacancies",
				"enabled": {
					"bindTo": "getUsrVacanciesEnabled"
				}
			},
			"parentName": "Header",
			"propertyName": "items",
			"index": 0
		}] /**SCHEMA_DIFF*/ ,
		attributes: {
		methods: {
			getUsrVacanciesEnabled: function() {
				// Get detail info
				var detailInfo = this.sandbox.publish("GetDetailInfo", null, [this.sandbox.id]) || {};
				// Get card name which hosts the detail
				var cardPageName = detailInfo.cardPageName;
				var vacanciesCardPageName = "UsrVacanciesPage";
				return cardPageName !== vacanciesCardPageName;
			}
		},
	};
});

Сообщение GetDetailInfo и метод getDetailInfo доступны в контексте детали, поэтому их можно вызывать в контексте детали:
var detailInfo = this.sandbox.publish("GetDetailInfo", null, [this.sandbox.id])|| {};
var detailInfo = this.getDetailInfo();

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

Код выше это код разметки детали, а не карточки. Если я оттуда вызову this.name я получу имя страницы с разметкой детали. А мне нужно получить имя страницы карточки, на которую добавлена деталь.
Вы не могли бы более подробно объяснить про "контекст детали"? Где именно я должен разместить указанные Вами строки кода, чтобы они оказались "в контексте детали"?

// v7.5
getUsrVacanciesEnabled: function() {
       var defaultValues = this.getDefaultValues();
       if (!Ext.isEmpty(defaultValues)) {
             return defaultValues.some(function(value){
                    return (value.name === "UsrCandidates")
             })
       }
}
 
// v7.6
getUsrVacanciesEnabled: function() {
       var value = this.getDefaultValueByName("UsrCandidates");
       return (!Ext.isEmpty(value));
}

Спасибо, работает!
Хотя способ конечно немного чудной)

вот это еще нашёл в bpm:

var cardPageName = this.get("CardPageName");

var OrderId = this.get("MasterRecordId");
Показать все комментарии

Потрібно створити фільтр, який би гарантував пусту вибірку.
Я собі так уявляю, що фільтр має реалізовувати умову типу 0=1.
Але всі методи на створення фільтрів так чи інакше одним з атрибутів мають поле.

Як правильно реалізувати фільтр ?

Нравится

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

Может, такое сработает?

esq.CreateIsNullFilter("Id");

А [Id] ні за яких умов не стане Guid.Empty() ?

Оно же первичный ключ. Кроме того, фильтр проверяет не Guid.Empty (из нулей), а Null.

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

Добрый день, только начинаю изучение данного ПО.
Столкнулся с таким вопросом, нужно получить результирующее поле по определенной формуле.
Я так полагаю что всё это делается по следующему пути: я открываю конфигурацию, там в Custom нахожу нужную форму, в ней создаю событие "перед сохранением" и там создаю процесс в который добавляю сценарий C# по расчету этих полей. Вот как в этом сценарии можно получить данные полей?
я так полагаю что

public virtual bool ScriptTask1Execute(ProcessExecutingContext context) {
                       
//так не работает
int result = Convert.ToInt32(UsrMargCoast.Value)+ 1;
UsrMargCoast.Value = result;

//так не понятно что написать где "dlData"
var Dataset = dlData.Dataset;
Dataset.Values('UsrMargCoast') = Dataset.Values('UsrMargCoast') + 1;

                }

или я вообще не в том краю?

Нравится

8 комментариев
//так не понятно что написать где "dlData"
var Dataset = dlData.Dataset;
Dataset.Values('UsrMargCoast') = Dataset.Values('UsrMargCoast') + 1;

Это синтаксис террасофта тройки

в BPM используйте вот такой скрипт

Entity.SetColumnValue("UsrMargCoast", Entity.GetTypedColumnValue<int>("UsrMargCoast")+1);

Добрый день!

Данное решение описано для embeded process - обработчиков, которые запускаются по событиям объекта.
Данную задачу можно реализовать через бизнес процесс без написания не единой строки кода.
Создайте новый бизнес процесс в дизайнере процессов. Создайте новый параметр бизнес процесса с типом уникальный идентификатор (назовем его "Id записи"). Приступим к реализации бизнес процесса.
Бизнес процесс будет иметь два стартовых элемента - сигнала:

  1. При добавлении новой записи
  2. При изменении существующей записи

После каждого стартового сигнала, используйте элемент "Формула". Этим элементом мы запишем Id записи, по которой запускается процесс, в параметр "Id записи".
Объеденим две ветки, используя элемент "Исключающее ИЛИ".
После исключающего ИЛИ, используйте "Чтение данных". Выберите нужный объект (раздел) и в фильтре сравните Id с параметром "Id записи".
Далее, используйте элемент "Изменить данные". Выберите нужное поле и в заполните значение этого поля, расчитывая нужное Вам значение.

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

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

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

ааа, ещё не опубликовал

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

"Демьяник Алексей Олегович" написал:Создайте новый параметр бизнес процесса с типом уникальный идентификатор (назовем его "Id записи")
не где не могу найти где они создаются(((

На скриншоте отображена страница со свойствами процесса.
Откройте свойства процесса. Если панели изображенной на скриншоте нет, тогда нажмите на стрелку, отмеченную в квадрате под номером 1.
Вверху будет ветка процесса. Нажмите правой кнопкой на "Parameters". Нажмите "Добавить" (квадрат под номером 2).

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

"Демьяник Алексей Олегович" написал:

На скриншоте отображена страница со свойствами процесса.

Откройте свойства процесса. Если панели изображенной на скриншоте нет, тогда нажмите на стрелку, отмеченную в квадрате под номером 1.

Вверху будет ветка процесса. Нажмите правой кнопкой на "Parameters". Нажмите "Добавить" (квадрат под номером 2).

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


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

"Демьяник Алексей Олегович" написал:Данную задачу можно реализовать через бизнес процесс без написания не единой строки кода.

всё сделал как описали. Спасибо. всё работает замечательно!

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

Как сделать что бы, при выборе поле "Контрагент" изображался список контактов привязанных к данному контрагенту? Фильтрация с помощью C# почему-то у меня не получилось.

Заранее большое спасибо.

Нравится

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

В обработчике события Init процесса страницы карточки надо дописать код вроде:

Page.ContactEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
        if (!Page.AccountEdit.Value.Equals(Guid.Empty)) {
                var filters = e.Filters;
                filters.Add(new Dictionary<string, object> {
           {"comparisonType", FilterComparisonType.Equal},
           {"leftExpressionColumnPath", "Account.Id"},
           {"useDisplayValue", false},
           {"rightExpressionParameterValues", new object[] {(Guid)Page.AccountEdit.Value}}});
 
        }
};

Большое спасибо. Заработала.

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

На разделе «Контрагент» ест 2 детали:
1. «Карьера контакта»
2. «Недавние Звонки»

На детали «Недавние Звонки» есть поле «Сотрудники» привязанный к справочнику «Карьера контакта». Но почему-то при нажатие на данное поле справочник открывается с пустым значением (реестром). Хотя на детали «Карьера контакта» фильтруется контакты связанных с соответствующему Контрагенту. Где я не правильно настроила? Прощу помочь.

Заранее большое спасибо.

Нравится

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

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

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

1.Имеем некоторый код,который отправляет данные на сервер.Получем данные в виде JSON.
2.Хочу эти данные обрабоать и отобразить в контрагентах.
3.Какие дейстивия мне пошагово надо сделать(какие вкадки открывать, что и куда писать)?

Нравится

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

Владимир, интеграция с внешними ресурсами возможна через протокол OData. Данные можно получить в формате JSON или XML.

С детальной документацией по запросам OData можете ознакомиться на http://www.terrasoft.ru/bpmonlinesdk/ по пути Статьи -> API BPMOnline -> OData, а именно:
http://www.terrasoft.ru/bpmonlinesdk/WorkWithBpmByOdata.html
http://www.terrasoft.ru/bpmonlinesdk/WorkWithBpmByOdataHttp.html

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

Здравствуйте, Николай!

Реализация полностью зависит от данных, которые Вы хотите получать. Примера, на основании которого можно реализовать получение любых данных, нет. Главное начать, а по точечным вопросам уже легче получить ответ:wink:.

Здравствуйте.
Вопрос следующий:
Вот у нас есть свой билинг и он может отдавать РОST запросы если оплата произведена. В запросе будет хранится информация об OrderId заказа и Email клиента что сделал оплату. Что мне нужно сделать чтобы bpmonline получил и обработал этот запрос и в счете поменялась состояние оплаты на оплачен полностью.

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

Создайте бизнес процесс ChangeOrderStatus с параметром OrderId. Элементом изменить данные Вы будете менять состояние счета, у которого Id совпадает с параметром процесса OrderId.

С биллинга отправляйте http запрос на адрес http[s]://<адрес_приложения_bpm'online>/0/ServiceModel/ProcessEngineService.svc/ChangeOrderStatus/Execute?OrderId='Здесь должен быть Id заказа'

Более подробно Вы можете узнать по ссылке.

Спасибо, Алексей.
А скажите еще. Может ли bpmonline отправлять запросы? Если да, то как это сделать?

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

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

Создайте бизнес процесс ChangeOrderStatus с параметром OrderId. Элементом изменить данные Вы будете менять состояние счета, у которого Id совпадает с параметром процесса OrderId.

С биллинга отправляйте http запрос на адрес http[s]://<адрес_приложения_bpm'online>/0/ServiceModel/ProcessEngineService.svc/ChangeOrderStatus/Execute?OrderId='Здесь должен быть Id заказа'

Более подробно Вы можете узнать по ссылке.


Я так понимаю это get запрос. А можна сделать Post запрос, ибо у нас еще одна задача - в запросе передать значения карточок контакта (150 полей в одной карточке) и они не поместятся все в строку.

В документации написано следующее:
"Запуск бизнес-процесса

Чтобы запустить в системе определенный бизнес-процесс, необходимо вызвать метод Execute сервиса ProcessEngineService.

Вызов метода Execute можно выполнять с помощью HTTP-запросов GET и POST."

Так что все поместится) Главное, чтобы параметра был с типом "Строка 500 символов".

Я так понял, Я после Post запроса получу в бизнесс-процессе (например) файл Json и присвою его параметру с типом "Строка 500 символов".
А как мне достать из этого вайла все нужные мне поля? Есть какой-то пример?
Спасибо вам большое за ваши ответы, Алексей!

У сервиса ProcessEngineService есть результирующий параметр ResultParameterName, результат которого может быть получен в результате выполнения бизнес-процесса. В этот параметр Вы можете записать JSON строку.

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

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

Как сделать чтобы иконка корректно отображалась в списке разделов и в области уведомлений?
И ещё один вопрос: можно ли сделать напоминание на деталь а не на раздел?

Версия 7.5

Нравится

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

Вячеслав, добрый день!

1. Если я правильно понял, то изображение для уведомлений можно добавить в модуле «NotificationsModule» (Рис. 1) (предварительно необходимо заместить).

Для корректного отображения необходимо, чтобы размер был 42х42 pixels и была заливка заднего фона (например, серый).

2. Такой возможности в приложении нет.

Заместил NotificationsModule, скопировал исходный код. Загрузил изображение, но получаю ошибку в консоли "Cannot read property 'source' of undefined"
Выяснил что ругается на эту функцию:

            /**
             * Создает контейнер для размещения текста о новых уведомлениях
             * @private
             * @return {Object} Возвращает экземпляр конфигурации контейнера
             */
            getMessageContainer: function() {
                debugger;
                return {
                    className: "Terrasoft.Container",
                    id: "messageContainer",
                    selectors: {wrapEl: "#messageContainer"},
                    classes: {wrapClassName: ["showNewNotificationContainer-class"]},
                    visible: {bindTo: "ShowNewNotificationsVisible"},
                    items: [
                        {
                            className: "Terrasoft.Button",
                            caption: {bindTo: "getShowNewNotificationText"},
                            classes: {textClass: ["showNewNotificationButton-class"]},
                            style: Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                            iconAlign: Terrasoft.controls.ButtonEnums.iconAlign.LEFT,
                            imageConfig: {
                                source: Terrasoft.ImageSources.URL,
                                url: Terrasoft.ImageUrlBuilder.getUrl(resources.localizableImages.More)
                            },
                            click: {bindTo: "onShowNewNotificationClick"}
                        }
                    ]
                };
            },

Как я понимаю не может получить путь к изображению в строке
"url: Terrasoft.ImageUrlBuilder.getUrl(resources.localizableImages.More)"
потому, что resources.localizableImages.More = undefined

Я так понимаю, что при замещении объекта, localizableImages не подтянулись. Допустим ActivityImage и DocumentImage я могу перезалить. А вот что такое More ?

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

Вячеслав, судя по сообщению:

"Ляутин Вячеслав Андреевич" написал:Заместил NotificationsModule, скопировал исходный код. Загрузил изображение, но получаю ошибку в консоли "Cannot read property 'source' of undefined"

У Вас не подгрузились ресурсы.

Есть не большая специфичность у модулей. При замещении модулей необходимо копировать полностью код, в ручную добавлять в структуру замещенного модуля, например, Images, т.е. копировать из родительского «ActivityImage», «DocumentImage» и т.д. И затем заново загружать изображения в поле «Изображение».
Также название в структуре для всех изображений необходимо задать новое (например, ActivityImageNew), а также изменить в коде на соответствующее название объекта.

Например:

imageConfig: {
source: Terrasoft.ImageSources.URL,
url:Terrasoft.ImageUrlBuilder.getUrl(resources.localizableImages.MoreNew)
},
click: {bindTo: "onShowNewNotificationClick"}
}

"Ляутин Вячеслав Андреевич" написал:
Я так понимаю, что при замещении объекта, localizableImages не подтянулись. Допустим ActivityImage и DocumentImage я могу перезалить. А вот что такое More ?

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

"Ляутин Вячеслав Андреевич" написал:
И в связи с чем вопрос почему на вкладке "Изображения" изображения не отображаются? Я бы мог оттуда их вытащить.

Колонка «Изображение» работает только на импорт файлов.
Изображение можно отобразить используя разметку страницу в браузере.

Например, можно поступить следующим образом, прописать в адресной строке:

https://название_сайта/0/img/source-code/hash/NotificationsModule/More

, где

NotificationsModule – название модуля
More – название изображения

И в результате можно сохранить изображение на рабочий стол.

Загрузил изображение для localizableImages.More

Ошибок нет и все картинки отображаются как и прежде. Т.е. стандартные разделы отображаются иконками с фоном. А мой кастомный раздел "Заявки" на прозрачном фоне, хотя в localizableImages.EmptyImage загрузил иконку с фоном.

На всякий случай загружаю скриншот исходного кода NotificationProvider для моего раздела

NotificationProvider

А еще пришлось переписывать все localizableStrings.

Вячеслав, как писал ранее:

«Есть не большая специфичность у модулей. При замещении модулей необходимо копировать полностью код, в ручную добавлять в структуру замещенного модуля, например, Images, т.е. копировать из родительского «ActivityImage», «DocumentImage» и т.д.»

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

Если данный способ не помог, то можно поступить следующим образом:

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

sozdanie_spravochnika_s_izobrazheniem.docx

- в SysImage найти ID нужного изображения;
- проапдейтить изображения в колонке LogoID для нужного раздела (таблица SysModule);
- почистить Redis и кэш браузера.

Кэш и редис конечно чистил.

Я пока не пробовал способ через справочник. Но в теории мне кажется это не совсем то, что мне надо. У меня уже есть иконка раздела и колонка LogoID в таблице SysModule заполнена для моего раздела "Заявки". Там у меня хранится иконка с прозрачным фоном как я понимаю. А если я вместо неё загружу с фоном тогда при смене цветовой схемы в списке разделов будет не корректно отображаться иконка.

И еще исходя из названия локализированной картинки EmptyImage - она используется когда у раздела нет иконки, а у меня то она есть.

Или я что-то не так понимаю?..

Вячеслав, Вам необходимо загрузить в SysImage изображение. Нет разницы каким способом Вы это сделаете (через новый справочник или например, можно загрузить через мастер раздела изображение а потом вернуть прежнюю).
Если Вы хотите:
1. иконку для левой панели, где размещаются разделы, то Вам необходима прозрачная иконка и проапдейтить колонку «Image32Id» (таблица SysModule);
2. иконку для правой панели (панель уведомлений), то Вам необходима иконка с фоном (заливкой) и проапдейтить колонку «LogoId» (таблица SysModule);

Т.е загружаете изображение, узнаете ID и обновить значение для соответствующей колонки.

Да! Вот именно это мне и нужно было, оказывается колонка "Image32Id" для левой панели а "LogoId" для правой!

Спасибо большое всё заработало!
NotificationsModule можно не трогать.

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

Есть задача считать кол-во переносов задачи.
Сделал поле "кол-во переносов" и когда у задачи дата завершения меняется, то +1 к переносам.
Потом может быть будет получена задача выводить список переносов (кто, на какой срок). Поэтому подумал, что может сделать в рамках аудита, но не понятно как в bpm сделать поле с запросом с sql (как в тройке можно было). Такое можно сделать в bpm?

Начал копать в сторону на событие перед сохранением записи. Но не понятно как получить старое значение колонки. Есть ли какое-нибудь свойство OldValue и как его получить?

Если нет, думаю над двумя костылями:
1) После загрузки данных, записывать значение в переменную и сравнивать с ней
2) В скрипте делать запрос к БД к этой активности (перед сохранением запись еще не изменена и там находится старое значение)

Какие есть пути решения?

Нравится

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

Добрый день, Александр Владимирович!

Для решения Вашей задачи используйте следующие возможности:
1) Создайте деталь с полями:

  • Старая дата начала
  • Новая дата начала
  • Старая дата окончания
  • Новая дата окнончания
  • Активности

Поля "Создал" и "Дата создания" - системные
Колонка связи с объектом Активности - Деталь.Активность=Активность.Id.
2) Создайте бизнес процесс с двумя входами:

  • При добавлении записи "Активность"
  • При изменении записи "Активность" в полях "Дата начала", "Завершение"

Логика следующая:
1) Первая запись будет создаваться при добавлении активности
2) Узнать старую дату начала Вы сможете в поле "Новая дата начала", старую дату окончания - в поле "Новая дата окончания", отсортировав записи на детали по дате создания по убыванию.
3) Количество переносов = (количество записей на детали - 1)

А в объекте Contact в процессе есть следующий метод NamePartColumnChanged, в котором как раз отслеживается старое значение:

return changedColumns.Any(column => {
return
column.Name == namePart &&
column.Value != null &&
!string.IsNullOrEmpty(column.Value.ToString()) &&
!column.Value.Equals(column.OldValue);
});

Так же в событии Saving доступно значение Entity.GetTypedOldColumnValue("FieldName"), которое можно записать в параметр, а потом в событии Saved уже сравнивать с текущим значением

Владимир, данный вариант предполагает хорошие навыки программирования. Мой вариант подойдет для пользователей, которые не владеют программированием.

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