Создание панели модератора и доработка уведомлений
This commit is contained in:
parent
248f5470f9
commit
4f8a99d8e2
|
@ -36,10 +36,15 @@ class CartController extends Controller
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$model = new Order();
|
$model = new Order();
|
||||||
$model->save() or throw new Exception('Не удалось инициализировать заказ');
|
|
||||||
|
|
||||||
// Подключение
|
if ($model->save()) {
|
||||||
$model->connect($account);
|
// Удалось инициализировать заказ
|
||||||
|
|
||||||
|
// Подключение заказа к аккаунту
|
||||||
|
$model->connect($account);
|
||||||
|
} else {
|
||||||
|
throw new Exception('Не удалось инициализировать заказ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Инициализация содержимого корзины
|
// Инициализация содержимого корзины
|
||||||
|
|
|
@ -12,6 +12,8 @@ use yii\web\Cookie;
|
||||||
|
|
||||||
use app\models\Order;
|
use app\models\Order;
|
||||||
use app\models\AccountEdgeOrder;
|
use app\models\AccountEdgeOrder;
|
||||||
|
use app\models\Notification;
|
||||||
|
use Codeception\PHPUnit\ResultPrinter\HTML;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
class OrderController extends Controller
|
class OrderController extends Controller
|
||||||
|
@ -71,6 +73,7 @@ class OrderController extends Controller
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$orders = Order::search(type: 'all', limit: 10, page: 1, select: '{account_edge_order, order}');
|
$orders = Order::search(type: 'all', limit: 10, page: 1, select: '{account_edge_order, order}');
|
||||||
|
$moderator_orders = self::genOrdersForModeration();
|
||||||
|
|
||||||
if (yii::$app->request->isPost) {
|
if (yii::$app->request->isPost) {
|
||||||
// POST-запрос
|
// POST-запрос
|
||||||
|
@ -78,14 +81,14 @@ class OrderController extends Controller
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('/orders/index', compact('orders')),
|
'main' => $this->renderPartial('/orders/index', compact('orders', 'moderator_orders')),
|
||||||
'title' => 'Заказы',
|
'title' => 'Заказы',
|
||||||
'redirect' => '/orders',
|
'redirect' => '/orders',
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('/orders/index', compact('orders'));
|
return $this->render('/orders/index', compact('orders', 'moderator_orders'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -313,13 +316,21 @@ class OrderController extends Controller
|
||||||
$edge = $edge[0];
|
$edge = $edge[0];
|
||||||
|
|
||||||
// Запись
|
// Запись
|
||||||
$edge->type = 'accepted';
|
$edge->type = 'requested';
|
||||||
|
|
||||||
// Отправка изменений
|
if ($edge->update()) {
|
||||||
$edge->update();
|
// Удалось сохранить изменения
|
||||||
|
|
||||||
|
// Запись в журнал
|
||||||
|
$model->journal('requested');
|
||||||
|
|
||||||
|
// Отправка уведомлений модераторам
|
||||||
|
Notification::_write($this->renderPartial('/notification/system/newOrder', ['id' => $edge->_key]), true, '@auth', Notification::TYPE_MODERATOR_ORDER_NEW);
|
||||||
|
}
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$orders = Order::search(type: 'all', limit: 10, page: 1, select: '{account_edge_order, order}');
|
$orders = Order::search(type: 'all', limit: 30, page: 1, select: '{account_edge_order, order}');
|
||||||
|
$moderator_orders = Order::search(account: '@all', type: 'requested', limit: 10, page: 1, select: '{account_edge_order, order}');
|
||||||
|
|
||||||
if (yii::$app->request->isPost) {
|
if (yii::$app->request->isPost) {
|
||||||
// POST-запрос
|
// POST-запрос
|
||||||
|
@ -327,13 +338,32 @@ class OrderController extends Controller
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('/orders/index', compact('orders')),
|
'main' => $this->renderPartial('/orders/index', compact('orders', 'moderator_orders')),
|
||||||
'title' => 'Заказы',
|
'title' => 'Заказы',
|
||||||
'redirect' => '/orders',
|
'redirect' => '/orders',
|
||||||
'_csrf' => yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('/orders/index', compact('orders'));
|
return $this->render('/orders/index', compact('orders', 'moderator_orders'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Генерация данных заказов для модераторов
|
||||||
|
*
|
||||||
|
* Включает поиск запрошенных заказов и связанных с ними поставках
|
||||||
|
*
|
||||||
|
* @return array ['order' => array, 'order_edge_account' => array, 'supplies' => array]
|
||||||
|
*/
|
||||||
|
protected static function genOrdersForModeration(int $page = 1): array {
|
||||||
|
$orders = Order::search(account: '@all', type: 'requested', limit: 10, page: 1, select: '{account_edge_order, order}');
|
||||||
|
|
||||||
|
foreach ($orders as &$order) {
|
||||||
|
// Перебор заказов
|
||||||
|
|
||||||
|
$order['supplies'] = Order::searchById($order['order']['_id'])->content(10, $page);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $orders;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,30 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
return static::searchById($_id);
|
return static::searchById($_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Чтение всех модераторов
|
||||||
|
*/
|
||||||
|
public static function readAllModerators(): array
|
||||||
|
{
|
||||||
|
return static::find()->where(['type' => 'moderator'])->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Чтение всех администраторов
|
||||||
|
*/
|
||||||
|
public static function readAllAdministrators(): array
|
||||||
|
{
|
||||||
|
return static::find()->where(['type' => 'administrator'])->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Чтение всех уполномоченных аккаунтов
|
||||||
|
*/
|
||||||
|
public static function readAllAuthorizeds(): array
|
||||||
|
{
|
||||||
|
return static::find()->where(['type' => 'moderator'])->orWhere(['type' => 'administrator'])->all();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Проверка почты
|
* Проверка почты
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,20 +29,25 @@ class Notification extends Document
|
||||||
const SCENARIO_TRUSTED_CREATE = 'create';
|
const SCENARIO_TRUSTED_CREATE = 'create';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Тип уведомления: памятка
|
* Уведомление: "памятка"
|
||||||
*/
|
*/
|
||||||
const TYPE_NOTICE = 'notice';
|
const TYPE_NOTICE = 'notice';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Тип уведомления: предупреждение
|
* Уведомление: "предупреждение"
|
||||||
*/
|
*/
|
||||||
const TYPE_WARNING = 'warning';
|
const TYPE_WARNING = 'warning';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Тип уведомления: ошибка
|
* Уведомление: "ошибка"
|
||||||
*/
|
*/
|
||||||
const TYPE_ERROR = 'error';
|
const TYPE_ERROR = 'error';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Уведомление для модераторов: "новый заказ"
|
||||||
|
*/
|
||||||
|
const TYPE_MODERATOR_ORDER_NEW = 'new order';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Цель для отправки уведомления
|
* Цель для отправки уведомления
|
||||||
*
|
*
|
||||||
|
@ -192,7 +197,7 @@ class Notification extends Document
|
||||||
|
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
if (in_array('@all', $accounts, true)) {
|
if (in_array('@all', $accounts, true)) {
|
||||||
// Найден флаг обозначающий отправку всем пользователям
|
// Всем пользователям
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$return = [];
|
$return = [];
|
||||||
|
@ -200,11 +205,64 @@ class Notification extends Document
|
||||||
foreach (Account::readAll() as $account) {
|
foreach (Account::readAll() as $account) {
|
||||||
// Перебор всех аккаунтов
|
// Перебор всех аккаунтов
|
||||||
|
|
||||||
|
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
|
||||||
|
$return[] = AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type);
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
in_array('@authorized', $accounts, true)
|
||||||
|
|| in_array('@authorizeds', $accounts, true)
|
||||||
|
|| in_array('@authorised', $accounts, true)
|
||||||
|
|| in_array('@authoriseds', $accounts, true)
|
||||||
|
|| in_array('@auth', $accounts, true)
|
||||||
|
|| in_array('@autheds', $accounts, true)
|
||||||
|
) {
|
||||||
|
// Всем авторизованным
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$return = [];
|
||||||
|
|
||||||
|
foreach (Account::readAllAuthorizeds() as $account) {
|
||||||
|
// Перебор всех аккаунтов
|
||||||
|
|
||||||
|
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
|
||||||
|
$return[] = AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type);
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
in_array('@administrator', $accounts, true)
|
||||||
|
|| in_array('@administrators', $accounts, true)
|
||||||
|
|| in_array('@admin', $accounts, true)
|
||||||
|
|| in_array('@admins', $accounts, true)
|
||||||
|
) {
|
||||||
|
// Администраторам
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$return = [];
|
||||||
|
|
||||||
|
foreach (Account::readAllAdministrators() as $account) {
|
||||||
|
// Перебор всех аккаунтов
|
||||||
|
|
||||||
|
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
|
||||||
|
$return[] = AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type);
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
in_array('@moderator', $accounts, true)
|
||||||
|
|| in_array('@moderators', $accounts, true)
|
||||||
|
|| in_array('@moder', $accounts, true)
|
||||||
|
|| in_array('@moders', $accounts, true)
|
||||||
|
) {
|
||||||
|
// Модераторам
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$return = [];
|
||||||
|
|
||||||
|
foreach (Account::readAllModerators() as $account) {
|
||||||
|
// Перебор всех аккаунтов
|
||||||
|
|
||||||
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
|
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
|
||||||
$return[] = AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type);
|
$return[] = AccountEdgeNotification::writeSafe($model->readId(), $account->readId(), $type);
|
||||||
}
|
}
|
||||||
} else if (in_array('@test', $accounts, true)) {
|
} else if (in_array('@test', $accounts, true)) {
|
||||||
// Найден флаг обозначающий тестирование (отправка самому себе)
|
// Тестирование (отправка самому себе)
|
||||||
|
|
||||||
$return[] = AccountEdgeNotification::writeSafe($model->readId(), yii::$app->user->id, $type);
|
$return[] = AccountEdgeNotification::writeSafe($model->readId(), yii::$app->user->id, $type);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -236,33 +236,51 @@ class Order extends Document implements DocumentInterface
|
||||||
/**
|
/**
|
||||||
* Поиск заказа
|
* Поиск заказа
|
||||||
*/
|
*/
|
||||||
public static function search(Account $account = null, string $type = 'current', int $limit = 1, int $page = 1, string $select = null): self|array|null
|
public static function search(Account|string $account = null, string $type = 'current', int $limit = 1, int $page = 1, string $select = null): self|array|null
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация аккаунта
|
||||||
$account or $account = yii::$app->user->identity ?? throw new Exception('Не удалось инициализировать пользователя');
|
if (empty($account) && isset(yii::$app->user->identity)) {
|
||||||
|
// Данные не переданы
|
||||||
|
|
||||||
// Генерация сдвига по запрашиваемым данным (пагинация)
|
$subquery_where = [
|
||||||
$offset = $limit * ($page - 1);
|
[
|
||||||
|
'account._id' => yii::$app->user->identity->readId()
|
||||||
if (strcasecmp($type, 'all') !== 0) {
|
]
|
||||||
// Если не указан параметр поиска всех заказов
|
|
||||||
|
|
||||||
$where_type = [
|
|
||||||
'account_edge_order.type' => $type
|
|
||||||
];
|
];
|
||||||
|
} else if ($account instanceof Account) {
|
||||||
|
// Передан аккаунт
|
||||||
|
|
||||||
|
$subquery_where = [
|
||||||
|
[
|
||||||
|
'account._id' => $account->readId()
|
||||||
|
]
|
||||||
|
];
|
||||||
|
} else if (str_contains($account, '@all')) {
|
||||||
|
// Запрос на обработку всех аккаунтов
|
||||||
|
|
||||||
|
$subquery_where = [];
|
||||||
} else {
|
} else {
|
||||||
$where_type = [];
|
throw new Exception('Не удалось инициализировать пользователя');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Инициализация типа заказа
|
||||||
|
if (strcasecmp($type, 'all') !== 0) {
|
||||||
|
// Если не указан поиск всех заказов
|
||||||
|
|
||||||
|
$subquery_where[] = [
|
||||||
|
'account_edge_order.type' => $type
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Инициализация сдвига по запрашиваемым данным (пагинация)
|
||||||
|
$offset = $limit * ($page - 1);
|
||||||
|
|
||||||
|
// Запрос
|
||||||
$return = self::searchByEdge(
|
$return = self::searchByEdge(
|
||||||
from: 'account',
|
from: 'account',
|
||||||
to: 'order',
|
to: 'order',
|
||||||
subquery_where: [
|
subquery_where: $subquery_where,
|
||||||
[
|
|
||||||
'account._id' => $account->readId()
|
|
||||||
],
|
|
||||||
$where_type
|
|
||||||
],
|
|
||||||
foreach: ['edge' => 'account_edge_order'],
|
foreach: ['edge' => 'account_edge_order'],
|
||||||
where: 'edge._to == order._id',
|
where: 'edge._to == order._id',
|
||||||
limit: $limit,
|
limit: $limit,
|
||||||
|
@ -366,8 +384,7 @@ class Order extends Document implements DocumentInterface
|
||||||
// Поиск привязанного товара
|
// Поиск привязанного товара
|
||||||
$connection['product'] = Product::searchBySupplyId($connection['supply']['_id']);
|
$connection['product'] = Product::searchBySupplyId($connection['supply']['_id']);
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
// Инициализация доставки Dellin (автоматическая)
|
// Инициализация доставки Dellin (автоматическая)
|
||||||
$connection['delivery']['auto'] = Dellin::calcDeliveryAdvanced(
|
$connection['delivery']['auto'] = Dellin::calcDeliveryAdvanced(
|
||||||
explode('_', $connection['account']['opts']['delivery_from_terminal'])[1],
|
explode('_', $connection['account']['opts']['delivery_from_terminal'])[1],
|
||||||
|
@ -385,10 +402,9 @@ class Order extends Document implements DocumentInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// Запись цены (цена поставки + цена доставки + наша наценка)
|
// Запись цены (цена поставки + цена доставки + наша наценка)
|
||||||
$connection['cost']['auto'] = ($cost['ЦенаЗаЕдиницу'] ?? $connection['supply']->onec['Цены']['Цена']['ЦенаЗаЕдиницу']) + ($connection['delivery']['auto']['price']['all'] ?? $connection['delivery']['auto']['price']['one'] ?? 0) + ($settings['increase'] ?? 0);
|
$connection['cost']['auto'] = ($cost['ЦенаЗаЕдиницу'] ?? $connection['supply']->onec['Цены']['Цена']['ЦенаЗаЕдиницу']) + ($connection['delivery']['auto']['price']['all'] ?? $connection['delivery']['auto']['price']['one'] ?? 0) + ($settings['increase'] ?? 0) ?? 0;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
// Инициализация доставки Dellin (автоматическая)
|
// Инициализация доставки Dellin (автоматическая)
|
||||||
$connection['delivery']['avia'] = Dellin::calcDeliveryAdvanced(
|
$connection['delivery']['avia'] = Dellin::calcDeliveryAdvanced(
|
||||||
explode('_', $connection['account']['opts']['delivery_from_terminal'])[1],
|
explode('_', $connection['account']['opts']['delivery_from_terminal'])[1],
|
||||||
|
@ -403,11 +419,11 @@ class Order extends Document implements DocumentInterface
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$connection['delivery']['avia']['error'] = true;
|
$connection['delivery']['avia']['error'] = true;
|
||||||
|
|
||||||
var_dump(json_decode($e->getMessage(), true)['errors']); die;
|
// var_dump(json_decode($e->getMessage(), true)['errors']); die;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Запись цены (цена поставки + цена доставки + наша наценка)
|
// Запись цены (цена поставки + цена доставки + наша наценка)
|
||||||
$connection['cost']['avia'] = ($cost['ЦенаЗаЕдиницу'] ?? $connection['supply']->onec['Цены']['Цена']['ЦенаЗаЕдиницу']) + ($connection['delivery']['avia']['price']['all'] ?? $connection['delivery']['avia']['price']['one'] ?? 0) + ($settings['increase'] ?? 0);
|
$connection['cost']['avia'] = ($cost['ЦенаЗаЕдиницу'] ?? $connection['supply']->onec['Цены']['Цена']['ЦенаЗаЕдиницу']) + ($connection['delivery']['avia']['price']['all'] ?? $connection['delivery']['avia']['price']['one'] ?? 0) + ($settings['increase'] ?? 0) ?? 0;
|
||||||
|
|
||||||
// Запись валюты
|
// Запись валюты
|
||||||
$connection['currency'] = $cost['Валюта'];
|
$connection['currency'] = $cost['Валюта'];
|
||||||
|
|
|
@ -118,6 +118,9 @@ class Dellin extends Model
|
||||||
$length = $z;
|
$length = $z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$query = [];
|
||||||
|
|
||||||
// Рассчёт типа доставки
|
// Рассчёт типа доставки
|
||||||
if (
|
if (
|
||||||
$weight <= 30
|
$weight <= 30
|
||||||
|
@ -126,43 +129,46 @@ class Dellin extends Model
|
||||||
) {
|
) {
|
||||||
// Доставка категории "small"
|
// Доставка категории "small"
|
||||||
|
|
||||||
$type = 'small';
|
$query['delivery']['deliveryType']['type'] = 'small';
|
||||||
$variant = 'address';
|
$query['delivery']['derival']['variant'] = 'address';
|
||||||
|
$query['delivery']['derival']['address']['search'] = $from;
|
||||||
|
$query['delivery']['derival']['time']['worktimeStart'] = '08:00';
|
||||||
|
$query['delivery']['derival']['time']['worktimeEnd'] = '20:00';
|
||||||
|
$query['delivery']['arrival']['variant'] = 'address';
|
||||||
|
$query['delivery']['arrival']['address']['search'] = $to;
|
||||||
|
$query['delivery']['arrival']['time']['worktimeStart'] = '08:00';
|
||||||
|
$query['delivery']['arrival']['time']['worktimeEnd'] = '20:00';
|
||||||
} else {
|
} else {
|
||||||
// Доставка категории "auto"
|
// Доставка категории "auto"
|
||||||
|
|
||||||
if ($avia) {
|
if ($avia) {
|
||||||
// Рассчет для доставки по воздуху
|
// Рассчет для доставки по воздуху
|
||||||
|
|
||||||
|
// Ограничение на минимальный вес
|
||||||
$weight <= 0.5 and $weight = 0.5;
|
$weight <= 0.5 and $weight = 0.5;
|
||||||
$type = 'avia';
|
|
||||||
|
$query['delivery']['deliveryType']['type'] = 'avia';
|
||||||
} else {
|
} else {
|
||||||
// Рассчет для доставки по земле
|
// Рассчет для доставки по земле
|
||||||
|
|
||||||
$type = 'auto';
|
$query['delivery']['deliveryType']['type'] = 'auto';
|
||||||
}
|
}
|
||||||
|
|
||||||
$variant = 'terminal';
|
$query['delivery']['derival']['variant'] = 'terminal';
|
||||||
|
$query['delivery']['derival']['terminalID'] = $from;
|
||||||
|
$query['delivery']['arrival']['variant'] = 'terminal';
|
||||||
|
$query['delivery']['arrival']['terminalID'] = $to;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Запрос
|
// Инициализация
|
||||||
$request = self::$browser->post('/v2/calculator.json', [
|
$query = array_merge_recursive(
|
||||||
'json' => [
|
$query,
|
||||||
|
[
|
||||||
'appkey' => yii::$app->params['dellin']['key'],
|
'appkey' => yii::$app->params['dellin']['key'],
|
||||||
'sessionID' => self::$session,
|
'sessionID' => self::$session,
|
||||||
'delivery' => [
|
'delivery' => [
|
||||||
'deliveryType' => [
|
|
||||||
'type' => $type
|
|
||||||
],
|
|
||||||
'derival' => [
|
'derival' => [
|
||||||
'produceDate' => date('Y-m-d', time() + ($settings['delivery_handle_time'] ?? 86400)),
|
'produceDate' => date('Y-m-d', time() + ($settings['delivery_handle_time'] ?? 86400))
|
||||||
'variant' => $variant,
|
|
||||||
'terminalID' => $from,
|
|
||||||
|
|
||||||
],
|
|
||||||
'arrival' => [
|
|
||||||
'variant' => $variant,
|
|
||||||
'terminalID' => $to
|
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'members' => [
|
'members' => [
|
||||||
|
@ -182,6 +188,11 @@ class Dellin extends Model
|
||||||
'oversizedVolume' => $x * $y * $z
|
'oversizedVolume' => $x * $y * $z
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Запрос
|
||||||
|
$request = self::$browser->post('/v2/calculator.json', [
|
||||||
|
'json' => $query
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($request->getStatusCode() === 200) {
|
if ($request->getStatusCode() === 200) {
|
||||||
|
|
|
@ -43,11 +43,15 @@ use DateTime;
|
||||||
if (isset($connection['delivery']['auto']['error'])) {
|
if (isset($connection['delivery']['auto']['error'])) {
|
||||||
// Не удалось рассчитать доставку
|
// Не удалось рассчитать доставку
|
||||||
|
|
||||||
|
// Инициализация времени
|
||||||
$delivery_auto = '?';
|
$delivery_auto = '?';
|
||||||
|
|
||||||
|
// Инициализация цены
|
||||||
|
$cost_auto = '?';
|
||||||
} else {
|
} else {
|
||||||
// Удалось рассчитать доставку
|
// Удалось рассчитать доставку
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация времени
|
||||||
$delivery_auto = ceil((DateTime::createFromFormat('Y-m-d', $connection['delivery']['auto']['orderDates']['arrivalToOspReceiver'])->getTimestamp() - time()) / 60 / 60 / 24) + 1;
|
$delivery_auto = ceil((DateTime::createFromFormat('Y-m-d', $connection['delivery']['auto']['orderDates']['arrivalToOspReceiver'])->getTimestamp() - time()) / 60 / 60 / 24) + 1;
|
||||||
|
|
||||||
// Инициализация цены
|
// Инициализация цены
|
||||||
|
@ -58,10 +62,15 @@ use DateTime;
|
||||||
if (isset($connection['delivery']['avia']['error'])) {
|
if (isset($connection['delivery']['avia']['error'])) {
|
||||||
// Не удалось рассчитать доставку
|
// Не удалось рассчитать доставку
|
||||||
|
|
||||||
|
// Инициализация времени
|
||||||
$delivery_avia = '?';
|
$delivery_avia = '?';
|
||||||
|
|
||||||
|
// Инициализация цены
|
||||||
|
$cost_avia = '?';
|
||||||
} else {
|
} else {
|
||||||
// Удалось рассчитать доставку
|
// Удалось рассчитать доставку
|
||||||
|
|
||||||
|
// Инициализация времени
|
||||||
$delivery_avia = ceil((DateTime::createFromFormat('Y-m-d H:i:s', $connection['delivery']['avia']['orderDates']['giveoutFromOspReceiver'])->getTimestamp() - time()) / 60 / 60 / 24) + 1;
|
$delivery_avia = ceil((DateTime::createFromFormat('Y-m-d H:i:s', $connection['delivery']['avia']['orderDates']['giveoutFromOspReceiver'])->getTimestamp() - time()) / 60 / 60 / 24) + 1;
|
||||||
|
|
||||||
// Инициализация цены
|
// Инициализация цены
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
|
|
||||||
<p>Импортированы товары из 1C <span>(<?= $date ?>)</span></p>
|
<p>Импортированы товары из 1C <span>(<?= $date ?>)</span></p>
|
|
@ -0,0 +1 @@
|
||||||
|
<a href="orders#<?= $id ?>">Новый заказ</a>
|
|
@ -33,7 +33,7 @@
|
||||||
<p><b class="mr-1">4</b> Гарантия, условия возврата</p>
|
<p><b class="mr-1">4</b> Гарантия, условия возврата</p>
|
||||||
</h5>
|
</h5>
|
||||||
<p class="ml-3"><b>4.1</b> Комплектность товара проверяется торговой площадкой при получении на складе торговой площадкой</p>
|
<p class="ml-3"><b>4.1</b> Комплектность товара проверяется торговой площадкой при получении на складе торговой площадкой</p>
|
||||||
<p class="ml-3"><b>4.2</b> Поставщик гарантирует приём возврата некачественного, <u>а так же</u> некомплектного товара в течение 60 дней</p>
|
<p class="ml-3"><b>4.2</b> Поставщик гарантирует приём возврата некачественного, а так же некомплектного товара в течение 60 дней</p>
|
||||||
<p class="ml-3"><b>4.3</b> Выявленные расхождения в поставке, возврат товара отражаются сообщаются поставщику на адрес электронной почты указанную при регистрации</p>
|
<p class="ml-3"><b>4.3</b> Выявленные расхождения в поставке, возврат товара отражаются сообщаются поставщику на адрес электронной почты указанную при регистрации</p>
|
||||||
<p class="ml-3"><b>4.4</b> Поставщик даёт согласие и гарантирует законность сбора/обработки/хранения и передачи сведений, в т. ч. персональных данных, которые поставщик указывает в системе сайта</p>
|
<p class="ml-3"><b>4.4</b> Поставщик даёт согласие и гарантирует законность сбора/обработки/хранения и передачи сведений, в т. ч. персональных данных, которые поставщик указывает в системе сайта</p>
|
||||||
</br>
|
</br>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
<p><b class="mr-1">5</b> Иные условия</p>
|
<p><b class="mr-1">5</b> Иные условия</p>
|
||||||
</h5>
|
</h5>
|
||||||
<p class="ml-3"><b>5.1</b> Все споры решаются путём переговоров, в ином случае в Арбитражном суде города Хабаровск</p>
|
<p class="ml-3"><b>5.1</b> Все споры решаются путём переговоров, в ином случае в Арбитражном суде города Хабаровск</p>
|
||||||
<p class="ml-3"><b>5.2</b> Настоящий договор-оферта может быть расторгнут: - по инициативе поставщика путём направления соответствующего сообщения в систему сайта либо на <u>электронный адрес</u> указанный ниже в теле текста настоящего договора-оферты; - по инициативе торговой площадки путём направления соответствующего сообщения через систему сайта, либо на адрес электронной почты указанной поставщиком при регистрации</p>
|
<p class="ml-3"><b>5.2</b> Настоящий договор-оферта может быть расторгнут: - по инициативе поставщика путём направления соответствующего сообщения в систему сайта либо на электронный адрес указанный ниже в теле текста настоящего договора-оферты; - по инициативе торговой площадки путём направления соответствующего сообщения через систему сайта, либо на адрес электронной почты указанной поставщиком при регистрации</p>
|
||||||
<p class="ml-3"><b>5.3</b> Изменения оферты вступают в силу с момента их публикации</p>
|
<p class="ml-3"><b>5.3</b> Изменения оферты вступают в силу с момента их публикации</p>
|
||||||
<p class="ml-3"><b>5.4</b> Стороны информированы о ранее действующих версиях оферт</p>
|
<p class="ml-3"><b>5.4</b> Стороны информированы о ранее действующих версиях оферт</p>
|
||||||
</br>
|
</br>
|
||||||
|
|
|
@ -1,7 +1,174 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use yii;
|
||||||
|
use yii\bootstrap\ActiveForm;
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
if (
|
||||||
|
!yii::$app->user->isGuest
|
||||||
|
&& yii::$app->user->identity->type === 'administrator'
|
||||||
|
|| yii::$app->user->identity->type === 'moderator'
|
||||||
|
) {
|
||||||
|
$panel ?? $panel = 'orders_panel_moderation';
|
||||||
|
} else {
|
||||||
|
$panel ?? $panel = 'orders_panel_orders';
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
<link href="/css/pages/orders.css" rel="stylesheet">
|
<link href="/css/pages/orders.css" rel="stylesheet">
|
||||||
|
|
||||||
<div id="page_orders" class="container mb-auto py-3">
|
<div id="page_orders" class="container mb-auto py-3">
|
||||||
<article class="py-3 px-4 rounded">
|
<?php if (
|
||||||
|
!yii::$app->user->isGuest
|
||||||
|
&& yii::$app->user->identity->type === 'administrator'
|
||||||
|
|| yii::$app->user->identity->type === 'moderator'
|
||||||
|
) : ?>
|
||||||
|
<div class="orders_panel_menu mb-2">
|
||||||
|
<label class="btn button_white mb-0 mr-2" for="orders_panel_moderation">Модерация</label>
|
||||||
|
<label class="btn button_white mb-0" for="orders_panel_orders">Мои заказы</label>
|
||||||
|
</div>
|
||||||
|
<input type="radio" id="orders_panel_moderation" name="main_panel" <?= $panel === 'orders_panel_moderation' ? 'checked' : null ?> />
|
||||||
|
<article>
|
||||||
|
<div class="orders_panel_moderation_menu mb-3">
|
||||||
|
<label class="btn btn-sm button_white mb-0 mr-2" for="orders_panel_moderation_all">Все</label>
|
||||||
|
<label class="btn btn-sm button_white mb-0 mr-2" for="orders_panel_moderation_requested">Запрошены</label>
|
||||||
|
<label class="btn btn-sm button_white mb-0 mr-2" for="orders_panel_moderation_handled">Обрабатываются</label>
|
||||||
|
<label class="btn btn-sm button_white mb-0" for="orders_panel_moderation_completed">Завершены</label>
|
||||||
|
</div>
|
||||||
|
<?php if (!empty($moderator_orders)) : ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Инициализация счетчика заказов
|
||||||
|
$order_number = 1;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php foreach ($moderator_orders as $order) : ?>
|
||||||
|
<div class="page_order_panel mb-3 py-3 px-4 rounded">
|
||||||
|
<h5 class="row mt-1 mb-3">
|
||||||
|
<?php
|
||||||
|
// Инициализация времени отправки заказа
|
||||||
|
$date = null;
|
||||||
|
|
||||||
|
foreach ($order['order']['jrnl'] as $entry) {
|
||||||
|
// Перебор записей в журнал
|
||||||
|
|
||||||
|
if ($entry['action'] === 'requested') {
|
||||||
|
if (empty($date) || $date <= $entry['date']) {
|
||||||
|
// Буфер не инициализирован или в него записано более старое событие
|
||||||
|
|
||||||
|
// Запись
|
||||||
|
$date = $entry['date'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$date = [
|
||||||
|
'H:i' => date('H:i', $date),
|
||||||
|
'm.d.Y' => date('m.d.Y', $date)
|
||||||
|
];
|
||||||
|
|
||||||
|
?>
|
||||||
|
<p class="col-auto ml-1">#<?= $order['order']['_key'] ?></p>
|
||||||
|
<p class="col-auto mr-1">
|
||||||
|
<span class="mr-2"><?= $date['H:i'] ?? 'Неизвестно' ?></span>
|
||||||
|
<span><?= $date['m.d.Y'] ?? 'Неизвестно' ?></span>
|
||||||
|
</p>
|
||||||
|
</h5>
|
||||||
|
<div class="dropdown-divider mb-3"></div>
|
||||||
|
<div id="orders_panel_supplies_<?= $order_number ?>" class="row px-2 unselectable">
|
||||||
|
<div class="col-3">
|
||||||
|
<?php if (!empty($order['supplies'])) : ?>
|
||||||
|
<?php
|
||||||
|
// Инициализация счетчика поставок для отрисовки горизонтального разделителя
|
||||||
|
$count = 1;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php foreach ($order['supplies'] as $supply) : ?>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Инициализация обложки
|
||||||
|
$covr = null;
|
||||||
|
|
||||||
|
foreach ($imgs ?? [] as $img) {
|
||||||
|
// Перебор изображений для обложки
|
||||||
|
|
||||||
|
if ($img['covr'] ?? false) {
|
||||||
|
// Обложка найдена
|
||||||
|
|
||||||
|
$covr = $img['h150'];
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($covr)) {
|
||||||
|
// Обложка не инициализирована
|
||||||
|
|
||||||
|
if (!$covr = $imgs[0]['h150'] ?? false) {
|
||||||
|
// Не удалось использовать первое изображение как обложку
|
||||||
|
|
||||||
|
// Запись обложки по умолчанию
|
||||||
|
$covr = '/img/covers/h150/product.png';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php foreach ($supply['order_edge_supply'] as $part) : ?>
|
||||||
|
<a id="<?= $part['_id'] ?>" class="row p-2 px-0 rounded row_supply" type="button" onclick="return orders_supply_edit(this, <?= $order_number ?>);">
|
||||||
|
<img class="col-auto px-0 h-100 img-fluid rounded" src="<?= $covr ?>" />
|
||||||
|
<p class="col text-dark"><?= $supply['product']['catn'] ?></p>
|
||||||
|
</a>
|
||||||
|
<?php endforeach ?>
|
||||||
|
|
||||||
|
<?php if ($count++ < count($order['supplies'])) : ?>
|
||||||
|
<div class="dropdown-divider mb-2"></div>
|
||||||
|
<?php endif ?>
|
||||||
|
<?php endforeach ?>
|
||||||
|
<?php else : ?>
|
||||||
|
<div class="row">
|
||||||
|
<p>Поставки не найдены</p>
|
||||||
|
</div>
|
||||||
|
<?php endif ?>
|
||||||
|
</div>
|
||||||
|
<div id="orders_panel_edit_<?= $order_number ?>" class="col-6 d-flex">
|
||||||
|
<p class="my-auto">Выберите поставку</p>
|
||||||
|
</div>
|
||||||
|
<div id="orders_panel_info_<?= $order_number ?>" class="col-3 d-flex flex-column">
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Конвертация статуса заказа
|
||||||
|
$status = match ($order['account_edge_order'][0]['type']) {
|
||||||
|
'requested' => 'Запрошен',
|
||||||
|
'handled' => 'Обрабатывается',
|
||||||
|
'completed' => 'Завершен',
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<p class="row mt-0 mb-3 px-2"><b>Статус:</b> <span class="ml-auto"><?= $status ?></span></p>
|
||||||
|
<small class="row mt-auto mb-3 px-2">Здесь будет информация об общей цене и о максимальном сроке доставки которые будут меняться по мере настройки и подтверждения наличия поставок</small>
|
||||||
|
<a class="row mb-0 text-center text-white btn button_blue button_clean" type="button" onclick="return false;">Подтвердить</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
// Обновление счетчика заказов
|
||||||
|
++$order_number;
|
||||||
|
?>
|
||||||
|
<?php endforeach ?>
|
||||||
|
<?php else : ?>
|
||||||
|
<div class="page_order_panel py-3 px-4 rounded">
|
||||||
|
<p class="text-center">Заказов нет</p>
|
||||||
|
</div>
|
||||||
|
<?php endif ?>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<input type="radio" id="orders_panel_orders" name="main_panel" <?= $panel === 'orders_panel_orders' ? 'checked' : null ?> />
|
||||||
|
<?php endif ?>
|
||||||
|
<article class="page_order_panel mt-3 py-3 px-4 rounded">
|
||||||
<h4 class="ml-4 mt-2 mb-4"><i class="fas fa-list mr-2"></i>Заказы</h4>
|
<h4 class="ml-4 mt-2 mb-4"><i class="fas fa-list mr-2"></i>Заказы</h4>
|
||||||
<div class="col mb-4 list rounded overflow-hidden">
|
<div class="col mb-4 list rounded overflow-hidden">
|
||||||
<div class="row py-2">
|
<div class="row py-2">
|
||||||
|
@ -62,3 +229,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/js/orders.js" defer></script>
|
<script src="/js/orders.js" defer></script>
|
||||||
|
<?php if (
|
||||||
|
!yii::$app->user->isGuest
|
||||||
|
&& (yii::$app->user->identity->type === 'administrator'
|
||||||
|
|| yii::$app->user->identity->type === 'moderator')
|
||||||
|
) : ?>
|
||||||
|
<script src="/js/orders_panel.js" defer></script>
|
||||||
|
<?php endif ?>
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
$catg ?? $catg = 'Категория';
|
$catg ?? $catg = 'Категория';
|
||||||
$covr = null;
|
$covr = null;
|
||||||
|
|
||||||
|
// Инициализация обложки
|
||||||
foreach ($imgs ?? [] as $img) {
|
foreach ($imgs ?? [] as $img) {
|
||||||
// Перебор изображений для обложки
|
// Перебор изображений для обложки
|
||||||
|
|
||||||
|
@ -53,6 +54,9 @@
|
||||||
// Обложка не инициализирована
|
// Обложка не инициализирована
|
||||||
|
|
||||||
if (!$covr = $imgs[0]['h150'] ?? false) {
|
if (!$covr = $imgs[0]['h150'] ?? false) {
|
||||||
|
// Не удалось использовать первое изображение как обложку
|
||||||
|
|
||||||
|
// Запись обложки по умолчанию
|
||||||
$covr = '/img/covers/h150/product.png';
|
$covr = '/img/covers/h150/product.png';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ AppAsset::register($this);
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<?= Html::submitButton('Отправить', ['name' => 'submitRequest', 'id' => 'request-button-send', 'class' => 'col-auto mx-auto btn button_white button_clean']) ?>
|
<?= Html::submitButton('Отправить', ['name' => 'submitRequest', 'id' => 'request-button-send', 'class' => 'col-auto mx-auto btn button_blue button_clean']) ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php ActiveForm::end(); ?>
|
<?php ActiveForm::end(); ?>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#page_orders article {
|
#page_orders .page_order_panel {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#page_orders article .list .row:nth-child(2n+1) {
|
#page_orders .page_order_panel .list .row:nth-child(2n+1) {
|
||||||
background-color: #f7f6f9;
|
background-color: #f7f6f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
#page_orders article .list .row:first-child {
|
#page_orders .page_order_panel .list .row:first-child {
|
||||||
background-color: #dbdde3;
|
background-color: #dbdde3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,3 +14,23 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: larger;
|
font-size: larger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#page_orders>article, #page_orders>input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_orders>input:checked+article {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_orders article .row_supply {
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_orders article .row_supply:hover {
|
||||||
|
background-color: #e9e7ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_orders article .row_supply:active, #page_orders article .row_supply_active {
|
||||||
|
background-color: #e4e2ea;
|
||||||
|
}
|
||||||
|
|
|
@ -315,6 +315,12 @@ function cart_response(data, status) {
|
||||||
reinitialization(main);
|
reinitialization(main);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Перенаправление
|
||||||
|
if (data.redirect !== undefined) {
|
||||||
|
// Перенаправление
|
||||||
|
history.pushState({}, document.title, data.redirect);
|
||||||
|
}
|
||||||
|
|
||||||
// CSRF-токен
|
// CSRF-токен
|
||||||
if (data._csrf !== undefined) {
|
if (data._csrf !== undefined) {
|
||||||
// Обновление документа
|
// Обновление документа
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
function orders_response(data, status) {
|
||||||
|
// Обработка ответов
|
||||||
|
|
||||||
|
// Основной блок
|
||||||
|
if (data.main !== undefined) {
|
||||||
|
main = document.getElementsByTagName('main')[0];
|
||||||
|
|
||||||
|
// Обновление документа
|
||||||
|
main.innerHTML = data.main;
|
||||||
|
|
||||||
|
// Реинициализация
|
||||||
|
reinitialization(main);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Перенаправление
|
||||||
|
if (data.redirect !== undefined) {
|
||||||
|
// Перенаправление
|
||||||
|
history.pushState({}, document.title, data.redirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSRF-токен
|
||||||
|
if (data._csrf !== undefined) {
|
||||||
|
// Обновление документа
|
||||||
|
$('meta[name=csrf-token]').prop("content", data._csrf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function orders_response_success(data, status) {
|
||||||
|
// Обработка ответов от удавшихся запросов
|
||||||
|
|
||||||
|
orders_response(data, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
function orders_response_error(data, status) {
|
||||||
|
// Обработка ответов от неудавшихся запросов
|
||||||
|
|
||||||
|
// Инициализвация
|
||||||
|
data = data.responseJSON;
|
||||||
|
|
||||||
|
orders_response(data, status);
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
function orders_supply_edit(target, order_number) {
|
||||||
|
// Поиск панели для вывода информации
|
||||||
|
let panel = document.getElementById('orders_panel_edit_' + order_number);
|
||||||
|
|
||||||
|
// Поиск всех кнопок с поставками
|
||||||
|
let rows = document.getElementsByClassName('row_supply');
|
||||||
|
|
||||||
|
// Деактивация остальных кнопок
|
||||||
|
for (let i = 0; i < rows.length; i++) {
|
||||||
|
if (rows[i].parentElement.parentElement.getAttribute('id') === 'orders_panel_supplies_' + order_number) {
|
||||||
|
// Если это кнопка конкретно с этого заказа
|
||||||
|
|
||||||
|
rows[i].classList.remove('row_supply_active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Активация выбранной кнопки
|
||||||
|
target.classList.add('row_supply_active');
|
||||||
|
|
||||||
|
panel.innerHTML = target.getAttribute('id');
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
Reference in New Issue