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

Очень актуально для многих Клиентов - зафиксировать наименование столбцов в Списочном представлении реестра записей в разделах.

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

Огромная просьба, внести корректировки в систему.

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

Разработчики системы говорят, что примерно в версии 7.15.2 запланировано добавление такой возможности.

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

это будет замечательно,если они это реализуют в версии 7.15.2. Уж очень ждем. :)

Максимова Екатерина,

Здравствуйте. Данный функционал уже реализован и будет доступен после обновления на версию 7.15.2

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

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

Возможно ли сделать нумерацию строк в каждом реестре BPM (разделы, детали)?

Пишу сюда в надежде на помощь ибо нет даже предположений как это сделать(

Нравится

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

А вам нужна именно нумерация строк или записей?

Второе решается более-менее стандартными методами, а цель первого не совсем понятна

Владимир Соколов,

именно строк, меняем сортировку, фильтры - нумерация та самая - 1,2,3,4. Многие цели клиентов нам не понятны...

Добрый день, Виталий!

Самый простой способ сделать это в разделе - это заместить обьект и добавить к нему целочисленное поле, в котором динамически проставлять нумерацию. Можно сделать и добавление колнки динамически, а не через обьект, но это намного сложнее и может привести к проблемам в некоторых разделах. Например, к разделу "Контакт" добавим поле с именем UsrRowNumber. Для этого после добавления поля к обьекту "Контакт" нужно настроить отображение колонок и вывести новосозданное поле. А потом на странице раздела ContactPageV2 переопределить метод onGridDataLoaded, чтобы получилось примерно такое:

onGridDataLoaded: function() {
  this.callParent(arguments);
  for (var i = 0; i < this.getGridData().collection.items.length; i++) {
    var itemId = this.getGridData().collection.items[i].get("Id");
    this.getGridData().get(itemId).set("UsrRowNumber", (i + 1));
  }
},

Таким образом, будет работать нумерация в разделе "Контакты". Скорее всего вам не нужна будет сортировка по этой колонке реестра, так как это не даст никакой сортировки. В этом случае можно переопределить также метод sortColumn, в котором проверять какая колонка сейчас будет отсортирована и не сортировать, если это колонка UsrRowNumber. Как пример:

sortColumn: function(index) {
  var columnsSettingsProfile = this.get("Profile");
  var columnsConfig = columnsSettingsProfile.DataGrid.listedConfig;
  var columnName;
  if (!Ext.isEmpty(columnsConfig)) {
    var columns = this.Ext.decode(columnsConfig);
    var column = columns.items[index];
    columnName = column.bindTo;
  }
  if (columnName !== "UsrRowNumber") {
    this.callParent(arguments);
  }
}

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

Если же говорить про детали, то тут немного проще динамически добавить колонку. Можно попробовать перехватить Profile детали в котором находятся конфиги на отображение в списочном и плиточном отображении (listedConfig и tiledConfig). 

К примеру в методе initProfile после вызова this.callParent(arguments) взять this.get("Profile") и динамически изменить listedConfig (или tiledConfig) для изменения конфигурации колонок грида. Сначала конфиг нужно распарсить (можно использовать либо Ext.decode, либо JSON.parse), модифицировать как вам необходимо и вернуть орбатно с помощью this.set("Profile", newProfile).

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

Радчук Виталий Владимирович,

Чтобы сделать сразу на всех деталях нужно делать перехват Profile как описано выше, но этот перехват делать на базовой клиентской схеме детали грида (например, BaseGridDetailV2) и тогда все будет работать для всех деталей, которые от него наследуются.

То же самое можно сказать и для раздела, но там все сложнее. Модифицировать придется также базовый раздел BaseSection, но тут нет метода initProfile, поэтому сложнее динамически модифицировать колонки.

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

Были настроены права по записям.

После чего были импортированы сами записи в систему. Итог их никто кроме админа не видит.

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

Нравится

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

Тут так: если у вас система более-менее свежая, тогда права расставятся по ответственному (должно хватить по идее) - добавьте в исходник поле "Ответственый" и из него грузите в поле "Ответственный" системы. Автора можете ставить любого, все равно будет считаться тот, кто импортировал. Мы первый раз решали процессом, которым правили при сохранении по условию права (но есть потенциальный дедлок), либо запросом на правку прав до дефолтного состояния уже после импорта (есть такой у поддержки, дают по запросу пользователя). Запрос к сожалению Вам изменит все права, в том числе и настроенные вручную в записи, наприме. Если же не свежая, тогда и у владельца права не появятся и тут только запросом или процессом при сохранении.

Дмитрий Степанов,

версия свежая.

Ваш совет в целом помог.

Но происходит теперь другая ситуация.

Что я импортирую записи, и их видят все. То есть по ролям не разбиваются.

Делаю импорт в 8 заходов, для каждой роли совой импорт.

Но  в итоге все видят все

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

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

А права у меня все вида

Москва видит Москву

Питер видит Питер

и т.д.

Нет ролей которые видят все

 

Картинку настройки доступа к объектам в студию.

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

Добрый день.

Прошу помощи, т.к. сама не сильно разбираюсь в данном вопросе. Если код корявый, подскажите как поправить, я новичок в этом.
Задача была поставлена следующая, в разделе "Обращения" выделить записи просроченные по реакции или по разрешению. Я добавила в методы схемы Section page schema - Cases, код:

                prepareResponseCollectionItem: function(item) {
                        this.callParent(arguments);
                        item.customStyle = null;
                        //var running = item.get("ResponseOverdue");
                        if (item.values.ResponseOverdue) {
                                item.customStyle = {"background": "#EB3D51"};
                        }
                        //var running = item.get("SolutionOverdue");
                        if (item.values.SolutionOverdue) {
                                item.customStyle = {"background": "#EB3D51"};
                        }
                }

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

У нас стоит service enterprise версии 7.8.1

Нравится

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

Пускай другие пользователи почистят кеш браузера и перезайдут на сайт ;)

Максим, спасибо, Вы навели меня на мысль, что записи подсветятся только если эти колонки выведены в реестр. Это подтвердилось.
У пользователей, колонки Просрочен по реакции и по разрешению не выведены в реестр, можно сделать выделение, не зависящем от отображения этих колонок в реестре?

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

Добрый день.
У меня колонки выведены, далее не делала.

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

1) Заместить схему секции.
2) Переопределить метод initQueryColumns.
3) В замещающем методе в параметр esq добавлять нужную колонкую

Пример:

initQueryColumns: function(esq) {
	this.callParent(arguments);
        // проверка на присутствие необходимой колонки в esq
	entitySchemaQuery.addColumn("имя колонки");
},
Показать все комментарии

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

1. Название последней активности
2. Статус последней активности
3. Другие поля. Например, ответственный, даты и.т.д. т.е. любые поля сущности Активность.

И что бы все это отображалось в реестре, вид Плиточный.

Нравится

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

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

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

Михаил, цель - чтобы визуально видеть какое последнее действие по контрагенту было не заходя в карточку контрагента. При формировании динамического фильтра таже проблема возникает:
- нельзя отфильтровать кнтрагента по названию последней активности
- нельзя отфильтровать по другим колонкам конкретной активности https://yadi.sk/i/ycf23ySBrpEBG

Мы не можем датой подыгрывать, т.к. может эта последняя задача 3 месяца назад начата и незакончена, а может быть назначена на 3 месяца вперёд

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

Как вариант добавить новые колонки в объект раздела (через тот же мастер раздела), и при добавлении данных на деталь запускать бизнес-процесс, который данные с таблицы детали будет переносить в колонку объекта. Другой вопрос, что средств связи и адресов с одним типом может быть несколько. Эту логику необходимо предосмотреть в бизнес-процессе.

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

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

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

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

Приятного дня!

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

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

Нравится

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

Решал похожую задачу: при клике OK в карточке проверял условие и если оно выполнялось - показывал вопрос пользователю (да или нет). Если да - выполнял некое действие, а затем базовая логика сохранения и закрытия карточки. Если нет - не делал ничего, карточка оставалась открытой.
фрагмент БП
У вас должно быть похоже, но проще. Принимается сообщение нажатия на кнопку, в блоке-скрипте присваивается значение булевскому параметру (его надо создать в дизайнере). Затем два потока, один условный при параметре, равном true, на событие нажатия кнопки в базовом процессе. Другой - по умолчанию (если параметр false) - сообщение пользователю о невозможности удаления и всё.

В скрипте scr_AccountsGridArea событие btnDeleteOnClick необходимо изменить примерно так:

var SelectedIDs = grdData.SelectedIDs;
	var SelectedIDs = grdData.SelectedIDs;
	var SelectedIDsCount = SelectedIDs.Count;
	if (!SelectedIDsCount) {
  		return;
	}
	var deleteflag = true;
	var i;
	for (i = 0; i<SelectedIDsCount; i++) {
		if (GetDatasetFieldValueByID('ds_Account', SelectedIDs([i]), 'StatusID') == StatusIdValue) {
			deleteflag = false;
		}
	}
	if (deleteflag) {
		scr_BaseGridArea.btnDeleteOnClick(Control)
	}
        else {
		ShowInformationDialog('Нельзя удалить действующего контрагента');
	}

Где 'StatusID' - Имя поля Статус, а StatusIdValue - ID статуса "действующий"

Не заметил, что BPM. Но может кому-то понадобится для CRM.

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

При таком подходе, Вы возвращаете серверную подписку на кнопку, в то время, как по умолчанию - клиентская.
Как выход, на событии Init своей страницы, перед вызовом базового обработчика подписаться на событие DataSource.BeforeRemoveRow, выполнить проверку на условие и в случае отрицательного результата такой проверки установить свойство DataSourceEventArgs.Cancel = true; При таком подходе, Вам не придется делать какие-то дополнительные запросы в БД, поскольку аргумент DataSourceEventArgs будет содержать ссылку на удаляемую строку.

Приблизительно будет так:
В скрипте перед вызовом базовой логики пишете:

Page.DataSource.BeforeRemoveRow += (sender, e) => {
var account = e.Row;
if (account == null) {
return;
}
Guid statusId = account.GetTypedColumnValue("StatusId");
if (statusId.Equals(ActiveAccountStatusId)) {
e.Cancel = true; // Это нужно, что не прошло базовое удаление
ErrorMessageText = new LocalizableString("Вы не можете удалить действующего контрагента");
}
};

Где StatusId - название поля статуса в БД, ActiveAccountStatusId - константа действующего статуса контрагента, а ErrorMessageText - локализируемая строка с сообщением (разумеется Вашим :) ).
Потом вставляете Исключающее или с условным потоком в котором проверяете:

!string.IsNullOrEmpty(ErrorMessageText.ToString())

и после которого идет скрипт о сообщении.

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

Коллеги, в тройке была возможность добавления действия на карточке редактирования любого объекта, с помощью которого можно было перейти к связанной сущности. То есть, например, на карточке задачи в поле редактирования контрагента можно было нажать на это действие (выглядело как молния) и из появившегося меню выбрать либо "Открыть карточку контрагента", либо "Перейти к контрагенту". Можно ли реализовать аналогичный функционал в BPMonline? Если да, то каким образом?

Также в тройке была возможность в реестре записей, например, тех же задач (и в других реестрах тоже) щелкнуть по почти любой колонке конкретной записи и открыть карточку редактирования этого объекта, например, щелкнув в реестре задач по контакту, открывалась карточка редактирования этого контакта. Возможно ли такое в BPMonline?

Нравится

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

1) Посмотрите как реализовано тут http://www.community.terrasoft.ua/blogs/8319
2) В реестрах если нажать правой кнопкой мыши есть пункт - "Перейти к" - возможно этот функционал вам подойдет

Максим, по п.1, в целом, подходящая реализация, но громоздкая. кнопки занимают много места и не очень гармонично смотрятся на карточке. Особенно, если их создавать на многих полях. Может быть все же есть возможность реализации, аналогичной тройке? чтобы и места отъедать немного, и можно было бы заодно еще какое-то действие привязать, помимо открытия карточки.
по п.2: как вариант такая реализация вполне подойдет. Но "Перейти к" есть не во всех реестрах, а там где есть, переход предлагается только к одному полю (это либо Контрагент, либо Создал, либо Ответственный). Подскажите, как можно расширить этот список, а в тех реестрах где нет этого пункта, создать его?

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

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

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

Уточните, пожалуйста, какое у Вас отраслевое решение?

Много примеров в карточке Инцидента и Запроса на обслуживание в продукте Service Desk.

У нас обычная версия 5.2, неотраслевое решение. Сервис деска нет. В любом случае и в нашем решении есть стандартные меню "Перейти к Ответственному/Контрагенту и т.д.". Например, в разделе "Контрагенты" есть пункт "Перейти к -> Создал". Где можно посмотреть как это реализовано?

Пример создания контекстного меню можно посмотреть в базовом реестре (BaseGridPage), а конкретной реализации скрипта перехода - в процессе окна напоминаний (RemindingsPage) в обработчике JumpButtonClickScriptTask.

Анна, к сожалению, я так и не смог разобраться в BaseGridPage и повторить реализацию, например, меню "Отправить e-mail". Может быть, вы сможете описать подробнее что мне нужно сделать и какой код использовать?
Я добавил меню "Открыть" в общее контекстное меню в реестре контрагентов. Теперь я хотел бы, чтобы при наведении на этот пункт у меня открылись два пункта "Ответственный" и "Контакт". Соотв-но, меня интересуют все действия, которые мне нужно сделать, чтобы
1) при наведении на "Открыть" у меня появились два новых пункта
2) при нажатии на пункт меню "Ответственный" у меня открылась карточка редактирования ответственного за текущего контрагента сотрудника.

Меню "Перейти к" формируется ядром по следующему принципу: в него включаются все колонки справочника, которые на данный момент выведены в реестр.

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

Формировать это меню в конфигурации не получится - можно только сделать свое отдельное по аналогии, но для этого следует задействовать jscript

А в этом отдельном меню можно реализовать то, о чем я спрашивал?

"D.T." написал:Также в тройке была возможность в реестре записей, например, тех же задач (и в других реестрах тоже) щелкнуть по почти любой колонке конкретной записи и открыть карточку редактирования этого объекта, например, щелкнув в реестре задач по контакту, открывалась карточка редактирования этого контакта. Возможно ли такое в BPMonline?

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

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

"D.T." написал:То есть, например, на карточке задачи в поле редактирования контрагента можно было нажать на это действие (выглядело как молния) и из появившегося меню выбрать либо "Открыть карточку контрагента", либо "Перейти к контрагенту". Можно ли реализовать аналогичный функционал в BPMonline? Если да, то каким образом?

Для реализации это функциональности Вам следует в дизайнере карточки нажать правой кнопкой мыши на поле, и добавить на него кнопку-молнию, затем реализовать программный компонент перехода по аналогии с описанным тут: http://www.community.terrasoft.ua/blogs/8319

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

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

Помогите, пожалуйста, уже всю голову сломала...

Каким образом можно программно "добраться" до быстрого фильтра??? (установить его и применить).

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

Версия 3.2.

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

Нравится

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

Программно установить быстрый фильтр не получится.

Фильтрация при выборе значения из справочника.

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

function btnAddShablonOnClick(Control) {
	var WorkspaceWindow = GetAttribute(Self, 'WorkspaceWindow');
	var DetailPages = WorkspaceWindow.ComponentsByName('pcDetails');
	var FilesPage = WorkspaceWindow.ComponentsByName('pgFilesDetail');
	var FilesDetailWindow = 
		WorkspaceWindow.ComponentsByName('wndFilesDetail').Window;
	var FileDataWindow = FilesDetailWindow.ComponentsbyName('wndFileData').Window;  
 
	var SelWin = ShowSelectWorkspaceWindow('wnd_LibraryWorkspace', FileDataWindow);
	NotVisibleDetails(SelWin.ComponentsByName('wnddata').Window.
		ComponentsbyName('pcDetails'));
	SelWin.ComponentsByName('wnddata').Window.ComponentsbyName('pcDetails').
		ItemsByName('pgFilesDetail').IsVisible = true;
 
	var DocTypeID = BaseGridArea.GridDataset.DataFields.
		ItemsByName('DocumentTypeID').Value;
	var LibID = GetDatasetFieldValueByID('ds_DocumentType', DocTypeID,
			'ShablonGroupID');
	SetAttribute(SelWin.ComponentsByName('wnddata').Window.
		ComponentsByName('wndGridData').Window, 'ParentItemID', LibID);
	var DataSet = SelWin.ComponentsByName('wnddata').Window.
		ComponentsByName('wndGridData').Window.ComponentsByName('dlData').Dataset;
 
	var IsEnabled = !IsEmptyValue(LibID);
	ApplyDatasetFilter(DataSet, 'ID', LibID, IsEnabled);
 
}

Была в отпуске, не могла об этом думать )

После применения фильтра датасет нужно переоткрывать.

Пробовала. Все равно не фильтруется.

....
DataSet.Close();
DataSet.Open();
}

Попробуйте перед применением фильтра закрывать датасет, а после - открывать. Например, так:

if (DataSet.State != dstInactive) {
    DataSet.Close();
}
ApplyDatasetFilter(DataSet, 'ID', LibID, IsEnabled);
DataSet.Open();

Вообще я правильно понимаю, что Вы сначала открываете окно (с помощью функции ShowSelectWorkspaceWindow), а потом накладываете фильтр на датасет? Попробуйте наоборот: сначала применить фильтр, а потом открывать окно.

Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.

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

А если в окно передавать уже отфильтрованный датасет? Применили фильтр, а потом

Window.ComponentsByName('dlData').Dataset = OurFilteredDataset;

Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.

Вот так заработало. Олег, огромное спасибо за помощь.

function btnAddShablonOnClick(Control) {
	var WorkspaceWindow = GetAttribute(Self, 'WorkspaceWindow');
	var DetailPages = WorkspaceWindow.ComponentsByName('pcDetails');
	var FilesPage = WorkspaceWindow.ComponentsByName('pgFilesDetail');
	var FilesDetailWindow = 
		WorkspaceWindow.ComponentsByName('wndFilesDetail').Window;
	var FileDataWindow = FilesDetailWindow.ComponentsbyName('wndFileData').Window; 
 
	var DocTypeID = BaseGridArea.GridDataset.DataFields.
		ItemsByName('DocumentTypeID').Value;
	var LibID = GetDatasetFieldValueByID('ds_DocumentType', DocTypeID,
			'ShablonGroupID');
	var IsEnabled = !IsEmptyValue(LibID);
 
	var LibDataset = Services.GetNewItemByUSI('ds_Library');
	ApplyDatasetIDFilter(LibDataset, LibID, IsEnabled);
	var SelWin = Services.GetNewItemByUSI('wnd_SelectWorkspaceData');
	SetAttribute(SelWin, 'NotifyObject', FileDataWindow);
	SetAttribute(SelWin, 'WorkspaceUSI', 'wnd_LibraryWorkspace');
	System.BeginProcessing();
	try {
		SelWin.Prepare();
		SelWin.ComponentsByName('wnddata').Window.ComponentsByName('wndGridData').
			Window.ComponentsByName('dlData').Dataset = LibDataset;
		SelWin.Show();
		LibDataset.Open();
	} finally {
		System.EndProcessing();
	}
 
	NotVisibleDetails(SelWin.ComponentsByName('wnddata').Window.
		ComponentsbyName('pcDetails'));
	SelWin.ComponentsByName('wnddata').Window.ComponentsbyName('pcDetails').
		ItemsByName('pgFilesDetail').IsVisible = true;
 
}

(функция добавления шаблонов документов из библиотеки, в зависимости от типа документа)

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