From: fomichev Date: Thu, 16 Jan 2025 20:20:56 +0000 (+0300) Subject: Создание справочника X-Git-Tag: 1.7~68^2 X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=2e41b153234fa22dff4132ff8565188f635442b4;p=erp24_rep%2Fyii-erp24%2F.git Создание справочника --- diff --git a/erp24/controllers/StoreCityListController.php b/erp24/controllers/StoreCityListController.php new file mode 100644 index 00000000..eb9860b9 --- /dev/null +++ b/erp24/controllers/StoreCityListController.php @@ -0,0 +1,229 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ] + ); + } + + /** + * Lists all StoreCityList models. + * + * @return string + */ + public function actionIndex() + { + $searchModel = new StoreCityListSearch(); + $dataProvider = $searchModel->search($this->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + public function actionImport() + { + if (Yii::$app->request->isPost) { + $file = UploadedFile::getInstanceByName('importFile'); + + if ($file) { + $filePath = Yii::getAlias('@runtime/') . $file->name; + + if ($file->saveAs($filePath)) { + try { + $this->processImportFile($filePath); + Yii::$app->session->setFlash('success', 'Данные успешно загружены.'); + } catch (\Exception $e) { + Yii::$app->session->setFlash('error', 'Ошибка при обработке файла: ' . $e->getMessage()); + } + } else { + Yii::$app->session->setFlash('error', 'Не удалось загрузить файл.'); + } + } else { + Yii::$app->session->setFlash('error', 'Файл не выбран.'); + } + } + + return $this->redirect(['index']); + } + + + protected function processImportFile($filePath) + { + $data = []; + + if (pathinfo($filePath, PATHINFO_EXTENSION) === 'csv') { + + if (($handle = fopen($filePath, 'r')) !== false) { + $header = fgetcsv($handle); + while (($row = fgetcsv($handle)) !== false) { + $data[] = array_combine($header, $row); + } + fclose($handle); + } + } else { + $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($filePath); + $sheet = $spreadsheet->getActiveSheet(); + $data = $sheet->toArray(null, true, true, true); + } + + foreach ($data as $row) { + $model = new StoreCityList(); + $model->name = $row['name'] ?? $row['A']; + $model->parent_id = $row['parent_id'] ?? $row['B']; + $model->type = $row['type'] ?? $row['C']; + + if (!$model->save()) { + Yii::error("Ошибка при сохранении: " . json_encode($model->errors)); + } + } + } + + public function actionParentOptions($q = null, $type = null) + { + $query = StoreCityList::find() + ->select(['id', 'name']) + ->andFilterWhere(['like', 'name', $q]); + + if ($type === 'region') { + $query->andWhere(['type' => 'region']); + } elseif ($type === 'city') { + $query->andWhere(['type' => 'city']); + } + + $result = $query->asArray()->all(); + + return $this->asJson([ + 'results' => array_map(function ($item) { + return ['id' => $item['id'], 'text' => $item['name']]; + }, $result), + ]); + } + + /** + * Displays a single StoreCityList model. + * @param int $id Первичный ключ + * @return string + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new StoreCityList model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return string|\yii\web\Response + */ + public function actionCreate() + { + $model = new StoreCityList(); + + if ($this->request->isPost) { + if ($model->load($this->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + } else { + $model->loadDefaultValues(); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing StoreCityList model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param int $id Первичный ключ + * @return string|\yii\web\Response + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + $parentData = []; + if ($model->parent_id) { + $parent = StoreCityList::find() + ->select(['id', 'name']) + ->where(['id' => $model->parent_id]) + ->asArray() + ->one(); + if ($parent) { + $parentData = [$parent['id'] => $parent['name']]; + } + } + + if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->render('update', [ + 'model' => $model, + 'parentData' => $parentData, + ]); + } + + /** + * Deletes an existing StoreCityList model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param int $id Первичный ключ + * @return \yii\web\Response + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $this->findModel($id)->delete(); + + return $this->redirect(['index']); + } + + /** + * Finds the StoreCityList model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param int $id Первичный ключ + * @return StoreCityList the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = StoreCityList::findOne(['id' => $id])) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } +} diff --git a/erp24/migrations/m250116_112743_create_store_city_list_table.php b/erp24/migrations/m250116_112743_create_store_city_list_table.php index bb29d302..e57dc5dc 100644 --- a/erp24/migrations/m250116_112743_create_store_city_list_table.php +++ b/erp24/migrations/m250116_112743_create_store_city_list_table.php @@ -8,9 +8,7 @@ use yii\db\Migration; class m250116_112743_create_store_city_list_table extends Migration { const TABLE_NAME = 'erp24.store_city_list'; - /** - * {@inheritdoc} - */ + public function safeUp() { $tableSchema = $this->db->getTableSchema(self::TABLE_NAME); @@ -27,6 +25,14 @@ class m250116_112743_create_store_city_list_table extends Migration ->comment('Дата создания записи'), ]); + // Создаём индекс для внешнего ключа + $this->createIndex( + 'idx-store_city_list-parent_id', + self::TABLE_NAME, + 'parent_id' + ); + + // Добавляем внешний ключ $this->addForeignKey( 'fk-store_city_list-parent_id', self::TABLE_NAME, @@ -39,14 +45,13 @@ class m250116_112743_create_store_city_list_table extends Migration } } - /** - * {@inheritdoc} - */ public function safeDown() { $tableSchema = $this->db->getTableSchema(self::TABLE_NAME); if (isset($tableSchema)) { $this->dropForeignKey('fk-store_city_list-parent_id', self::TABLE_NAME); + $this->dropIndex('idx-store_city_list-parent_id', self::TABLE_NAME); + $this->dropTable(self::TABLE_NAME); } } diff --git a/erp24/records/StoreCityList.php b/erp24/records/StoreCityList.php new file mode 100644 index 00000000..9c8c0bfd --- /dev/null +++ b/erp24/records/StoreCityList.php @@ -0,0 +1,90 @@ + null], + [['parent_id'], 'integer'], + [['name', 'type'], 'required'], + [['created_at', 'parent_id'], 'safe'], + [['name', 'type'], 'string', 'max' => 255], + [['type'], 'in', 'range' => [self::TYPE_REGION, self::TYPE_CITY, self::TYPE_DISTRICT]], + [['parent_id'], 'exist', 'skipOnError' => true, 'targetClass' => StoreCityList::class, 'targetAttribute' => ['parent_id' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'Первичный ключ', + 'parent_id' => 'Идентификатор родителя', + 'name' => 'Название (регион, город, район)', + 'type' => 'Тип (region, city, district)', + 'created_at' => 'Дата создания записи', + ]; + } + + /** + * Gets query for [[Parent]]. + * + * @return \yii\db\ActiveQuery + */ + public function getParent() + { + return $this->hasOne(StoreCityList::class, ['id' => 'parent_id']); + } + + /** + * Gets query for [[StoreCityLists]]. + * + * @return \yii\db\ActiveQuery + */ + public function getStoreCityLists() + { + return $this->hasMany(StoreCityList::class, ['parent_id' => 'id']); + } + + public static function getTypes() + { + return [ + self::TYPE_REGION => 'Region', + self::TYPE_CITY => 'City', + self::TYPE_DISTRICT => 'District', + ]; + } +} diff --git a/erp24/records/StoreCityListSearch.php b/erp24/records/StoreCityListSearch.php new file mode 100644 index 00000000..03e3d1fb --- /dev/null +++ b/erp24/records/StoreCityListSearch.php @@ -0,0 +1,71 @@ + $query, + ]); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + // grid filtering conditions + $query->andFilterWhere([ + 'id' => $this->id, + 'parent_id' => $this->parent_id, + 'created_at' => $this->created_at, + ]); + + $query->andFilterWhere(['ilike', 'name', $this->name]) + ->andFilterWhere(['ilike', 'type', $this->type]); + + return $dataProvider; + } +} diff --git a/erp24/views/store-city-list/_form.php b/erp24/views/store-city-list/_form.php new file mode 100644 index 00000000..d559a4ea --- /dev/null +++ b/erp24/views/store-city-list/_form.php @@ -0,0 +1,56 @@ +registerJsFile('/js/store_city_list/_form.js', ['position' => \yii\web\View::POS_END]); +?> + +
+ + + + field($model, 'type')->dropDownList([ + 'region' => 'Регион', + 'city' => 'Город', + 'district' => 'Район', + ], [ + 'prompt' => 'Выберите тип', + 'id' => 'type-selector', + ]) ?> + + + + field($model, 'name')->textInput(['maxlength' => true]) ?> + +
+ 'btn btn-success']) ?> +
+ + + +
diff --git a/erp24/views/store-city-list/_search.php b/erp24/views/store-city-list/_search.php new file mode 100644 index 00000000..7de0dfa7 --- /dev/null +++ b/erp24/views/store-city-list/_search.php @@ -0,0 +1,35 @@ + + + diff --git a/erp24/views/store-city-list/create.php b/erp24/views/store-city-list/create.php new file mode 100644 index 00000000..323f6d82 --- /dev/null +++ b/erp24/views/store-city-list/create.php @@ -0,0 +1,21 @@ +title = 'Создание элемента адреса (регион, город, район)'; +$this->params['breadcrumbs'][] = ['label' => 'Store City Lists', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ 'btn btn-primary my-4']) ?> +

title) ?>

+ + render('_form', [ + 'model' => $model, + 'parentData' => null, + ]) ?> + +
diff --git a/erp24/views/store-city-list/index.php b/erp24/views/store-city-list/index.php new file mode 100644 index 00000000..6f9e529d --- /dev/null +++ b/erp24/views/store-city-list/index.php @@ -0,0 +1,75 @@ +title = 'Справочник адресов (регион, город, район)'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +
+

title) ?>

+ +
+

+ Загрузка из excel регионов в справочник +

+ 'multipart/form-data', 'class' => 'row row-cols-lg-auto g-3 align-items-center']) ?> + +
+ 'form-control']) ?> +
+ +
+ 'btn btn-primary']) ?> +
+ + +
+ +
+ +

+ 'btn btn-success']) ?> +

+ + + + render('_search', ['model' => $searchModel]); ?> + + $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], + + 'id', + [ + 'attribute' => 'parent_id', + 'value' => function ($model) { + return $model->parent ? $model->parent->name : ''; + }, + 'label' => 'Родитель', + ], + 'name', + 'type', + 'created_at', + [ + 'class' => ActionColumn::class, + 'urlCreator' => function ($action, StoreCityList $model, $key, $index, $column) { + return Url::toRoute([$action, 'id' => $model->id]); + } + ], + ], + ]); ?> + + +
diff --git a/erp24/views/store-city-list/update.php b/erp24/views/store-city-list/update.php new file mode 100644 index 00000000..dfd1b0f9 --- /dev/null +++ b/erp24/views/store-city-list/update.php @@ -0,0 +1,23 @@ +title = 'Редактирование элемента адреса (регион, город, район): ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => 'Store City Lists', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = 'Update'; +?> +
+ 'btn btn-primary my-4']) ?> +

title) ?>

+ + render('_form', [ + 'model' => $model, + 'parentData' => $parentData, + ]) ?> + +
diff --git a/erp24/views/store-city-list/view.php b/erp24/views/store-city-list/view.php new file mode 100644 index 00000000..d1bf064d --- /dev/null +++ b/erp24/views/store-city-list/view.php @@ -0,0 +1,40 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => 'Store City Lists', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +?> +
+ 'btn btn-primary my-4']) ?> +

title) ?>

+ +

+ $model->id], ['class' => 'btn btn-primary']) ?> + $model->id], [ + 'class' => 'btn btn-danger', + 'data' => [ + 'confirm' => 'Вы уверены, что хотите удалить элемент?', + 'method' => 'post', + ], + ]) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'parent_id', + 'name', + 'type', + 'created_at', + ], + ]) ?> + +
diff --git a/erp24/web/js/store_city_list/_form.js b/erp24/web/js/store_city_list/_form.js new file mode 100644 index 00000000..f123f01e --- /dev/null +++ b/erp24/web/js/store_city_list/_form.js @@ -0,0 +1,16 @@ +document.addEventListener('DOMContentLoaded', function() { + const typeSelector = document.getElementById('type-selector'); + const parentIdField = document.getElementById('parent-id-field'); + + function toggleParentField() { + const selectedType = typeSelector.value; + if (selectedType === 'region') { + parentIdField.style.display = 'none'; + } else { + parentIdField.style.display = 'block'; + } + } + + typeSelector.addEventListener('change', toggleParentField); + toggleParentField(); +}); \ No newline at end of file