From 48794a894a1c7d5b2f5299ced8b4363c77fecca9 Mon Sep 17 00:00:00 2001 From: Alexander Smirnov Date: Fri, 4 Apr 2025 14:36:59 +0300 Subject: [PATCH] [ERP-396] product replacement import from excel --- .../crud/Product1cReplacementController.php | 17 ++++ .../services/Product1cReplacementService.php | 83 +++++++++++++++++ .../crud/product1c-replacement/index.php | 4 +- .../web/js/crud/product1cReplacement/index.js | 90 +++++++++++++++++++ 4 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 erp24/services/Product1cReplacementService.php create mode 100644 erp24/web/js/crud/product1cReplacement/index.js diff --git a/erp24/controllers/crud/Product1cReplacementController.php b/erp24/controllers/crud/Product1cReplacementController.php index 0d1d5663..e19e3514 100644 --- a/erp24/controllers/crud/Product1cReplacementController.php +++ b/erp24/controllers/crud/Product1cReplacementController.php @@ -5,6 +5,7 @@ namespace yii_app\controllers\crud; use Yii; use yii\behaviors\TimestampBehavior; use yii\data\ActiveDataProvider; +use yii\web\UploadedFile; use yii_app\records\Admin; use yii_app\records\Prices; use yii_app\records\Product1cReplacement; @@ -14,6 +15,7 @@ use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; use yii_app\records\Products1c; +use yii_app\services\Product1cReplacementService; /** * Product1CReplacementController implements the CRUD actions for Product1CReplacement model. @@ -52,6 +54,21 @@ class Product1cReplacementController extends Controller */ public function actionIndex() { + if (Yii::$app->request->isPost) { + $file = UploadedFile::getInstanceByName('myfile'); + if ($file) { + $fileName = '/template_replacement_temp.xlsx'; + $path1 = Yii::getAlias('@uploads') . $fileName; + $file->saveAs($path1); + + $data = Product1cReplacementService::uploadTemplateReplacement($path1); + + return implode('
', $data['errors']); + } else { + return 'not ok'; + } + } + $searchModel = new Product1cReplacementSearch(); $dataProvider = $searchModel->search($this->request->queryParams); diff --git a/erp24/services/Product1cReplacementService.php b/erp24/services/Product1cReplacementService.php new file mode 100644 index 00000000..31dc13e7 --- /dev/null +++ b/erp24/services/Product1cReplacementService.php @@ -0,0 +1,83 @@ +where(['like', 'name', $name, false])->one(); + if ($product1c) { + return $product1c->id; + } + preg_match('/\(\d+\)/', $name, $m); + if ($m) { + $articule = trim($m[0], '()'); + $product1c = Products1c::find()->where(['articule' => $articule])->one(); + return $product1c ? $product1c->id : null; + } + return null; + } + + public static function uploadTemplateReplacement($path) { + try { + $spreadsheets = IOFactory::load($path); + } catch (\Exception $ex) { + return ['errors' => ['Некорректный файл. Загрузите файл, заполненный по шаблону.']]; + } + $errors = []; + $spreadSheet = $spreadsheets->getAllSheets()[0]; + foreach ($spreadSheet->getRowIterator() as $ind => $spreadSheetRow) { + $row = []; + foreach ($spreadSheetRow->getCellIterator() as $indColumn => $spreadSheetRowCell) { + if ($indColumn == "C") { + break; + } + $row[] = $spreadSheetRowCell->getValue(); + } + if (!empty($row[0]) && mb_strlen($row[0]) > 3 && !empty($row[1]) && mb_strlen($row[1]) > 3) { + $name = trim($row[0]); + $replacementNames = array_filter(array_map('self::filterKeyWords', array_map('trim', explode(';', $row[1])))); + if (count($replacementNames) > 0) { + $productGuid = self::getGuidFromName($name); + $replacementGuids = []; + if ($productGuid) { + foreach ($replacementNames as $r) { + $repGuid = self::getGuidFromName($r); + if ($repGuid) { + $replacementGuids []= $repGuid; + $rep = Product1cReplacement::find()->where(['guid' => $productGuid, 'guid_replacement' => $repGuid])->one(); + if (!$rep) { + $rep = new Product1cReplacement; + $rep->guid = $productGuid; + $rep->guid_replacement = $repGuid; + $rep->created_at = date('Y-m-d H:i:s'); + $rep->save(); + if ($rep->getErrors()) { + $errors [] = Json::encode($rep->getErrors()); + } + } + } else { + $errors [] = "Не могу найти гуид для $r"; + } + } + } else { + $errors [] = "Не могу найти гуид для $name"; + } + } + } + } + return compact('errors'); + } +} \ No newline at end of file diff --git a/erp24/views/crud/product1c-replacement/index.php b/erp24/views/crud/product1c-replacement/index.php index f298a46d..967e1170 100644 --- a/erp24/views/crud/product1c-replacement/index.php +++ b/erp24/views/crud/product1c-replacement/index.php @@ -16,6 +16,7 @@ use yii_app\records\Products1c; $this->title = 'Возможные замены номенклатуры'; $this->params['breadcrumbs'][] = $this->title; +$this->registerJsFile('/js/crud/product1cReplacement/index.js', ['position' => \yii\web\View::POS_END]); ?>
@@ -23,7 +24,8 @@ $this->params['breadcrumbs'][] = $this->title;

title) ?>

- 'btn btn-success']) ?> + 'btn btn-success']) ?>    + 'btn btn-secondary btn-sm', 'onclick' => 'openUploadReplacement();']) ?>

diff --git a/erp24/web/js/crud/product1cReplacement/index.js b/erp24/web/js/crud/product1cReplacement/index.js new file mode 100644 index 00000000..41bb5ad7 --- /dev/null +++ b/erp24/web/js/crud/product1cReplacement/index.js @@ -0,0 +1,90 @@ +/* jshint esversion: 6 */ + +const param32 = $("meta[name=csrf-param]").attr("content"); +const token32 = $("meta[name=csrf-token]").attr("content"); + +function openUploadReplacement() { + const $mainModal = $('#mainModal'); + const $modalBody = $mainModal.find('.modal-body'); + const $modalTitle = $mainModal.find('.modal-title'); + + $mainModal.find('.close').on('click', () => { $mainModal.modal('hide'); }); + + let title = 'Загрузка замен'; + let downloadLink = '/files/download?url=/uploads/template_product1cReplacement.xlsx'; + let linkText = 'Шаблон. Загрузка замен'; + + $modalTitle.html(title); + + $modalBody.html(` +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Скачать шаблон
+
+
+ +
+ `); + + 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() { + info.innerHTML = 'загрузка...'; + if (browse.files[0].size > 200000) { + info.innerHTML = 'Некорректный файл. Слишком большой. Загрузите файл, заполненный по шаблону.'; + return; + } + const formData = new FormData(form); + formData.append(param32, token32); + + try { + const response = await fetch("/crud/product1c-replacement/index", { + method: "POST", + body: formData, + }); + const text = await response.text(); + console.log(text) + if (text === 'not ok') { + info.innerHTML = 'Не смог загрузить файл'; + } else if (text.replaceAll('
', '') === '') { + info.innerHTML = 'Успешно загружен'; + } else { + info.innerHTML = '' + text + ''; + } + } 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'); +} -- 2.39.5