Существует ли в ServiceDesk возможность настроить деталь "Инциденты" Конфигурационной Единицы таким образом, чтобы в ней отображались инциденты как по выделенному КЕ, так и по КЕ, входящим в состав выделенного и определенным на детали Комплектация?
Нравится
Можно поступить так: добавить в запрос инцидентов (sq_Incident) группу фильтров вида:
WHERE( ... ([tbl_Incident].[ConfigurationItemID] = :ConfigurationItemID OR EXISTS (SELECT [tbl_ConfigItemComplectation].[ID] AS [ID] FROM [dbo].[tbl_ConfigItemComplectation] AS [tbl_ConfigItemComplectation] WHERE([tbl_ConfigItemComplectation].[ConfigurationItemID] = :ConfigurationItemID AND [tbl_Incident].[ConfigurationItemID] = [tbl_ConfigItemComplectation].[ChildConfigurationItemID]))) )
Далее создать в реестре инцидентов (wnd_IncidentsGridArea) новое представление, в свойстве FilterSetCode которого указать код этой группы фильтров.
Необходимо также учесть, что данное представление должно быть видимым только тогда, когда реестр инцидентов используется в детали раздела "Конфигурационные единицы" - для этого соответственным образом отредактировать обработчик события OnPrepare реестра. Также при активации представления необходимо отключать фильтр по ConfigurationItemID, который включается при обновлении детали. Для этого необходимо создать обработчик события OnActiveViewChanged объекта grdData в окне реестра инцидентов, и добавить в него примерно такой текст:
function grdDataOnActiveViewChanged(DataGrid, OldDataGridView) { scr_BaseGridArea.grdDataOnActiveViewChanged(DataGrid, OldDataGridView); var ActiveView = DataGrid.ActiveView; if (ActiveView.Name == <Название представления>) { EnableDatasetFilters(dlData.Dataset, false, 'ConfigurationItemID'); RefreshDataset(dlData.Dataset); } }
Если там ничего не дописывать, и запустить представление видимым всегда, то при переключении на него в детали Инциденты Конфигурационного элемента выскакивает отладчик скриптов и ругается на следующее:
function RefreshDataset(Dataset) {
CheckAssigned(Dataset, 'Dataset');
Dataset.Close();
Dataset.Open();
}
В обработчике OnPrepare реестра инцидентов (скрипт wnd_IncidentsGridAreaScript) вызывается функция Initialize, в которой есть блок:
if (!IsEmptyValue(ParentItemFieldName)) { ... }
Таким образом осуществляется проверка, является ли реестр инцидентов деталью. В конце этого блока можно дописать:
if (!IsEmptyValue(ParentItemFieldName)) { ... <Название представления>.IsVisible = ParentItemFieldName == 'ConfigurationItemID'; }
"shymaza" написал:Если там ничего не дописывать, и запустить представление видимым всегда, то при переключении на него в детали Инциденты Конфигурационного элемента выскакивает отладчик скриптов и ругается на следующее
Проверьте с помощью профайлера, какой запрос отправляется на сервер. Возможно, Вы не совсем верно сформировали фильтр для представления.
Доброе утро, Олег, спасибо за подробные комментарии.
Я исправил немного фильтр, ошибки выходить перестали, но требуемой информации тоже нет. Инциденты вижу только свои, без инцидентов вложенных КЕ. Дело в том, что у нас база Оракл, и я не знаю есть ли там аналог профайлера.
Можете выложить следующие сервисы из Вашей конфигурации: sq_Incident, wnd_IncidentsGridArea, wnd_IncidentsGridAreaScript?
Не срабатывает из-за некорректного условия в функции grdDataOnActiveViewChanged: Вы сравниваете название представления с его заголовком (Caption). Замените текст обработчика на такой:
function grdDataOnActiveViewChanged(DataGrid, OldDataGridView) { scr_BaseGridArea.grdDataOnActiveViewChanged(DataGrid, OldDataGridView); var ActiveView = DataGrid.ActiveView; if (ActiveView.Name == 'dgvCIwithChild') { EnableDatasetFilters(dlData.Dataset, false, 'ConfigurationItemID'); //EnableDatasetFilters(dlData.Dataset, true, 'CIID'); RefreshDataset(dlData.Dataset); } }
Включение фильтра CIID не обязательно, так как он включится автоматически при переходе на нужное представление, поскольку Вы его указали в свойстве FilterSetCode представления. Поэтому здесь я его закомментировал.
Единственное, что можно ещё подправить - убрать строку
dgvCIwithChild.IsVisible = ParentItemFieldName == 'ConfigurationItemID';
из блока
if (!IsEmptyValue(ParentItemFieldName)) { ... }
и вставить её перед этим блоком. Это обеспечит скрытие представления в реестре раздела "Инциденты".
Спасибо, все было бы замечательно, только теперь эта группа фильтров не выключается автоматом, при переходе на представление "Все". Т.е. когда я открываю деталь инциденты интересующей меня КЕ, в представлении "Все" я вижу только те инциденты, которые зарегистрированы непосредственно на эту КЕ, перехожу на представление "byCI", вижу как и хотел инциденты по КЕ и вложенным КЕ, возвращаюсь на представление "Все" а картинка как будто на "byCI". Добавил else в обработчик ChangeView не помогло, как выключить этот фильтр, когда он не нужен?
function grdDataOnActiveViewChanged(DataGrid, OldDataGridView) { scr_BaseGridArea.grdDataOnActiveViewChanged(DataGrid, OldDataGridView); var ActiveView = DataGrid.ActiveView; if (ActiveView.Name == 'dgvCIwithChild') { EnableDatasetFilters(dlData.Dataset, false, 'ConfigurationItemID'); // EnableDatasetFilters(dlData.Dataset, true, 'CIID'); RefreshDataset(dlData.Dataset); } else { EnableDatasetFilters(dlData.Dataset, false, 'CIID'); RefreshDataset(dlData.Dataset); } }
Думаю, фильтр выключается, но необходимо обратно включить фильтр по ConfigurationItemID. Попробуйте так:
function grdDataOnActiveViewChanged(DataGrid, OldDataGridView) { scr_BaseGridArea.grdDataOnActiveViewChanged(DataGrid, OldDataGridView); var ActiveView = DataGrid.ActiveView; if (ActiveView.Name == 'dgvCIwithChild') { EnableDatasetFilters(dlData.Dataset, false, 'ConfigurationItemID'); RefreshDataset(dlData.Dataset); } else { EnableDatasetFilters(dlData.Dataset, true, 'ConfigurationItemID'); RefreshDataset(dlData.Dataset); } }
Спасибо, Олег. Еще один вопрос, как можно добавить это условие
var ActiveView = DataGrid.ActiveView; if (ActiveView.Name == 'dgvCIwithChild') { EnableDatasetFilters(dlData.Dataset, false, 'ConfigurationItemID'); RefreshDataset(dlData.Dataset); } else { EnableDatasetFilters(dlData.Dataset, true, 'ConfigurationItemID'); RefreshDataset(dlData.Dataset); }
в обработчик onPrepare. Иначе при переходе между КЕ при выбранном представлении byCI фильтр не включается, поскольку не срабатывает обработчик onChangeView.
При простом копировании невозможно задать ActiveView, из-за другого контекста.
Нужно добавлять не в обработчик OnPrepare реестра инцидентов, а в функцию обновления деталей (RefreshDetails) скрипта wnd_ConfigurationItemWorkspaceScript. Для быстрого решения можно изменить блок, который относится к обновлению детали "Инциденты", примерно так:
... if (pcDetails.ActivePage.Name == pgIncidentsDetail.Name) { RefreshCommonDetail(BaseWorkspace, wndIncidentsDetail, 'ConfigurationItemID', 'ConfigurationItemID'); if (wndIncidentsDetail.Window.ComponentsByName('grdData').ActiveView.Name == 'dgvCIwithChild') { var DetailDataset = wndIncidentsDetail.Window.ComponentsByName('dlData').Dataset; EnableDatasetFilters(DetailDataset, false, 'ConfigurationItemID'); RefreshDataset(DetailDataset); } } else ...
Недостаток этого решения - при обновлении детали всегда выполняется два запроса на выборку. Для того, чтобы лишний запрос не выполнялся, нужно написать свою функцию обновления вместо RefreshCommonDetail, которая учитывала бы изменение применяемых фильтров в зависимости от активного представления.