Добрый день!
Пример с использованием обратных связей
var servicePact = this.get("ServicePact");
if (!servicePact) {
return;
}
var filtersCollection = this.Terrasoft.createFilterGroup();
filtersCollection.add("ServiceItemByServicePactFilter", this.Terrasoft.createColumnFilterWithParameter(this.Terrasoft.ComparisonType.EQUAL,
"[ServiceInServicePact:ServiceItem].ServicePact", servicePact.value));

return filtersCollection;

выполняет следующий запрос
select * from ServiceItem
where exists(select * from ServiceInServicePact
where ServiceInServicePact.ServiceItemID = ServiceItem.ID and
ServiceInServicePact.ServicePactID = @value)

т.е. показываются только те сервисы, которые есть в этом сервисном договоре.

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

select * from ServiceCategory
where exists(select * from ServiceInServicePact
inner join ServiceItem on ServiceInServicePact.ServiceItemID=ServiceItem.ID
where ServiceItem.CategoryID = ServiceCategory.ID and
ServiceInServicePact.ServicePactID = @value)

Нравится

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

Попробовала такой вариант для вышеописанного запроса

var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "ServiceCategory"});
esq.addColumn("Id");
esq.filters.add("servicePactAndCategoryFilter", this.getServiceCategoryFilters());

где
getServiceCategoryFilters: function() {
var servicePact = this.get("ServicePact");
if (!servicePact) {
return;
}
var filtersCollection = this.Terrasoft.createFilterGroup();
filtersCollection.add("ServiceCategoryByServicePactFilter", this.Terrasoft.createColumnFilterWithParameter(this.Terrasoft.ComparisonType.EQUAL, "[ServiceInServicePact.ServiceItem:ServiceCategory].ServicePact", servicePact.value));
return filtersCollection;

но такой вариант не работает.

Интересует - насколько корректна конструкция ? filtersCollection.add("ServiceCategoryByServicePactFilter", this.Terrasoft.createColumnFilterWithParameter(this.Terrasoft.ComparisonType.EQUAL, "[ServiceInServicePact.ServiceItem:ServiceCategory].ServicePact", servicePact.value));

Аналогична ли она условию в запросе
select * from ServiceCategory
where exists(select * from ServiceInServicePact
inner join ServiceItem on ServiceInServicePact.ServiceItemID=ServiceItem.ID
where ServiceItem.CategoryID = ServiceCategory.ID and
ServiceInServicePact.ServicePactID = @value) ?

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

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

Данная логика является специфичной и у нас нет примеров реализации данного функционала, но вероятнее всего в фильтре, который Вы пытаетесь построить должна быть колонка «[ServiceItem:Category].[ServiceInServicePact: ServiceItem].ServicePact».

Спасибо, Елена!
Думаю, это то, что нужно
Итак, фильтр на объект ServiceCategory
«[ServiceItem:Category].[ServiceInServicePact: ServiceItem].ServicePact».

Насколько я поняла, этот фильтр дает такой запрос
select * from ServiceCategory
where exists (select * from ServiceItem
where ServiceItem.CategoryID= ServiceCategory.ID
and exists (select * from ServiceInServicePact
where ServiceInServicePact.ServiceItemId = ServiceItem.ID
and ServiceInServicePact.ServicePactId = @value))

что в общем-то накладывает необходимое условие.

Елена, скажите, пожалуйста, я правильно поняла действие этого условия
[ServiceItem:Category].[ServiceInServicePact: ServiceItem].ServicePact ?

Не могли бы вы пояснить, какой в результате фильтр в терминах sql накладывается на ServiceCategory,
если применить условие
[ServiceItem:Category].[ServiceInServicePact: ServiceItem].ServicePact

Да, Елена, проверила!
Это условие действительно то самое.
Спасибо!

Всегда рада помочь:)

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

Добрый день!
Уважаемые коллеги и разработчики,

подскажите как решить такой вопрос -
Определенные менеджеры должны видеть только клиентов из определенного региона.
Например:
Менеджер 1 - Минск и область
Менеджер 2 - Гродно обл + Брест обл
Менеджер 3 - Гомель обл + Могилев обл

Спасибо.

Нравится

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

Добрый день!

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

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

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

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

Использую BPM 7.5

Нравится

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

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

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

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

Добрый день.
Помогите.Как создать сценарий,вписать туда код и просмотреть его результат. Например самое простое: написать код на С# в сценарий,который бы выводил "Hellow world"

Нравится

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

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

Вы можете реализовать бизнес-процесс, в котором будет создан параметр с типом данных "Строка".

В сценарии обратиться к параметру как к переменной и записать в него "Hello World".

С помощью элемента "Изменение данных" или "Добавление данных" Вы можете присвоить значение данного параметра одной из колонок любого объекта с типом "Строка".

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

Как можно сделат так что бы, при нажатие кнопки "Сервис" на карточки активности, открылся справочник "Сервис" с филтрацией с полем "Тип обращения"? (прик. файл)

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

Нравится

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

Активность по инциденту?
Если да, то аналогично этому, но сначала получаем значение IncidentId у задачи. Если оно заполнено, то вытягиваем тип этого обращения при помощи функции GetEntityTypedColumnValue и по этому типу и фильтруем.

В обработчике события ServiceEdit процесса страницы карточки задача добавила следующий код:

Page.ServiceEdit.PrepareLookupFilter += delegate(object sender, LookupEditEventArgs e) {
/*var typeOfServiceRequestIncidentId = (Guid)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "TypeOfServiceRequestIncident");
var typeOfServiceRequestServiceCallId = (Guid)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "TypeOfServiceRequestServiceCall");
var typeOfServiceRequestMassIncidentId = (Guid)Terrasoft.Core.Configuration.SysSettings.GetValue(UserConnection, "TypeOfServiceRequestMassIncident");*/
var currentTypeId = Page.DataSource.ActiveRow.GetTypedColumnValue("SubTypeId");
//currentTypeId = currentTypeId == typeOfServiceRequestMassIncidentId ? typeOfServiceRequestIncidentId : currentTypeId;
//if (currentTypeId == typeOfServiceRequestIncidentId || currentTypeId == typeOfServiceRequestServiceCallId) {
e.Filters.Add(new Dictionary {
{"comparisonType", FilterComparisonType.Equal},
{"leftExpressionColumnPath", "TypeOfServiceRequest"},
{"useDisplayValue", false},
{"rightExpressionParameterValues", new object [] {currentTypeId}}
});
};

Но к сожалению не зарабола.. (( Где я ошиблась?

Такой код нужно размещать на Init, а не в обработчике нажатия.

Начинает выдавать следующую ошибку при выборе справочника "Сервисы" на карточки активности: (прик. файл)

Date: 05.08.2015 15:12:11
Date (UTC): 05.08.2015 10:12:11

Exception Message: Значение с именем "SubTypeId" не найдено
Exception Type: Terrasoft.Common.ItemNotFoundException
Exception Source: Terrasoft.Core

Значит, у Вас в объекте «Активность» нет поля «SubTypeId» или оно не так называется.

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

Что-то у меня не получилась(( Не могли бы пожалуйста если не трудно подробно объяснит куда и что нужно добавит?

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

Но я же не знаю структуры Вашей базы и как называются поля.
Что-то вроде:

var serviceRequestId = Page.DataSource.ActiveRow.GetTypedColumnValue("ServiceRequestId");
var subTypeId = Terrasoft.Configuration.CommonUtilities.GetEntityTypedColumnValue<Guid>(UserConnection, "ServiceRequest", "SybType.Id", serviceRequestId);
Показать все комментарии

Добрый день!

Engagement Center 7.6
стандартный процесс - создание обращение через CTI-панель по входящему звонку
В процессе есть параметры ContactID и AccountID
Звонит какой-то пользователь в системе( Supervisor, допустим) другому пользователю.
У этого Supervisor заполнен Контрагент-Наша компания.

Сам процесс на входе как-то получает значения параметров ContactID и AccountID ( звонящий пользователь и его контрагент).
Где это происходит, в каком месте, скажите, пожалуйста?

Нравится

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

Добрый день!

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

Настройка процессов для CTI панели
Перечень процессов, который отображается в cti панели настраивается в справочнике "Действие cti панели". В справочнике можно добавлять/удалять кнопки запуска процессов, указывать текст кнопки, сам процесс для запуска и порядок расположения.

Обязательное условие для корректного запуска процесса из cti панели - наличие параметров ContactId, AccountId, PhoneNumber. В эти параметры передаются данные контрагента или контакта по звонку. В процессе можно использовать эти данные для быстрого поиска обращений по абоненту или созданию новой записи с данными из cti панели.
ContactId – принимает идентификатор контакта в звонке, тип данных – справочник, справочник контактов
AccountId – принимает идентификатор контрагента в звонке, тип данных – справочник, справочник контрагентов
PhoneNumber – принимает номер абонента в CTI панели, строка, 250 символов

Отображение процессов для пользователей
Зачастую процессы нужны только пользователям, которые являются сотрудникаци КЦ. Что бы настроить отображение процессов только для нужной группы сотрудников в системе создана группа "Операторы КЦ". Только пользователи, которые включены в эту группу будут видеть кнопки запуска процессов в cti панели.
Если необходимо изменить группу, для которой нужно отображать процессы, это можно сделать в системных настройках. Задать другую группу для отображения процессов можно в настройке "Группа операторов КЦ".

Передача параметров реализована на CTI панеле. Когда пользователь "кликает" по нужному процессу, система передает описанные выше параметры в процесс.

"Передача параметров реализована на CTI панеле. Когда пользователь "кликает" по нужному процессу, система передает описанные выше параметры в процесс."

Расскажите подробнее, пожалуйста, где именно в пакете CTIProcessActions реализована функциональность передачи параметров в процесс.

В itil transitions при добавлении действия в CTI-панель происходит почему-то только передача параметра-контакта, а его контрагент почему-то не передается в параметр.
Хотелось бы понять почему.

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

После ответа на звонок мы идентифицируем либо контрагента либо контакта. И далее панель, при запуске процесса, передает идентифицированную запись. Т.е. либо контакт либо контрагент. Если вы хотите получить контрагента идентифицированного контакта, то лучше его вычитать из самого контакта.

В Engagement Center у вас все же идентифицируется и контакт, и его контрагент. По крайней мере, подставляется и контакт, и его контрагент. Где же в таком случае происходит идентификация контрагента?

Дарья, идентификация Контакта и Контрагента производится процессом "ContactIdentification", который находится в пакете "OperatorCustomerEngagementCenter". В рамках данного процесса сначала производится поиск Контакта, а затем из найденной карточки контакта считывается Контрагент, что видно на скриншоте.

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

Елена, спасибо.
Посмотрите, на схему его теперь, пожалуйста.

В самом начале, идет ветвление:

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

Если же определен либо Контакт, либо Контрагент, то происходит сразу же выход из-под процесса
( эта стрелка самая верхняя - в ней условия [#Контакт#] != Guid.Empty || [#Контрагент#] != Guid.Empty).
Как вы видите, в этом ветке не происходит никакого считывания контрагента.
После создается обращение по процессу - в котором заполнены и контакт, и контрагент.
Вопрос - где в данном случае происходит определение контрагента? Полагаю, что и контрагент, и контакт передаются как входящие параметры в процесс.
Это возвращает нас к моему первоначальному вопросу:
"Расскажите подробнее, пожалуйста, где именно в пакете CTIProcessActions реализована функциональность передачи параметров в процесс." Где именно, в каком сервисе, каком пакете это определяется?

Дарья, процесс определения Контакта и Контрагента происходит в CTI-панели при входящем звонке, далее эти параметры передаются в процессы.

Ниже привожу код функции, которая определяет параметры в CTI-панели и зашита в коде объекта.

getActionProcessParameters: function() {
var parameters = {
PhoneNumber: this.getLastAbonentNumber()
};
var subscriberKey = this.get("IdentifiedSubscriberKey");
if (!subscriberKey) {
return parameters;
}
var subscriberCollection = this.get("IdentifiedSubscriberPanelCollection");
var subscriberPanel = subscriberCollection.get(subscriberKey);
switch (subscriberPanel.get("Type")) {
case CtiConstants.SubscriberTypes.Contact:
case CtiConstants.SubscriberTypes.Employee:
parameters.ContactId = subscriberPanel.get("Id");
break;
case CtiConstants.SubscriberTypes.Account:
parameters.AccountId = subscriberPanel.get("Id");
break;
default:
break;
}
return parameters;
},

Спасибо. Можете сказать, в каком именно объекте зашита эта функция? Название сервиса?

Дарья, данная функция находится в объекте CtiPanel.

Добрый день!
Про engagement center поняла - спасибо.
по аналогии открыла конфигурацию ITIL transitions 7.5
нашла в объекте CTIPanel эту функцию.
Функция есть и она имеет вид

getActionProcessParameters: function() {
var parameters = {
PhoneNumber: this.getLastAbonentNumber()
};
var subscriberKey = this.get("IdentifiedSubscriberKey");
if (Ext.isEmpty(subscriberKey)) {
return parameters;
}
var subscribers = this.get("IdentifiedSubscribers");
var subscriber = subscribers.get(subscriberKey);
switch (subscriber.SubscriberType) {
case CtiConstants.SubscriberTypes.Contact:
case CtiConstants.SubscriberTypes.Employee:
parameters.ContactId = subscriber.Id;
break;
case CtiConstants.SubscriberTypes.Account:
parameters.AccountId = subscriber.Id;
break;
default:
break;
}
return parameters;
}

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

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

Что не так в этой стандартной функции в определении параметров для ITIL?
Может быть исправлено это было в более новых сборках? Я сейчас рассматриваю 7.5.0.1054

Дарья, здравствуйте.

CTIPanel определяет только ИЛИ контакт ИЛИ контрагент и передает их значения в бизнес-процесс.

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

Case.BaseCasePage

onEntityInitialized: function() {
if (this.isAddMode() || this.isCopyMode()) {
this.setCaseNumber();
}
this.Terrasoft.SysSettings.querySysSettingsItem(this.statusDefSysSettingsName, function(value) {
this.set("StatusDefSysSettingsValue", value);
}, this);
this.updateOriginals();
var contact = this.get("Contact");
if (contact && !this.get("Account")) {
var account = contact.Account;
if (account) {
this.set("Account", account);
}
}
this.set("PreviousStatus", this.get("Status"));
this.callParent(arguments);
},

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

Добрый день,

каким образом можно организовать деталь, аналогичную Ленте в разделе Обращения, но изначально настроить так, чтобы все комментарии в данной ленте обращения были бы доступны только сотрудникам компании?

Нравится

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

Маргарита, добрый день!

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

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

Деталь Лента является специфической. К сожалению, у нас нет подробной инструкции по ее созданию, ориентироваться следует на существующую логику, реализованную в системе.
Для того, чтобы отображать/скрывать деталь, следует:
1) на странице редактирования раздела, в блоке diff в элементе детали добавить атрибут «visible», отвечающий за отображение/скрытие детали;
2) создать метод, который будет выполнять проверку видимости согласно Вашей бизнес-логике;
3) связать метод с атрибутом.

Пример:

{
"operation": "insert",
"name": "TabsContainer",
"parentName": "CardContentContainer",
"propertyName": "items",
"values": {
"itemType": Terrasoft.ViewItemType.CONTAINER,
"visible": {"bindTo": "getTabsContainerVisible"},
"items": []
}
}

Также следует отметить, что Вы можете разграничить доступ к детали в меню Управление конфигурацией – Администрирование: доступ к объектам.

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

Здравствуйте.
Существует ли интеграция переноса данных базовых версий 3.х.х -> 7.6.0 ?
К примеру Контрагентов, Контактов, Продаж и т.п.

Нравится

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

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

Есть два варианта выполнения подобного переноса.

Первый, это выполнение экспорта данных из версии Terrasoft 3.x и последующий импорт (используя универсальный импорт записей) в bpm'online 7.6.

Второй вариант, это перенос данных с помощью написания sql скриптов.

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

"Alina_Velichko" написал:Первый, это выполнение экспорта данных из версии Terrasoft 3.x и последующий импорт (используя универсальный импорт записей) в bpm'online 7.6.

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

Владимир, система позволяет импортировать таким способом до 10 тысяч записей одним файлом.
Но, естественно, преимущество за вторым вариантом, используя перенос с помощью базовых комманд select/insert.

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

Здравствуйте! Нуждаюсь в помощи по двум вопросам.

Вопрос №1

Делаю в БП страницу редактирования Договора. Мне надо чтобы элемент был выполнен только если на детали Продукты есть хотя-бы одна запись. Пробовал сделать через агрегирующий фильтр:

агрегирующий фильтр

После чего я вижу:

ошибка

Пробовал на другие детали, работает как-то выборочно. Например на визу работает, а на активности нет. Поставил зависимости от пакетов:
ContracInOrder, Order, CoreContract, и другие

Пробовал на разных сайтах. Ошибка идентичная.

Данную задачу можно выполнить с помощью элемента "Чтение данных", но интересно почему не работают фильтры и как с ними работать?

Вопрос №2

в БП нужно создать визу в договоре на Контакта у которого
контрагент = Наша компания,
филиал = Контакт текущего пользователя.Филиал
должность = Фин.директор
И когда виза будет подтверждена продолжать БП. Подскажите как это лучше реализовать. Заранее спасибо.

версия 7.5

Нравится

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

Добрый вечер!

Вопрос №1.

Ничего не указывайте в поле "Считать элемент выполненым, если объект соответствует условиям".
После завершения задачи, используйте элемент "Чтение данных". Считайте количество записей в объекте "Продукт в заказе", где Заказ = Id Вашего заказа.
Используйте условные потоки:

  • Если количество = 0, тогда возвращаемся к редактированию заказа
  • Иначе - идем по процессу дальше

Вопрос №2.

1) Используйте элемент "Чтение данных" по объекту "Контакт", с фильтром Контакт = Контакт текущего пользователя
2) Используйте элемент "Чтение данных" по объекту "Контакт", с фильтром Филиал = Чтение данных1.Первый элемент результирующей коллекции.Филиал и Контрагент = Наша компания и Должность = Фин.директор
3) Используйте элемент "Добавить данные" в объекте "Виза договора". Установите визирующим контакта, прочитанного на втором шаге.
4) Используйте "Промежуточный обрабатыващий сигнал" по объекту "Виза договора", событие - изменение записи по Id созданной на предыдущем шаге записи с фильтром Состояние = "Положительная", чтобы отследить изменение состояния в поле "Состояние".

Только учтите, что состояние визы еще может быть "Отрицательным".

1. Я через чтение данных и сделал. Интересовало как работать с агрегирующими фильтрами и работают ли они ?
2. А если будет несколько контактов в должности фин.директор ?
Я пробую записать в объект Виза договора результат выборки по контакту. Но я столкнулся с тем, что колонка визирующий смотрит в объект "Объект администрирования"

Добрый день!

1. Как видно из предоставленных Вами скриншотов, фильтры работают некорректно - было предложено альтернативное решение.
2. Полностью с Вами согласен - виза проставляется либо роли, либо пользователю, поэтому объект действительно "Объект администрирования".
Перед элементом "Добавить данные" используйте еще одно чтение данных по объекту "Объект администрирования" с фильтром Контакт = Id контакта с должностью фин. директор.

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

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

Добрый день!
В стандартной поставке звонилки. В базе сохраняется только номер с которого звонят. А как перехватить номер оператора на который позвонили? И есть ли возможность проследить все введеные цифры с момета дозвона в AVR?
Спасибо.

Нравится

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

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

Инеграция с Call center Infinity. Он же AVR и АТС.

Здравствуйте. Во вложении прикрепил скриншот с примером IVR. Возможно будет полезным.

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