From b50049eb670a9df711cde9e54967553965524473 Mon Sep 17 00:00:00 2001 From: Arsen Mirzaev Tatyano-Muradovich Date: Sun, 11 Apr 2021 04:08:09 +1000 Subject: [PATCH] =?UTF-8?q?=D0=92=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=BB=D0=BB=D0=B5=D1=80=20=D1=81=D0=BA=D0=BE=D0=BF=D0=B8=D0=BF?= =?UTF-8?q?=D0=B0=D1=81=D1=82=D0=B8=D0=BB=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C...=20=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/controllers/ProductController.php | 581 ++++++------------ mirzaev/skillparts/system/models/Product.php | 4 +- 2 files changed, 177 insertions(+), 408 deletions(-) diff --git a/mirzaev/skillparts/system/controllers/ProductController.php b/mirzaev/skillparts/system/controllers/ProductController.php index 0cccc41..83d0c0e 100644 --- a/mirzaev/skillparts/system/controllers/ProductController.php +++ b/mirzaev/skillparts/system/controllers/ProductController.php @@ -2,469 +2,238 @@ declare(strict_types=1); -namespace app\models; +namespace app\controllers; use yii; +use yii\filters\AccessControl; +use yii\web\Controller; +use yii\web\Response; +use yii\web\HttpException; use yii\web\UploadedFile; -use yii\imagine\Image; -use app\models\traits\SearchByEdge; -use Exception; -use moonland\phpexcel\Excel; +use app\models\Product; -/** - * Продукт (в ассортименте магазина) - * - * Представляет собой лот состоящий из предложений от поставщиков - * - * @see Supply Поставки для продуктов - */ -class Product extends Document +class ProductController extends Controller { - use SearchByEdge; - - /** - * Сценарий импорта .excel документа - * - * Использовать для обхода правил при загрузке файла - */ - const SCENARIO_IMPORT_EXCEL = 'import_excel'; - - /** - * Сценарий импорта изображений - * - * Использовать для обхода правил при загрузке файла - */ - const SCENARIO_IMPORT_IMAGE = 'import_image'; - - /** - * Сценарий записи товара - */ - const SCENARIO_WRITE = 'write'; - - /** - * Файл .excel для импорта товаров - */ - public Excel|string|array|null $file_excel = null; - - /** - * Изображение для импорта - */ - public UploadedFile|string|array|null $file_image = null; - - /** - * Группа в которой состоит товар - */ - public ProductGroup|null $group = null; - - /** - * Имя коллекции - */ - public static function collectionName(): string + public function actionIndex(string $catn): array|string|null { - return 'product'; + if ($model = Product::searchByCatn($catn)) { + // Товар найден + + if (yii::$app->request->isAjax) { + // AJAX-POST-запрос + + yii::$app->response->format = Response::FORMAT_JSON; + + return [ + 'main' => $this->renderPartial('index', compact('model')), + 'redirect' => '/product/' . $catn, + '_csrf' => yii::$app->request->getCsrfToken() + ]; + } + + return $this->render('index', compact('model')); + } else { + throw new HttpException(404); + } } - /** - * Свойства - */ - public function attributes(): array - { - return array_merge( - parent::attributes(), - [ - 'catn', - 'name', - // В библеотеке есть баг на название DESC (неизвестно в моей или нет) - 'dscr', - 'prod', - 'dmns', - 'imgs', - 'time' - ] - ); - } - - /** - * Метки свойств - */ - public function attributeLabels(): array - { - return array_merge( - parent::attributeLabels(), - [ - 'catn' => 'Каталожный номер (catn)', - 'name' => 'Название (name)', - 'dscr' => 'Описание (dscr)', - 'prod' => 'Производитель (prod)', - 'dmns' => 'Габариты (dmns)', - 'imgs' => 'Изображения (imgs)', - 'time' => 'Срок доставки (time)', - 'file_excel' => 'Документ (file_excel)', - 'file_image' => 'Изображение (file_image)', - 'group' => 'Группа (group)' - ] - ); - } - - /** - * Правила - */ - public function rules(): array - { - return array_merge( - parent::rules(), - [ - [ - 'catn', - 'required', - 'message' => 'Заполните поля: {attribute}', - 'on' => self::SCENARIO_WRITE, - 'except' => [self::SCENARIO_IMPORT_EXCEL, self::SCENARIO_IMPORT_IMAGE] - ], - [ - 'catn', - 'string', - 'message' => '{attribute} должен быть строкой' - ], - [ - 'imgs', - 'arrayValidator', - 'message' => '{attribute} должен быть массивом' - ], - [ - 'dmns', - 'arrayWithNumbersValidator', - 'message' => '{attribute} должен быть массивом и хранить циферные значения' - ], - [ - 'file_excel', - 'required', - 'message' => 'Заполните поля: {attribute}', - 'on' => self::SCENARIO_IMPORT_EXCEL - ], - [ - 'file_excel', - 'file', - 'skipOnEmpty' => false, - 'extensions' => 'xlsx', - 'checkExtensionByMimeType' => false, - 'maxFiles' => 5, - 'maxSize' => 1024 * 1024 * 30, - 'wrongExtension' => 'Разрешены только документы в формате: ".xlsx"', - 'message' => 'Проблема при чтении документа', - 'on' => self::SCENARIO_IMPORT_EXCEL - ], - [ - 'file_image', - 'required', - 'message' => 'Загрузите изображение', - 'on' => self::SCENARIO_IMPORT_IMAGE - ], - [ - 'file_image', - 'file', - 'skipOnEmpty' => false, - 'extensions' => ['jpg', 'jpeg', 'png', 'gif', 'webp'], - 'checkExtensionByMimeType' => true, - 'maxFiles' => 10, - 'maxSize' => 1024 * 1024 * 30, - 'wrongExtension' => 'Разрешены только изображения в формате: ".jpg", ".jpeg", ".png", ".gif", ".webp"', - 'message' => 'Проблема при загрузке изображения', - 'on' => self::SCENARIO_IMPORT_IMAGE - ] - ] - ); - } - - /** - * Запись пустого продукта - */ - public static function writeEmpty(string $catn): ?self + public function actionEditTitle(string $catn): array|string|null { // Инициализация - $model = new self; + $return = [ + '_csrf' => yii::$app->request->getCsrfToken() + ]; - // Настройки - $model->catn = $catn; + if (is_null($catn)) { + // Не получен артикул - // Запись - return $model->save() ? $model : null; - } + yii::$app->response->statusCode = 500; - /** - * Импорт изображений - * - * @return int Количество сохранённых изображений - */ - public function importImages(): int - { - // Инициализация - $amount = 0; + goto end; + } - if ($this->validate()) { - // Проверка пройдена + if ($model = Product::searchByCatn($catn)) { + // Товар найден - foreach ($this->file_image as $file) { - // Перебор обрабатываемых изображений + // Инициализация + $text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия'; - if (!file_exists(YII_PATH_PUBLIC . $catalog = '/img/products/' . $this->_key)) { - // Директория для изображений продукта не найдена + $model->name = $text; - if (!mkdir(YII_PATH_PUBLIC . $catalog, 0775, true)) { - // Не удалось записать директорию + if ($model->save()) { + // Товар обновлён - return false; - }; - } - - - if (!file_exists(YII_PATH_PUBLIC . $catalog_h150 = '/img/products/' . $this->_key . '/h150')) { - // Директория для обложек изображений продукта не найдена - - if (!mkdir(YII_PATH_PUBLIC . $catalog_h150, 0775, true)) { - // Не удалось записать директорию - - return false; - }; - } - - // Запись на сервер - $file->saveAs(YII_PATH_PUBLIC . $catalog . '/' . $file->baseName . '.' . $file->extension . '.original'); - - // Конвертация изображения для сохранения полного изображения - Image::resize(YII_PATH_PUBLIC . $catalog . '/' . $file->baseName . '.' . $file->extension . '.original', 800, 800) - ->save(YII_PATH_PUBLIC . $catalog . '/' . $file->baseName . '.' . $file->extension, ['quality' => 80]); - - // Конвертация изображения для сохранения обложки (150px) - Image::resize(YII_PATH_PUBLIC . $catalog . '/' . $file->baseName . '.' . $file->extension, 150, 150) - ->save(YII_PATH_PUBLIC . $catalog_h150 . '/' . $file->baseName . '.' . $file->extension, ['quality' => 80]); - - // Инициализация - $this->imgs ?? $this->imgs = []; - - // Запись в базу данных - $this->imgs = array_merge( - $this->imgs, - [[ - 'covr' => count($this->imgs) === 0 ? true : false, - 'orig' => $catalog . '/' . $file->baseName . '.' . $file->extension, - 'h150' => $catalog_h150 . '/' . $file->baseName . '.' . $file->extension - ]] - ); - - $this->scenario = self::SCENARIO_WRITE; - - if ($this->save()) { - // Изменения сохранены в базе данных - - // Постинкрементация счётчика - $amount++; - } + $return['name'] = $text; } } - if ($this->hasErrors()) { - // Получены ошибки + /** + * Конец алгоритма + */ + end: - foreach ($this->getErrors() as $attribute => $errors) { - // Перебор атрибутов + if (yii::$app->request->isPost) { + // POST-запрос - foreach ($errors as $error) { - // Перебор ошибок атрибутов + yii::$app->response->format = Response::FORMAT_JSON; - $label = $this->getAttributeLabel($attribute); + return $return; + } - Notification::_write("$label: $error", type: Notification::TYPE_ERROR); - } + if ($model = Product::searchByCatn($catn)) { + return $this->render('index', compact('model')); + } else { + return $this->redirect('/'); + } + } + + public function actionEditCatn(string $catn): array|string|null + { + // Инициализация + $return = [ + '_csrf' => yii::$app->request->getCsrfToken() + ]; + + if (is_null($catn)) { + // Не получен артикул + + yii::$app->response->statusCode = 500; + + goto end; + } + + if ($model = Product::searchByCatn($catn)) { + // Товар найден + + // Инициализация + $text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия'; + + $model->catn = $text; + + if ($model->save()) { + // Товар обновлён + + $return['main'] = $this->renderPartial('index', compact('model')); } } - return $amount; + /** + * Конец алгоритма + */ + end: + + if (yii::$app->request->isPost) { + // POST-запрос + + yii::$app->response->format = Response::FORMAT_JSON; + + return $return; + } + + if ($model = Product::searchByCatn($catn)) { + return $this->render('index', compact('model')); + } else { + return $this->redirect('/'); + } } - /** - * Импорт товаров - * - * На данный момент обрабатывает только импорт из - * файлов с расширением .excel - */ - public function importExcel(): bool + public function actionEditDesc(string $catn): array|string|null { // Инициализация - $data = []; - $amount = 0; + $return = [ + '_csrf' => yii::$app->request->getCsrfToken() + ]; - if ($this->validate()) { - foreach ($this->file_excel as $file) { - // Перебор файлов + if (is_null($catn)) { + // Не получен артикул - // Инициализация - $dir = '../assets/import/' . date('Y_m_d#H-i', time()) . '/excel/'; + yii::$app->response->statusCode = 500; - // Сохранение на диск - if (!file_exists($dir)) { - mkdir($dir, 0775, true); - } - $file->saveAs($path = $dir . $file->baseName . '.' . $file->extension); + goto end; + } - $data[] = Excel::import($path, [ - 'setFirstRecordAsKeys' => true, - 'setIndexSheetByName' => true, - ]); + if ($product = Product::searchByCatn($catn)) { + // Товар найден + + // Инициализация + $text = yii::$app->request->get('text') ?? yii::$app->request->post('text') ?? 'Без названия'; + + $product->desc = $text; + + if ($product->save()) { + // Товар обновлён + + $return['description'] = $text; } + } + /** + * Конец алгоритма + */ + end: - foreach ($data as $data) { - // Перебор конвертированных файлов + if (yii::$app->request->isPost) { + // POST-запрос - if (count($data) < 1) { - // Не найдены строки с товарами + yii::$app->response->format = Response::FORMAT_JSON; - $this->addError('erros', 'Не удалось найти данные товаров'); - } else { - // Перебор найденных товаров + return $return; + } - foreach ($data as $doc) { - // Перебор полученных документов + if ($model = Product::searchByCatn($catn)) { + return $this->render('index', compact('model')); + } else { + return $this->redirect('/'); + } + } - // Сохранение в базе данных - $product = new static($doc); + public function actionWriteImage(string $catn): array|string|null + { + // Инициализация + $return = [ + '_csrf' => yii::$app->request->getCsrfToken() + ]; - $product->scenario = $product::SCENARIO_WRITE; + if (is_null($catn)) { + // Не получен артикул - if ($product->validate()) { - // Проверка пройдена + yii::$app->response->statusCode = 500; - // Запись документа - $product->save(); + goto end; + } - // Постинкрементация счётчика - $amount++; + if ($model = Product::searchByCatn($catn)) { + // Товар найден - // Запись группы - // $group = static::class . 'Group'; - // (new $group())->writeMember($product, $this->group); - } else { - // Проверка не пройдена - foreach ($product->errors as $attribute => $error) { - $this->addError($attribute, $error); - } - } - } - } + // Инициализация + $model->file_image = UploadedFile::getInstancesByName('images'); + $model->scenario = $model::SCENARIO_IMPORT_IMAGE; + + if ($model->importImages() > 0) { + // Товар обновлён + + $return['main'] = $this->renderPartial('index', compact('model')); } - - // Деинициализация - $this->file_excel = ''; - - static::afterImportExcel($amount); - - return true; } - $this->addError('erros', 'Неизвестная ошибка'); + /** + * Конец алгоритма + */ + end: - static::afterImportExcel($amount); + if (yii::$app->request->isPost) { + // POST-запрос - return false; - } + yii::$app->response->format = Response::FORMAT_JSON; - /** - * Поиск по каталожному номеру - * - * Ищет продукт и возвращает его, - * либо выполняет поиск через представление - * - * @todo Переделать нормально - */ - public static function searchByCatn(string $catn, int $limit = 1, array $select = []): static|array|null - { - if ($limit <= 1) { - return static::findOne(['catn' => $catn]); + return $return; } - $query = self::find() - ->where(['catn' => $catn]) - ->limit($limit) - ->select($select) - ->createCommand() - ->execute() - ->getAll(); - - foreach ($query as &$attribute) { - // Приведение всех свойств в массив и очистка от лишних данных - - $attribute = $attribute->getAll(); + if ($model = Product::searchByCatn($catn)) { + return $this->render('index', compact('model')); + } else { + return $this->redirect('/'); } - - return $query; - } - - /** - * Поиск по каталожному номеру (через представления) - * - * Ищет продукт и возвращает его, - * либо выполняет поиск через представление - * - * @todo Переделать нормально - */ - public static function searchByPartialCatn(string $catn, int $limit = 1, array $select = []): static|array|null - { - $query = self::find() - ->for('product') - ->in('product_search') - ->search(['catn' => $catn]) - ->limit($limit) - ->select($select) - ->createCommand() - ->execute() - ->getAll(); - - foreach ($query as &$attribute) { - // Приведение всех свойств в массив и очистка от лишних данных - - $attribute = $attribute->getAll(); - } - - return $query; - } - - /** - * Вызывается после загрузки поставок из excel-документа - * - * @param int $amount Количество - */ - public static function afterImportExcel(int $amount = 0): bool - { - // Инициализация - $model = new Notification; - $date = date('H:i d.m.Y', time()); - - // Настройка - $model->text = yii::$app->controller->renderPartial('/notification/system/afterImportExcel', compact('amount', 'date')); - $model->type = $model::TYPE_NOTICE; - - // Отправка - return (bool) $model->write(); - } - - /** - * Вызывается после загрузки поставок из 1С - * - * @param int $amount Количество - */ - public static function afterImport1c(): bool - { - // Инициализация - $model = new Notification; - $date = date('H:i d.m.Y', time()); - - // Настройка - $model->text = yii::$app->controller->renderPartial('/notification/system/afterImport1c', compact('amount', 'date')); - $model->type = $model::TYPE_NOTICE; - - // Отправка - return (bool) $model->write(); } } diff --git a/mirzaev/skillparts/system/models/Product.php b/mirzaev/skillparts/system/models/Product.php index cf0fd02..0cccc41 100644 --- a/mirzaev/skillparts/system/models/Product.php +++ b/mirzaev/skillparts/system/models/Product.php @@ -454,14 +454,14 @@ class Product extends Document * * @param int $amount Количество */ - public static function afterImportOnec(): bool + public static function afterImport1c(): bool { // Инициализация $model = new Notification; $date = date('H:i d.m.Y', time()); // Настройка - $model->text = yii::$app->controller->renderPartial('/notification/system/afterImportOnec', compact('amount', 'date')); + $model->text = yii::$app->controller->renderPartial('/notification/system/afterImport1c', compact('amount', 'date')); $model->type = $model::TYPE_NOTICE; // Отправка