diff --git a/mirzaev/skillparts/system/controllers/OrderController.php b/mirzaev/skillparts/system/controllers/OrderController.php index 95ec031..2ccf0fd 100644 --- a/mirzaev/skillparts/system/controllers/OrderController.php +++ b/mirzaev/skillparts/system/controllers/OrderController.php @@ -589,21 +589,27 @@ class OrderController extends Controller $model = Order::searchByType(supplies: true); // Поиск ребра - $edge = AccountEdgeOrder::searchByVertex(yii::$app->user->id, $model->readId(), 'current'); + $account_edge_order = AccountEdgeOrder::searchByVertex(yii::$app->user->id, $model->readId(), 'current')[0]; - if (count($edge) > 1) { + if ($supplies = OrderEdgeSupply::searchByDirection($account_edge_order->to)) { + // Поставки найдены + + // Добавить проверку на то, что товары активны + + } + + var_dump($supplies); die; + + if (count($account_edge_order) > 1) { // Найден более чем 1 заказ return null; } - // Инициализация - $edge = $edge[0]; - // Запись - $edge->type = 'requested'; + $account_edge_order->type = 'requested'; - if ($edge->update()) { + if ($account_edge_order->update()) { // Удалось сохранить изменения // Запись в журнал @@ -613,6 +619,8 @@ class OrderController extends Controller $supplies = []; foreach ($model['supplies'] as $supply) { + // Перебор поставок + $supplies[] = [ 'title' => $supply['supply']['catn'], 'amount' => [ @@ -634,13 +642,13 @@ class OrderController extends Controller ], 'order' => [ 'id' => $model->_key, - 'date' => $edge->date ?? time(), + 'date' => $account_edge_order->date ?? time(), 'entries' => $supplies ] ])); // Отправка уведомлений модераторам - Notification::_write($this->renderPartial('/notification/system/orders/new', ['id' => $edge->_key]), true, '@auth', Notification::TYPE_MODERATOR_ORDER_NEW); + Notification::_write($this->renderPartial('/notification/system/orders/new', ['id' => $account_edge_order->_key]), true, '@auth', Notification::TYPE_MODERATOR_ORDER_NEW); } return $this->actionIndex(); diff --git a/mirzaev/skillparts/system/controllers/ProductController.php b/mirzaev/skillparts/system/controllers/ProductController.php index 3596f79..b36479c 100644 --- a/mirzaev/skillparts/system/controllers/ProductController.php +++ b/mirzaev/skillparts/system/controllers/ProductController.php @@ -5,18 +5,82 @@ declare(strict_types=1); 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\filters\AccessControl; use app\models\Product; +use app\models\Settings; use app\models\SupplyEdgeProduct; use app\models\Supply; +use app\models\Account; +use app\models\Notification; +use app\models\OrderEdgeSupply; + +use Exception; class ProductController extends Controller { + public function behaviors() + { + return [ + 'access' => [ + 'class' => AccessControl::class, + 'rules' => [ + [ + 'allow' => true, + 'actions' => [ + 'index', + ] + ], + [ + 'allow' => true, + 'roles' => ['@'], + 'actions' => [] + ], + [ + 'allow' => true, + 'actions' => [ + 'read', + 'write', + 'delete', + 'connect', + 'disconnect', + 'edit-title', + 'edit-catn', + 'edit-dscr', + 'edit-dmns', + 'edit-wght', + 'write-image', + 'delete-image', + 'write-cover', + 'write-image', + 'status' + ], + 'matchCallback' => function ($rule, $action): bool { + if ( + !yii::$app->user->isGuest + && (yii::$app->user->identity->type === 'administrator' + || yii::$app->user->identity->type === 'moderator') + ) { + return true; + } + + return false; + } + ], + [ + 'allow' => false, + 'roles' => ['?'], + 'denyCallback' => [$this, 'accessDenied'] + ] + ] + ] + ]; + } + public function actionIndex(string $catn): array|string|null { if ($model = Product::searchByCatn($catn)) { @@ -143,6 +207,44 @@ class ProductController extends Controller return $this->redirect("/"); } + /** + * Чтение товаров + * + * @param string $stts Статус + * + * @return string|array|null + */ + public function actionRead(string $stts = 'all'): string|array|null + { + if (yii::$app->request->isPost) { + // POST-запрос + + // Инициализация входных параметров + $amount = yii::$app->request->post('amount') ?? yii::$app->request->get('amount') ?? 50; + $order = yii::$app->request->post('order') ?? yii::$app->request->get('order') ?? ['DESC']; + + // Инициализация cookie + $cookies = yii::$app->response->cookies; + + + // Инициализация аккаунта + $account ?? $account = Account::initAccount(); + + // Чтение товаров + $products = Product::read(where: $stts === 'all' || $stts === 'inactive' ? [] : ['stts' => $stts], limit: $amount, order: $order); + + // Запись формата ответа + yii::$app->response->format = Response::FORMAT_JSON; + + return [ + 'products' => $this->renderPartial('/product/list', compact('account', 'products')), + '_csrf' => yii::$app->request->getCsrfToken() + ]; + } + + return false; + } + /** * Удаление товара * @@ -307,7 +409,7 @@ class ProductController extends Controller yii::$app->response->statusCode = 500; // Запись в буфер возврата - $return['alert'] = "Не удалось найти товар к которому требуется соединение: $catn"; + $return['alert'] = "Не удалось найти товар: $catn"; // Переход в конец алгоритма goto end; @@ -848,4 +950,81 @@ class ProductController extends Controller return $this->redirect('/'); } } + + /** + * Изменение статуса + * + * @param string $catn Артикул + */ + public function actionStatus(string $catn): array|string|null + { + if (yii::$app->request->isPost) { + // POST-запрос + + // Запись заголовка с форматом ответа + yii::$app->response->format = Response::FORMAT_JSON; + + // Инициализация буфера ответа + $return = [ + '_csrf' => yii::$app->request->getCsrfToken() + ]; + + if (empty($catn)) { + // Не получен артикул + + // Запись кода ответа + yii::$app->response->statusCode = 500; + + // Переход в конец алгоритма + goto end; + } + + if ($product = Product::searchByCatn($catn)) { + // Найден товар + + // Запись старого статуса + $old = $product->stts; + + // Запись параметров + $product->stts = $stts = yii::$app->request->post('stts') ?? 'inactive'; + + if ($product->update() > 0) { + // Записаны изменения + + // Запись в журнал + $product->journal(data: [ + 'stts' => [ + 'old' => $old, + 'new' => $stts + ] + ]); + + $return['main'] = $this->renderPartial('index', ['model' => $product]); + } else { + // Не записаны изменения + + // Отправка уведомления + Notification::_write("Не удалось изменить статус на $stts у товара $catn", type: Notification::TYPE_ERROR); + } + } else { + // Не найден товар + + // Запись кода ответа + yii::$app->response->statusCode = 500; + + // Отправка уведомления + Notification::_write("Не удалось найти товар $catn", type: Notification::TYPE_ERROR); + + // Переход в конец алгоритма + goto end; + } + + // Конец алгоритма + end: + + return $return; + } + + return null; + } } diff --git a/mirzaev/skillparts/system/controllers/SearchController.php b/mirzaev/skillparts/system/controllers/SearchController.php index 790bd4e..f70e2ae 100644 --- a/mirzaev/skillparts/system/controllers/SearchController.php +++ b/mirzaev/skillparts/system/controllers/SearchController.php @@ -134,7 +134,7 @@ class SearchController extends Controller $limit = yii::$app->request->isPost ? 10 : 20; - if ($response = Product::searchByPartialCatn($query, $limit, [ + if ($response = Product::searchByPartialCatn($query, 'active', $limit, [ '_key' => '_key', 'catn' => 'catn', 'prod' => 'prod', diff --git a/mirzaev/skillparts/system/models/Document.php b/mirzaev/skillparts/system/models/Document.php index 3d3c089..c6528d1 100644 --- a/mirzaev/skillparts/system/models/Document.php +++ b/mirzaev/skillparts/system/models/Document.php @@ -168,9 +168,9 @@ abstract class Document extends ActiveRecord /** * Чтение записей по максимальному ограничению */ - public static function read(int $limit = 100, array|null $order = null): array + public static function read(?array $where = [], int $limit = 100, ?array $order = null): array { - return static::find()->limit($limit)->orderby($order)->all(); + return static::find()->where($where)->orderby($order)->limit($limit)->all(); } /** diff --git a/mirzaev/skillparts/system/models/Product.php b/mirzaev/skillparts/system/models/Product.php index ac10f31..32d5c33 100644 --- a/mirzaev/skillparts/system/models/Product.php +++ b/mirzaev/skillparts/system/models/Product.php @@ -89,6 +89,7 @@ class Product extends Document 'imgs', 'time', 'bffr', + 'stts' ] ); } @@ -109,6 +110,7 @@ class Product extends Document 'imgs' => 'Изображения (imgs)', 'time' => 'Срок доставки (time)', 'bffr' => 'Буфер', + 'stts' => 'Статус', 'file_excel' => 'Документ (file_excel)', 'file_image' => 'Изображение (file_image)', 'group' => 'Группа (group)', @@ -168,6 +170,12 @@ class Product extends Document 'max' => 30000, 'message' => '{attribute} должен иметь значение от 0 до 30000' ], + [ + 'stts', + 'string', + 'length' => [4, 20], + 'message' => '{attribute} должен быть строкой от 4 до 20 символов' + ], [ 'file_excel', 'file', @@ -201,6 +209,29 @@ class Product extends Document ); } + /** + * Перед сохранением + * + * @todo Подождать обновление от ебаного Yii2 и добавить + * проверку типов передаваемых параметров + */ + public function beforeSave($create): bool + { + if (parent::beforeSave($create)) { + // Пройдена родительская проверка + + if ($this->isNewRecord) { + // Новая запись + + $this->stts = 'inactive'; + } + + return true; + } + + return false; + } + /** * Запись пустого продукта */ @@ -346,11 +377,12 @@ class Product extends Document * * @todo Переделать нормально */ - public static function searchByPartialCatn(string $catn, int $limit = 1, array $select = []): static|array|null + public static function searchByPartialCatn(string $catn, string $stts = 'active', int $limit = 1, array $select = []): static|array|null { $query = self::find() ->for('product') ->in('product_search') + ->where(['stts' => $stts]) ->filter(['catn' => $catn], 'START_SENSETIVE') ->limit($limit) ->orderBy(['catn' => 'ASC']) diff --git a/mirzaev/skillparts/system/models/Search.php b/mirzaev/skillparts/system/models/Search.php index e1821ea..9774e77 100644 --- a/mirzaev/skillparts/system/models/Search.php +++ b/mirzaev/skillparts/system/models/Search.php @@ -118,7 +118,7 @@ class Search extends Document /** - * Поиск содержимого поиска + * Поиск содержимого поиска (продуктов) * * @todo В будущем возможно заказ не только поставок реализовать * Переписать реестр и проверку на дубликаты, не понимаю как они работают @@ -343,6 +343,7 @@ class Search extends Document } } + // Запись обработанных данных $_row['supplies'] = array_merge($connections, $buffer_connections); diff --git a/mirzaev/skillparts/system/models/Supply.php b/mirzaev/skillparts/system/models/Supply.php index 85ba571..90d6087 100644 --- a/mirzaev/skillparts/system/models/Supply.php +++ b/mirzaev/skillparts/system/models/Supply.php @@ -459,7 +459,7 @@ class Supply extends Product implements ProductInterface, OfferInterface $analogs = explode(',', $row['Артикул'] ?? $row['артикул'] ?? $row['Article'] ?? $row['article'] ?? $row['catn'], 50); // Инициализация функции создания поставки - $create = function (string $_supply) use ($row, $analogs, &$created, &$updated, &$imported, $amount, $account) { + $create = function (string $_supply) use ($row, $analogs, &$created, &$updated, &$imported, $amount, $account): bool { // Очистка $_supply = trim($_supply); @@ -591,21 +591,35 @@ class Supply extends Product implements ProductInterface, OfferInterface if ($product = Product::searchByCatn($supply->catn)) { // Найден товар подходящий для привязки с только что созданной поставкой - if (isset($product->prod) && $product->prod === $supply->prod) { - // Производитель совпадает с тем, что указан в товаре - - for ($i = 0; $i++ < $amount;) { - // Перебор создаваемых рёбер (так работает обозначение количества товаров в наличии) - - // Запись ребра (с проверкой на дубликат) - SupplyEdgeProduct::writeSafe($supply->readId(), $product->readId(), data: ['type' => 'connect']); - } - } + // Приведение типа (для анализатора) + if (is_array($product)) $product = $product[0]; } else { // Не найден товар подходящий для привязки с только что созданной поставкой - // Отправка уведомления - Notification::_write("Не найден товар подходящий для связи с поставкой: $supply->catn", account: '@authorized'); + if ($product = Product::writeEmpty($supply->catn)) { + // Удалось записать новый товар (НЕАКТИВНЫЙ) + + // Отправка уведомления + // Notification::_write("Не найден товар подходящий для связи с поставкой: $supply->catn", account: '@authorized'); + } else { + // Не удалось записать новый товар + + // Отправка уведомления + Notification::_write("Не удалось создать новый товар: $supply->catn", account: '@authorized'); + + return false; + } + } + + if (isset($product->prod) && $product->prod === $supply->prod) { + // Производитель совпадает с тем, что указан в товаре + + for ($i = 0; $i++ < $amount;) { + // Перебор создаваемых рёбер (так работает обозначение количества товаров в наличии) + + // Запись ребра (с проверкой на дубликат) + SupplyEdgeProduct::writeSafe($supply->readId(), $product->readId(), data: ['type' => 'connect']); + } } } else { // Проверка не пройдена diff --git a/mirzaev/skillparts/system/views/product/index.php b/mirzaev/skillparts/system/views/product/index.php index b7518fe..46a013d 100644 --- a/mirzaev/skillparts/system/views/product/index.php +++ b/mirzaev/skillparts/system/views/product/index.php @@ -87,6 +87,7 @@ use app\models\Product; && (yii::$app->user->identity->type === 'administrator' || yii::$app->user->identity->type === 'moderator') ) { + // Инициализация артикула $catn = $model['catn']; echo <<