]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
ERP-302 Редактирование букета
authormarina <m.zozirova@gmail.com>
Tue, 11 Feb 2025 14:29:15 +0000 (17:29 +0300)
committermarina <m.zozirova@gmail.com>
Tue, 11 Feb 2025 14:29:15 +0000 (17:29 +0300)
erp24/.gitignore
erp24/controllers/BouquetController.php
erp24/migrations/m250211_064121_create_bouquet_forecast_table.php
erp24/records/BouquetComposition.php
erp24/records/BouquetCompositionProducts.php
erp24/records/BouquetForecast.php
erp24/views/bouquet/update.php
erp24/views/bouquet/view.php
erp24/widgets/FileUploadWidget.php [deleted file]

index c25408fcb4a45b289de527a03f1ba07b4ebfcdc3..a5dd55d5531487ee9fca6ac786cfa3d812f913df 100644 (file)
@@ -40,4 +40,5 @@ tests/_support/_generated
 /data/*
 /runtime/*
 /api2/runtime/*
-/api2/json/*
\ No newline at end of file
+/api2/json/*
+/widgets/app.log
\ No newline at end of file
index 4851bc0fb9ec6e72410ef6b47f944dc77ae477ef..0a81ba7a9241a194020ddbac14b6f38a40202b33 100644 (file)
@@ -5,6 +5,8 @@ namespace app\controllers;
 use Exception;
 use Yii;
 use yii\helpers\ArrayHelper;
+use yii\helpers\FileHelper;
+use yii\helpers\Url;
 use yii\web\Controller;
 use yii\web\NotFoundHttpException;
 use yii\web\UploadedFile;
@@ -12,9 +14,11 @@ use yii_app\records\BouquetComposition;
 use yii_app\records\BouquetCompositionProducts;
 use yii_app\records\BouquetForecast;
 use yii_app\records\CityStore;
+use yii_app\records\Files;
 use yii_app\records\Products1c;
 use yii_app\records\Products1cNomenclature;
 use yii_app\records\StoreType;
+use yii_app\services\FileService;
 
 /**
  * Контроллер для управления букетами и их составами.
@@ -28,17 +32,96 @@ class BouquetController extends Controller
 
     public function actionView($id)
     {
+        $model = BouquetComposition::findOne($id);
+
+        if (Yii::$app->request->isPost) {
+            $data = Yii::$app->request->post();
+            $month = $data['month'];
+            $year = $data['year'];
+
+            $model->photo_bouquet = UploadedFile::getInstances($model, 'photo_bouquet');
+            if ($model->photo_bouquet) {
+                Files::deleteAll(['file_type' => 'image', 'entity_id' => $id, 'entity' => BouquetComposition::PHOTO_BOUQUET]);
+                foreach ($model->photo_bouquet as $photo) {
+                    FileService::saveUploadedFile($photo, BouquetComposition::PHOTO_BOUQUET, $model->id);
+                }
+            }
+
+            $model->video_presentation = UploadedFile::getInstances($model, 'video_presentation');
+            if ($model->video_presentation) {
+                Files::deleteAll(['file_type' => 'video', 'entity_id' => $id, 'entity' => BouquetComposition::VIDEO_PRESENTATION]);
+                FileService::saveUploadedFile($model->video_presentation, BouquetComposition::VIDEO_PRESENTATION, $model->id);
+            }
+
+            $model->video_build_process = UploadedFile::getInstances($model, 'video_build_process');
+            if ($model->video_build_process) {
+                Files::deleteAll(['file_type' => 'video', 'entity_id' => $id, 'entity' => BouquetComposition::VIDEO_BUILD_PROCESS]);
+                FileService::saveUploadedFile($model->video_build_process, BouquetComposition::VIDEO_BUILD_PROCESS, $model->id);
+            }
+
+
+            if (!empty($data['BouquetForecast']['type_sales_value'])) {
+                $salesData = $data['BouquetForecast']['type_sales_value'];
+
+                if (!empty($salesData['offline'])) {
+                    BouquetForecast::processSalesData($id, $year, $month, $salesData['offline'], BouquetForecast::OFFLINE_STORES);
+                }
+
+                if (!empty($salesData['online'])) {
+                    BouquetForecast::processSalesData($id, $year, $month, $salesData['online'], BouquetForecast::ONLINE_STORES);
+                }
+
+                if (!empty($salesData['marketplace'])) {
+                    BouquetForecast::processSalesData($id, $year, $month, $salesData['marketplace'], BouquetForecast::MARKETPLACE);
+                }
+            }
+
+        }
+
+
+        $photoFiles = Files::find()->where(['entity_id' => $id, 'file_type' => 'image', 'entity' => BouquetComposition::PHOTO_BOUQUET])->all();
+        $videoFiles = Files::find()->where(['entity_id' => $id, 'file_type' => 'image', 'entity' => BouquetComposition::VIDEO_PRESENTATION])->all();
+        $processFiles = Files::find()->where(['entity_id' => $id, 'file_type' => 'image', 'entity' => BouquetComposition::VIDEO_BUILD_PROCESS])->all();
+
+        $photoUrls = array_map(fn($file) => Url::to([$file->url]), $photoFiles);
+        $videoUrls = array_map(fn($file) => Url::to([$file->url]), $videoFiles);
+        $processUrls = array_map(fn($file) => Url::to([$file->url]), $processFiles);
+
+        $bouquetCompositionProducts = BouquetCompositionProducts::find()->andWhere(['bouquet_id' => $id])->all();
+        $storesTypeList = BouquetForecast::getStoresList($id, BouquetForecast::OFFLINE_STORES, StoreType::class, []);
+        $marketplaceList = BouquetForecast::getStoresList($id, BouquetForecast::MARKETPLACE, CityStore::class, ['visible' => CityStore::IS_VISIBLE]);
+        $onlineStoresList = BouquetForecast::getStoresList($id, BouquetForecast::ONLINE_STORES, CityStore::class, ['visible' => CityStore::IS_VISIBLE]);
 
-        BouquetForecast::findAll(['bouquet_id' => $id]);
-        $storesTypeList =  ArrayHelper::map(BouquetForecast::findAll(['bouquet_id' => $id]) ?? StoreType::find()->orderBy('sequence_number')->all(), 'id', 'name');
-        $storesList = ArrayHelper::map(BouquetForecast::findAll(['bouquet_id' => $id]) ?? CityStore::findAll(['visible' => CityStore::IS_VISIBLE]), 'id', 'name');
 
         return $this->render('view', [
-            'storesList' => $storesList,
+            'model' => $model,
+            'onlineStoresList' => $onlineStoresList,
+            'bouquetCompositionProducts' => $bouquetCompositionProducts,
+            'marketplaceList' => $marketplaceList,
             'storesTypeList' => $storesTypeList,
+            'photoUrls' => $photoUrls,
+            'photoFiles' => $photoFiles,
+            'videoUrls' => $videoUrls,
+            'processUrls' => $processUrls,
         ]);
     }
 
+
+    /**
+     * Сохранение записи в таблицу files
+     */
+    private function saveFileRecord($bouquetId, $filePath, $type)
+    {
+        $file = new Files([
+            'url' => $filePath,
+            'file_type' => $type,
+            'created_at' => time(),
+            'entity_id' => $bouquetId,
+            'entity' => 'bouquet/photo',
+        ]);
+        $file->save();
+    }
+
     public function actionUpdate($id)
     {
         $model = BouquetComposition::findOne($id);
@@ -99,6 +182,7 @@ class BouquetController extends Controller
             'availableItems' => $availableItems,
         ]);
     }
+
     public function actionUpload()
     {
         $model = new BouquetComposition();
index 4037f70a3f53d564ec3331143c41778b05c5899a..e6bf5564f7a204e58274feee887cb0ae6679fc38 100644 (file)
@@ -12,14 +12,14 @@ class m250211_064121_create_bouquet_forecast_table extends Migration
      */
     public function safeUp()
     {
-        $this->createTable('{{%bouquet_forecast}}', [
+        $this->createTable('{{%erp24.bouquet_forecast}}', [
             'id' => $this->primaryKey(),
             'bouquet_id' => $this->integer()->comment('ИД букета'),
             'year' => $this->integer()->comment('Год'),
             'month' => $this->integer()->comment('Месяц'),
             'type_sales' => $this->integer()->comment('Тип продаж'),
-            'store_sales_id' => $this->integer()->comment('ИД сущности типа продаж'),
-            'value' => $this->float('Значение'),
+            'type_sales_id' => $this->integer()->comment('ИД сущности типа продаж'),
+            'type_sales_value' => $this->float('Значение'),
             'created_at' => $this->dateTime()->comment('Дата создания'),
             'updated_at' => $this->dateTime()->comment('Дата обновления'),
             'created_by' => $this->integer()->comment('ID создателя записи'),
index c791c6ee1ea3a90bb6ae9cf6be58c6bd9ba644c2..6f3f1672054be8975af35de11af475ab4b6165cf 100644 (file)
@@ -27,6 +27,14 @@ use yii_app\records\BouquetCompositionProducts;
  */
 class BouquetComposition extends ActiveRecord
 {
+    public $photo_bouquet;
+    public $video_presentation;
+    public $video_build_process;
+
+    public const PHOTO_BOUQUET = 'bouquet/photo_bouquet';
+    public const VIDEO_PRESENTATION = 'bouquet/video_presentation';
+    public const VIDEO_BUILD_PROCESS = 'bouquet/video_build_process';
+
     public static function tableName()
     {
         return 'erp24.bouquet_composition';
@@ -56,11 +64,9 @@ class BouquetComposition extends ActiveRecord
             [['name'], 'required'],
             [['matrix_type_id', 'video_id', 'created_by', 'updated_by'], 'integer'],
             [['created_at', 'updated_at'], 'safe'],
-
-            [['photo_id'], 'file', 'extensions' => 'jpg, jpeg, png, gif'],
-
-
             [['guid', 'name'], 'string', 'max' => 255],
+            [['photo_bouquet'], 'file', 'extensions' => 'jpg, jpeg, png, gif', 'maxFiles' => 10],
+            [['video_presentation', 'video_build_process'], 'file', 'extensions' => 'mkv, mov, avi, mp4'],
         ];
     }
 
index 98d4b778e78a189819af14a211d06b18f78ca616..88c98581babb4ddb607515b6933cfb8935f7ca82 100644 (file)
@@ -78,7 +78,7 @@ class BouquetCompositionProducts extends ActiveRecord
     }
 
     public function getProduct() {
-        return $this->hasOne(Products1c::class, ['id' => 'product_guid']); // Исправил связь
+        return $this->hasOne(Products1c::class, ['id' => 'product_guid']);
     }
 
 }
index be9c4f5b33e592fd65c344a814cb88b28bd60896..6acef163d876732575242cc6f125b3299ab1ba74 100644 (file)
@@ -3,7 +3,10 @@
 namespace yii_app\records;
 
 use Yii;
+use yii\behaviors\BlameableBehavior;
+use yii\behaviors\TimestampBehavior;
 use yii\db\ActiveRecord;
+use yii\db\Expression;
 
 /**
  * This is the model class for table "bouquet_forecast".
@@ -13,8 +16,8 @@ use yii\db\ActiveRecord;
  * @property int|null $year Год
  * @property int|null $month Месяц
  * @property int|null $type_sales Тип продаж
- * @property int|null $store_sales_id ИД сущности типа продаж
- * @property float|null $value Значение
+ * @property int|null $type_sales_id ИД сущности типа продаж
+ * @property float|null $type_sales_value Значение
  * @property string|null $created_at Дата создания
  * @property string|null $updated_at Дата обновления
  * @property int|null $created_by ID создателя записи
@@ -32,7 +35,24 @@ class BouquetForecast extends ActiveRecord
      */
     public static function tableName()
     {
-        return '{{%bouquet_forecast}}';
+        return '{{%erp24.bouquet_forecast}}';
+    }
+
+    public function behaviors()
+    {
+        return [
+            [
+                'class' => TimestampBehavior::class,
+                'createdAtAttribute' => 'created_at',
+                'updatedAtAttribute' => 'updated_at',
+                'value' => new Expression('NOW()'),
+            ],
+            [
+                'class' => BlameableBehavior::class,
+                'createdByAttribute' => 'created_by',
+                'updatedByAttribute' => 'updated_by',
+            ],
+        ];
     }
 
     /**
@@ -41,8 +61,8 @@ class BouquetForecast extends ActiveRecord
     public function rules()
     {
         return [
-            [['bouquet_id', 'year', 'month', 'type_sales', 'store_sales_id', 'created_by', 'updated_by'], 'integer'],
-            [['value'], 'number'],
+            [['bouquet_id', 'year', 'month', 'type_sales', 'type_sales_id', 'created_by', 'updated_by'], 'integer'],
+            [['type_sales_value'], 'number'],
             [['created_at', 'updated_at'], 'safe'],
         ];
     }
@@ -58,12 +78,66 @@ class BouquetForecast extends ActiveRecord
             'year' => 'Год',
             'month' => 'Месяц',
             'type_sales' => 'Тип продаж',
-            'store_sales_id' => 'ИД сущности типа продаж',
-            'value' => 'Значение',
+            'type_sales_id' => 'ИД сущности типа продаж',
+            'type_sales_value' => 'Значение',
             'created_at' => 'Дата создания',
             'updated_at' => 'Дата обновления',
             'created_by' => 'ID создателя записи',
             'updated_by' => 'ID обновителя записи',
         ];
     }
-}
+
+    public static function getStoresList($id, $typeSales, $defaultModel, $defaultCondition)
+    {
+        $joinTable = $defaultModel === CityStore::class ? 'city_store' : 'store_type';
+
+        $list = BouquetForecast::find()
+            ->andWhere(['bouquet_id' => $id, 'type_sales' => $typeSales])
+            ->leftJoin("$joinTable AS df", "df.id = bouquet_forecast.type_sales_id")
+            ->select(["df.name AS name", 'type_sales_value AS value', 'type_sales_id AS id'])
+            ->orderBy('type_sales_id')
+            ->asArray()
+            ->all();
+
+        if (empty($list)) {
+            $list = $defaultModel::find()
+                ->andWhere($defaultCondition)
+                ->select([
+                    'id',
+                    'name',
+                    new Expression('NULL as value')
+                ])
+                ->asArray()
+                ->all();
+        }
+
+        return $list;
+    }
+
+    public static function processSalesData($id, $year, $month, $salesData, $salesType)
+    {
+        foreach ($salesData as $key => $value) {
+            $model = BouquetForecast::findOne([
+                'bouquet_id' => $id,
+                'year' => $year,
+                'month' => $month,
+                'type_sales' => $salesType,
+                'type_sales_id' => $key
+            ]);
+
+            if (empty($model)) {
+                $model = new BouquetForecast([
+                    'bouquet_id' => $id,
+                    'year' => $year,
+                    'month' => $month,
+                    'type_sales' => $salesType,
+                    'type_sales_id' => $key,
+                    'type_sales_value' => $value
+                ]);
+                $model->save();
+            } elseif ($model->type_sales_value != $value) {
+                $model->updateAttributes(['type_sales_value' => $value]);
+            }
+        }
+    }
+}
\ No newline at end of file
index c0f485dfa157e9fd04cae6b09d0c516153d92fd3..cc9b340708a59b105de900b62ed2f774f6ac5db0 100644 (file)
@@ -12,7 +12,7 @@ use yii_app\records\Products1cNomenclature;
 /** @var array|null $availableItems */
 /** @var array|null $selectedItems */
 
-$this->title = 'Три гладиолуса';
+$this->title = $model->name;
 $this->params['breadcrumbs'][] = ['label' => 'Букеты', 'url' => ['index']];
 $this->params['breadcrumbs'][] = $this->title;
 
@@ -20,7 +20,6 @@ $this->registerJsFile('/js/bouquet/bouquet.js', ['position' => \yii\web\View::PO
 ?>
 
 <div class="bouquet-update p-4">
-<!--    --><?php //= Html::label('Редактирование букета', null, ['class' => 'h4']) ?>
     <h3 class="ms-3 d-inline"><?= Html::encode("Редактирование букета: ") ?></h3>
     <h2 class="d-inline"><strong><?= Html::encode($this->title) ?></strong></h2>
     <div class="row">
index 59f528d95ef7a7de862791c3be0674d502fbfdc3..0ca81748fd3e9328bc9c365e488cc1e2ad02fe4b 100644 (file)
@@ -1,28 +1,36 @@
 <?php
 
-use app\widgets\FileUploadWidget;
-use app\widgets\MediaUploader;
-use dosamigos\fileupload\FileUploadUI;
 use kartik\file\FileInput;
 use yii\helpers\ArrayHelper;
 use yii\helpers\Html;
 use yii\helpers\Url;
 use yii\widgets\ActiveForm;
-use yii\widgets\DetailView;
 use yii_app\records\BouquetComposition;
 use yii_app\records\MatrixType;
 
 /** @var yii\web\View $this */
-/** @var yii_app\records\BouquetComposition $model
- */
+/** @var yii_app\records\BouquetComposition $model */
+/** @var array $bouquetCompositionProducts */
+/** @var array $storesTypeList */
+/** @var array $marketplaceList */
+/** @var array $onlineStoresList */
+/** @var array $photoFiles */
+/** @var array $videoFiles */
+/** @var array $processFiles */
 
-//$this->title = $model->name;
-$this->title = 'Три гладиолуса';
-//$this->title = $model->name;
+$this->title = $model->name;
 $this->params['breadcrumbs'][] = ['label' => 'Букеты', 'url' => ['index']];
 $this->params['breadcrumbs'][] = $this->title;
 ?>
 <?php
+
+$photoConfig = array_map(fn($file) => [
+    'caption' => $file->url,
+    'key' => $file->id,
+    'url' => Url::to(['file/delete', 'id' => $file->id]),
+], $photoFiles);
+?>
+<?php
 $this->registerCss("
              .file-caption {
                     max-width: 62% !important; 
@@ -31,7 +39,7 @@ $this->registerCss("
 ?>
 <div class="bouquet-view border-bottom-4 p-4">
     <?php $form = ActiveForm::begin([
-        'options' => ['enctype' => 'multipart/form-data'], // Это необходимо для загрузки файлов
+        'options' => ['enctype' => 'multipart/form-data'],
     ]);
     ?>
     <div class="row d-flex border-bottom justify-content-between align-items-center py-4">
@@ -63,19 +71,21 @@ $this->registerCss("
             </div>
 
             <div class="row bg-white border rounded shadow-sm">
+                <?php foreach ($bouquetCompositionProducts as $product) { ?>
                 <div class="row ms-1 py-2">
-                    <div class="col-md-4 text-center">Гладиолусы краш</div>
-                    <div class="col-md-2 text-center">3.0</div>
+                    <div class="col-md-4 text-center"><?= $product->product->name ?></div>
+                    <div class="col-md-2 text-center"><?= $product->count ?></div>
                     <div class="col-md-1 text-center">10%</div>
                     <div class="col-md-2 text-center">30%</div>
                     <div class="col-md-1 text-center">10%</div>
                     <div class="col-md-2 text-center">3.2%</div>
                 </div>
+                <?php } ?>
             </div>
             <div class="row pt-3">
                 <div class="col-md-8"></div>
                 <div class="col-md-4">
-                    <?= Html::submitButton('Редактировать', ['class' => 'btn btn-warning w-100']) ?>
+                    <?= Html::a('Редактировать', Url::to("/bouquet/update?id=$model->id"), ['class' => 'btn btn-warning w-100']) ?>
                 </div>
             </div>
         </div>
@@ -83,20 +93,23 @@ $this->registerCss("
             <div class="row w-100 w-md-75 w-lg-50">
                 <?php $model = new BouquetComposition(); ?>
                 <div class="row mb-2"><?= Html::label("Фото", null, ['class' => 'text-center font-weight-bold pt-5 h5']) ?></div>
-                <?= $form->field($model, 'photo_id[]')->widget(FileInput::class, [
+                <?= $form->field($model, 'photo_bouquet[]')->widget(FileInput::class, [
                     'options' => [
                         'id' => 'bouquet-file-upload',
                         'multiple' => true,  // Поддержка выбора нескольких файлов
+                        'accept' => 'image/png, image/jpeg, image/jpg',
                     ],
                     'language' => 'ru',
                     'pluginOptions' => [
+                        'initialPreview' => $photoUrls,
+                        'initialPreviewConfig' => $photoConfig,
                         'showPreview' => true,
                         'showUpload' => false,
                         'showCancel' => false,
                         'mainClass' => 'input-group-lg',
-                        'initialPreview' => [],  // Задайте начальный список для предварительного просмотра (если есть)
+//                        'initialPreview' => [],  // Задайте начальный список для предварительного просмотра (если есть)
                         'maxFileSize' => 2800,  // Максимальный размер файла (в килобайтах)
-                        'dropZoneTitle' => 'Выберите файл',  // Текст на зоне для перетаскивания
+                        'dropZoneTitle' => 'Выберите изображение',  // Текст на зоне для перетаскивания
                         'browseOnZoneClick' => true,  // Разрешить клик по зоне перетаскивания
                         'fileActionSettings' => [
                             'showZoom' => false,  // Убираем иконку для увеличения
@@ -107,10 +120,11 @@ $this->registerCss("
             <div class="row">
                 <div class="col-md-6 w-100 w-md-75 w-lg-50">
                     <div class="row mb-2"><?= Html::label("Презентация", null, ['class' => 'text-center font-weight-bold pt-5 h5']) ?></div>
-                    <?= $form->field($model, 'photo_id[]')->widget(FileInput::class, [
+                    <?= $form->field($model, 'video_presentation')->widget(FileInput::class, [
                         'options' => [
                             'id' => 'video-file-upload',
-                            'multiple' => false,  // Поддержка выбора нескольких файлов
+                            'multiple' => false,
+                            'accept' => 'video/mp4, video/avi, video/mov, video/mkv',
                         ],
                         'language' => 'ru',
                         'pluginOptions' => [
@@ -118,22 +132,23 @@ $this->registerCss("
                             'showUpload' => false,
                             'showCancel' => false,
                             'mainClass' => 'input-group-lg',
-                            'initialPreview' => [],  // Задайте начальный список для предварительного просмотра (если есть)
-                            'maxFileSize' => 2800,  // Максимальный размер файла (в килобайтах)
-                            'dropZoneTitle' => 'Выберите файл',  // Текст на зоне для перетаскивания
+                            'initialPreview' => $videoUrls,
+                            'maxFileSize' => 100000,  // Максимальный размер файла (в килобайтах)
+                            'dropZoneTitle' => 'Выберите видеофайл',  // Текст на зоне для перетаскивания
                             'browseOnZoneClick' => true,  // Разрешить клик по зоне перетаскивания
                             'fileActionSettings' => [
-                                'showZoom' => false,  // Убираем иконку для увеличения
+                                'showZoom' => false,
                             ],
                         ],
                     ])->label(false) ?>
                 </div>
                 <div class="col-md-6 w-100 w-md-75 w-lg-50">
                     <div class="row mb-2"><?= Html::label("Процесс сборки", null, ['class' => 'text-center font-weight-bold pt-5 h5']) ?></div>
-                    <?= $form->field($model, 'photo_id[]')->widget(FileInput::class, [
+                    <?= $form->field($model, 'video_build_process')->widget(FileInput::class, [
                         'options' => [
                             'id' => 'presentation-file-upload',
-                            'multiple' => false,  // Поддержка выбора нескольких файлов
+                            'multiple' => false,
+                            'accept' => 'video/mp4, video/avi, video/mov, video/mkv',
                         ],
                         'language' => 'ru',
                         'pluginOptions' => [
@@ -141,9 +156,9 @@ $this->registerCss("
                             'showUpload' => false,
                             'showCancel' => false,
                             'mainClass' => 'input-group-lg',
-                            'initialPreview' => [],  // Задайте начальный список для предварительного просмотра (если есть)
-                            'maxFileSize' => 2800,  // Максимальный размер файла (в килобайтах)
-                            'dropZoneTitle' => 'Выберите файл',  // Текст на зоне для перетаскивания
+                            'initialPreview' => $processUrls,
+                            'maxFileSize' => 100000,  // Максимальный размер файла (в килобайтах)
+                            'dropZoneTitle' => 'Выберите видеофайл',
                             'browseOnZoneClick' => true,  // Разрешить клик по зоне перетаскивания
                             'fileActionSettings' => [
                                 'showZoom' => false,  // Убираем иконку для увеличения
@@ -172,50 +187,52 @@ $this->registerCss("
             </div>
             <div class="row">
                 <div class="container border p-3" style="max-height: 185px; background-color: white; overflow: auto;">
-                    <div class="row align-items-center mb-2">
-                        <?php foreach ($storesTypeList as $type) {
-                            echo '<div class="col-md-8">
-                                    <label class="col-form-label">'.$type.'</label>
-                                </div>
-                                <div class="col-md-4">
-                                    <input type="number" class="form-control h-25" placeholder="Введите значение">
-                                </div>';
-                        } ?>
-                    </div>
+                    <?php foreach ($storesTypeList as $item) { ?>
+                        <div class="row align-items-center mb-2">
+                            <div class="col-md-8">
+                                <?= Html::label($item['name'], null, ['class' => "col-form-label"]); ?>
+                            </div>
+                            <div class="col-md-4">
+                                <?= Html::input('number', "BouquetForecast[type_sales_value][offline][{$item['id']}]", $item['value'], ['class' => 'form-control']) ?>
+                            </div>
+                        </div>
+                    <?php } ?>
                 </div>
             </div>
+
             <div class="row">
                 <?= Html::label("Интернет магазины", null, ['class' => 'text-center font-weight-bold pt-3 h6']) ?>
             </div>
             <div class="row">
                 <div class="container border p-3" style="max-height: 185px;background-color: white; overflow: auto;">
-                    <div class="row align-items-center mb-2">
-                        <?php foreach ($storesList as $store) {
-                            echo '<div class="col-md-8">
-                                    <label class="col-form-label">'.$store.'</label>
-                                </div>
-                                <div class="col-md-4">
-                                    <input type="number" class="form-control h-25" placeholder="Введите значение">
-                                </div>';
-                        } ?>
-                    </div>
+                    <?php foreach ($onlineStoresList as $item) { ?>
+                        <div class="row align-items-center mb-2">
+                            <div class="col-md-8">
+                                <?= Html::label($item['name'], null, ['class' => "col-form-label"]); ?>
+                            </div>
+                            <div class="col-md-4">
+                                <?= Html::input('number', "BouquetForecast[type_sales_value][online][{$item['id']}]", $item['value'], ['class' => 'form-control']) ?>
+                            </div>
+                        </div>
+                    <?php } ?>
                 </div>
             </div>
+
             <div class="row">
                 <?= Html::label("Маркетплейсы", null, ['class' => 'text-center font-weight-bold pt-3 h6']) ?>
             </div>
             <div class="row">
                 <div class="container border p-3" style="max-height: 185px; background-color: white; overflow: auto;">
-                    <div class="row align-items-center mb-2">
-                        <?php foreach ($storesList as $store) {
-                            echo '<div class="col-md-8">
-                                    <label class="col-form-label">'.$store.'</label>
-                                </div>
-                                <div class="col-md-4">
-                                    <input type="number" class="form-control" placeholder="Введите значение">
-                                </div>';
-                        } ?>
-                    </div>
+                    <?php foreach ($marketplaceList as $item) { ?>
+                        <div class="row align-items-center mb-2">
+                            <div class="col-md-8">
+                                <?= Html::label($item['name'], null, ['class' => "col-form-label"]); ?>
+                            </div>
+                            <div class="col-md-4">
+                                <?= Html::input('number', "BouquetForecast[type_sales_value][marketplace][{$item['id']}]", $item['value'], ['class' => 'form-control']) ?>
+                            </div>
+                        </div>
+                    <?php } ?>
                 </div>
             </div>
         </div>
diff --git a/erp24/widgets/FileUploadWidget.php b/erp24/widgets/FileUploadWidget.php
deleted file mode 100644 (file)
index b4e60fd..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-
-namespace app\widgets;
-
-use yii\base\Widget;
-use yii\helpers\Html;
-
-class FileUploadWidget extends Widget
-{
-    public $containerId = 'file-upload-widget';  // Идентификатор контейнера
-    public $inputId = 'file-upload';  // Идентификатор input для файлов
-    public $maxFiles = 10;  // Максимальное количество файлов (по желанию)
-
-    public function init()
-    {
-        parent::init();
-    }
-
-    public function run()
-    {
-        $this->registerAssets();
-
-        return $this->renderContent();
-    }
-
-    // Рендеринг HTML-контента для виджета
-    protected function renderContent()
-    {
-        return Html::tag('div',
-            Html::tag('label',
-                Html::tag('input', '', ['type' => 'file', 'id' => $this->inputId, 'multiple' => true]) .
-                Html::tag('span', '+', ['class' => 'plus-icon']),
-                ['for' => $this->inputId, 'class' => 'upload-label']
-            ),
-            ['id' => $this->containerId, 'class' => 'file-container']
-        );
-    }
-
-    // Встраивание CSS и JS непосредственно в HTML
-    protected function registerAssets()
-    {
-        $view = $this->getView();
-
-        $css = <<<CSS
-        .file-container {
-            display: flex;
-            flex-wrap: wrap;
-            gap: 10px;
-        }
-
-        .upload-label {
-            position: relative;
-            width: 100px;
-            height: 100px;
-            background-color: #f0f0f0;
-            border: 2px dashed #ccc;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            cursor: pointer;
-        }
-
-        .upload-label input[type="file"] {
-            display: none;
-        }
-
-        .plus-icon {
-            font-size: 2rem;
-            color: #555;
-        }
-
-        .uploaded-image {
-            width: 100px;
-            height: 100px;
-            object-fit: cover;
-            border: 2px solid #ccc;
-        }
-
-        .uploaded-container {
-            position: relative;
-        }
-
-        .remove-btn {
-            position: absolute;
-            top: 5px;
-            right: 5px;
-            background-color: red;
-            color: white;
-            border: none;
-            border-radius: 50%;
-            width: 20px;
-            height: 20px;
-            font-size: 14px;
-            cursor: pointer;
-        }
-        CSS;
-
-        $js = <<<JS
-        (function(\$) {
-            \$(document).on('change', '#$this->inputId', function(event) {
-                const files = event.target.files;
-                
-                for (const file of files) {
-                    const reader = new FileReader();
-                    reader.onload = function(e) {
-                        const fileContainer = \$(<div class="uploaded-container"></div>);
-                        
-                        const img = \$(<img src="\${e.target.result}" class="uploaded-image">);
-                        const removeButton = \$(<button class="remove-btn">X</button>);
-                        
-                        removeButton.on('click', function() {
-                            fileContainer.remove();
-                        });
-                        
-                        fileContainer.append(img).append(removeButton);
-                        \$('#$this->containerId').prepend(fileContainer);
-                    };
-                    
-                    reader.readAsDataURL(file);
-                }
-            });
-        })(jQuery);
-        JS;
-
-        // Вставляем CSS и JS в страницу
-        $view->registerCss($css);
-        $view->registerJs($js);
-    }
-}