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

# Практики при разработке документов

## ODM документа

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

- У полей с датами в названии системного имени НЕ пишем слово Date
  Примеры:

  - dReg;

  - dDoc;

  - dExec.

- Для поля с датой регистрации, ставим значение по умолчанию текущую дату `defaultValue="sysdate"`.

- Для полей с номерами, датой рег., состоянием и номером состояния устанавливаем.`isCopyInCopyObject="false"`, чтобы значения не копировались при копировании

- Для полей с номером, датой и типом объекта устанавливаем свойство `isHeadLine="true"`, так как они в большинстве случаем участвуют в вычислении заголовкаю

- Добавляем поле с номером состояния, не видимоею

            <attr name="idStateMC" attribute-type="Number" caption="Номер состояния" order="80" type="basic"
                  isVisible="false" isCopyInCopyObject="false" isStateMC="true">
                <mnemoCodeColumn/>
            </attr>

- Большинство полей можно взять из шаблона: `bs\src\main\resources\META-INF\attribute-template.xml`
  Доп. поля связанные со складом и тмц: `stk\src\main\resources\META-INF\attribute-template.xml`

- Для денежных полей с суммами и ценами устанавливаем сразу денежный редактор: `editorType="currency"`

- Для булевых полей ставим значение по умолчанию 0 `defaultValue="0"` и тип редактора галку `editorType="check"`

- Добавляем скрипты регистрации состояний, закладок и типов документа (вместо Demo_Doc напишите свой класс)

        <dbData>
            <script name="regObjectType" version="1">
                <depends>
                    <dep on="Demo_Doc.regTab"/>
                    <dep on="Demo_Doc.regState"/>
                </depends>
                <install>Demo_DocApi.regObjectType(false);</install>
            </script>
            <script name="regState" version="1">
                <install>Demo_DocApi.regState();</install>
            </script>
            <script name="regTab" version="1">
                <install>Demo_DocApi.regTab();</install>
            </script>
        </dbData>

- Если нужны прикрепленные файлы устанавливаем свойство в шапку: `attachType="simple"` или `attachType="versioned"` для версионного режима.

- Если нужна настройка по счетам учета, то добавляем в коллекции настройку: `<var-collection name="Bs_AccObjSetting" ref.attr="gidSrc" cascadeOnDelete="true"/>`.

## ODM коллекции документа

- Наименование коллекций, как правило, содержит имя документа (может быть и сокращенное) и суффикс `Det` или какой то другой, например `Demo_DocDet`.

- Порядковый номер для позиций следует наименовать как `nRow - № п/п` и делать его числовым, наименование `nOrder` путает с `Bs_Order`. Его не следует делать автонумерующимся, так как нумерация срабатывает на сохранение. Нумерацию можно сделать руками в `Api.insertByParent` (ниже будет пример).

## Api документа:

- Вместо `ListBuffer` следует использовать `ArrayBuffer`, так как он меньше занимает места в памяти.

- Переопределяем `calcHeadLine`, для вычисление заголовка с учетом типа документа, номера и даты:

      override def calcHeadLine(idp: NLong): NString = {
        var svHeadLine = NString()
        if (idp.isNotNull) {
          load(idp) :> { aro =>
            if (aro != null) {
              svHeadLine = s"${Btk_ObjectTypeApi().getShortCaption(aro.idObjectType).nvl(Btk_ClassApi().getHeadLine(aro.idClass))} №" ++ aro.sNumDoc.nvl("") ++ " от " ++ aro.dDoc.toString("dd.MM.yyyy").nvl("")
            }
          }
        }
        svHeadLine
      }

- Переопределяем `insert` для установки типа объекта по умолчанию и других атрибутов (например валюта и тип курса) при создании:

      override def insert(): ApiRop = {
        val rop = super.insert()
        //установка типа объекта по умолчанию
        setidObjectType(rop, Btk_ObjectTypeApi().getDefaultObjType(idClass))

        //установки даты документа без времени
        //setdDoc(rop, NDate.now().truncate())

        //установка нац. валюты Cur_Currency
        //setidCur(rop, Cur_CurrencySettingsApi().getidCurrencyMain)
        //установка типа курса Cur_CurrencyRateType
        //setidCurRateType(rop, Cur_CurrencySettingsApi().getidCurrencyRateType)

        //установка типа налогообложения Tax_TaxType
        //setidTaxType(rop, Tax_TaxTypeApi().getDefaults)
        //установка ставки налога по умолчанию Tax_TaxRate
        //setidVATRate(rop, Tax_TaxRateApi().getDefaults)

        //установка текущего пользователя Btk_User
        //setidUser(rop, Btk_UserApi().getCurrentUserID)
        //установка текущего физ. лица Bs_Person
        //setidPerson(rop, Bs_PersonApi().getCurrentPersonID)
        //установка текущего сотрудника Bs_Employee
        //setidEmployee(rop, Bs_EmployeeApi().getidCurrentEmployee)

        rop
      }

- Переопределяем `delete`, чтобы нельзя было удалить документ, если он находится не в состоянии Оформляется:

      override def delete(rop: ApiRop): Unit = {
        if (rop.get(_.idStateMC).isDistinct(100.nn))
          throw AppException("Ошибка. Удаление документа возможно только в состоянии \"Оформляется\".")
        //Удаление из журнала с признаками проведения в учетах
        //Bs_FlagAccKindBookDocApi().delByObj(rop.gid)
        //Удаление из журнала связанных документов
        //Bts_DocLinkApi().delByDoc(rop.gid)
        super.delete(rop)
      }

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

      override def setidDepOwner(rop: ApiRop, value: NLong): Unit = {
        super.setidDepOwner(rop, value)
        Bs_AccObjSettingApi().registerAccObjSetByObjectForDoc(
          gidpObject = rop.gid
        )
        //если есть КПП организации, то устанавливаем его
        //setidSelfKpp(rop, Bs_DepOwnerApi().getIdDefKpp(value))
      }

      override def setidObjectType(rop: ApiRop, value: NLong): Unit = {
        super.setidObjectType(rop, value)
        Bs_AccObjSettingApi().registerAccObjSetByObjectForDoc(
          gidpObject = rop.gid
        )
      }

- Для `setidState` в прикладной логике надо использовать номера состояний, а на их id.
  Пример действий на перевод состояний:

      //проверки для документа при выполнении
      protected def validateOnAccept(rop: ApiRop): Unit = {

      }

      //проверки для документа при откате
      protected def validateOnDecline(rop: ApiRop): Unit = {
        //проверка на наличие проведения в бух., нал., упр. учетах
        //Bs_FlagAccKindBookDocApi().validateObj(rop.gid)
      }

      //действия на выполнен
      protected def accept(rop: ApiRop): Unit = {
        //если не заполнена дата исполнения, то заполняем ее текущей датой
        //if (rop.get(_.dExec).isNull)
        //  setdExec(rop, NDate.now())
      }

      //действия на откат из выполнен
      protected def decline(rop: ApiRop): Unit = {

      }

      override def setidState(rop: ApiRop, value: NLong): Unit = {
        //номера состояний
        //из какого
        val nvStateFrom = rop.get(_.idStateMC) //если нет поля можно использовать Btk_ClassStateApi().getOrder(rop.get(_.idState))
        //в какое
        val nvStateTo = Btk_ClassStateApi().getOrder(value)
        //Должно выполняться в самом начале. На понижение состояния (с учетом состояния в настройке) - проверка проведения в бух. учете, при синхронном проведении, откат проводок
        Bs_TransPkg().setidStateBefore(rop, rop.get(_.idObjectType), nvStateFrom, nvStateTo)

        //переход в выполнен (вверх по состоянию)
        if (nvStateTo >= 300.nn && nvStateFrom < 300.nn) {
          //проверки для документа при выполнении
          validateOnAccept(rop)
          //действия на выполнен
          accept(rop)
        } else if (nvStateTo < 300.nn && nvStateFrom >= 300.nn) {
          //проверки для документа при откате
          validateOnDecline(rop)
          //действия на откат из выполнен
          decline(rop)
        }

        super.setidState(rop, value)

        //Должно выполняться в самом конце. На повышение состояния (с учетом состояния в настройке): при синхронном проведение - выполнение ТХО, при отложенном - добавление в очередь отложенного проведения документов
        Bs_TransPkg().setidStateAfter(rop, rop.get(_.idObjectType), nvStateFrom, nvStateTo)
      }

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

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

      /**
        * прогрузка в кэш самого документа с коллекциями
        *
        * @param idap
        */
      protected def loadDocWithCollections(idp:NLong): Unit = {
        new OQuery(entityAta.Type) {
          where(t.id === idp)
          batchIn(Demo_DocDetAta, Demo_DocDetItemAta, Stk_OperationAta)
        }.foreach { rop => }
      }

- Создаем метод `regState` для регистрация состояний (здесь просто написан пример).

      def regState(): Unit = {
        session.commit()
        Btk_Pkg().setRWSharedUOWEditType()
        //первоначальное состояние
        Btk_ClassStateApi().register(
          idpMasterClass = idClass,
          spSystemName = "Create",
          spCaption = "Оформляется",
          bpStartState = 1.nn,
          npOrer = 100.nn
        )
        session.flush()
        Btk_ClassStateApi().register(
          idpMasterClass = idvClass,
          spSystemName = "Annulled",
          spCaption = "Аннулирован",
          bpStartState = 0.nn,
          npOrer = 50.nn)
        Btk_ClassStateApi().register(
          idpMasterClass = idClass,
          spSystemName = "Agreed",
          spCaption = "Согласуется",
          bpStartState = 0.nn,
          npOrer = 200.nn)
        Btk_ClassStateApi().register(
          idpMasterClass = idClass,
          spSystemName = "Executed",
          spCaption = "Выполнен",
          bpStartState = 0.nn,
          npOrer = 300.nn
        )
        session.commit()
      }

- Создаем метод `regTab` для регистрация закладок
  Примеры:

      //регистрация закладок
      def regTab(): Unit = {
        session.commit()
        Btk_Pkg().setRWSharedUOWEditType()

        Btk_TabApi().register(
          spCaption = "Позиции",
          spSel = "gtk-Demo_DocDetAvi",
          spRep = "List_idDoc",
          idprefClass = idClass
        )

        Btk_TabApi().register(
          spCaption = "Прикрепленные файлы"
          , spSel = "gtk-Btk_AttachItemAvi"
          , spRep = "List_SimpleAttach"
          , idprefClass = idClass
        )

        Btk_TabApi().register(
          spCaption = "Объектные характеристики",
          spSel = "gtk-Demo_DocAvi",
          spRep = "Card_ObjectAttr",
          idprefClass = idClass
        )

        Btk_TabApi().register(
          spCaption = "Связанные документы"
          , spSel = "gtk-Bts_DocLinkAvi"
          , spRep = "Tree"
          , idprefClass = idClass
        )

        Btk_TabApi().register(
          spCaption = "Проводки",
          spSel = "gtk-Act_TransAvi",
          spRep = "List_gidDoc",
          idprefClass = idClass
        )

        Btk_TabApi().register(
          spCaption = "Настройка счетов учета",
          spSel = "gtk-Bs_AccObjSettingAvi",
          spRep = "List_gidSrc",
          idprefClass = idClass
        )
        session.commit()
      }

- Создаем метод `regObjectType` для регистрация типов объекта (здесь просто написан пример)

      //регистрация типов
      def regObjectType(bpNeedRefresh: Boolean = false): Unit = {
        session.commit()
        Btk_Pkg().setRWSharedUOWEditType()
        //параметр bpNeedRefresh = false нужен, чтобы не затирать данные на проектных базах, если такого типа объекта нет, то он будет создан
        //если хотите все перезаписать, то выполните в Jexl скрипте Demo_DocApi.regObjectType(true);
        if (bpNeedRefresh || Btk_ObjectTypeApi().findByMnemoCodeAndClass("Demo_DocObjType", idClass).isNull) {
          //регистрируем тип
    	    val idvOT = Btk_ObjectTypeApi().register(spCode = "Demo_DocObjType"
            , spCaption = "Тип А"
            , spShortCaption = "Документ А"
            , idpRefClass = idClass
            , bpIsDefault = 1.nn)

    	    //ищем закладку и привязываем к типу
          var idvTab = Btk_TabApi().findByMnemoCode("Demo_DocAvi.List_idDoc")
          if (idvTab.isNotNull)
            Btk_ObjectTypeTabApi().registerTab(
              idpObjectType = idvObjectType
              , idpTab = idvTab
              , spCaption = "Позиции"
              , npOrder = 10.nn
            )

          idvTab = Btk_TabApi().findByMnemoCode("Demo_DocAvi.Card_ObjectAttr")
          if (idvTab.isNotNull)
            Btk_ObjectTypeTabApi().registerTab(
              idpObjectType = idvObjectType
              , idpTab = idvTab
              , spCaption = "Характеристики"
              , npOrder = 20.nn
            )

    	    //регистрируем переходы состояний для типа
          Btk_StateChangeApi().registerForObjectType(idvOT, List(
            "Create" -> "Agreed",
            "Agreed" -> "Executed",
            "Agreed" -> "Create",
            "Executed" -> "Create",
            "Executed" -> "Agreed"
          ))
        }
        session.commit()
      }

## Api коллекции

- Переопределяем `insertByParent` для установки порядкового номера при создании:

      override def insertByParent(ropParent: AnyRop): ApiRop = {
        val nvRow = byParent(ropParent).map(_.get(_.nRow).nvl(0.nn)).reduceOption(_ max _).getOrElse(0.nn) + 1.nn
        super.insertByParent(ropParent) :/ { rop =>
          setnRow(rop, nvRow)
          rop
        }
      }

## Avi документа:

### для отображения List

- Переопределяем `onRefreshItem`, чтобы выполнялся запрос из `selectStatement`.

        override protected def onRefreshItem: Recs = {
          prepareSelectStatement(s"t.$getPKFieldName = :$getPKFieldName")
        }

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

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

        override def checkWorkability(): Unit = {
          super.checkWorkability()
          val bvRO = getSelfVar("idStateMC").asNNumber.isDistinct(100.nn)
          opers().setEnabled("Delete", selection.canDelete && !getVar("ID").isNull && !bvRO)
        }

- Если нужно передать параметры в карточку при создании из списка, надо переопределить метод `insert_Params`, и затем обработать данный параметр в отображении для карточки в методе `onInsertItem`.
  Пример передачи организации из фильтра списка.

        override def insert_Params(): Map[String, Any] = {
          Map("idDepOwner#" -> getVar("flt_idDepOwner").asNLong)
        }

- Если нужно сделать фильтр по состоянию или типу, надо добавить на `beforeFirstOpen` переменные со значением id нашего класса, чтобы работали стандартные вып. списки для типа и состояния.

        override protected def beforeFirstOpen(): Unit = {
          super.beforeFirstOpen()
          addVar("idStateClass#", thisApi().idClass, FieldType.ftInteger) // для фильтра по состоянию
          addVar("idObjTypeClass", thisApi().idClass, FieldType.ftInteger) // для фильтра по типу
        }

- Для установки значений по умолчанию при открытии для полей в фильтре c датами и организации, значения которых будут браться из глобального фильтра, надо использовать значения по умолчанию через Avm, а не через `beforeFirstOpen`.

### для отображения Card - шапки

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

        override protected def onInsertItem(): Unit = {
          super.onInsertItem()
          //если был передана организация через параметр
          val idvDepOwner = getSelfVar("idDepOwner#").asNLong.nvl(getVar("super$idGlobalDepOwner").asNLong)
          if (idvDepOwner.isNotNull) thisApi().setidDepOwner(thisRop(), idvDepOwner)
        }

- Если есть закладки или детальные формы, то переопределяем `refresh`, чтобы при нажатии обновить обновлялись детали тоже:

        override def refresh(): Unit = {
          super.refresh()
          selection.refreshDetails()
        }

- Переопределяем `saveForm`, чтобы прописать обновление карточки, если есть автонумерующиеся атрибуты:

        @Oper(refreshAfter = true)
        override def saveForm(): Unit = super.saveForm()
        //или так
        override def saveForm(): Unit = {
          super.saveForm()
          selection.refreshItem()
        }

- Если нужна операция с молоточком и ключом, то устанавливаем для нее активность:

        @Oper(active = true)
        override def extraOperations() = super.extraOperations()

- Переопределяем `setidState`, чтобы дописать различные действия:

        override def setidState(event: SetterEvent): Unit = {
          super.setidState(event)

          //завершение транзакции
          session.commit()
          //снятие блокировки
          Btk_FormSessionApi().closeLockUnit()

          //обновление карточки
          selection.refreshItem()
          //вызов checkWorkability в карточке
          selection.checkWorkability()
          //вызов checkWorkability в деталях
          selection.cwaDetails()
          //если нужно обновление деталей вместо cwaDetails используем selection.refreshDetails
        }

- Переопределяем CWA, для блокировки полей и операций в зависимости от состояния:

        //для управления редактируемостью атрибутов
        protected def setAttrReadOnly(): Unit = {
          val avAttrsNotApply = Set("DREG", "SREGNUM", "IDSTATE", "IDSTATEHL")
          val bvStNotForm = thisRop().get(_.idStateMC).isDistinct(100.nn)
          attrs().filterNot(f => avAttrsNotApply.contains(f.name.toUpperCase))
            .foreach(_.isReadOnly = bvStNotForm)
        }

        //для управления видимостью атрибутов
        protected def setAttrVisible(): Unit = {
          //(A.idObjectType + "HL").isVisible = false
        }

        //для управления активностью операций
        protected def setEnabledOpers(): Unit = {
          val bvStNotForm = thisRop().get(_.idStateMC).isDistinct(100.nn)
          val bvStAcc = thisRop().get(_.idStateMC) >= 300.nn
          opers("fillDoc").isEnabled = !bvStNotForm
          opers("clonePrint").isEnabled = bvStAcc
        }

        override def checkWorkability(): Unit = {
          super.checkWorkability()
          //для управления редактируемостью атрибутов
          setAttrReadOnly
          //для управления видимостью атрибутов
          setAttrVisible
          //для управления активностью операций
          setEnabledOpers
        }

- Реляционные запросы в `onRefresh` в карточках не следует использовать, так как если будет написан запрос, то перед выполнением произойдет сразу СОХРАНЕНИЕ. Все доп. поля пишем либо через `onRefreshExt`, `additionalInfo` или `case class`.

- Если переопределяете `LookUp` или пишите свои вып. списки, не забывайте дописывать `@FlushBefore(mode = FlushBeforeMode.Disabled)`, так как это тоже приводит к коммиту при вызове запроса.

        import ru.bitec.app.gtk.gl.{FlushBefore, FlushBeforeMode}

        @FlushBefore(mode = FlushBeforeMode.Disabled)
        override protected def onRefresh: Recs

## Avi коллекции

- Переопределяем `onRefresh`, чтобы добавить сортировку по №п/п:

        override def onRefresh: Recs = {
          thisApi().refreshByParent(getIdMaster).toList.sortBy(_.get(_.nRow))
        }

- Реляционные запросы в `onRefresh` в коллекциях не следует использовать, так как если будет написан запрос, то перед выполнением произойдет сразу СОХРАНЕНИЕ. Все доп. поля пишем либо через `onRefreshExt`, `additionalInfo` или объектный `List[case class]`.

- Переопределяем CWA, для блокировки полей и операций, в зависимости от состояния:

        //для управления редактируемостью атрибутов
        protected def setAttrReadOnly(): Unit = {
          val bvStNotForm = getVar("super$idStateMC").asNNumber.isDistinct(100.nn)
          attrs().foreach(_.isReadOnly = bvStNotForm)
        }

        //для управления видимостью атрибутов
        protected def setAttrVisible(): Unit = {
          //(A.idGds + "HL").isVisible = false
        }

        //для управления активностью операций
        protected def setEnabledOpers(): Unit = {
          val bvStNotForm = getVar("super$idStateMC").asNNumber.isDistinct(100.nn)
          opers("insert").isEnabled = getIdMaster.isNotNull && !bvStNotForm
          opers("delete").isEnabled = !bvStNotForm && !A.id.isNull
          opers("copyObject").isEnabled = !bvStNotForm && !A.id.isNull
        }

        override def checkWorkability(): Unit = {
          super.checkWorkability()
          //для управления редактируемостью атрибутов
          setAttrReadOnly
          //для управления видимостью атрибутов
          setAttrVisible
          //для управления активностью операций
          setEnabledOpers
        }

## Avm документа

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

                <attr name="idObjectTypeHL" caption="Тип" order="50.2" editorType="lookup" isLastInLine="false" isVisible="true">
                    <editor>
                        <lookup lookupQuery="gtk-Btk_ObjectTypeAvi#MainLookup" isLookupLazyLoad="true"
                                changeableAttr="idObjectType" lookupKeyAttr="id" lookupListAttr="sHeadLine"
                                isResetButtonVisible="true"/>
                    </editor>
                </attr>

- Для атрибута организация в отображении Default устанавливаем тип редактора - выпадающий список:

                <attr name="idDepOwnerHL" caption="Организация" order="70.2" isRequired="true">
                    <editor>
                        <lookup lookupQuery="gtk-Bs_DepOwnerAvi#Lookup"
                                changeableAttr="idDepOwner" isLookupLazyLoad="false"
                                lookupKeyAttr="id" lookupListAttr="sHeadLine" isResetButtonVisible="false"/>
                    </editor>
                </attr>

- Устанавливаем закладки от типа документа, по умолчанию видимые в карточке и не видимые в списке (`isVisible="false"`):

    <tabItems isVisible="true" selection="gtk-Btk_ObjectTypeTabAvi"
                              representation="List_Tab"
                              selection.selectionAttr="SSELECTIONNAME"
                              selection.representationAttr="SREPRESENTATIONNAME"
                              selection.captionAttr="SCAPTION"
                              selection.imageIndexAttr="NIMAGE"
                              selection.paramsAttr="JSONPARAMS"
                    />

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

                    <!--Период с-->
                    <condition id="filterFrom" logicalOperator="and" isExpression="true"
                               expression=":flt_dFrom &lt;= t.dPeriod">
                        <filterAttr attribute-type="Date" name="flt_dFrom" editorType="datePick" order="10.0"
                                    caption="Период с" isLastInLine="false" defaultValue="super$DGLOBALBEGINDATE">
                            <card controlWidth="24" isControlWidthFixed="true"/>
                        </filterAttr>
                    </condition>
                    <!--Период по-->
                    <condition id="filterTo" logicalOperator="and" isExpression="true"
                               expression=":flt_dTo &gt;= t.dPeriod">
                        <filterAttr attribute-type="Date" name="flt_dTo" editorType="datePick" order="20.0" caption="по"
                                    isLastInLine="false" defaultValue="super$DGLOBALENDDATE">
                            <card controlWidth="20" isControlWidthFixed="true"/>
                        </filterAttr>
                    </condition>
                    <!--План счетов-->
                    <condition logicalOperator="and" id="filterIdAdjustMethod" isExpression="true"
                               expression="t.idAdjustMethod = :flt_idAdjustMethod">
                        <filterAttr name="flt_idAdjustMethod" attribute-type="Long" isVisible="false" order="30"
                                    defaultValue="super$idGlobalAdjustMethod"/>
                        <filterAttr name="flt_idAdjustMethodHL" attribute-type="Varchar" caption="План счетов" order="30.1"
                                    editorType="lookup" isLastInLine="false">
                            <editor>
                                <lookup lookupQuery="gtk-Bs_AdjustMethodAvi#Lookup"
                                        lookupKeyAttr="id" lookupListAttr="sHeadLine" changeableAttr="flt_idAdjustMethod"
                                        isLookupLazyLoad="false" isResetButtonVisible="true"/>
                            </editor>
                        </filterAttr>
                    </condition>
                    <!--Организация-->
                    <condition logicalOperator="and" id="filterIdDepOwner" isExpression="true"
                               expression="t.idDepOwner = :flt_idDepOwner">
                        <filterAttr name="flt_idDepOwner" attribute-type="Long" caption="Организация" order="50"
                                    defaultValue="super$idGlobalDepOwner" isVisible="false"/>
                        <filterAttr name="flt_idDepOwnerHL" attribute-type="Varchar" caption="Организация" order="50.2"
                                    editorType="lookup" isLastInLine="false">
                            <editor>
                                <lookup lookupQuery="gtk-Bs_DepOwnerAvi#Lookup"
                                        changeableAttr="flt_idDepOwner" isLookupLazyLoad="false"
                                        lookupKeyAttr="id" lookupListAttr="sHeadLine" isResetButtonVisible="true"/>
                            </editor>
                        </filterAttr>
                    </condition>