From 5f3623a258f8e783b1dff778f5186150644dc716 Mon Sep 17 00:00:00 2001 From: Arsen Mirzaev Tatyano-Muradovich Date: Mon, 26 Jul 2021 05:27:41 +1000 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B4=20=D1=81=D0=B0=D0=B9=D1=82=D0=BE=D0=BC=2016?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mirzaev/skillparts/system/assets/AppAsset.php | 1 + .../controllers/AuthenticationController.php | 22 ++- .../system/controllers/InvoiceController.php | 14 +- .../system/controllers/OrderController.php | 185 ++++++++++++++---- .../system/controllers/ProductController.php | 13 +- .../system/controllers/ProfileController.php | 28 ++- .../system/controllers/VerifyController.php | 88 +++++++-- mirzaev/skillparts/system/models/Account.php | 94 ++++----- mirzaev/skillparts/system/models/Order.php | 30 ++- .../skillparts/system/views/account/index.php | 30 +-- .../skillparts/system/views/orders/index.php | 16 +- .../skillparts/system/views/profile/index.php | 4 +- mirzaev/skillparts/system/web/css/main.css | 8 +- mirzaev/skillparts/system/web/js/account.js | 44 +++-- .../skillparts/system/web/js/moment.min.js | 2 + mirzaev/skillparts/system/web/js/orders.js | 27 ++- mirzaev/skillparts/system/web/js/product.js | 2 +- .../skillparts/system/web/js/product_panel.js | 16 +- 18 files changed, 443 insertions(+), 181 deletions(-) create mode 100644 mirzaev/skillparts/system/web/js/moment.min.js diff --git a/mirzaev/skillparts/system/assets/AppAsset.php b/mirzaev/skillparts/system/assets/AppAsset.php index acab48f..c801b8d 100644 --- a/mirzaev/skillparts/system/assets/AppAsset.php +++ b/mirzaev/skillparts/system/assets/AppAsset.php @@ -38,6 +38,7 @@ class AppAsset extends AssetBundle 'https://cdn.jsdelivr.net/bxslider/4.1.1/jquery.bxslider.min.js', 'https://unpkg.com/cookielib/src/cookie.min.js', 'https://api-maps.yandex.ru/2.0-stable/?load=package.standard&lang=ru-RU', + 'js/moment.min.js', 'js/menu.js', 'js/main.js', 'js/account.js', diff --git a/mirzaev/skillparts/system/controllers/AuthenticationController.php b/mirzaev/skillparts/system/controllers/AuthenticationController.php index 5bbc015..cc0a3c8 100644 --- a/mirzaev/skillparts/system/controllers/AuthenticationController.php +++ b/mirzaev/skillparts/system/controllers/AuthenticationController.php @@ -39,8 +39,16 @@ class AuthenticationController extends Controller // Инициализация $model = new AccountForm(yii::$app->request->post('AccountForm')); $type = yii::$app->request->post('type') ?? yii::$app->request->get('type'); + $target = yii::$app->request->post('target') ?? yii::$app->request->get('target'); $model->scenario = $model::SCENARIO_AUTHENTICATION; + // Фильтрация + $target = match ($target) { + 'menu' => 'menu', + 'main' => 'main', + default => 'main' + }; + if (yii::$app->request->isPost) { // AJAX-POST-запрос @@ -48,13 +56,13 @@ class AuthenticationController extends Controller yii::$app->response->format = Response::FORMAT_JSON; // Валидация формы - if (!empty($errors = ActiveForm::validate($model))) { + // if (!empty($errors = ActiveForm::validate($model))) { - // Настройка кода ответа - yii::$app->response->statusCode = 401; + // // Настройка кода ответа + // yii::$app->response->statusCode = 401; - return $errors; - }; + // return $errors; + // }; if (!yii::$app->user->isGuest || $model->authentication()) { // Аккаунт аутентифицирован @@ -69,7 +77,7 @@ class AuthenticationController extends Controller // Запись ответа $return = [ - 'menu' => $this->renderPartial('/account/panel/authenticated', compact( + $target => $this->renderPartial('/account/panel/authenticated', compact( 'notifications_button', 'notifications_panel', 'notifications_panel_full' @@ -123,7 +131,7 @@ class AuthenticationController extends Controller yii::$app->response->statusCode = 400; return [ - 'main' => $this->renderPartial('/account/index', compact('model')), + $target => $this->renderPartial('/account/index', compact('model')), 'redirect' => '/authentication', '_csrf' => yii::$app->request->getCsrfToken() ]; diff --git a/mirzaev/skillparts/system/controllers/InvoiceController.php b/mirzaev/skillparts/system/controllers/InvoiceController.php index 192f73b..876ef89 100644 --- a/mirzaev/skillparts/system/controllers/InvoiceController.php +++ b/mirzaev/skillparts/system/controllers/InvoiceController.php @@ -30,7 +30,17 @@ class InvoiceController extends Controller // Инициализация файла $file = YII_PATH_PUBLIC . '/../assets/invoices/' . $order . '/invoice.xlsx'; - if (file_exists($file)) return $this->response->sendFile($file); - else yii::$app->response->statusCode = 500; + if (file_exists($file)) { + // Удалось найти файл + + return $this->response->sendFile($file); + } else { + // Не удалось найти файл + + // Запись кода ответа + yii::$app->response->statusCode = 500; + + return yii::$app->response->redirect('/orders'); + } } } diff --git a/mirzaev/skillparts/system/controllers/OrderController.php b/mirzaev/skillparts/system/controllers/OrderController.php index e2d019f..cb6dd3c 100644 --- a/mirzaev/skillparts/system/controllers/OrderController.php +++ b/mirzaev/skillparts/system/controllers/OrderController.php @@ -18,11 +18,13 @@ use app\models\AccountEdgeOrder; use app\models\connection\Dellin; use app\models\Invoice; use app\models\Notification; +use app\models\Settings; use app\models\SupplyEdgeProduct; use Codeception\PHPUnit\ResultPrinter\HTML; use DateTime; use Exception; +use Throwable; class OrderController extends Controller { @@ -38,7 +40,6 @@ class OrderController extends Controller 'actions' => [ 'index', 'accept', - 'read', 'write', 'delete', 'amount-update', @@ -62,13 +63,23 @@ class OrderController extends Controller public function accessDenied() { - // Инициализация + // Инициализация cookie $cookies = yii::$app->response->cookies; + // Инициализация данных из HTTP-заголовка referrer + $referrer = trim(parse_url(yii::$app->request->referrer, PHP_URL_PATH) . '?' . parse_url(yii::$app->request->referrer, PHP_URL_QUERY), '/'); + + $redirect = match(yii::$app->request->pathInfo) { + 'order/write' => $referrer, + 'order/delete', 'order/amount-update', 'order/request' => 'cart', + 'order/accept', 'order/supply-read', 'order/supply-write-stts', 'order/supply-edit-time', 'order/supply-edit-cost', 'order/supply-edit-comm' => 'orders', + default => yii::$app->request->pathInfo + }; + // Запись cookie с редиректом, который выполнится после авторизации $cookies->add(new Cookie([ 'name' => 'redirect', - 'value' => yii::$app->request->pathInfo + 'value' => $redirect ])); if (yii::$app->request->isPost) { @@ -90,11 +101,100 @@ class OrderController extends Controller } } - public function actionIndex(string $type = 'all') + public function actionIndex(string $filter = 'all') { - // Инициализация - $orders = Order::search(type: $type, limit: 10, page: 1, select: '{account_edge_order, order}', supplies: true); - $moderator_orders = self::genOrdersForModeration(); + // Инициализация cookie + $cookies = yii::$app->response->cookies; + + // Инициализация фильтра по типу + if ($filter === 'last') { + // Запрошено использование прошлых данных о фильтрации по типу + + // Чтение сохраненных cookie с данными прошлой фильтрации по типу + $filter = $cookies->get('filter'); + } else { + // Запрошена сортировка + + // Запись cookie с данными текущей фильтрации по типу + $cookies->add(new Cookie([ + 'name' => 'filter', + 'value' => $filter + ])); + } + + // Инициализация входных данных + $from = yii::$app->request->post('from') ?? yii::$app->request->get('from'); + $to = yii::$app->request->post('to') ?? yii::$app->request->get('to'); + + // Инициализация фильтра по периоду + if (!empty($from) && !empty($to) && filter_var($from, FILTER_VALIDATE_INT) && filter_var($to, FILTER_VALIDATE_INT)) { + // Данные фильтра по периоду переданы и представляют собой целые числа (подразумевается unixtime) + + // Конвертация типов + $from = (int) $from; + $to = (int) $to; + + // Запись cookie с данными начала периода + $cookies->add(new Cookie([ + 'name' => 'from', + 'value' => $from + ])); + + // Запись cookie с данными окончания периода + $cookies->add(new Cookie([ + 'name' => 'to', + 'value' => $to + ])); + } else { + // Некоректные данные или их отсутствие + + // Чтение сохраненных cookie с данными прошлой фильтрации по периоду (начало) + $from = $cookies->get('from'); + + // Чтение сохраненных cookie с данными прошлой фильтрации по периоду (конец) + $to = $cookies->get('to'); + + if (empty($from) || empty($to) || filter_var($from, FILTER_VALIDATE_INT) || filter_var($to, FILTER_VALIDATE_INT)) { + // Каких-то cookie не оказалось, либо данные в них не подходящие, либо это первый запрос, но без фильтрации по периоду + + // Реинициализация на стандартные параметры (неделя) + $from = time() - 604800; + $to = time(); + } else { + // Данные в cookie найдены и подходят для выполнения + + // Конвертация типов + $from = (int) $from; + $to = (int) $to; + } + } + + // Инициализация заказов + $orders = Order::search( + type: $filter, + limit: 10, + page: 1, + select: '{account_edge_order, order}', + supplies: true, + from: $from, + to: $to + ); + + if ( + !yii::$app->user->isGuest + && yii::$app->user->identity->type === 'administrator' + || yii::$app->user->identity->type === 'moderator' + ) { + // Пользователь имеет доступ + + // Инициализация заказов для модератора + $moderator_orders = self::genOrdersForModeration(); + } else { + // Пользователь не имеет доступ + + // Инициализация заглушки + $moderator_orders = null; + } if (yii::$app->request->isPost) { // POST-запрос @@ -102,8 +202,12 @@ class OrderController extends Controller // Настройка yii::$app->response->format = Response::FORMAT_JSON; + // Конвертация из UNIXTIME в формат поддерживаемый календарём по спецификации HTML + $from = DateTime::createFromFormat('U', (string) $from)->format('Y-m-d'); + $to = DateTime::createFromFormat('U', (string) $to)->format('Y-m-d'); + return [ - 'main' => $this->renderPartial('/orders/index', compact('orders', 'moderator_orders')), + 'main' => $this->renderPartial('/orders/index', compact('orders', 'moderator_orders', 'from', 'to')), 'title' => 'Заказы', 'redirect' => '/orders', '_csrf' => yii::$app->request->getCsrfToken() @@ -382,6 +486,9 @@ class OrderController extends Controller if ($edge->update()) { // Удалось сохранить изменения + // Запись в журнал + $model->journal('requested'); + // Инициализация буфера поставок $supplies = []; @@ -412,31 +519,11 @@ class OrderController extends Controller ] ])); - // Запись в журнал - $model->journal('requested'); - // Отправка уведомлений модераторам Notification::_write($this->renderPartial('/notification/system/orders/new', ['id' => $edge->_key]), true, '@auth', Notification::TYPE_MODERATOR_ORDER_NEW); } - // Инициализация - $orders = Order::search(type: 'all', limit: 10, page: 1, select: '{account_edge_order, order}', supplies: true); - $moderator_orders = self::genOrdersForModeration(); - - if (yii::$app->request->isPost) { - // POST-запрос - - yii::$app->response->format = Response::FORMAT_JSON; - - return [ - 'main' => $this->renderPartial('/orders/index', compact('orders', 'moderator_orders')), - 'title' => 'Заказы', - 'redirect' => '/orders', - '_csrf' => yii::$app->request->getCsrfToken() - ]; - } - - return $this->render('/orders/index', compact('orders', 'moderator_orders')); + return $this->actionIndex(); } /** @@ -486,10 +573,23 @@ class OrderController extends Controller $product = Product::searchBySupplyId($order_edge_supply->_to); try { + // Инициализация данных геолокации + try { + $from = (int) $account['opts']['delivery_from_terminal'] ?? Settings::search()->delivery_from_default ?? 36; + } catch (Exception $e) { + $from = (int) Settings::search()->delivery_from_default ?? 36; + } + + try { + $to = (int) yii::$app->user->identity->opts['delivery_to_terminal'] ?? 36; + } catch (Exception $e) { + $to = 36; + } + // Инициализация доставки $delivery = Dellin::calcDeliveryAdvanced( - $account['opts']['delivery_from_terminal'], - yii::$app->user->identity->opts['delivery_to_terminal'], + $from, + $to, (int) ($product['wght'] ?? 0), (int) ($product['dmns']['x'] ?? 0), (int) ($product['dmns']['y'] ?? 0), @@ -497,13 +597,30 @@ class OrderController extends Controller avia: $order_edge_supply->dlvr['type'] === 'avia' ); - // Рассчет времени + // Инициализация даты отправки try { + // Взять данные из "arrivalToOspSender" (Дата прибытия на терминал-отправитель) + + $delivery_send_date = DateTime::createFromFormat('Y-m-d', $delivery['orderDates']['arrivalToOspSender'])->getTimestamp(); + } catch (Throwable $e) { + // Взять данные из "pickup" (Дата передачи груза на адресе отправителя) + + $delivery_send_date = DateTime::createFromFormat('Y-m-d', $delivery['orderDates']['pickup'])->getTimestamp(); + } + + // Инициализация времени доставки + try { + // Доставка по воздуху (подразумевается), данные из "giveoutFromOspReceiver" (Дата и время, с которого груз готов к выдаче на терминале) + $delivery_converted = DateTime::createFromFormat('Y-m-d H:i:s', $delivery['orderDates']['giveoutFromOspReceiver'])->getTimestamp(); - } catch (Exception $e) { + } catch (Throwable $e) { + // Автоматическая доставка (подразумевается), данные из "arrivalToOspReceiver" (Дата прибытия натерминал-получатель) + $delivery_converted = DateTime::createFromFormat('Y-m-d', $delivery['orderDates']['arrivalToOspReceiver'])->getTimestamp(); } - $delivery = ceil(($delivery_converted - time()) / 60 / 60 / 24) + 1; + + // Рассчет времени доставки + $delivery = ceil(($delivery_converted - ($delivery_send_date ?? 0)) / 60 / 60 / 24) + 1; } catch (Exception $e) { // var_dump($e->getMessage()); // var_dump($e->getTrace()); diff --git a/mirzaev/skillparts/system/controllers/ProductController.php b/mirzaev/skillparts/system/controllers/ProductController.php index 4d9c9e6..cb35b7d 100644 --- a/mirzaev/skillparts/system/controllers/ProductController.php +++ b/mirzaev/skillparts/system/controllers/ProductController.php @@ -115,6 +115,7 @@ class ProductController extends Controller // Товар обновлён $return['main'] = $this->renderPartial('index', compact('model')); + $return['redirect'] = '/product/' . $model->catn; } } @@ -131,10 +132,16 @@ class ProductController extends Controller return $return; } - if ($model = Product::searchByCatn($catn)) { - return $this->render('index', compact('model')); + if (Product::searchByCatn($catn)) { + // Старый товар ещё существует (подразумевается, что произошла ошибка) + + // Возврат на страницу товара + return $this->redirect("/product/$catn"); } else { - return $this->redirect('/'); + // Старый товар не существует (подразумевается, что его артикул успешно изменён) + + // Переадресация на новую страницу товара + return $this->redirect("/product/$model->catn"); } } diff --git a/mirzaev/skillparts/system/controllers/ProfileController.php b/mirzaev/skillparts/system/controllers/ProfileController.php index 66c39b5..56b0543 100644 --- a/mirzaev/skillparts/system/controllers/ProfileController.php +++ b/mirzaev/skillparts/system/controllers/ProfileController.php @@ -29,6 +29,12 @@ class ProfileController extends Controller 'access' => [ 'class' => AccessControl::class, 'rules' => [ + [ + 'allow' => true, + 'actions' => [ + 'geolocation-init' + ] + ], [ 'allow' => true, 'roles' => ['@'], @@ -37,8 +43,7 @@ class ProfileController extends Controller 'supplies', 'import', 'monitoring', - 'readGroups', - 'geolocation-init' + 'readGroups' ] ], [ @@ -468,8 +473,21 @@ class ProfileController extends Controller { if (Yii::$app->request->isPost) { // POST-запрос - // Инициализация аккаунта - $account ?? $account = yii::$app->user->identity; + + if (is_null($account)) { + // Данные аккаунта не переданы + + if (yii::$app->user->isGuest) { + // Аккаунт не аутентифицирован + + return false; + } else { + // Аккаунт аутентифицирован + + // Инициализация + $account = yii::$app->user->identity; + } + } // Инициализация IP-адреса $ip = yii::$app->request->userIp === 'localhost' || yii::$app->request->userIp === '127.0.0.1' ? '46.226.227.20' : yii::$app->request->userIp; @@ -509,6 +527,6 @@ class ProfileController extends Controller return false; } - yii::$app->response->redirect('/'); + return false; } } diff --git a/mirzaev/skillparts/system/controllers/VerifyController.php b/mirzaev/skillparts/system/controllers/VerifyController.php index 1a945e8..c42370c 100644 --- a/mirzaev/skillparts/system/controllers/VerifyController.php +++ b/mirzaev/skillparts/system/controllers/VerifyController.php @@ -19,14 +19,57 @@ class VerifyController extends Controller if (Account::verification($vrfy, auth: true)) { // Успешно подтверждена регистрация - return $this->redirect('/'); + return $this->redirect('/profile'); } return ErrorController::throw('Ошибка подтверждения регистрации', 'Код подтверждения не совпадает с тем, что мы отправили вам на почту, либо регистрация уже была подтверждена. Свяжитесь с администрацией'); } else { // Простой запрос - return $this->render('/account/verify'); + if (yii::$app->user->isGuest) { + // Пользователь не аутентифицирован + + return yii::$app->response->redirect('/registration'); + } else { + // Пользователь аутентифицирован + + if (yii::$app->user->identity->vrfy === true) { + // Регистрация аккаунта уже подтверждена + + if (yii::$app->request->isPost) { + // POST-запрос + + // Запись формата ответа + yii::$app->response->format = Response::FORMAT_JSON; + + return [ + 'main' => $this->renderPartial('/profile/index'), + 'title' => 'Профиль', + 'redirect' => '/profile', + '_csrf' => yii::$app->request->getCsrfToken() + ]; + } else { + // GET-запрос (подразумевается) + + return $this->render('/profile/index'); + } + } else { + // Регистрация аккаунта ещё не подтверждена + + if (yii::$app->request->isPost) { + // POST-запрос + + // Запись формата ответа + yii::$app->response->format = Response::FORMAT_JSON; + + return $this->genPostVerify(); + } else { + // GET-запрос (подразумевается) + + return $this->render('/account/verify'); + } + } + } } } @@ -37,24 +80,39 @@ class VerifyController extends Controller */ public function actionSend(): string|array { - yii::$app->user->identity->verifyRegenerate(); + if (!yii::$app->user->isGuest) { + // Пользователь аутентифицирован - yii::$app->user->identity->sendMailVerify(); + // Регенерация кода подтверждения + yii::$app->user->identity->verifyRegenerate(); - if (yii::$app->request->isPost) { - // POST-запрос + // Отправка кода подтверждения на почту + yii::$app->user->identity->sendMailVerify(); - yii::$app->response->format = Response::FORMAT_JSON; + if (yii::$app->request->isPost) { + // POST-запрос - return [ - 'main' => $this->renderPartial('/account/verify'), - 'title' => 'Корзина', - '_csrf' => yii::$app->request->getCsrfToken() - ]; - } else { - // Подразумевается как GET-запрос + // Запись формата ответа + yii::$app->response->format = Response::FORMAT_JSON; - return $this->render('/account/verify'); + return $this->genPostVerify(); + } else { + // GET-запрос (подразумевается) + + return $this->render('/account/verify'); + } } } + + /** + * Генерация данных для POST-запроса с переадресацией на страницу подтверждения + */ + function genPostVerify(): array { + return [ + 'main' => $this->renderPartial('/account/verify'), + 'title' => 'Подтверждение аккаунта', + 'redirect' => '/account/verify', + '_csrf' => yii::$app->request->getCsrfToken() + ]; + } } diff --git a/mirzaev/skillparts/system/models/Account.php b/mirzaev/skillparts/system/models/Account.php index 0cdcbce..1b8abd9 100644 --- a/mirzaev/skillparts/system/models/Account.php +++ b/mirzaev/skillparts/system/models/Account.php @@ -259,6 +259,53 @@ class Account extends Document implements IdentityInterface, PartnerInterface return static::find()->where(['type' => 'moderator'])->orWhere(['type' => 'administrator'])->all(); } + /** + * Подтверждение регистрации + */ + public static function verification(string $vrfy, bool $auth = false): bool + { + if ($account = static::findByVrfy($vrfy)) { + // Аккаунт найден + + // Запись в буфер + $account->vrfy = true; + + // Отправка изменений + $updated = $account->update() > 0; + + if ($updated && $auth) { + // Регистрация была подтверждена, а так же запрошена автоматическая аутентификация + + // Аутентификация + yii::$app->user->login($account, true ? 3600 * 24 * 30 : 0); + } + + return $updated; + } + + return false; + } + + /** + * Проверка пароля + */ + public function validatePassword(string $pswd): bool + { + // return yii::$app->security->validatePassword($pswd, $this->pswd); + return $pswd === $this->pswd; + } + + /** + * Проверка аутентификационного ключа + * + * @todo Подождать обновление Yii2 и добавить + * проверку типов передаваемых параметров + */ + public function validateAuthKey($auth): bool + { + return $this->getAuthKey() === $auth; + } + /** * Проверка почты */ @@ -311,53 +358,6 @@ class Account extends Document implements IdentityInterface, PartnerInterface } } - /** - * Подтверждение регистрации - */ - public static function verification(string $vrfy, bool $auth = false): bool - { - if ($account = static::findByVrfy($vrfy)) { - // Аккаунт найден - - // Запись в буфер - $account->vrfy = true; - - // Отправка изменений - $updated = $account->update() > 0; - - if ($updated && $auth) { - // Регистрация была подтверждена, а так же запрошена автоматическая аутентификация - - // Аутентификация - yii::$app->user->login($account, true ? 3600 * 24 * 30 : 0); - } - - return $updated; - } - - return false; - } - - /** - * Проверка пароля - */ - public function validatePassword(string $pswd): bool - { - // return yii::$app->security->validatePassword($pswd, $this->pswd); - return $pswd === $this->pswd; - } - - /** - * Проверка аутентификационного ключа - * - * @todo Подождать обновление Yii2 и добавить - * проверку типов передаваемых параметров - */ - public function validateAuthKey($auth): bool - { - return $this->getAuthKey() === $auth; - } - /** * Записать параметр * diff --git a/mirzaev/skillparts/system/models/Order.php b/mirzaev/skillparts/system/models/Order.php index a115185..6af90b8 100644 --- a/mirzaev/skillparts/system/models/Order.php +++ b/mirzaev/skillparts/system/models/Order.php @@ -237,7 +237,7 @@ class Order extends Document implements DocumentInterface * * @todo Привести в порядок */ - public static function search(Account|string $account = null, string $type = 'current', int $limit = 1, int $page = 1, string $select = null, bool $supplies = false): self|array|null + public static function search(Account|string $account = null, string $type = 'current', int $limit = 1, int $page = 1, string $select = null, bool $supplies = false, int|null $from = null, int|null $to = null): self|array|null { // Инициализация аккаунта if (empty($account) && isset(yii::$app->user->identity)) { @@ -276,13 +276,35 @@ class Order extends Document implements DocumentInterface // Инициализация сдвига по запрашиваемым данным (пагинация) $offset = $limit * ($page - 1); - // Запрос + // Инициализация фильтрации + if (isset($from, $to)) { + // Задан период + + // Инициализация логики + $foreach = [ + ['edge' => 'account_edge_order'], + ['jrnl' => 'order.jrnl'] + ]; + + // Инициализация фильтра + $where = "edge._to == order._id && jrnl.action == 'requested' && jrnl.date >= $from && jrnl.date <= $to"; + } else { + // Ничего не задано + + // Инициализация логики + $foreach = ['edge' => 'account_edge_order']; + + // Инициализация фильтра + $where = "edge._to == order._id"; + } + + // Запрос на поиск заказов $return = self::searchByEdge( from: 'account', to: 'order', subquery_where: $subquery_where, - foreach: ['edge' => 'account_edge_order'], - where: 'edge._to == order._id', + foreach: $foreach, + where: $where, limit: $limit, offset: $offset, sort: ['DESC'], diff --git a/mirzaev/skillparts/system/views/account/index.php b/mirzaev/skillparts/system/views/account/index.php index 6dc3ed7..9a48e40 100644 --- a/mirzaev/skillparts/system/views/account/index.php +++ b/mirzaev/skillparts/system/views/account/index.php @@ -17,12 +17,21 @@ use app\models\AccountForm;
$form_id, @@ -35,10 +44,7 @@ use app\models\AccountForm; ], 'options' => [ 'class' => 'form_account', - 'onsubmit' => 'return false;', - 'data' => [ - 'pjax' => true - ] + 'onsubmit' => 'return false;' ], 'enableClientValidation' => false, 'enableAjaxValidation' => true @@ -61,11 +67,11 @@ use app\models\AccountForm; - field($model, 'mail', ['enableLabel' => false, 'options' => ['class' => 'mb-2'], 'errorOptions' => ['class' => 'help-block help-block-error small']])->textInput(['autofocus' => true, 'placeholder' => $model->getAttributeLabel('mail')]) ?> - field($model, 'pswd', ['enableLabel' => false, 'errorOptions' => ['class' => 'help-block help-block-error small']])->passwordInput(['placeholder' => $model->getAttributeLabel('pswd')]) ?> + field($model, 'mail', ['enableLabel' => false, 'options' => ['class' => 'mb-2'], 'errorOptions' => ['class' => 'help-block help-block-error px-2 small']])->textInput(['autofocus' => true, 'placeholder' => $model->getAttributeLabel('mail')]) ?> + field($model, 'pswd', ['enableLabel' => false, 'errorOptions' => ['class' => 'help-block help-block-error px-2 small']])->passwordInput(['placeholder' => $model->getAttributeLabel('pswd')]) ?>
- 'submitAuthentication', 'onclick' => 'authentication(this.parentElement.parentElement);', 'class' => 'flex-grow-1 mr-2 btn btn-primary button_clean']) ?> + 'submitAuthentication', 'onclick' => 'authentication(this.parentElement.parentElement, \'' . $target . '\');', 'class' => 'flex-grow-1 mr-2 btn btn-primary button_clean']) ?> field($model, 'auto', ['checkboxTemplate' => '
{beginLabel}' . Html::submitButton('{labelTitle}', ['name' => 'submit', 'data-toggle' => 'button', 'class' => 'w-100 btn btn-primary button_clean', 'aria-pressed' => 'false', 'onclick' => 'return authentication_auto_button_status_switch(this);']) . '{endLabel}
'])->checkbox()->label($model->getAttributeLabel('auto'), ['class' => 'w-100 m-0']) ?> @@ -77,8 +83,6 @@ use app\models\AccountForm; ActiveForm::end(); - Pjax::end(); - ?>
diff --git a/mirzaev/skillparts/system/views/orders/index.php b/mirzaev/skillparts/system/views/orders/index.php index 486b912..2b95734 100644 --- a/mirzaev/skillparts/system/views/orders/index.php +++ b/mirzaev/skillparts/system/views/orders/index.php @@ -182,19 +182,15 @@ if (
- День - Неделя - Месяц - Год + День + Неделя + Месяц + Год
-
- -
+

-

-
- -
+
diff --git a/mirzaev/skillparts/system/views/profile/index.php b/mirzaev/skillparts/system/views/profile/index.php index a913c8e..6f10ce9 100644 --- a/mirzaev/skillparts/system/views/profile/index.php +++ b/mirzaev/skillparts/system/views/profile/index.php @@ -87,7 +87,7 @@ if ( // Инициализация $model ?? $model = yii::$app->user->identity; - $delivery_from_terminal_list or $delivery_from_terminal_list = ['Нет данных']; + $delivery_from_terminal_list ?? $delivery_from_terminal_list = ['Нет данных']; ?> field($model, 'opts[delivery_from_terminal]', ['options' => ['class' => "mb-1"]]) @@ -118,7 +118,7 @@ if ( // Инициализация $model ?? $model = yii::$app->user->identity; - $import_oem_list or $import_oem_list = ['Нет данных']; + $import_oem_list ?? $import_oem_list = ['Нет данных']; ?> field($model, 'opts[import_supplies_oem]', ['options' => ['class' => "mb-1"]]) diff --git a/mirzaev/skillparts/system/web/css/main.css b/mirzaev/skillparts/system/web/css/main.css index b4c8542..502cc4c 100644 --- a/mirzaev/skillparts/system/web/css/main.css +++ b/mirzaev/skillparts/system/web/css/main.css @@ -70,7 +70,6 @@ main { .button_clean_full:focus, .button_clean_full:active { outline : none !important; - box-shadow: none !important; } .button_clean_full, @@ -81,6 +80,13 @@ main { background: none !important; } +.form_control_clean, +.form_control_clean:hover, +.form_control_clean:focus, +.form_control_clean:active { + box-shadow: none !important; +} + .button_blue_simple { color : #eee; background-color: #123EAB; diff --git a/mirzaev/skillparts/system/web/js/account.js b/mirzaev/skillparts/system/web/js/account.js index 032f432..ab98d79 100644 --- a/mirzaev/skillparts/system/web/js/account.js +++ b/mirzaev/skillparts/system/web/js/account.js @@ -11,7 +11,8 @@ function identification() { document.addEventListener('DOMContentLoaded', identification(), true); -function authentication(form) { +function authentication(form, target = 'main') { + if (form == undefined) { form = { '_csrf': yii.getCsrfToken() @@ -20,10 +21,17 @@ function authentication(form) { form = $(form).serializeArray(); } - form.push({ - name: 'type', - value: 'authentication' - }); + form.push( + { + name: 'type', + value: 'authentication' + }, + { + name: 'target', + value: target + } + ); + $.ajax({ url: '/authentication', @@ -248,6 +256,19 @@ function account_response(data, status, xhr) { // reinitialization(main); // } + main_response(data, status, xhr); +} + +function account_response_success(data, status, xhr) { + // Обработка ответов от удавшихся запросов + + // Реинициализация панели поиска + // Перенести в отдельный файл который подгружается в зависимости от настроек + // search_panel_show(); + + // // Обновление панели поиска + // product_search(); + if (data !== undefined) { // Получены данные с сервера @@ -264,19 +285,6 @@ function account_response(data, status, xhr) { } } - main_response(data, status, xhr); -} - -function account_response_success(data, status, xhr) { - // Обработка ответов от удавшихся запросов - - // Реинициализация панели поиска - // Перенести в отдельный файл который подгружается в зависимости от настроек - // search_panel_show(); - - // // Обновление панели поиска - // product_search(); - account_response(data, status, xhr); } diff --git a/mirzaev/skillparts/system/web/js/moment.min.js b/mirzaev/skillparts/system/web/js/moment.min.js new file mode 100644 index 0000000..3783892 --- /dev/null +++ b/mirzaev/skillparts/system/web/js/moment.min.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,i;function f(){return e.apply(null,arguments)}function o(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function u(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function m(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function l(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(var t in e)if(m(e,t))return;return 1}function r(e){return void 0===e}function h(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function a(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function d(e,t){for(var n=[],s=0;s>>0,s=0;sFe(e)?(r=e+1,a-Fe(e)):(r=e,a);return{year:r,dayOfYear:o}}function Ae(e,t,n){var s,i,r=Ge(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+je(i=e.year()-1,t,n):a>je(e.year(),t,n)?(s=a-je(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function je(e,t,n){var s=Ge(e,t,n),i=Ge(e+1,t,n);return(Fe(e)-s+i)/7}C("w",["ww",2],"wo","week"),C("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),A("week",5),A("isoWeek",5),ce("w",te),ce("ww",te,Q),ce("W",te),ce("WW",te,Q),ge(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=Z(e)});function Ie(e,t){return e.slice(t,7).concat(e.slice(0,t))}C("d",0,"do","day"),C("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),C("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),C("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),C("e",0,0,"weekday"),C("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),A("day",11),A("weekday",11),A("isoWeekday",11),ce("d",te),ce("e",te),ce("E",te),ce("dd",function(e,t){return t.weekdaysMinRegex(e)}),ce("ddd",function(e,t){return t.weekdaysShortRegex(e)}),ce("dddd",function(e,t){return t.weekdaysRegex(e)}),ge(["dd","ddd","dddd"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:y(n).invalidWeekday=e}),ge(["d","e","E"],function(e,t,n,s){t[s]=Z(e)});var Ze="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ze="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),qe=de,Be=de,Je=de;function Qe(){function e(e,t){return t.length-e.length}for(var t,n,s,i,r=[],a=[],o=[],u=[],l=0;l<7;l++)t=_([2e3,1]).day(l),n=me(this.weekdaysMin(t,"")),s=me(this.weekdaysShort(t,"")),i=me(this.weekdays(t,"")),r.push(n),a.push(s),o.push(i),u.push(n),u.push(s),u.push(i);r.sort(e),a.sort(e),o.sort(e),u.sort(e),this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function Xe(){return this.hours()%12||12}function Ke(e,t){C(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function et(e,t){return t._meridiemParse}C("H",["HH",2],0,"hour"),C("h",["hh",2],0,Xe),C("k",["kk",2],0,function(){return this.hours()||24}),C("hmm",0,0,function(){return""+Xe.apply(this)+T(this.minutes(),2)}),C("hmmss",0,0,function(){return""+Xe.apply(this)+T(this.minutes(),2)+T(this.seconds(),2)}),C("Hmm",0,0,function(){return""+this.hours()+T(this.minutes(),2)}),C("Hmmss",0,0,function(){return""+this.hours()+T(this.minutes(),2)+T(this.seconds(),2)}),Ke("a",!0),Ke("A",!1),L("hour","h"),A("hour",13),ce("a",et),ce("A",et),ce("H",te),ce("h",te),ce("k",te),ce("HH",te,Q),ce("hh",te,Q),ce("kk",te,Q),ce("hmm",ne),ce("hmmss",se),ce("Hmm",ne),ce("Hmmss",se),ye(["H","HH"],Me),ye(["k","kk"],function(e,t,n){var s=Z(e);t[Me]=24===s?0:s}),ye(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),ye(["h","hh"],function(e,t,n){t[Me]=Z(e),y(n).bigHour=!0}),ye("hmm",function(e,t,n){var s=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s)),y(n).bigHour=!0}),ye("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s,2)),t[Se]=Z(e.substr(i)),y(n).bigHour=!0}),ye("Hmm",function(e,t,n){var s=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s))}),ye("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s,2)),t[Se]=Z(e.substr(i))});var tt=z("Hours",!0);var nt,st={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Te,monthsShort:Ne,week:{dow:0,doy:6},weekdays:Ze,weekdaysMin:$e,weekdaysShort:ze,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){for(var t,n,s,i,r=0;r=t&&function(e,t){for(var n=Math.min(e.length,t.length),s=0;s=t-1)break;t--}r++}return nt}function ut(t){var e;if(void 0===it[t]&&"undefined"!=typeof module&&module&&module.exports)try{e=nt._abbr,require("./locale/"+t),lt(e)}catch(e){it[t]=null}return it[t]}function lt(e,t){var n;return e&&((n=r(t)?dt(e):ht(e,t))?nt=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),nt._abbr}function ht(e,t){if(null===t)return delete it[e],null;var n,s=st;if(t.abbr=e,null!=it[e])Y("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])s=it[t.parentLocale]._config;else{if(null==(n=ut(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;s=n._config}return it[e]=new x(b(s,t)),rt[e]&&rt[e].forEach(function(e){ht(e.name,e.config)}),lt(e),it[e]}function dt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return nt;if(!o(e)){if(t=ut(e))return t;e=[e]}return ot(e)}function ct(e){var t,n=e._a;return n&&-2===y(e).overflow&&(t=n[ve]<0||11xe(n[pe],n[ve])?ke:n[Me]<0||24je(n,r,a)?y(e)._overflowWeeks=!0:null!=u?y(e)._overflowWeekday=!0:(o=Ee(n,s,i,r,a),e._a[pe]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(r=St(e._a[pe],s[pe]),(e._dayOfYear>Fe(r)||0===e._dayOfYear)&&(y(e)._overflowDayOfYear=!0),n=Ve(r,0,e._dayOfYear),e._a[ve]=n.getUTCMonth(),e._a[ke]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=u[t]=s[t];for(;t<7;t++)e._a[t]=u[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[Me]&&0===e._a[De]&&0===e._a[Se]&&0===e._a[Ye]&&(e._nextDay=!0,e._a[Me]=0),e._d=(e._useUTC?Ve:function(e,t,n,s,i,r,a){var o;return e<100&&0<=e?(o=new Date(e+400,t,n,s,i,r,a),isFinite(o.getFullYear())&&o.setFullYear(e)):o=new Date(e,t,n,s,i,r,a),o}).apply(null,u),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[Me]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(y(e).weekdayMismatch=!0)}}function Ot(e){if(e._f!==f.ISO_8601)if(e._f!==f.RFC_2822){e._a=[],y(e).empty=!0;for(var t,n,s,i,r,a,o,u=""+e._i,l=u.length,h=0,d=H(e._f,e._locale).match(N)||[],c=0;cn.valueOf():n.valueOf()"}),pn.toJSON=function(){return this.isValid()?this.toISOString():null},pn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},pn.unix=function(){return Math.floor(this.valueOf()/1e3)},pn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},pn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},pn.eraName=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;nthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},pn.isLocal=function(){return!!this.isValid()&&!this._isUTC},pn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},pn.isUtc=At,pn.isUTC=At,pn.zoneAbbr=function(){return this._isUTC?"UTC":""},pn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},pn.dates=n("dates accessor is deprecated. Use date instead.",fn),pn.months=n("months accessor is deprecated. Use month instead",Ue),pn.years=n("years accessor is deprecated. Use year instead",Le),pn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),pn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!r(this._isDSTShifted))return this._isDSTShifted;var e,t={};return v(t,this),(t=bt(t))._a?(e=(t._isUTC?_:Tt)(t._a),this._isDSTShifted=this.isValid()&&0