SalesPlatform Vtiger CRM Developers Руководство Создание виджета рабочего стола
Cистема SalesPlatform Vtiger CRM позволяет отображать оперативную информацию о работе с клиентами при помощи виджетов.
Виджет - это небольшой графический элемент, выводимый на главную страницу системы Vtiger CRM, либо на страницу “Виджеты” для любых Модулей системы.
В системе имеются стандартные Виджеты:
- Журнал
- Ближайшие События
- Воронка продаж
- Стадии Сделок
- Процесс продаж
- Доход от продаж
- Последние Сделки
- Статусы Обращений
- Источники Обращений
- Обращения по отраслям и т.д.
Полный список стандартных виджетов Вы сможете просмотреть на главной странице системы Vtiger CRM при щелчке на раскрывающемся списке “Добавить виджет”.
Если же не достаточно имеющейся функциональности, которая заложена в стандартные виджеты, имеется возможность реализовывать виджеты программно. При его создании желательно отделить прикладную логику и данные от их представления. Для этого создаются:
- Файл с php-кодом;
- Шаблон Smarty.
В качестве примера создадим виджет для Модуля “Мой Модуль”, который будет осуществлять группировку Сделок по стадиям, например:
Стадии Сделки | Количество |
Нуждается в анализе | 1 |
Переговоры | 2 |
Предложение | 3 |
Создание php-кода
Для начала создайте файл “Test.php” (название файла может любое) в директории “modules/MyModule/dashboards/”. Содержимое данного файла представляет собой контроллер, обрабатывающий запросы для получения данных виджета. Поэтому, как будет показано ниже, его содержимое должно быть оформлено в соответствии с некоторыми правилами системы Vtiger CRM: должно быть создано определение класса, имя которого соответствует шаблону "<Имя модуля>_<Имя файла, в котором определен класс>_Dashboard", кроме того данный класс должен быть унаследован от класса Vtiger_Controller или одного из его потомков. Это обеспечивает работосбособность встроенных в систему механизмов обработки запросов, контроля доступа и т.п. В частности, контроль доступа определяется тем, доступен ли текущему пользователю модуль, который обрабатывается запрос. Дополнительно контроль доступа можно осуществлять в методе validateRequest контроллера.
Для начала, опишем логику получения данных для виджета. Произведем подсчет общего количества записей для каждой стадии, при помощи оператора “count()” с использованием группировки (GROUP BY):
$Result = $adb->pquery("SELECT sales_stage, count(sales_stage) AS 'COUNT' FROM vtiger_potential INNER JOIN vtiger_crmentity ON vtiger_potential.potentialid=vtiger_crmentity.crmid INNER JOIN vtiger_potentialscf ON vtiger_potential.potentialid=vtiger_potentialscf.potentialid WHERE vtiger_crmentity.deleted=0 GROUP BY sales_stage");
Далее из результата запроса считываем полученные значения в массивы:
- $array_stage - стадии Сделок;
- $array_count - количество записей для каждой Сделки.
for ($i = 0; $i < $record_count; $i++) { array_push($array_stage, getTranslatedString($adb->query_result($Result, $i, 'sales_stage'), $moduleName)); array_push($array_count, $adb->query_result($Result, $i, 'count')); }
После чего передаем полученные данные в шаблон (см. ниже: создание шаблона Smarty):
$viewer->assign('WIDGET', $widget); $viewer->assign('MODULE_NAME', $moduleName); $viewer->assign('COUNT', $record_count); $viewer->assign('ARRAY_STAGE', $array_stage); $viewer->assign('ARRAY_COUNT', $array_count);
где для передачи данных из php-файла в шаблон используется метод “assign”:
$viewer->assign('name', $name);
в качестве параметров указываются:
- name - название переменной (используется в шаблоне), которая принимает передаваемое значение;
- $name - значение передаваемой переменной.
Ниже представлен готовый php-скрипт:
<?php class MyModule_Test_Dashboard extends Vtiger_IndexAjax_View { public function process(Vtiger_Request $request) { global $adb; $currentUser = Users_Record_Model::getCurrentUserModel(); $viewer = $this->getViewer($request); $moduleName = $request->getModule(); $linkId = $request->get('linkid'); $Result = $adb->pquery("SELECT sales_stage, count(sales_stage) AS 'COUNT' FROM vtiger_potential INNER JOIN vtiger_crmentity ON vtiger_potential.potentialid=vtiger_crmentity.crmid INNER JOIN vtiger_potentialscf ON vtiger_potential.potentialid=vtiger_potentialscf.potentialid WHERE vtiger_crmentity.deleted=0 GROUP BY sales_stage"); $record_count = $adb->num_rows($Result); $array_stage = array(); $array_count = array(); for ($i = 0; $i < $record_count; $i++) { array_push($array_stage, getTranslatedString($adb->query_result($Result, $i, 'sales_stage'), $moduleName)); array_push($array_count, $adb->query_result($Result, $i, 'count')); } $widget = Vtiger_Widget_Model::getInstance($linkId, $currentUser->getId()); $viewer->assign('WIDGET', $widget); $viewer->assign('MODULE_NAME', $moduleName); $viewer->assign('COUNT', $record_count); $viewer->assign('ARRAY_STAGE', $array_stage); $viewer->assign('ARRAY_COUNT', $array_count); $content = $request->get('content'); if(!empty($content)) { $viewer->view('dashboards/TestContents.tpl', $moduleName); } else { $viewer->view('dashboards/Test.tpl', $moduleName); } } }
Создание шаблона Smarty
Smarty - это компилирующий обработчик шаблонов для PHP, предоставляющий один из инструментов, который позволяет добиться отделения прикладной логики и данных от их представления.
Если большинство Ваших шаблонов имеют похожие верхние и нижние части, то желательно вынести их в отдельные файлы и подключать их.
Создайте три файла (можно использовать один) в директории “layouts/vlayout/modules/MyModule/dashboards/”:
- Test.tpl - подгружает ниже перечисленные файлы;
- TestHeader.tpl - файл-заголовок;
- TestContents.tpl - файл-содержимое.
Важно
- Для версии SalesPlatform Vtiger CRM 7 данные три файла следует создать в директории “layouts/v7/modules/MyModule/dashboards/”
Файл Test.tpl:
<script type="text/javascript"> Vtiger_Widget_Js('Vtiger_Test_Widget_Js',{},{}); </script> <div class="dashboardWidgetHeader"> {include file="dashboards/TestHeader.tpl"|@vtemplate_path:$MODULE_NAME} </div> <div class="dashboardWidgetContent"> {include file="dashboards/TestContents.tpl"|@vtemplate_path:$MODULE_NAME} </div>
Файл TestHeader.tpl:
{foreach key=index item=cssModel from=$STYLES} <link rel="{$cssModel->getRel()}" href="{$cssModel->getHref()}" type="{$cssModel->getType()}" media="{$cssModel->getMedia()}" /> {/foreach} {foreach key=index item=jsModel from=$SCRIPTS} <script type="{$jsModel->getType()}" src="{$jsModel->getSrc()}"></script> {/foreach} <table width="100%" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="span5"> <div class="dashboardTitle textOverflowEllipsis" title="{vtranslate($WIDGET->getTitle(), $MODULE_NAME)}" style="width: 15em;"><b> {vtranslate($WIDGET->getTitle(), $MODULE_NAME)}</b></div> </td> <td class="refresh span2" align="right"> <span style="position:relative;"> </span> </td> <td class="widgeticons span5" align="right"> <div class="box pull-right"> {include file="dashboards/DashboardHeaderIcons.tpl"|@vtemplate_path:$MODULE_NAME} </div> </td> </tr> </tbody> </table> <div class="row-fluid filterContainer hide" style="position:absolute;z-index:100001"> <table width="100%" cellspacing="0" cellpadding="0"> <tr> <td> <div class="dashboardTitle" title="">{vtranslate($WIDGET->getTitle(), $MODULE_NAME)}</div> </td> </tr> </table> </div>
Важно
- В версии SalesPlatform Vtiger CRM 7 структура виджета была изменена (кнопки "Фильтр", "Обновить" и "Удалить" размещены внизу виджета), в связи с этим:
1) в конце файла "Test.tpl" следует добавить строки:
<div class="widgeticons dashBoardWidgetFooter"> <div class="filterContainer"> <div class="row"> <span class="col-lg-5"> <span class="pull-right"> {vtranslate('Expected Close Date', $MODULE_NAME)} {vtranslate('LBL_BETWEEN', $MODULE_NAME)} </span> </span> <span class="col-lg-7"> <div class="input-daterange input-group dateRange widgetFilter" id="datepicker" name="expectedclosedate"> <input type="text" class="input-sm form-control" name="start" style="height:30px;"/> <span class="input-group-addon">to</span> <input type="text" class="input-sm form-control" name="end" style="height:30px;"/> </div> </span> </div> </div> <div class="footerIcons pull-right"> {include file="dashboards/DashboardFooterIcons.tpl"|@vtemplate_path:$MODULE_NAME SETTING_EXIST=true} </div> </div>
2) в файле "TestHeader.tpl" необходимо удалить строки:
<td class="refresh span2" align="right"> <span style="position:relative;"> </span> </td> <td class="widgeticons span5" align="right"> <div class="box pull-right"> {include file="dashboards/DashboardHeaderIcons.tpl"|@vtemplate_path:$MODULE_NAME} </div> </td>
Файл TestContents.tpl:
<table class="table table-bordered"> <thead> <tr> <td class="fieldLabel medium"><strong>{vtranslate('LBL_STAGE', $MODULE_NAME)}</strong></td> <td class="fieldLabel medium"><strong>{vtranslate('LBL_COUNT', $MODULE_NAME)}</strong></td> </tr> </thead> {for $i=0 to $COUNT-1} <tr> <td>{$ARRAY_STAGE[$i]}</td> <td>{$ARRAY_COUNT[$i]} </td> </tr> {/for} </table>
Для версии ниже SalesPlatform Vtiger CRM 7 зарегистрируте виджет в таблице “vtiger_links” при помощи скрипта (например: Script.sql) со следующим содержимым:
SET @linkid = (SELECT id+1 FROM vtiger_links_seq); SET @Home_tab_id = (SELECT DISTINCT tabid FROM vtiger_tab WHERE name='Home'); INSERT INTO vtiger_links VALUES (@linkid, @Home_tab_id, 'DASHBOARDWIDGET', 'MyWidget', 'index.php?module=MyModule&view=ShowWidget&name=Test','',14,NULL,NULL,NULL); UPDATE vtiger_links_seq SET id = @linkid;
Важно
- Для версии SalesPlatform Vtiger CRM 7 в таблицу "vtiger_links" было добавлено дополнительное поле "parent_link". В результате запрос для регистрации виджета будет выглядеть следующим образом:
SET @linkid = (SELECT id+1 FROM vtiger_links_seq); SET @Home_tab_id = (SELECT DISTINCT tabid FROM vtiger_tab WHERE name='Home'); INSERT INTO vtiger_links VALUES (@linkid, @Home_tab_id, 'DASHBOARDWIDGET','MyWidget','index.php?module=MyModule&view=ShowWidget&name=Test','',14,NULL,NULL,NULL,NULL); UPDATE vtiger_links_seq SET id = @linkid;
Выполните скрипт:
$ mysql -u <username> -p -i vtiger640 < Script.sql
В результате в раскрывающемся списке “Добавить виджет” появится Ваш виджет, который Вы сможете добавить на главную страницу (см. Рисунок 1) .