====== Этап разработки отчетов ====== [[start:|lss]] ===== Введение ===== На этом этапе мы разрабатываем 2 отчета - по планам и фактическому исполнению ремонтов. Мы создаем экранные формы для возможности задать параметры этим отчетам, контроллеры отчетов и прописываем вызовы в главном меню системы. ===== Развертывание этапа на площадке ===== * Скачаем архив **LSS проекта** для текущего этапа. * Обновим проект из архива. Надо быть осторожным с конфигурационным файлом площадки **php/config/config-place.php**, он содержит текущие параметры соединения с базой данных, его обновлять не надо. * база данных не поменялась, скрипты можно не прогонять. ===== Описание ===== ==== Экранные формы для вызова отчетов ==== Для вызова и задания параметров отчета разработаны 2 экранные формы: **formReportPlan** и **formReportFact**. Они похожи, разберем подробно экранную форму **formReportPlan**. Она размещена в папке **php/forms/reports**. XML описание в файле **formReportPlan.xml**:
* В форме присутствует единственный источник данных **filter** с признаком **filter="1"**. Имя **filter** служебное, оно означает, что на стороне сервера у источника данных нет контроллера, все должно быть описано прямо в экранной форме. Признак filter="1" означает особое поведение источника данных - он всегда состоит из 1-й строки, не пытается отписывать значения полей на сервер, автоматически перечитывает подчиненные источники данных при изменении значений своих полей (в нашем случае это не актуально). В нем явно объявлены поля: * **dplanmin**, **dplanmax** - даты * **deparmentid**, **sectorid** - справочники цехов и участков соответственно. Участки привязаны к цехам, если цех не задан то участок readonly. При смене значения поля цеха **deparmentid** формируется запрос **change**, его обрабатывает контроллер экранной формы и очищает участок. * **department_name**, **sector_name** - поля отображения значений цехов и участков, соответствуют полям **name** соответствующих справочников. * **machinetypeid**, **machinestatusid** - поля справочников множественного выбора. Значением поля является список, через запятую, ключей выбранных значений. * форма состоит из 2-х панелей. Справа поля справочника и кнопка перечитки. Слева панель **webbrowser** вызывающая формирование и отображение отчета. Режим **repaint="manual"** означает, что содержимое панели надо обновлять при перечитке связанного с панелью источника данных, в нашем случае это **filter**. Соответственно, запрос **go** формирования отчета, это запрос на перечитку источника данных **filter**. В атрибуте **url="/reports.php?name=plan"** указано имя контроллера отчета - **plan**. Параметры **param** передают контроллеру отчетов значения полей источника данных **filter**. Для этой экранной формы написан контроллер - **formReportPlan.php**: class FormReportPlan extends FormController { protected function getDefinitionMacro($params=Array()) { $result=parent::getDefinitionMacro($params); return $result; } public function getResponse($params=Array(), $events=Array()) { $result=''; $dataSourceName=$params['#request.datasource']; $requestName=$params['#request.name']; $requestMode=$params['#request.mode']; if ($dataSourceName=='filter') { if ($requestName=='change' && $requestMode=='departmentid') { $result.="\n".<< XML; } } return $result; } } return new FormReportPlan(); * метод **getResponse** позволяет обрабатывать запросы контроллером формы. В нашем случае он обрабатывает запрос **change** поля **departmentid**, посылая ответ, требующий очистить поля участка при смене цеха. ==== Контроллеры отчетов ==== Разработаны 2 контроллера отчетов - **plan** и **fact**. Они размещены в папке **php/reports**. Разберем подробно контроллер **plan.php**: includeLib('lib-report.php'); class ReportPlan extends ReportController { public function getParams() { $params=parent::getParams(); if (testDate($_REQUEST['dplanmin'])) $params['dplanmin']=$_REQUEST['dplanmin']; if (testDate($_REQUEST['dplanmax'])) $params['dplanmax']=$_REQUEST['dplanmax']; if ($_REQUEST['departmentid']) { $dataStorageDepartment=getDataStorage('department'); $itemDepartment=$dataStorageDepartment->getItem($_REQUEST['departmentid']); if ($itemDepartment->getId()) $params['departmentid']=$itemDepartment->getId(); } if ($_REQUEST['sectorid']) { $dataStorageSector=getDataStorage('sector'); $itemSector=$dataStorageSector->getItem($_REQUEST['sectorid']); if ($itemSector->getId()) $params['sectorid']=$itemSector->getId(); } if ($_REQUEST['machinetypeid']) { $dataStorageMachineType=getDataStorage('machinetype'); $lst=Array(); foreach($dataStorageMachineType->getItems(Array('filter.id'=>$_REQUEST['machinetypeid'])) as $itemMachineType) { $machinetypeid=$itemMachineType->getId(); $lst[$machinetypeid]=$machinetypeid; } if (count($lst)>0) $params['machinetypeid']=$lst; } if ($_REQUEST['machinestatusid']) { $dataStorageMachineStatus=getDataStorage('machinestatus'); $lst=Array(); foreach($dataStorageMachineStatus->getItems(Array('filter.id'=>$_REQUEST['machinestatusid'])) as $itemMachineStatus) { $machinestatusid=$itemMachineStatus->getId(); $lst[$machinestatusid]=$machinestatusid; } if (count($lst)>0) $params['machinestatusid']=$lst; } return $params; } public function getBody(&$params=Array()) { $format=$params['format']; $result=<<План ремонтов HTML; $sql_where='1=1'; $html_params=''; { // период $html=''; if ($params['dplanmin']) { if ($html) $html.=' '; $html.='с '.date2Html($params['dplanmin']).''; $sql_date=$this->str2Sql($params['dplanmin']); $sql_where.="\n".<<='{$sql_date}' HTML; } if ($params['dplanmax']) { if ($html) $html.=' '; $html.='по '.date2Html($params['dplanmax']).''; $sql_date=$this->str2Sql($params['dplanmax']); $sql_where.="\n".<<getItem($params['departmentid']); $html.='цех '.$itemDepartment->getHtml('name').''; $sql_value=$this->php2SqlIn($params['departmentid']); $sql_where.="\n".<<getItem($params['sectorid']); $html.='участок '.$itemSector->getHtml('name').''; $sql_value=$this->php2SqlIn($params['sectorid']); $sql_where.="\n".<<getItems(Array('filter.id'=>$params['machinetypeid'])) as $itemMachineType) { if ($html) $html.=', '; $html.=''.$itemMachineType->getHtml('name').''; } $sql_value=$this->php2SqlIn($params['machinetypeid']); $sql_where.="\n".<<getItems(Array('filter.id'=>$params['machinestatusid'])) as $itemMachineStatus) { if ($html) $html.=', '; $html.=''.$itemMachineStatus->getHtml('name').''; } $sql_value=$this->php2SqlIn($params['machinestatusid']); $sql_where.="\n".<< {$html_params} HTML; } $p=Array(); $p['sql']=<<'dplan', 'caption'=>'Плановая дата', 'type'=>'date' ); $fields[]=Array( 'fieldname'=>'repair_name', 'caption'=>'Вид ремонта' ); $fields[]=Array( 'fieldname'=>'invnum', 'caption'=>'Инвентарный номер' ); $fields[]=Array( 'fieldname'=>'model', 'caption'=>'Модель' ); $fields[]=Array( 'fieldname'=>'department_name', 'caption'=>'Цех' ); $fields[]=Array( 'fieldname'=>'sector_name', 'caption'=>'Участок' ); $fields[]=Array( 'fieldname'=>'machinetype_name', 'caption'=>'Тип оборудования' ); $fields[]=Array( 'fieldname'=>'machinestatus_name', 'caption'=>'Состояние оборудования' ); $p['fields']=$fields; $p['format']=$format; $objReport=new ReportBuilder($p); $result.=$objReport->Get(); unset($objReport); if ($format=='html') { $toolBarPrint=$this->getToolBarPrint($params); $result=<< {$toolBarPrint} {$result} HTML; } return $result; } } return new ReportPlan(); * метод **getParams** разбирает входные параметры отчета, проверяет их корректность и возвращает в виде ассоциативного массива. * метод **getBody** возвращает HTML текст отчета. Для формирования отчета используется генератор табличных отчетов из **php/lss-server/lib/lib-report.php**. Формируется SQL запрос, описание полей и по ним строится таблица. Режим **format** может принимать значения '**html**', '**xls**', '**word**'. В зависимости от него формируется HTML, адаптированный под корректное отображение в web-браузере, MS-Excel или MS-Word. ==== Главное меню проекта ==== Главное меню проекта описывается в XML файле **php/config/appmenu.xml**: * Добавлен раздел **Отчеты** ===== Демонстрационные примеры и ссылки ===== Демонстрационные примеры доступны в режиме "**только чтение**". Для входа используйте логин **root**, пароль **1**. * демонстрация работы **тестового примера** "Материальные активы" у нас на сайте: [[https://lss.m-cti.ru/storage/example/lss-exampl]]