Пользовательское условие на вывод данных в listview. Часть 2

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

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

Способ полностью в стиле Upgrade Safe, и заключается в переопределении SugarCRM класса ListView для нашего модуля. Для наглядности возьмем все ту же любимую задачу: для всех пользователей, кроме администратора, необходимо не показывать закрытые сделки.

Создаем файл по пути custom/modules/Opportunities/views/view.list.php

Если у вас этот файл уже есть, вам надо будет только добавить описанную ниже функцию listViewProcess ().

<?php
require_once('include/MVC/View/views/view.list.php');

class OpportunitiesViewList extends ViewList
{
  function __construct()
  {
    parent::ViewList();
  }

  function listViewProcess()
  {
    $this->processSearchForm();

    // Наш пользовательский запрос
    // для администраторов по умолчанию показываем все записи
    // Для всех остальных только не закрытые сделки
    if (!is_admin($GLOBALS['current_user']))
    {
      // если уже есть запрос where то дописываем к нему, а иначе наш запрос единственный
      if (!empty($this->where)) $this->where .= ' AND ';
      // Сюда можно добавить любое условие
      $this->where .= " sales_stage NOT IN ('Closed Won', 'Closed Lost') ";
    }
    // Конец пользовательского запроса
    // Стандартный код функции listViewProcess
    $this->lv->searchColumns = $this->searchForm->searchColumns;
    if(!$this->headers) return;
    if(empty($_REQUEST['search_form_only']) || $_REQUEST['search_form_only'] == false)
    {
      $this->lv->setup($this->seed, 'include/ListView/ListViewGeneric.tpl', $this->where, $this->params);
      $savedSearchName = empty($_REQUEST['saved_search_select_name']) ? '' : (' - ' . $_REQUEST['saved_search_select_name']);
      echo get_form_header($GLOBALS['mod_strings']['LBL_LIST_FORM_TITLE'] . $savedSearchName, '', false);
      echo $this->lv->display();
    }
  }
}
?>

Я включил комментарии непосредственно в код, так что в дополнительных комментариях, думаю, нужды нет. Если вам нужен запрос и для администраторов в том числе, то просто уберите условие if is_admin ($GLOBALS['current_user'])).

Допустим, пользователи все-таки имеют возможность просмотреть информацию об уже закрытых заказах. После нашего изменения, если они выберут в поиске условие посмотреть заказы в стадиях продаж «Закрыто с успехом» или «Закрытом с потерями»:

Выбор стадии сделки в SugarCRM

то в ответ они получат пустой список, так как мы добавили им условие не показывать сделки в данных стадиях. И будут «приятно» удивлены и, скорее всего, первым, к кому они побегут за помощью, будете именно вы :-)

Перепишем наше условие так, чтобы только в случае, если пользователь не запрашивает сделки с определенными стадиями, мы применяли фильтр, а иначе выдавали пользователю, то что он «просил».

Я не буду повторно приводить полный код, лишь приведу новое условие:

// Наш пользовательский запрос
// для администраторов по умолчанию показываем все записи
// Для всех остальных только не закрытые сделки
if (($_REQUEST['searchFormTab'] == 'advanced_search' AND empty($_REQUEST['sales_stage_advanced']))
	OR ($_REQUEST['searchFormTab'] == 'basic_search' AND empty($_REQUEST['sales_stage_basic'])))
	{
	  // если уже есть запрос where, то дописываем к нему, а иначе наш запрос единственный
	  if (!empty($this->where)) $this->where .= ' AND ';
	  // Сюда можно добавить любое условие
	  $this->where .= " sales_stage NOT IN ('Closed Won', 'Closed Lost') ";
	}
// Конец пользовательского запроса

Как видно по условию, мы проверяем, какая панель поиска сейчас включена (базовый или расширенный поиск) и выбрано ли в данной панели условие стадии сделки. Только в случае отсутствия мы добавляем наше условие.

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

Выбор стадии сделки в SugarCRM

Чтобы избавиться и от этого недостатка, просто добавим в запрос REQUEST данные значения фильтра, как будто их запросил пользователь. Это обязательно надо делать до того, как обработается форма поиска $this->processSearchForm (); Так что окончательный код функции listViewProcess с учетом всех особенностей будет таким:

function listViewProcess()
{
  if (($_REQUEST['searchFormTab'] == 'advanced_search' AND empty($_REQUEST['sales_stage_advanced']))
    OR ($_REQUEST['searchFormTab'] == 'basic_search' AND empty($_REQUEST['sales_stage_basic'])))
  {
    if ($_REQUEST['searchFormTab'] == 'advanced_search')
    {
      // это расширенный поиск
      $_REQUEST['sales_stage_advanced'] = array ('Closed Won', 'Closed Lost');
    }
    else
    {
      // это базовый поиск
      $_REQUEST['sales_stage_basic'] = array ('Closed Won', 'Closed Lost');
    }
  }

  $this->processSearchForm(); 

  // Наш пользовательский запрос
  // для администраторов по умолчанию показываем все записи
  // Для всех остальных только не закрытые проекты
  if (($_REQUEST['searchFormTab'] == 'advanced_search' AND empty($_REQUEST['sales_stage_advanced']))
    OR ($_REQUEST['searchFormTab'] == 'basic_search' AND empty($_REQUEST['sales_stage_basic'])))
  {
    if ($_REQUEST['searchFormTab'] == 'advanced_search')
    {
      // это расширенный поиск
      $_REQUEST['sales_stage_advanced'] = array ('Closed Won', 'Closed Lost');
    }
    else
    {
      // это базовый поиск
      $_REQUEST['sales_stage_basic'] = array ('Closed Won', 'Closed Lost');
    }
    // если уже есть запрос where, то дописываем к нему, а иначе наш запрос единственный
    if (!empty($this->where)) $this->where .= ' AND ';
    // Сюда можно добавить любое условие
    $this->where .= " sales_stage NOT IN ('Closed Won', 'Closed Lost') ";
  }
  // Конец пользовательского запроса

  // Стандартный код функции listViewProcess
  $this->lv->searchColumns = $this->searchForm->searchColumns; 

  if(!$this->headers) return; 
  if(empty($_REQUEST['search_form_only']) || $_REQUEST['search_form_only'] == false)
  {
    $this->lv->setup($this->seed, 'include/ListView/ListViewGeneric.tpl', $this->where, $this->params);
    $savedSearchName = empty($_REQUEST['saved_search_select_name']) ? '' : (' - ' . $_REQUEST['saved_search_select_name']);
    echo get_form_header($GLOBALS['mod_strings']['LBL_LIST_FORM_TITLE'] . $savedSearchName, '', false);
    echo $this->lv->display();
    }
  }

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

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

Думаю, что сегодня я вас уже переутомил тоннами кода :-) Так что до новых встреч.

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

Есть 2 коммент. к “Пользовательское условие на вывод данных в listview. Часть 2”

  1. Memet:

    Добрый день.

    Отличная статья, спасибо.

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

    ДЛя того что бы не открывать всплывающее окно, а просто выбрать нужный параметр и отфильтровать? Спасибо.

  2. Шуга Админ:

    Есть. Если Вас интересуют какие либо вопросы, то обсуждение по данной теме доступно на нашем форуме в соответствующей ветке

Написать комментарий

Вы должны войти чтобы комментировать.