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

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


lssexampl-04-doc

Этап разработки системы планирования и учета ремонтов оборудования

lss

Введение

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

lssexampl-04-doc.txt · Последнее изменение: 2024/07/08 12:56 — 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki