Работа над сайтом 20
This commit is contained in:
parent
fab247b4bc
commit
d9337944b1
|
@ -45,7 +45,11 @@ class AppAsset extends AssetBundle
|
|||
'js/search.js',
|
||||
'js/notification.js',
|
||||
'js/reinitialization.js',
|
||||
'js/geolocation.js'
|
||||
'https://api-maps.yandex.ru/2.1/?apikey=0c4ba9aa-c448-4bd0-9c8c-6181f21ede90&lang=ru_RU',
|
||||
'js/yandex/metrika.js',
|
||||
'js/yandex/geolocation.js',
|
||||
'https://www.googletagmanager.com/gtag/js?id=G-6XYKBJJWR4',
|
||||
'js/google/analytics.js'
|
||||
];
|
||||
public $jsOptions = [
|
||||
// 'position' => View::POS_HEAD
|
||||
|
|
|
@ -16,7 +16,7 @@ class InvoiceController extends Controller
|
|||
if ($order = Order::searchById(Order::collectionName() . '/' . $order)) {
|
||||
|
||||
return $this->renderPartial('/invoice/order/pattern', [
|
||||
'account' => yii::$app->user->identity->_key,
|
||||
'account' => yii::$app->user->identity,
|
||||
'order' => [
|
||||
'id' => $order->_key,
|
||||
'date' => $order->date ?? time() // @todo доделать
|
||||
|
|
|
@ -184,7 +184,7 @@ class NotificationController extends Controller
|
|||
$notification = $notifications[0];
|
||||
|
||||
$return['popup'] = [
|
||||
'html' => $this->renderPartial('popup', compact('model', 'notification')),
|
||||
'html' => $this->renderPartial('popup', compact('model', 'notification', 'account')),
|
||||
'id' => 'popup/' . $notification->readId()
|
||||
];
|
||||
} else if (yii::$app->request->post('stream')) {
|
||||
|
|
|
@ -24,6 +24,7 @@ use app\models\Supply;
|
|||
use app\models\SupplyEdgeProduct;
|
||||
|
||||
use Codeception\PHPUnit\ResultPrinter\HTML;
|
||||
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
@ -306,7 +307,7 @@ class OrderController extends Controller
|
|||
|
||||
return [
|
||||
'main' => $this->renderPartial('/orders/index', compact('orders', 'moderator_orders', 'search', 'from', 'to', 'window')
|
||||
+ ['panel' => $this->renderPartial('/orders/search/panel', ['response' => $orders[0]['supplies']])]),
|
||||
+ ['panel' => $this->renderPartial('/orders/search/panel', compact('account') + ['response' => @$orders[0]['supplies']] ?? null)]),
|
||||
'title' => 'Заказы',
|
||||
'redirect' => '/orders',
|
||||
'_csrf' => yii::$app->request->getCsrfToken()
|
||||
|
@ -489,14 +490,14 @@ class OrderController extends Controller
|
|||
yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
return [
|
||||
'main' => $this->renderPartial('/cart/index', compact('order', 'connections')),
|
||||
'main' => $this->renderPartial('/cart/index', compact('order', 'connections', 'account')),
|
||||
'title' => 'Корзина',
|
||||
'redirect' => '/cart',
|
||||
'_csrf' => yii::$app->request->getCsrfToken()
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('/cart/index', compact('order', 'connections'));
|
||||
return $this->render('/cart/index', compact('order', 'connections', 'account'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -507,7 +508,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;
|
||||
$account = yii::$app->user->identity;
|
||||
$order = Order::search();
|
||||
$connections = $order->content(10, $page);
|
||||
|
||||
|
@ -566,14 +567,14 @@ class OrderController extends Controller
|
|||
yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
return [
|
||||
'main' => $this->renderPartial('/cart/index', compact('order', 'connections')),
|
||||
'main' => $this->renderPartial('/cart/index', compact('order', 'connections', 'account')),
|
||||
'title' => 'Корзина',
|
||||
'redirect' => '/cart',
|
||||
'_csrf' => yii::$app->request->getCsrfToken()
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('/cart/index', compact('order', 'connections'));
|
||||
return $this->render('/cart/index', compact('order', 'connections', 'account'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -681,7 +682,7 @@ class OrderController extends Controller
|
|||
|
||||
}
|
||||
|
||||
if ($order_edge_supply = OrderEdgeSupply::searchById($_id = OrderEdgeSupply::collectionName() . '/' . $_key)) {
|
||||
if ($order_edge_supply = OrderEdgeSupply::searchById($_id = OrderEdgeSupply::collectionName() . '/' . $catn)) {
|
||||
// Удалось найти инстанцию поставки
|
||||
|
||||
// Инициализация ребра: ПОСТАВКА -> ТОВАР
|
||||
|
|
|
@ -286,12 +286,38 @@ class ProfileController extends Controller
|
|||
/**
|
||||
* Страница мониторинга
|
||||
*/
|
||||
public function actionMonitoring(): string|array
|
||||
public function actionMonitoring(Account|int|null $account = null): string|array
|
||||
{
|
||||
// Инициализация
|
||||
$panel = yii::$app->request->post('panel') ?? yii::$app->request->get('panel');
|
||||
$sidebar = $this->renderPartial('sidebar');
|
||||
|
||||
if (is_null($account)) {
|
||||
// Данные аккаунта не переданы
|
||||
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Аккаунт не аутентифицирован
|
||||
|
||||
return [];
|
||||
} else {
|
||||
// Аккаунт аутентифицирован
|
||||
|
||||
// Инициализация
|
||||
$account = yii::$app->user->identity;
|
||||
}
|
||||
} else {
|
||||
if (is_int($account)) {
|
||||
// Передан идентификатор (_key) аккаунта (подразумевается)
|
||||
|
||||
// Инициализация (поиск в базе данных)
|
||||
if (!$account = Account::searchById(Account::collectionName() . "/$account")) {
|
||||
// Не удалось инициализировать аккаунт
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Инициализация номера страницы
|
||||
$page_search_history = (yii::$app->request->post('search') ?? yii::$app->request->get('search')) - 1;
|
||||
|
||||
|
@ -368,7 +394,8 @@ class ProfileController extends Controller
|
|||
'sidebar',
|
||||
'search_history',
|
||||
'page_search_history',
|
||||
'panel'
|
||||
'panel',
|
||||
'account'
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -483,32 +510,6 @@ class ProfileController extends Controller
|
|||
// Настройка ответа
|
||||
yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
// if (is_null($account)) {
|
||||
// // Данные аккаунта не переданы
|
||||
|
||||
// if (yii::$app->user->isGuest) {
|
||||
// // Аккаунт не аутентифицирован
|
||||
|
||||
// return false;
|
||||
// } else {
|
||||
// // Аккаунт аутентифицирован
|
||||
|
||||
// // Инициализация
|
||||
// $account = yii::$app->user->identity;
|
||||
// }
|
||||
// } else {
|
||||
// if (is_int($account)) {
|
||||
// // Передан идентификатор (_key) аккаунта (подразумевается)
|
||||
|
||||
// // Инициализация (поиск в базе данных)
|
||||
// if (!$account = Account::searchById(Account::collectionName() . "/$account")) {
|
||||
// // Не удалось инициализировать аккаунт
|
||||
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Инициализация аккаунта
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Аккаунт не аутентифицирован
|
||||
|
@ -524,47 +525,32 @@ class ProfileController extends Controller
|
|||
// Настройка ответа
|
||||
yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
// Инициализация IP-адреса
|
||||
$ip = yii::$app->request->userIp === 'localhost' || yii::$app->request->userIp === '127.0.0.1' ? '46.226.227.20' : yii::$app->request->userIp;
|
||||
if (false !== $return = self::geolocationCheck($account)) {
|
||||
// Удалось сгенерировать данные для возврата
|
||||
|
||||
// Проверка записи геолокации
|
||||
if (isset($account->geol)) {
|
||||
// Удалось найти данные геолокации
|
||||
} else {
|
||||
// Не удалось найти данные геолокации
|
||||
|
||||
try {
|
||||
// Инициализация данных геолокации
|
||||
$dadata = new Dadata(yii::$app->params['dadata']['key'], yii::$app->params['dadata']['secret']);
|
||||
|
||||
// Запись в буфер данных о геолокации
|
||||
$account->geol = $dadata->iplocate($ip);
|
||||
} catch (Throwable $t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Запись в буфер данных о типе геолокации
|
||||
$account->geol = ['type' => 'ip'] + ($account->geol ?? []);
|
||||
|
||||
self::syncGeolocationWithDellin($account);
|
||||
return $return;
|
||||
}
|
||||
|
||||
return self::geolocationAccuracyCheck($account);
|
||||
return [
|
||||
'geolocation' => false,
|
||||
'_csrf' => yii::$app->request->getCsrfToken()
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация ответа по данным геолокации
|
||||
*
|
||||
* Проверка точности и наличия данных о геолокации
|
||||
* Проверка наличия записи о геолокации
|
||||
*
|
||||
* @param Account|string|null $account
|
||||
*
|
||||
* @return array|bool JSON, в случае успеха
|
||||
*
|
||||
* @todo
|
||||
* 1. 👁_👁
|
||||
*/
|
||||
public static function geolocationAccuracyCheck(Account|int|null $account = null): array|bool
|
||||
public static function geolocationCheck(Account|int|null $account = null): array|bool
|
||||
{
|
||||
if (is_null($account)) {
|
||||
// Данные аккаунта не переданы
|
||||
|
@ -597,15 +583,15 @@ class ProfileController extends Controller
|
|||
|
||||
// Генерация ответа
|
||||
return [
|
||||
'requestGps' => match ($account->geol['type'] ?? null) {
|
||||
'gps' => false,
|
||||
default => true
|
||||
},
|
||||
'geolocation' => true,
|
||||
'_csrf' => yii::$app->request->getCsrfToken()
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
return [
|
||||
'geolocation' => false,
|
||||
'_csrf' => yii::$app->request->getCsrfToken()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -614,6 +600,9 @@ class ProfileController extends Controller
|
|||
* @param string|null $account Аккаунт
|
||||
*
|
||||
* @return array|bool JSON, в случае успеха
|
||||
*
|
||||
* @todo
|
||||
* 1. Избавиться от второго запроса к DaData ($dadata->clean("address", $account->city);)
|
||||
*/
|
||||
public function actionGeolocationWrite(): array|bool
|
||||
{
|
||||
|
@ -623,36 +612,13 @@ class ProfileController extends Controller
|
|||
// Настройка ответа
|
||||
yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
// if (is_null($account)) {
|
||||
// // Данные аккаунта не переданы
|
||||
|
||||
// if (yii::$app->user->isGuest) {
|
||||
// // Аккаунт не аутентифицирован
|
||||
|
||||
// return false;
|
||||
// } else {
|
||||
// // Аккаунт аутентифицирован
|
||||
|
||||
// // Инициализация
|
||||
// $account = yii::$app->user->identity;
|
||||
// }
|
||||
// } else {
|
||||
// if (is_int($account)) {
|
||||
// // Передан идентификатор (_key) аккаунта (подразумевается)
|
||||
|
||||
// // Инициализация (поиск в базе данных)
|
||||
// if (!$account = Account::searchById(Account::collectionName() . "/$account")) {
|
||||
// // Не удалось инициализировать аккаунт
|
||||
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Инициализация аккаунта
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Аккаунт не аутентифицирован
|
||||
|
||||
// Запись кода ответа
|
||||
yii::$app->response->statusCode = 401;
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Аккаунт аутентифицирован
|
||||
|
@ -664,15 +630,21 @@ class ProfileController extends Controller
|
|||
// Настройка ответа
|
||||
yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
// Инициализация широты
|
||||
$latitude = yii::$app->request->post('latitude') ?? yii::$app->request->get('latitude');
|
||||
// Инициализация данных яндекса
|
||||
$yandex = yii::$app->request->post('yandex') ?? yii::$app->request->get('yandex');
|
||||
|
||||
// Инициализация долготы
|
||||
$longitude = yii::$app->request->post('longitude') ?? yii::$app->request->get('longitude');
|
||||
// Инициализация широты (среднее значение из общего периметра)
|
||||
$latitude = ($yandex['coordinates'][0][0] + $yandex['coordinates'][1][0]) / 2;
|
||||
|
||||
// Инициализация долготы (среднее значение из общего периметра)
|
||||
$longitude = ($yandex['coordinates'][0][1] + $yandex['coordinates'][1][1]) / 2;
|
||||
|
||||
if (empty($latitude) || empty($longitude)) {
|
||||
// Широта или долгота не передана
|
||||
|
||||
// Запись кода ответа
|
||||
yii::$app->response->statusCode = 500;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -682,13 +654,31 @@ class ProfileController extends Controller
|
|||
|
||||
// Запись в буфер данных о геолокации
|
||||
$account->geol = $dadata->geolocate("address", $latitude, $longitude)[0];
|
||||
|
||||
// Запись в буфер полученного города
|
||||
$account->city = $account->geol['data']['city'];
|
||||
|
||||
// Запись в буфер новых данных (непонятно почему, но только вторым запросом можно получать часовую зону)
|
||||
$account->geol = $account->geol + $dadata->clean("address", $account->city);
|
||||
|
||||
// Запись в буфер часовой зоны
|
||||
$account->zone = $account->geol['data']['timezone'];
|
||||
|
||||
if($account->update() < 1) {
|
||||
// Не удалось записать данные
|
||||
|
||||
// Запись кода ответа
|
||||
yii::$app->response->statusCode = 500;
|
||||
|
||||
return false;
|
||||
};
|
||||
} catch (Throwable $t) {
|
||||
// Запись кода ответа
|
||||
yii::$app->response->statusCode = 500;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Запись в буфер данных о типе геолокации
|
||||
$account->geol = ['type' => 'gps'] + $account->geol;
|
||||
|
||||
return self::syncGeolocationWithDellin($account);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ class SearchController extends Controller
|
|||
{
|
||||
// Инициализация параметров
|
||||
$auth_only = false;
|
||||
$account = yii::$app->user->identity;
|
||||
|
||||
if ($auth_only && yii::$app->user->isGuest) {
|
||||
// Если активирован режим "Поиск только аутентифицированным" и запрос пришел не от аутентифицированного
|
||||
|
@ -49,7 +50,7 @@ class SearchController extends Controller
|
|||
yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
return [
|
||||
'panel' => $this->renderPartial('/search/panel', ['history' => true]),
|
||||
'panel' => $this->renderPartial('/search/panel', compact('account') + ['history' => true]),
|
||||
'_csrf' => yii::$app->request->getCsrfToken()
|
||||
];
|
||||
}
|
||||
|
|
|
@ -6,9 +6,10 @@ namespace app\controllers;
|
|||
|
||||
use yii;
|
||||
use yii\web\Controller;
|
||||
use app\models\Account;
|
||||
use yii\web\Response;
|
||||
|
||||
use app\models\Account;
|
||||
|
||||
class VerifyController extends Controller
|
||||
{
|
||||
public function actionIndex(string $vrfy = null): string|Response
|
||||
|
@ -36,6 +37,9 @@ class VerifyController extends Controller
|
|||
if (yii::$app->user->identity->vrfy === true) {
|
||||
// Регистрация аккаунта уже подтверждена
|
||||
|
||||
// Генерация хеша пароля
|
||||
yii::$app->user->identity->pswd = yii::$app->security->generatePasswordHash(yii::$app->user->identity->pswd);
|
||||
|
||||
if (yii::$app->request->isPost) {
|
||||
// POST-запрос
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
'name',
|
||||
'simc',
|
||||
'sity',
|
||||
'zone',
|
||||
'comp',
|
||||
'taxn',
|
||||
'onec',
|
||||
|
@ -72,6 +73,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
'name' => 'Имя',
|
||||
'simc' => 'Номер',
|
||||
'sity' => 'Город',
|
||||
'zone' => 'Часовой пояс',
|
||||
'comp' => 'Компания',
|
||||
'taxn' => 'ИНН',
|
||||
'onec' => 'Данные 1C',
|
||||
|
@ -116,7 +118,10 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
'message' => 'Атрибут {attribute} должен иметь уникальное значение'
|
||||
],
|
||||
[
|
||||
'indx',
|
||||
[
|
||||
'indx',
|
||||
'zone'
|
||||
],
|
||||
'string'
|
||||
],
|
||||
[
|
||||
|
@ -287,11 +292,18 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Проверка пароля
|
||||
* Проверка пароля с хешированием
|
||||
*/
|
||||
public function validatePassword(string $pswd): bool
|
||||
public function validatePasswordWithHash(string $pswd): bool
|
||||
{
|
||||
return yii::$app->security->validatePassword($pswd, $this->pswd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка пароля без хеширования
|
||||
*/
|
||||
public function validatePasswordWithoutHash(string $pswd): bool
|
||||
{
|
||||
// return yii::$app->security->validatePassword($pswd, $this->pswd);
|
||||
return $pswd === $this->pswd;
|
||||
}
|
||||
|
||||
|
@ -487,7 +499,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
|
||||
// Запись
|
||||
empty($terminal->city) && empty($terminal->strt) && empty($terminal->hous)
|
||||
or $list[$terminal->dell] = (empty($terminal->city) ? '' : "г. $terminal->city"). (empty($terminal->strt) ? '' : ", ул. $terminal->strt") . (empty($terminal->hous) ? '' : ", д. $terminal->hous") . (empty($terminal->offs) ? '' : ", оф. $terminal->offs") . (empty($terminal->comm) ? '' : " ($terminal->comm)");
|
||||
or $list[$terminal->dell] = (empty($terminal->city) ? '' : "г. $terminal->city") . (empty($terminal->strt) ? '' : ", ул. $terminal->strt") . (empty($terminal->hous) ? '' : ", д. $terminal->hous") . (empty($terminal->offs) ? '' : ", оф. $terminal->offs") . (empty($terminal->comm) ? '' : " ($terminal->comm)");
|
||||
}
|
||||
|
||||
return $this->syncListWithSettings($list, 'delivery_to_terminal');
|
||||
|
|
|
@ -8,6 +8,7 @@ use yii;
|
|||
use yii\base\Model;
|
||||
|
||||
use app\models\Account;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* AccountForm is the model behind the login form.
|
||||
|
@ -146,10 +147,24 @@ class AccountForm extends Model
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$account || !$account->validatePassword($this->pswd)) {
|
||||
// Проверка не пройдена
|
||||
if ($account) {
|
||||
// Удалось инициализировать аккаунт
|
||||
|
||||
$this->addError($attribute, 'Проверьте пароль');
|
||||
try {
|
||||
$account->validatePasswordWithHash($this->pswd);
|
||||
} catch (Exception $e) {
|
||||
// Проверка с хешем не пройдена
|
||||
|
||||
try {
|
||||
$account->validatePasswordWithoutHash($this->pswd);
|
||||
} catch (Exception $e) {
|
||||
// Проверка без хеша не пройдена
|
||||
|
||||
$this->addError($attribute, 'Проверьте пароль');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->addError($attribute, 'Не удалось идентифицировать аккаунт');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ class Notification extends Document
|
|||
$text = htmlspecialchars(strip_tags($text ?? null));
|
||||
|
||||
$model->html = <<<HTML
|
||||
<p class="my-2 mx-3">$text</p>
|
||||
<p>$text</p>
|
||||
HTML;
|
||||
}
|
||||
|
||||
|
@ -281,4 +281,19 @@ class Notification extends Document
|
|||
|
||||
return $return ? $return : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Конвертация типа уведомления в версию для отображения
|
||||
*
|
||||
* @param string|null $type Тип уведомления
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function genTypeToRussian(string $type = null): string {
|
||||
return match($type ?? $this->type) {
|
||||
'notice' => 'Уведомление',
|
||||
'warning' => 'Предупреждение',
|
||||
'error' => 'Ошибка'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,14 @@ namespace app\models;
|
|||
use yii;
|
||||
use yii\web\UploadedFile;
|
||||
use yii\imagine\Image;
|
||||
use app\models\Settings;
|
||||
|
||||
use app\models\traits\SearchByEdge;
|
||||
use moonland\phpexcel\Excel;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
|
@ -318,18 +322,45 @@ class Product extends Document
|
|||
* На данный момент обрабатывает только импорт из
|
||||
* файлов с расширением .excel
|
||||
*/
|
||||
public function importExcel(): bool
|
||||
public function importExcel(Account|int|null $account = null): bool
|
||||
{
|
||||
// Инициализация
|
||||
$data = [];
|
||||
$amount = 0;
|
||||
|
||||
if (is_null($account)) {
|
||||
// Данные аккаунта не переданы
|
||||
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Аккаунт не аутентифицирован
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Аккаунт аутентифицирован
|
||||
|
||||
// Инициализация
|
||||
$account = yii::$app->user->identity;
|
||||
}
|
||||
} else {
|
||||
if (is_int($account)) {
|
||||
// Передан идентификатор (_key) аккаунта (подразумевается)
|
||||
|
||||
// Инициализация (поиск в базе данных)
|
||||
if (!$account = Account::searchById(Account::collectionName() . "/$account")) {
|
||||
// Не удалось инициализировать аккаунт
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($this->validate()) {
|
||||
foreach ($this->file_excel as $file) {
|
||||
// Перебор файлов
|
||||
|
||||
// Инициализация
|
||||
$dir = YII_PATH_PUBLIC . '../assets/import/' . date('Y-m-d', time()) . '/excel/' . (yii::$app->user->identity->_key ?? 'system') . '/' . time() . '/';
|
||||
$dir = YII_PATH_PUBLIC . '../assets/import/' . (new DateTime('now', new DateTimeZone($account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3'))) . '/excel/' . (yii::$app->user->identity->_key ?? 'system') . '/' . time() . '/';
|
||||
|
||||
// Сохранение на диск
|
||||
if (!file_exists($dir)) {
|
||||
|
@ -467,9 +498,16 @@ class Product extends Document
|
|||
*/
|
||||
public static function afterImportExcel(int $amount = 0): bool
|
||||
{
|
||||
// Инициализация
|
||||
// Инициализация параметров
|
||||
$model = new Notification;
|
||||
$date = date('H:i d.m.Y', time());
|
||||
$account = yii::$app->user->identity;
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
// Инициализация даты
|
||||
$date = (new DateTime('now', new DateTimeZone($timezone)))->format('H:i d.m.Y');
|
||||
|
||||
// Настройка
|
||||
$model->text = yii::$app->controller->renderPartial('@app/views/notification/system/afterImportExcel', compact('amount', 'date'));
|
||||
|
@ -482,11 +520,42 @@ class Product extends Document
|
|||
/**
|
||||
* Вызывается после загрузки поставок из 1С
|
||||
*/
|
||||
public static function afterImport1c(): bool
|
||||
public static function afterImport1c(Account|int|null $account = null): bool
|
||||
{
|
||||
// Инициализация
|
||||
$model = new Notification;
|
||||
$date = date('H:i d.m.Y', time());
|
||||
|
||||
if (is_null($account)) {
|
||||
// Данные аккаунта не переданы
|
||||
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Аккаунт не аутентифицирован
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Аккаунт аутентифицирован
|
||||
|
||||
// Инициализация
|
||||
$account = yii::$app->user->identity;
|
||||
}
|
||||
} else {
|
||||
if (is_int($account)) {
|
||||
// Передан идентификатор (_key) аккаунта (подразумевается)
|
||||
|
||||
// Инициализация (поиск в базе данных)
|
||||
if (!$account = Account::searchById(Account::collectionName() . "/$account")) {
|
||||
// Не удалось инициализировать аккаунт
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
$date = (new DateTime('now', new DateTimeZone($timezone)))->format('H:i d.m.Y');
|
||||
|
||||
// Настройка
|
||||
$model->text = yii::$app->controller->renderPartial('@app/views/notification/system/afterImport1c', compact('date'));
|
||||
|
|
|
@ -9,10 +9,14 @@ use yii\base\Model;
|
|||
|
||||
use app\models\Dellin as DellinModel;
|
||||
use app\models\Product;
|
||||
use app\models\Account;
|
||||
use app\models\Settings;
|
||||
|
||||
use GuzzleHttp\Client as Guzzle;
|
||||
use GuzzleHttp\Exception\ClientException as GuzzleException;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Exception;
|
||||
|
||||
class Dellin extends Model
|
||||
|
@ -68,18 +72,44 @@ class Dellin extends Model
|
|||
* @param int $y Высота (cм)
|
||||
* @param int $z Длинна (cм)
|
||||
* @param int $amount Количество
|
||||
* @param Account|int|null $account Аккаунт
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @todo Загружать помимо терминалов ещё и адреса, чтобы доделать доставку малогабаритных грузов
|
||||
* Разрабраться с параметрами 0,54м * 0,39м * 0,39м (0.082134м) и 0.1 куб метр в чем разница
|
||||
*/
|
||||
public static function calcDeliveryAdvanced(int $from, int $to, int $weight, int $x, int $y, int $z, int $amount = 1, bool $avia = false): array
|
||||
public static function calcDeliveryAdvanced(int $from, int $to, int $weight, int $x, int $y, int $z, int $amount = 1, bool $avia = false, Account|int|null $account = null): array
|
||||
{
|
||||
|
||||
return self::handle(function () use ($from, $to, $weight, $x, $y, $z, $amount, $avia) {
|
||||
return self::handle(function () use ($from, $to, $weight, $x, $y, $z, $amount, $avia, $account) {
|
||||
// Всё готово к работе
|
||||
|
||||
if (is_null($account)) {
|
||||
// Данные аккаунта не переданы
|
||||
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Аккаунт не аутентифицирован
|
||||
|
||||
return [];
|
||||
} else {
|
||||
// Аккаунт аутентифицирован
|
||||
|
||||
// Инициализация
|
||||
$account = yii::$app->user->identity;
|
||||
}
|
||||
} else {
|
||||
if (is_int($account)) {
|
||||
// Передан идентификатор (_key) аккаунта (подразумевается)
|
||||
|
||||
// Инициализация (поиск в базе данных)
|
||||
if (!$account = Account::searchById(Account::collectionName() . "/$account")) {
|
||||
// Не удалось инициализировать аккаунт
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Инициализация
|
||||
$from = DellinModel::searchByTerminalId($from, terminal_data_only: true);
|
||||
$to = DellinModel::searchByTerminalId($to, terminal_data_only: true);
|
||||
|
@ -126,7 +156,8 @@ class Dellin extends Model
|
|||
$query = [];
|
||||
|
||||
// Рассчёт типа доставки
|
||||
if ( !$avia
|
||||
if (
|
||||
!$avia
|
||||
&& $weight <= 30
|
||||
&& ($length <= 0.54 && $width <= 0.39 && $height <= 0.39)
|
||||
&& $length * $width * $height <= 0.1
|
||||
|
@ -164,6 +195,10 @@ class Dellin extends Model
|
|||
$query['delivery']['arrival']['terminalID'] = $to->id;
|
||||
}
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
// Инициализация
|
||||
$query = array_merge_recursive(
|
||||
$query,
|
||||
|
@ -172,8 +207,7 @@ class Dellin extends Model
|
|||
'sessionID' => self::$session,
|
||||
'delivery' => [
|
||||
'derival' => [
|
||||
// 'produceDate' => date('Y-m-d', time() + ($settings['delivery_handle_time'] ?? 86400))
|
||||
'produceDate' => date('Y-m-d', time() + 86400 * 3)
|
||||
'produceDate' => (new DateTime())->setTimestamp(time())->setTimezone(new DateTimeZone($timezone))->format('Y-m-d')
|
||||
]
|
||||
],
|
||||
'members' => [
|
||||
|
@ -273,146 +307,42 @@ class Dellin extends Model
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Импорт городов
|
||||
*
|
||||
* @return array|null Сохранённые города
|
||||
*/
|
||||
// public static function importCities(): ?int
|
||||
// {
|
||||
// return self::handle(function () {
|
||||
// // Всё готово к работе
|
||||
|
||||
// // Запрос ссылки на файл с городами, возвращает ['hash' => string, 'url' => string]
|
||||
// $request = self::$browser->post('/v1/public/cities.json', [
|
||||
// 'json' => [
|
||||
// 'appkey' => yii::$app->params['dellin']['key'],
|
||||
// ]
|
||||
// ]);
|
||||
|
||||
// if ($request->getStatusCode() === 200) {
|
||||
// // Запрос прошел успешно
|
||||
|
||||
// // Инициализация
|
||||
// $response = json_decode((string) $request->getBody(), true);
|
||||
// $hash_target = $response['hash'];
|
||||
// $dir = YII_PATH_PUBLIC . '/../assets/import/' . date('Y-m-d', time()) . '/dellin/cities/' . (yii::$app->user->identity->_key ?? 'system') . '/';
|
||||
|
||||
// if (!file_exists($dir)) {
|
||||
// // Директории не существует
|
||||
|
||||
// mkdir($dir, 0775, true);
|
||||
// }
|
||||
|
||||
// $request = self::$browser->get($response['url'], [
|
||||
// 'sink' => $file = $dir . time() . '.csv'
|
||||
// ]);
|
||||
|
||||
// // Проверка хеша (оказалось это хеш запроса, бесполезный)
|
||||
// // if ($hash_target === $hash_received = md5_file($file)) {
|
||||
// // Удалось пройти проверку на хеши файлов
|
||||
|
||||
// // Инициализация (чтение файла)
|
||||
// $file = fopen($file, "r");
|
||||
// $first_raw_block = true;
|
||||
|
||||
// while ($row = fgets($file, 4096)) {
|
||||
// // Перебор строк
|
||||
|
||||
// if ($first_raw_block) {
|
||||
// // Сработала защита от чтения первой строки файла (указываются названия колонок)
|
||||
|
||||
// // Отключение
|
||||
// $first_raw_block = false;
|
||||
|
||||
// // Пропуск цикла
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// // Инициализация
|
||||
// $data = explode(',', $row, 4);
|
||||
// $amount = 0;
|
||||
|
||||
// // Очистка
|
||||
// array_walk($data, fn (&$value) => $value = trim($value, '"'));
|
||||
|
||||
// if ($city = City::searchByDellinId($data[0])) {
|
||||
// // Удалось найти город в базе данных
|
||||
|
||||
// $after_import_log = function () use ($city): void {
|
||||
// // Запись в журнал
|
||||
// $city->journal('update');
|
||||
|
||||
// if (yii::$app->getRequest()->isConsoleRequest) {
|
||||
// // Вызов из терминала
|
||||
|
||||
// echo 'Удалось перезаписать город: ' . $city->name . PHP_EOL;
|
||||
// }
|
||||
// };
|
||||
// } else {
|
||||
// // Не удалось найти город в базе данных
|
||||
|
||||
// $city = new City();
|
||||
|
||||
// $after_import_log = function () use ($city): void {
|
||||
// if (yii::$app->getRequest()->isConsoleRequest) {
|
||||
// // Вызов из терминала
|
||||
|
||||
// echo 'Удалось записать город: ' . $city->name . PHP_EOL;
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
// // Запись
|
||||
// $city->indx = $data[0];
|
||||
// $city->name = $data[1];
|
||||
// $city->code = $data[2];
|
||||
// $city->term = (bool) $data[3];
|
||||
|
||||
// // Отправка в базу данных
|
||||
// if ($city->save()) {
|
||||
// // Удалось сохранить в базе данных
|
||||
|
||||
// // Запись в журнал
|
||||
// $after_import_log();
|
||||
|
||||
// // Постинкрементация счётчика
|
||||
// $amount++;
|
||||
|
||||
// continue;
|
||||
// } else {
|
||||
// // Не удалось сохранить в базе данных
|
||||
|
||||
// throw new Exception('Не удалось сохранить город ' . $data[1] . ' в базу данных', 500);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Деинициализация
|
||||
// fclose($file);
|
||||
|
||||
// return $amount;
|
||||
// // } else {
|
||||
// // // Не удалось пройти проверку на соответствие хешей файлов
|
||||
|
||||
// // throw new Exception('Хеши файлов не совпадают. Должен быть: "' . $hash_target . '", получен: "' . $hash_received . '"', 500);
|
||||
// // }
|
||||
// }
|
||||
|
||||
// throw new Exception('Не удалось синхронизировать данные городов с ДеловыеЛинии', 500);
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Импорт терминалов
|
||||
*
|
||||
* @return array|null Сохранённые терминалы
|
||||
*/
|
||||
public static function importTerminals(): ?int
|
||||
public static function importTerminals(Account|int|null $account = null): ?int
|
||||
{
|
||||
return self::handle(function () {
|
||||
return self::handle(function () use ($account) {
|
||||
// Всё готово к работе
|
||||
|
||||
if (is_null($account)) {
|
||||
// Данные аккаунта не переданы
|
||||
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Аккаунт не аутентифицирован
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
// Аккаунт аутентифицирован
|
||||
|
||||
// Инициализация
|
||||
$account = yii::$app->user->identity;
|
||||
}
|
||||
} else {
|
||||
if (is_int($account)) {
|
||||
// Передан идентификатор (_key) аккаунта (подразумевается)
|
||||
|
||||
// Инициализация (поиск в базе данных)
|
||||
if (!$account = Account::searchById(Account::collectionName() . "/$account")) {
|
||||
// Не удалось инициализировать аккаунт
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Запрос ссылки на файл с городами, возвращает ['hash' => string, 'url' => string]
|
||||
$request = self::$browser->post('/v3/public/terminals.json', [
|
||||
'json' => [
|
||||
|
@ -423,9 +353,13 @@ class Dellin extends Model
|
|||
if ($request->getStatusCode() === 200) {
|
||||
// Запрос прошел успешно
|
||||
|
||||
// Инициализация
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
// Инициализация параметров
|
||||
$response = json_decode((string) $request->getBody(), true);
|
||||
$dir = YII_PATH_PUBLIC . '/../assets/import/' . date('Y-m-d', time()) . '/dellin/terminals/' . (yii::$app->user->identity->_key ?? 'system') . '/';
|
||||
$dir = YII_PATH_PUBLIC . '/../assets/import/' . (new DateTime('now', new DateTimeZone($timezone)))->format('Y-m-d') . '/dellin/terminals/' . (yii::$app->user->identity->_key ?? 'system') . '/';
|
||||
$amount = 0;
|
||||
|
||||
if (!file_exists($dir)) {
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
<?php
|
||||
|
||||
use app\models\Settings;
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
|
@ -78,7 +83,13 @@
|
|||
|
||||
<tr>
|
||||
<td style="text-indent: 2px; text-align: left; border-bottom: medium; font-size: 18rem;" colspan="13" rowspan="3" valign="center">
|
||||
<b>Счет на оплату №<?= $order['id'] ?> от <?= date('d.m.Y', $order['date']) ?></b>
|
||||
<?php
|
||||
// Инициализация часового пояса
|
||||
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
?>
|
||||
<b>Счет на оплату №<?= $order['id'] ?> от <?= (new DateTime())->setTimestamp($order['date'])->setTimezone(new DateTimeZone($timezone))->format('d.m.Y') ?></b>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
@ -144,7 +155,10 @@
|
|||
<tr>
|
||||
<td style="text-align: center; border: solid; border-left: thick;" colspan="1" valign="center"><?= $row++ ?></td>
|
||||
<td style="text-align: left; border: solid;" colspan="6" valign="center"><?= $entry['title'] ?></td>
|
||||
<td style="text-align: center; border: solid;" colspan="2" valign="center"><?= $entry['amount']['value'] ?></td>
|
||||
|
||||
<?php var_dump($entry) ?>
|
||||
|
||||
<td style="text-align: center; border: solid;" colspan="2" valign="center"><?= $entry['amount']['auto']['value'] ?></td>
|
||||
<td style="text-align: center; border: solid;" valign="center"><?= $entry['cost']['value'] ?></td>
|
||||
<td style="text-align: center; border: solid;" valign="center"><?= $entry['cost']['unit'] ?></td>
|
||||
<td style="text-align: center; border: solid; border-right: thick;" colspan="2" valign="center"><?= $cost += $entry['cost']['value'] * $entry['amount']['value'] ?></td>
|
||||
|
@ -182,7 +196,7 @@
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="width: 8pt;" colspan="13"><img src="<?= YII_PATH_PUBLIC . '/img/invoices/signature.png'?>" /></td>
|
||||
<td style="width: 8pt;" colspan="13"><img src="<?= YII_PATH_PUBLIC . '/img/invoices/signature.png' ?>" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
|
|
@ -20,23 +20,8 @@ AppAsset::register($this);
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/favicons/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/favicons/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/favicons/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="/favicons/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/favicons/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/favicons/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/favicons/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/favicons/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/favicons/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/favicons/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/favicons/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="/favicons/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<link rel="icon" href="/favicon.ico" type="image/x-icon">
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
|
||||
|
||||
<?php $this->registerCsrfMetaTags() ?>
|
||||
<title><?= Html::encode($this->title ?? 'SkillParts') ?></title>
|
||||
|
@ -46,7 +31,7 @@ AppAsset::register($this);
|
|||
<body>
|
||||
<?php $this->beginBody() ?>
|
||||
|
||||
<div id="notifications_popup_wrap" class="col-3 m-4"></div>
|
||||
<div id="notifications_popup_wrap" class="m-4 col-6 col-sm-5 col-md-4 col-lg-4 col-xl-3"></div>
|
||||
|
||||
<header class="container pt-2 mt-1 mb-2 mb-sm-4 unselectable">
|
||||
<div class="row h-100">
|
||||
|
|
|
@ -1,10 +1,34 @@
|
|||
<?php
|
||||
$id = 'popup/' . $notification->readId();
|
||||
$html = $notification->html;
|
||||
|
||||
echo <<<HTML
|
||||
<div id="$id" class="mt-3 p-0 notification rounded" onmouseleave="return notification_popup_delete(this);">
|
||||
$html
|
||||
</div>
|
||||
HTML;
|
||||
?>
|
||||
use app\models\Settings;
|
||||
|
||||
// Инициализация данных для генерации HTML
|
||||
$id = 'popup/' . $notification->readId();
|
||||
$html = $notification->html;
|
||||
$type = $notification->genTypeToRussian();
|
||||
$date = null;
|
||||
|
||||
// Поиск даты создания
|
||||
foreach ($notification->jrnl as $jrnl) {
|
||||
if ($jrnl['action'] === 'create') {
|
||||
// Найдена дата создания
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
// Инициализация данных для генерации HTML
|
||||
$date = (new DateTime())->setTimestamp($jrnl['date'])->setTimezone(new DateTimeZone($timezone))->format('H:i d.m.Y');
|
||||
}
|
||||
}
|
||||
|
||||
$title = <<<HTML
|
||||
<b class="row mb-1 px-3"><small>$type<span class="ml-auto">$date</span></small></b>
|
||||
HTML;
|
||||
|
||||
echo <<<HTML
|
||||
<div id="$id" class="col mt-3 py-2 px-3 notification rounded" onmouseleave="return notification_popup_delete(this);">
|
||||
$title
|
||||
$html
|
||||
</div>
|
||||
HTML;
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
<a href="/orders#<?= $id ?>">Новый заказ</a>
|
||||
<div class="p-3 h-100">
|
||||
<p class="text-center my-auto">Новый заказ: <a href="/orders#<?= $id ?>">#<?= $id ?></a></p>
|
||||
</div>
|
||||
|
|
|
@ -8,6 +8,9 @@ use yii\bootstrap\ActiveForm;
|
|||
use app\models\AccountEdgeOrder;
|
||||
use app\models\Order;
|
||||
use app\models\OrderEdgeSupply;
|
||||
use app\models\Settings;
|
||||
|
||||
use moonland\phpexcel\Excel;
|
||||
|
||||
// Инициализация открытой панели
|
||||
if (empty($window)) {
|
||||
|
@ -54,21 +57,27 @@ if (empty($window)) {
|
|||
$date = null;
|
||||
|
||||
foreach ($order['order']['jrnl'] as $entry) {
|
||||
// Перебор записей в журнал
|
||||
// Перебор записей в журнале
|
||||
|
||||
if ($entry['action'] === 'requested') {
|
||||
// Найдена запись со временем запроса заказа
|
||||
|
||||
if (empty($date) || $date <= $entry['date']) {
|
||||
// Буфер не инициализирован или в него записано более старое событие
|
||||
|
||||
// Запись
|
||||
// Запись в буфер
|
||||
$date = $entry['date'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
// Конвертация данных из буфера
|
||||
$date = [
|
||||
'H:i' => date('H:i', $date),
|
||||
'm.d.Y' => date('m.d.Y', $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')
|
||||
];
|
||||
|
||||
?>
|
||||
|
@ -87,8 +96,13 @@ if (empty($window)) {
|
|||
$count = 1;
|
||||
?>
|
||||
|
||||
<?php foreach ($order['supplies'] as $supply) : ?>
|
||||
<?php foreach ($order['supplies'] as $supply) :
|
||||
// Перебор поставок
|
||||
?>
|
||||
|
||||
<?php
|
||||
// Инициализация окружения
|
||||
extract($supply);
|
||||
|
||||
// Инициализация обложки
|
||||
$covr = null;
|
||||
|
@ -116,18 +130,51 @@ if (empty($window)) {
|
|||
}
|
||||
}
|
||||
|
||||
// Инициализация окружения
|
||||
extract($supply);
|
||||
?>
|
||||
if ($amount['auto'] > 0) {
|
||||
// Найдены поставки с автоматической доставкой
|
||||
|
||||
<a id="<?= $supply['catn'] ?>_supply" class="row mb-2 p-2 px-0 rounded row_supply" type="button" onclick="return orders_supply_edit('<?= $supply['catn'] ?>', <?= $order['order']['_key'] ?>);">
|
||||
<img class="col-auto px-0 h-100 img-fluid rounded" src="<?= $covr ?>" />
|
||||
<p id="<?= $supply['catn'] ?>_supply_stts_indicator" class="col d-flex text-dark"><?= $product['catn'] . ' x' . $amount['auto'] ?>
|
||||
<?php if (Order::checkSuppliesStts($order_edge_supply)) : ?>
|
||||
<span id="<?= $supply['catn'] ?>_supply_stts_indicator_icon" class="ml-auto my-auto fas fa-check"></span>
|
||||
<?php endif ?>
|
||||
</p>
|
||||
</a>
|
||||
if (Order::checkSuppliesStts($order_edge_supply)) {
|
||||
$status = '<span id="' . $supply['catn'] . '_auto_supply_stts_indicator_icon" class="ml-auto my-auto fas fa-check"></span>';
|
||||
} else {
|
||||
$status = '';
|
||||
}
|
||||
|
||||
// Генерация HTML
|
||||
echo <<<HTML
|
||||
<a id="{$supply['catn']}_auto_supply" class="row mb-2 p-2 px-0 rounded row_supply" type="button" onclick="return orders_supply_edit('{$supply['catn']}_auto', {$order['order']['_key']});">
|
||||
<img class="col-auto px-0 h-100 img-fluid rounded" src="$covr" />
|
||||
<p id="{$supply['catn']}_auto_supply_stts_indicator" class="col d-flex text-dark">
|
||||
{$product['catn']} x{$amount['auto']}
|
||||
<small class="ml-2 my-auto fas fa-truck"></small>
|
||||
$status
|
||||
</p>
|
||||
</a>
|
||||
HTML;
|
||||
}
|
||||
|
||||
if ($amount['avia'] > 0) {
|
||||
// Найдены поставки с автоматической доставкой
|
||||
|
||||
if (Order::checkSuppliesStts($order_edge_supply)) {
|
||||
$status = '<span id="' . $supply['catn'] . '_avia_supply_stts_indicator_icon" class="ml-auto my-auto fas fa-check"></span>';
|
||||
} else {
|
||||
$status = '';
|
||||
}
|
||||
|
||||
// Генерация HTML
|
||||
echo <<<HTML
|
||||
<a id="{$supply['catn']}_avia_supply" class="row mb-2 p-2 px-0 rounded row_supply" type="button" onclick="return orders_supply_edit('{$supply['catn']}_avia', {$order['order']['_key']});">
|
||||
<img class="col-auto px-0 h-100 img-fluid rounded" src="$covr" />
|
||||
<p id="{$supply['catn']}_avia_supply_stts_indicator" class="col d-flex text-dark">
|
||||
{$product['catn']} x{$amount['avia']}
|
||||
<small class="ml-2 my-auto fas fa-plane"></small>
|
||||
$status
|
||||
</p>
|
||||
</a>
|
||||
HTML;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<?php if ($count++ < count($order['supplies'])) : ?>
|
||||
<div class="dropdown-divider mb-2"></div>
|
||||
|
@ -242,13 +289,27 @@ if (empty($window)) {
|
|||
// Пропуск активного заказа (несформированного, корзины)
|
||||
if ($account_edge_order[0]['type'] === 'current') continue;
|
||||
|
||||
// Деинициализация мусора
|
||||
unset($date);
|
||||
|
||||
// Инициализация времени подтверждения заказа
|
||||
if (isset($order['jrnl'])) foreach ($order['jrnl'] as $entry) {
|
||||
if ($entry['action'] === 'accepted') $date = date('H:i d.m.Y', $entry['date']);
|
||||
if (isset($order['jrnl'])) {
|
||||
// Журнал найден
|
||||
|
||||
foreach ($order['jrnl'] as $entry) {
|
||||
// Перебор записей в журнале
|
||||
|
||||
if ($entry['action'] === 'accepted') {
|
||||
// Найден принятый заказ
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
// Запись данных о дате заказа
|
||||
$date = (new DateTime())->setTimestamp($entry['date'])->setTimezone(new DateTimeZone($timezone))->format('H:i d.m.Y');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Инициализация значения по умолчанию
|
||||
$date ?? $date = 'Ожидается';
|
||||
|
||||
// Инициализация буфера поставок
|
||||
|
@ -260,99 +321,158 @@ if (empty($window)) {
|
|||
if (isset($supplies)) {
|
||||
// Найдены поставки
|
||||
|
||||
// Инициализация максимального срока доставки
|
||||
$delivery_max = 0;
|
||||
|
||||
// Инициализация поставок
|
||||
foreach ($supplies as $supply) {
|
||||
// Перебор поставок
|
||||
|
||||
// Инициализация окружения
|
||||
// Инициализация переменных
|
||||
extract($supply);
|
||||
|
||||
// Инициализация связи поставки с заказом (подразумевается, что все одинаковые по основным параметрам)
|
||||
$part = $order_edge_supply[0];
|
||||
// Инициализация цены
|
||||
$price_raw = $cost;
|
||||
|
||||
// Инициализация доставки
|
||||
if (isset($delivery['error'])) {
|
||||
// Не удалось рассчитать доставку
|
||||
// Инициализация комментария
|
||||
$comment = $order_edge_supply['comm'] ?? 'Комментарий к заказу';
|
||||
|
||||
// Инициализация индикатора
|
||||
$date_icon = '';
|
||||
if ($amount['auto'] > 0) {
|
||||
// Найдены поставки с автоматической доставкой
|
||||
|
||||
// Инициализация цены
|
||||
$price_auto = $price_raw['auto'] . ' ' . $currency;
|
||||
|
||||
// Инициализация доставки
|
||||
if (isset($part['date'])) {
|
||||
// Найдены данные в инстанции поставки
|
||||
if (!isset($delivery) || (isset($delivery['auto'], $delivery['auto']['error']) || $delivery === '?')) {
|
||||
// Не удалось рассчитать доставку
|
||||
|
||||
// Запись в буфер вывода
|
||||
// $time = $part['time'] . ' дн';
|
||||
$date = date('d.m.Y', $part['date']);
|
||||
$date_html = "<span class=\"m-auto\">$date</span>";
|
||||
// Инициализация времени
|
||||
$delivery_auto = '?';
|
||||
} else {
|
||||
$date = 'Неизвестно';
|
||||
$date_html = "<small class=\"m-auto\">$date</small>";
|
||||
// Удалось рассчитать доставку
|
||||
|
||||
// Инициализация даты отправки
|
||||
try {
|
||||
// Взять данные из "arrivalToOspSender" (Дата прибытия на терминал-отправитель)
|
||||
|
||||
$delivery_auto_send_date = DateTime::createFromFormat('Y-m-d', $delivery['auto']['orderDates']['arrivalToOspSender'])->getTimestamp();
|
||||
} catch (Throwable $e) {
|
||||
// Взять данные из "pickup" (Дата передачи груза на адресе отправителя)
|
||||
|
||||
$delivery_auto_send_date = DateTime::createFromFormat('Y-m-d', $delivery['auto']['orderDates']['pickup'])->getTimestamp();
|
||||
}
|
||||
|
||||
// Инициализация времени доставки
|
||||
try {
|
||||
// Доставка по воздуху (подразумевается), данные из "giveoutFromOspReceiver" (Дата и время, с которого груз готов к выдаче на терминале)
|
||||
|
||||
// Оставлено на всякий случай для дальнейших разбирательств
|
||||
|
||||
$delivery_auto_converted = DateTime::createFromFormat('Y-m-d H:i:s', $delivery['auto']['orderDates']['giveoutFromOspReceiver'])->getTimestamp();
|
||||
} catch (Throwable $e) {
|
||||
// Автоматическая доставка (подразумевается), данные из "arrivalToOspReceiver" (Дата прибытия натерминал-получатель)
|
||||
|
||||
$delivery_auto_converted = DateTime::createFromFormat('Y-m-d', $delivery['auto']['orderDates']['arrivalToOspReceiver'])->getTimestamp();
|
||||
}
|
||||
$delivery_auto = ceil(($delivery_auto_converted - ($delivery_auto_send_date ?? 0)) / 60 / 60 / 24) + 1;
|
||||
}
|
||||
|
||||
// Инициализация стоимости
|
||||
if (isset($part['cost'])) $cost_html = '<span class="m-auto">' . ($cost = $part['cost']) . ' <small>' . $currency . '</small></span>';
|
||||
else $cost_html = '<small class="m-auto">' . ($cost = 'Неизвестно') . '</small>';
|
||||
} else {
|
||||
// Удалось рассчитать доставку
|
||||
// Инициализация статуса связи поставки
|
||||
$status = OrderEdgeSupply::convertStatusToRussian($part['stts'] ?? '');
|
||||
|
||||
// Инициализация типа доставки
|
||||
$time_type = $part['dlvr']['type'] ?? 'auto';
|
||||
|
||||
// Инициализация индикатора
|
||||
$date_icon = match ($time_type) {
|
||||
'avia' => '<i class="ml-1 fas fa-plane"></i>',
|
||||
default => '<i class="ml-1 fas fa-truck"></i>'
|
||||
// Инициализация класса для поставки (если необходимо)
|
||||
$css = match ($part['stts'] ?? '') {
|
||||
'accepted' => ' supply_accepted',
|
||||
default => ''
|
||||
};
|
||||
|
||||
// Инициализация доставки
|
||||
if (isset($part['date'])) {
|
||||
// Найдены данные в инстанции поставки
|
||||
// Реинициализация максимальной даты доставки
|
||||
if ($delivery_max !== '?' && $delivery_max < $delivery_auto) $delivery_max = $delivery_auto;
|
||||
else if ($delivery_auto === '?') $delivery_max = '?';
|
||||
|
||||
// Запись в буфер вывода
|
||||
// $time = $part['time'] . ' дн';
|
||||
$date = date('d.m.Y', $part['date']);
|
||||
$date_html = "<span class=\"m-auto\">$date</span>";
|
||||
} else {
|
||||
// Рассчет времени из данных поставки
|
||||
|
||||
try {
|
||||
$time_converted = DateTime::createFromFormat('Y-m-d H:i:s', $delivery['auto']['orderDates']['giveoutFromOspReceiver'])->getTimestamp();
|
||||
} catch (Exception $e) {
|
||||
$time_converted = DateTime::createFromFormat('Y-m-d', $delivery['auto']['orderDates']['arrivalToOspReceiver'])->getTimestamp();
|
||||
}
|
||||
// $time = (ceil(($time_converted - time()) / 60 / 60 / 24) + 1) . ' дн';
|
||||
$date = date('d.m.Y', $time_converted);
|
||||
$date_html = "<span class=\"m-auto\">$date</span>";
|
||||
}
|
||||
|
||||
// Инициализация стоимости
|
||||
if (isset($part['cost'])) $cost_html = '<span class="m-auto">' . ($cost = $part['cost']) . ' <small>' . $currency . '</small></span>';
|
||||
else $cost_html = '<span class="m-auto">' . ($cost = $cost['auto']) . ' <small>' . $currency . '</small></span>';
|
||||
// Генерация HTML
|
||||
// Пробела между supply и $css не должно быть
|
||||
$supplies_html .= <<<HTML
|
||||
<div class="row py-2 supply$css text-center">
|
||||
<div class="m-auto col-2">{$supply['catn']}</div>
|
||||
<small class="m-auto col-3">$status</small>
|
||||
<div class="m-auto col-3">$delivery_auto <small class="mr-1 fas fa-truck"></small></div>
|
||||
<div class="m-auto col-2">{$amount['auto']}</div>
|
||||
<div class="m-auto col-2">$price_auto</div>
|
||||
</div>
|
||||
HTML;
|
||||
}
|
||||
|
||||
// Инициализация статуса связи поставки
|
||||
$status = OrderEdgeSupply::convertStatusToRussian($part['stts'] ?? '');
|
||||
if ($amount['avia'] > 0) {
|
||||
// Найдены поставки с доставкой по воздуху
|
||||
|
||||
// Инициализация класса для поставки (если необходимо)
|
||||
$css = match ($part['stts'] ?? '') {
|
||||
'accepted' => ' supply_accepted',
|
||||
default => ''
|
||||
};
|
||||
// Инициализация цены
|
||||
$price_avia = $price_raw['avia'] . ' ' . $currency;
|
||||
|
||||
// Пробела между supply и $css не должно быть
|
||||
$supplies_html .= <<<HTML
|
||||
// Инициализация доставки
|
||||
if (!isset($delivery) || (isset($delivery['avia'], $delivery['avia']['error']) || $delivery === '?')) {
|
||||
// Не удалось рассчитать доставку
|
||||
|
||||
// Инициализация времени
|
||||
$delivery_avia = '?';
|
||||
} else {
|
||||
// Удалось рассчитать доставку
|
||||
|
||||
// Инициализация даты отправки
|
||||
try {
|
||||
// Взять данные из "arrivalToOspSender" (Дата прибытия на терминал-отправитель)
|
||||
|
||||
$delivery_avia_send_date = DateTime::createFromFormat('Y-m-d', $delivery['avia']['orderDates']['arrivalToOspSender'])->getTimestamp();
|
||||
} catch (Throwable $e) {
|
||||
// Взять данные из "pickup" (Дата передачи груза на адресе отправителя)
|
||||
|
||||
$delivery_avia_send_date = DateTime::createFromFormat('Y-m-d', $delivery['avia']['orderDates']['pickup'])->getTimestamp();
|
||||
}
|
||||
|
||||
// Инициализация времени доставки
|
||||
try {
|
||||
// Доставка по воздуху (подразумевается), данные из "giveoutFromOspReceiver" (Дата и время, с которого груз готов к выдаче на терминале)
|
||||
|
||||
$delivery_avia_converted = DateTime::createFromFormat('Y-m-d H:i:s', $delivery['avia']['orderDates']['giveoutFromOspReceiver'])->getTimestamp();
|
||||
} catch (Throwable $e) {
|
||||
// Автоматическая доставка (подразумевается), данные из "arrivalToOspReceiver" (Дата прибытия натерминал-получатель)
|
||||
|
||||
// Оставлено на всякий случай для дальнейших разбирательств
|
||||
|
||||
$delivery_avia_converted = DateTime::createFromFormat('Y-m-d', $delivery['avia']['orderDates']['arrivalToOspReceiver'])->getTimestamp();
|
||||
}
|
||||
$delivery_avia = ceil(($delivery_avia_converted - ($delivery_avia_send_date ?? 0)) / 60 / 60 / 24) + 1;
|
||||
}
|
||||
|
||||
// Инициализация статуса связи поставки
|
||||
$status = OrderEdgeSupply::convertStatusToRussian($part['stts'] ?? '');
|
||||
|
||||
// Инициализация класса для поставки (если необходимо)
|
||||
$css = match ($part['stts'] ?? '') {
|
||||
'accepted' => ' supply_accepted',
|
||||
default => ''
|
||||
};
|
||||
|
||||
// Реинициализация максимальной даты доставки
|
||||
if ($delivery_max !== '?' && $delivery_max < $delivery_avia) $delivery_max = $delivery_avia;
|
||||
else if ($delivery_avia === '?') $delivery_max = '?';
|
||||
|
||||
// Генерация HTML
|
||||
// Пробела между supply и $css не должно быть
|
||||
$supplies_html .= <<<HTML
|
||||
<div class="row py-2 supply$css text-center">
|
||||
<div class="col-2">{$supply['catn']}</div>
|
||||
<div class="col-3 d-flex"><small class="m-auto">$status</small></div>
|
||||
<div class="col-3 d-flex">$date_html</div>
|
||||
<div class="col-2">{$amount['auto']}</div>
|
||||
<div class="col-2 d-flex">$cost_html</div>
|
||||
<div class="m-auto col-2">{$supply['catn']}</div>
|
||||
<small class="m-auto col-3">$status</small>
|
||||
<div class="m-auto col-3">$delivery_avia <small class="mr-1 fas fa-plane"></small></div>
|
||||
<div class="m-auto col-2">{$amount['avia']}</div>
|
||||
<div class="m-auto col-2">$price_avia</div>
|
||||
</div>
|
||||
HTML;
|
||||
}
|
||||
|
||||
// Обновление общего счётчика цены
|
||||
$sum += (int) $cost;
|
||||
// Инициализация общей цены
|
||||
$sum = $price_raw['avia'] * $amount['avia'] + $price_raw['auto'] * $amount['auto'];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,7 +489,7 @@ if (empty($window)) {
|
|||
<div class="row py-2 cart_list_target_total text-center">
|
||||
<div class="col-2">$invoice</div>
|
||||
<div class="col-3"><b>$status</b></div>
|
||||
<div class="col-3"><b>$date</b></div>
|
||||
<div class="col-3"><b>$delivery_max</b></div>
|
||||
<div class="col-2"></div>
|
||||
<div class="col-2"><b>$sum <small><b>руб</b></small></b></div>
|
||||
</div>
|
||||
|
@ -395,6 +515,11 @@ if (empty($window)) {
|
|||
// Инициализация индикатора готовности календаря
|
||||
orders_calendar_ready = false;
|
||||
|
||||
<?php
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
?>
|
||||
|
||||
if (document.readyState === "complete") {
|
||||
// Документ загружен
|
||||
|
||||
|
@ -409,7 +534,7 @@ if (empty($window)) {
|
|||
onSelect: orders_calendar_select
|
||||
});
|
||||
|
||||
$('#orders_period_calendar').data('datepicker').selectDate([new Date('<?= $from ?? date('Y-m-d', time() - 604800) ?>'), new Date('<?= $to ?? date('Y-m-d', time()) ?>')]);
|
||||
$('#orders_period_calendar').data('datepicker').selectDate([new Date('<?= $from ?? (new DateTime())->setTimestamp(time() - 604800)->setTimezone(new DateTimeZone($timezone))->format('Y-m-d') ?>'), new Date('<?= $to ?? (new DateTime('now', new DateTimeZone($timezone)))->format('Y-m-d') ?>')]);
|
||||
|
||||
// Активация календаря
|
||||
orders_calendar_ready = true;
|
||||
|
@ -431,7 +556,7 @@ if (empty($window)) {
|
|||
onSelect: orders_calendar_select
|
||||
});
|
||||
|
||||
$('#orders_period_calendar').data('datepicker').selectDate([new Date('<?= $from ?? date('Y-m-d', time() - 604800) ?>'), new Date('<?= $to ?? date('Y-m-d', time()) ?>')]);
|
||||
$('#orders_period_calendar').data('datepicker').selectDate([new Date('<?= $from ?? (new DateTime())->setTimestamp(time() - 604800)->setTimezone(new DateTimeZone($timezone))->format('Y-m-d') ?>'), new Date('<?= $to ?? (new DateTime('now', new DateTimeZone($timezone)))->format('Y-m-d') ?>')]);
|
||||
|
||||
// Активация календаря
|
||||
orders_calendar_ready = true;
|
||||
|
|
|
@ -3,18 +3,13 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
use app\models\Search;
|
||||
use app\models\Settings;
|
||||
|
||||
if (isset($history) && $history) {
|
||||
// Отображение истории
|
||||
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Не аутентифицирован
|
||||
|
||||
// В будущем выводить историю из cookie
|
||||
|
||||
echo <<<HTML
|
||||
<p class="m-0 py-2 d-flex justify-content-center">Войдите для просмотра истории поиска</p>
|
||||
HTML;
|
||||
} else if ($rows = Search::searchByEdge(
|
||||
from: 'account',
|
||||
to: 'search',
|
||||
|
@ -23,31 +18,18 @@ if (isset($history) && $history) {
|
|||
)) {
|
||||
// История поиска существует
|
||||
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
// Инициализация
|
||||
$time = $row->jrnl;
|
||||
$date = empty($time) ? '' : date('d.m.y', end($time)['date']);
|
||||
$date = empty($time) ? '' : (new DateTime())->setTimestamp(end($time)['date'])->setTimezone(new DateTimeZone($timezone))->format('d.m.y');
|
||||
|
||||
echo <<<HTML
|
||||
<a class="dropdown-item d-flex button_white text-dark" href="/search?type=product&q=$row->text">$row->text<span class="ml-auto">$date</span></a>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
} else if (isset($response) && $response) {
|
||||
// Ответ получен
|
||||
|
||||
foreach ($response as $row) {
|
||||
// Перебор найденных данных
|
||||
|
||||
$catn = $row['supply']['catn'];
|
||||
|
||||
echo <<<HTML
|
||||
<a class="dropdown-item button_white text-dark" href="/product/$catn">$catn</a>
|
||||
HTML;
|
||||
}
|
||||
} else {
|
||||
echo <<<HTML
|
||||
<p class="m-0 py-2 d-flex justify-content-center">Ничего не найдено</p>
|
||||
HTML;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -39,7 +39,12 @@ $panel ?? $panel = 'profile_panel_monitoring_input_search_history';
|
|||
foreach ($search_history ?? [] as $row) {
|
||||
// Инициализация
|
||||
$time = $row->jrnl;
|
||||
$date = empty($row->jrnl) ? '' : date('H:i d.m.Y', end($time)['date']);
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
$date = empty($row->jrnl) ? '' : (new DateTime())->setTimestamp(end($time)['date'])->setTimezone(new DateTimeZone($timezone))->format('H:i d.m.Y');
|
||||
|
||||
echo <<<HTML
|
||||
<div class="row py-1">
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
use app\models\Search;
|
||||
use app\models\Settings;
|
||||
|
||||
if (isset($history) && $history) {
|
||||
// Отображение истории
|
||||
|
@ -23,10 +24,13 @@ if (isset($history) && $history) {
|
|||
)) {
|
||||
// История поиска существует
|
||||
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::search()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
// Инициализация
|
||||
$time = $row->jrnl;
|
||||
$date = empty($time) ? '' : date('H:i d.m.Y', end($time)['date']);
|
||||
$date = empty($time) ? '' : (new DateTime())->setTimestamp(end($time)['date'])->setTimezone(new DateTimeZone($timezone))->format('H:i d.m.Y');
|
||||
|
||||
echo <<<HTML
|
||||
<a class="dropdown-item d-flex button_white text-dark" href="/search?type=product&q=$row->text">$row->text<span class="ml-auto">$date</span></a>
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
z-index : 100;
|
||||
bottom : 0;
|
||||
position: fixed;
|
||||
width: 370px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 164 KiB |
|
@ -303,14 +303,15 @@ function account_response(data, status, xhr) {
|
|||
function account_response_success(data, status, xhr) {
|
||||
// Обработка ответов от удавшихся запросов
|
||||
|
||||
account_response(data, status, xhr);
|
||||
|
||||
// Реинициализация панели поиска
|
||||
// Перенести в отдельный файл который подгружается в зависимости от настроек
|
||||
// search_panel_show();
|
||||
|
||||
// // Обновление панели поиска
|
||||
// product_search();
|
||||
product_search();
|
||||
|
||||
account_response(data, status, xhr);
|
||||
}
|
||||
|
||||
function account_response_error(data, status, xhr) {
|
||||
|
|
|
@ -1,83 +1,83 @@
|
|||
// Инициализация геолокации (запись геолокации по айпи, если не существует)
|
||||
function geolocation_init() {
|
||||
$.ajax({
|
||||
url: '/profile/geolocation/init',
|
||||
type: 'post',
|
||||
dataType: 'json',
|
||||
data: { '_csrf': yii.getCsrfToken() },
|
||||
success: geolocation_success,
|
||||
error: geolocation_error
|
||||
});
|
||||
};
|
||||
// // Инициализация геолокации (запись геолокации по айпи, если не существует)
|
||||
// function geolocation_init() {
|
||||
// $.ajax({
|
||||
// url: '/profile/geolocation/init',
|
||||
// type: 'post',
|
||||
// dataType: 'json',
|
||||
// data: { '_csrf': yii.getCsrfToken() },
|
||||
// success: geolocation_success,
|
||||
// error: geolocation_error
|
||||
// });
|
||||
// };
|
||||
|
||||
geolocation_init();
|
||||
// geolocation_init();
|
||||
|
||||
// Запись геолокации (точный режим из браузера по запросу)
|
||||
function geolocation_gps() {
|
||||
// // Запись геолокации (точный режим из браузера по запросу)
|
||||
// function geolocation_gps() {
|
||||
|
||||
// Запрос геолокации у пользователя
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
geolocation_gps_success,
|
||||
geolocation_gps_error,
|
||||
{
|
||||
enableHighAccuracy: true
|
||||
}
|
||||
);
|
||||
};
|
||||
// // Запрос геолокации у пользователя
|
||||
// navigator.geolocation.getCurrentPosition(
|
||||
// geolocation_gps_success,
|
||||
// geolocation_gps_error,
|
||||
// {
|
||||
// enableHighAccuracy: true
|
||||
// }
|
||||
// );
|
||||
// };
|
||||
|
||||
// Получено подтверждение выдачи геолокации от пользователя
|
||||
function geolocation_gps_success({ coords }) {
|
||||
// // Получено подтверждение выдачи геолокации от пользователя
|
||||
// function geolocation_gps_success({ coords }) {
|
||||
|
||||
// Инициализация
|
||||
const { latitude, longitude } = coords;
|
||||
// // Инициализация
|
||||
// const { latitude, longitude } = coords;
|
||||
|
||||
// Запрос
|
||||
$.ajax({
|
||||
url: '/profile/geolocation/write',
|
||||
type: 'post',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
'latitude': latitude,
|
||||
'longitude': longitude,
|
||||
'_csrf': yii.getCsrfToken()
|
||||
},
|
||||
success: geolocation_success,
|
||||
error: geolocation_error
|
||||
});
|
||||
};
|
||||
// // Запрос
|
||||
// $.ajax({
|
||||
// url: '/profile/geolocation/write',
|
||||
// type: 'post',
|
||||
// dataType: 'json',
|
||||
// data: {
|
||||
// 'latitude': latitude,
|
||||
// 'longitude': longitude,
|
||||
// '_csrf': yii.getCsrfToken()
|
||||
// },
|
||||
// success: geolocation_success,
|
||||
// error: geolocation_error
|
||||
// });
|
||||
// };
|
||||
|
||||
// Не получено подтверждение выдачи геолокации от пользователя
|
||||
function geolocation_gps_error({ message }) {
|
||||
};
|
||||
// // Не получено подтверждение выдачи геолокации от пользователя
|
||||
// function geolocation_gps_error({ message }) {
|
||||
// };
|
||||
|
||||
function geolocation_responce(data, status, xhr) {
|
||||
// Обработка ответов
|
||||
// function geolocation_responce(data, status, xhr) {
|
||||
// // Обработка ответов
|
||||
|
||||
main_response(data, status, xhr);
|
||||
};
|
||||
// main_response(data, status, xhr);
|
||||
// };
|
||||
|
||||
function geolocation_success(data, status, xhr) {
|
||||
// Обработка ответов от удавшихся запросов
|
||||
// function geolocation_success(data, status, xhr) {
|
||||
// // Обработка ответов от удавшихся запросов
|
||||
|
||||
if (data !== undefined) {
|
||||
// Получены данные с сервера
|
||||
// if (data !== undefined) {
|
||||
// // Получены данные с сервера
|
||||
|
||||
|
||||
// Запрос более точной геолокации
|
||||
if (data.requestGps !== undefined && data.requestGps === true) {
|
||||
// // Запрос более точной геолокации
|
||||
// if (data.requestGps !== undefined && data.requestGps === true) {
|
||||
|
||||
geolocation_gps();
|
||||
}
|
||||
};
|
||||
// geolocation_gps();
|
||||
// }
|
||||
// };
|
||||
|
||||
geolocation_responce(data, status, xhr);
|
||||
};
|
||||
// geolocation_responce(data, status, xhr);
|
||||
// };
|
||||
|
||||
function geolocation_error(data, status, xhr) {
|
||||
// Обработка ответов от неудавшихся запросов
|
||||
// function geolocation_error(data, status, xhr) {
|
||||
// // Обработка ответов от неудавшихся запросов
|
||||
|
||||
// Инициализация
|
||||
data = data.responseJSON;
|
||||
// // Инициализация
|
||||
// data = data.responseJSON;
|
||||
|
||||
geolocation_responce(data, status, xhr);
|
||||
};
|
||||
// geolocation_responce(data, status, xhr);
|
||||
// };
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-6XYKBJJWR4');
|
|
@ -40,7 +40,7 @@ function order_accept(order_key) {
|
|||
return false;
|
||||
};
|
||||
|
||||
function orders_supply_edit(supply_key, order_key) {
|
||||
function orders_supply_edit(type, supply_key, order_key) {
|
||||
// Инициализация
|
||||
let supply = document.getElementById(supply_key + '_supply');
|
||||
|
||||
|
@ -229,7 +229,7 @@ function orders_supply_edit(supply_key, order_key) {
|
|||
|
||||
// Инициализация индикатора
|
||||
let span = document.createElement('span');
|
||||
span.setAttribute('id', supply.getAttribute('id') + '_stts_indicator_icon');
|
||||
span.setAttribute('id', supply.getAttribute('id') + '_' + type + '_supply_stts_indicator_icon');
|
||||
span.setAttribute('class', 'ml-auto my-auto fas fa-check');
|
||||
|
||||
// Инициализация кнопки
|
||||
|
@ -237,7 +237,7 @@ function orders_supply_edit(supply_key, order_key) {
|
|||
button.setAttribute('id', supply.getAttribute('id') + '_stts_button');
|
||||
button.setAttribute('type', 'button');
|
||||
button.setAttribute('role', 'button');
|
||||
button.setAttribute('onclick', 'return orders_supply_comm_write(this, \'' + supply_key + '\', \'' + order_key + '\');');
|
||||
button.setAttribute('onclick', 'return orders_supply_comm_write(this, \'' + type + '\' \'' + supply_key + '\', \'' + order_key + '\');');
|
||||
if (data.stts === undefined || data.stts == 0) {
|
||||
button.setAttribute('class', 'col-12 btn button_blue button_clean');
|
||||
button.innerText = 'Подтвердить';
|
||||
|
@ -246,9 +246,9 @@ function orders_supply_edit(supply_key, order_key) {
|
|||
button.innerText = 'Подтверждено';
|
||||
|
||||
// Инициализация
|
||||
let title = document.getElementById(supply.getAttribute('id') + '_stts_indicator');
|
||||
let title = document.getElementById(supply.getAttribute('id') + '_' + type + '_supply_stts_indicator');
|
||||
|
||||
if (title.children[0] === undefined) {
|
||||
if (title.children[1] === undefined) {
|
||||
// Индикатор не найден
|
||||
|
||||
// Запись индикатора
|
||||
|
@ -273,7 +273,7 @@ function orders_supply_edit(supply_key, order_key) {
|
|||
return false;
|
||||
};
|
||||
|
||||
function orders_supply_comm_write(button, supply_key, order_key) {
|
||||
function orders_supply_comm_write(button, type, supply_key, order_key) {
|
||||
// Инициализация
|
||||
let supply = document.getElementById(supply_key + '_supply');
|
||||
|
||||
|
@ -288,7 +288,7 @@ function orders_supply_comm_write(button, supply_key, order_key) {
|
|||
success: function (data, status, xhr) {
|
||||
// Инициализация индикатора
|
||||
let span = document.createElement('span');
|
||||
span.setAttribute('id', supply.getAttribute('id') + '_stts_indicator_icon');
|
||||
span.setAttribute('id', supply.getAttribute('id') + '_' + type + '_supply_stts_indicator_icon');
|
||||
span.setAttribute('class', 'ml-auto my-auto fas fa-check');
|
||||
|
||||
if (data.stts === undefined || data.stts == 0) {
|
||||
|
@ -299,7 +299,7 @@ function orders_supply_comm_write(button, supply_key, order_key) {
|
|||
button.innerText = 'Подтверждено';
|
||||
|
||||
// Инициализация
|
||||
let title = document.getElementById(supply.getAttribute('id') + '_stts_indicator');
|
||||
let title = document.getElementById(supply.getAttribute('id') + '_' + type + '_supply_stts_indicator');
|
||||
|
||||
if (title.children[0] === undefined) {
|
||||
// Индикатор не найден
|
||||
|
|
|
@ -79,9 +79,6 @@ function search_panel_response(text, advanced, data, status, xhr) {
|
|||
// Обновление окна результатов поиска
|
||||
panel.innerHTML = data.panel;
|
||||
|
||||
// Отображение окна (потом надо переделать)
|
||||
$('#search_line').dropdown('show');
|
||||
|
||||
// Реинициализация
|
||||
reinitialization(panel);
|
||||
};
|
||||
|
@ -101,6 +98,11 @@ function search_panel_response(text, advanced, data, status, xhr) {
|
|||
};
|
||||
};
|
||||
|
||||
// Отображение окна поиска
|
||||
if (data.search_line_window_show === 1) {
|
||||
search_panel_show();
|
||||
};
|
||||
|
||||
// Сокрытие окна поиска
|
||||
if (data.search_line_window_hide === 1) {
|
||||
search_panel_hide();
|
||||
|
@ -116,7 +118,7 @@ function search_panel_success(text, advanced, data, status, xhr) {
|
|||
search_panel_response(text, advanced, data, status, xhr);
|
||||
};
|
||||
|
||||
function search_panel_error(text, advanced, data, status) {
|
||||
function search_panel_error(text, advanced, data, status, xhr) {
|
||||
// Обработка ответов от неудавшихся запросов
|
||||
|
||||
// Инициализация
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
'use strict'
|
||||
|
||||
// Инициализация геолокации (запись геолокации по айпи, если не существует)
|
||||
function yandex_geolocation_init() {
|
||||
$.ajax({
|
||||
url: '/profile/geolocation/init',
|
||||
type: 'post',
|
||||
dataType: 'json',
|
||||
data: { '_csrf': yii.getCsrfToken() },
|
||||
success: yandex_geolocation_success,
|
||||
error: yandex_geolocation_error
|
||||
});
|
||||
};
|
||||
|
||||
yandex_geolocation_init();
|
||||
|
||||
function yandex_geolocation_search() {
|
||||
try {
|
||||
ymaps.geolocation.get({
|
||||
autoReverseGeocode: true
|
||||
}).then(function (result) {
|
||||
// Запрос
|
||||
$.ajax({
|
||||
url: '/profile/geolocation/write',
|
||||
type: 'post',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
'yandex': {
|
||||
// 'metadata': result.geoObjects.get(0).properties.get('metaDataProperty'),
|
||||
'coordinates': result.geoObjects.get(0).properties.get('boundedBy')
|
||||
},
|
||||
'_csrf': yii.getCsrfToken()
|
||||
},
|
||||
success: yandex_geolocation_success,
|
||||
error: yandex_geolocation_error
|
||||
});
|
||||
})
|
||||
} catch (err) {
|
||||
setTimeout(yandex_geolocation_search, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function yandex_geolocation_responce(data, status, xhr) {
|
||||
// Обработка ответов
|
||||
|
||||
main_response(data, status, xhr);
|
||||
};
|
||||
|
||||
function yandex_geolocation_success(data, status, xhr) {
|
||||
// Обработка ответов от удавшихся запросов
|
||||
|
||||
if (data !== undefined) {
|
||||
// Получены данные с сервера
|
||||
|
||||
// Запрос геолокации
|
||||
if (data.geolocation !== undefined && data.geolocation === false) {
|
||||
|
||||
yandex_geolocation_search();
|
||||
}
|
||||
};
|
||||
|
||||
yandex_geolocation_responce(data, status, xhr);
|
||||
};
|
||||
|
||||
function yandex_geolocation_error(data, status, xhr) {
|
||||
// Обработка ответов от неудавшихся запросов
|
||||
|
||||
// Инициализация
|
||||
data = data.responseJSON;
|
||||
|
||||
yandex_geolocation_responce(data, status, xhr);
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
(function (m, e, t, r, i, k, a) {
|
||||
m[i] = m[i] || function () { (m[i].a = m[i].a || []).push(arguments) };
|
||||
m[i].l = 1 * new Date(); k = e.createElement(t), a = e.getElementsByTagName(t)[0], k.async = 1, k.src = r, a.parentNode.insertBefore(k, a)
|
||||
})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(84269905, "init", {
|
||||
clickmap: true,
|
||||
trackLinks: true,
|
||||
accurateTrackBounce: true,
|
||||
webvisor: true
|
||||
});
|
Reference in New Issue