Добрый день

Есть в системе деталь, которая отображает запросы пользователей к сервису. Один пользователь может обращаться много раз. На каждый запрос формируется запись с ID пользователя, датой и типом запроса.

Как получить график количество уникальных пользователей за текущий квартал в группировке по датам. На SQL легко и просто.

SELECT
CAST(DATEADD(HH,3,EPMRequestDate) as date) as [Дата], --дата запроса с учетом часового пояса
COUNT(DISTINCT EPMAuthDataEnergyId) as [Уникальные пользователи],
COUNT(Id) as [Посещения]
FROM EPMAuthDataStatisticEntity
WHERE
EPMAuthDataEnergyId!='9bb71e40-09b4-4352-ba5a-0f55b486f8f0' --Исключение ИД
and EPMTypeRequest = 1 --тип запроса
and EPMRequestDate between DATEADD(M,-3, GETDATE()) and GETDATE() --Текущий квартал
GROUP BY CAST(DATEADD(HH,3,EPMRequestDate) as date)
ORDER BY CAST(DATEADD(HH,3,EPMRequestDate) as date)

Начинаю делать в BPM и получаю только количество посещений в день

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

Насколько понимаю стандартными средствами никак?

Нравится

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

Нужно создать view в БД, на основе view создать объект. И уже делать график основываясь на данных виртуального объекта (view)

Поищите по форуму, как создаются объекты на основе вьюхи, вот например в этой теме есть инфа.

https://community.terrasoft.ru/questions/sozdanie-obekta-na-osnove-db-view

Нужно создать view в БД, на основе view создать объект. И уже делать график основываясь на данных виртуального объекта (view)

Поищите по форуму, как создаются объекты на основе вьюхи, вот например в этой теме есть инфа.

https://community.terrasoft.ru/questions/sozdanie-obekta-na-osnove-db-view

Благодарю за помощь. Создал View, объект в системе по ней и построил требуемые графики. Единственная сложность возникла при создании Объекта. Система требовала обязательно указать ключевое поле. Пришлось задать его во View

Да, для корректной работы view должна быть максимально похожа по набору стандартных полей на обычные объекты. Ещё поле для отображения указать будет не лишним.

Если не знаете, что вывести в качестве уникального Id, можно взять MD5-хэш от остальных полей.

 

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

Добрый день, коллеги.

В базе данных bpmonline я создал представление dbo.UsrGetStats c нужными мне атрибутами (Contact, MaxTime, MinTime, AvgTime).

Такой вопрос, как создать объект на основе этого DB VIEW (UsrGetStats)? 

Нравится

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

Добрый день.

Создаете так же, как и простую схему объекта. Подробнее об этом почитайте на академии.

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

Также при создании схемы не забудьте указать признак 'Представление в базе данных':

Добрый день.

Создаете так же, как и простую схему объекта. Подробнее об этом почитайте на академии.

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

Также при создании схемы не забудьте указать признак 'Представление в базе данных':

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

Здравствуйте, спасибо за ответ, помогло!

Примечание: во View не было Id из-за этого выходила ошибка.

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

Проблема заключается в том что в LDAP имя и фамилия латиницей указаны отдельно а в displayName указаны латинице. Пользователи хотят видеть кирилицу.

Можно ли в поле "ФИО" совместить через меню настройки LDAP синхронизации два атрибута или там только один может быть?

Нравится

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

Нет, один атрибут синхронизируется с одним полем.

Если всё же планируете разобраться и что-то переделать в механизме синхронизации с LDAP, см. эту и эту темы.

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

Спасибо. Так и реализовано сейчас, через кастомизацию, и как подметил 

Мотков Илья при каждом обновлении приходится проводить адаптацию кода так как он меняется в этом пакете при каждом обновлении

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

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

Имеем классический трехуровневый ландшафт: Разработка (DEV), Тестирование (TST) и промышленный (PRD). В DEV включен режим разработки в файловой среде. Есть потребность в наполнении DEV данными из PRD. Именно только данные. Пробовал делать бэкап базы PRD и разворачивать его на DEV. Из минусов решения - это то, что все пакеты разработки становятся установленными из вне, теряют связь с хранилищем, заново приходится отключать все настройки синхронизации почты и перенастраивать интеграции на другие базы.

Есть вариант написать SQL скрипт в котором определить перечень некопируемых таблиц и запускать его. Кстати, подобным образом происходит копирование систем у SAP (если уместно данное сравнение).

А как это делаете вы?

Нравится

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

Здравствуйте! Что касается пакетов,  можете разблокировать их выполнив sql скрипт

update SysPackage
set IsChanged = 1, InstallType = 0, IsLocked = 1, Maintainer = 'Customer'
where Name in ('PkgName')
and SysWorkspaceId in (select Id from SysWorkspace where Name = 'Default')

Что касается привязки пакета к хранилищу, то по этому поводу хорошо описано в данной статье- https://academy.terrasoft.ru/documents/technic-sdk/7-14/privyazka-k-svn-ne-svyazannogo-s-hranilishchem-paketa

Здравствуйте! Что касается пакетов,  можете разблокировать их выполнив sql скрипт

update SysPackage
set IsChanged = 1, InstallType = 0, IsLocked = 1, Maintainer = 'Customer'
where Name in ('PkgName')
and SysWorkspaceId in (select Id from SysWorkspace where Name = 'Default')

Что касается привязки пакета к хранилищу, то по этому поводу хорошо описано в данной статье- https://academy.terrasoft.ru/documents/technic-sdk/7-14/privyazka-k-svn-ne-svyazannogo-s-hranilishchem-paketa

Нигрескул Алексей,

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

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

Все зависит как часто вам нужно с прода переносить данніе в среду разработки, и нужно ли переносить абсолютно все или например данные нескольких разделов (те отдельные таблиы) если второе то как вариант можно использовать зеркалирование (Database Mirroring) или другие аналогичные мезанизмы синхронизации разных БД

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

Добрый день! 

На системе установлено приложение Excel reports builder for bpm’online, выпущенное terrasoft (отчетность, выгружаемая в эксель). Оно использует библиотеку EPPlus.dll И мы в нашей разработке использовали  эту же библиотеку, но версии этой dll в этих пакетах разные (у нас более новая).

Сейчас при установке решения на систему с Excel reports builder for bpm’online, возникает ошибка из-за разницы в версиях библиотек.

Как можно урегулировать этот конфликт?

Благодарю!

 

Нравится

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

 Решение опубликовано не Terrasoft, а bpm’online labs. Вам нужно уточнить новую версию библиотеки и написать на email поддержки решения — bpmonlinelabs@bpmonline.com

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

Александр, добрый день! Спасибо за отклик. Там смогут предоставить пакеты с новой версией библиотеки?

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

Зверев Александр пишет:

 Решение опубликовано не Terrasoft, а bpm’online labs. Вам нужно уточнить новую версию библиотеки и написать на email поддержки решения — bpmonlinelabs@bpmonline.com

 

Данный адрес не существует. есть альтернативный адрес? 

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

Добрый день. Подскажите, может у кого есть идеи как скрыть контакты сотрудников из раздела "Контакты" не используя группы?

Нравится

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

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

Пример фильтрации в разделе

getFilters: function () {
    var sectionFilters = this.callParent(arguments);
    this.setCommunicationFilter(sectionFilters);
    return sectionFilters;
},
setCommunicationFilter: function (filterCollection) {
    var testAttr = this.get("TestAttr");
    var isActive = this.get("IsActiveTestAttr");
    if (!isActive) {
         filterCollection.removeByKey("FilterContactCommunication");
    } else {
    filterCollection.add("FilterContactCommunication", 
         this.Terrasoft.createColumnFilterWithParameter(
                this.Terrasoft.ComparisonType.CONTAIN, "[ContactCommunication:Contact:Id].Number", testAttr));
         }
},

 

Доброе утро.

По классике это можно сделать разделением прав доступа.

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

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

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

Для схемы таблицы 'Средство связи контакта' включаете администрирование по записям.

Если есть потребность корректируете права доступа на записи с помощью настройки специального бизнес-процесса. Например, если Вам нужно скрывать только телефоны сотрудников, а e-mail показывать.

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

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

мне нужно скрыть не поля в контактах а сами контакты типа "сотрудник" из списка контактов для сотрудников

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

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

Григорий Чех, 

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

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

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

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

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

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

Пример фильтрации в разделе

getFilters: function () {
    var sectionFilters = this.callParent(arguments);
    this.setCommunicationFilter(sectionFilters);
    return sectionFilters;
},
setCommunicationFilter: function (filterCollection) {
    var testAttr = this.get("TestAttr");
    var isActive = this.get("IsActiveTestAttr");
    if (!isActive) {
         filterCollection.removeByKey("FilterContactCommunication");
    } else {
    filterCollection.add("FilterContactCommunication", 
         this.Terrasoft.createColumnFilterWithParameter(
                this.Terrasoft.ComparisonType.CONTAIN, "[ContactCommunication:Contact:Id].Number", testAttr));
         }
},

 

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

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

Хотелось бы добавить кастомное правило поиска дублей. Действовал с оглядкой на https://academy.terrasoft.ru/documents/technic-sdk/7-14/dobavlenie-pravila-poiska-dubley ,но возникла сложность при объявлении типов параметров, если аналог с mscql UNIQUEIDENTIFIER - uuid, то какой аналог у CreatingObjectInfo? 

Будет ли достаточно создания только одной процедурки или имеются еще какие-то не очевидные, но нужные действия

Как она будет взаимодействовать с elasticsearch в таком случае

И хоть и неправильную но все же процедуру я пытался прикреплять к правилу, согласно гайду, но с пустым телом "RuleBody" она не хотела функционировать

Было бы прекрасно, если бы имелся какой-нибудь пример на postgresql.

Bpm'online развернут on-site. Глобальный поиск и тд настроены

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

Нравится

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

Посмотрите статью в академии ДОБАВЛЕНИЕ ПРАВИЛА ПОИСКА ДУБЛЕЙ

Руслан, добрый день!



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

Инструкция по настройке массового поиска дублей для приложений on-site:

https://academy.terrasoft.ru/documents/administration/7-14/nastroyka-massovogo-poiska-dubley

Григорий Чех, На неё я и оглядывался, когда пытался добавить правило

Мотков Илья,

В этом и проблема, что я настроил глобальный поиск и массовый поиск дубликатов, но нужно добавить "неординарное" правило

Для Postgre есть только поиск дублей на основе ElasticSearch. Старые разработки на основе хранимых процедур работать не будут.

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

Коллеги, подскажите в процессе есть элемент "Обработка таймера", который выполняет следующее "([#Системная переменная.Текущее значение даты и времени#].AddDays(1) - [#Системная переменная.Текущее значение даты и времени#]).TotalSeconds" при этом иногда этот блок по одному процессу отрабатывает, а по другому нет.

В чем может быть проблема?

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

Нравится

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

Добрый день!

А почему туда просто константу нельзя задать ?

У вас коробка или облачное решение ?

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

Добрый день, Евгений!



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

1. Установить для пула приложений IIS, на котором работает приложение, Idle Timeout = 0

2. Настроить автоматический мониторинг Loader'a и приложения с помощью бесплатного сервиса мониторинга https://uptimerobot.com/ (настроить автоматический мониторинг c периодичностью 5-10 минут)



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

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

У нас наблюдается такая же проблема - "Обработка таймера" не выполняется, т.е. он выполняется бесконечно. Настроил БП так чтобы он запустился в 8:15, я вошел в систему около 8:00, т.е. если я правильно понимаю, пул активен. Несмотря на это "Обработка таймера" не завершается (таймер ждет 60 секунд). К тому же если выполнить его вручную, нажав на кнопку "Выполнить элемент", то он успешно выполняется. В чем может быть проблема?

Руслан, а с Quartz на сервере всё в порядке? Таймер не работает в одном конкретном процессе или везде?

Не могу ответить про порядок с Quartz'ом, как это можно проверить? У нас два БП с таймером и оба не работают. Было больше, у других убрал таймер, без него они ночью отрабатывают нормально. 

В базе есть таблицы с названием, начинающимся на QRTZ, в них хранится информация о заданиях, их состоянии и прочем. См. тему и обсуждение, а также ещё тут.

Хочу добавить. Чтобы запустить планировщик после перезапуска вэб-приложения (или засыпания, как тут писали), нужно зайти именно на страницу логина. То есть пока кто-нибудь не зайдет на страницу логина, планировщик не запустится. Планировщик живет в верхнем квадратике. Если пользователь аутентифицирован до перезапуска вэб-приложения, то можно сразу выйти на страницы .../0/..., но это не запустит планировщик.

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

Добрый день.

Есть Данные, хранящиеся в json-строке

Есть Объект, со структурой полей соответствующей Данным в json.

Есть Модуль с DataGrid, в котором нужно отобразить реестр записей.

Наполняю коллекцию GridData: 

 

prepareDataGridViewModule: function(dataList){
    //Наполнить GridData
    var gridData = this.get("GridData");
    var entityConfig = this.getEntityConfig(this.$MasterEntityName);
    this.Terrasoft.each(dataList, function(item) {
        var itemData = Ext.JSON.decode(item.Data);
        var itemModel = this.Ext.create("Terrasoft.BaseViewModel", {
              columns: entityConfig.columns, //Коллекция полей Объекта
              values: itemData   //Коллекция значений полей
         });
         gridData.add(item.Id, itemModel);
      }, this);
}

В итоге получаю отображение: 

https://yadi.sk/i/XUkp2kMCWWB4KQ



Кто сталкивался?

Как можно наполнить плиточное представление реестра в каждой строке своими динамическими полями?

Нравится

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

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

Вы можете разработать формирование всей информации на уровне базы данных в представление, по которому в конфигурации создан объект. Как работать с JSON в MS SQL, описано в этой статье.

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

Мне нужно это сделать именно на клиентской части.

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

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

Перефразирую:

В каком виде я должен передать свою коллекцию значений и полей в GridData, чтобы Базовыми средствами отрисовать поля реестра?

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

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

Я и нашёл. в LocalDuplicateSearchPageV2 и его миксине DuplicatesSearchUtilitiesV2, где в методе loadElasticDuplicates в модель реестра передаются поля (columns) и значения (values).

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

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

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

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

Произведите отладку Вашего кода и работающего на странице дублей. Также Вы можете заказать такие доработки у компаний-партнёров.

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

Есть два справочника: "Запрос" и "Расчет к запросам".

В "Запрос" крепится деталь, где указывается поле из второго справочника (см.Рис 1.2.).

 

Как можно через кнопку(JS на клиенте/сама кнопка уже есть) в справочнике "Запрос" узнать Id прикрепленной детали?

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

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

 

 

 

 

 

 

 

 

 

Нравится

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

Так в том и дело, что нет разницы сколько на данный момент записей в детали одна или несколько. Все они хранятся в коллекции GridData детали.

Вы уверенны, что эта логика должна отрабатывать на клиентской части?

Т.к. в итоге вам нужно будет делать esq-запрос к всё той же детали  для получения значения поля "Статус(usrStatus)" (т.к. не факт, что в реестре детали выведено поле "Статус(usrStatus)" )

Если всё же на клиентской части, то 

в BasePageV2 есть коллекция this.entitySchemaInfo.details,

И есть метод var detailId = this.getDetailId(detailName);

Вы можете на странице Запроса (где кнопка) создать адресное сообщение (publish)

И при клике на кнопку его отправлять. Адресатом будет detailId.

А в схеме детали с реестом (Расчет) добавить это же сообщение, но уже как подписчика (subscribe).И при получении этого сообщения возвращать this.get("GridData")

 

Вам нужно получить ID детали или Id определённой записи из детали?

Получить Id прикрепленной детали, у неё найти поле "Статус(usrStatus)" и сверить что поле = "Согласован"



Это первый опыт работы с деталями

Т.е. всё же Id записи  "Расчет к запросам" связанный с текущим Запросом?

А кнопка у вас где располагается?

 

Коновалов Игорь,

В справочнике "Запрос"

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

 

Коновалов Игорь,

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

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

Так в том и дело, что нет разницы сколько на данный момент записей в детали одна или несколько. Все они хранятся в коллекции GridData детали.

Вы уверенны, что эта логика должна отрабатывать на клиентской части?

Т.к. в итоге вам нужно будет делать esq-запрос к всё той же детали  для получения значения поля "Статус(usrStatus)" (т.к. не факт, что в реестре детали выведено поле "Статус(usrStatus)" )

Если всё же на клиентской части, то 

в BasePageV2 есть коллекция this.entitySchemaInfo.details,

И есть метод var detailId = this.getDetailId(detailName);

Вы можете на странице Запроса (где кнопка) создать адресное сообщение (publish)

И при клике на кнопку его отправлять. Адресатом будет detailId.

А в схеме детали с реестом (Расчет) добавить это же сообщение, но уже как подписчика (subscribe).И при получении этого сообщения возвращать this.get("GridData")

 

Как вариант можно использовать сообщения например такой сценарий

1)по нажатии вашей кнопки на карточке публикуется сообщение

2) в дели по подписке на сообщение перебираются все строки данных и формируется в массив список id записей у которых статус = согласован. Сформированый массив передается в карточку.

 

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