Инструменты пользователя

Инструменты сайта


lssexampl-05-report

Этап разработки отчетов

lss

Введение

На этом этапе мы разрабатываем 2 отчета - по планам и фактическому исполнению ремонтов. Мы создаем экранные формы для возможности задать параметры этим отчетам, контроллеры отчетов и прописываем вызовы в главном меню системы.

Развертывание этапа на площадке

  • Скачаем архив LSS проекта для текущего этапа.
  • Обновим проект из архива. Надо быть осторожным с конфигурационным файлом площадки php/config/config-place.php, он содержит текущие параметры соединения с базой данных, его обновлять не надо.
  • база данных не поменялась, скрипты можно не прогонять.

Описание

Экранные формы для вызова отчетов

Для вызова и задания параметров отчета разработаны 2 экранные формы: formReportPlan и formReportFact. Они похожи, разберем подробно экранную форму formReportPlan. Она размещена в папке php/forms/reports. XML описание в файле formReportPlan.xml:

<form name="%form%" caption="Отчет по плану ремонтов">
  <rowsets>
    <rowset name="filter" filter="1" >
      <fields>
        <field name="dplanmin"  type="date" caption="с"/>
        <field name="dplanmax"  type="date" caption="по"/>

        <field name="departmentid" type="ref" caption="Цех">
          <change>
            <param name="departmentid"/>
          </change>
          <ref datasource="department"/>
        </field>
        <field name="sectorid" type="ref" caption="Участок" js_readonly="!get('filter.departmentid')">
          <ref datasource="sector">
            <param name="filter.departmentid" js_value="get('filter.departmentid',-1)"/>
          </ref>
        </field>

        <field name="machinetypeid" type="multilist" caption="Тип оборудования" refname="name" stretch="1">
          <ref datasource="machinetype"/>
        </field>
        <field name="machinestatusid" type="multilist" caption="Состояние" refname="name" stretch="1">
          <ref datasource="machinestatus"/>
        </field>

        <field name="department_name" type="string" refid="departmentid" refname="name" stretch="1" caption="Цех"/>
        <field name="sector_name" type="string" refid="sectorid" refname="name" stretch="1" caption="Участок"/>
      </fields>
    </rowset>
  </rowsets>
	
  <request name="go" icon="ok" caption="Перечитать">
    <request rowset="filter" name="refresh"/>
  </request>

  <panels>
    <panel rowset="filter">
      <panel align="right" type="scroll" width="420px" color="scheme3" margin="1">
        <panel align="top" height="10px"/>
        <panel align="top" type="fields" caption="Период">
          <field name="dplanmin" line="1"/>
          <field name="dplanmax" line="1"/>
        </panel>
				
        <panel align="top" height="6px"/>
        <panel align="top" height="1px" color="white"/>
        <panel align="top" height="6px"/>
        <panel type="fields" align="top" padding="5px" captionup="1" caption="Место размещения">
          <field name="department_name"/>
          <field name="sector_name"/>
        </panel>
        <panel align="top" height="6px"/>
        <panel align="top" height="1px" color="white"/>
        <panel align="top" height="6px"/>
        <panel type="fields" align="top" padding="5px" captionup="1" caption="Дополнительно">
          <field name="machinetypeid"/>
          <field name="machinestatusid"/>
        </panel>
        <panel align="top" height="6px"/>
        <panel align="top" height="1px" color="white"/>
        <panel align="top" height="6px"/>
        <panel align="top">
          <buttons>
            <request name="go" align="right"/>
          </buttons>
        </panel>
      </panel>
      
      <panel border="1">
        <panel rowset="filter" type="webbrowser" url="/reports.php?name=plan" repaint="manual">
          <param name="dplanmin" js_value="get('filter.dplanmin')" skipempty="1"/>
          <param name="dplanmax" js_value="get('filter.dplanmax')" skipempty="1"/>
          <param name="departmentid" js_value="get('filter.departmentid')" skipempty="1"/>
          <param name="sectorid" js_value="get('filter.sectorid')" skipempty="1"/>
          <param name="machinetypeid" js_value="get('filter.machinetypeid')" skipempty="1"/>
          <param name="machinestatusid" js_value="get('filter.machinestatusid')" skipempty="1"/>
        </panel>
      </panel>
      
    </panel>
  </panels>
</form>
  • В форме присутствует единственный источник данных 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
<response name="ok">
<change sectorid="" sector_name=""/>
</response>
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
<h1>План ремонтов</h1>
HTML;
		
		$sql_where='1=1';
		$html_params='';
		{  // период
			$html='';
			if ($params['dplanmin']) {
				if ($html) $html.=' ';
				$html.='с <b>'.date2Html($params['dplanmin']).'</b>';
				$sql_date=$this->str2Sql($params['dplanmin']);
				$sql_where.="\n".<<<HTML
and "machinerepair".dplan>='{$sql_date}'
HTML;
			}
			if ($params['dplanmax']) {
				if ($html) $html.=' ';
				$html.='по <b>'.date2Html($params['dplanmax']).'</b>';
				$sql_date=$this->str2Sql($params['dplanmax']);
				$sql_where.="\n".<<<HTML
and "machinerepair".dplan<='{$sql_date}'
HTML;
			}
			if ($html) {
				if ($html_params) $html_params.="\n";
				$html_params.="<div>{$html}</div>";
			}
		}
		{  // цех, участок
			$html='';
			if ($params['departmentid']) {
				if ($html) $html.=', ';
				$dataStorageDepartment=getDataStorage('department');
				$itemDepartment=$dataStorageDepartment->getItem($params['departmentid']);
				$html.='цех <b>'.$itemDepartment->getHtml('name').'</b>';
				$sql_value=$this->php2SqlIn($params['departmentid']);
				$sql_where.="\n".<<<HTML
and "machine".departmentid in ({$sql_value})
HTML;
			}
			if ($params['sectorid']) {
				if ($html) $html.=', ';
				$dataStorageSector=getDataStorage('sector');
				$itemSector=$dataStorageSector->getItem($params['sectorid']);
				$html.='участок <b>'.$itemSector->getHtml('name').'</b>';
				$sql_value=$this->php2SqlIn($params['sectorid']);
				$sql_where.="\n".<<<HTML
and "machine".sectorid in ({$sql_value})
HTML;
			}
			if ($html) {
				if ($html_params) $html_params.="\n";
				$html_params.="<div>{$html}</div>";
			}
		}
		{  // тип оборудования
			$html='';
			if ($params['machinetypeid']) {
				$dataStorageMachineType=getDataStorage('machinetype');
				foreach($dataStorageMachineType->getItems(Array('filter.id'=>$params['machinetypeid'])) as $itemMachineType) {
					if ($html) $html.=', ';
					$html.='<b>'.$itemMachineType->getHtml('name').'</b>';
				}
				$sql_value=$this->php2SqlIn($params['machinetypeid']);
				$sql_where.="\n".<<<HTML
and "machine".machinetypeid in ({$sql_value})
HTML;
			}
			if ($html) {
				if ($html_params) $html_params.="\n";
				$html_params.="<div>тип оборудования {$html}</div>";
			}
		}
		{  // состояние оборудования
			$html='';
			if ($params['machinestatusid']) {
				$dataStorageMachineStatus=getDataStorage('machinestatus');
				foreach($dataStorageMachineStatus->getItems(Array('filter.id'=>$params['machinestatusid'])) as $itemMachineStatus) {
					if ($html) $html.=', ';
					$html.='<b>'.$itemMachineStatus->getHtml('name').'</b>';
				}
				$sql_value=$this->php2SqlIn($params['machinestatusid']);
				$sql_where.="\n".<<<HTML
and "machine".machinestatusid in ({$sql_value})
HTML;
			}
			if ($html) {
				if ($html_params) $html_params.="\n";
				$html_params.="<div>состояние оборудования {$html}</div>";
			}
		}
		if ($html_params) {
$result.="\n".<<<HTML
<div class="params-report">
{$html_params}
</div>
HTML;
		}
		
		$p=Array();
		$p['sql']=<<<SQL
select
	"machine".*,
	"machinerepair".dplan,
	"repair".name as repair_name,
	"department".name as department_name,
	"sector".name as sector_name,
	"machinetype".name as machinetype_name,
	"machinestatus".name as machinestatus_name
from
	"machine"
		join "machinerepair" on 
			"machinerepair".machineid="machine".id and
			"machinerepair".dplan is not null
		left join "repair" on "repair".id="machinerepair".repairid
		left join "department" on "department".id="machine".departmentid
		left join "sector" on "sector".id="machine".sectorid
		left join "machinetype" on "machinetype".id="machine".machinetypeid
		left join "machinestatus" on "machinestatus".id="machine".machinestatusid
where
{$sql_where}
order by "machinerepair".dplan desc, "machine".invnum, "machine".id
SQL;

		$fields=Array();
		$fields[]=Array(
			'fieldname'=>'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=<<<HTML
<div class="container">
{$toolBarPrint}
{$result}
</div>
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:

<node name="Паспорта оборудования и ремонты" icon="box" form="formMachine"/>
<node name="Типы оборудования и нормативы ремонтов" icon="ref" form="ref.formMachineType"/>
<node name="Отчеты" icon="print">
  <node name="Отчет по плану ремонтов" icon="print" form="reports.formReportPlan"/>
  <node name="Отчет по выполненным ремонтам" icon="print" form="reports.formReportFact"/>
</node>
<node name="Справочники" icon="reffolder">
  <node name="Структура предприятия" icon="ref" form="ref.formDepartment"/>
  <node name="Виды ремонта" icon="ref" form="ref.formRepair"/>
  <node name="Состояния оборудования" icon="ref" form="ref.formMachineStatus"/>
</node>
  • Добавлен раздел Отчеты

Демонстрационные примеры и ссылки

Демонстрационные примеры доступны в режиме «только чтение». Для входа используйте логин root, пароль 1.

lssexampl-05-report.txt · Последнее изменение: 2024/07/08 13:01 — 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki