OSDN Git Service

6ed8265a512be2dacfaa07ec0bdfb28c0ab6d2c6
[invent/invent.git] / controllers / ItemsController.php
1 <?php
2
3 namespace app\controllers;
4
5 use Yii;
6 use app\models\Items;
7 use app\models\Import;
8 use app\models\Check;
9 use app\models\Moving;
10 use app\models\Locations;
11 use app\models\ItemsSearch;
12 use app\models\MovingSearch;
13 use app\models\Status;
14 use app\models\User;
15 use yii\web\Controller;
16 use yii\web\NotFoundHttpException;
17 use yii\web\UploadedFile;
18 use yii\filters\VerbFilter;
19
20 use kartik\mpdf\Pdf;
21 use \phpexcel;
22
23 #require "/vendor/phpoffice/phpexcel/Classes/PHPExcel.php";
24
25 /**
26  * ItemsController implements the CRUD actions for Items model.
27  */
28 class ItemsController extends Controller
29 {
30     /**
31      * {@inheritdoc}
32      */
33     public function behaviors()
34     {
35         return [
36             'verbs' => [
37                 'class'   => VerbFilter::className(),
38                 'actions' => [
39                     'delete' => [ 'POST' ],
40                 ],
41             ],
42         ];
43     }
44
45     /**
46      * Добавление предмета/оборудование если его нет
47      * @param array $options
48      *        string 'invent'
49      *        string 'model'
50      *        string 'comment'
51      *        string|NULL 'type'
52      *        string|NULL 'netname'
53      *        string|NULL 'os'
54      *        string|NULL 'mac'
55      *        string|NULL 'serial'
56      *        string|NULL 'product'
57      *        string|NULL 'modelnumber'
58      * @return integer|FALSE
59      */
60     public static function addIfNeed($options)
61     {
62         $result = [
63             'id' => FALSE,
64             'error' => Yii::t('items', 'Items: Key field missing "invent" :') . print_r($options, TRUE),
65         ];
66         // Если указан инвентарный номер
67         if (is_array($options) && isset($options[ 'invent' ]))
68         {
69             $item = Items::find()
70                 ->where([ 'invent' => $options[ 'invent' ]]); // Ищем оборудование с инвентарным номером.
71             // Если указан серийный номер
72             if (isset($options[ 'serial' ])) {
73                 $item = $item->andWhere([ 'like', 'serial', $options[ 'serial' ]]); // Ищем дополнительно с серийным номером
74             }
75             $item = $item->all(); // Получаем все записи
76
77             if (count($item) > 0) // Записи найдены, выводим первую совпавшую
78             {
79                 $result[ 'id' ] = $item[ 0 ]->id;
80                 $result[ 'error' ] = '';
81             }
82             else
83             {
84                 // Внесённого оборудования не найдено. Добавим новую запись
85                 if (isset($options[ 'model' ]))
86                 {
87                     $model = ModelsController::addIfNeed($options);
88                     if ($model[ 'id' ] === FALSE)
89                     {
90                         $result[ 'error' ] .= '<br />' . $model[ 'error' ];
91                     }
92                     else
93                     {
94                         // Создаём новую запись предмета/оборудования
95                         $item = new Items();
96                         $item->name        = isset($options[ 'netName' ]) ? $options[ 'netName' ] : NULL; // Сетевое имя
97
98                         $item->model_id    = $model[ 'id' ];                                              // идентификатор модели (Подготовлено для преобразования)
99                         $item->invent      = isset($options[ 'invent' ]) ? $options[ 'invent' ] : NULL;   // Инвентарный номер
100                         $item->comment     = isset($options[ 'comment' ]) ? $options[ 'comment' ] : NULL; // Коментарий
101                         $item->os          = isset($options[ 'os' ]) ? $options[ 'os' ] : NULL;           // Операционная система
102                         $item->mac         = isset($options[ 'mac' ]) ? $options[ 'mac' ] : NULL;         // MAC-адрес
103                         $item->serial      = isset($options[ 'serial' ]) ? $options[ 'serial' ] : NULL;   // Серийный номер
104                         $item->checked     = false;                                                       // Не инвентризирован (требует внимания после импорта)
105                         // Сохраняем запись
106                         if ($item->validate() && $item->save())
107                         {
108                             $result[ 'id' ] = $item->id; // Возвращаем идентификатор записанного оборудования
109                             $result[ 'error' ] = '';
110                         }
111                         else
112                         {
113                             $result[ 'error' ] .= Yii::t('items', 'Items: Failed to add entry: ') . print_r($item->errors, TRUE) . '<br />';
114                         }
115                     }
116                 }
117             }
118         }
119         return $result;
120     }
121
122     /**
123      * Формирование PDF файла для печати QR-кодов для наклеек
124      * @param integer|array|null id
125      * @return mixed
126      */
127     public function actionPrint()
128     {
129         if (! User::canPermission('takingInventory') ) {
130             return Yii::$app->response->redirect(['site/index']);
131         }
132         // Список предметов/оборудования, если есть
133         $id = Yii::$app->request->get('id');
134
135         $models = Items::find();
136         if (isset($id))
137             if (is_array($id))
138             {
139                 $models = $models->where([ 'in', 'id', $id ]); // Несколько предметов/оборудования
140             } else
141             {
142                 $models = $models->where([ 'id' => $id ]); // Один предмет/оборудование
143             }
144         $models = $models->all(); // Формирование списка
145
146         $pdf = Yii::$app->pdf; // Pабота с PDF
147
148         $pdf->methods[ 'SetHeader' ] = ''; // Yii::t('items', 'Items');
149         $pdf->methods[ 'SetFooter' ] = ''; // ['{PAGENO}'];
150         // Границы листа
151         $pdf->marginLeft   = 5;
152         $pdf->marginRight  = 5;
153         $pdf->marginTop    = 9;
154         $pdf->marginBottom = 15;
155         // Имя файла для выгрузки, по умолчанию document.pdf
156         $pdf->filename     = Yii::t('app', Yii::$app->name) . ' (' . Yii::t('items', 'Items') . ').pdf';
157
158         // Заполнение страницы данными
159         $pdf->content = $this->renderPartial('print', [ 'models' => $models ]);
160
161         // Выгрузка PDF
162         return $pdf->render();
163     }
164
165     /**
166      * Процедура начала инвентаризации.
167      * @return mixed
168      */
169     public function actionStart_checking()
170     {
171         // Проверка доступа для проведения инвентаризации
172         if (! User::canPermission('takingInventory') ) {
173             // Переход к списку предметов/оборудования, если доступ не разрешён.
174             return $this->redirect(['index']);
175         }
176         // Запрос на получение списка идентификаторов предметов/оборудования, которые списаны
177         $modelS = Moving::find()
178             ->select('item_id')
179             ->joinWith('status')
180             ->Where([ 'ilike', Status::tableName() . '.name', 'Списано' ]);
181
182         // Получаем список всех предметов/оборудования, кроме списанного
183         $model = Items::find()
184             ->select('id')
185             ->innerJoin([ 'm' => $modelS ], 'not m.item_id = id')
186             ->all();
187
188         // Устанавливаем флаг непроинвентаризированных для всех предметов/оборудования из полученного списка.
189         Items::updateAll([ 'checked' => false ], [ 'in', 'id', $model ]);
190
191         // Переход к списку предметов/оборудования.
192         return $this->redirect([ 'index' ]);
193     }
194
195     /**
196      * Инвентаризация
197      * @param string|null $qrcheck считанный QR-код
198      * @return mixed
199      */
200      public function actionCheck()
201      {
202         // Проверка доступа для проведения инвентаризации
203         if (! User::canPermission('takingInventory') ) {
204             // Показ стартовой страницы, если доступ не разрешён.
205             return $this->redirect(['site/index']);
206         }
207
208         $model = new Check();
209         $message = '';
210         if ($model->load(Yii::$app->request->post()))
211         {
212             if ((! empty($model->qrcheck)) && strpos($model->qrcheck, ',') !== false)
213             {
214                 $keys = explode(',', $model->qrcheck);
215                 $color=''; // Цветовая метка по умолчанию
216                 // Получаем все предметы/оборудование с совпадением инвентарного и серийного номеров
217                 $items = Items::find()->where([ 'invent' => trim($keys[ 0 ]), 'serial' => trim($keys[ 1 ]) ])->all();
218                 if (count($items) > 0 )
219                 {
220                     foreach ($items as $row)
221                     {
222                         if ($row->checked)
223                         {
224                             // Этот инвентарный номер был учтён
225                             $color = ' color="#FF0000"';
226                         }
227                         // Ищем местоположение
228                         $moving_id = Moving::find()->select('MAX(id) as id')->groupBy([ 'item_id' ])->where([ 'item_id' => $row->id ])->one()->id;
229                         $moving = Moving::find()->where([ 'id' => $moving_id ])->one();
230                         // Показываем название и местоположение
231                         $message .= $row->models->name . ' (' . $moving->locations->name  . ' [' . $moving->regions->name . '])';
232                     }
233                 }
234                 else
235                 {
236                     // Неизвестный инвентарный номер
237                     $color = ' color = "#FF8830"';
238                     $message .= Yii::t('items', 'Not found!') . ' ' . Yii::t('items', 'Inventory number') . ': ' . trim($keys[ 0 ]);
239                 }
240                 // Отмечаем проинвентаризированными все найденные предметы/оборудование
241                 Items::updateAll([ 'checked' => TRUE ], [ 'invent' => trim($keys[ 0 ]), 'serial' => trim($keys[ 1 ]) ]);
242
243                 if ($message != '')
244                     if ( $color == ' color = "#FF8830"')
245                     {
246                         $message = '<font' . $color . '>' . $message . '</font>';
247                     }
248                     else
249                     {
250                         $message = '<font' . $color . '>' . Yii::t('items', 'Checked item(s): ') . $message . '</font>';
251                     }
252                 $model->qrcheck = '';
253             }
254         }
255         $searchModel = new ItemsSearch();
256         //$dataProvider = $searchModel->noinvent($model);
257         $dataProvider = $searchModel->noinvent(Yii::$app->request->queryParams);
258
259         return $this->render('check', [
260             'message'      => $message,
261             'model'        => $model,
262             'searchModel'  => $searchModel,
263             'dataProvider' => $dataProvider,
264         ]);
265      }
266
267     /**
268      * Список всех предметов/оборудования.
269      * @return mixed
270      */
271     public function actionIndex()
272     {
273         if (! User::canPermission('createRecord') )
274         {
275             return $this->redirect(['site/index']);
276         }
277         if (isset($_GET[ 'pageSize' ]))
278         {
279             Yii::$app->session['pageSize'] = (int) $_GET[ 'pageSize' ];
280             unset($_GET[ 'pageSize' ]);
281         }
282         $searchModel = new ItemsSearch();
283         if (isset(Yii::$app->request->queryParams['id']))
284         {
285             $id = Yii::$app->request->queryParams['id'];
286             $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
287             //$dataProvider->query->select(Items::tableName() . '.id');
288             $pageSize = $dataProvider->pagination->pageSize;
289             $dataProvider->pagination = FALSE;
290             $rows = $dataProvider->getModels();
291             $page = 0;
292             foreach ($rows as $key => $val)
293             {
294                 if ($id == $val->id)
295                 {
296                     $page = ceil(($key + 1) / $pageSize);
297                     break;
298                 }
299             }
300             return $this->redirect(['index', 'page' => $page]);
301         }
302         $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
303
304         return $this->render('index', [
305             'searchModel' => $searchModel,
306             'dataProvider' => $dataProvider,
307         ]);
308     }
309
310     /**
311      * Импортирование строк товаров из массива
312      */
313     public function doImport($arrayRows)
314     {
315         // Инициализация счётчиков
316         $arrayReturn = [
317             'countRows'     => count($arrayRows),
318             'countImported' => 0,
319             'countExists'   => 0,
320             'countErrors'   => 0,
321             'errors'        => '',
322         ];
323
324         // Проверка наличия ключевых полей
325         if ((!isset($arrayRows[ 0 ][ 'model' ]))
326             || (!isset($arrayRows[ 0 ][ 'type' ]))
327             || (!isset($arrayRows[ 0 ][ 'invent' ]))
328             || (!isset($arrayRows[ 0 ][ 'location' ]))
329             || (!isset($arrayRows[ 0 ][ 'region' ]))
330             || (!isset($arrayRows[ 0 ][ 'date' ]))
331         )
332         {
333             // Сообщение об ошибке
334             $arrayReturn[ 'countErrors' ] = count($arrayRows);
335             $arrayReturn[ 'errors' ] .= '<br />' . Yii::t('import', 'Skip all. Key column(s) "model", "type", "invent", "location", "region", "date" not found: ') . print_r($arrayRows[0], TRUE);
336         }
337         else
338         {
339             // Просмотрим весь массив
340             foreach($arrayRows as $row)
341             {
342                 // ПОлучим местоположения
343                 $location = LocationsController::addIfNeed($row); // Получение идентификатора расположения
344                 if ( $location[ 'id' ] === FALSE)
345                 {
346                     // Сообщим об ошибке
347                     $arrayReturn[ 'countErrors' ]++;
348                     $arrayReturn[ 'errors' ] .= '<br />' . $location[ 'error' ];
349                 }
350                 else
351                 {
352                     // Попробуем найти или добавить предмет/оборудование
353                     $item = $this->addIfNeed($row);
354                     if ($item[ 'id' ] === FALSE)
355                     {
356                         $arrayReturn[ 'countErrors' ]++;
357                         $arrayReturn[ 'errors' ] .= '<br />' . $item[ 'error' ];
358                     }
359                     else
360                     {
361                         // Проверка, что предмет/оборудование уже были в базе
362                         $item = Items::find()->where([ 'id' => $item[ 'id' ]])->one();
363                         if ($item->checked === TRUE)
364                         {
365                             $arrayReturn[ 'countExists' ]++;
366                         }
367                         else
368                         {
369                             $state = isset($row[ 'status' ]) ? StatusController::addIfNeed($row) : StatusController::addIfNeed([ 'status' => 'Склад' ]);
370                             if ( $state[ 'id' ] === FALSE )
371                             {
372                                 // Сообщим об ошибке
373                                 $arrayReturn[ 'countErrors' ]++;
374                                 $arrayReturn[ 'errors' ] .= '<br />' . $state[ 'error' ];
375                             }
376                             else
377                             {
378                                 // Новый предмет/оборудование. Пробуем добавить первое перемещение
379                                 // Проверка что последнее перемещение такое же, как и импортируемое
380                                 $moving = Moving::find()->where([ 'item_id' => $item[ 'id' ]])->all();
381                                 $flag = false;
382                                 if (count($moving) > 0)
383                                 {
384                                     // Признак, что последнее перемещение совпало с импортируемым
385                                     $flag = $moving[ count($moving) - 1 ]->location_id == $location[ 'id' ];
386                                 }
387                                 // Проверим, что существующая запись перемещения больше добавляемой
388                                 $moving = Moving::find()->where([ 'item_id' => $item[ 'id' ]])->andWhere([ '>', 'date', $row[ 'date' ]])->all();
389                                 if ($flag || count($moving) > 0)
390                                 {
391                                     // Добавлять запись до существующих нельзя.
392                                     $arrayReturn[ 'countExists' ]++;
393                                 }
394                                 else
395                                 {
396                                     // Проверим, есть ли уже такое перемещение
397                                     $moving = Moving::find()->where([ 'item_id' => $item[ 'id' ], 'date' => $row[ 'date' ]])->orderBy([ 'id' => SORT_ASC ])->all();
398                                     if (count($moving) == 0)
399                                     {
400                                         // Такой транзакции нет ещё.
401                                         $moving = new Moving();
402                                         $moving->date        = $row[ 'date' ];
403                                         $moving->state_id    = $state[ 'id' ];
404                                         $moving->item_id     = $item[ 'id' ];
405                                         $moving->location_id = $location[ 'id' ];
406                                         $moving->comment     = Yii::t('import', 'Import: {comment}', $row);
407
408                                         if ($moving->validate() && $moving->save())
409                                         {
410                                             // Записаали первое движение
411                                             $arrayReturn[ 'countImported' ]++;
412                                         }
413                                         else
414                                         {
415                                             // Запись не удалась, пробуем удалить предмет/оборудование
416                                             Items::find()->where([ 'id' => $item[ 'id' ], 'checked' => FALSE ])->one()->delete();
417                                             // Сообщим об ошибке
418                                             $arrayReturn[ 'countErrors' ]++;
419                                             $arrayReturn[ 'errors' ] .= '<br />' . Yii::t('import', 'Moving: {date} (') . $moving->errors['date'][0]. Yii::t('import', '), Inventory number:{invent}, model: {model}, location: {location} ( {region} )' , $row);
420                                         }
421                                     }
422                                     else
423                                     {
424                                         // Такое перемещение уже было
425                                         $arrayReturn[ 'countExists' ]++;
426                                         // Удаление дубликатов, если вдруг они образовались
427                                         if (count($moving) > 1)
428                                         {
429                                             // переберём все записи со второй  и удалим их.
430                                             for ($i = 1; $i < count($moving); $i++)
431                                             {
432                                                 $moving[$i]->delete();
433                                             }
434                                         }
435                                     }
436                                 }
437                                 unset($moving);
438                             }
439                         }
440                     }
441                 }
442             }
443         }
444
445         // Возврат результата импорта
446         return $arrayReturn;
447     }
448
449     /**
450      * Импорт данных из файла csv
451      * Структура файла данных при выгрузке из 1С: (Колонки могут меняться.
452      * | № п/п |  | Предмет/оборудование |  |  |  |  |  |  | Инвентарный номер | Материально отвественное лицо |  |  | Место размещения | Регион/подразделение | Количество |
453      * Так как 1С из коробки не умеет выгружать форму в .csv, то приходится сначала выгрузить в .xls(x), и уже из MS Excel/Lible office Calc сохранять в .csv
454      */
455     public function actionImport()
456     {
457         if (! User::canPermission('updateRecord') ) {
458             return $this->redirect(['site/index']);
459         }
460         $model   = new Import();
461         $message = '';
462         $searchModel = new ItemsSearch();
463         $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
464         if (Yii::$app->request->isPost)
465         {
466             $rows = [];
467             $columns = [];
468             $columnsNames = [
469                 'npp'         => Yii::t('import', 'No. in order'),
470                 'model'       => Yii::t('import', 'Primary means'),
471                 'netname'     => Yii::t('import', 'Network name'),
472                 'invent'      => Yii::t('import', 'Inventory number'),
473                 'comment'     => Yii::t('import', 'Financially responsible person'),
474                 'os'          => Yii::t('import', 'Operation system'),
475                 'mac'         => Yii::t('import', 'MAC address'),
476                 'serial'      => Yii::t('import', 'Serial number'),
477                 'product'     => Yii::t('import', 'Product number'),
478                 'modelnumber' => Yii::t('import', 'Model number'),
479                 'date'        => Yii::t('import', 'Date of acceptance for registration'),
480                 'location'    => Yii::t('import', 'Location'),
481                 'region'      => Yii::t('import', 'Region'),
482                 'type'        => Yii::t('import', 'Type'),
483                 'status'      => Yii::t('import', 'State'),
484             ];
485             $model->filecsv = UploadedFile::getInstance($model, 'filecsv');
486             if ($model->upload())
487             {
488                 $fileName = 'upload/' . $model->filecsv->baseName . '.' . $model->filecsv->extension;
489                 $handle = fopen($fileName, 'r');
490                 if ($handle !== FALSE)
491                 {
492                     if (strcasecmp($model->filecsv->extension, 'csv') === 0 )
493                     {
494                         // Построчное чтение CSV файла
495                         while (($row = fgetcsv($handle, 2048, ';')) !== false )
496                         {
497                             // Пока не собраны индексы столбцов из шапки
498                             if (count($columns) == 0)
499                             {
500                                 // Ищем строку с заголовком таблицы
501                                 if ( stripos($row[0], $columnsNames[ 'npp' ]) !== FALSE )
502                                 {
503                                     // Перебираем все колонки
504                                     foreach ($row as $key => $item)
505                                     {
506                                         // Перебираем все названия заголовков колонок
507                                         foreach($columnsNames as $name => $text)
508                                         {
509                                             // Если название совпало,
510                                             if (stripos($item, $text) !== FALSE)
511                                             {
512                                                 // Сохраняем индек колонки
513                                                 $columns[ $name ] = $key;
514                                             }
515                                         }
516                                     }
517                                 }
518                             }
519                             else
520                             {
521                                 // Перебираем предметы/оборудование (Номер по порядку должен быть целым числом)
522                                 if (ctype_digit(str_replace(' ', '', $row[ $columns[ 'npp' ]])))
523                                 {
524                                     // Заполняем очередную строку для таблицы
525                                     $line = [];
526                                     foreach ($columns as $key => $index)
527                                     {
528                                         $line[ $key ] = trim(str_replace("\t", ' ', $row[ $index ])); // Заменяем табуляторы на пробелы и удаляем ведущие и ведомые пробелы.
529                                     }
530                                     // Обработка даты
531                                     if (isset($line[ 'date' ]))
532                                     {
533                                         if ($line[ 'date' ] == '#NULL!') $line[ 'date' ] = date('d.m.Y');
534                                     }
535                                     else
536                                     {
537                                         $line[ 'date' ] = date('d.m.Y');
538                                     }
539                                     array_push($rows, $line);
540                                 }
541                             }
542                         } // Перебор строк файла
543                     }
544                     else // xls(x) файлы
545                     {
546                         $inputFileType = \PHPExcel_IOFactory::identify($fileName); // Получение типа данных в файле
547                         $excelReader = \PHPExcel_IOFactory::createReader($inputFileType); // Создание потока чтения из файла
548                         $excelObj = $excelReader->load($fileName); // Открытие файла
549                         $worksheet = $excelObj->getSheet(0);       // Работаем только с первым листом (обычно туда выгружает 1С)
550                         // Индексы ячеек
551
552                         // Цикл по всем строкам
553                         foreach ($worksheet->getRowIterator() as $row)
554                         {
555                             $cellIterator = $row->getCellIterator(); // Получаем итератор ячеек в строке
556                             $cellIterator->setIterateOnlyExistingCells(FALSE); // Указываем проверять даже не установленные ячейки
557
558                             if (count($columns) == 0) // Пока не найдена шапка, проверяем строку
559                             {
560                                 $flag = FALSE;
561                                 foreach ($cellIterator as $key => $item)
562                                 {
563                                     if (($key == 'A') && (stripos($item->getCalculatedValue(), $columnsNames[ 'npp' ]) !== FALSE)) $flag = TRUE;
564                                     if ($flag)
565                                     {
566                                         foreach ($columnsNames as $name => $text)
567                                         {
568                                             if (stripos($item->getCalculatedValue(), $text) !== FALSE)
569                                             {
570                                                 $columns[ $name ] = $key;
571                                             }
572                                         }
573                                     }
574                                 }
575                             }
576                             else
577                             {
578                                 $flag = FALSE;
579                                 $line = [];
580                                 foreach ($cellIterator as $key => $item)
581                                 {
582                                     if ($key == $columns[ 'npp' ])
583                                     {
584                                         $npp = str_replace(' ', '', $item->getCalculatedValue());
585                                         if (ctype_digit($npp)) $flag = TRUE;
586                                     }
587                                     if ($flag)
588                                     {
589                                         foreach($columns as $keym => $index)
590                                         {
591                                             if ($index == $key) $line[ $keym ] = trim(str_replace("\t", ' ', $item->getCalculatedValue()));
592                                         }
593                                     }
594                                 }
595                                 if ($flag)
596                                 {
597                                     if (isset($line[ 'date' ]))
598                                     {
599                                         if ($line[ 'date' ] == '#NULL!') $line[ 'date' ] = date('d.m.Y');
600                                     }
601                                     else
602                                     {
603                                         $line[ 'date' ] = date('d.m.Y');
604                                     }
605                                     array_push($rows, $line);
606                                 }
607                             }
608                         }
609                     }
610                     fclose($handle);
611                     $res = $this->doImport($rows);
612                 }
613                 $message .= Yii::t('items', 'Read {countRows} records.<br />Imported {countImported} Items.<br />Exists {countExists} Items.<br />Error read {countErrors} records.<br />{errors}', $res);
614             }
615         }
616         return $this->render('import',[
617             'message' => $message,
618             'model' => $model,
619             'searchModel' => $searchModel,
620             'dataProvider' => $dataProvider,
621         ]);
622     }
623
624     /**
625      * Показ одного предмета/оборудования. (не используется)
626      * @param integer $id
627      * @return mixed
628      * @throws NotFoundHttpException если предмет/оборудование отсутствует
629      */
630     public function actionView($id)
631     {
632         if (! User::canPermission('updateRecord') ) {
633             return $this->redirect([ 'index', 'id' => $id ]);
634         }
635         return $this->render('view', [
636             'model' => $this->findModel($id),
637         ]);
638     }
639
640     /**
641      * Создание нового предмета/оборудования.
642      * @return mixed
643      */
644     public function actionCreate()
645     {
646         if (! User::canPermission('createRecord') ) {
647             return $this->redirect(['site/index']);
648         }
649         $model = new Items(); // Новый предмет/оборудование
650         $model->checked = true;
651         $modelm = new Moving();
652         if ($model->load(Yii::$app->request->post()) && $model->save())
653         {
654             // Удалось сохранить, создаём первую запись движения
655             if ($modelm->load(Yii::$app->request->post()))
656             {
657                 $modelm->item_id = $model->id;
658                 $modelm->comment = 'Поступление';
659
660                 if ( $modelm->save() ) // Пробуем сохранить движение
661                 {
662                     return $this->redirect([ 'index', 'id' => $model->id ]); // Если удалось, показываем список оборудования
663                 } else
664                 {
665                     $this->findModel($model->id)->delete();  // Иначе удаляем созданную запись предмета/оборудования
666                     unset($model->id);                       // Очищаем идентификатор предмета/оборудования
667                     $model->isNewRecord = true;
668                     return $this->render('create', [         // Показываем форму создания нового предмета/оборудования
669                         'model'  => $model,
670                         'modelm' => $modelm,
671                     ]);
672                 }
673             } else
674             {
675                 $this->findModel($model->id)->delete();  // Иначе удаляем созданную запись предмета/оборудования
676                 unset($model->id);                      // Очищаем идентификатор предмета/оборудования
677                 $model->isNewRecord = true;
678                 return $this->render('create', [        // Показываем форму создания нового предмета/оборудования
679                     'model'  => $model,
680                     'modelm' => $modelm,
681                 ]);
682             }
683         } else // не удалось сохранить - отображаем форму создания нового предмета/оборудования
684         {
685             return $this->render('create', [
686                 'model'  => $model,
687                 'modelm' => $modelm,
688             ]);
689         }
690
691     }
692
693     /**
694      * Изменение существующего предмета/оборудвания.
695      * Если премет/обрудование сохранён, то возвращаемся на страницу списка всех предметов/оборудования.
696      * @param integer $id
697      * @return mixed
698      * @throws NotFoundHttpException если предмет/оборудование отсутствует
699      */
700     public function actionUpdate($id)
701     {
702         if (! User::canPermission('updateRecord') ) {
703             return $this->redirect(['index']);
704         }
705         $model = $this->findModel($id);
706
707         if ($model->load(Yii::$app->request->post()) && $model->save())
708         {
709             return $this->redirect([ 'index', 'id' => $model->id ]);
710         }
711
712         $searchModelM = new MovingSearch([ 'item_id' => $model->id ]);
713         $dataProviderM = $searchModelM->search(Yii::$app->request->queryParams);
714
715          return $this->render('update', [
716             'searchModelM'  => $searchModelM,
717             'dataProviderM' => $dataProviderM,
718             'model'         => $model,
719         ]);
720     }
721
722     /**
723      * Удаляет сушествующий предмет/оборудование.
724      * Если премет/обрудование удалён, то возвращаемся на страницу списка всех предметов/оборудования.
725      * @param integer $id
726      * @return mixed
727      * @throws NotFoundHttpException if the model cannot be found
728      */
729     public function actionDelete($id)
730     {
731         if (! User::canPermission('updateRecord') ) {
732             return $this->redirect(['site/index']);
733         }
734         $this->findModel($id)->delete();
735
736         return $this->redirect([ 'index' ]);
737     }
738
739     /**
740      * Finds the Items model based on its primary key value.
741      * If the model is not found, a 404 HTTP exception will be thrown.
742      * @param integer $id
743      * @return Items the loaded model
744      * @throws NotFoundHttpException если предмет/оборудование отсутствует
745      */
746     protected function findModel($id)
747     {
748         if (($model = Items::findOne($id)) !== null)
749         {
750             return $model;
751         }
752
753         throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
754     }
755 }