OSDN Git Service

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