Перейти к основному содержанию
`Ctrl`+`K`

# Связь выборок с администрируемыми объектами

## Основные понятия

- Элемент администрирования (класс `Btk_AcItem`) - логический объект, который соответствует одной выборке.
  На каждую выборку, обладающую своей `avm.xml`, создается отдельный элемент администрирования, обладает перечнем элементарных привилегий.

- Элементарная привилегия (класс `Btk_AcItemPrivilege`, коллекция `Btk_AcItem`) - логический объект, который соответствует одному из элементов выборки: атрибуту или операции.
  Элементарные привилегии обладают типом привилегии. Например, атрибуты относятся к типу Чтение.

- Тип элементарной привилегии - определяет группу Элементарной привилегии. Позволяет управлять доступом к группам привилегий, а не по отдельности к каждой элементарной привилегии.

- Объект администрирования (класс `Btk_AcObject`) - логический объект, который соответствует Бизнес объекту, и обладает перечнем элементов администрирования, входящих в этот объект.

- Бизнес объект (класс `Btk_BoEntity`) - логическое объединение нескольких классов в единую сущность. Бизнес объект создается на корневой класс, и включает все его коллекции.

- Базовая выборка - выборка, которая соответствует классу. Например, выборка `Btk_ClassAvi` является базовой выборкой класса `Btk_Class`.

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

- Корневой класс - класс, на который формируется отдельный бизнес объект. Является логическим отдельным объектом, который обладает своими коллекциями.
  Это классы с типом: Справочник, Документ, Настройка, Журнал.

## Принцип построения администрируемых объектов

### Формирование на основе структуры odm.xml

1. На каждый корневой класс создается свой администрируемый объект, имя которого равно имени класса.

2. В администрируемый объект включаются элементы администрирования, которые соответствуют выборкам всех классов входящий в бизнес объект (сам класс и все его коллекции).

Пример структуры бизнес объекта:

      Документ Some_Document
        + Коллекция Some_DocumentPosition
          + Коллекция Some_DocumentPositionDet
        + V-коллекция Коллекция Some_DocumentLink

Пример сформированного администрируемого объекта:

      Администрируемый объект Some_Document
        + Элемент Some_DocumentAvi
        + Элемент Some_Document\Some_DocumentPositionAvi
        + Элемент Some_Document\Some_DocumentPosition\Some_DocumentPositionDetAvi
        + Элемент Some_Document\Some_DocumentLinkAvi

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

### Подключение произвольной выборки в структуру администрируемого объекта

Помимо элементов администрирования, соответствующих базовым выборкам классов бизнес объектов, есть возможность добавить произвольную выборку в структуру администрируемого объекта. Для этого существует 2 способа:

- Подключение в исходном коде:
  В `avm.xml` базовой выборки корневого класса добавить тег `acObject`, в котором указать дополнительные элементы администрирования.

  Пример разметки:

      <view xmlns="http://www.global-system.ru/xsd/global3-view-1.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.global-system.ru/xsd/global3-view-1.0"
         name="Some_Document">

       <acObject>
           <acItems>
               <acItem name="Some_Document\Some_CustomAvi" caption="Произвольная выборка"/>
           </acItems>
       </acObject>
      </view>

  В этом примере объявлен один дополнительный элемент администрирования в составе объекта `Some_Document`, с именем `Some_Document\Some_CustomAvi` и наименованием Произвольная выборка. Наименование используется для визуального отображения этого элемента в приложении «Администратор»

- Подключение через приложение «Администратор».

  1. Открыть карточку нужного объекта администрирования.

  2. Добавить новый элемент на закладке Элементы администрируемого объекта.

## Определение связи выборки и администрируемого объекта

Каждая выборка на открытии в событии `onLoadAdminMeta` через методы выборки `acObject` и `acObjectItem` определяет свою принадлежность к элементу администрирования и объекту администрирования. Все настройки прав доступа к выборке будут искаться по паре значений, которые вернули эти два метода.

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

Чтобы к выборке корректно применялись настройки доступа, в приложении администратор должен быть объект администрирования, имя которого равно результату метода `acObject`, и в составе этого объекта должен быть элемент администрирования, имя которого равно результату метода `acObjectItem`.

### Метод acObject

Возвращает системное имя объекта администрирования к которому относится выборка. Например, `Some_Document`.

Основной принцип:

1. Если выборка принадлежит классу, и класс `корневой`, то имя этого класса = имя администрируемого объекта.

2. Иначе вызывается метод `acObject` мастер-выборки.

### Метод acObjectItem

Возвращает системное имя элемента администрирования в составе объекта. например, `Some_Document\Some_DocumentPositionAvi`.

Основной принцип:

1. Вызывается метод `acObjectItem` мастер-выборки.

2. К полученному значению добавляется текущее имя выборки.

### Базовые выборки классов

Для базовых выборок классов в большинстве случаев корректно отрабатывает стандартная логика определения элемента администрирования и объекта администрирования.

Исключением может служить базовая выборка `v-коллекций`, если она открывается вне формы, на которой расположена базовая выборка мастер-объекта. Например, если открыть список объектов `v-коллекции`, как главную выборку формы.

### Произвольные выборки

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

В большинстве случаев разработчику требуется самостоятельно переопределить работу методов `acObject` и `acObjectItem`.

#### Выборка как самостоятельный администрируемый объект

Если произвольную выборку предполагается использовать как самостоятельный объект администрирования, то требуется:

1. В `avm.xml` объявить тег `acObject`.

2. В `Avi` переопределить методы `acObject` и `acObjectItem` следующим образом:

        override def acObject: NString = {
          baseAvi.simpleName
        }

        override def acObjectItem: NString = {
          baseAvi.simpleName
        }

#### Выборка как часть другого администрируемого объекта

Если произвольную выборку предполагается использовать как часть существующего объекта администрирования, то требуется:

1. В `avm.xml` базовой выборки корневого класса этого бизнес объекта объявить тег `acObject` и внутри него добавить новый элемент администрирования:

       <view xmlns="http://www.global-system.ru/xsd/global3-view-1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.global-system.ru/xsd/global3-view-1.0"
          name="Some_Document">

        <acObject>
            <acItems>
                <acItem name="Some_Document\Some_CustomAvi" caption="Произвольная выборка"/>
            </acItems>
        </acObject>
       </view>

2. в `Avi` произвольной выборки переопределить методы `acObject` и `acObjectItem`:

        override def acObject: NString = {
          //имя объекта
          "Some_Document"
        }

        override def acObjectItem: NString = {
          //путь, который мы указали в теге acItem
          "Some_Document\\Some_CustomAvi"
        }

3. в `Api` произвольной выборки зарегистрировать с помощью метода `Btk_AcObjectItemApi().registerByAcObjectItemName`:

        def regAcObjectItem(): Unit = {
        val bvDefinedAcObjectItem = TxIndex(Btk_AcObjectItemAta.Type)(_.sCode).byKey("Some_Document\\Some_Document\\Some_CustomAvi#Default").isEmpty
        if (bvDefinedAcObjectItem) Btk_AcObjectItemApi().registerByAcObjectItemName("Some_Document\\Some_Document\\Some_CustomAvi#Default")
       }

## Часто задаваемые вопросы

### При заходе не под суперпользователем выборка не отображается/не применяются права

Возможная причина: некорректное определение `acObjectItem` или `acObject`.

Решение:

1. Войдите под суперпользователем или пользователем с правами:

   - доступ к отображению;

   - права на открытие окна отладки.

2. Откройте окно отладки (`Ctrl+Alt+Shift+W`) и проверьте:

   - `acObjectItem` должен быть цепочкой «мастер-деталь»;

   - начало `acObjectItem` должно совпадать с `acObject`.

Примеры корректного определения:

Для выборки как администрируемого объекта:

Для детализации:

Для переопределенной выборки:

Для переопределенной детализации:

Примеры некорректных определений:

1. Переопределение `thisApi` в выборке без класса.

Решение:

- Убрать ненужное переопределение.

- Или переопределить `acObject` соответствующим образом.

2. Коллекция переменной ссылочности без мастера.

Решение:

- Не открывать такие списки как самостоятельные отображения.

- Или переопределить `acObject` как один из возможных БО.

3. Ошибка в переопределении `acObject`.
   Решение:

- Исправить или удалить некорректное переопределение.

Если объект определяется правильно, но проблема осталась:

Решение:

1. Откройте приложение «Администратор»

2. Обновите администрируемый объект.

### Новый атрибут/колонка не отображается у обычного пользователя

Проверка:

1. В приложении «Администратор» найдите нужный элемент администрирования.

2. Убедитесь в наличии нужной привилегии.

Если привилегии нет:

1. Обновите администрируемый объект.

2. Проверьте `avm`:

   - Атрибут определен в `dvm`, но отсутствует в `avm`: добавьте ссылку на шаблон `dvm`.

   - Для динамических построителей: добавьте атрибут в `avm`.

### SQL-ошибка из-за дискретного доступа

Скрипт фильтрации может вызывать ошибки, если:

- Обращается к несуществующим в отображении колонкам.

- Используется параметр (например `&id`), отсутствующий в запросе.

Рекомендации:

1. Используйте только гарантированно существующие колонки (лучше `id`).

2. Для специальных отображений:

   - Если администрирование не нужно: переопределите `isAdministered: Boolean = false`.

   - Если нужно разграничение прав: вынесите в отдельную выборку.

### Отключение администрирования в отображении

Решение:

Для отключения администрирования (например для кастомного отображения) на нужном отображении переопределите метод `isAdministered`: `isAdministered: Boolean = false`.