Склады
This commit is contained in:
parent
7a4f12aa94
commit
b08f7f7d0a
|
@ -58,21 +58,9 @@ class AuthenticationController extends Controller
|
||||||
// Настройка кода ответа
|
// Настройка кода ответа
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
// Валидация формы
|
|
||||||
// if (!empty($errors = ActiveForm::validate($model))) {
|
|
||||||
|
|
||||||
// // Настройка кода ответа
|
|
||||||
// yii::$app->response->statusCode = 401;
|
|
||||||
|
|
||||||
// return $errors;
|
|
||||||
// };
|
|
||||||
|
|
||||||
if (!yii::$app->user->isGuest || $model->authentication()) {
|
if (!yii::$app->user->isGuest || $model->authentication()) {
|
||||||
// Аккаунт аутентифицирован
|
// Аккаунт аутентифицирован
|
||||||
|
|
||||||
// Создание сессии
|
|
||||||
// yii::$app->session->open();
|
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$notifications_button = $this->renderPartial('/notification/button');
|
$notifications_button = $this->renderPartial('/notification/button');
|
||||||
$notifications_panel = $this->renderPartial('/notification/panel', ['notifications_panel_full' => true]);
|
$notifications_panel = $this->renderPartial('/notification/panel', ['notifications_panel_full' => true]);
|
||||||
|
@ -94,19 +82,6 @@ class AuthenticationController extends Controller
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
$return['redirect'] = '/' . $cookies['redirect'];
|
$return['redirect'] = '/' . $cookies['redirect'];
|
||||||
|
|
||||||
// try {
|
|
||||||
// if (empty($return['main'] = $this->renderPartial($return['redirect']))) {
|
|
||||||
// throw new Exception('Представление найдено, но вернуло пустой результат');
|
|
||||||
// }
|
|
||||||
// } catch (Throwable $t) {
|
|
||||||
// $return['main'] = $this->renderPartial($return['redirect'] . '/index');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Генерация и запись
|
|
||||||
// $controller = 'app\\controllers\\' . ucfirst($cookies['redirect']) . 'Controller';
|
|
||||||
// $action = 'action' . ucfirst($cookies['redirect_action']);
|
|
||||||
// $return['main'] = (new $controller())->$action();
|
|
||||||
|
|
||||||
// Очистка cookie
|
// Очистка cookie
|
||||||
unset(yii::$app->response->cookies['redirect']);
|
unset(yii::$app->response->cookies['redirect']);
|
||||||
|
|
||||||
|
|
|
@ -298,13 +298,16 @@ class OrderController extends Controller
|
||||||
if (yii::$app->request->isPost) {
|
if (yii::$app->request->isPost) {
|
||||||
// POST-запрос
|
// POST-запрос
|
||||||
|
|
||||||
// Настройка
|
// Инициализация аккаунта
|
||||||
yii::$app->response->format = Response::FORMAT_JSON;
|
$account ?? $account = Account::initAccount();
|
||||||
|
|
||||||
// Конвертация из UNIXTIME в формат поддерживаемый календарём по спецификации HTML
|
// Конвертация из UNIXTIME в формат поддерживаемый календарём по спецификации HTML
|
||||||
$from = DateTime::createFromFormat('U', (string) $from)->format('Y-m-d');
|
$from = DateTime::createFromFormat('U', (string) $from)->format('Y-m-d');
|
||||||
$to = DateTime::createFromFormat('U', (string) $to)->format('Y-m-d');
|
$to = DateTime::createFromFormat('U', (string) $to)->format('Y-m-d');
|
||||||
|
|
||||||
|
// Запись формата ответа
|
||||||
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('/orders/index', compact('orders', 'moderator_orders', 'search', 'from', 'to', 'window')
|
'main' => $this->renderPartial('/orders/index', compact('orders', 'moderator_orders', 'search', 'from', 'to', 'window')
|
||||||
+ ['panel' => $this->renderPartial('/orders/search/panel', compact('account') + ['response' => @$orders[0]['supplies']] ?? null)]),
|
+ ['panel' => $this->renderPartial('/orders/search/panel', compact('account') + ['response' => @$orders[0]['supplies']] ?? null)]),
|
||||||
|
|
|
@ -20,7 +20,7 @@ use app\models\Settings;
|
||||||
use app\models\Dellin;
|
use app\models\Dellin;
|
||||||
use app\models\SettingsEdgeSettings;
|
use app\models\SettingsEdgeSettings;
|
||||||
use app\models\Terminal;
|
use app\models\Terminal;
|
||||||
|
use app\models\Warehouse;
|
||||||
use Dadata\DadataClient as Dadata;
|
use Dadata\DadataClient as Dadata;
|
||||||
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
@ -453,6 +453,7 @@ class ProfileController extends Controller
|
||||||
$help = (bool) (yii::$app->request->post('help') ?? yii::$app->request->get('help'));
|
$help = (bool) (yii::$app->request->post('help') ?? yii::$app->request->get('help'));
|
||||||
$target = yii::$app->request->post('account') ?? yii::$app->request->get('account');
|
$target = yii::$app->request->post('account') ?? yii::$app->request->get('account');
|
||||||
$number = yii::$app->request->post('number') ?? yii::$app->request->get('number');
|
$number = yii::$app->request->post('number') ?? yii::$app->request->get('number');
|
||||||
|
$warehouse = yii::$app->request->post('warehouse') ?? yii::$app->request->get('warehouse');
|
||||||
$sidebar = $this->renderPartial('sidebar');
|
$sidebar = $this->renderPartial('sidebar');
|
||||||
$groups = self::readGroups();
|
$groups = self::readGroups();
|
||||||
|
|
||||||
|
@ -474,6 +475,9 @@ class ProfileController extends Controller
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Инициализация файла
|
||||||
|
$supply->file_excel = UploadedFile::getInstance($supply, 'file_excel');
|
||||||
|
|
||||||
if (!empty($target)) {
|
if (!empty($target)) {
|
||||||
// Получен аккаунт для которого необходимо загрузить каталог
|
// Получен аккаунт для которого необходимо загрузить каталог
|
||||||
|
|
||||||
|
@ -489,9 +493,9 @@ class ProfileController extends Controller
|
||||||
if (Account::isMinimalAuthorized()) {
|
if (Account::isMinimalAuthorized()) {
|
||||||
// Авторизован доступ к выполнению этого действия
|
// Авторизован доступ к выполнению этого действия
|
||||||
|
|
||||||
$supply->{"file_excel_$number"} = UploadedFile::getInstance($supply, 'file_excel');
|
if ($supply->importExcel((int) $warehouse, $target)) {
|
||||||
|
// Импорт успешно завершён
|
||||||
|
|
||||||
if ($supply->importExcel($target)) {
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('supplies', compact(
|
'main' => $this->renderPartial('supplies', compact(
|
||||||
'supply',
|
'supply',
|
||||||
|
@ -515,12 +519,9 @@ class ProfileController extends Controller
|
||||||
} else {
|
} else {
|
||||||
// Не получен аккаунт для которого необходимо загрузить каталог
|
// Не получен аккаунт для которого необходимо загрузить каталог
|
||||||
|
|
||||||
// Инициализация файлов
|
|
||||||
$supply->file_excel_1 = UploadedFile::getInstance($supply, 'file_excel_1');
|
|
||||||
$supply->file_excel_2 = UploadedFile::getInstance($supply, 'file_excel_2');
|
|
||||||
$supply->file_excel_3 = UploadedFile::getInstance($supply, 'file_excel_3');
|
|
||||||
|
|
||||||
if ($supply->importExcel()) {
|
if ($supply->importExcel((int) $warehouse)) {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('supplies', compact(
|
'main' => $this->renderPartial('supplies', compact(
|
||||||
'supply',
|
'supply',
|
||||||
|
@ -536,12 +537,15 @@ class ProfileController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('supplies', compact(
|
return [
|
||||||
|
'main' => $this->renderPartial('supplies', compact(
|
||||||
'supply',
|
'supply',
|
||||||
'groups',
|
'groups',
|
||||||
'sidebar',
|
'sidebar',
|
||||||
'panel'
|
'panel'
|
||||||
));
|
)),
|
||||||
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function readGroups()
|
public static function readGroups()
|
||||||
|
|
|
@ -78,19 +78,6 @@ class RegistrationController extends Controller
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
$return['redirect'] = '/' . $cookies['redirect'];
|
$return['redirect'] = '/' . $cookies['redirect'];
|
||||||
|
|
||||||
// try {
|
|
||||||
// if (empty($return['main'] = $this->renderPartial($return['redirect']))) {
|
|
||||||
// throw new Exception('Представление найдено, но вернуло пустой результат');
|
|
||||||
// }
|
|
||||||
// } catch (Throwable $t) {
|
|
||||||
// $return['main'] = $this->renderPartial($return['redirect'] . '/index');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Генерация и запись
|
|
||||||
// $controller = 'app\\controllers\\' . ucfirst($cookies['redirect']) . 'Controller';
|
|
||||||
// $action = 'action' . ucfirst($cookies['redirect_action']);
|
|
||||||
// $return['main'] = (new $controller())->$action();
|
|
||||||
|
|
||||||
// Очистка cookie
|
// Очистка cookie
|
||||||
unset(yii::$app->response->cookies['redirect']);
|
unset(yii::$app->response->cookies['redirect']);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
|
class m211221_183410_create_warehouse_collection extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string Название коллекции
|
||||||
|
* @param array Тип коллекции (2 - документ, 3 - ребро)
|
||||||
|
*/
|
||||||
|
$this->createCollection('warehouse', ['type' => 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->dropCollection('warehouse');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
|
class m211221_183447_create_warehouse_edge_import_collection extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string Название коллекции
|
||||||
|
* @param array Тип коллекции (2 - документ, 3 - ребро)
|
||||||
|
*/
|
||||||
|
$this->createCollection('warehouse_edge_import', ['type' => 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->dropCollection('warehouse_edge_import');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
|
class m211221_193454_create_account_edge_warehouse_collection extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string Название коллекции
|
||||||
|
* @param array Тип коллекции (2 - документ, 3 - ребро)
|
||||||
|
*/
|
||||||
|
$this->createCollection('account_edge_warehouse', ['type' => 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->dropCollection('account_edge_warehouse');
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ use carono\exchange1c\interfaces\PartnerInterface;
|
||||||
|
|
||||||
use app\models\Dellin;
|
use app\models\Dellin;
|
||||||
use app\models\traits\SearchByEdge;
|
use app\models\traits\SearchByEdge;
|
||||||
|
|
||||||
use yii\web\UploadedFile;
|
use yii\web\UploadedFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -455,40 +456,6 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
return $this->syncListWithSettings($list, 'import_supplies_oem');
|
return $this->syncListWithSettings($list, 'import_supplies_oem');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Генерация списка терминалов из ДеловыеЛинии для отправителя
|
|
||||||
*
|
|
||||||
* Актуальное (выбранное, активное) значение записывается первым
|
|
||||||
*
|
|
||||||
* @param array Необработанный список терминалов
|
|
||||||
*/
|
|
||||||
public function genListTerminalsFrom(): array
|
|
||||||
{
|
|
||||||
// Инициализация
|
|
||||||
$list = [];
|
|
||||||
|
|
||||||
$cities = Dellin::readAll();
|
|
||||||
|
|
||||||
foreach ($cities as $city) {
|
|
||||||
// Перебор городов
|
|
||||||
|
|
||||||
foreach ($city->data['terminals']['terminal'] as $termial) {
|
|
||||||
// Перебор терминалов
|
|
||||||
|
|
||||||
if (in_array($termial['id'], $list, true)) {
|
|
||||||
// Если встретился дубликат (исполняется очень часто)
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Запись
|
|
||||||
$list[$termial['id']] = $city->data['name'] . ' (' . $termial['address'] . ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->syncListWithSettings($list, 'delivery_from_terminal');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Генерация списка терминалов из ДеловыеЛинии для получателя
|
* Генерация списка терминалов из ДеловыеЛинии для получателя
|
||||||
*
|
*
|
||||||
|
@ -901,7 +868,7 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
*
|
*
|
||||||
* @param static|null $account Аккаунт
|
* @param static|null $account Аккаунт
|
||||||
*/
|
*/
|
||||||
public static function initAccount($account = null): ?static
|
public static function initAccount(Account|int $account = null): ?static
|
||||||
{
|
{
|
||||||
if (is_null($account)) {
|
if (is_null($account)) {
|
||||||
// Данные аккаунта не переданы
|
// Данные аккаунта не переданы
|
||||||
|
@ -917,7 +884,11 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
return $account;
|
return $account;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (is_int($account)) {
|
if ($account instanceof Account) {
|
||||||
|
// Передана инстанция аккаунта
|
||||||
|
|
||||||
|
return $account;
|
||||||
|
} else if (is_int($account)) {
|
||||||
// Передан идентификатор (_key) аккаунта (подразумевается)
|
// Передан идентификатор (_key) аккаунта (подразумевается)
|
||||||
|
|
||||||
// Инициализация (поиск в базе данных)
|
// Инициализация (поиск в базе данных)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
use app\models\Account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Связь аккаунтов и складов
|
||||||
|
*/
|
||||||
|
class AccountEdgeWarehouse extends Edge
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return 'account_edge_warehouse';
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,32 +51,6 @@ class AccountForm extends Model
|
||||||
'message' => 'Заполните поле',
|
'message' => 'Заполните поле',
|
||||||
'on' => self::SCENARIO_AUTHENTICATION
|
'on' => self::SCENARIO_AUTHENTICATION
|
||||||
],
|
],
|
||||||
// Обязательные поля для регистрации
|
|
||||||
// [
|
|
||||||
// [
|
|
||||||
// 'rept',
|
|
||||||
// 'pols'
|
|
||||||
// ],
|
|
||||||
// 'required',
|
|
||||||
// 'message' => 'Заполните поле',
|
|
||||||
// 'on' => self::SCENARIO_REGISTRATION
|
|
||||||
// ],
|
|
||||||
// Повтор пароля
|
|
||||||
// [
|
|
||||||
// 'rept',
|
|
||||||
// 'compare',
|
|
||||||
// 'compareAttribute' => 'pswd',
|
|
||||||
// 'message' => "Пароли не совпадают",
|
|
||||||
// 'on' => self::SCENARIO_REGISTRATION,
|
|
||||||
// ],
|
|
||||||
// Принятие политики конфидециальности
|
|
||||||
// [
|
|
||||||
// 'pols',
|
|
||||||
// 'compare',
|
|
||||||
// 'compareValue' => 'on',
|
|
||||||
// 'message' => "Чтобы продолжить примите нашу политику конфидециальности",
|
|
||||||
// 'on' => self::SCENARIO_REGISTRATION,
|
|
||||||
// ],
|
|
||||||
// Функция "Запомнить меня"
|
// Функция "Запомнить меня"
|
||||||
[
|
[
|
||||||
'auto',
|
'auto',
|
||||||
|
@ -151,12 +125,20 @@ class AccountForm extends Model
|
||||||
// Удалось инициализировать аккаунт
|
// Удалось инициализировать аккаунт
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$account->validatePasswordWithHash($this->pswd);
|
if (!$account->validatePasswordWithHash($this->pswd)) {
|
||||||
|
// Не пройдена проверка с хешем
|
||||||
|
|
||||||
|
throw new exception;
|
||||||
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
// Проверка с хешем не пройдена
|
// Не пройдена проверка с хешем
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$account->validatePasswordWithoutHash($this->pswd);
|
if (!$account->validatePasswordWithoutHash($this->pswd)) {
|
||||||
|
// Не пройдена проверка с паролем
|
||||||
|
|
||||||
|
throw new exception;
|
||||||
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
// Проверка без хеша не пройдена
|
// Проверка без хеша не пройдена
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use app\models\Account;
|
||||||
/**
|
/**
|
||||||
* Импорт поставок
|
* Импорт поставок
|
||||||
*
|
*
|
||||||
* Хранит себе связи с поставками которые были загружены вместе
|
* Хранит в себе связи с поставками которые были загружены вместе
|
||||||
*/
|
*/
|
||||||
class Import extends Document
|
class Import extends Document
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,6 @@ class Import extends Document
|
||||||
return array_merge(
|
return array_merge(
|
||||||
parent::attributes(),
|
parent::attributes(),
|
||||||
[
|
[
|
||||||
'pstn',
|
|
||||||
'name',
|
'name',
|
||||||
'file'
|
'file'
|
||||||
]
|
]
|
||||||
|
@ -49,7 +48,6 @@ class Import extends Document
|
||||||
return array_merge(
|
return array_merge(
|
||||||
parent::attributeLabels(),
|
parent::attributeLabels(),
|
||||||
[
|
[
|
||||||
'pstn' => 'Позиция',
|
|
||||||
'name' => 'Название',
|
'name' => 'Название',
|
||||||
'file' => 'Файл'
|
'file' => 'Файл'
|
||||||
]
|
]
|
||||||
|
@ -64,14 +62,6 @@ class Import extends Document
|
||||||
return array_merge(
|
return array_merge(
|
||||||
parent::rules(),
|
parent::rules(),
|
||||||
[
|
[
|
||||||
[
|
|
||||||
'pstn',
|
|
||||||
'required'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'pstn',
|
|
||||||
'integer'
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
'file',
|
'file',
|
||||||
|
@ -83,15 +73,26 @@ class Import extends Document
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function searchByPosition(int $position = 1, Account $account = null, int $limit = 1): array
|
/**
|
||||||
|
* Поиск по складу
|
||||||
|
*
|
||||||
|
* @param Warehouse $warehouse Инстанция склада
|
||||||
|
* @param int $limit Ограничение по максимальному количеству
|
||||||
|
*
|
||||||
|
* @return array Инстанции испортов
|
||||||
|
*/
|
||||||
|
public static function searchByWarehouse(Warehouse $warehouse, int $limit = 10): array
|
||||||
{
|
{
|
||||||
return self::searchByEdge(
|
return self::searchByEdge(
|
||||||
from: 'account',
|
from: 'warehouse',
|
||||||
to: 'import',
|
to: 'import',
|
||||||
edge: 'import_edge_account',
|
edge: 'warehouse_edge_import',
|
||||||
direction: 'INBOUND',
|
direction: 'INBOUND',
|
||||||
subquery_where: 'account._key == "' . Account::initAccount($account)->_key . '" && import_edge_account.type == "loaded"',
|
subquery_where: [
|
||||||
where: ['import.pstn' => $position],
|
['warehouse_edge_import._from' => $warehouse->readId()],
|
||||||
|
['warehouse_edge_import.type' => 'loaded']
|
||||||
|
],
|
||||||
|
where: 'warehouse_edge_import[0] != null',
|
||||||
limit: $limit
|
limit: $limit
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,32 +51,9 @@ class Product extends Document
|
||||||
* Файл .excel для импорта товаров
|
* Файл .excel для импорта товаров
|
||||||
*
|
*
|
||||||
* Универсальный, когда неизвестно на какую позицию загружать каталог
|
* Универсальный, когда неизвестно на какую позицию загружать каталог
|
||||||
*
|
|
||||||
* @todo Избавиться от свойств и сделать бесконечное количество места под новые каталоги
|
|
||||||
*/
|
*/
|
||||||
public Excel|UploadedFile|string|null $file_excel = null;
|
public Excel|UploadedFile|string|null $file_excel = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* Файл .excel для импорта товаров
|
|
||||||
*
|
|
||||||
* @todo Избавиться от свойств и сделать бесконечное количество места под новые каталоги
|
|
||||||
*/
|
|
||||||
public Excel|UploadedFile|string|null $file_excel_1 = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Файл .excel для импорта товаров
|
|
||||||
*
|
|
||||||
* @todo Избавиться от свойств и сделать бесконечное количество места под новые каталоги
|
|
||||||
*/
|
|
||||||
public Excel|UploadedFile|string|null $file_excel_2 = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Файл .excel для импорта товаров
|
|
||||||
*
|
|
||||||
* @todo Избавиться от свойств и сделать бесконечное количество места под новые каталоги
|
|
||||||
*/
|
|
||||||
public Excel|UploadedFile|string|null $file_excel_3 = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Изображение для импорта
|
* Изображение для импорта
|
||||||
*/
|
*/
|
||||||
|
@ -132,9 +109,7 @@ class Product extends Document
|
||||||
'imgs' => 'Изображения (imgs)',
|
'imgs' => 'Изображения (imgs)',
|
||||||
'time' => 'Срок доставки (time)',
|
'time' => 'Срок доставки (time)',
|
||||||
'bffr' => 'Буфер',
|
'bffr' => 'Буфер',
|
||||||
'file_excel_1' => 'Документ (file_excel_1)',
|
'file_excel' => 'Документ (file_excel)',
|
||||||
'file_excel_2' => 'Документ (file_excel_2)',
|
|
||||||
'file_excel_3' => 'Документ (file_excel_3)',
|
|
||||||
'file_image' => 'Изображение (file_image)',
|
'file_image' => 'Изображение (file_image)',
|
||||||
'group' => 'Группа (group)',
|
'group' => 'Группа (group)',
|
||||||
'account' => 'Аккаунт'
|
'account' => 'Аккаунт'
|
||||||
|
@ -194,11 +169,7 @@ class Product extends Document
|
||||||
'message' => '{attribute} должен иметь значение от 0 до 30000'
|
'message' => '{attribute} должен иметь значение от 0 до 30000'
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[
|
'file_excel',
|
||||||
'file_excel_1',
|
|
||||||
'file_excel_2',
|
|
||||||
'file_excel_3'
|
|
||||||
],
|
|
||||||
'file',
|
'file',
|
||||||
'skipOnEmpty' => true,
|
'skipOnEmpty' => true,
|
||||||
'extensions' => 'xlsx',
|
'extensions' => 'xlsx',
|
||||||
|
|
|
@ -13,7 +13,7 @@ use app\models\SupplyEdgeProduct;
|
||||||
use app\models\Settings;
|
use app\models\Settings;
|
||||||
use app\models\Import;
|
use app\models\Import;
|
||||||
use app\models\ImportEdgeSupply;
|
use app\models\ImportEdgeSupply;
|
||||||
use app\models\ImportEdgeAccount;
|
use app\models\WarehouseEdgeImport;
|
||||||
|
|
||||||
use carono\exchange1c\interfaces\OfferInterface;
|
use carono\exchange1c\interfaces\OfferInterface;
|
||||||
use carono\exchange1c\interfaces\ProductInterface;
|
use carono\exchange1c\interfaces\ProductInterface;
|
||||||
|
@ -379,8 +379,11 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
||||||
*
|
*
|
||||||
* На данный момент обрабатывает только импорт из
|
* На данный момент обрабатывает только импорт из
|
||||||
* файлов с расширением .excel
|
* файлов с расширением .excel
|
||||||
|
*
|
||||||
|
* @param int $warehouse Идентификатор склада (_key)
|
||||||
|
* @param Account|int|null $account Аккаунт
|
||||||
*/
|
*/
|
||||||
public function importExcel(Account|int|null $account = null): bool
|
public function importExcel(int $warehouse, Account|int|null $account = null): bool
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$data = [];
|
$data = [];
|
||||||
|
@ -391,49 +394,26 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
||||||
if ($this->validate()) {
|
if ($this->validate()) {
|
||||||
// Пройдена проверка
|
// Пройдена проверка
|
||||||
|
|
||||||
if (isset($this->file_excel_1)) {
|
if (!isset($this->file_excel)) {
|
||||||
// Найден файл в позиции 1
|
// Не найден файл
|
||||||
|
|
||||||
// Инициализация позиции
|
|
||||||
$position = 1;
|
|
||||||
|
|
||||||
// Запись в буфер
|
|
||||||
$file = $this->file_excel_1;
|
|
||||||
} else if (isset($this->file_excel_2)) {
|
|
||||||
// Найден файл в позиции 2
|
|
||||||
|
|
||||||
// Инициализация позиции
|
|
||||||
$position = 2;
|
|
||||||
|
|
||||||
// Запись в буфер
|
|
||||||
$file = $this->file_excel_2;
|
|
||||||
} else if (isset($this->file_excel_3)) {
|
|
||||||
// Найден файл в позиции 3
|
|
||||||
|
|
||||||
// Инициализация позиции
|
|
||||||
$position = 3;
|
|
||||||
|
|
||||||
// Запись в буфер
|
|
||||||
$file = $this->file_excel_3;
|
|
||||||
} else {
|
|
||||||
// Не найден ни один файл
|
|
||||||
|
|
||||||
// Запись ошибки
|
// Запись ошибки
|
||||||
$this->addError('erros', 'Файл для импорта не найден');
|
$this->addError('errors', 'Файл для импорта не найден');
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация хранилища файлов
|
||||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||||
$timezone = $timezone[1][0];
|
$timezone = $timezone[1][0];
|
||||||
// $path = YII_PATH_PUBLIC . "/../assets/accounts/$account->_key/files/" . (new DateTime('now', new DateTimeZone($timezone)))->getTimestamp();
|
$path = YII_PATH_PUBLIC . "/files/$account->_key/$warehouse/" . (new DateTime('now', new DateTimeZone($timezone)))->getTimestamp();
|
||||||
$path = YII_PATH_PUBLIC . "/files/$account->_key/" . (new DateTime('now', new DateTimeZone($timezone)))->getTimestamp();
|
|
||||||
|
|
||||||
// Сохранение на диск
|
// Сохранение на диск
|
||||||
if (!file_exists($path))
|
if (!file_exists($path))
|
||||||
if (!mkdir($path, 0775, true))
|
if (!mkdir($path, 0775, true))
|
||||||
throw new Exception('Не удалось создать директорию', 500);
|
throw new Exception('Не удалось создать директорию', 500);
|
||||||
|
|
||||||
$file->saveAs($path = "$path/" . $filename = $file->baseName . '.' . $file->extension);
|
$this->file_excel->saveAs($path = "$path/" . $filename = $this->file_excel->baseName . '.' . $this->file_excel->extension);
|
||||||
|
|
||||||
$data[] = Excel::import($path, [
|
$data[] = Excel::import($path, [
|
||||||
'setFirstRecordAsKeys' => true,
|
'setFirstRecordAsKeys' => true,
|
||||||
|
@ -449,7 +429,7 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
||||||
if (count($data) < 1) {
|
if (count($data) < 1) {
|
||||||
// Не найдены строки с товарами
|
// Не найдены строки с товарами
|
||||||
|
|
||||||
$this->addError('erros', 'Не удалось найти данные товаров');
|
$this->addError('errors', 'Не удалось найти данные товаров');
|
||||||
} else {
|
} else {
|
||||||
// Найдены строки с товарами
|
// Найдены строки с товарами
|
||||||
|
|
||||||
|
@ -542,17 +522,16 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
||||||
|
|
||||||
$import->file = $path;
|
$import->file = $path;
|
||||||
$import->name = $filename;
|
$import->name = $filename;
|
||||||
$import->pstn = $position;
|
|
||||||
|
|
||||||
if ($import->save()) {
|
if ($import->save()) {
|
||||||
// Инстанция импорта успешно загружена
|
// Инстанция импорта успешно загружена
|
||||||
|
|
||||||
if (ImportEdgeAccount::write(yii::$app->user->identity->collectionName() . '/' . yii::$app->user->identity->_key, $import->collectionName() . "/$import->_key", data: ['type' => 'loaded'])) {
|
if (WarehouseEdgeImport::write(Warehouse::collectionName() . "/$warehouse", $import->readId(), data: ['type' => 'loaded'])) {
|
||||||
// Записано ребро: АККАУНТ -> ИНСТАНЦИЯ ПОСТАВОК
|
// Записано ребро: СКЛАД -> ИНСТАНЦИЯ ПОСТАВОК
|
||||||
|
|
||||||
// Запись в журнал инстанции импорта
|
// Запись в журнал инстанции импорта
|
||||||
$import->journal('connect_with_account', [
|
$import->journal('connect_with_warehouse', [
|
||||||
'target' => yii::$app->user->identity->collectionName() . '/' . yii::$app->user->identity->_key
|
'target' => Warehouse::collectionName() . "/$warehouse"
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +543,7 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
||||||
|
|
||||||
// Запись в журнал инстанции импорта
|
// Запись в журнал инстанции импорта
|
||||||
$import->journal('connect_with_supply', [
|
$import->journal('connect_with_supply', [
|
||||||
'target' => $supply->collectionName() . "/$supply->_key"
|
'target' => $supply->readId()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,19 +554,19 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
||||||
static::afterImportExcel($created, $updated);
|
static::afterImportExcel($created, $updated);
|
||||||
|
|
||||||
// Удаление (важно именно задать null для формы в представлении)
|
// Удаление (важно именно задать null для формы в представлении)
|
||||||
$this->file_excel_1 = $this->file_excel_2 = $this->file_excel_3 = null;
|
$this->file_excel = null;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Запись ошибки
|
// Запись ошибки
|
||||||
$this->addError('erros', 'Не пройдена проверка параметров');
|
$this->addError('errors', 'Не пройдена проверка параметров');
|
||||||
|
|
||||||
// Макрос действий после импорта
|
// Макрос действий после импорта
|
||||||
static::afterImportExcel($created, $updated);
|
static::afterImportExcel($created, $updated);
|
||||||
|
|
||||||
// Удаление (важно именно задать null для формы в представлении)
|
// Удаление (важно именно задать null для формы в представлении)
|
||||||
$this->file_excel_1 = $this->file_excel_2 = $this->file_excel_3 = null;
|
$this->file_excel = null;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -757,34 +736,34 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Прочитать стоимость
|
* Прочитать стоимость
|
||||||
// *
|
*
|
||||||
// * @param Product|null $product Товар для поиска по вершинам
|
* @param Product|null $product Товар для поиска по вершинам
|
||||||
// *
|
*
|
||||||
// * @return array|null Данные о ценах
|
* @return array|null Данные о ценах
|
||||||
// */
|
*/
|
||||||
// public function readCost(Product $product = null): ?array
|
public function readCost(Product $product = null): ?array
|
||||||
// {
|
{
|
||||||
// return static::readCostById($this->readId(), $product);
|
return static::readCostById($this->readId(), $product);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Прочитать стоимость по идентификатору поставки
|
* Прочитать стоимость по идентификатору поставки
|
||||||
// *
|
*
|
||||||
// * @param string $_id Идентификатор поставки
|
* @param string $_id Идентификатор поставки
|
||||||
// * @param Product|null $product Товар для поиска по вершинам
|
* @param Product|null $product Товар для поиска по вершинам
|
||||||
// *
|
*
|
||||||
// * @return array|null Данные о ценах
|
* @return array|null Данные о ценах
|
||||||
// */
|
*/
|
||||||
// public static function readCostById(string $_id, Product $product = null): ?array
|
public static function readCostById(string $_id, Product $product = null): ?array
|
||||||
// {
|
{
|
||||||
// if (isset($product)) {
|
if (isset($product)) {
|
||||||
// return SupplyEdgeProduct::searchByVertex($_id, $product->readId(), type: 'connect', limit: 1)['onec']['Цены']['Цена'];
|
return SupplyEdgeProduct::searchByVertex($_id, $product->readId(), type: 'connect', limit: 1)['onec']['Цены']['Цена'];
|
||||||
// }
|
}
|
||||||
|
|
||||||
// return SupplyEdgeProduct::searchByDirection($_id, type: 'connect', limit: 1)['onec']['Цены']['Цена'];
|
return SupplyEdgeProduct::searchByDirection($_id, type: 'connect', limit: 1)['onec']['Цены']['Цена'];
|
||||||
// }
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Найти аккаунт владельца
|
* Найти аккаунт владельца
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
use app\models\traits\SearchByEdge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Склад
|
||||||
|
*
|
||||||
|
* Хранит в себе связи с инстанциями поставок, а от них и связи со всеми поставками
|
||||||
|
*/
|
||||||
|
class Warehouse extends Document
|
||||||
|
{
|
||||||
|
use SearchByEdge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return 'warehouse';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::attributes(),
|
||||||
|
[
|
||||||
|
'name',
|
||||||
|
'addr',
|
||||||
|
'trmn',
|
||||||
|
'actv'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метки свойств
|
||||||
|
*/
|
||||||
|
public function attributeLabels(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::attributeLabels(),
|
||||||
|
[
|
||||||
|
'name' => 'Название',
|
||||||
|
'addr' => 'Адрес',
|
||||||
|
'trmn' => 'Терминал',
|
||||||
|
'actv' => 'Активность'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Правила
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::rules(),
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'name',
|
||||||
|
'addr'
|
||||||
|
],
|
||||||
|
'string'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'actv',
|
||||||
|
'boolean'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запись по аккаунту
|
||||||
|
*
|
||||||
|
* @param Account|null $account Аккаунт
|
||||||
|
*
|
||||||
|
* @return static|null Записанный склад
|
||||||
|
*/
|
||||||
|
public static function writeByAccount(Account|null $account = null): ?static
|
||||||
|
{
|
||||||
|
// Инициализация аккаунта
|
||||||
|
$account = Account::initAccount($account);
|
||||||
|
|
||||||
|
// Инициализация склада
|
||||||
|
$warehouse = new static;
|
||||||
|
|
||||||
|
// Запись параметров склада
|
||||||
|
$warehouse->actv = true;
|
||||||
|
|
||||||
|
if ($warehouse->save()) {
|
||||||
|
// Удалось записать склад в базу данных
|
||||||
|
|
||||||
|
// Инициализация ребра: АККАУНТ -> СКЛАД
|
||||||
|
AccountEdgeWarehouse::writeSafe($account->readId(), $warehouse->readId(), data: ['type' => 'connected']);
|
||||||
|
|
||||||
|
return $warehouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Найти по аккаунту
|
||||||
|
*
|
||||||
|
* @param Account|null $account Аккаунт
|
||||||
|
* @param int $limit Ограничение по максимальному количеству
|
||||||
|
*
|
||||||
|
* @return mixed Склады
|
||||||
|
*/
|
||||||
|
public static function searchByAccount(Account|null $account = null, int $limit = 10): mixed
|
||||||
|
{
|
||||||
|
if ($account = Account::initAccount($account)) {
|
||||||
|
// Инициализирован аккаунт
|
||||||
|
|
||||||
|
return static::searchByEdge(
|
||||||
|
from: 'account',
|
||||||
|
to: 'warehouse',
|
||||||
|
edge: 'account_edge_warehouse',
|
||||||
|
direction: 'INBOUND',
|
||||||
|
subquery_where: [
|
||||||
|
[
|
||||||
|
'account_edge_warehouse._from == "' . $account->readId() . '"'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'account_edge_warehouse.type == "connected"'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
where: 'account_edge_warehouse[0] != null',
|
||||||
|
limit: $limit
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Инициализация с записью
|
||||||
|
*
|
||||||
|
* Читает все склады привязанные к аккаунту, либо создает новый склад
|
||||||
|
*
|
||||||
|
* @param Account|null $account Аккаунт
|
||||||
|
* @param int $limit — Ограничение по максимальному количеству
|
||||||
|
*
|
||||||
|
* @return array Склады
|
||||||
|
*/
|
||||||
|
public static function initWithWrite(Account|null $account = null, int $limit = 10): array
|
||||||
|
{
|
||||||
|
if ($account = Account::initAccount($account)) {
|
||||||
|
// Инициализирован аккаунт
|
||||||
|
|
||||||
|
if ($warehouses = static::searchByAccount($account, $limit)) {
|
||||||
|
// Найдены склады
|
||||||
|
|
||||||
|
return $warehouses;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [static::writeByAccount()];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Генерация списка терминалов из ДеловыеЛинии для отправителя
|
||||||
|
*
|
||||||
|
* Актуальное (выбранное, активное) значение записывается первым
|
||||||
|
*
|
||||||
|
* @param array Необработанный список терминалов
|
||||||
|
*/
|
||||||
|
public function genListTerminalsFrom(): array
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
$list = [];
|
||||||
|
|
||||||
|
$cities = Dellin::read(9999);
|
||||||
|
|
||||||
|
foreach ($cities as $city) {
|
||||||
|
// Перебор городов
|
||||||
|
|
||||||
|
foreach ($city->data['terminals']['terminal'] as $termial) {
|
||||||
|
// Перебор терминалов
|
||||||
|
|
||||||
|
if (in_array($termial['id'], $list, true)) {
|
||||||
|
// Если встретился дубликат (исполняется очень часто)
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запись
|
||||||
|
$list[$termial['id']] = $city->data['name'] . ' (' . $termial['address'] . ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->syncListWithSettings($list, 'trmn');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Синхронизация списка вариантов параметра с текущим значением из настроек
|
||||||
|
*
|
||||||
|
* @param array &$list Список
|
||||||
|
* @param string $var Название параметра
|
||||||
|
*
|
||||||
|
* @return array Сортированный список
|
||||||
|
*/
|
||||||
|
protected function syncListWithSettings(array &$list, string $var): array
|
||||||
|
{
|
||||||
|
// Инициализация текущего значения параметра в начале массива
|
||||||
|
if (isset($this->$var)) {
|
||||||
|
// Параметр найден в настройках аккаунта
|
||||||
|
|
||||||
|
if (isset($list[$this->$var])) {
|
||||||
|
// Найдено совпадение сохранённого параметра с полученным списком из поставок
|
||||||
|
|
||||||
|
// Буфер для сохранения параметра
|
||||||
|
$buffer = $list[$this->$var];
|
||||||
|
|
||||||
|
// Удаление параметра
|
||||||
|
unset($list[$this->$var]);
|
||||||
|
|
||||||
|
// Сохранение параметра в начале массива
|
||||||
|
$list = [$this->$var => $buffer] + $list;
|
||||||
|
} else {
|
||||||
|
// Совпадение не найдено
|
||||||
|
|
||||||
|
// Сохранение параметра из данных аккаунта в начале массива
|
||||||
|
$list = [$this->$var => $this->$var] + $list;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Параметр $var не найден в настройках аккаунта
|
||||||
|
|
||||||
|
// Сохранение параметра из данных аккаунта в начале массива
|
||||||
|
$list = ['Выберите' => 'Выберите'] + $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
use app\models\Account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Связь складов с инстанциями импортов
|
||||||
|
*/
|
||||||
|
class WarehouseEdgeImport extends Edge
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return 'warehouse_edge_import';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поиск по складу
|
||||||
|
*
|
||||||
|
* @param Warehouse $warehouse Склад
|
||||||
|
* @param int $limit Ограничение по максимальному количеству
|
||||||
|
*
|
||||||
|
* @return array Связи склада и инстанций поставок
|
||||||
|
*
|
||||||
|
* @deprecated Бесполезно
|
||||||
|
*/
|
||||||
|
public static function searchByWarehouse(Warehouse $warehouse, int $limit = 1): array
|
||||||
|
{
|
||||||
|
return static::find()->where(['_from' => $warehouse->readId()])->limit($limit)->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поиск по инстанции импорта
|
||||||
|
*
|
||||||
|
* @param Import $import Инстанция импорта
|
||||||
|
* @param int $limit Ограничение по максимальному количеству
|
||||||
|
*
|
||||||
|
* @return array Связи склада и инстанций поставок
|
||||||
|
*
|
||||||
|
* @deprecated Бесполезно
|
||||||
|
*/
|
||||||
|
public static function searchByImport(Import $import, int $limit = 1): array
|
||||||
|
{
|
||||||
|
return static::find()->where(['_to' => $import->readId()])->limit($limit)->all();
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,6 @@ if (
|
||||||
</nav>
|
</nav>
|
||||||
<article class="col-9">
|
<article class="col-9">
|
||||||
<div class="p-4 rounded">
|
<div class="p-4 rounded">
|
||||||
<h4 class="ml-4 mb-4"><i class="fas fa-sliders-h my-auto mr-2"></i>Настройки</h4>
|
|
||||||
<div id="profile_panel_settings" class="profile_panel">
|
<div id="profile_panel_settings" class="profile_panel">
|
||||||
<div class="profile_panel_menu mb-3">
|
<div class="profile_panel_menu mb-3">
|
||||||
<?php if (!yii::$app->user->isGuest) : ?>
|
<?php if (!yii::$app->user->isGuest) : ?>
|
||||||
|
|
|
@ -15,7 +15,6 @@ $panel ?? $panel = 'profile_panel_monitoring_input_search_history';
|
||||||
</nav>
|
</nav>
|
||||||
<article class="col-9">
|
<article class="col-9">
|
||||||
<div class="p-4 rounded">
|
<div class="p-4 rounded">
|
||||||
<h4 class="ml-3 mb-4"><i class="fas fa-eye my-auto mr-2"></i>Мониторинг</h4>
|
|
||||||
<div id="profile_panel_monitoring" class="profile_panel">
|
<div id="profile_panel_monitoring" class="profile_panel">
|
||||||
<div class="profile_panel_menu mb-3">
|
<div class="profile_panel_menu mb-3">
|
||||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_monitoring_input_orders_history">Заказы</label>
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_monitoring_input_orders_history">Заказы</label>
|
||||||
|
|
|
@ -34,7 +34,6 @@ $timezone = $timezone[1][0];
|
||||||
</nav>
|
</nav>
|
||||||
<article class="col-9">
|
<article class="col-9">
|
||||||
<div class="p-4 rounded">
|
<div class="p-4 rounded">
|
||||||
<h4 class="ml-4 mb-4"><i class="fas fa-user-shield my-auto mr-2"></i>Панель управления</h4>
|
|
||||||
<div id="profile_panel_panel" class="profile_panel">
|
<div id="profile_panel_panel" class="profile_panel">
|
||||||
<div class="profile_panel_menu mb-3">
|
<div class="profile_panel_menu mb-3">
|
||||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_input_notifications" onclick="return page_profile_panel_choose('profile_panel_input_notifications');">Уведомления</label>
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_input_notifications" onclick="return page_profile_panel_choose('profile_panel_input_notifications');">Уведомления</label>
|
||||||
|
|
|
@ -6,9 +6,9 @@ use yii;
|
||||||
use yii\bootstrap\ActiveForm;
|
use yii\bootstrap\ActiveForm;
|
||||||
|
|
||||||
use app\models\Account;
|
use app\models\Account;
|
||||||
use app\models\Document;
|
|
||||||
use app\models\Import;
|
use app\models\Import;
|
||||||
use app\models\Settings;
|
use app\models\Settings;
|
||||||
|
use app\models\Warehouse;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use DateTimeZone;
|
use DateTimeZone;
|
||||||
|
@ -27,11 +27,10 @@ $panel ?? $panel = 'profile_panel_supplies_input_import';
|
||||||
</nav>
|
</nav>
|
||||||
<article class="col-9">
|
<article class="col-9">
|
||||||
<div class="h-100 p-4 rounded">
|
<div class="h-100 p-4 rounded">
|
||||||
<h4 class="ml-4 mb-4"><i class="fas fa-truck my-auto mr-2"></i>Управление поставками</h4>
|
|
||||||
<div id="profile_panel_supplies" class="profile_panel">
|
<div id="profile_panel_supplies" class="profile_panel">
|
||||||
<div class="profile_panel_menu mb-3">
|
<div class="profile_panel_menu mb-3">
|
||||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_supplies_input_settings">Настройки</label>
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_supplies_input_settings">Настройки</label>
|
||||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_supplies_input_import">Импорт</label>
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_supplies_input_import">Склады</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="profile_panel_content">
|
<div class="profile_panel_content">
|
||||||
|
|
||||||
|
@ -42,10 +41,10 @@ $panel ?? $panel = 'profile_panel_supplies_input_import';
|
||||||
|
|
||||||
<input type="radio" id="profile_panel_supplies_input_import" name="main_panel" <?= $panel === 'profile_panel_supplies_input_import' ? 'checked' : null ?> />
|
<input type="radio" id="profile_panel_supplies_input_import" name="main_panel" <?= $panel === 'profile_panel_supplies_input_import' ? 'checked' : null ?> />
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h5>Импорт из Excel-документа</h5>
|
<h5>Управление складами</h5>
|
||||||
<div class="dropdown-divider mb-4"></div>
|
<div class="dropdown-divider mb-4"></div>
|
||||||
|
|
||||||
<?php if (Account::isMinimalAuthorized()) : ?>
|
<?php if (false && Account::isMinimalAuthorized()) : ?>
|
||||||
<?php
|
<?php
|
||||||
$form = ActiveForm::begin([
|
$form = ActiveForm::begin([
|
||||||
'id' => 'form_product_import_excel',
|
'id' => 'form_product_import_excel',
|
||||||
|
@ -62,7 +61,7 @@ $panel ?? $panel = 'profile_panel_supplies_input_import';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<?= $form->field($supply, 'account', ['options' => ['class' => "ml-auto mb-4 pr-0 col-4 d-flex"]])->input('text', ['placeholder' => yii::$app->user->identity->_key])->label(options: ['class' => 'mr-2 my-auto font-weight-bold']); ?>
|
<?= $form->field($supply, 'account', ['options' => ['class' => "ml-auto mb-4 pr-0 col-4 d-flex"]])->input('text', ['placeholder' => yii::$app->user->identity->_key])->label(options: ['class' => 'mr-2 my-auto font-weight-bold']); ?>
|
||||||
<?= $form->field($supply, 'file_excel', ['enableLabel' => false, 'options' => ['class' => 'mr-auto mb-4 pr-0 col-5 d-flex flex-column']])->fileInput(['class' => 'my-auto', 'multiple' => true, 'onChange' => 'page_profile_supplies_import_excel_moderator(this.parentElement.parentElement, \'profile_panel_supplies_input_import\', this.parentElement.parentElement.getElementsByTagName(\'input\')[0].value)']) ?>
|
<?= $form->field($supply, 'file_excel', ['enableLabel' => false, 'options' => ['class' => 'mr-auto mb-4 pr-0 col-5 d-flex flex-column']])->fileInput(['class' => 'my-auto', 'multiple' => true, 'onChange' => 'page_profile_supplies_import_excel(this.parentElement.parentElement, this.parentElement.parentElement.getElementsByTagName(\'input\')[0].value, \'profile_panel_supplies_input_import\')']) ?>
|
||||||
|
|
||||||
<?php ActiveForm::end(); ?>
|
<?php ActiveForm::end(); ?>
|
||||||
<?php
|
<?php
|
||||||
|
@ -123,9 +122,58 @@ $panel ?? $panel = 'profile_panel_supplies_input_import';
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
|
<?php
|
||||||
|
// Инициализация складов
|
||||||
|
$warehouses = Warehouse::initWithWrite();
|
||||||
|
|
||||||
|
// Инициализация итератора
|
||||||
|
$amount_warehouses = 0;
|
||||||
|
?>
|
||||||
|
<?php foreach ($warehouses as $warehouse) : ?>
|
||||||
|
<section class="col<?= ++$amount_warehouses <= count($warehouses) ? ' mb-4' : '' ?>">
|
||||||
|
<h5 class="d-flex"><?= $warehouse->name ?? 'Без названия' ?><small class="ml-auto mt-auto"><a class="text-dark fas fa-pen" type="button" onclick="edit_zaloopa"></a></small></h5>
|
||||||
|
|
||||||
|
<?php $form = ActiveForm::begin([
|
||||||
|
'id' => 'form_warehouse_settings',
|
||||||
|
'action' => false,
|
||||||
|
'fieldConfig' => [
|
||||||
|
'template' => '{label}{input}',
|
||||||
|
],
|
||||||
|
'options' => [
|
||||||
|
'onsubmit' => 'return false;'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$list = $warehouse->genListTerminalsFrom();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?= $form->field($warehouse, 'trmn', ['options' => ['class' => "mb-3"]])
|
||||||
|
->dropDownList($list, [
|
||||||
|
'onChange' => 'page_profile_settings(this.parentElement.parentElement, \'profile_panel_settings_company\')',
|
||||||
|
'disabled' => count($list) <= 1
|
||||||
|
])->label(false); ?>
|
||||||
|
|
||||||
|
<?php ActiveForm::end(); ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Инициализация номера инстанции импорта
|
||||||
|
$amount_imports = 0;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php foreach (Import::searchByWarehouse($warehouse) as $import) : ?>
|
||||||
|
<div class="mx-2 mb-3 row">
|
||||||
|
<div class="col-auto"><?= ++$amount_imports ?>.</div>
|
||||||
|
<div class="col">
|
||||||
|
<?= $import[0]->name ?? 'Без названия' ?>
|
||||||
|
</div>
|
||||||
|
<a class="pr-0 my-auto col-auto fas fa-file-download text-dark" type="button" aria-hidden="true" onclick="page_profile_supplies_download()"></a>
|
||||||
|
<a class="my-auto col-auto fas fa-trash-alt text-dark" type="button" aria-hidden="true" onclick="page_profile_supplies_delete()"></a>
|
||||||
|
</div>
|
||||||
|
<?php endforeach ?>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$form = ActiveForm::begin([
|
$form = ActiveForm::begin([
|
||||||
'id' => 'form_product_import_excel',
|
'id' => 'form_warehouse_supplies',
|
||||||
'action' => false,
|
'action' => false,
|
||||||
'fieldConfig' => [
|
'fieldConfig' => [
|
||||||
'template' => '{label}{input}',
|
'template' => '{label}{input}',
|
||||||
|
@ -137,70 +185,21 @@ $panel ?? $panel = 'profile_panel_supplies_input_import';
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
?>
|
?>
|
||||||
<?php if ($import_1 = Import::searchByPosition(1)) : ?>
|
|
||||||
<div class="mb-3 row">
|
|
||||||
<div class="col-auto">1.</div>
|
|
||||||
<div class="col">
|
|
||||||
<?= $import_1[0]->name ?? 'Без названия' ?>
|
|
||||||
</div>
|
|
||||||
<a class="pr-0 my-auto col-auto fas fa-file-download text-dark" type="button" aria-hidden="true" onclick="page_profile_supplies_download()"></a>
|
|
||||||
<a class="my-auto col-auto fas fa-trash-alt text-dark" type="button" aria-hidden="true" onclick="page_profile_supplies_delete()"></a>
|
|
||||||
</div>
|
|
||||||
<?php else : ?>
|
|
||||||
<div class="mb-3 row">
|
|
||||||
<div class="col-auto">1.</div>
|
|
||||||
<div class="col">
|
|
||||||
<?= $form->field($supply, 'file_excel_1', ['enableLabel' => false])->fileInput(['multiple' => true, 'onChange' => 'page_profile_supplies_import_excel(this.parentElement.parentElement.parentElement.parentElement, \'profile_panel_supplies_input_import\')']) ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php endif ?>
|
|
||||||
|
|
||||||
<div class="dropdown-divider mb-3"></div>
|
|
||||||
|
|
||||||
<?php if ($import_2 = Import::searchByPosition(2)) : ?>
|
|
||||||
<div class="mb-3 row">
|
<div class="mb-3 row">
|
||||||
<div class="col-auto">2.</div>
|
<?= $form->field($supply, 'file_excel', ['enableLabel' => false])->fileInput(['multiple' => true, 'onChange' => 'page_profile_supplies_import_excel(this.parentElement.parentElement.parentElement, ' . $warehouse->_key . ', undefined, \'profile_panel_supplies_input_import\')']) ?>
|
||||||
<div class="col">
|
|
||||||
<?= $import_2[0]->name ?? 'Без названия' ?>
|
|
||||||
</div>
|
</div>
|
||||||
<a class="pr-0 my-auto col-auto fas fa-file-download text-dark" type="button" aria-hidden="true" onclick="page_profile_supplies_download()"></a>
|
|
||||||
<a class="my-auto col-auto fas fa-trash-alt text-dark" type="button" aria-hidden="true" onclick="page_profile_supplies_delete()"></a>
|
|
||||||
</div>
|
|
||||||
<?php else : ?>
|
|
||||||
<div class="mb-3 row">
|
|
||||||
<div class="col-auto">2.</div>
|
|
||||||
<div class="col">
|
|
||||||
<?= $form->field($supply, 'file_excel_2', ['enableLabel' => false])->fileInput(['multiple' => true, 'onChange' => 'page_profile_supplies_import_excel(this.parentElement.parentElement.parentElement.parentElement, \'profile_panel_supplies_input_import\')']) ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php endif ?>
|
|
||||||
|
|
||||||
<div class="dropdown-divider mb-3"></div>
|
|
||||||
|
|
||||||
<?php if ($import_3 = Import::searchByPosition(3)) : ?>
|
|
||||||
<div class="mb-3 row">
|
|
||||||
<div class="col-auto">3.</div>
|
|
||||||
<div class="col">
|
|
||||||
<?= $import_3[0]->name ?? 'Без названия' ?>
|
|
||||||
</div>
|
|
||||||
<a class="pr-0 my-auto col-auto fas fa-file-download text-dark" type="button" aria-hidden="true" onclick="page_profile_supplies_download()"></a>
|
|
||||||
<a class="my-auto col-auto fas fa-trash-alt text-dark" type="button" aria-hidden="true" onclick="page_profile_supplies_delete()"></a>
|
|
||||||
</div>
|
|
||||||
<?php else : ?>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-auto">3.</div>
|
|
||||||
<div class="col">
|
|
||||||
<?= $form->field($supply, 'file_excel_3', ['enableLabel' => false])->fileInput(['multiple' => true, 'onChange' => 'page_profile_supplies_import_excel(this.parentElement.parentElement.parentElement.parentElement, \'profile_panel_supplies_input_import\')']) ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php endif ?>
|
|
||||||
|
|
||||||
<?= $form->errorSummary($supply, ['header' => 'В документе были допущены ошибки:' /*, 'footer' => 'Исправьте их и попробуйте снова'*/]); ?>
|
<?= $form->errorSummary($supply, ['header' => 'В документе были допущены ошибки:' /*, 'footer' => 'Исправьте их и попробуйте снова'*/]); ?>
|
||||||
|
|
||||||
<?php ActiveForm::end(); ?>
|
<?php ActiveForm::end(); ?>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php if ($amount_warehouses < count($warehouses)) : ?>
|
||||||
|
<div class="dropdown-divider mx-3 mb-4"></div>
|
||||||
|
<?php endif ?>
|
||||||
|
<?php endforeach ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
RewriteEngine on
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-d
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
|
||||||
RewriteRule . index.php [L]
|
|
|
@ -27,34 +27,40 @@ function page_profile_supplies(form, panel) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
function page_profile_supplies_import_excel(form, panel, account) {
|
function page_profile_supplies_import_excel(form, warehouse, account, panel) {
|
||||||
function send(help = false) {
|
function send(help = false) {
|
||||||
if (form === undefined) {
|
if (form === undefined) {
|
||||||
form = {
|
form = {
|
||||||
'_csrf': yii.getCsrfToken()
|
'_csrf': yii.getCsrfToken()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
form.help = +help;
|
||||||
|
|
||||||
if (panel !== undefined) {
|
if (panel !== undefined) {
|
||||||
form.panel = panel;
|
form.panel = panel;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (account !== undefined) {
|
if (warehouse !== undefined) {
|
||||||
form.number = prompt('Номер позиции в которую загружать каталог', 1);
|
form.warehouse = warehouse;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (account !== undefined) {
|
||||||
form.account = account;
|
form.account = account;
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
form = new FormData(form);
|
form = new FormData(form);
|
||||||
|
|
||||||
form.append('help', help);
|
form.append('help', +help);
|
||||||
|
|
||||||
if (panel !== undefined) {
|
if (panel !== undefined) {
|
||||||
form.append('panel', panel);
|
form.append('panel', panel);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (account !== undefined) {
|
if (warehouse !== undefined) {
|
||||||
form.append('number', prompt('Номер позиции в которую загружать каталог', 1));
|
form.append('warehouse', warehouse);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (account !== undefined) {
|
||||||
form.append('account', account);
|
form.append('account', account);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Reference in New Issue