]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
ERP-302 Редактирование букета
authormarina <m.zozirova@gmail.com>
Mon, 3 Feb 2025 13:46:06 +0000 (16:46 +0300)
committermarina <m.zozirova@gmail.com>
Mon, 3 Feb 2025 13:46:06 +0000 (16:46 +0300)
erp24/controllers/BouquetController.php [new file with mode: 0644]
erp24/records/BouquetComposition.php [new file with mode: 0644]
erp24/records/BouquetCompositionProducts.php [new file with mode: 0644]
erp24/records/Products1c.php
erp24/views/bouquet/index.php [new file with mode: 0644]
erp24/views/bouquet/update.php [new file with mode: 0644]
erp24/views/bouquet/view.php [new file with mode: 0644]
erp24/widgets/DualList.php [new file with mode: 0644]

diff --git a/erp24/controllers/BouquetController.php b/erp24/controllers/BouquetController.php
new file mode 100644 (file)
index 0000000..1444a2f
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+namespace app\controllers;
+
+use Yii;
+use yii\helpers\ArrayHelper;
+use yii\web\Controller;
+use yii_app\records\BouquetComposition;
+use yii_app\records\BouquetCompositionProducts;
+use yii_app\records\Products1c;
+
+/**
+ * Контроллер для управления букетами и их составами.
+ */
+class BouquetController extends Controller
+{
+    public function actionIndex() {
+        return $this->render('index');
+    }
+
+    public function actionView() {
+        return $this->render('view');
+    }
+
+    public function actionUpdate() {
+        return $this->render('update');
+    }
+
+    public function actionGetList()
+    {
+        \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
+
+        $products = Products1c::find()
+            ->where(['tip' => Products1c::TYPE_PRODUCTS, 'view' => Products1c::IS_VISIBLE])
+            ->asArray()
+            ->all();
+
+        return ArrayHelper::map($products, 'id', 'name');
+    }
+}
diff --git a/erp24/records/BouquetComposition.php b/erp24/records/BouquetComposition.php
new file mode 100644 (file)
index 0000000..7e14a46
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+namespace yii_app\records;
+
+use Yii;
+use yii\db\ActiveRecord;
+use yii_app\records\BouquetCompositionProducts;
+
+/**
+ * This is the model class for table "erp24.bouquet_composition".
+ *
+ * @property int $id
+ * @property string|null $guid
+ * @property string $name
+ * @property int|null $matrix_type_id
+ * @property int|null $photo_id
+ * @property int|null $video_id
+ * @property string|null $created_at
+ * @property string|null $updated_at
+ * @property int|null $created_by
+ * @property int|null $updated_by
+ *
+ * @property BouquetCompositionProducts[] $bouquetCompositionProducts
+ */
+class BouquetComposition extends ActiveRecord
+{
+    public static function tableName()
+    {
+        return 'erp24.bouquet_composition';
+    }
+
+    public function rules()
+    {
+        return [
+            [['name'], 'required'],
+            [['matrix_type_id', 'photo_id', 'video_id', 'created_by', 'updated_by'], 'integer'],
+            [['created_at', 'updated_at'], 'safe'],
+            [['guid', 'name'], 'string', 'max' => 255],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'id' => 'ID',
+            'guid' => 'GUID букета',
+            'name' => 'Название букета',
+            'matrix_type_id' => 'ИД типа матрицы',
+            'photo_id' => 'ИД фото',
+            'video_id' => 'ИД видео',
+            'created_at' => 'Дата создания',
+            'updated_at' => 'Дата обновления',
+            'created_by' => 'ID создателя записи',
+            'updated_by' => 'ID обновителя записи',
+        ];
+    }
+
+    public function getBouquetCompositionProducts()
+    {
+        return $this->hasMany(BouquetCompositionProducts::class, ['bouquet_id' => 'id']);
+    }
+}
diff --git a/erp24/records/BouquetCompositionProducts.php b/erp24/records/BouquetCompositionProducts.php
new file mode 100644 (file)
index 0000000..c71005e
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+namespace yii_app\records;
+
+use Yii;
+use yii\db\ActiveRecord;
+
+/**
+ * This is the model class for table "erp24.bouquet_composition_products".
+ *
+ * @property int $id
+ * @property int $bouquet_id
+ * @property string $product_guid
+ * @property float|null $count
+ * @property string|null $created_at
+ * @property string|null $updated_at
+ * @property int|null $created_by
+ * @property int|null $updated_by
+ *
+ * @property BouquetComposition $bouquet
+ */
+class BouquetCompositionProducts extends ActiveRecord
+{
+    public static function tableName()
+    {
+        return 'erp24.bouquet_composition_products';
+    }
+
+    public function rules()
+    {
+        return [
+            [['bouquet_id', 'product_guid'], 'required'],
+            [['bouquet_id', 'created_by', 'updated_by'], 'integer'],
+            [['count'], 'number'],
+            [['created_at', 'updated_at'], 'safe'],
+            [['product_guid'], 'string', 'max' => 255],
+            [['bouquet_id'], 'exist', 'skipOnError' => true, 'targetClass' => BouquetComposition::class, 'targetAttribute' => ['bouquet_id' => 'id']],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'id' => 'ID',
+            'bouquet_id' => 'ID букета',
+            'product_guid' => 'GUID продукта',
+            'count' => 'Количество продукта',
+            'created_at' => 'Дата создания',
+            'updated_at' => 'Дата обновления',
+            'created_by' => 'ID создателя записи',
+            'updated_by' => 'ID обновителя записи',
+        ];
+    }
+
+    public function getBouquet()
+    {
+        return $this->hasOne(BouquetComposition::class, ['id' => 'bouquet_id']);
+    }
+}
index b72a9f232efc26d4d790bfbbedef99b0f2c77238..64de0abf41a1b66634937251cade6769952c5878 100644 (file)
@@ -21,6 +21,9 @@ use yii\helpers\ArrayHelper;
 class Products1c extends \yii\db\ActiveRecord
 {
 
+    public const TYPE_PRODUCTS = 'products';
+    public const IS_VISIBLE = 1;
+
     const PRODUCT1C_FIELDS = ['id', 'parent_id', 'tip', 'code', 'name', 'articule', 'view', 'components', 'AdditionCharacteristics'];
 
     /**
diff --git a/erp24/views/bouquet/index.php b/erp24/views/bouquet/index.php
new file mode 100644 (file)
index 0000000..2a3f091
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+
+use yii\helpers\Html;
+
+/** @var yii\web\View $this */
+
+$this->title = 'Составы букетов';
+?>
+<div class="bouquet-index">
+    <h1><?= Html::encode($this->title) ?></h1>
+
+    <p>
+        <?= Html::a('Добавить букет', ['create'], ['class' => 'btn btn-success']) ?>
+    </p>
+
+</div>
diff --git a/erp24/views/bouquet/update.php b/erp24/views/bouquet/update.php
new file mode 100644 (file)
index 0000000..83a862a
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+use app\widgets\DualList;
+use yii\helpers\ArrayHelper;
+use yii\helpers\Html;
+use yii_app\records\Products1c;
+
+/** @var yii\web\View $this */
+/** @var yii_app\records\BouquetComposition $model */
+
+$this->title = 'Три гладиолуса';
+$this->params['breadcrumbs'][] = ['label' => 'Букеты', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+<div class="bouquet-update p-4">
+    <?= Html::label('Редактирование букета', null, ['class' => 'h4']) ?>
+    <h1 class="ms-3"><?= Html::encode($this->title) ?></h1>
+
+    <div class="row">
+        <div class="col-md-3 p-3 border rounded ms-3">
+            <div class="row mb-2">
+                <?= Html::dropDownList('category', null, [], ['class' => 'form-select', 'prompt' => 'Выберите категорию']) ?>
+            </div>
+            <div class="row mb-2">
+                <?= Html::dropDownList('species', null, [], ['class' => 'form-select', 'prompt' => 'Выберите вид']) ?>
+            </div>
+            <div class="row mb-2">
+                <?= Html::dropDownList('type', null, [], ['class' => 'form-select', 'prompt' => 'Выберите тип']) ?>
+            </div>
+            <div class="row mb-2">
+                <?= Html::dropDownList('size', null, [], ['class' => 'form-select', 'prompt' => 'Выберите размер']) ?>
+            </div>
+            <div class="row mb-3">
+                <?= Html::dropDownList('color', null, [], ['class' => 'form-select', 'prompt' => 'Выберите цвет']) ?>
+            </div>
+
+            <?= Html::button('Применить', ['class' => 'btn btn-primary w-100 mb-3', 'id' => 'apply-button']) ?>
+
+            <div class="border-top pt-2">
+                <p class="mb-1"><strong>Себестоимость:</strong> <span class="cost-value">0</span> ₽</p>
+                <p class="mb-1"><strong>Наценка:</strong> <span class="markup-value">0</span> %</p>
+                <p class="mb-0"><strong>Цена:</strong> <span class="price-value">0</span> ₽</p>
+            </div>
+        </div>
+
+        <div class="col-md-8">
+            <?= DualList::widget([
+                'name' => 'products',
+                'items' => ArrayHelper::map(
+                    Products1c::findAll(['tip' => Products1c::TYPE_PRODUCTS, 'view' => Products1c::IS_VISIBLE]),
+                    'id', 'name'
+                ),
+                'ajaxUrl' => ['/bouquet/get-list'], // для асинхронной загрузки данных
+                'options' => [
+                    'multiple' => true,
+                    'size' => 10,
+                ],
+                'triggerButton' => 'apply-button',  // Кнопка, которая будет обновлять список
+                'clientOptions' => [
+                    'moveOnSelect' => false,
+                    'nonSelectedListLabel' => 'Выбор',
+                    'selectedListLabel' => 'Состав букета',
+                    'filterTextClear' => 'Показать всё',
+                    'filterPlaceHolder' => 'Фильтр...',
+                    'infoText' => 'Показано {0}',
+                    'infoTextFiltered' => '<span class="badge bg-info">{0}</span> из {1}',
+                    'infoTextEmpty' => 'Список пуст',
+                ],
+            ]); ?>
+        </div>
+    </div>
+</div>
diff --git a/erp24/views/bouquet/view.php b/erp24/views/bouquet/view.php
new file mode 100644 (file)
index 0000000..ae40101
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+use kartik\file\FileInput;
+use yii\helpers\ArrayHelper;
+use yii\helpers\Html;
+use yii\helpers\Url;
+use yii\widgets\DetailView;
+use yii_app\records\MatrixType;
+
+/** @var yii\web\View $this */
+/** @var yii_app\records\BouquetComposition $model
+ */
+
+//$this->title = $model->name;
+$this->title = 'Три гладиолуса';
+//$this->title = $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Букеты', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+<div class="bouquet-view p-4">
+    <?= Html::label('Состав букета', null, ['class' => 'h4']) ?>
+    <h1 class="ms-5"><?= Html::encode($this->title) ?></h1>
+
+    <div class="row">
+        <div class="col-md-4">
+            Тут типа расчеты
+        </div>
+        <div class="col-md-8">
+            <div class="row">
+                <div class="col-md-4">
+                    <?= Html::label('Фото', null, ['class' => 'h4']) ?>
+                    <?= FileInput::widget([
+                        'name' => 'attachment_4',
+                        'disabled' => true
+                    ]); ?>
+                </div>
+                <div class="col-md-7">
+                    <div class="row border-bottom">
+                        <div class="col-md-5">
+                            <?= Html::label('Тип матрицы', null, ['class' => 'h4']) ?>
+                            <br>
+                            <a href="<?= Url::to('/matrix-type') ?>" class="text-decoration-none" target="_blank">Редактировать</a>
+                        </div>
+                        <div class="col-md-7 pt-2 mb-2">
+                            <?= Html::dropDownList('matrix_type_id', null, ArrayHelper::map(MatrixType::find()->all(), 'id', 'name'), ['class' => 'form-control', 'prompt' => 'Тип матрицы']) ?>
+                        </div>
+                    </div>
+                    <div class="row">
+                        <?= Html::label('Прогноз продаж (мес.)', null, ['class' => 'h5 text-center pt-5']) ?>
+                    </div>
+                    <div class="row pt-2">
+                        <div class="col-md-4">
+                            <?= Html::label('Маркетплейсы', null, ['class' => 'h5 pt-2']) ?>
+                        </div>
+                        <div class="col-md-8">
+                            <?= Html::input('number', 'marketplace', null, ['class' => 'form-control']) ?>
+                        </div>
+                    </div>
+                    <div class="row pt-2">
+                        <div class="col-md-4">
+                            <?= Html::label('Интернет магазин', null, ['class' => 'h5 pt-2']) ?>
+                        </div>
+                        <div class="col-md-8">
+                            <?= Html::input('number', 'online_stores', null, ['class' => 'form-control']) ?>
+                        </div>
+                    </div>
+                    <div class="row">
+                        <?= Html::label('Оффлайн магазины', null, ['class' => 'h5 text-center pt-5']) ?>
+                    </div>
+                    <div class="row">
+                        <?php foreach (\yii_app\records\StoreType::find()->all() as $number => $store) { ?>
+                            <div class="col-md-3 pt-1 d-flex align-items-center">
+                                <span class="offline-stores me-3"><?= Html::encode($store->name) ?></span>
+                            </div>
+                            <div class="col-md-9 pt-1 d-flex align-items-center">
+                                <?= Html::input('number', "offline-store-$store->id", null, ['class' => 'form-control']) ?>
+                            </div>
+                        <?php } ?>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
diff --git a/erp24/widgets/DualList.php b/erp24/widgets/DualList.php
new file mode 100644 (file)
index 0000000..8aab21f
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+
+namespace app\widgets;
+
+use yii\helpers\Json;
+use yii\web\View;
+use yii\helpers\Url;
+use softark\duallistbox\DualListbox;
+class DualList extends DualListbox
+{
+    public $ajaxUrl; // URL для AJAX-запроса
+    public $triggerButton; // ID кнопки, которая будет запускать AJAX-запрос
+    protected function registerPlugin($id)
+    {
+        parent::registerPlugin($id);
+
+        $view = $this->getView();
+
+        // Проверяем, что URL и кнопка переданы
+        if (!$this->ajaxUrl || !$this->triggerButton) {
+            return;
+        }
+
+        // Получаем URL для AJAX-запроса и кнопки
+        $ajaxUrl = Url::to($this->ajaxUrl);
+        $triggerButton = $this->triggerButton ? '#' . $this->triggerButton : null;
+
+        // Скрипт для обработки клика по кнопке и отправки AJAX-запроса
+        $js = <<<JS
+    function loadDualListboxData() {
+        console.log('Запрос отправляется на:', '$ajaxUrl');
+
+        $.ajax({
+            url: '$ajaxUrl',
+            method: 'GET',
+            success: function(data) {
+                console.log('Данные получены:', data);
+                if (Array.isArray(data)) {
+                    let options = data.map(item => `<option value="\${item.id}">\${item.name}</option>`);
+                    $('#$id').html(options.join(''));  // Очищаем список и добавляем новые данные
+                    $('#$id').bootstrapDualListbox('refresh'); // Обновляем плагин
+                }
+            },
+            error: function(xhr) {
+                console.error('Ошибка загрузки данных:', xhr);
+            }
+        });
+    }
+
+    // Проверим, что кнопка существует
+    $(document).on('click', '$triggerButton', function() {
+        console.log('Кнопка с ID $triggerButton нажата!');
+        loadDualListboxData();
+    });
+
+    // Печать, чтобы проверить, загружен ли скрипт
+    console.log('JavaScript был загружен и привязан!');
+JS;
+
+        // Регистрируем JS скрипт
+        $view->registerJs($js);
+    }
+}
+
+
+