From 177de6b3ef7d7d8ca7f606fbe81fccd321ef90d6 Mon Sep 17 00:00:00 2001 From: Arsen Mirzaev Tatyano-Muradovich Date: Sun, 25 Jul 2021 09:05:14 +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 --- composer.json | 3 +- composer.lock | 53 ++++++++++++- mirzaev/skillparts/system/assets/AppAsset.php | 4 +- .../controllers/AuthenticationController.php | 10 ++- .../system/controllers/CartController.php | 4 +- .../system/controllers/ProfileController.php | 72 ++++++++++++++++- mirzaev/skillparts/system/models/Account.php | 17 ++-- .../skillparts/system/models/AccountForm.php | 2 +- mirzaev/skillparts/system/models/Dellin.php | 10 +++ .../skillparts/system/views/account/index.php | 20 ++++- .../skillparts/system/views/cart/index.php | 79 +++++++++++-------- .../skillparts/system/views/layouts/main.php | 2 +- .../skillparts/system/views/orders/index.php | 39 +++++---- mirzaev/skillparts/system/web/css/main.css | 8 +- mirzaev/skillparts/system/web/js/account.js | 29 ++++++- .../skillparts/system/web/js/geolocation.js | 34 ++++++++ 16 files changed, 303 insertions(+), 83 deletions(-) create mode 100644 mirzaev/skillparts/system/web/js/geolocation.js diff --git a/composer.json b/composer.json index ef2f72f..006cd4d 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,8 @@ "mirzaev/yii2-arangodb": ">=2.1.x-dev", "mirzaev/yii2-arangodb-sessions": ">=1.1.x-dev", "guzzlehttp/guzzle": "^7.3", - "phpoffice/phpspreadsheet": "^1.18" + "phpoffice/phpspreadsheet": "^1.18", + "hflabs/dadata": "^20.12" }, "require-dev": { "codeception/codeception": ">=4.1", diff --git a/composer.lock b/composer.lock index 5c8b738..ba81eda 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "695a3f9969bbc0bbc0650efdc2e245af", + "content-hash": "fcf19d2c1a3e56a85324e01a1c6c55ab", "packages": [ { "name": "bower-asset/bootstrap", @@ -704,6 +704,57 @@ }, "time": "2021-04-26T09:17:50+00:00" }, + { + "name": "hflabs/dadata", + "version": "20.12.0", + "source": { + "type": "git", + "url": "https://github.com/hflabs/dadata-php.git", + "reference": "c6db345bb4a389423ba14f6c4c626d830c0d9992" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hflabs/dadata-php/zipball/c6db345bb4a389423ba14f6c4c626d830c0d9992", + "reference": "c6db345bb4a389423ba14f6c4c626d830c0d9992", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~6.0|^7.0", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Dadata\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "HFLabs and contributors", + "homepage": "https://github.com/hflabs/dadata-php/contributors" + } + ], + "description": "Data cleansing, enrichment and suggestions via Dadata API", + "homepage": "https://github.com/nalgeon/dadata-php", + "keywords": [ + "DaData", + "api", + "php", + "suggestions" + ], + "support": { + "issues": "https://github.com/hflabs/dadata-php/issues", + "source": "https://github.com/hflabs/dadata-php/tree/20.12.0" + }, + "time": "2020-12-24T15:49:58+00:00" + }, { "name": "imagine/imagine", "version": "1.2.4", diff --git a/mirzaev/skillparts/system/assets/AppAsset.php b/mirzaev/skillparts/system/assets/AppAsset.php index 2f07432..acab48f 100644 --- a/mirzaev/skillparts/system/assets/AppAsset.php +++ b/mirzaev/skillparts/system/assets/AppAsset.php @@ -37,12 +37,14 @@ class AppAsset extends AssetBundle 'js/bootstrap/bootstrap.min.js', '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/menu.js', 'js/main.js', 'js/account.js', 'js/search.js', 'js/notification.js', - 'js/reinitialization.js' + 'js/reinitialization.js', + 'js/geolocation.js' ]; public $jsOptions = [ // 'position' => View::POS_HEAD diff --git a/mirzaev/skillparts/system/controllers/AuthenticationController.php b/mirzaev/skillparts/system/controllers/AuthenticationController.php index 029603d..5bbc015 100644 --- a/mirzaev/skillparts/system/controllers/AuthenticationController.php +++ b/mirzaev/skillparts/system/controllers/AuthenticationController.php @@ -44,10 +44,17 @@ class AuthenticationController extends Controller if (yii::$app->request->isPost) { // AJAX-POST-запрос + // Настройка кода ответа yii::$app->response->format = Response::FORMAT_JSON; // Валидация формы - if (!empty($errors = ActiveForm::validate($model))) return $errors; + if (!empty($errors = ActiveForm::validate($model))) { + + // Настройка кода ответа + yii::$app->response->statusCode = 401; + + return $errors; + }; if (!yii::$app->user->isGuest || $model->authentication()) { // Аккаунт аутентифицирован @@ -112,6 +119,7 @@ class AuthenticationController extends Controller } else { // Аккаунт не аутентифицирован + // Настройка кода ответа yii::$app->response->statusCode = 400; return [ diff --git a/mirzaev/skillparts/system/controllers/CartController.php b/mirzaev/skillparts/system/controllers/CartController.php index 2f5e1ac..1850ecc 100644 --- a/mirzaev/skillparts/system/controllers/CartController.php +++ b/mirzaev/skillparts/system/controllers/CartController.php @@ -4,18 +4,18 @@ declare(strict_types=1); namespace app\controllers; -use app\models\Notification; use yii; use yii\filters\AccessControl; use yii\web\Controller; use yii\web\Response; +use yii\web\Cookie; use app\models\Product; use app\models\Order; use app\models\OrderEdgeSupply; +use app\models\Notification; use Exception; -use yii\web\Cookie; class CartController extends Controller { diff --git a/mirzaev/skillparts/system/controllers/ProfileController.php b/mirzaev/skillparts/system/controllers/ProfileController.php index 912ffc4..66c39b5 100644 --- a/mirzaev/skillparts/system/controllers/ProfileController.php +++ b/mirzaev/skillparts/system/controllers/ProfileController.php @@ -16,8 +16,11 @@ use app\models\SupplyGroup; use app\models\Search; use app\models\Notification; use app\models\Settings; +use app\models\Dellin; use app\models\SettingsEdgeSettings; +use Dadata\DadataClient as Dadata; + class ProfileController extends Controller { public function behaviors() @@ -29,7 +32,14 @@ class ProfileController extends Controller [ 'allow' => true, 'roles' => ['@'], - 'actions' => ['index', 'supplies', 'import', 'monitoring', 'readGroups'] + 'actions' => [ + 'index', + 'supplies', + 'import', + 'monitoring', + 'readGroups', + 'geolocation-init' + ] ], [ 'allow' => true, @@ -121,8 +131,7 @@ class ProfileController extends Controller $delivery_from_terminal_list = $model->genListTerminalsFrom(); $delivery_to_terminal_list = $model->genListTerminalsTo(); $import_oem_list = $model->genListOem(Supply::searchByAccount(select: 'supply.onec["ЗначенияСвойств"]')); - $array_unshift_in_start = function (array &$array, string|int $key, mixed $value) - { + $array_unshift_in_start = function (array &$array, string|int $key, mixed $value) { $array = array_reverse($array, true); $array[$key] = $value; return $array = array_reverse($array, true); @@ -191,7 +200,7 @@ class ProfileController extends Controller if (!$model_settings = Settings::readLast()) { $model_settings = new Settings(); - if(!$model_settings->save()) { + if (!$model_settings->save()) { $this->redirect('/'); } } @@ -447,4 +456,59 @@ class ProfileController extends Controller return $groups; } + + /** + * Инициализация данных о геолокации + * + * @param string|null $account + * + * @return bool + */ + public function actionGeolocationInit(string|null $account = null): bool + { + if (Yii::$app->request->isPost) { + // POST-запрос + // Инициализация аккаунта + $account ?? $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; + + // Настройка ответа + yii::$app->response->format = Response::FORMAT_JSON; + + // Проверка записи геолокации + if (isset($account->geol)) { + // Удалось найти данные геолокации + + return true; + } else { + // Не удалось найти данные геолокации + + // Инициализация данных геолокации + $dadata = new Dadata(yii::$app->params['dadata']['key'], null); + + // Запись в буфер + $account->geol = $dadata->iplocate($ip); + + // Синхронизация с базой данных ДеловыеЛинии + if ($dellin = Dellin::searchByCityKladr(str_pad($account->geol['data']['city_kladr_id'], 25, '0000000000000000000000'))) { + // Удалось найти город с терминалами ДеловыеЛинии + + // Запись связанного с городом терминала в настройки пользователя + // !!! Берётся первый попавшийся терминал + $account->opts = [ + 'delivery_to_terminal' => $dellin['data']['terminals']['terminal'][0]['id'] + ] + ($account->opts ?? []); + + // Отправка данных из буфера в базу данных + return $account->update() >= 1; + } + } + + return false; + } + + yii::$app->response->redirect('/'); + } } diff --git a/mirzaev/skillparts/system/models/Account.php b/mirzaev/skillparts/system/models/Account.php index 76b5990..0cdcbce 100644 --- a/mirzaev/skillparts/system/models/Account.php +++ b/mirzaev/skillparts/system/models/Account.php @@ -51,6 +51,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface 'agnt', 'type', 'vrfy', + 'geol', 'acpt' ] ); @@ -78,6 +79,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface 'agnt' => 'Агент (поставщик)', 'type' => 'Тип аккаунта', 'vrfy' => 'Статус подтверждения владением почты', + 'geol' => 'Геолокация', 'acpt' => 'Согласие с офертой' ] ); @@ -390,13 +392,13 @@ class Account extends Document implements IdentityInterface, PartnerInterface * * Актуальное (выбранное, активное) значение записывается первым */ - public function genListCity(): array + public function genListCity(): void { - $browser = new Dellin(); + // $browser = new Dellin(); - $request = $browser->get('https://api.github.com/user', [ - 'auth' => ['user', 'pass'] - ]); + // $request = $browser->get('https://api.github.com/user', [ + // 'auth' => ['user', 'pass'] + // ]); } /** @@ -723,7 +725,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface } . ' ' . match (rand(1, 15)) { 1 => 'забыли', - 2 => 'отжали', + 2 => 'испортили', 3 => 'забрали', 4 => 'порвали', 5 => 'украли', @@ -736,6 +738,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface 12 => 'испортили', 13 => 'добили', 14 => 'разбили', + 15 => 'сорвали', default => 'сломали' } . ' ' . match (rand(1, 9)) { @@ -749,7 +752,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface 8 => 'поменяю', default => 'куплю' } - . ' в скиллпартсе'; + . ' в скиллпартс'; } /** diff --git a/mirzaev/skillparts/system/models/AccountForm.php b/mirzaev/skillparts/system/models/AccountForm.php index 7360abd..689997d 100644 --- a/mirzaev/skillparts/system/models/AccountForm.php +++ b/mirzaev/skillparts/system/models/AccountForm.php @@ -107,7 +107,7 @@ class AccountForm extends Model return [ 'mail' => 'Почта', 'pswd' => 'Пароль', - 'auto' => '', + 'auto' => '', 'pols' => 'Политика конфедециальности' ]; } diff --git a/mirzaev/skillparts/system/models/Dellin.php b/mirzaev/skillparts/system/models/Dellin.php index 8bb26d1..4e040c2 100644 --- a/mirzaev/skillparts/system/models/Dellin.php +++ b/mirzaev/skillparts/system/models/Dellin.php @@ -43,6 +43,16 @@ class Dellin extends Document return static::findOne(['data["id"]' => $id]); } + /** + * Поиск по КЛАДР-коду города + * + * @param string $id Код КЛАДР города + */ + public static function searchByCityKladr(string $code): ?static + { + return static::findOne(['data["code"]' => $code]); + } + /** * Поиск по идентификатору терминала * diff --git a/mirzaev/skillparts/system/views/account/index.php b/mirzaev/skillparts/system/views/account/index.php index edd352c..6dc3ed7 100644 --- a/mirzaev/skillparts/system/views/account/index.php +++ b/mirzaev/skillparts/system/views/account/index.php @@ -4,6 +4,7 @@ declare(strict_types=1); use yii\helpers\Html; use yii\bootstrap\ActiveForm; +use yii\widgets\Pjax; use app\models\AccountForm; @@ -16,6 +17,10 @@ use app\models\AccountForm;
[ 'class' => 'form_account', - 'onsubmit' => 'return false;' + 'onsubmit' => 'return false;', + 'data' => [ + 'pjax' => true + ] ], 'enableClientValidation' => false, 'enableAjaxValidation' => true @@ -59,13 +67,19 @@ use app\models\AccountForm;
'submitAuthentication', 'onclick' => 'authentication(this.parentElement.parentElement);', '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']) . + 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']) ?>
'submitRegistration', 'onclick' => 'return registration_start(this.parentElement);', 'class' => 'col-12 ml-auto btn btn-success btn-sm button_clean']) ?> - +
diff --git a/mirzaev/skillparts/system/views/cart/index.php b/mirzaev/skillparts/system/views/cart/index.php index 4dde4ef..f42a73b 100644 --- a/mirzaev/skillparts/system/views/cart/index.php +++ b/mirzaev/skillparts/system/views/cart/index.php @@ -39,72 +39,85 @@ use DateTime; foreach ($connections as $connection) { // Перебор поставок - // Инициализация доставки - if (isset($connection['delivery']['error'])) { - // Не удалось рассчитать доставку + // Инициализация переменных + extract($connection); - // Инициализация индикатора - $delivery_icon = ''; + // Инициализация цены + $price_raw = $cost; + $price = $price_raw . ' ' . $currency; + + // Инициализация типа доставки + $delivery_type = reset($order_edge_supply)['dlvr']['type'] ?? 'auto'; + + // Инициализация индикатора + $delivery_icon = match ($delivery_type) { + 'avia' => '', + default => '' + }; + + // Инициализация доставки + if (isset($delivery['error']) || $delivery === '?') { + // Не удалось рассчитать доставку // Инициализация времени $delivery = '?'; - - // Инициализация цены - $cost = '?'; } else { // Удалось рассчитать доставку - // Инициализация типа доставки - $delivery_type = reset($connection['order_edge_supply'])['dlvr']['type'] ?? 'auto'; - - // Инициализация индикатора - $delivery_icon = match ($delivery_type) { - 'avia' => '', - default => '' - }; - - // Рассчет времени + // Инициализация даты отправки try { - $delivery_converted = DateTime::createFromFormat('Y-m-d H:i:s', $connection['delivery']['orderDates']['giveoutFromOspReceiver'])->getTimestamp(); - } catch (Exception $e) { - $delivery_converted = DateTime::createFromFormat('Y-m-d', $connection['delivery']['orderDates']['arrivalToOspReceiver'])->getTimestamp(); - } - $delivery = ceil(($delivery_converted - time()) / 60 / 60 / 24) + 1; + // Взять данные из "arrivalToOspSender" (Дата прибытия на терминал-отправитель) - // Инициализация цены - $cost = $connection['cost'] . ' ' . $connection['currency']; + $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 (Throwable $e) { + // Автоматическая доставка (подразумевается), данные из "arrivalToOspReceiver" (Дата прибытия натерминал-получатель) + + $delivery_converted = DateTime::createFromFormat('Y-m-d', $delivery['orderDates']['arrivalToOspReceiver'])->getTimestamp(); + } + $delivery = ceil(($delivery_converted - ($delivery_send_date ?? 0)) / 60 / 60 / 24) + 1; } // Инициализация комментария - $comment = $connection['order_edge_supply'][0]['comm'] ?? 'Комментарий к заказу'; + $comment = $order_edge_supply[0]['comm'] ?? 'Комментарий к заказу'; echo <<
- +
- {$connection['supply']['catn']} + {$supply['catn']}
- {$connection['supply']['dscr']} + {$supply['dscr']}
- +
-

$delivery_icon ~$delivery дн

+

$delivery_icon ~$delivery дн

- $cost + $price
-

$comment

+

$comment

diff --git a/mirzaev/skillparts/system/views/layouts/main.php b/mirzaev/skillparts/system/views/layouts/main.php index e33b78c..2f09fb9 100644 --- a/mirzaev/skillparts/system/views/layouts/main.php +++ b/mirzaev/skillparts/system/views/layouts/main.php @@ -82,7 +82,7 @@ AppAsset::register($this);