diff --git a/.gitignore b/.gitignore
index 3a3b256..3493d07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
/vendor
-/cache
\ No newline at end of file
+/cache
+/.vscode
\ No newline at end of file
diff --git a/composer.json b/composer.json
index b91d853..42bd93c 100644
--- a/composer.json
+++ b/composer.json
@@ -24,8 +24,7 @@
"triagens/arangodb": "^3.6",
"moonlandsoft/yii2-phpexcel": ">=2.0",
"carono/yii2-1c-exchange": "^0.3.1",
- "mirzaev/yii2-arangodb": "~2.1.x-dev",
- "mirzaev/yii2-arangodb-sessions": "~1.0.0"
+ "yiisoft/yii2-imagine": "*"
},
"require-dev": {
"codeception/codeception": ">=4.1",
@@ -42,7 +41,9 @@
},
"autoload": {
"psr-4": {
- "mirzaev\\skillparts\\": "mirzaev/skillparts/system"
+ "mirzaev\\skillparts\\": "mirzaev/skillparts/system",
+ "mirzaev\\yii2\\arangodb\\": "../yii2-arangodb/mirzaev/yii2/arangodb",
+ "mirzaev\\yii2\\arangodb\\sessions\\": "../yii2-arangodb-sessions/mirzaev/yii2/arangodb/sessions"
}
},
"autoload-dev": {
diff --git a/composer.lock b/composer.lock
index 0025dae..e30579c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "116946ecdb84687a081d5633fd8505f6",
+ "content-hash": "77be6b3a5d18070b9d685430060a770e",
"packages": [
{
"name": "bower-asset/bootstrap",
@@ -471,6 +471,68 @@
},
"time": "2020-06-29T00:56:53+00:00"
},
+ {
+ "name": "imagine/imagine",
+ "version": "1.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/avalanche123/Imagine.git",
+ "reference": "d2e18be6e930ca169e4f921ef73ebfc061bf55d8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/d2e18be6e930ca169e4f921ef73ebfc061bf55d8",
+ "reference": "d2e18be6e930ca169e4f921ef73ebfc061bf55d8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.2",
+ "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4 || ^9.3"
+ },
+ "suggest": {
+ "ext-gd": "to use the GD implementation",
+ "ext-gmagick": "to use the Gmagick implementation",
+ "ext-imagick": "to use the Imagick implementation"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-develop": "0.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Imagine\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bulat Shakirzyanov",
+ "email": "mallluhuct@gmail.com",
+ "homepage": "http://avalanche123.com"
+ }
+ ],
+ "description": "Image processing for PHP 5.3",
+ "homepage": "http://imagine.readthedocs.org/",
+ "keywords": [
+ "drawing",
+ "graphics",
+ "image manipulation",
+ "image processing"
+ ],
+ "support": {
+ "issues": "https://github.com/avalanche123/Imagine/issues",
+ "source": "https://github.com/avalanche123/Imagine/tree/1.2.4"
+ },
+ "time": "2020-11-03T22:35:03+00:00"
+ },
{
"name": "maennchen/zipstream-php",
"version": "2.1.0",
@@ -2019,6 +2081,89 @@
],
"time": "2020-06-24T00:04:01+00:00"
},
+ {
+ "name": "yiisoft/yii2-imagine",
+ "version": "2.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-imagine.git",
+ "reference": "b103b1b1deb786d4d5fe955898ec866dbee5c1b4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-imagine/zipball/b103b1b1deb786d4d5fe955898ec866dbee5c1b4",
+ "reference": "b103b1b1deb786d4d5fe955898ec866dbee5c1b4",
+ "shasum": ""
+ },
+ "require": {
+ "imagine/imagine": "^1.0",
+ "yiisoft/yii2": "~2.0.0"
+ },
+ "require-dev": {
+ "cweagans/composer-patches": "^1.7",
+ "phpunit/phpunit": "4.8.34"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ },
+ "composer-exit-on-patch-failure": true,
+ "patches": {
+ "phpunit/phpunit-mock-objects": {
+ "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
+ },
+ "phpunit/phpunit": {
+ "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
+ "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "yii\\imagine\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Antonio Ramirez",
+ "email": "amigo.cobos@gmail.com"
+ }
+ ],
+ "description": "The Imagine integration for the Yii framework",
+ "keywords": [
+ "helper",
+ "image",
+ "imagine",
+ "yii2"
+ ],
+ "support": {
+ "forum": "http://www.yiiframework.com/forum/",
+ "irc": "irc://irc.freenode.net/yii",
+ "issues": "https://github.com/yiisoft/yii2-imagine/issues",
+ "source": "https://github.com/yiisoft/yii2-imagine",
+ "wiki": "http://www.yiiframework.com/wiki/"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/yiisoft",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/yiisoft",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-imagine",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-12-23T17:16:36+00:00"
+ },
{
"name": "yiisoft/yii2-swiftmailer",
"version": "2.1.2",
diff --git a/mirzaev/skillparts/system/config/web.php.example b/mirzaev/skillparts/system/config/web.php.example
index 251c418..66411fa 100644
--- a/mirzaev/skillparts/system/config/web.php.example
+++ b/mirzaev/skillparts/system/config/web.php.example
@@ -19,16 +19,27 @@ $config = [
'class' => 'yii\caching\FileCache',
],
'user' => [
- 'identityClass' => 'app\models\Account',
+ 'identityClass' => 'app\models\Account',
'loginUrl' => ['/authentication'],
- 'enableAutoLogin' => true
+ 'enableAutoLogin' => true,
+ 'enableSession' => true
+ ],
+ 'session' => [
+ 'class' => 'mirzaev\yii2\arangodb\sessions\ArangoDbSession',
+ 'document' => 'session',
+ 'cookieParams' => [
+ // 'lifetime' => 3600 * 24 * 30 * 12
+ 'lifetime' => 3600 * 24 * 3
+ ],
+ 'writeCallback' => function($session) {
+ return [
+ 'account' => Yii::$app->user->id,
+ 'ip' => yii::$app->request->userIP
+ ];
+ },
+ 'timeout' => 3600 * 24 * 3,
+ 'useCookies' => true,
],
- // 'session' => [
- // 'class' => 'yii\web\Session',
- // 'cookieParams' => ['lifetime' => 3600 * 24 * 30 * 12],
- // 'timeout' => 3600 * 24 * 30 * 12,
- // 'useCookies' => true,
- // ],
'errorHandler' => [
'errorAction' => 'error',
],
diff --git a/mirzaev/skillparts/system/controllers/AuthenticationController.php b/mirzaev/skillparts/system/controllers/AuthenticationController.php
index 9d4292c..ce388f9 100644
--- a/mirzaev/skillparts/system/controllers/AuthenticationController.php
+++ b/mirzaev/skillparts/system/controllers/AuthenticationController.php
@@ -48,7 +48,7 @@ class AuthenticationController extends Controller
// Аккаунт аутентифицирован
// Создание сессии
- yii::$app->session->open();
+ // yii::$app->session->open();
// Инициализация
$notifications_button = $this->renderPartial('/notification/button');
diff --git a/mirzaev/skillparts/system/controllers/DeauthenticationController.php b/mirzaev/skillparts/system/controllers/DeauthenticationController.php
index a82c7e5..95b3565 100644
--- a/mirzaev/skillparts/system/controllers/DeauthenticationController.php
+++ b/mirzaev/skillparts/system/controllers/DeauthenticationController.php
@@ -37,11 +37,13 @@ class DeauthenticationController extends Controller
// Инициализация
yii::$app->response->format = Response::FORMAT_JSON;
+ // Удаление сессии
+ yii::$app->session['status'] = 'inactive';
+ // yii::$app->session->close();
+
// Выход из аккаунта
yii::$app->user->logout();
- // Удаление сессии
- yii::$app->session->destroy();
// Инициализация
$model = new AccountForm(yii::$app->request->post('AccountForm') ?? yii::$app->request->get('AccountForm') ?? null);
diff --git a/mirzaev/skillparts/system/controllers/NotificationController.php b/mirzaev/skillparts/system/controllers/NotificationController.php
index 827acba..ebbd6ca 100644
--- a/mirzaev/skillparts/system/controllers/NotificationController.php
+++ b/mirzaev/skillparts/system/controllers/NotificationController.php
@@ -19,11 +19,11 @@ class NotificationController extends Controller
return [
'access' => [
'class' => AccessControl::class,
- 'only' => ['index'],
'rules' => [
[
'allow' => true,
- 'roles' => ['@']
+ 'roles' => ['@'],
+ 'actions' => ['index']
]
]
]
@@ -35,8 +35,6 @@ class NotificationController extends Controller
*/
public function actionIndex()
{
- var_dump(yii::$app->session->id);
-
if (yii::$app->request->isPost) {
// POST-запрос
diff --git a/mirzaev/skillparts/system/controllers/OrderController.php b/mirzaev/skillparts/system/controllers/OrderController.php
index 76616eb..47f25c1 100644
--- a/mirzaev/skillparts/system/controllers/OrderController.php
+++ b/mirzaev/skillparts/system/controllers/OrderController.php
@@ -20,17 +20,52 @@ class OrderController extends Controller
return [
'access' => [
'class' => AccessControl::class,
- 'only' => ['index'],
'rules' => [
[
'allow' => true,
- 'roles' => ['@']
+ 'roles' => ['@'],
+ 'actions' => ['index', 'write', 'delete', 'amount-update', 'pay']
+ ],
+ [
+ 'allow' => false,
+ 'roles' => ['?'],
+ 'denyCallback' => [$this, 'accessDenied']
]
]
]
];
}
+ public function accessDenied()
+ {
+ // Инициализация
+ $cookies = yii::$app->response->cookies;
+
+ // Запись cookie с редиректом, который выполнится после авторизации
+ $cookies->add(new Cookie([
+ 'name' => 'redirect',
+ 'value' => yii::$app->request->pathInfo
+ ]));
+
+ if (Yii::$app->request->isPost) {
+ // POST-запрос
+
+ // Настройка
+ Yii::$app->response->format = Response::FORMAT_JSON;
+
+ // Генерация ответа
+ Yii::$app->response->content = json_encode([
+ 'main' => $this->renderPartial('/orders/index'),
+ 'redirect' => '/authentication',
+ '_csrf' => Yii::$app->request->getCsrfToken()
+ ]);
+ } else if (Yii::$app->request->isGet) {
+ // GET-запрос
+
+ $this->redirect('/authentication');
+ }
+ }
+
public function actionIndex()
{
// Инициализация
diff --git a/mirzaev/skillparts/system/controllers/ProductController.php b/mirzaev/skillparts/system/controllers/ProductController.php
index 3c3f531..83d0c0e 100644
--- a/mirzaev/skillparts/system/controllers/ProductController.php
+++ b/mirzaev/skillparts/system/controllers/ProductController.php
@@ -4,56 +4,31 @@ declare(strict_types=1);
namespace app\controllers;
-use Yii;
+use yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\Response;
use yii\web\HttpException;
+use yii\web\UploadedFile;
use app\models\Product;
class ProductController extends Controller
{
- // /**
- // * {@inheritdoc}
- // */
- // public function behaviors()
- // {
- // return [
- // 'access' => [
- // 'class' => AccessControl::class,
- // 'rules' => [
- // [
- // 'allow' => true,
- // 'actions' => ['index'],
- // 'roles' => ['@']
- // ],
- // [
- // 'allow' => false,
- // 'roles' => ['?']
- // ],
- // ]
- // ]
- // ];
- // }
-
- public function actionIndex(string $catn)
+ public function actionIndex(string $catn): array|string|null
{
if ($model = Product::searchByCatn($catn)) {
// Товар найден
- // Инициализация
- $model = $model->getAttributes();
-
- if (Yii::$app->request->isAjax) {
+ if (yii::$app->request->isAjax) {
// AJAX-POST-запрос
- Yii::$app->response->format = Response::FORMAT_JSON;
+ yii::$app->response->format = Response::FORMAT_JSON;
return [
'main' => $this->renderPartial('index', compact('model')),
'redirect' => '/product/' . $catn,
- '_csrf' => Yii::$app->request->getCsrfToken()
+ '_csrf' => yii::$app->request->getCsrfToken()
];
}
@@ -62,4 +37,203 @@ class ProductController extends Controller
throw new HttpException(404);
}
}
+
+ public function actionEditTitle(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->name = $text;
+
+ if ($model->save()) {
+ // Товар обновлён
+
+ $return['name'] = $text;
+ }
+ }
+
+ /**
+ * Конец алгоритма
+ */
+ 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('/');
+ }
+ }
+
+ 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'));
+ }
+ }
+
+ /**
+ * Конец алгоритма
+ */
+ 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('/');
+ }
+ }
+
+ public function actionEditDesc(string $catn): array|string|null
+ {
+ // Инициализация
+ $return = [
+ '_csrf' => yii::$app->request->getCsrfToken()
+ ];
+
+ if (is_null($catn)) {
+ // Не получен артикул
+
+ yii::$app->response->statusCode = 500;
+
+ goto end;
+ }
+
+ 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:
+
+ 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('/');
+ }
+ }
+
+ public function actionWriteImage(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)) {
+ // Товар найден
+
+ // Инициализация
+ $model->file_image = UploadedFile::getInstancesByName('images');
+ $model->scenario = $model::SCENARIO_IMPORT_IMAGE;
+
+ if ($model->importImages() > 0) {
+ // Товар обновлён
+
+ $return['main'] = $this->renderPartial('index', compact('model'));
+ }
+ }
+
+ /**
+ * Конец алгоритма
+ */
+ 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('/');
+ }
+ }
}
diff --git a/mirzaev/skillparts/system/controllers/ProfileController.php b/mirzaev/skillparts/system/controllers/ProfileController.php
index 5eff1ba..3b5491f 100644
--- a/mirzaev/skillparts/system/controllers/ProfileController.php
+++ b/mirzaev/skillparts/system/controllers/ProfileController.php
@@ -29,7 +29,7 @@ class ProfileController extends Controller
[
'allow' => true,
'roles' => ['@'],
- 'actions' => ['index', 'supplies', 'import', 'monitoring', 'readGroups'],
+ 'actions' => ['index', 'supplies', 'import', 'monitoring', 'readGroups']
],
[
'allow' => false,
@@ -38,9 +38,16 @@ class ProfileController extends Controller
],
[
'allow' => true,
- 'actions' => ['trusted', 'trusted-notification-write'],
- 'matchCallback' => function ($rule, $action) {
- return yii::$app->user->identity->trst;
+ 'actions' => ['panel', 'panel-notification-write'],
+ 'matchCallback' => function ($rule, $action): bool {
+ if (
+ yii::$app->user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+ ) {
+ return true;
+ }
+
+ return false;
}
]
]
@@ -140,7 +147,7 @@ class ProfileController extends Controller
/**
* Страница панели управления для доверенных пользователей
*/
- public function actionTrusted(): string|array
+ public function actionPanel(): string|array
{
// Инициализация
$model_notifications = null;
@@ -196,18 +203,18 @@ class ProfileController extends Controller
yii::$app->response->format = Response::FORMAT_JSON;
return [
- 'main' => $this->renderPartial('trusted', compact(
+ 'main' => $this->renderPartial('panel', compact(
'model_notifications',
'model_settings',
'sidebar',
'panel'
)),
- 'redirect' => '/profile/trusted',
+ 'redirect' => '/profile/panel',
'_csrf' => yii::$app->request->getCsrfToken()
];
}
- return $this->render('trusted', compact(
+ return $this->render('panel', compact(
'model_notifications',
'model_settings',
'sidebar',
@@ -348,9 +355,10 @@ class ProfileController extends Controller
*/
public function actionImport()
{
+ var_dump($_FILES);
// Инициализация
$model = new Supply(yii::$app->request->post('Supply') ?? yii::$app->request->get('Supply'));
- $model->scenario = $model::SCENARIO_IMPORT;
+ $model->scenario = $model::SCENARIO_IMPORT_EXCEL;
$panel = yii::$app->request->post('panel') ?? yii::$app->request->get('panel');
$sidebar = $this->renderPartial('sidebar');
$groups = self::readGroups();
@@ -360,9 +368,9 @@ class ProfileController extends Controller
yii::$app->response->format = Response::FORMAT_JSON;
- $model->file = UploadedFile::getInstances($model, 'file');
+ $model->file_excel = UploadedFile::getInstances($model, 'file_excel');
- if ($model->import()) {
+ if ($model->importExcel()) {
return [
'main' => $this->renderPartial('supplies', compact(
'model',
diff --git a/mirzaev/skillparts/system/controllers/SearchController.php b/mirzaev/skillparts/system/controllers/SearchController.php
index d89e4ff..6796777 100644
--- a/mirzaev/skillparts/system/controllers/SearchController.php
+++ b/mirzaev/skillparts/system/controllers/SearchController.php
@@ -51,7 +51,6 @@ class SearchController extends Controller
// Инициализация сессии
$session = yii::$app->session;
- $session->open();
// Инициализация ответа
$response = null;
@@ -129,7 +128,7 @@ class SearchController extends Controller
$limit = yii::$app->request->isPost ? 10 : 20;
- if ($response = Product::searchByCatn($query, $limit, ['catn' => 'catn', '_key' => '_key'])) {
+ if ($response = Product::searchByPartialCatn($query, $limit, ['catn' => 'catn', '_key' => '_key'])) {
// Данные найдены по поиску в полях Каталожного номера
foreach ($response as &$row) {
diff --git a/mirzaev/skillparts/system/models/Account.php b/mirzaev/skillparts/system/models/Account.php
index c7b43fe..3d6a4d6 100644
--- a/mirzaev/skillparts/system/models/Account.php
+++ b/mirzaev/skillparts/system/models/Account.php
@@ -42,7 +42,8 @@ class Account extends Document implements IdentityInterface, PartnerInterface
'taxn',
'onec',
'opts',
- 'trst'
+ 'agnt',
+ 'type'
]
);
}
@@ -65,7 +66,8 @@ class Account extends Document implements IdentityInterface, PartnerInterface
'taxn' => 'ИНН',
'onec' => 'Данные 1C',
'opts' => 'Параметры',
- 'trst' => 'Доверенный пользователь'
+ 'agnt' => 'Агент (поставщик)',
+ 'type' => 'Тип аккаунта'
]
);
}
diff --git a/mirzaev/skillparts/system/models/AccountForm.php b/mirzaev/skillparts/system/models/AccountForm.php
index bcd473d..c4bc15e 100644
--- a/mirzaev/skillparts/system/models/AccountForm.php
+++ b/mirzaev/skillparts/system/models/AccountForm.php
@@ -23,7 +23,7 @@ class AccountForm extends Model
public $mail;
public $pswd;
- public $auto = true;
+ public $auto = false;
private $account = false;
diff --git a/mirzaev/skillparts/system/models/Document.php b/mirzaev/skillparts/system/models/Document.php
index 8d0c1e1..fc46b3f 100644
--- a/mirzaev/skillparts/system/models/Document.php
+++ b/mirzaev/skillparts/system/models/Document.php
@@ -67,11 +67,14 @@ abstract class Document extends ActiveRecord
if (parent::beforeSave($data)) {
if ($this->isNewRecord) {
// Запись в журнал
- $this->jrnl = [[
- 'date' => time(),
- 'account' => yii::$app->user->id,
- 'action' => 'create'
- ]];
+ $this->jrnl = array_merge(
+ [[
+ 'date' => time(),
+ 'account' => yii::$app->user->id,
+ 'action' => 'create'
+ ]],
+ $this->jrnl ?? []
+ );
}
return true;
@@ -92,7 +95,10 @@ abstract class Document extends ActiveRecord
public function journal(string $action = 'update', array ...$data): int|bool
{
// Инициализация
- is_array($this->jrnl) or $this->jrnl = [];
+ if (isset($this->jrnl) && is_array($this->jrnl)) {
+ } else {
+ $this->jrnl = [];
+ }
// Генерация
$this->jrnl = array_merge(
@@ -108,7 +114,7 @@ abstract class Document extends ActiveRecord
);
// Запись и возврат
- return $this->save() ? $time : false;
+ return $this->update() ? $time : false;
}
/**
diff --git a/mirzaev/skillparts/system/models/Edge.php b/mirzaev/skillparts/system/models/Edge.php
index fa10d2a..a88cfa7 100644
--- a/mirzaev/skillparts/system/models/Edge.php
+++ b/mirzaev/skillparts/system/models/Edge.php
@@ -118,16 +118,7 @@ abstract class Edge extends Document
}
}
- if ($edge->save()) {
- // Записано в базу данных
-
- // Запись в журнал
- $edge->journal('create');
-
- return $edge;
- }
-
- return null;
+ return $edge->save() ? $edge : null;
}
/**
diff --git a/mirzaev/skillparts/system/models/Notification.php b/mirzaev/skillparts/system/models/Notification.php
index 874700f..bd22f71 100644
--- a/mirzaev/skillparts/system/models/Notification.php
+++ b/mirzaev/skillparts/system/models/Notification.php
@@ -45,7 +45,7 @@ class Notification extends Document
*
* @see SCENARIO_TRUSTED_CREATE
*/
- public string $account;
+ public string|null $account;
/**
* Текст уведомления
diff --git a/mirzaev/skillparts/system/models/Order.php b/mirzaev/skillparts/system/models/Order.php
index 30f20c6..2779396 100644
--- a/mirzaev/skillparts/system/models/Order.php
+++ b/mirzaev/skillparts/system/models/Order.php
@@ -146,8 +146,6 @@ class Order extends Document
if (!$supply_model = Supply::searchByCatn($supply_raw) or !OrderEdgeSupply::write($this->readId(), $supply_model->readId(), 'write')) {
// Поставка не найдена или запись ребра не удалась
- var_dump('ПИЗДА');
-
continue;
} else {
// Ребро создано (товар подключен к заказу)
diff --git a/mirzaev/skillparts/system/models/Product.php b/mirzaev/skillparts/system/models/Product.php
index 7d52fa7..d68294d 100644
--- a/mirzaev/skillparts/system/models/Product.php
+++ b/mirzaev/skillparts/system/models/Product.php
@@ -5,6 +5,8 @@ declare(strict_types=1);
namespace app\models;
use yii;
+use yii\web\UploadedFile;
+use yii\imagine\Image;
use app\models\traits\SearchByEdge;
@@ -22,11 +24,18 @@ class Product extends Document
use SearchByEdge;
/**
- * Сценарий импорта из .excel документа
+ * Сценарий импорта .excel документа
*
* Использовать для обхода правил при загрузке файла
*/
- const SCENARIO_IMPORT = 'import';
+ const SCENARIO_IMPORT_EXCEL = 'import_excel';
+
+ /**
+ * Сценарий импорта изображений
+ *
+ * Использовать для обхода правил при загрузке файла
+ */
+ const SCENARIO_IMPORT_IMAGE = 'import_image';
/**
* Сценарий записи товара
@@ -36,7 +45,12 @@ class Product extends Document
/**
* Файл .excel для импорта товаров
*/
- public Excel|string|array|null $file = null;
+ public Excel|string|array|null $file_excel = null;
+
+ /**
+ * Изображение для импорта
+ */
+ public UploadedFile|string|array|null $file_image = null;
/**
* Группа в которой состоит товар
@@ -59,9 +73,10 @@ class Product extends Document
return array_merge(
parent::attributes(),
[
+ 'catn',
+ 'name',
'desc',
'ocid',
- 'catn',
'imgs',
'time',
'oemn',
@@ -79,13 +94,15 @@ class Product extends Document
parent::attributeLabels(),
[
'catn' => 'Каталожный номер (catn)',
+ 'name' => 'Название (name)',
'desc' => 'Описание (desc)',
'ocid' => 'Идентификатор 1C (ocid)',
'imgs' => 'Изображения (imgs)',
'time' => 'Срок доставки (time)',
'oemn' => 'OEM номера (oemn)',
'cost' => 'Стоимость (cost)',
- 'file' => 'Документ (file)',
+ 'file_excel' => 'Документ (file_excel)',
+ 'file_image' => 'Изображение (file_image)',
'group' => 'Группа (group)'
]
);
@@ -104,7 +121,7 @@ class Product extends Document
'required',
'message' => 'Заполните поля: {attribute}',
'on' => self::SCENARIO_WRITE,
- 'except' => self::SCENARIO_IMPORT
+ 'except' => [self::SCENARIO_IMPORT_EXCEL, self::SCENARIO_IMPORT_IMAGE]
],
[
'catn',
@@ -120,13 +137,13 @@ class Product extends Document
'message' => '{attribute} должен быть массивом.'
],
[
- 'file',
+ 'file_excel',
'required',
'message' => 'Заполните поля: {attribute}',
- 'on' => self::SCENARIO_IMPORT
+ 'on' => self::SCENARIO_IMPORT_EXCEL
],
[
- 'file',
+ 'file_excel',
'file',
'skipOnEmpty' => false,
'extensions' => 'xlsx',
@@ -135,7 +152,25 @@ class Product extends Document
'maxSize' => 1024 * 1024 * 30,
'wrongExtension' => 'Разрешены только документы в формате: ".xlsx"',
'message' => 'Проблема при чтении документа',
- 'on' => self::SCENARIO_IMPORT
+ '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
]
]
);
@@ -223,20 +258,93 @@ class Product extends Document
return $catn[0];
}
+
+ /**
+ * Импорт изображений
+ *
+ * @return int Количество сохранённых изображений
+ */
+ public function importImages(): int
+ {
+ if ($this->validate()) {
+ // Проверка пройдена
+
+ // Инициализация
+ $amount = 0;
+
+ foreach ($this->file_image as $file) {
+ // Перебор обрабатываемых изображений
+
+ if (!file_exists(YII_PATH_PUBLIC . $catalog = '/img/products/' . $this->_key)) {
+ // Директория для изображений продукта не найдена
+
+ if (!mkdir(YII_PATH_PUBLIC . $catalog, 0775, true)) {
+ // Не удалось записать директорию
+
+ 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 = array_merge(
+ $this->imgs ?? [],
+ [[
+ 'orig' => $catalog . '/' . $file->baseName . '.' . $file->extension,
+ 'h150' => $catalog_h150 . '/' . $file->baseName . '.' . $file->extension
+ ]]
+ );
+
+
+ $this->scenario = self::SCENARIO_WRITE;
+
+ if ($this->save()) {
+ // Изменения сохранены в базе данных
+
+ // Постинкрементация счётчика
+ $amount++;
+ }
+ }
+ }
+
+ return $amount;
+ }
+
/**
* Импорт товаров
*
* На данный момент обрабатывает только импорт из
* файлов с расширением .excel
*/
- public function import(): bool
+ public function importExcel(): bool
{
// Инициализация
$data = [];
$amount = 0;
if ($this->validate()) {
- foreach ($this->file as $file) {
+ foreach ($this->file_excel as $file) {
// Перебор файлов
// Инициализация
@@ -296,7 +404,7 @@ class Product extends Document
}
// Деинициализация
- $this->file = '';
+ $this->file_excel = '';
static::afterImportExcel($amount);
@@ -325,7 +433,34 @@ class Product extends Document
}
$query = self::find()
- ->collection('product_search')
+ ->where(['catn' => $catn])
+ ->limit($limit)
+ ->select($select)
+ ->createCommand()
+ ->execute()
+ ->getAll();
+
+ foreach ($query as &$attribute) {
+ // Приведение всех свойств в массив и очистка от лишних данных
+
+ $attribute = $attribute->getAll();
+ }
+
+ return $query;
+ }
+
+ /**
+ * Поиск по каталожному номеру (через представления)
+ *
+ * Ищет продукт и возвращает его,
+ * либо выполняет поиск через представление
+ *
+ * @todo Переделать нормально
+ */
+ public static function searchByPartialCatn(string $catn, int $limit = 1, array $select = []): static|array|null
+ {
+ $query = self::find()
+ ->in('product_search')
->search(['catn' => $catn])
->limit($limit)
->select($select)
diff --git a/mirzaev/skillparts/system/views/account/index.php b/mirzaev/skillparts/system/views/account/index.php
index f87072e..2d180df 100644
--- a/mirzaev/skillparts/system/views/account/index.php
+++ b/mirzaev/skillparts/system/views/account/index.php
@@ -7,6 +7,9 @@ use yii\bootstrap\ActiveForm;
use app\models\AccountForm;
+/**
+ * @todo Восстановить сохранение сессии
+ */
?>
diff --git a/mirzaev/skillparts/system/views/product/index.php b/mirzaev/skillparts/system/views/product/index.php
index 85eba8b..a63601a 100644
--- a/mirzaev/skillparts/system/views/product/index.php
+++ b/mirzaev/skillparts/system/views/product/index.php
@@ -6,6 +6,7 @@ use yii\helpers\Html;
use app\models\Product;
?>
+
@@ -19,17 +20,26 @@ use app\models\Product;
// Перебор изображений
// Инициализация
- $name = $image['name'] ?? 'Без названия';
$h150 = $image['h150'] ?? '/img/covers/h150/product.png';
// Генерация предпросмотра изображения
echo <<
-
-
- HTML;
+
+
+
+ HTML;
}
?>
+
+ user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+ ) : ?>
+
+
+
+
+
$image) {
+ foreach ($model['imgs'] ?? [null] as $key => $image) {
// Перебор изображений
// Инициализация
@@ -54,11 +64,11 @@ use app\models\Product;
// Генерация изображения
echo <<
-
-
-
- HTML;
+
+
+
+
+ HTML;
// Деинициализация
$checked = '';
@@ -67,13 +77,47 @@ use app\models\Product;
-
Название товара
- = $model['catn'] ?>
+ user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+ ) : ?>
+ = $model['name'] ?? 'Без названия' ?>
+
+ = $model['name'] ?? 'Без названия' ?>
+
+
+ user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+ ) : ?>
+
+ = $model['catn'] ?>
+
+
+
+
+ = $model['catn'] ?>
+
+
+ user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+ ) : ?>
+
= $model['desc'] ?? 'Без описания' ?>
+
+
= $model['name'] ?? 'Без описания' ?>
+
- ОЕМ-номера можно сюда добавить с возможностью перехода
-
+
+
-
\ No newline at end of file
+
+
+
+user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+) : ?>
+
+
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/views/profile/index.php b/mirzaev/skillparts/system/views/profile/index.php
index 4279dca..7e08539 100644
--- a/mirzaev/skillparts/system/views/profile/index.php
+++ b/mirzaev/skillparts/system/views/profile/index.php
@@ -6,7 +6,11 @@ use yii;
use yii\bootstrap\ActiveForm;
// Инициализация
-$panel ?? $panel = 'profile_panel_settings_import';
+if (yii::$app->user->identity->agnt) {
+ $panel ?? $panel = 'profile_panel_settings_import';
+} else {
+ $panel ?? $panel = 'profile_panel_settings_account';
+}
?>
@@ -22,51 +26,59 @@ $panel ?? $panel = 'profile_panel_settings_import';
-
/>
+
/>
1
-
/>
-
- 2
-
+ user->identity->agnt) : ?>
+
/>
+
+ 2
+
-
/>
-
-
Параметры 1C
-
- 'form_profile_settings',
- 'action' => false,
- 'fieldConfig' => [
- 'template' => '{label}{input}',
- ],
- 'options' => [
- 'onsubmit' => 'return false;'
- ]
- ]);
+
/>
+
+
Параметры 1C
+
+ 'form_profile_settings',
+ 'action' => false,
+ 'fieldConfig' => [
+ 'template' => '{label}{input}',
+ ],
+ 'options' => [
+ 'onsubmit' => 'return false;'
+ ]
+ ]);
- // Инициализация
- $model ?? $model = yii::$app->user->identity;
- $list or $list = ['Нет данных'];
- ?>
+ // Инициализация
+ $model ?? $model = yii::$app->user->identity;
+ $list or $list = ['Нет данных'];
+ ?>
- = $form->field($model, 'opts[import_sections_oem]', ['options' => ['class' => "mb-1"]])
- ->dropDownList($list, [
- 'onChange' => 'page_profile_settings(this.parentElement.parentElement, \'profile_panel_settings_import\')',
- 'disabled' => count($list) <= 1
- ])->label('OEM-номера'); ?>
-
Выберите поле в котором хранятся ОЕМ-номера и повторите импорт
-
Значения взяты из импортированных товаров
+ = $form->field($model, 'opts[import_sections_oem]', ['options' => ['class' => "mb-1"]])
+ ->dropDownList($list, [
+ 'onChange' => 'page_profile_settings(this.parentElement.parentElement, \'profile_panel_settings_import\')',
+ 'disabled' => count($list) <= 1
+ ])->label('OEM-номера'); ?>
-
-
+
Выберите поле в котором хранятся ОЕМ-номера и повторите импорт
+
Значения взяты из импортированных товаров
+
+
+
+
@@ -74,4 +86,10 @@ $panel ?? $panel = 'profile_panel_settings_import';
-
\ No newline at end of file
+
+user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+) : ?>
+
+
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/views/profile/monitoring.php b/mirzaev/skillparts/system/views/profile/monitoring.php
index 3851db1..28b51bd 100644
--- a/mirzaev/skillparts/system/views/profile/monitoring.php
+++ b/mirzaev/skillparts/system/views/profile/monitoring.php
@@ -29,7 +29,7 @@ $panel ?? $panel = 'profile_panel_monitoring_input_search_history';
/>
-
+
-
\ No newline at end of file
+
+user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+) : ?>
+
+
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/views/profile/trusted.php b/mirzaev/skillparts/system/views/profile/panel.php
similarity index 83%
rename from mirzaev/skillparts/system/views/profile/trusted.php
rename to mirzaev/skillparts/system/views/profile/panel.php
index 5ca1390..fe43d0a 100644
--- a/mirzaev/skillparts/system/views/profile/trusted.php
+++ b/mirzaev/skillparts/system/views/profile/panel.php
@@ -9,7 +9,7 @@ use yii\helpers\Html;
use app\models\Notification;
// Инициализация
-$panel ?? $panel = 'profile_panel_trusted_input_notifications';
+$panel ?? $panel = 'profile_panel_panel_input_notifications';
?>
@@ -23,19 +23,19 @@ $panel ?? $panel = 'profile_panel_trusted_input_notifications';
Панель управления
-
+
-
/>
+
/>
Отправка уведомления
'form_profile_trusted_notifications',
+ 'id' => 'form_profile_panel_notifications',
'action' => false,
'fieldConfig' => [
'template' => '{label}{input}'
@@ -62,17 +62,17 @@ $panel ?? $panel = 'profile_panel_trusted_input_notifications';
= $form->field($model_notifications, 'text', ['options' => ['class' => "mb-3"]])->textarea(); ?>
- = Html::submitButton('Отправить', ['name' => 'submitNotification', 'onclick' => 'page_profile_trusted_notification_create(this.parentElement);', 'class' => 'flex-grow-1 mr-2 btn button_white button_clean']) ?>
- = Html::submitButton('Отправить как HTML', ['name' => 'submitNotification', 'onclick' => 'page_profile_trusted_notification_create(this.parentElement, 1);', 'class' => 'flex-grow-1 mr-2 btn button_white button_clean']) ?>
+ = Html::submitButton('Отправить', ['name' => 'submitNotification', 'onclick' => 'page_profile_panel_notification_create(this.parentElement);', 'class' => 'flex-grow-1 mr-2 btn button_white button_clean']) ?>
+ = Html::submitButton('Отправить как HTML', ['name' => 'submitNotification', 'onclick' => 'page_profile_panel_notification_create(this.parentElement, 1);', 'class' => 'flex-grow-1 mr-2 btn button_white button_clean']) ?>
-
/>
+
/>
'form_profile_trusted_settings_search_period',
+ 'id' => 'form_profile_panel_settings_search_period',
'action' => false,
'fieldConfig' => [
'template' => '{label}{input}',
@@ -86,14 +86,14 @@ $panel ?? $panel = 'profile_panel_trusted_input_notifications';
= $form->errorSummary($model_settings, ['header' => 'Получены ошибки:']) ?>
- = $form->field($model_settings, 'search_period', ['options' => ['class' => "mb-1"]])->textInput(['value' => $model_settings['search_period'], 'onChange' => 'page_profile_trusted_settings(this.parentElement.parentElement, \'profile_panel_trusted_input_settings\')']); ?>
+ = $form->field($model_settings, 'search_period', ['options' => ['class' => "mb-1"]])->textInput(['value' => $model_settings['search_period'], 'onChange' => 'page_profile_panel_settings(this.parentElement.parentElement, \'profile_panel_panel_input_settings\')']); ?>
Время которое надо ждать для повторного поиска в секундах
'form_profile_trusted_settings_search_connect_keep',
+ 'id' => 'form_profile_panel_settings_search_connect_keep',
'action' => false,
'fieldConfig' => [
'template' => '{label}{input}',
@@ -128,7 +128,7 @@ $panel ?? $panel = 'profile_panel_trusted_input_notifications';
}
?>
- = $form->field($model_settings, 'search_connect_keep', ['options' => ['class' => "mb-1"]])->dropDownList($list, ['onChange' => 'page_profile_trusted_settings(this.parentElement.parentElement, \'profile_panel_trusted_input_settings\')']); ?>
+ = $form->field($model_settings, 'search_connect_keep', ['options' => ['class' => "mb-1"]])->dropDownList($list, ['onChange' => 'page_profile_panel_settings(this.parentElement.parentElement, \'profile_panel_panel_input_settings\')']); ?>
Удерживать открытое соединение до истечения срока блокировки поиска?
При малой задержке позволяет снизить время загрузки страницы, но при большой будет казаться, что сайт завис
@@ -142,4 +142,4 @@ $panel ?? $panel = 'profile_panel_trusted_input_notifications';
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/views/profile/sidebar.php b/mirzaev/skillparts/system/views/profile/sidebar.php
index 2e8848a..c36d980 100644
--- a/mirzaev/skillparts/system/views/profile/sidebar.php
+++ b/mirzaev/skillparts/system/views/profile/sidebar.php
@@ -18,11 +18,14 @@ use app\models\SupplyEdgeProduct;
user->identity->trst) {
+ if (
+ yii::$app->user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+ ) {
// Пользователь является доверенным
// Инициализация
- $targetUrl = '/profile/trusted';
+ $targetUrl = '/profile/panel';
if ('/' . yii::$app->request->pathInfo === $targetUrl) {
// Запрошена та же страница от которой послан запрос (текущая)
@@ -35,7 +38,7 @@ use app\models\SupplyEdgeProduct;
} else {
echo <<
- Панель управления
+ Панель управления
HTML;
}
@@ -43,19 +46,21 @@ use app\models\SupplyEdgeProduct;
?>
request->pathInfo === $targetUrl = '/profile/supplies'
- || '/' . yii::$app->request->pathInfo === $targetUrl = '/profile/import'
- ) {
- // Запрошена та же страница от которой послан запрос (текущая)
+ if (yii::$app->user->identity->agnt) {
+ if (
+ '/' . yii::$app->request->pathInfo === $targetUrl = '/profile/supplies'
+ || '/' . yii::$app->request->pathInfo === $targetUrl = '/profile/import'
+ ) {
+ // Запрошена та же страница от которой послан запрос (текущая)
- echo <<Поставки
HTML;
- } else {
- echo <<Поставки
HTML;
+ }
}
?>
@@ -96,21 +101,24 @@ use app\models\SupplyEdgeProduct;
?>
-
-
-
Загрузок с аккаунта:
-
= AccountEdgeSupply::readAmount() ?>
-
-
-
Товары:
-
= Product::readAmount() ?>
-
-
-
Поставки:
-
= Supply::readAmount() ?>
-
-
-
Связано поставок:
-
= SupplyEdgeProduct::readAmount() ?>
-
+ user->identity->agnt) : ?>
+
+
+
Загрузок с аккаунта:
+
= AccountEdgeSupply::readAmount() ?>
+
+
+
+
Товары:
+
= Product::readAmount() ?>
+
+
+
Поставки:
+
= Supply::readAmount() ?>
+
+
+
Связано поставок:
+
= SupplyEdgeProduct::readAmount() ?>
+
+
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/views/profile/supplies.php b/mirzaev/skillparts/system/views/profile/supplies.php
index 95b74a5..0d54e5f 100644
--- a/mirzaev/skillparts/system/views/profile/supplies.php
+++ b/mirzaev/skillparts/system/views/profile/supplies.php
@@ -51,7 +51,7 @@ $panel ?? $panel = 'profile_panel_supplies_input_import';
]);
?>
- = $form->field($model, 'file', ['enableLabel' => false])->fileInput(['multiple' => true, 'class' => 'mb-2', 'onChange' => 'page_profile_supplies_import_excel(this.parentElement.parentElement, \'profile_panel_supplies_input_import\')']) ?>
+ = $form->field($model, 'file_excel', ['enableLabel' => false])->fileInput(['multiple' => true, 'class' => 'mb-2', 'onChange' => 'page_profile_supplies_import_excel(this.parentElement.parentElement, \'profile_panel_supplies_input_import\')']) ?>
= $form->errorSummary($model, ['header' => 'В документе были допущены ошибки:' /*, 'footer' => 'Исправьте их и попробуйте снова'*/]); ?>
@@ -63,4 +63,10 @@ $panel ?? $panel = 'profile_panel_supplies_input_import';
-
\ No newline at end of file
+
+user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+) : ?>
+
+
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/views/search/index.php b/mirzaev/skillparts/system/views/search/index.php
index 30dc211..30bd0fe 100644
--- a/mirzaev/skillparts/system/views/search/index.php
+++ b/mirzaev/skillparts/system/views/search/index.php
@@ -9,7 +9,7 @@
Слишком частые запросы, повторите попытку через: $timer секунд
Подождите или нажмите на кнопку вручную
-
Повторить
+
Повторить
\ No newline at end of file
+
+
+user->identity->type === 'administrator'
+ || yii::$app->user->identity->type === 'moderator'
+) : ?>
+
+
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/web/css/pages/product.css b/mirzaev/skillparts/system/web/css/pages/product.css
index a5db4a6..66645d2 100644
--- a/mirzaev/skillparts/system/web/css/pages/product.css
+++ b/mirzaev/skillparts/system/web/css/pages/product.css
@@ -30,4 +30,8 @@
#page_product #product_slider>.product_slider_preview>label:focus>img {
cursor: pointer;
filter: brightness(0.8) contrast(1.3);
+}
+
+#page_product article .product_description {
+ display: contents;
}
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/web/img/.gitignore b/mirzaev/skillparts/system/web/img/.gitignore
index b784184..61872d3 100644
--- a/mirzaev/skillparts/system/web/img/.gitignore
+++ b/mirzaev/skillparts/system/web/img/.gitignore
@@ -1 +1,2 @@
-/supplies
\ No newline at end of file
+/supplies
+/products
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/web/img/covers/h150/product_new.png b/mirzaev/skillparts/system/web/img/covers/h150/product_new.png
new file mode 100644
index 0000000..c7194bb
Binary files /dev/null and b/mirzaev/skillparts/system/web/img/covers/h150/product_new.png differ
diff --git a/mirzaev/skillparts/system/web/img/covers/product_new.png b/mirzaev/skillparts/system/web/img/covers/product_new.png
new file mode 100644
index 0000000..24482ed
Binary files /dev/null and b/mirzaev/skillparts/system/web/img/covers/product_new.png differ
diff --git a/mirzaev/skillparts/system/web/js/cart.js b/mirzaev/skillparts/system/web/js/cart.js
index e58bc62..ff745f7 100644
--- a/mirzaev/skillparts/system/web/js/cart.js
+++ b/mirzaev/skillparts/system/web/js/cart.js
@@ -61,7 +61,6 @@ function cart_pay() {
* Управление чекбоксами
*/
function cart_list_checkbox(target) {
-
// Инициализация
let elements = document.getElementsByClassName('cart_list_target');
let reg = /^\w+_([^_]*)$/;
diff --git a/mirzaev/skillparts/system/web/js/product.js b/mirzaev/skillparts/system/web/js/product.js
new file mode 100644
index 0000000..17385a8
--- /dev/null
+++ b/mirzaev/skillparts/system/web/js/product.js
@@ -0,0 +1,36 @@
+function product_response_success(data, status) {
+ product_response(data, status);
+}
+
+function product_response_error(data, status) {
+ // Инициализация
+ data = data.responseJSON;
+
+ product_response(data, status);
+}
+
+function product_response(data, status) {
+ // Основной блок
+ if (data.main !== undefined) {
+ // Инициализация
+ main = document.getElementsByTagName('main')[0];
+
+ // Обновление документа
+ main.innerHTML = data.main;
+
+ // Реинициализация
+ reinitialization(main);
+ };
+
+ // Перенаправление
+ if (data.redirect !== undefined) {
+ // Перенаправление
+ history.pushState({}, document.title, data.redirect);
+ };
+
+ // CSRF-токен
+ if (data._csrf !== undefined) {
+ // Обновление документа
+ $('meta[name=csrf-token]').prop("content", data._csrf);
+ };
+}
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/web/js/product_panel.js b/mirzaev/skillparts/system/web/js/product_panel.js
new file mode 100644
index 0000000..f6870bd
--- /dev/null
+++ b/mirzaev/skillparts/system/web/js/product_panel.js
@@ -0,0 +1,181 @@
+function product_panel_title_edit(catn, element) {
+ if (catn !== null && catn !== undefined && element !== null && element !== undefined) {
+ element.innerHTML = '
';
+
+ element.removeAttribute('onclick');
+
+ return false;
+ }
+
+ return true;
+}
+
+function product_panel_title_save(catn, element) {
+ if (catn !== null && catn !== undefined && element !== null && element !== undefined) {
+ // Инициализация
+ let text = element.children[0].value;
+
+ // Обновление заголовка (предзагрузка)
+ element.innerHTML = text;
+
+ // Запись аттрибута (предзагрузка)
+ element.setAttribute('onclick', 'return product_panel_title_edit(\'' + catn + '\', this);');
+
+ $.ajax({
+ url: '/product/' + catn + '/edit/title',
+ type: 'post',
+ dataType: 'json',
+ data: {
+ '_csrf': yii.getCsrfToken(),
+ 'text': text
+ },
+ success: function (data, status) {
+ // Заголовок
+ if (data.name !== undefined && element !== null && element !== undefined) {
+ // Обновление заголовка
+ element.innerHTML = data.name;
+
+ // Запись аттрибута
+ element.setAttribute('onclick', 'return product_panel_title_edit(\'' + catn + '\', this);');
+ };
+
+ product_response_success(data, status);
+ },
+ error: product_response_error
+ });
+
+ return false;
+ }
+
+ return true;
+}
+
+function product_panel_catn_edit(catn, element, redirect = false) {
+ if (catn !== null && catn !== undefined && element !== null && element !== undefined) {
+ element.innerHTML = '
';
+
+ element.removeAttribute('onclick');
+
+ return false;
+ }
+
+ return true;
+}
+
+function product_panel_catn_save(catn, element, redirect = false) {
+ if (catn !== null && catn !== undefined && element !== null && element !== undefined) {
+ // Инициализация
+ let text = element.children[0].value;
+
+ // Обновление заголовка (предзагрузка)
+ element.innerHTML = text;
+
+ // Запись аттрибута (предзагрузка)
+ element.setAttribute('onclick', 'return product_panel_catn_edit(\'' + catn + '\', this);');
+
+ $.ajax({
+ url: '/product/' + catn + '/edit/catn',
+ type: 'post',
+ dataType: 'json',
+ data: {
+ '_csrf': yii.getCsrfToken(),
+ 'text': text
+ },
+ success: function (data, status) {
+ // Заголовок
+ if (data.catn !== undefined && element !== null && element !== undefined) {
+ if (redirect) {
+ // Перенаправление
+ history.pushState({}, '/product/' + catn, '/product/' + data.catn);
+ }
+ };
+
+ product_response_success(data, status);
+ },
+ error: product_response_error
+ });
+
+ return false;
+ }
+
+ return true;
+}
+
+function product_panel_description_edit(catn, element) {
+ if (catn !== null && catn !== undefined && element !== null && element !== undefined) {
+ element.innerHTML = '
';
+
+ element.removeAttribute('onclick');
+
+ return false;
+ }
+
+ return true;
+}
+
+function product_panel_description_save(catn, element) {
+ if (catn !== null && catn !== undefined && element !== null && element !== undefined) {
+ // Инициализация
+ let text = element.children[0].value;
+
+ // Обновление заголовка (предзагрузка)
+ element.innerHTML = text;
+
+ // Запись аттрибута (предзагрузка)
+ element.setAttribute('onclick', 'return product_panel_description_edit(\'' + catn + '\', this);');
+
+ $.ajax({
+ url: '/product/' + catn + '/edit/desc',
+ type: 'post',
+ dataType: 'json',
+ data: {
+ '_csrf': yii.getCsrfToken(),
+ 'text': text
+ },
+ success: function (data, status) {
+ // Заголовок
+ if (data.description !== undefined && element !== null && element !== undefined) {
+ // Обновление заголовка
+ element.innerHTML = data.description;
+
+ // Запись аттрибута
+ element.setAttribute('onclick', 'return product_panel_description_edit(\'' + catn + '\', this);');
+ };
+
+ product_response_success(data, status);
+ },
+ error: product_response_error
+ });
+
+ return false;
+ }
+
+ return true;
+}
+
+function product_panel_images_write(catn, element) {
+ if (catn !== null && catn !== undefined && element !== null && element !== undefined) {
+ // Инициализация
+ let data = new FormData();
+
+ data.append('_csrf', yii.getCsrfToken());
+ for (i = 0; i < element.files.length; i++) {
+ data.append('images[' + i + ']', element.files[i]);
+ }
+
+ $.ajax({
+ url: '/product/' + catn + '/write/image',
+ type: 'post',
+ dataType: 'json',
+ processData: false,
+ contentType: false,
+ data: data,
+ success: product_response_success,
+ error: product_response_error
+ });
+
+ return false;
+ }
+
+ return true;
+}
\ No newline at end of file
diff --git a/mirzaev/skillparts/system/web/js/profile.js b/mirzaev/skillparts/system/web/js/profile.js
index 2975953..6d191c1 100644
--- a/mirzaev/skillparts/system/web/js/profile.js
+++ b/mirzaev/skillparts/system/web/js/profile.js
@@ -48,9 +48,9 @@ function page_profile_supplies_import_excel(form, panel) {
url: '/profile/import',
type: 'post',
dataType: 'json',
- data: form,
processData: false,
contentType: false,
+ data: form,
success: page_profile_response_success,
error: page_profile_response_error
});
diff --git a/mirzaev/skillparts/system/web/js/profile_trusted.js b/mirzaev/skillparts/system/web/js/profile_panel.js
similarity index 75%
rename from mirzaev/skillparts/system/web/js/profile_trusted.js
rename to mirzaev/skillparts/system/web/js/profile_panel.js
index ee104c3..8d4c80c 100644
--- a/mirzaev/skillparts/system/web/js/profile_trusted.js
+++ b/mirzaev/skillparts/system/web/js/profile_panel.js
@@ -1,4 +1,4 @@
-function page_profile_trusted_notification_create(form, html = 0) {
+function page_profile_panel_notification_create(form, html = 0) {
if (form == undefined) {
form = {
'_csrf': yii.getCsrfToken()
@@ -13,10 +13,10 @@ function page_profile_trusted_notification_create(form, html = 0) {
});
}
- return page_profile_trusted_write(form);
+ return page_profile_panel_write(form);
}
-function page_profile_trusted_settings(form, panel) {
+function page_profile_panel_settings(form, panel) {
if (form == undefined) {
form = {
'_csrf': yii.getCsrfToken()
@@ -34,12 +34,12 @@ function page_profile_trusted_settings(form, panel) {
});
}
- return page_profile_trusted_write(form);
+ return page_profile_panel_write(form);
}
-function page_profile_trusted_write (form) {
+function page_profile_panel_write (form) {
$.ajax({
- url: '/profile/trusted',
+ url: '/profile/panel',
type: 'post',
dataType: 'json',
data: form,