]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Загрузка и валидация xslx проходит в модальном диалоге
authorAlexander Smirnov <fredeom@mail.ru>
Wed, 24 Jul 2024 15:48:00 +0000 (18:48 +0300)
committerAlexander Smirnov <fredeom@mail.ru>
Wed, 24 Jul 2024 15:48:00 +0000 (18:48 +0300)
erp24/actions/motivation/IndexAction.php
erp24/composer.json
erp24/controllers/MotivationController.php
erp24/views/motivation/index.php
erp24/web/js/motivation/index.js [new file with mode: 0644]

index 94a06feb812d7dbcaf6123d2a71a30c91761c62a..bed7da143deff000d96e9ffeba36af8513dda0ba 100644 (file)
 
 namespace yii_app\actions\motivation;
 
+use PhpOffice\PhpSpreadsheet\IOFactory;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
 use Yii;
 use yii\base\Action;
 use yii\base\DynamicModel;
 use yii\helpers\ArrayHelper;
+use yii\web\UploadedFile;
 use yii_app\records\CityStore;
+use yii_app\records\MotivationCostsItem;
 
 class IndexAction extends Action
 {
     public function run() {
+        if (Yii::$app->request->isPost) {
+            $file = UploadedFile::getInstanceByName('myfile');
+            if ($file) {
+                $path = Yii::getAlias('@uploads') . '/template_plan.xslx';
+                $file->saveAs($path);
+
+                $motivationCostsItems = MotivationCostsItem::find()->indexBy('code')->all();
+                $spreadsheets = IOFactory::load($path);
+                $sheets = [];
+                $errors = [];
+                foreach ($spreadsheets->getAllSheets() as $spreadSheet) {
+                    $rows = [];
+                    $finish = false;
+                    $storeStr = true;
+                    $error = '';
+                    foreach ($spreadSheet->getRowIterator() as $ind => $spreadSheetRow) {
+                        $row = [];
+                        foreach ($spreadSheetRow->getCellIterator() as $spreadSheetRowCell) {
+                            $value = $spreadSheetRowCell->getValue();
+                            if ($value == '###') {
+                                $finish = true;
+                                break;
+                            }
+                            $row []= $value;
+                        }
+                        if ($finish) {
+                            break;
+                        }
+                        if ($storeStr) {
+                            $store = CityStore::find()->where(['id' => $row[0] ?? -1])->one();
+                            if (!$store) {
+                                $error = "Не найден магазин с таким индексом [0,0]";
+                                break;
+                            } elseif ($store->name != ($row[1] ?? 'NO_NAME')) {
+                                $error = "Не найден магазин с таким названием [1,0]" . $row[1] . ' ' . $store->name;
+                                break;
+                            }
+                            $year = ((int)$row[2]) ?? -1;
+                            $month = ((int)$row[3]) ?? -1;
+                            if ($year > 2030 || $year < 2023) {
+                                $error = "Не корректно указан год [2,0]";
+                                break;
+                            }
+                            if ($month < 1 || $month > 12) {
+                                $error = "Не корректно указан месяц [3,0]";
+                                break;
+                            }
+                            $storeStr = false;
+                        } else {
+                            if (!isset($motivationCostsItems[$row[0] ?? -1])) {
+                                $error = "Не корректен код элемента " . ($row[0] ?? '') . "[$ind,0]";
+                                break;
+                            }
+                            /** @var $motivationCostsItems MotivationCostsItem[] */
+                            if ($motivationCostsItems[$row[0]]->name != ($row[1] ?? 'NO_NAME')) {
+                                $error = "Не корректно название элемента " . ($row[1] ?? '') . "[$ind,1]";
+                                break;
+                            }
+                            if (($row[2] ?? 'NO_NAME') == 'NO_NAME') {
+                                $error = "Не корректно значение элемента [$ind,2]";
+                                break;
+                            }
+                            switch ($motivationCostsItems[$row[0]]->data_type) {
+                                case MotivationCostsItem::DATA_TYPE_INT: { if (is_int($row[2])) { $value = (int)$row[2]; } else { $error = "Не инт [$ind,2]"; }; break; }
+                                case MotivationCostsItem::DATA_TYPE_FLOAT: { if (is_int($row[2]) || is_float($row[2])) { $value = (float)$row[2]; } else {$error = "Не флот [$ind,2]"; } break; }
+                                case MotivationCostsItem::DATA_TYPE_STRING: { $value = $row[2]; break; }
+                            }
+                            if (!empty($error)) {
+                                break;
+                            }
+                        }
+                        $rows []= $row;
+                    }
+                    $errors []= empty($error) ? '' : $error;
+                    $sheets []= $rows;
+                }
+
+                return implode('<br>', $errors);
+            } else {
+                return 'not ok';
+            }
+        }
+
         $model = DynamicModel::validateData([
                 'store_id' => null, 'year' => null, 'month' => null
             ], [
index 762e20ef34052934f42f5e69c27370d14026aa03..46fe76d7e34e7ed73b3ac6ff895e7f493923d1de 100644 (file)
@@ -27,7 +27,7 @@
         "kartik-v/yii2-widget-fileinput": "dev-master",
         "yiisoft/yii2-imagine": "^2.3",
         "kartik-v/yii2-builder": "dev-master",
-        "box/spout": "^3.3"
+        "phpoffice/phpspreadsheet": "^1.12"
     },
     "require-dev": {
         "yiisoft/yii2-debug": "~2.1.0",
index e21ab556e7a1b5f1c18b3845d3a77c66c9e18f36..1fb1ca185bca70c025aa182b38565098eea395dd 100644 (file)
@@ -12,7 +12,7 @@ class MotivationController extends Controller
     public function actions() {
         return [
             'index' => \yii_app\actions\motivation\IndexAction::class,
-            'upload-xlsx' => \yii_app\actions\motivation\UploadXlsxAction::class,
+            //'upload-xlsx' => \yii_app\actions\motivation\UploadXlsxAction::class,
             'values' => \yii_app\actions\motivation\ValuesAction::class,
             'create-value' => \yii_app\actions\motivation\CreateValueAction::class,
             'update-value' => \yii_app\actions\motivation\UpdateValueAction::class,
index 04a1860dfaf4636d79304d40068134922123c4ca..f43c5475d4890f1dd443e2ac8a3c6e446081f557 100644 (file)
@@ -10,6 +10,8 @@ use yii\base\DynamicModel;
 /** @var $years array */
 /** @var $months array */
 
+$this->registerJsFile('/js/motivation/index.js', ['position' => \yii\web\View::POS_END]);
+
 ?>
 
 <div class="motivationIndex m-5">
@@ -54,6 +56,10 @@ use yii\base\DynamicModel;
             <div class="d-flex justify-content-around align-items-center gap-2">
                 <div class="mb-3"><?= Html::submitButton('Применить', ['class' => 'btn btn-secondary btn-sm'])?></div>
             </div>
+            <div class="d-flex justify-content-around align-items-center gap-2">
+                <div class="mb-3"><?= Html::button('Загрузить плановых значений', ['class' => 'btn btn-success btn-sm',
+                        'onclick' => 'openUploadDictionary();'])?></div>
+            </div>
         </div>
     </div>
 
diff --git a/erp24/web/js/motivation/index.js b/erp24/web/js/motivation/index.js
new file mode 100644 (file)
index 0000000..6d2ea84
--- /dev/null
@@ -0,0 +1,53 @@
+/* jshint esversion: 8 */
+
+const param10 = $("meta[name=csrf-param]").attr("content");
+const token10 = $("meta[name=csrf-token]").attr("content");
+
+/* jshint unused: false */
+function openUploadDictionary() {
+    'use strict'
+    const $mainModal = $('#mainModal');
+    const $modalBody = $mainModal.find('.modal-body');
+    const $modalFooter = $mainModal.find('.modal-footer');
+    $mainModal.find('.close').on('click', () => { $mainModal.modal('hide'); });
+    $mainModal.find('.modal-title').html('Загрузка плановых значений');
+    $modalFooter.html('');
+    $modalBody.html('<div class="row"><div class="col-12"><form class="d-flex justify-content-left align-items-center" enctype="multipart/form-data"><div class="d-none"><input type="file" name="myfile" accept=".xlsx"/></div><div><input class="btn btn-success btn-sm" type="submit" value="Загрузить" /></div></form></div></div><div class="row"><div class="col-12" id="infoModal"</div>');
+    const browse = $modalBody.find('input[type=file]').get(0);
+    const btn = $modalBody.find('input[type=submit]').get(0);
+    const info = $modalBody.find('#infoModal').get(0);
+    const form = $modalBody.find('form').get(0);
+    async function UploadDict() {
+        const formData = new FormData(form);
+        formData.append(param10, token10);
+        try {
+            const response = await fetch("/motivation/index", {
+                method: "POST",
+                body: formData,
+            });
+            const text = await response.text();
+            if (text === 'not ok') {
+                info.innerHTML = '<span style="color:red">Не смог загрузить файл</span>';
+            } else if (text.replaceAll('<br>', '') === '') {
+                info.innerHTML = '<span style="color:green">Успешно загружен</span>';
+            } else {
+                info.innerHTML = '<span style="color:red">' + text + '</span>';
+            }
+        } catch (e) {
+            console.error(e);
+        }
+    }
+    browse.addEventListener('change', (event) => {
+        event.preventDefault();
+        event.stopPropagation();
+        UploadDict();
+    })
+
+    btn.addEventListener('click', (event) => {
+        event.preventDefault();
+        event.stopPropagation();
+        browse.click();
+    })
+
+    $mainModal.modal('show');
+}
\ No newline at end of file