Универсальный фильтр#

Как создать дополнительную группу фильтрации по классу#

  1. На операции lazyInitFilter инициализируем дополнительную группу:

    override def lazyInitFilter(): Unit = {
      if (!fltManager.isPopulatedRootGroup) {
        Btk_FltPkg().createRootGroupByClass(fltManager, "Bs_Goods", "ТМЦ")
      }
      super.lazyInitFilter()
    }
    
  2. На onApplyFiler получаем текст фильтрации по группе:

    override def onApplyFilter(): Unit = {
      super.onApplyFilter()
      //проверяем, что группы инициализированы и фильтр активен в выборке
      if (fltManager.isPopulatedRootGroup && fltManager.isActive) {
        val alias = "tt"
        val macros = Btk_FltPkg().generateMacroByGroup(fltManager, "Bs_Goods", alias)
        selection.setMacro("GdsMacro", macros.where)   
      }
    }
    
  3. В операции onRefresh используем установленный в onApplyFiler макрос:

    • Через метод prepareSelectStatement

    override protected def onRefresh: Recs = {
      prepareSelectStatement("&GdsMacro")
    }
    
    • В тексте sql-запроса

    override protected def onRefresh: Recs = {
      """
        select .....
          from .....
         where ....
           and &GdsMacro
      """
    }
    

Как создать дополнительную группу фильтрации с произвольными атрибутами#

  1. На операции lazyInitFilter инициализируем дополнительную группу:

    override def lazyInitFilter(): Unit = {
      if (!fltManager.isPopulatedRootGroup) {
         Btk_FltPkg().createCustomRootGroup(fltManager, "Some_CustomGroup", "Произвольная группа", (builder) => {
           builder.addRefObjectAttr("idGds", "Тмц", "Bs_Goods")
           builder.addBasicAttr("sCode", "Код", AttributeTypes.Varchar, false)
         })
      }
      super.lazyInitFilter()
    }
    
  2. На onApplyFiler получаем текст фильтрации по группе:

    override def onApplyFilter(): Unit = {
      super.onApplyFilter()
      //проверяем, что группы инициализированы и фильтр активен в выборке
      if (fltManager.isPopulatedRootGroup && fltManager.isActive) {
        val macros = Btk_FltPkg().generateMacroByGroup(fltManager, "Some_CustomGroup", "tt")
        selection.setMacro("SomeMacro", macros.where)   
      }
    }
    
  3. В операции onRefresh используем установленный в onApplyFiler макрос:

    • Через метод prepareSelectStatement

    override protected def onRefresh: Recs = {
      prepareSelectStatement("&SomeMacro")
    }
    
    • В тексте sql-запроса

    override protected def onRefresh: Recs = {
      """
        select .....
          from ..... 
         where ....
           and &SomeMacro
      """
    }
    

Как добавить json-атрибуту признак раскрываемости в дереве атрибутов и сформировать атрибуты, которые будут отображаться при его раскрытии.#

def afterBuildFltEntityMeta(fltMetaEntity: FltMetaEntity, fltManager: FltManager): Unit = {
  //проверка, что переданный класс - класс, для которого нужно добавить логику
  if (fltMetaEntity.name == "Bs_Goods") {
    //определяем, что json-атрибут доступен по умолчанию.
    val typeSizeAttrOpt = fltMetaEntity.attrMap.get("jTypeSizeAttrs".toLowerCase)
    if (typeSizeAttrOpt.isDefined) {
      val typeSizeAttr = typeSizeAttrOpt.get
      //ставим признак, что он может быть раскрыт в дереве
      Btk_FltMetaAttributePkg().setCanExpand(typeSizeAttr, true)

      //формируем атрибуты-потомки
      for (rvx <- new OQuery(Gds_TypeSizeCharacteristicAta.Type) {
      }) {
        //создаем значимые атрибуты, которые хранятся в json-контейнере
        val fltAttr = Btk_FltMetaAttributePkg().buildBasicJObjectAttr(
          systemName = rvx.get(_.sCode),
          caption = rvx.get(_.sCaption),
          dbType = AttributeTypes.Number,
          isBoolean = false,
          jsonColumnName = "jTypeSizeAttrs"
        )

        //устанавливаем созданному атрибуту потомка.
        Btk_FltMetaAttributePkg().setParentTree(fltAttr, typeSizeAttr)

        //добавляем атрибут в общий перечень атрибутов.
        fltMetaEntity.attrMap(fltAttr.systemName.toLowerCase) = fltAttr
      }
    }
  }
}

Примечание

Каждый из таких атрибутов формирует условие, которое получает значение из json-контейнера.

Как сделать значимый атрибут ссылочным и добавить признак раскрываемости в дереве атрибутов.#

def afterBuildFltEntityMeta(fltMetaEntity: FltMetaEntity, fltManager: FltManager): Unit = {
  // Проверка, что переданный класс - класс, для которого нужно добавить логику.
  if(fltMetaEntity.name == "Bs_Goods") {
      // Вызываем из пакета `Btk_FltMetaAttributePkg` метод для создания значимого атрибута `buildBasicAttr`.
      val fltAttr = Btk_FltMetaAttributePkg().buildBasicAttr( 
        systemName = "screateuser_dz",              // systemName — системное имя атрибута. Уникально в пределах одного класса,
        caption = "Создавший пользователь",         // caption — отображаемое наименование,
        dbType = AttributeTypes.Varchar,            // dbType — тип данных,
        isBoolean = false)                          // isBoolean — булевый атрибут.

      // Вызываем из пакета `Btk_FltMetaAttributePkg` метод для установки параметров преобразования атрибута в ссылочный `setExpandableParams`.
      Btk_FltMetaAttributePkg().setExpandableParams(
        fltAttr = fltAttr,                          // fltAttr — атрибут фильтра, который преобразуется в ссылочный,
        selfAttrName = "screateuser_dz",            // selfAttrName — имя поля в текущем объекте (self), используемое в выражении selfJoinExpression,
        selfJoinExpression = "lower(${column})",    // selfJoinExpression — выражение, которое формирует правую часть условия JOIN, используя поле текущего объекта,
        childAttrName = "susername",                // childAttrName — имя поля в дочернем объекте (child), используемое в выражении childJoinExpression,
        childJoinExpression = "lower(${column})",   // childJoinExpression — выражение, которое формирует левую часть условия JOIN, используя поле дочернего объекта,
        refClass = "Btk_User")                      // refClass — имя класса (таблицы), к которой делается JOIN.
      // Здесь формируется join по атрибутам с приведением значений к нижнему регистру (через lower).
      // ${column} — подставляет алиас таблицы и имя поля, которое указываем в `selfAttrName` или `childAttrName`
      // в зависимости от выражения `selfJoinExpression` подставляется `selfAttrName`, а к `childJoinExpression` подставляется `childAttrName`.
      // В результате получается запрос вида: 
      //  join Btk_User t94 on lower(t94.susername) = lower(t93.screateuser_dz)
    
      // Ставим признак, что атрибут может быть раскрыт в дереве.
      Btk_FltMetaAttributePkg().setCanExpand(fltAttr, true)

      // Добавляем атрибут в общий перечень атрибутов.
      fltMetaEntity.attrMap(fltAttr.systemName.toLowerCase) = fltAttr
  }
}

Как скрыть группу Отбор#

Для скрытия группы «Отбор» необходимо в операции инициализации фильтра lazyInitFilter установить флаг ru.bitec.app.btk.flt.FltAviManager#isAvailableMainGroup в значение False.

Пример кода:

override def lazyInitFilter(): Unit = {
  if (!fltManager.isPopulatedRootGroup) {
    fltManager.isAvailableMainGroup = false
  }
  super.lazyInitFilter()
}