From 4fafe85639d491fc550fcca32e59a9862730cbf2 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 4 Aug 2022 13:37:24 +0000 Subject: [PATCH] =?UTF-8?q?=D0=B7=D0=B0=D0=BB=D1=83=D0=BF=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/controllers/CartController.php | 7 +- .../system/controllers/OrderController.php | 851 +- .../system/controllers/SearchController.php | 1 + .../system/models/AccountEdgeOrder.php | 80 +- mirzaev/skillparts/system/models/Edge.php | 2 +- mirzaev/skillparts/system/models/Order.php | 108 +- .../system/models/OrderEdgeSupply.php | 19 +- .../system/views/invoice/order/pattern.pdf | Bin 0 -> 8680 bytes .../views/notification/system/orders/edit.php | 2 +- .../skillparts/system/views/orders/index.php | 235 +- .../skillparts/system/views/search/index.php | 14 +- .../web/css/bootstrap/bootstrap-grid.rtl.css | 4996 +++++++ .../css/bootstrap/bootstrap-grid.rtl.css.map | 1 + .../css/bootstrap/bootstrap-grid.rtl.min.css | 7 + .../bootstrap/bootstrap-grid.rtl.min.css.map | 1 + .../css/bootstrap/bootstrap-reboot.rtl.css | 423 + .../bootstrap/bootstrap-reboot.rtl.css.map | 1 + .../bootstrap/bootstrap-reboot.rtl.min.css | 8 + .../bootstrap-reboot.rtl.min.css.map | 1 + .../web/css/bootstrap/bootstrap-utilities.css | 4752 +++++++ .../css/bootstrap/bootstrap-utilities.css.map | 1 + .../css/bootstrap/bootstrap-utilities.min.css | 7 + .../bootstrap/bootstrap-utilities.min.css.map | 1 + .../css/bootstrap/bootstrap-utilities.rtl.css | 4743 +++++++ .../bootstrap/bootstrap-utilities.rtl.css.map | 1 + .../bootstrap/bootstrap-utilities.rtl.min.css | 7 + .../bootstrap-utilities.rtl.min.css.map | 1 + .../web/css/bootstrap/bootstrap.rtl.css | 10796 ++++++++++++++++ .../web/css/bootstrap/bootstrap.rtl.css.map | 1 + .../web/css/bootstrap/bootstrap.rtl.min.css | 7 + .../css/bootstrap/bootstrap.rtl.min.css.map | 1 + mirzaev/skillparts/system/web/img/.gitignore | 1 + .../system/web/js/bootstrap/bootstrap.esm.js | 4946 +++++++ .../web/js/bootstrap/bootstrap.esm.js.map | 1 + .../web/js/bootstrap/bootstrap.esm.min.js | 7 + .../web/js/bootstrap/bootstrap.esm.min.js.map | 1 + mirzaev/skillparts/system/web/js/cart.js | 14 +- mirzaev/skillparts/system/web/js/menu.js | 4 +- mirzaev/skillparts/system/web/js/orders.js | 15 +- .../skillparts/system/web/js/orders_panel.js | 728 +- 40 files changed, 32019 insertions(+), 773 deletions(-) create mode 100755 mirzaev/skillparts/system/views/invoice/order/pattern.pdf create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-grid.rtl.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-grid.rtl.css.map create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-grid.rtl.min.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-grid.rtl.min.css.map create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-reboot.rtl.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-reboot.rtl.css.map create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-reboot.rtl.min.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-reboot.rtl.min.css.map create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-utilities.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-utilities.css.map create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-utilities.min.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-utilities.min.css.map create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-utilities.rtl.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-utilities.rtl.css.map create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-utilities.rtl.min.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap-utilities.rtl.min.css.map create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap.rtl.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap.rtl.css.map create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap.rtl.min.css create mode 100755 mirzaev/skillparts/system/web/css/bootstrap/bootstrap.rtl.min.css.map create mode 100755 mirzaev/skillparts/system/web/js/bootstrap/bootstrap.esm.js create mode 100755 mirzaev/skillparts/system/web/js/bootstrap/bootstrap.esm.js.map create mode 100755 mirzaev/skillparts/system/web/js/bootstrap/bootstrap.esm.min.js create mode 100755 mirzaev/skillparts/system/web/js/bootstrap/bootstrap.esm.min.js.map diff --git a/mirzaev/skillparts/system/controllers/CartController.php b/mirzaev/skillparts/system/controllers/CartController.php index 7188fde..ef82ecb 100644 --- a/mirzaev/skillparts/system/controllers/CartController.php +++ b/mirzaev/skillparts/system/controllers/CartController.php @@ -86,7 +86,8 @@ class CartController extends Controller $account = Account::initAccount(); // Поиск корзины (текущего заказа) - $data = Order::searchByType()[0] ?? null; + $data = Order::searchSmart()[0] ?? null; + if (empty($data['order'])) { // Корзина не инициализирована @@ -105,7 +106,7 @@ class CartController extends Controller } // Инициализация содержимого корзины - $data['supplies'] = $data['order']->supplies(10, $page, test: true); + $data['supplies'] = $data['order']->supplies(10, $page); // Инициализация данных списка для выбора терминала $delivery_to_terminal_list = $account->genListTerminalsTo(); @@ -163,7 +164,7 @@ class CartController extends Controller goto end; } - if ($edges = OrderEdgeSupply::searchBySupplyCatnAndProd($catn, $prod, Order::searchByType())) { + if ($edges = OrderEdgeSupply::searchBySupplyCatnAndProd($catn, $prod, Order::searchByType()[0]['order'])) { // Рёбра найдены (связи заказа с поставкой) // Инициализация diff --git a/mirzaev/skillparts/system/controllers/OrderController.php b/mirzaev/skillparts/system/controllers/OrderController.php index c19038b..728ae1f 100644 --- a/mirzaev/skillparts/system/controllers/OrderController.php +++ b/mirzaev/skillparts/system/controllers/OrderController.php @@ -46,9 +46,11 @@ class OrderController extends Controller 'write', 'delete', 'amount-update', + 'amount-update', 'request', + 'edit-stts', 'supply-read', - 'supply-write-stts', + 'supply-edit-stts', 'supply-edit-time', 'supply-edit-cost', 'supply-edit-comm' @@ -114,7 +116,7 @@ class OrderController extends Controller } } - public function actionIndex(string $type = 'all') + public function actionIndex(string $stts = '@all') { // Инициализация cookie $cookies = yii::$app->response->cookies; @@ -122,9 +124,12 @@ class OrderController extends Controller // Инициализация открытой панели ("Модерация", "Мои заказы") $window = yii::$app->request->post('window') ?? yii::$app->request->get('window') ?? 'orders_panel_orders'; + // Инициализация аккаунта + $account = Account::initAccount(); + // Инициализация данных поиска try { - if ('@last' === $search = yii::$app->request->post('search') ?? yii::$app->request->get('search')) { + if ($search = yii::$app->request->post('search') ?? yii::$app->request->get('search') === '@last') { // Запрошено использование прошлых данных // Чтение сохраненных данных в cookie @@ -162,35 +167,35 @@ class OrderController extends Controller // Инициализация открытого окна try { - if ('@last' === $type) { + if ($stts === '@last') { // Запрошено использование прошлых данных // Чтение сохраненных данных в cookie - $type = $cookies->get('type'); + $stts = $cookies->get('stts'); - if (empty($type)) { + if (empty($stts)) { // Переданы неверные данные - throw new Exception("Переданы неверные данные \$type: $type", 500); + throw new Exception("Переданы неверные данные \$stts: $stts", 500); } } else { - // Запрошена сортировка + // Запрошено использование новых данных - if (empty($type)) { + if (empty($stts)) { // Переданы неверные данные - throw new Exception("Переданы неверные данные \$type: $type", 500); + throw new Exception("Переданы неверные данные \$stts: $stts", 500); } // Запись данных в cookie $cookies->add(new Cookie([ - 'name' => 'type', - 'value' => $type + 'name' => 'stts', + 'value' => $stts ])); } } catch (Exception $e) { // Реинициализация - $type = 'all'; + $stts = '@all'; } // Инициализация данных периода (от) @@ -265,37 +270,68 @@ class OrderController extends Controller $to = (int) $to; } - // Инициализация заказов - $data = Order::searchByType( - type: $type, - limit: 10, - page: 1, - supplies: true, - from: $from, - to: $to, - search: $search - ); + if ($window === 'orders_panel_orders') { + // Обработка панели заказов пользователя - // Фильтрация - if ( - !yii::$app->user->isGuest - && yii::$app->user->identity->type === 'administrator' - || yii::$app->user->identity->type === 'moderator' - ) { - // Пользователь имеет доступ + // Инициализация заказов + $data = Order::searchSmart( + stts: $stts, + limit: 10, + page: 1, + supplies: true, + from: $from, + to: $to, + search: $search + ); - // Инициализация заказов для модератора - $moderator_data = Order::searchByType(account: '@all', type: 'requested', limit: 10, page: 1, supplies: true); + // Инициализация панели модератора заказов + if (!yii::$app->user->isGuest && Account::isMinimalAuthorized($account)) { + // Имеет доступ пользователь + + // Инициализация заказов для модератора + $moderator_data = Order::searchSmart(account: '@all', stts: '@all', limit: 10, page: 1, supplies: true); + } else { + // Не имеет доступ пользователь + + // Инициализация заглушки + $moderator_data = null; + } + } else if ($window === 'orders_panel_moderation') { + // Обработка панели модерации заказов + + // Инициализация заказов + $data = Order::searchSmart( + stts: '@all', + limit: 10, + page: 1, + supplies: true + ); + + // Инициализация панели модератора заказов + if (!yii::$app->user->isGuest && Account::isMinimalAuthorized($account)) { + // Имеет доступ пользователь + + // Инициализация заказов для модератора + $moderator_data = Order::searchSmart( + account: '@all', + stts: $stts, + limit: 10, + page: 1, + supplies: true, + from: $from, + to: $to, + search: $search + ); + } else { + // Не имеет доступ пользователь + + // Инициализация заглушки + $moderator_data = null; + } } else { - // Пользователь не имеет доступ - - // Инициализация заглушки - $moderator_data = null; + // Запрошено неизвестное окно } - // Инициализация аккаунта - $account ?? $account = Account::initAccount(); - if (yii::$app->request->isPost) { // POST-запрос @@ -318,50 +354,6 @@ class OrderController extends Controller return $this->render('/orders/index', compact('data', 'moderator_data', 'account')); } - /** - * Подтверждение заказа - * - * @param int $_key Ключ записи в коллекции order - * - * @return string|array|null - */ - public function actionAccept(int $_key): string|array|null - { - // Инициализация - $buffer = []; - $account_edge_order = AccountEdgeOrder::searchByOrder(Order::collectionName() . '/' . $_key, limit: 1)[0]; - - // Запись в буфер записи в базу данных - $account_edge_order->type = 'accepted'; - - // Отправка изменений в базу данных - if ($account_edge_order->save()) { - // Удалось сохранить изменения - - // Запись в журнал - Order::searchById($account_edge_order->_to)->journal('accepted'); - - // Инициализация - $orders = Order::searchByType(type: 'all', limit: 10, page: 1, select: '{account_edge_order, order}', supplies: true); - $moderator_orders = self::genOrdersForModeration(); - - // Запись в буфер вывода - $buffer['main'] = $this->renderPartial('/orders/index', compact('orders', 'moderator_orders')); - } else { - // Не удалось сохранить изменения - - yii::$app->response->statusCode = 500; - } - - // Запись обязательных параметров - $buffer['_csrf'] = yii::$app->request->getCsrfToken(); - - // Настройка ответа - yii::$app->response->format = Response::FORMAT_JSON; - - return $buffer; - } - /** * Запись */ @@ -374,12 +366,12 @@ class OrderController extends Controller $account = yii::$app->user->identity; $supply_id = yii::$app->request->post('supply_id'); $amount = yii::$app->request->post('amount') ?? 1; - $delivery_type = yii::$app->request->post('delivery_type'); + $delivery = yii::$app->request->post('delivery'); // Запись настроек ответа в буфер yii::$app->response->format = Response::FORMAT_JSON; - if (empty($supply_id) || empty($delivery_type)) { + if (empty($supply_id) || empty($delivery)) { // Не выполнены условия для выполнения // 501 Not Implemented @@ -392,7 +384,7 @@ class OrderController extends Controller ]; // Инициализация корзины - if (!$data = Order::searchByType($account)[0]) { + if (!$data = Order::searchSmart($account)[0] ?? null) { // Корзина не найдена (текущий заказ) // Инициализация @@ -400,11 +392,11 @@ class OrderController extends Controller $data['order']->save() or throw new Exception('Не удалось инициализировать заказ'); // Запись ребра: АККАУНТ -> ЗАКАЗ - AccountEdgeOrder::write($account->readId(), $data['order']->readId(), 'current') or $data['order']->addError('errors', 'Не удалось инициализировать ребро: АККАУНТ -> ЗАКАЗ'); + AccountEdgeOrder::write($account->readId(), $data['order']->readId(), data: ['stts' => 'current']) or $data['order']->addError('errors', 'Не удалось инициализировать ребро: АККАУНТ -> ЗАКАЗ'); } // Если запись не удалась, то вернуть код: 500 Internal Server Error - $data['order']->writeSupply($supply_id, $delivery_type, (int) $amount) or yii::$app->response->statusCode = 500; + $data['order']->writeSupply($supply_id, $delivery, (int) $amount) or yii::$app->response->statusCode = 500; return $return; } @@ -421,73 +413,84 @@ class OrderController extends Controller */ public function actionDelete(): string|array|null { - // Инициализация + // Инициализация входных параметров (необязательных) $targets = yii::$app->request->post('targets') ?? yii::$app->request->get('targets'); $page = yii::$app->request->get('page') ?? yii::$app->request->post('page') ?? 1; - $account = yii::$app->user->identity; - $order = Order::searchByType(); - if ($targets) { - // Удаление выбранных целей (удаление из заказа) + // Инициализация аккаунта + $account = Account::initAccount(); - foreach (isset($targets[0]) && is_array($targets[0]) ? $targets : [$targets] as $target) { - // Унификация входных параметров + // Инициализация заказа + $order = Order::searchSmart($account)[0]['order'] ?? null; - foreach ($target as $catn => $amount) { - // Перебор целей + if (isset($order)) { + // Получены необходимые параметры - // Удаление - $order->deleteSupply([$catn => (int) $amount]); - } - } - } else { - // Целью подразумевается сам заказ (удаление заказа) - - // Инициализация - $order->stts = 'reserved'; - - if ($order->update()) { - // Запись в журнал - $order->journal('reserved'); - - // Поиск - $edge = AccountEdgeOrder::searchByVertex($account->readId(), $order->readId(), 'current'); - - if (count($edge) > 1) { - // Найден более чем 1 заказ - - return null; + if ($targets) { + // Удаление выбранных целей (удаление из заказа) + + foreach (isset($targets[0]) && is_array($targets[0]) ? $targets : [$targets] as $target) { + // Унификация входных параметров + + foreach ($target as $catn => $amount) { + // Перебор целей + + // Удаление + $order->deleteSupply([$catn => (int) $amount]); + } } + } else { + // Целью подразумевается сам заказ (удаление заказа) // Инициализация - $edge = $edge[0]; - $edge->type = 'reserved'; + $order->stts = 'reserved'; - // Запись - $edge->update(); + if ($order->update() > 0) { + // Сохранены изменения - // Реинициализация - $order = Order::searchByType(); + // Запись в журнал + $order->journal('reserved'); - if (empty($order)) { - // Корзина не инициализирована + // Поиск + $edge = AccountEdgeOrder::searchByVertex($account->readId(), $order->readId(), filter: ['stts' => 'current']); + + if (count($edge) > 1) { + // Найден более чем 1 заказ + + return null; + } // Инициализация - $order = new Order(); - $order->save() or throw new Exception('Не удалось инициализировать заказ'); + $edge = $edge[0]; + $edge->stts = 'reserved'; - // Подключение - $order->connect($account); + // Запись + $edge->update(); + + // Реинициализация + $order = Order::searchSmart($account); + + if (empty($order)) { + // Корзина не инициализирована + + // Инициализация + $order = new Order(); + $order->save() or throw new Exception('Не удалось инициализировать заказ'); + + // Подключение + $order->connect($account); + } } } } // Инициализация содержимого корзины - $connections = $order->content(10, $page); + $connections = $order->supplies(10, $page); if (yii::$app->request->isPost) { // POST-запрос + // Инициализация формата ответа yii::$app->response->format = Response::FORMAT_JSON; return [ @@ -510,7 +513,7 @@ class OrderController extends Controller $targets = yii::$app->request->post('targets') ?? yii::$app->request->get('targets'); $page = yii::$app->request->get('page') ?? yii::$app->request->post('page') ?? 1; $account = yii::$app->user->identity; - $order = Order::searchByType(); + $order = Order::searchSmart(); $connections = $order->content(10, $page); foreach (isset($targets[0]) && is_array($targets[0]) ? $targets : [$targets] as $target) { @@ -593,9 +596,9 @@ class OrderController extends Controller // Заполнены все необходимые поля для оформления заказа (подразумевается прохождение второго этапа регистрации) // Инициализация данных о заказе и поставках - $data = Order::searchByType(supplies: true)[0]; + $data = Order::searchSmart(supplies: true)[0]; - if (($account_edge_order = AccountEdgeOrder::searchByVertex(yii::$app->user->id, $data['order']->readId(), 'current')[0]) ?? false) { + if (($account_edge_order = AccountEdgeOrder::searchByVertex(yii::$app->user->id, $data['order']->readId(), filter: ['stts' => 'current'])[0]) ?? false) { // Найдено ребро: АККАУНТ -> ЗАКАЗ // Инициализация статуса необходимости реинициализации @@ -607,9 +610,69 @@ class OrderController extends Controller foreach ($order_edge_supply as $edge) { // Перебор рёбер: ЗАКАЗ -> ПОСТАВКА - if ($product = Product::searchBySupplyId($edge->_to)) { + if ($product = (Product::searchByCatnAndProd(($product = Product::searchBySupplyId($edge->_to))['catn'], $product['prod']))) { // Найден товар + if ($sender = Account::searchById($account_edge_order->_from)) { + // Найден отправитель + try { + // Инициализация данных геолокации + + // Инициализация буфера + $buffer = []; + + try { + $from = (int) $sender->opts['delivery_from_terminal'] ?? empty(Settings::searchActive()->delivery_from_default) ? 36 : (int) Settings::searchActive()->delivery_from_default; + } catch (Exception $e) { + $from = empty(Settings::searchActive()->delivery_from_default) ? 36 : (int) Settings::searchActive()->delivery_from_default; + } + + try { + $to = (int) $account->opts['delivery_to_terminal'] ?? 36; + } catch (Exception $e) { + $to = 36; + } + + if (($buffer_connection = $buffer['product']['bffr']["$from-$to-" . $edge['dlvr']['type']] ?? false) && time() < $buffer_connection['expires']) { + // Найдены данные доставки в буфере и их срок хранения не превышен, информация актуальна + + // Запись в буфер вывода + $buffer['delivery'] = $buffer_connection['data']; + } else { + // Инициализация доставки Dellin (автоматическая) + $product->bffr = ($product->bffr ?? []) + [ + "$from-$to-" . $edge['dlvr']['type'] => [ + 'data' => $buffer['delivery'] = Dellin::calcDeliveryAdvanced( + $from, + $to, + (int) ($buffer['product']['wght'] ?? 0), + (int) ($buffer['product']['dmns']['x'] ?? 0), + (int) ($buffer['product']['dmns']['y'] ?? 0), + (int) ($buffer['product']['dmns']['z'] ?? 0), + avia: $edge['dlvr']['type'] === 'avia' + ), + 'expires' => time() + 86400 + ] + ]; + + // Отправка в базу данных + $product->update(); + } + + // Запись даты доставки + $edge->dlvr = $edge->dlvr + ['data' => $buffer['delivery']]; + + // Запись в базу данных + $edge->update(); + } catch (Exception $e) { + // Удаление из заказа + $edge->delete(); + + // Продолжение цикла + continue; + } + } + if ($product['stts'] !== 'active') { // Не активен товар @@ -619,15 +682,18 @@ class OrderController extends Controller // Статус необходимости реинициализации $reinitialization = true; } + + // Удаление ребра: ПОСТАВКА -> ТОВАР (уменьшение количества товаров доступных для покупки) + SupplyEdgeProduct::searchByVertex($edge->_to, $product->readId(), 'connect')[0]->delete(); } } } // Реинициализация - if ($reinitialization) $data = Order::searchByType(supplies: true); + if ($reinitialization) $data = Order::searchSmart(supplies: true); // Запись - $account_edge_order->type = 'requested'; + $account_edge_order->stts = 'requested'; if ($account_edge_order->update() > 0) { // Удалось сохранить изменения @@ -656,7 +722,7 @@ class OrderController extends Controller } else { // Не заполнены все необходимые поля для оформления заказа (подразумевается прохождение второго этапа регистрации) - var_dump($account->getErrors()); + // var_dump($account->getErrors()); foreach ($account->getErrors() as $parameter => $errors) { // Перебор параметров с ошибками @@ -677,6 +743,85 @@ class OrderController extends Controller } } + /** + * Изменение статуса заказа + * + * @param string $order Идентификатор заказа (_key) + * + * @return string|array|null + */ + public function actionEditStts(string $order): string|array|null + { + // Инициализация аккаунта + $account = Account::initAccount(); + + if (isset($account)) { + // Найден аккаунт + + // Инициализация входных параметров + $stts = yii::$app->request->post('stts') ?? yii::$app->request->get('stts') ?? 'processing'; + + // Инициализация буфера вывода + $buffer = []; + + if (empty($order)) { + // Не получен обязательные параметры + + yii::$app->response->statusCode = 500; + + goto end; + } + + if ($account_edge_order = AccountEdgeOrder::searchByOrder(Order::collectionName() . '/' . $order)[0]) { + // Удалось найти ребро до заказа + + // Запись в буфер изначальных данных + $old = $account_edge_order->stts; + + // Запись в буфер записи в базу данных + $account_edge_order->stts = $stts; + + // Отправка в базу данных + if ($account_edge_order->update() > 0) { + // Удалось сохранить изменения + + // Инициализация аккаунта покупателя + $buyer = Account::searchById($account_edge_order->_from); + + // Отправка уведомления + Notification::_write($this->renderPartial('/notification/system/orders/edit', ['order' => $order, 'from' => Order::statusToRussian($old), 'to' => Order::statusToRussian($stts), 'target' => 'Статус']), true, $buyer->_key, Notification::TYPE_NOTICE); + + // Запись в буфер вывода + $buffer['stts'] = $account_edge_order->stts; + } else { + // Не удалось сохранить изменения + + yii::$app->response->statusCode = 500; + } + } + + end: + + // Запись обязательных параметров + $buffer['_csrf'] = yii::$app->request->getCsrfToken(); + + // Инициализация данных заказов + $data = Order::searchSmart(stts: '@last', limit: 10, page: 1, supplies: true); + + // Инициализация панели модератора заказов + if (!yii::$app->user->isGuest && Account::isMinimalAuthorized($account)) $moderator_data = Order::searchSmart(account: '@all', stts: '@last', limit: 10, page: 1, supplies: true); + else $moderator_data = null; + + // Запись в буфер вывода + $buffer['main'] = $this->renderPartial('/orders/index', compact('data', 'moderator_data')); + + // Настройка ответа + yii::$app->response->format = Response::FORMAT_JSON; + + return $buffer; + } + } + /** * Чтение инстанции поставки в заказе (order_edge_supply) * @@ -684,12 +829,12 @@ class OrderController extends Controller * * @return string|array|null */ - public function actionSupplyRead(string $catn, string $prod): string|array|null + public function actionSupplyRead(string $order, string $prod, string $catn, string $delivery): string|array|null { - // Инициализация + // Инициализация буфера вывода $buffer = []; - if (empty($catn) || empty($prod)) { + if (empty($order) || empty($prod) || empty($catn) || empty($delivery)) { // Не получены обязательные параметры yii::$app->response->statusCode = 500; @@ -697,92 +842,68 @@ class OrderController extends Controller goto end; } - if ($order_edge_supply = OrderEdgeSupply::searchById($_id = OrderEdgeSupply::collectionName() . '/' . $catn)) { - // Удалось найти инстанцию поставки + if ($order_edge_supply = OrderEdgeSupply::searchBySupplyData($catn, $prod, $delivery, Order::searchById(Order::collectionName() . "/$order"))) { + // Удалось найти рёбра: ЗАКАЗ -> ПОСТАВКА // Инициализация ребра: ПОСТАВКА -> ТОВАР - $supply_edge_product = SupplyEdgeProduct::searchBySupplyId($order_edge_supply->_to); + $supply_edge_product = SupplyEdgeProduct::searchBySupplyId($order_edge_supply[0]->_to)[0] ?? null; // Поиск ребра до аккаунта - $account = Account::searchBySupplyId($order_edge_supply->_to); + $account = Account::searchBySupplyId($order_edge_supply[0]->_to); // Поиск привязанного товара - $product = Product::searchBySupplyId($order_edge_supply->_to); + $product = Product::searchBySupplyId($order_edge_supply[0]->_to); - try { - // Инициализация данных геолокации - try { - $from = (int) $account['opts']['delivery_from_terminal'] ?? Settings::searchActive()->delivery_from_default ?? 36; - } catch (Exception $e) { - $from = (int) Settings::searchActive()->delivery_from_default ?? 36; - } + // Поиск привязанного товара + $supply = Supply::searchById($order_edge_supply[0]->_to); - try { - $to = (int) yii::$app->user->identity->opts['delivery_to_terminal'] ?? 36; - } catch (Exception $e) { - $to = 36; - } + // Инициализация доставки + if (empty($time = $order_edge_supply[0]->time)) { + // Не найден срок доставки (в днях) - // Инициализация доставки - $delivery = Dellin::calcDeliveryAdvanced( - $from, - $to, - (int) ($product['wght'] ?? 0), - (int) ($product['dmns']['x'] ?? 0), - (int) ($product['dmns']['y'] ?? 0), - (int) ($product['dmns']['z'] ?? 0), - avia: $order_edge_supply->dlvr['type'] === 'avia' - ); + if (empty($order_edge_supply[0]->dlvr['data'])) { + // Не удалось рассчитать доставку - if ($delivery['ready'] ?? false) { - // Указана дата готовности к получению - - // Инициализация доставки - $delivery = $delivery['ready']; + // Инициализация времени + $time = 0; } else { - // Не указана дата готовности к получению + // Удалось рассчитать доставку // Инициализация даты отправки try { // Взять данные из "arrivalToOspSender" (Дата прибытия на терминал-отправитель) - $delivery_send_date = DateTime::createFromFormat('Y-m-d', $delivery['orderDates']['arrivalToOspSender'])->getTimestamp(); + $delivery_send_date = DateTime::createFromFormat('Y-m-d', $order_edge_supply[0]->dlvr['data']['orderDates']['arrivalToOspSender'])->getTimestamp(); } catch (Throwable $e) { // Взять данные из "pickup" (Дата передачи груза на адресе отправителя) - $delivery_send_date = DateTime::createFromFormat('Y-m-d', $delivery['orderDates']['pickup'])->getTimestamp(); + $delivery_send_date = DateTime::createFromFormat('Y-m-d', $order_edge_supply[0]->dlvr['data']['orderDates']['pickup'])->getTimestamp(); } // Инициализация времени доставки try { // Доставка по воздуху (подразумевается), данные из "giveoutFromOspReceiver" (Дата и время, с которого груз готов к выдаче на терминале) - $delivery_converted = DateTime::createFromFormat('Y-m-d H:i:s', $delivery['orderDates']['giveoutFromOspReceiver'])->getTimestamp(); + // Оставлено на всякий случай для дальнейших разбирательств + + $delivery_converted = DateTime::createFromFormat('Y-m-d H:i:s', $order_edge_supply[0]->dlvr['data']['orderDates']['giveoutFromOspReceiver'])->getTimestamp(); } catch (Throwable $e) { + // Инициализация даты отправки + // Автоматическая доставка (подразумевается), данные из "arrivalToOspReceiver" (Дата прибытия натерминал-получатель) - - $delivery_converted = DateTime::createFromFormat('Y-m-d', $delivery['orderDates']['arrivalToOspReceiver'])->getTimestamp(); + $delivery_converted = DateTime::createFromFormat('Y-m-d', $order_edge_supply[0]->dlvr['data']['orderDates']['arrivalToOspReceiver'])->getTimestamp(); } - - // Инициализация доставки - $delivery = ceil(($delivery_converted - ($delivery_send_date ?? 0)) / 60 / 60 / 24) + 1; + $time = ceil(($delivery_converted - ($delivery_send_date ?? 0)) / 60 / 60 / 24); } - } catch (Exception $e) { - // var_dump($e->getMessage()); - // var_dump($e->getTrace()); - // var_dump($e->getFile()); die; - - // var_dump(json_decode($e->getMessage(), true)['errors']); die; } // Запись параметров - $buffer['cost'] = $order_edge_supply->cost ?? $order_edge_supply->cost = $supply_edge_product[0]['onec']['Цены']['Цена']['ЦенаЗаЕдиницу']; - $buffer['time'] = $order_edge_supply->time ?? $delivery ?? 0; - $buffer['comm'] = $order_edge_supply->comm ?? $order_edge_supply->comm = 'Комментарий к заказу'; - $buffer['stts'] = $order_edge_supply->stts ?? $order_edge_supply->stts = 0; - $buffer['id'] = $order_edge_supply->_key ?? 'Неизвестно'; - - $order_edge_supply->save(); + $buffer['cost'] = $order_edge_supply[0]->cost ?? $supply->cost ?? 0; + $buffer['time'] = $time ?? 0; + $buffer['amnt'] = count($order_edge_supply) ?? 0; + $buffer['comm'] = $order_edge_supply[0]->comm ?? ''; + $buffer['stts'] = $order_edge_supply[0]->stts ?? 'processing'; + $buffer['id'] = $order_edge_supply[0]->_key ?? 'Неизвестно'; } end: @@ -797,19 +918,30 @@ class OrderController extends Controller } /** - * Запись статуса поставки в заказе (order_edge_supply) + * Редактирование цены поставки в заказе (order_edge_supply) * - * @param string $catn Артикул поставки + * @param string $order Заказ в котором находится поставка + * @param string $prod Производитель + * @param string $catn Артикул + * @param string $delivery Тип доставки * * @return string|array|null */ - public function actionSupplyWriteStts(string $catn, string $prod): string|array|null + public function actionSupplyEditCost(string $order, string $prod, string $catn, string $delivery): string|array|null { - // Инициализация - $stts = yii::$app->request->post('stts') ?? yii::$app->request->get('stts') ?? ''; + // Инициализация входных параметров + $cost = yii::$app->request->post('cost') ?? yii::$app->request->get('cost'); + + // Инициализация буфера вывода $buffer = []; - if (empty($catn) || empty($prod)) { + // Инициализация аккаунта + $account = Account::initAccount(); + + // Инициализация заказа + $order = Order::searchById(Order::collectionName() . "/$order"); + + if (empty($order) || empty($prod) || empty($catn) || empty($delivery) || empty($cost)) { // Не получены обязательные параметры yii::$app->response->statusCode = 500; @@ -817,13 +949,169 @@ class OrderController extends Controller goto end; } - if ($supply = OrderEdgeSupply::searchBySupplyCatnAndProd($catn, $prod)) { + if ($order_edge_supply = OrderEdgeSupply::searchBySupplyData($catn, $prod, $delivery, $order)[0]) { // Удалось найти инстанцию поставки - var_dump($supply); + // Запись в буфер изначальных данных + $old = $order_edge_supply->cost; + + // Запись в буфер записи в базу данных + $order_edge_supply->cost = $cost; + + // Отправка в базу данных + if ($order_edge_supply->update() > 0) { + // Удалось сохранить изменения + + // Инициализация аккаунта покупателя + $buyer = Account::searchById(AccountEdgeOrder::searchByOrder($order->readId())[0]->_from); + + // Отправка уведомления + Notification::_write($this->renderPartial('/notification/system/orders/edit', ['order' => $order->_key, 'from' => $old, 'to' => $cost, 'target' => 'Цена поставки']), true, $buyer->_key, Notification::TYPE_NOTICE); + + // Запись в буфер вывода + $buffer['cost'] = $order_edge_supply->cost; + } else { + // Не удалось сохранить изменения + + yii::$app->response->statusCode = 500; + } } - if ($order_edge_supply = OrderEdgeSupply::searchById($_id = OrderEdgeSupply::collectionName() . '/' . $catn)) { + end: + + // Запись обязательных параметров + $buffer['_csrf'] = yii::$app->request->getCsrfToken(); + + // Инициализация данных заказов + $data = Order::searchSmart(stts: '@last', limit: 10, page: 1, supplies: true); + + // Инициализация панели модератора заказов + if (!yii::$app->user->isGuest && Account::isMinimalAuthorized($account)) $moderator_data = Order::searchSmart(account: '@all', stts: '@last', limit: 10, page: 1, supplies: true); + else $moderator_data = null; + + // Запись в буфер вывода + $buffer['main'] = $this->renderPartial('/orders/index', compact('data', 'moderator_data')); + + // Настройка ответа + yii::$app->response->format = Response::FORMAT_JSON; + + return $buffer; + } + + /** + * Редактирование времени доставки поставки в заказе (order_edge_supply) + * + * @param string $order Заказ в котором находится поставка + * @param string $prod Производитель + * @param string $catn Артикул + * @param string $delivery Тип доставки + * + * @return string|array|null + */ + public function actionSupplyEditTime(string $order, string $prod, string $catn, string $delivery): string|array|null + { + // Инициализация входных параметров + $time = yii::$app->request->post('time') ?? yii::$app->request->get('time'); + + // Инициализация буфера вывода + $buffer = []; + + // Инициализация аккаунта + $account = Account::initAccount(); + + // Инициализация заказа + $order = Order::searchById(Order::collectionName() . "/$order"); + + if (empty($order) || empty($prod) || empty($catn) || empty($delivery) || empty($time)) { + // Не получены обязательные параметры + + yii::$app->response->statusCode = 500; + + goto end; + } + + if ($order_edge_supply = OrderEdgeSupply::searchBySupplyData($catn, $prod, $delivery, $order)[0]) { + // Удалось найти инстанцию поставки + + // Запись в буфер изначальных данных + $old = $order_edge_supply->time; + + // Запись в буфер записи в базу данных + $order_edge_supply->time = $time; + + // Отправка в базу данных + if ($order_edge_supply->update() > 0) { + // Удалось сохранить изменения + + // Инициализация аккаунта покупателя + $buyer = Account::searchById(AccountEdgeOrder::searchByOrder($order->readId())[0]->_from); + + // Отправка уведомления + Notification::_write($this->renderPartial('/notification/system/orders/edit', ['order' => $order->_key, 'from' => $old, 'to' => $time + 1, 'target' => 'Дата получения поставки']), true, $buyer->_key, Notification::TYPE_NOTICE); + + // Запись в буфер вывода + $buffer['time'] = $order_edge_supply->time; + } else { + // Не удалось сохранить изменения + + yii::$app->response->statusCode = 500; + } + } + + end: + + // Запись обязательных параметров + $buffer['_csrf'] = yii::$app->request->getCsrfToken(); + + // Инициализация данных заказов + $data = Order::searchSmart(stts: '@last', limit: 10, page: 1, supplies: true); + + // Инициализация панели модератора заказов + if (!yii::$app->user->isGuest && Account::isMinimalAuthorized($account)) $moderator_data = Order::searchSmart(account: '@all', stts: '@last', limit: 10, page: 1, supplies: true); + else $moderator_data = null; + + // Запись в буфер вывода + $buffer['main'] = $this->renderPartial('/orders/index', compact('data', 'moderator_data')); + + // Настройка ответа + yii::$app->response->format = Response::FORMAT_JSON; + + return $buffer; + } + + /** + * Редактирование статуса поставки в заказе (order_edge_supply) + * + * @param string $order Заказ в котором находится поставка + * @param string $prod Производитель + * @param string $catn Артикул + * @param string $delivery Тип доставки + * + * @return string|array|null + */ + public function actionSupplyEditStts(string $order, string $prod, string $catn, string $delivery): string|array|null + { + // Инициализация входных параметров + $stts = yii::$app->request->post('stts') ?? yii::$app->request->get('stts') ?? ''; + + // Инициализация буфера вывода + $buffer = []; + + // Инициализация аккаунта + $account = Account::initAccount(); + + // Инициализация заказа + $order = Order::searchById(Order::collectionName() . "/$order"); + + if (empty($order) || empty($prod) || empty($catn) || empty($delivery) || empty($stts)) { + // Не получены обязательные параметры + + yii::$app->response->statusCode = 500; + + goto end; + } + + if ($order_edge_supply = OrderEdgeSupply::searchBySupplyData($catn, $prod, $delivery, $order)[0]) { // Удалось найти инстанцию поставки // Запись в буфер изначальных данных @@ -833,14 +1121,14 @@ class OrderController extends Controller $order_edge_supply->stts = $stts; // Отправка в базу данных - if ($order_edge_supply->save()) { + if ($order_edge_supply->update() > 0) { // Удалось сохранить изменения // Инициализация аккаунта покупателя - $account = Account::searchById(AccountEdgeOrder::searchByOrder($order_edge_supply->_from)[0]->_from); + $buyer = Account::searchById(AccountEdgeOrder::searchByOrder($order->readId())[0]->_from); // Отправка уведомления - Notification::_write($this->renderPartial('/notification/system/orders/edit', ['order' => $order_edge_supply->_from, 'from' => OrderEdgeSupply::convertStatusToRussian($old), 'to' => OrderEdgeSupply::convertStatusToRussian($stts), 'target' => 'Комментарий']), true, $account->_key, Notification::TYPE_NOTICE); + Notification::_write($this->renderPartial('/notification/system/orders/edit', ['order' => $order->_key, 'from' => Order::statusToRussian($old), 'to' => Order::statusToRussian($stts), 'target' => 'Статус поставки']), true, $buyer->_key, Notification::TYPE_NOTICE); // Запись в буфер вывода $buffer['stts'] = $order_edge_supply->stts; @@ -856,105 +1144,15 @@ class OrderController extends Controller // Запись обязательных параметров $buffer['_csrf'] = yii::$app->request->getCsrfToken(); - // Настройка ответа - yii::$app->response->format = Response::FORMAT_JSON; + // Инициализация данных заказов + $data = Order::searchSmart(stts: '@last', limit: 10, page: 1, supplies: true); - return $buffer; - } + // Инициализация панели модератора заказов + if (!yii::$app->user->isGuest && Account::isMinimalAuthorized($account)) $moderator_data = Order::searchSmart(account: '@all', stts: '@last', limit: 10, page: 1, supplies: true); + else $moderator_data = null; - /** - * Запись цены поставки в заказе (order_edge_supply) - * - * @param string $catn Артикул поставки - * - * @return string|array|null - */ - public function actionSupplyEditCost(int $catn): string|array|null - { - // Инициализация - $cost = yii::$app->request->post('cost') ?? yii::$app->request->get('cost'); - $buffer = []; - - if ($order_edge_supply = OrderEdgeSupply::searchById($_id = OrderEdgeSupply::collectionName() . '/' . $catn)) { - // Удалось найти инстанцию поставки - - // Запись в буфер изначальных данных - $old = $order_edge_supply->cost; - - // Запись в буфер записи в базу данных - $order_edge_supply->cost = $cost; - - // Отправка в базу данных - if ($order_edge_supply->save()) { - // Удалось сохранить изменения - - // Инициализация аккаунта покупателя - $account = Account::searchById(AccountEdgeOrder::searchByOrder($order_edge_supply->_from)[0]->_from); - - // Отправка уведомления - Notification::_write($this->renderPartial('/notification/system/orders/edit', ['order' => $order_edge_supply->_from, 'from' => $old, 'to' => $cost, 'target' => 'Цена']), true, $account->_key, Notification::TYPE_NOTICE); - - // Запись в буфер вывода - $buffer['cost'] = $order_edge_supply->cost; - } else { - // Не удалось сохранить изменения - - yii::$app->response->statusCode = 500; - } - } - - // Запись обязательных параметров - $buffer['_csrf'] = yii::$app->request->getCsrfToken(); - - // Настройка ответа - yii::$app->response->format = Response::FORMAT_JSON; - - return $buffer; - } - - /** - * Запись времени доставки поставки в заказе (order_edge_supply) - * - * @param int $_key Ключ записи в коллекции order_edge_supply - * - * @return string|array|null - */ - public function actionSupplyEditTime(int $_key): string|array|null - { - // Инициализация - $time = yii::$app->request->post('time') ?? yii::$app->request->get('time'); - $buffer = []; - - if ($order_edge_supply = OrderEdgeSupply::searchById($_id = OrderEdgeSupply::collectionName() . '/' . $_key)) { - // Удалось найти инстанцию поставки - - // Запись в буфер изначальных данных - $old = $order_edge_supply->time; - - // Запись в буфер записи в базу данных - $order_edge_supply->time = $time; - - // Отправка в базу данных - if ($order_edge_supply->save()) { - // Удалось сохранить изменения - - // Инициализация аккаунта покупателя - $account = Account::searchById(AccountEdgeOrder::searchByOrder($order_edge_supply->_from)[0]->_from); - - // Отправка уведомления - Notification::_write($this->renderPartial('/notification/system/orders/edit', ['order' => $order_edge_supply->_from, 'from' => $old, 'to' => $time, 'target' => 'Дата поставки']), true, $account->_key, Notification::TYPE_NOTICE); - - // Запись в буфер вывода - $buffer['time'] = $order_edge_supply->time; - } else { - // Не удалось сохранить изменения - - yii::$app->response->statusCode = 500; - } - } - - // Запись обязательных параметров - $buffer['_csrf'] = yii::$app->request->getCsrfToken(); + // Запись в буфер вывода + $buffer['main'] = $this->renderPartial('/orders/index', compact('data', 'moderator_data')); // Настройка ответа yii::$app->response->format = Response::FORMAT_JSON; @@ -965,17 +1163,36 @@ class OrderController extends Controller /** * Запись комментария поставки в заказе (order_edge_supply) * - * @param int $_key Ключ записи в коллекции order_edge_supply + * @param string $order Заказ в котором находится поставка + * @param string $prod Производитель + * @param string $catn Артикул + * @param string $delivery Тип доставки * * @return string|array|null */ - public function actionSupplyEditComm(int $_key): string|array|null + public function actionSupplyEditComm(string $order, string $prod, string $catn, string $delivery): string|array|null { - // Инициализация + // Инициализация входных параметров $comm = yii::$app->request->post('comm') ?? yii::$app->request->get('comm'); + + // Инициализация буфера вывода $buffer = []; - if ($order_edge_supply = OrderEdgeSupply::searchById($_id = OrderEdgeSupply::collectionName() . '/' . $_key)) { + // Инициализация аккаунта + $account = Account::initAccount(); + + // Инициализация заказа + $order = Order::searchById(Order::collectionName() . "/$order"); + + if (empty($order) || empty($prod) || empty($catn) || empty($delivery) || empty($comm)) { + // Не получены обязательные параметры + + yii::$app->response->statusCode = 500; + + goto end; + } + + if ($order_edge_supply = OrderEdgeSupply::searchBySupplyData($catn, $prod, $delivery, $order)[0]) { // Удалось найти инстанцию поставки // Запись в буфер изначальных данных @@ -985,14 +1202,14 @@ class OrderController extends Controller $order_edge_supply->comm = $comm; // Отправка в базу данных - if ($order_edge_supply->save()) { + if ($order_edge_supply->update() > 0) { // Удалось сохранить изменения // Инициализация аккаунта покупателя - $account = Account::searchById(AccountEdgeOrder::searchByOrder($order_edge_supply->_from)[0]->_from); + $buyer = Account::searchById(AccountEdgeOrder::searchByOrder($order->readId())[0]->_from); // Отправка уведомления - Notification::_write($this->renderPartial('/notification/system/orders/edit', ['order' => $order_edge_supply->_from, 'from' => $old, 'to' => $comm, 'target' => 'Комментарий']), true, $account->_key, Notification::TYPE_NOTICE); + Notification::_write($this->renderPartial('/notification/system/orders/edit', ['order' => $order->_key, 'from' => $old, 'to' => $comm, 'target' => 'Комментарий поставки']), true, $buyer->_key, Notification::TYPE_NOTICE); // Запись в буфер вывода $buffer['comm'] = $order_edge_supply->comm; @@ -1003,9 +1220,21 @@ class OrderController extends Controller } } + end: + // Запись обязательных параметров $buffer['_csrf'] = yii::$app->request->getCsrfToken(); + // Инициализация данных заказов + $data = Order::searchSmart(stts: '@last', limit: 10, page: 1, supplies: true); + + // Инициализация панели модератора заказов + if (!yii::$app->user->isGuest && Account::isMinimalAuthorized($account)) $moderator_data = Order::searchSmart(account: '@all', stts: '@last', limit: 10, page: 1, supplies: true); + else $moderator_data = null; + + // Запись в буфер вывода + $buffer['main'] = $this->renderPartial('/orders/index', compact('data', 'moderator_data')); + // Настройка ответа yii::$app->response->format = Response::FORMAT_JSON; diff --git a/mirzaev/skillparts/system/controllers/SearchController.php b/mirzaev/skillparts/system/controllers/SearchController.php index 3e8d84f..5c13ba3 100644 --- a/mirzaev/skillparts/system/controllers/SearchController.php +++ b/mirzaev/skillparts/system/controllers/SearchController.php @@ -143,6 +143,7 @@ class SearchController extends Controller 'dscr' => 'dscr', 'catg' => 'catg', 'imgs' => 'imgs', + 'name' => 'name', 'prod' => 'prod', 'dmns' => 'dmns', 'stts' => 'stts' diff --git a/mirzaev/skillparts/system/models/AccountEdgeOrder.php b/mirzaev/skillparts/system/models/AccountEdgeOrder.php index 5d59965..0988bb9 100644 --- a/mirzaev/skillparts/system/models/AccountEdgeOrder.php +++ b/mirzaev/skillparts/system/models/AccountEdgeOrder.php @@ -11,6 +11,68 @@ class AccountEdgeOrder extends Edge return 'account_edge_order'; } + /** + * Свойства + */ + public function attributes(): array + { + return array_merge( + parent::attributes(), + [ + 'stts' + ] + ); + } + + /** + * Метки свойств + */ + public function attributeLabels(): array + { + return array_merge( + parent::attributeLabels(), + [ + 'stts' => 'Статус' + ] + ); + } + + /** + * Правила + */ + public function rules(): array + { + return array_merge( + parent::rules(), + [ + [ + [ + 'stts' + ], + 'string' + ] + ] + ); + } + + /** + * Перед сохранением + * + * @todo Подождать обновление от ебаного Yii2 и добавить + * проверку типов передаваемых параметров + */ + public function beforeSave($data): bool + { + if (parent::beforeSave($data)) { + if ($this->isNewRecord) { + $this->stts = 'current'; + } + + return true; + } + return false; + } + /** * Поиск по идентификатору заказа * @@ -23,22 +85,4 @@ class AccountEdgeOrder extends Edge { return self::find()->where(['_to' => $order_id])->limit($limit)->all(); } - - /** - * Генерация ярлыка на русском языке для статуса заказа - * - * @param string $status Статус заказа - * - * @return string Ярлык статуса на русском языке - */ - public static function statusToRussian(string $status = ''): string - { - return match ($status) { - 'requested' => 'Запрошен', - 'accepted' => 'Ожидается отправка', - 'going' => 'Доставляется', - 'completed' => 'Завершен', - default => 'Обрабатывается' - }; - } } diff --git a/mirzaev/skillparts/system/models/Edge.php b/mirzaev/skillparts/system/models/Edge.php index faf2054..3d06e84 100644 --- a/mirzaev/skillparts/system/models/Edge.php +++ b/mirzaev/skillparts/system/models/Edge.php @@ -120,7 +120,7 @@ abstract class Edge extends Document // Настройка $edge->_from = $_from; $edge->_to = $_to; - $edge->type = $type; + if (isset($type)) $edge->type = $type; foreach ($data as $key => $value) { if (is_int($key)) { diff --git a/mirzaev/skillparts/system/models/Order.php b/mirzaev/skillparts/system/models/Order.php index 2e5b44d..7f8126c 100644 --- a/mirzaev/skillparts/system/models/Order.php +++ b/mirzaev/skillparts/system/models/Order.php @@ -96,7 +96,7 @@ class Order extends Document implements DocumentInterface public function connect(Account $account): ?AccountEdgeOrder { // Запись ребра: АККАУНТ -> ЗАКАЗ - return AccountEdgeOrder::write($account->readId(), $this->readId(), 'current') ?? throw new Exception('Не удалось инициализировать ребро: АККАУНТ -> ЗАКАЗ'); + return AccountEdgeOrder::write($account->readId(), $this->readId(), data: ['stts' => 'current']) ?? throw new Exception('Не удалось инициализировать ребро: АККАУНТ -> ЗАКАЗ'); } /** @@ -263,9 +263,9 @@ class Order extends Document implements DocumentInterface * * @todo Привести в порядок */ - public static function searchByType( + public static function searchSmart( Account|string $account = null, - string $type = 'current', + string $stts = 'current', string|null $search = null, int $limit = 1, int $page = 1, @@ -276,24 +276,28 @@ class Order extends Document implements DocumentInterface bool $count = false ): int|array|null { // Инициализация аккаунта - if (empty($account) && isset(yii::$app->user->identity)) { - // Данные не переданы + if (empty($account)) { + // Не получен аккаунт $subquery_where = [ [ - 'account._id' => yii::$app->user->identity->readId() + 'account._id' => Account::initAccount()->readId() ] ]; } else if ($account instanceof Account) { - // Передан аккаунт + // Получен аккаунт - $subquery_where = [ - [ - 'account._id' => $account->readId() - ] - ]; + if (Account::isMinimalAuthorized(Account::initAccount())) { + $subquery_where = [ + [ + 'account._id' => $account->readId() + ] + ]; + } else { + throw new Exception('У вас нет прав на обработку другого пользователя'); + } } else if (str_contains($account, '@all')) { - // Запрос на обработку всех аккаунтов + // Получен запрос на обработку всех аккаунтов $subquery_where = []; } else { @@ -301,11 +305,11 @@ class Order extends Document implements DocumentInterface } // Инициализация типа заказа - if (strcasecmp($type, 'all') !== 0) { + if (strcasecmp($stts, '@all') !== 0) { // Если не указан поиск всех заказов $subquery_where[] = [ - 'account_edge_order.type' => $type + 'account_edge_order.stts' => $stts ]; } @@ -409,7 +413,7 @@ class Order extends Document implements DocumentInterface * @todo В будущем возможно заказ не только поставок реализовать * Переписать реестр и проверку на дубликаты, не понимаю как они работают */ - public function supplies(int $limit = 1, int $page = 1, string|null $search = null, bool $count = false, $test = false): Supply|int|array|null + public function supplies(int $limit = 1, int $page = 1, string|null $search = null, bool $count = false): Supply|int|array|null { // Инициализация аккаунта $account = Account::initAccount(); @@ -564,17 +568,32 @@ class Order extends Document implements DocumentInterface */ public static function checkSuppliesStts(array $order_edge_supply): bool { - foreach ($order_edge_supply as $edge) { - // Перебор поставок + if (isset($order_edge_supply['_key'])) { + // Получено ребро: ЗАКАЗ -> ПОСТАВКА - if (empty($edge['stts']) || $edge['stts'] !== 'accepted') { - // Найдена неподтверждённая поставка + if (empty($order_edge_supply['stts']) || $order_edge_supply['stts'] === 'processing' || $order_edge_supply['stts'] === 'requested') { + // Найдена неподтверждённая поставка - return false; - } + return false; + } + + return true; + } else if (isset($order_edge_supply[0]['_key'])) { + // Получен массив (подразумевается, что с рёбрами: ЗАКАЗ -> ПОСТАВКА) + + foreach ($order_edge_supply as $edge) { + // Перебор поставок + + if (empty($edge['stts']) || $edge['stts'] === 'processing' || $edge['stts'] === 'requested') { + // Найдена неподтверждённая поставка + + return false; + } + } + return true; } - return true; + return false; } /** @@ -737,6 +756,47 @@ class Order extends Document implements DocumentInterface */ public static function count(int $limit = 500, bool $supplies = false): int { - return (int) self::searchByType(supplies: $supplies, type: $supplies ? 'current' : 'all', limit: $limit, count: true); + return (int) self::searchSmart(supplies: $supplies, stts: $supplies ? 'current' : '@all', limit: $limit, count: true); + } + + /** + * Генерация ярлыка на русском языке для статуса заказа + * + * @param string|null $status Статус заказа + * + * @return string Ярлык статуса на русском языке + */ + public static function statusToRussian(?string $status = 'processing'): string + { + return match ($status) { + 'processing' => 'Обрабатывается', + 'requested' => 'Запрошен', + 'accepted' => 'Ожидается отправка', + 'going' => 'Доставляется', + 'ready' => 'Готов к выдаче', + 'completed' => 'Завершен', + 'reserved' => 'Резервирован', + default => 'Обрабатывается' + }; + } + + /** + * Генерация списка статусов на русском языке + * + * @param string|null $active Активный статус, который выведется первым в списке + * + * @return string Лист статусов на русском языке + */ + public static function statusListInRussian(?string $active = 'processing'): array + { + return [(empty($active) ? 'processing' : $active) => static::statusToRussian($active)] + [ + 'processing' => 'Обрабатывается', + 'requested' => 'Запрошен', + 'accepted' => 'Ожидается отправка', + 'going' => 'Доставляется', + 'ready' => 'Готов к выдаче', + 'completed' => 'Завершен', + 'reserved' => 'Резервирован' + ]; } } diff --git a/mirzaev/skillparts/system/models/OrderEdgeSupply.php b/mirzaev/skillparts/system/models/OrderEdgeSupply.php index a3ad355..0212c62 100644 --- a/mirzaev/skillparts/system/models/OrderEdgeSupply.php +++ b/mirzaev/skillparts/system/models/OrderEdgeSupply.php @@ -14,7 +14,6 @@ class OrderEdgeSupply extends Edge return 'order_edge_supply'; } - /** * Свойства */ @@ -118,7 +117,7 @@ class OrderEdgeSupply extends Edge /** - * Поиск поставки по артикулу + * Поиск по данным поставки * * @param string $catn Артикул * @param Order $order Заказ @@ -126,7 +125,7 @@ class OrderEdgeSupply extends Edge * * @return array Поставки */ - public static function searchBySupplyCatnAndProd(string $catn, string $prod, Order $order = null, int $limit = 10): array + public static function searchBySupplyData(string $catn, string $prod, ?string $delivery = null, ?Order $order = null, int $limit = 10): array { if ($supply = Supply::searchByCatnAndProd($catn, $prod)) { // Поставка найдена @@ -134,6 +133,12 @@ class OrderEdgeSupply extends Edge if (isset($order)) { // Поиск только по определённому заказу + if (isset($delivery)) { + // Поиск только по определённым типам доставки + + return self::find()->where(['_from' => $order->readId(), '_to' => $supply->readId(), 'order_edge_supply.dlvr.type' => $delivery])->limit($limit)->all(); + } + return self::find()->where(['_from' => $order->readId(), '_to' => $supply->readId()])->limit($limit)->all(); } @@ -143,21 +148,21 @@ class OrderEdgeSupply extends Edge return []; } - /** - * Генерация ярлыка на русском языке для статуса заказа поставки + * Генерация ярлыка на русском языке для статуса заказа * - * @param string $status Статус заказа поставки + * @param string|null $status Статус заказа * * @return string Ярлык статуса на русском языке */ - public static function statusToRussian(string $status = ''): string + public static function statusToRussian(?string $status = 'processing'): string { return match ($status) { 'requested' => 'Запрошен', 'accepted' => 'Ожидается отправка', 'going' => 'Доставляется', 'completed' => 'Завершен', + 'processing' => 'Обрабатывается', default => 'Обрабатывается' }; } diff --git a/mirzaev/skillparts/system/views/invoice/order/pattern.pdf b/mirzaev/skillparts/system/views/invoice/order/pattern.pdf new file mode 100755 index 0000000000000000000000000000000000000000..fe347073a43f04321a961a7776775455024c8b65 GIT binary patch literal 8680 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 IOBwM00KCh4A^-pY literal 0 HcmV?d00001 diff --git a/mirzaev/skillparts/system/views/notification/system/orders/edit.php b/mirzaev/skillparts/system/views/notification/system/orders/edit.php index fba82a2..fe2e73f 100644 --- a/mirzaev/skillparts/system/views/notification/system/orders/edit.php +++ b/mirzaev/skillparts/system/views/notification/system/orders/edit.php @@ -1 +1 @@ -

Данные заказа # изменены: с на

+

#: с "" на ""

diff --git a/mirzaev/skillparts/system/views/orders/index.php b/mirzaev/skillparts/system/views/orders/index.php index 3b37966..34cc8b2 100644 --- a/mirzaev/skillparts/system/views/orders/index.php +++ b/mirzaev/skillparts/system/views/orders/index.php @@ -42,18 +42,18 @@ if (empty($window)) { />
- - - - + + $label) : ?> + +
-
+
jrnl as $entry) { // Перебор записей в журнале @@ -76,18 +76,18 @@ if (empty($window)) { // Конвертация данных из буфера $date = [ 'H:i' => (new DateTime())->setTimestamp($date)->setTimezone(new DateTimeZone($timezone))->format('H:i'), - 'm.d.Y' => (new DateTime())->setTimestamp($date)->setTimezone(new DateTimeZone($timezone))->format('m.d.Y') + 'm.d.Y' => (new DateTime())->setTimestamp($date)->setTimezone(new DateTimeZone($timezone))->format('d.m.Y') ]; ?>

#_key ?>

- +

-
+
0) { // Пройдена проверка на количество поставок в заказе - // if (Order::checkSuppliesStts($order_edge_supply)) { - // $status = ''; - // } else { - $status = ''; - // } + if (Order::checkSuppliesStts($supply['edge'])) $status = "_key}_{$prod}_{$catn}_{$delivery}_supply_stts_indicator_icon\" class=\"ml-auto my-auto fas fa-check\">"; + else $status = ''; // Инициализация иконки $icon = $delivery === 'avia' ? 'fa-plane' : 'fa-truck'; // Генерация HTML echo << + -

- {$catn} x{$supply['amount']} +

+ {$catn} $status

@@ -166,9 +163,30 @@ if (empty($window)) {

Выберите поставку

+ 'form_profile_settings', + 'action' => false, + 'fieldConfig' => [ + 'template' => '{label}{input}', + ], + 'options' => [ + 'onsubmit' => 'return false;', + 'class' => 'row' + ] + ]); + + // Инициализация ребра до заказа + $account_edge_order = AccountEdgeOrder::searchByOrder($moderator_data['order']->readId())[0]; + ?> + + field($account_edge_order, 'stts', ['options' => ['class' => "mb-1 w-100"]]) + ->dropDownList(Order::statusListInRussian($account_edge_order->stts), [ + 'onChange' => "return orders_status_edit('{$moderator_data['order']->_key}', this);", + 'data-old-value' => $account_edge_order->stts + ])->label(false); ?> + Покупатель будет уведомлён + +