3 namespace app\controllers;
10 use app\models\Locations;
11 use app\models\ItemsSearch;
12 use app\models\MovingSearch;
13 use app\models\Status;
15 use yii\web\Controller;
16 use yii\web\NotFoundHttpException;
17 use yii\web\UploadedFile;
18 use yii\filters\VerbFilter;
23 * ItemsController implements the CRUD actions for Items model.
25 class ItemsController extends Controller
30 public function behaviors()
34 'class' => VerbFilter::className(),
36 'delete' => [ 'POST' ],
43 * Добавление предмета/оборудование если его нет
44 * @param array $options
48 * integer|NULL 'type_id'
49 * string|NULL 'typeName'
53 * string|NULL 'serial'
54 * string|NULL 'product'
55 * string|NULL 'modelnum'
56 * @return integer|FALSE
58 public static function addIfNeed($options)
60 if (is_array($options) && isset($options[ 'invent' ]))
63 ->where([ 'like', 'invent', $options[ 'invent' ]]);
64 if (isset($options[ 'serial' ])) {
65 $item = $item->andWhere([ 'like', 'serial', $options[ 'serial' ]]);
73 if (isset($options[ 'model' ]))
75 if (isset($options[ 'typeName' ]))
77 $type_id = TypesController::addIfNeed($options[ 'typeName' ]);
78 if($type_id === FALSE)
85 $type_id = isset($options[ 'type_id' ]) ? $options[ 'type_id' ] : NULL;
88 $item->name = isset($options[ 'name' ]) ? $options[ 'name' ] : NULL;
89 $item->model = isset($options[ 'model' ]) ? $options[ 'model' ] : NULL;
90 $item->invent = isset($options[ 'invent' ]) ? $options[ 'invent' ] : NULL;
91 $item->comment = isset($options[ 'comment' ]) ? $options[ 'comment' ] : NULL;
92 $item->type_id = $type_id;
93 $item->os = isset($options[ 'os' ]) ? $options[ 'os' ] : NULL;
94 $item->mac = isset($options[ 'mac' ]) ? $options[ 'mac' ] : NULL;
95 $item->serial = isset($options[ 'serial' ]) ? $options[ 'serial' ] : NULL;
96 $item->product = isset($options[ 'product' ]) ? $options[ 'product' ] : NULL;
97 $item->modelnumber = isset($options[ 'modelnumber' ]) ? $options[ 'modelnumber' ] : NULL;
98 $item->checked = false;
100 if ($item->validate() && $item->save())
110 * Формирование PDF файла для печати QR-кодов для наклеек
111 * @param integer|array|null id
114 public function actionPrint()
116 if (! User::canPermission('takingInventory') ) {
117 return $this->redirect(['site/index']);
119 // Список предметов/оборудования, если есть
120 $id = Yii::$app->request->get('id');
122 $models = Items::find();
126 $models = $models->where([ 'in', 'id', $id ]); // Несколько предметов/оборудования
129 $models = $models->where([ 'id' => $id ]); // Один предмет/оборудование
131 $models = $models->all(); // Формирование списка
133 $pdf = Yii::$app->pdf; // Pабота с PDF
135 $pdf->methods[ 'SetHeader' ] = ''; // Yii::t('items', 'Items');
136 $pdf->methods[ 'SetFooter' ] = ''; // ['{PAGENO}'];
138 $pdf->marginLeft = 5;
139 $pdf->marginRight = 5;
141 $pdf->marginBottom = 15;
142 // Имя файла для выгрузки, по умолчанию document.pdf
143 $pdf->filename = Yii::t('app', Yii::$app->name) . ' (' . Yii::t('items', 'Items') . ').pdf';
145 // Заполнение страницы данными
146 $pdf->content = $this->renderPartial('print', [ 'models' => $models ]);
149 return $pdf->render();
153 * Процедура начала инвентаризации.
156 public function actionStart_checking()
158 if (! User::canPermission('takingInventory') ) {
159 return $this->redirect(['site/index']);
161 // Запрос на получение списка идентификаторов предметов/оборудования, которые списаны
162 $modelS = Moving::find()
165 ->Where([ 'ilike', Status::tableName() . '.name', 'Списано' ]);
167 // Получаем список всех предметов/оборудования, кроме списанного
168 $model = Items::find()
170 ->innerJoin([ 'm' => $modelS ], 'not m.item_id = id')
173 // Устанавливаем флаг непроинвентаризированных для всех предметов/оборудования из полученного списка.
174 Items::updateAll([ 'checked' => false ], [ 'in', 'id', $model ]);
176 // Переход к списку предметов/оборудования.
177 return $this->redirect([ 'index' ]);
182 * @param string|null $qrcheck считанный QR-код
185 public function actionCheck()
188 if (! User::canPermission('takingInventory') ) {
189 return $this->redirect(['site/index']);
191 $model = new Check();
193 if ($model->load(Yii::$app->request->post()))
195 if ((! empty($model->qrcheck)) && strpos($model->qrcheck, ',') !== false)
197 $keys = explode(',', $model->qrcheck);
198 Items::updateAll([ 'checked' => true ], [ 'invent' => trim($keys[ 0 ]), 'serial' => trim($keys[ 1 ]) ]);
199 $items = Items::find()->where([ 'invent' => trim($keys[ 0 ]), 'serial' => trim($keys[ 1 ]) ])->all();
200 //$message = '[0] = "' . $keys[0] . '", [1] = "' . $keys[1] . '"<br />';
201 foreach ($items as $row)
203 $message .= $row->model . ' (' . $row->id . ')';
206 $message = Yii::t('items', 'Checked item(s): ') . $message;
207 $model->qrcheck = '';
210 $searchModel = new ItemsSearch();
211 $dataProvider = $searchModel->noinvent($model);
213 return $this->render('check', [
214 'message' => $message,
216 'searchModel' => $searchModel,
217 'dataProvider' => $dataProvider,
222 * Список всех предметов/оборудования.
225 public function actionIndex()
227 if (! User::canPermission('createRecord') ) {
228 return $this->redirect(['site/index']);
230 $searchModel = new ItemsSearch();
231 $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
233 return $this->render('index', [
234 'searchModel' => $searchModel,
235 'dataProvider' => $dataProvider,
240 * Импорт данных из файла csv
241 * Структура файла данных при выгрузке из 1С:
242 * | № п/п | | Предмет/оборудование | | | | | | | Инвентарный номер | Материально отвественное лицо | | | Место размещения | Регион/подразделение | Количество |
243 * | 0 | 1| 2 | 3| 4| 5| 6| 7| 8| 9 |10 |11|12|13 |14 |15 |
244 * Так как 1С из коробки не умеет выгружать форму в .csv, то приходится сначала выгрузить в .xls(x), и уже из MS Excel/Lible office Calc сохранять в .csv
246 public function actionImport()
248 if (! User::canPermission('updateRecord') ) {
249 return $this->redirect(['site/index']);
251 $model = new Import();
258 $searchModel = new ItemsSearch();
259 $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
260 if (Yii::$app->request->isPost)
262 $model->filecsv = UploadedFile::getInstance($model, 'filecsv');
263 if ($model->upload())
265 $handle = fopen('upload/' . $model->filecsv->baseName . '.' . $model->filecsv->extension, 'r');
266 if ($handle !== FALSE)
268 while (($row = fgetcsv($handle, 1024, ';')) !== false )
270 if (intval($row[ 0 ]) . '' == $row[ 0 ])
272 $location = $row[ 13 ];
273 $region = $row[ 14 ];
275 $location_id = LocationsController::addIfNeed([ 'name' => $location, 'region' => $region ]);
276 if ($location_id !== FALSE)
279 if (count(Items::find()->where([ 'like', 'invent', $invent ])->all()) == 0)
282 $comment = Yii::t('moving', 'Imported. {comment}', [ 'comment' => $row[ 10 ] ]);
283 $item_id = $this::addIfNeed([ 'invent' => $invent, 'model' => $model_, 'comment' => $comment ]);
284 if ( $item_id !== FALSE)
286 $date = date('d.m.Y');
287 $state_id = StatusController::addIfNeed([ 'name' => 'Склад' ]);
288 if ($state_id === FALSE)
291 } // Состояние предмета/оборудование
293 $moving = new Moving();
294 $moving->date = $date;
295 $moving->item_id = $item_id;
296 $moving->state_id = $state_id;
297 $moving->location_id = $location_id;
298 $moving->comment = $comment;
299 if ($moving->validate() && $moving->save())
302 } // Добавление перемещение
305 Items::find([ 'id' => $item_id ])->delete();
307 $errors .= '<br>Движение: ' . implode(';', $row);
308 } // Не удалось добавить перемещение
310 } // Предмет/оборудование добавлено
314 } // Предмет/оборудование уже есть
319 $errors .= '<br>Место расположения: ' . implode(';', $row);
320 } // не удалось найти или добавить место размещения
321 } // Строка с данными
322 } // Перебор строк файла
325 $message .= Yii::t('items', 'Read {count} records.<br />Imported {counti} Items.<br />Exists {exist} Items.<br />Error read {skip} records.<br />{errors}',
326 [ 'counti' => $counti, 'count' => $count, 'exist' => $existi, 'skip' => $skip, 'errors' => $errors ]);
329 return $this->render('import',[
330 'message' => $message,
332 'searchModel' => $searchModel,
333 'dataProvider' => $dataProvider,
338 * Показ одного предмета/оборудования. (не используется)
341 * @throws NotFoundHttpException если предмет/оборудование отсутствует
343 public function actionView($id)
345 if (! User::canPermission('updateRecord') ) {
346 return $this->redirect(['index']);
348 return $this->render('view', [
349 'model' => $this->findModel($id),
354 * Создание нового предмета/оборудования.
357 public function actionCreate()
359 if (! User::canPermission('createRecord') ) {
360 return $this->redirect(['site/index']);
362 $model = new Items(); // Новый предмет/оборудование
363 $model->checked = true;
364 $modelm = new Moving();
365 if ($model->load(Yii::$app->request->post()) && $model->save())
367 // Удалось сохранить, создаём первую запись движения
368 if ($modelm->load(Yii::$app->request->post()))
370 $modelm->item_id = $model->id;
371 $modelm->comment = 'Поступление';
373 if ( $modelm->save() ) // Пробуем сохранить движение
375 return $this->redirect([ 'index', 'id' => $model->id ]); // Если удалось, показываем список оборудования
378 $this->findModel($model->id)->delete(); // Иначе удаляем созданную запись предмета/оборудования
379 unset($model->id); // Очищаем идентификатор предмета/оборудования
380 $model->isNewRecord = true;
381 return $this->render('create', [ // Показываем форму создания нового предмета/оборудования
388 $this->findModel($model->id)->delete(); // Иначе удаляем созданную запись предмета/оборудования
389 unset($model->id); // Очищаем идентификатор предмета/оборудования
390 $model->isNewRecord = true;
391 return $this->render('create', [ // Показываем форму создания нового предмета/оборудования
396 } else // не удалось сохранить - отображаем форму создания нового предмета/оборудования
398 return $this->render('create', [
407 * Изменение существующего предмета/оборудвания.
408 * Если премет/обрудование сохранён, то возвращаемся на страницу списка всех предметов/оборудования.
411 * @throws NotFoundHttpException если предмет/оборудование отсутствует
413 public function actionUpdate($id)
415 if (! User::canPermission('updateRecord') ) {
416 return $this->redirect(['index']);
418 $model = $this->findModel($id);
420 if ($model->load(Yii::$app->request->post()) && $model->save())
422 return $this->redirect([ 'index', 'id' => $model->id ]);
425 $searchModelM = new MovingSearch([ 'item_id' => $model->id ]);
426 $dataProviderM = $searchModelM->search(Yii::$app->request->queryParams);
428 return $this->render('update', [
429 'searchModelM' => $searchModelM,
430 'dataProviderM' => $dataProviderM,
436 * Удаляет сушествующий предмет/оборудование.
437 * Если премет/обрудование удалён, то возвращаемся на страницу списка всех предметов/оборудования.
440 * @throws NotFoundHttpException if the model cannot be found
442 public function actionDelete($id)
444 if (! User::canPermission('updateRecord') ) {
445 return $this->redirect(['site/index']);
447 $this->findModel($id)->delete();
449 return $this->redirect([ 'index' ]);
453 * Finds the Items model based on its primary key value.
454 * If the model is not found, a 404 HTTP exception will be thrown.
456 * @return Items the loaded model
457 * @throws NotFoundHttpException если предмет/оборудование отсутствует
459 protected function findModel($id)
461 if (($model = Items::findOne($id)) !== null)
466 throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));