Содержание
Этап разработки системы планирования и учета ремонтов оборудования
Введение
На этом этапе мы разработаем экранные формы для планирования и учета ремонтов оборудования, допишем необходимый функционал в источники данных DataSource, скорректируем главное меню системы.
Развертывание этапа на площадке
- Скачаем архив LSS проекта для текущего этапа.
- Обновим проект из архива. Надо быть осторожным с конфигурационным файлом площадки php/config/config-place.php, он содержит текущие параметры соединения с базой данных, его обновлять не надо.
- Выполним с помощью утилиты pgAdmin скрипт заполнения содержимого таблиц первоначальными значениями, файл export-import/backup/backup.sql.
Описание
Контроллеры источников данных DataSource
Контроллер для таблицы machine
Вот содержимое файла контроллера источника данных для таблицы оборудования machine, файл php/datasources/machine.php:
class DataSource_Machine_Ext extends DataSource_Machine { protected function onRowAfter(&$row, $params=Array()) { $row['sectorid.readonly']=$row['departmentid']?0:1; } public function execChange($params=Array()) { $result=parent::execChange($params); $fieldName=$params['#request.mode']; if ($fieldName=='departmentid') { $row=Array(); $row['row.change']=1; $row['sectorid.readonly']=$params['departmentid']?0:1; $row['sectorid']=''; $row['sector_name']=''; $result[]=$row; } return $result; } } return new DataSource_Machine_Ext();
- обработчик событий onRowAfter при чтении данных на сервере задает признак readonly полю Участок если не задано значение поля Цех
- метод execChange вызывается при правке пользователем значения поля Цех. Обратите внимание, в экранной форме Разработка/Структура базы у поля departmentid таблицы machine задан параметр change со значением departmentid. Это означает, что правка пользователем этого поля будет отправлять на сервер запрос change с параметром departmentid содержащим исправленное значение этого поля. В ответе можно скорректировать значения других полей, в нашем случае мы при правке Цеха очищаем Участок и корректируем для него признак readonly.
Контроллер для таблицы machinerepair
Вот содержимое файла контроллера источника данных для таблицы запланированных и фактически выполненных ремонтов machinerepair, файл php/datasources/machinerepair.php:
class DataSource_Machinerepair_Ext extends DataSource_Machinerepair { protected function initRequests() { $result=parent::initRequests(); $result[]=Array( 'name'=>'rebuild', 'permoper'=>'write' ); return $result; } public function exec($params=Array()) { $requestName=$params['#request.name']; $requestMode=$params['#request.mode']; if ($requestName=='rebuild') { return $this->execRebuild($params); } return parent::exec($params); } public function execRebuild($params=Array()) { $this->rebuild(24); $result=Array(); return $result; } protected function rebuild($maxperiod) { $sql_dmax=(new DateTime())->modify("+{$maxperiod} month")->format('Y-m-01'); { // удаляем строки плана ремонтов $sql=<<<SQL delete from "machinerepair" where "machinerepair".dfact is null SQL; $this->pdo($sql); } { // упорядочиваем справочник видов ремонтов $sql=<<<SQL update "repair" set npp=a.npp from ( select "repair".id, rank() over (order by "repair".name, "repair".id) as npp from "repair" ) a where "repair".id=a.id and "repair".npp<>a.npp SQL; $this->pdo($sql); } { // добавляем строки планов ремонтов for($i=0; $i<500; $i++) { $sql=<<<SQL insert into "machinerepair" ( machineid, repairid, dplan ) select m.machineid, m.repairid, m.dnext from( select *, rank() over (partition by machineid order by m.dnext, m.repair_npp) as npp from ( select *, date_trunc('MONTH', m.dlast + (interval '1 month')*m.period)::DATE as dnext from ( select "machine".id as machineid, "repair".id as repairid, max("repair".npp) as repair_npp, max("repairnorm".period) as period, max( case when "machinerepair".id is null then "machine".dfrom when "machinerepair".dfact is null then "machinerepair".dplan else "machinerepair".dfact end ) as dlast from "machine" left join "repairnorm" on "repairnorm".machinetypeid="machine".machinetypeid left join "repair" on "repair".id="repairnorm".repairid left join "repair" "prepair" on "prepair".npp<="repair".npp left join "machinerepair" on "machinerepair".machineid="machine".id and "machinerepair".repairid="prepair".id group by "machine".id, "repair".id ) m ) m ) m where m.dnext<='{$sql_dmax}' and m.npp=1 SQL; $q=$this->pdo($sql); if (!$q->rowCount()) break; } } return; } protected function onRowAfter(&$row, $params=Array()) { $row['dplan.readonly']=1; if ($row['dplan']) { $row['repairid.readonly']=1; $row['machineid.readonly']=1; } } protected function onRowAfterDelete(&$row, $params=Array()) { if ($row['dplan']) throw new Exception('Задана плановая дата ремонта, нельзя удалять'); } } return new DataSource_Machinerepair_Ext();
- добавляем в источник данных поддержку запроса repair - полный пересчет плана ремонтов оборудования на 24 месяца вперед.
- переопределяем метод initRequests для регистрации запроса rebuild, это нужно для передачи LSS визуализатору описания поддерживаемых источником данных запросов
- переопределяем метод exec для обработки запроса rebuild посредством вызова метода execRebuild
- реализуем методы execRebuild и rebuild для выполнения пересчета. Подробное описание алгоритма мы тут приводить не будем, скажем только, что реализован он посредством специфических SQL запросов для диалекта PostgreSql . Сначала мы очищаем все строки плана, а затем, в цикле, для каждого оборудования формируем очередной ближайший ремонт. Цикл заканчивается либо когда все строки плана сформированы (новых нет), либо когда превышено максимально допустимое число шагов итерации - в нашем случае 500.
- обработчик событий onRowAfter выставляет признак readonly полям Оборудование и Вид ремонта для автоматически сформированных строк плана ремонта
- обработчик событий onRowAfterDelete блокирует возможность ручного удаления автоматически сформированных строк плана ремонта. Этот обработчик вызывается после удаления строк, но перед подтверждением транзакции. Вызов исключения приводит к откату транзакции.
Контроллер для таблицы repairnorm
Вот содержимое файла контроллера источника данных для таблицы норм ремонтов repairnorm, файл php/datasources/repairnorm.php:
class DataSource_Repairnorm_Ext extends DataSource_Repairnorm { /// переопределяем проверку после правки строки protected function onRowValid(&$row) { { // проверка значений repairid и machinetypeid на уникальность - для более понятного пользователю сообщения об ошибке $sql_repairid=$this->str2Sql($row['repairid']); $sql_machinetypeid=$this->str2Sql($row['machinetypeid']); $sql_id=$this->str2Sql($row['id']); $sql=<<<SQL select count(*) as n from "repairnorm" where "repairnorm".repairid='{$sql_repairid}' and "repairnorm".machinetypeid='{$sql_machinetypeid}' and "repairnorm".id<>'{$sql_id}' SQL; $rec=$this->pdoFetch($sql); if ($rec['n']) throw new Exception("Для типа оборудования '{$row['machinetype_name']}' периодичность ремонта '{$row['repair_name']}' уже задана"); } { // проверка значения периодичности ремонта if ($row['period']<=0) throw new Exception('Периодичность ремонтов должна быть положительна'); } } } return new DataSource_Repairnorm_Ext();
- обработчик события onRowValid проверяет уникальность сочетания полей Оборудование и Вид ремонта, и проверяет неотрицательность значения поля Периодичность ремонта.
Экранные формы FormController
Экранная форма нормативов ремонта
Экранная форма справочника Типы оборудования переделана в экранную форму Типы оборудования и нормативы ремонта:
<form name="%form%" caption="Типы оборудования и нормативы ремонтов"> <rowsets> <rowset name="machinetype"> <rowset name="repairnorm"> <param name="filter.machinetypeid" js_value="get('machinetype.id')"/> </rowset> </rowset> </rowsets> <panels> <panel> <panel type="grid" rowset="machinetype"> <toolbar menu="1"> <request rowset="#this" name="undo"/> <request rowset="#this" name="save"/> <request rowset="#this" name="refresh"/> <separator/> <request rowset="#this" name="append"/> <request rowset="#this" name="delete"/> </toolbar> <fields> <field name="name"/> </fields> </panel> <panel splitter="1" type="grid" rowset="repairnorm" align="right" width="50%"> <toolbar menu="1"> <request rowset="#this" name="undo"/> <request rowset="#this" name="save"/> <request rowset="#this" name="refresh"/> <separator/> <request rowset="#this" name="append"/> <request rowset="#this" name="delete"/> </toolbar> <fields> <field name="repair_name" stretch="1"/> <field name="period"/> </fields> </panel> </panel> </panels> </form>
- к источнику данных machinetype добавлен дочерний источник данных repairnorm, автоматически перечитывающийся при смене текущей строки родительского источника данных.
- добавлена дополнительная панель grid, позволяющая в табличном виде редактировать содержимое источника данных repairnorm.
Экранная форма паспортов оборудования и ремонтов
Разработана экранная форма formMachine, XML описание ее расположено в файле php/forms/formMachine/formMachine.xml:
<form name="%form%" caption="Паспорт оборудования"> <rowsets> <rowset name="machine"> <rowset name="machinerepair"> <param name="filter.machineid" js_value="get('machine.id')"/> </rowset> <rowset name="repairnorm" readonly="1"> <param name="filter.machinetypeid" js_value="get('machine.machinetypeid')"/> </rowset> </rowset> </rowsets> <requests> <request name="machinerepair-rebuild" icon="process" caption="Пересчитать план" confirm="Пересчитать план ремонтов для всего оборудования?"> <request rowset="machinerepair" name="rebuild"/> <request rowset="machinerepair" name="refresh"/> </request> </requests> <panels> <panel> <panel type="grid" rowset="machine" align="left" width="40%"> <toolbar menu="1"> <request rowset="#this" name="undo"/> <request rowset="#this" name="save"/> <request rowset="#this" name="refresh"/> <separator/> <request rowset="#this" name="append"/> <request rowset="#this" name="delete"/> </toolbar> <fields> <field name="invnum"/> <field name="machinetype_name" stretch="1"/> </fields> <buttons> <request name="machinerepair-rebuild" align="right"/> </buttons> </panel> <panel type="tab"> <panel rowset="machine" caption="Паспорт"> <panel type="scroll"> <panel align="top" type="fields" captionup="1" caption="Оборудование"> <field name="invnum" line="invnum"/> <field name="machinetype_name" line="invnum" stretch="1"/> <field name="dfrom" line="invnum" caption="ввод в экспл"/> <field name="model" line="dfrom" stretch="1"/> </panel> <panel align="top" type="fields" captionup="1" caption="Место размещения"> <field name="department_name" line="department" stretch="1"/> <field name="sector_name" line="department" stretch="1"/> </panel> <panel align="top" type="fields" captionup="1" caption="Состояние"> <field name="machinestatus_name" line="dstatus" stretch="1"/> <field name="dstatus" line="dstatus" caption="начало состояния"/> </panel> </panel> </panel> <panel rowset="machinerepair" caption="Ремонты"> <panel type="grid"> <toolbar menu="1"> <request rowset="#this" name="undo"/> <request rowset="#this" name="save"/> <request rowset="#this" name="refresh"/> <separator/> <request rowset="#this" name="append"/> <request rowset="#this" name="delete"/> </toolbar> <fields> <field name="dfact" caption="фактическая дата" len="12"/> <field name="repair_name" stretch="1"/> <field name="dplan"/> </fields> </panel> </panel> <panel rowset="repairnorm" caption="Нормативы ремонтов"> <panel type="grid"> <toolbar menu="1"> <request rowset="#this" name="refresh"/> </toolbar> <fields> <field name="repair_name" stretch="1"/> <field name="period"/> </fields> </panel> </panel> </panel> </panel> </panels> </form>
- задействованы родительский источник данных списка оборудования machine и два дочерних: список ремонтов machinerepair и нормы ремонтов repairnorm. Нормы ремонтов в этой экранной форме приведены для ознакомления, поэтому источник данных repairnorm подключен в режиме только для чтения.
- в разделе запросов формы requests объявлен запрос перестроения планов ремонтов оборудования machinerepair-rebuild. Он вызывает запрос rebuild источника данных machinerepair а затем для отображения пересчитанного плана ремонтов вызывает перечитку источника данных machinerepair.
- Структура панелей организована следующим образом: слева панель grid паспортов оборудования, справа панель закладок tab, составленная из 3-х панелей:
- анкета паспорта оборудования
- grid списка ремонтов
- grid норматива ремонтов
- Вызов запроса machinerepair-rebuild пересчитывающего план ремонтов сделан кнопкой
Главное меню проекта
Главное меню проекта описывается в XML файле php/config/appmenu.xml:
<node name="Паспорта оборудования и ремонты" icon="box" form="formMachine"/> <node name="Типы оборудования и нормативы ремонтов" icon="ref" form="ref.formMachineType"/> <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.
- демонстрация работы тестового примера «Материальные активы» у нас на сайте: https://lss.m-cti.ru/storage/example/lss-exampl