Содержание
Этап разработки системы планирования и учета ремонтов оборудования
Введение
На этом этапе мы разработаем экранные формы для планирования и учета ремонтов оборудования, допишем необходимый функционал в источники данных 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
