Панели аккаунтов, товаров, поставок, прайсов
This commit is contained in:
parent
29ea6a9a79
commit
8f32df518f
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'id' => 'skillparts-console',
|
||||
'basePath' => dirname(__DIR__),
|
||||
'bootstrap' => ['log'],
|
||||
'controllerNamespace' => 'app\commands',
|
||||
'aliases' => [
|
||||
'@vendor' => dirname(__DIR__) . '/../../../vendor',
|
||||
'@bower' => '@vendor/bower-asset',
|
||||
'@npm' => '@vendor/npm-asset',
|
||||
'@tests' => '@app/tests',
|
||||
],
|
||||
'components' => [
|
||||
'cache' => [
|
||||
'class' => 'yii\caching\FileCache',
|
||||
],
|
||||
'log' => [
|
||||
'targets' => [
|
||||
[
|
||||
'class' => 'yii\log\FileTarget',
|
||||
'levels' => ['error', 'warning'],
|
||||
],
|
||||
],
|
||||
],
|
||||
'arangodb' => require __DIR__ . '/db.php'
|
||||
],
|
||||
'params' => require __DIR__ . '/params.php',
|
||||
'controllerMap' => [
|
||||
'arangodb-migrate' => 'mirzaev\yii2\arangodb\console\controllers\MigrateController',
|
||||
'fixture' => [
|
||||
'class' => 'yii\faker\FixtureController',
|
||||
],
|
||||
]
|
||||
];
|
|
@ -408,7 +408,7 @@ class ProfileController extends Controller
|
|||
public function actionSupplies(): string|array
|
||||
{
|
||||
// Инициализация
|
||||
$model = new Supply(yii::$app->request->post('Supply') ?? yii::$app->request->get('Supply'));
|
||||
$supply = new Supply(yii::$app->request->post('Supply') ?? yii::$app->request->get('Supply'));
|
||||
$panel = yii::$app->request->post('panel') ?? yii::$app->request->get('panel');
|
||||
$sidebar = $this->renderPartial('sidebar');
|
||||
$groups = self::readGroups();
|
||||
|
@ -421,7 +421,7 @@ class ProfileController extends Controller
|
|||
|
||||
return [
|
||||
'main' => $this->renderPartial('supplies', compact(
|
||||
'model',
|
||||
'supply',
|
||||
'groups',
|
||||
'sidebar',
|
||||
'panel'
|
||||
|
@ -432,7 +432,7 @@ class ProfileController extends Controller
|
|||
}
|
||||
|
||||
return $this->render('supplies', compact(
|
||||
'model',
|
||||
'supply',
|
||||
'groups',
|
||||
'sidebar',
|
||||
'panel'
|
||||
|
@ -447,8 +447,8 @@ class ProfileController extends Controller
|
|||
public function actionImport()
|
||||
{
|
||||
// Инициализация
|
||||
$model = new Supply(yii::$app->request->post('Supply') ?? yii::$app->request->get('Supply'));
|
||||
$model->scenario = $model::SCENARIO_IMPORT_EXCEL;
|
||||
$supply = new Supply(yii::$app->request->post('Supply') ?? yii::$app->request->get('Supply'));
|
||||
$supply->scenario = $supply::SCENARIO_IMPORT_EXCEL;
|
||||
$panel = yii::$app->request->post('panel') ?? yii::$app->request->get('panel');
|
||||
$sidebar = $this->renderPartial('sidebar');
|
||||
$groups = self::readGroups();
|
||||
|
@ -456,14 +456,18 @@ class ProfileController extends Controller
|
|||
if (yii::$app->request->isPost) {
|
||||
// AJAX-POST-запрос
|
||||
|
||||
// Настройка ответа
|
||||
yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
$model->file_excel = UploadedFile::getInstances($model, 'file_excel');
|
||||
// Инициализация файлов
|
||||
$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 ($model->importExcel()) {
|
||||
if ($supply->importExcel()) {
|
||||
return [
|
||||
'main' => $this->renderPartial('supplies', compact(
|
||||
'model',
|
||||
'supply',
|
||||
'groups',
|
||||
'sidebar',
|
||||
'panel'
|
||||
|
@ -476,7 +480,7 @@ class ProfileController extends Controller
|
|||
}
|
||||
|
||||
return $this->render('supplies', compact(
|
||||
'model',
|
||||
'supply',
|
||||
'groups',
|
||||
'sidebar',
|
||||
'panel'
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
use mirzaev\yii2\arangodb\Migration;
|
||||
|
||||
class m211123_114511_create_import_collection extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
/**
|
||||
* @param string Название коллекции
|
||||
* @param array Тип коллекции (2 - документ, 3 - ребро)
|
||||
*/
|
||||
$this->createCollection('import', ['type' => 2]);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->dropCollection('import');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
use mirzaev\yii2\arangodb\Migration;
|
||||
|
||||
class m211123_120136_create_import_edge_supply_collection extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
/**
|
||||
* @param string Название коллекции
|
||||
* @param array Тип коллекции (2 - документ, 3 - ребро)
|
||||
*/
|
||||
$this->createCollection('import_edge_supply', ['type' => 3]);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->dropCollection('import_edge_supply');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
use mirzaev\yii2\arangodb\Migration;
|
||||
|
||||
class m211123_173801_create_import_edge_account_collection extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
/**
|
||||
* @param string Название коллекции
|
||||
* @param array Тип коллекции (2 - документ, 3 - ребро)
|
||||
*/
|
||||
$this->createCollection('import_edge_account', ['type' => 3]);
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->dropCollection('import_edge_account');
|
||||
}
|
||||
}
|
|
@ -977,4 +977,18 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
{
|
||||
return self::isModer($account) || self::isAdmin($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Сгенерировать тип аккаунта на русском языке
|
||||
*/
|
||||
public function type(): string
|
||||
{
|
||||
return match ($this->type) {
|
||||
'administrator' => 'Администратор',
|
||||
'moderator' => 'Модератор',
|
||||
'user' => 'Пользователь',
|
||||
'requested' => 'Запрошен',
|
||||
default => 'Неизвестно'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,9 +166,9 @@ abstract class Document extends ActiveRecord
|
|||
/**
|
||||
* Чтение записей по максимальному ограничению
|
||||
*/
|
||||
public static function read(int $limit = 100): array
|
||||
public static function read(int $limit = 100, array|null $order = null): array
|
||||
{
|
||||
return static::find()->limit($limit)->all();
|
||||
return static::find()->limit($limit)->orderby($order)->all();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,7 +190,7 @@ abstract class Document extends ActiveRecord
|
|||
$this->addError($attribute, 'Передан не массив');
|
||||
}
|
||||
|
||||
$this->addError($attribute, 'Неизвестная ошибка');
|
||||
$this->addError($attribute, 'Не пройдена проверка: "arrayValidator"');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,6 +215,28 @@ abstract class Document extends ActiveRecord
|
|||
$this->addError($attribute, $e->getMessage());
|
||||
}
|
||||
|
||||
$this->addError($attribute, 'Неизвестная ошибка');
|
||||
$this->addError($attribute, 'Не пройдена проверка: "arrayWithNumbersValidator"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Конвертировать _id в _key
|
||||
*/
|
||||
private static function keyFromId(string $_id): string
|
||||
{
|
||||
$_key = preg_match_all('/\/([0-9]+)$/m', $_id, $mathes);
|
||||
|
||||
return $mathes[0][1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Статический вызов
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $args
|
||||
*/
|
||||
public static function __callStatic(string $name, array $args): mixed {
|
||||
return match ($name) {
|
||||
'keyFromId' => self::keyFromId(...$args)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use yii;
|
||||
|
||||
use app\models\traits\SearchByEdge;
|
||||
use app\models\Account;
|
||||
|
||||
/**
|
||||
* Импорт поставок
|
||||
*
|
||||
* Хранит себе связи с поставками которые были загружены вместе
|
||||
*/
|
||||
class Import extends Document
|
||||
{
|
||||
use SearchByEdge;
|
||||
|
||||
/**
|
||||
* Имя коллекции
|
||||
*/
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'import';
|
||||
}
|
||||
|
||||
/**
|
||||
* Свойства
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
[
|
||||
'pstn',
|
||||
'name',
|
||||
'file'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метки свойств
|
||||
*/
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'pstn' => 'Позиция',
|
||||
'name' => 'Название',
|
||||
'file' => 'Файл'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Правила
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::rules(),
|
||||
[
|
||||
[
|
||||
'pstn',
|
||||
'required'
|
||||
],
|
||||
[
|
||||
'pstn',
|
||||
'integer'
|
||||
],
|
||||
[
|
||||
[
|
||||
'file',
|
||||
'name'
|
||||
],
|
||||
'string'
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public static function searchByPosition(int $position = 1, Account $account = null, int $limit = 1): array
|
||||
{
|
||||
return self::searchByEdge(
|
||||
from: 'account',
|
||||
to: 'import',
|
||||
edge: 'import_edge_account',
|
||||
direction: 'INBOUND',
|
||||
subquery_where: 'account._key == "' . Account::initAccount($account)->_key . '" && import_edge_account.type == "loaded"',
|
||||
where: ['import.pstn' => $position],
|
||||
limit: $limit
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use app\models\Account;
|
||||
|
||||
/**
|
||||
* Связь инстанций импорта с поставками
|
||||
*/
|
||||
class ImportEdgeAccount extends Edge
|
||||
{
|
||||
/**
|
||||
* Имя коллекции
|
||||
*/
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'import_edge_account';
|
||||
}
|
||||
|
||||
/**
|
||||
* Свойства
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
[
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метки свойств
|
||||
*/
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Правила
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::rules(),
|
||||
[
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск по аккаунту
|
||||
*
|
||||
* @param Account $account Аккаунт
|
||||
* @param int $limit Ограничение по максимальному количеству
|
||||
*/
|
||||
public static function searchByAccount(Account $account, int $limit = 1): array
|
||||
{
|
||||
$account = Account::initAccount($account);
|
||||
|
||||
return static::find()->where(['_from' => $account->collectionName() . "$account->_key"])->limit($limit)->all();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
/**
|
||||
* Связь инстанций импорта с поставками
|
||||
*/
|
||||
class ImportEdgeSupply extends Edge
|
||||
{
|
||||
/**
|
||||
* Имя коллекции
|
||||
*/
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'import_edge_supply';
|
||||
}
|
||||
|
||||
/**
|
||||
* Свойства
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
[
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метки свойств
|
||||
*/
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Правила
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::rules(),
|
||||
[
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,19 +4,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace app\models;
|
||||
|
||||
use yii;
|
||||
use yii\web\UploadedFile;
|
||||
use yii\imagine\Image;
|
||||
use app\models\Settings;
|
||||
|
||||
use app\models\traits\SearchByEdge;
|
||||
use moonland\phpexcel\Excel;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Продукт (в ассортименте магазина)
|
||||
*
|
||||
|
@ -57,9 +50,17 @@ class Product extends Document
|
|||
/**
|
||||
* Файл .excel для импорта товаров
|
||||
*/
|
||||
public Excel|string|array|null $file_excel = null;
|
||||
public Excel|string|array|null $file_excel_1 = null;
|
||||
public Excel|string|array|null $file_excel_2 = null;
|
||||
public Excel|UploadedFile|string|null $file_excel_1 = null;
|
||||
|
||||
/**
|
||||
* Файл .excel для импорта товаров
|
||||
*/
|
||||
public Excel|UploadedFile|string|null $file_excel_2 = null;
|
||||
|
||||
/**
|
||||
* Файл .excel для импорта товаров
|
||||
*/
|
||||
public Excel|UploadedFile|string|null $file_excel_3 = null;
|
||||
|
||||
/**
|
||||
* Изображение для импорта
|
||||
|
@ -116,9 +117,9 @@ class Product extends Document
|
|||
'imgs' => 'Изображения (imgs)',
|
||||
'time' => 'Срок доставки (time)',
|
||||
'bffr' => 'Буфер',
|
||||
'file_excel' => 'Документ (file_excel)',
|
||||
'file_excel_1' => 'Документ (file_excel)',
|
||||
'file_excel_2' => 'Документ (file_excel)',
|
||||
'file_excel_1' => 'Документ (file_excel_1)',
|
||||
'file_excel_2' => 'Документ (file_excel_2)',
|
||||
'file_excel_3' => 'Документ (file_excel_3)',
|
||||
'file_image' => 'Изображение (file_image)',
|
||||
'group' => 'Группа (group)',
|
||||
'account' => 'Аккаунт'
|
||||
|
@ -178,18 +179,15 @@ class Product extends Document
|
|||
'message' => '{attribute} должен иметь значение от 0 до 30000'
|
||||
],
|
||||
[
|
||||
'file_excel',
|
||||
'required',
|
||||
'message' => 'Заполните поля: {attribute}',
|
||||
'on' => self::SCENARIO_IMPORT_EXCEL
|
||||
],
|
||||
[
|
||||
'file_excel',
|
||||
[
|
||||
'file_excel_1',
|
||||
'file_excel_2',
|
||||
'file_excel_3'
|
||||
],
|
||||
'file',
|
||||
'skipOnEmpty' => false,
|
||||
'skipOnEmpty' => true,
|
||||
'extensions' => 'xlsx',
|
||||
'checkExtensionByMimeType' => false,
|
||||
'maxFiles' => 5,
|
||||
'maxSize' => 1024 * 1024 * 30,
|
||||
'wrongExtension' => 'Разрешены только документы в формате: ".xlsx"',
|
||||
'message' => 'Проблема при чтении документа',
|
||||
|
@ -323,131 +321,6 @@ class Product extends Document
|
|||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Импорт товаров
|
||||
*
|
||||
* На данный момент обрабатывает только импорт из
|
||||
* файлов с расширением .excel
|
||||
*/
|
||||
public function importExcel(Account|int|null $account = null): bool
|
||||
{
|
||||
// Инициализация
|
||||
$data = [];
|
||||
$created = 0;
|
||||
$updated = 0;
|
||||
$account = Account::initAccount($account);
|
||||
|
||||
if ($this->validate()) {
|
||||
foreach ($this->file_excel as $file) {
|
||||
// Перебор файлов
|
||||
|
||||
// Инициализация
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
$path = YII_PATH_PUBLIC . "/../assets/accounts/$account->_key/files/" . (new DateTime('now', new DateTimeZone($timezone)))->getTimestamp();
|
||||
|
||||
// Сохранение на диск
|
||||
if (!file_exists($path))
|
||||
if (!mkdir($path, 0775, true))
|
||||
throw new Exception('Не удалось создать директорию', 500);
|
||||
|
||||
$file->saveAs($path = $path . "/$file->baseName.$file->extension");
|
||||
|
||||
$data[] = Excel::import($path, [
|
||||
'setFirstRecordAsKeys' => true,
|
||||
'setIndexSheetByName' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ($data as $data) {
|
||||
// Перебор конвертированных файлов
|
||||
|
||||
if (count($data) < 1) {
|
||||
// Не найдены строки с товарами
|
||||
|
||||
$this->addError('erros', 'Не удалось найти данные товаров');
|
||||
} else {
|
||||
// Перебор найденных товаров
|
||||
|
||||
foreach ($data as $doc) {
|
||||
// Перебор полученных документов
|
||||
|
||||
// Инициализация буфера
|
||||
$_doc = $doc;
|
||||
|
||||
// Поиск всех артикулов (каталожных номеров)
|
||||
$products = explode(',', $doc['catn'], 300);
|
||||
|
||||
// Поиск количества товаров
|
||||
$amount = $doc['amnt'] ?? 1;
|
||||
|
||||
foreach ($products as $_product) {
|
||||
// Перебор продуктов (если catn перечислены через запятую)
|
||||
|
||||
$_product = trim($_product);
|
||||
|
||||
// Запись артикула (каталожного номера) в буфер
|
||||
$_doc['catn'] = $_product;
|
||||
|
||||
// Инициализация продукта
|
||||
$product = new static($_doc);
|
||||
|
||||
$product->scenario = $product::SCENARIO_WRITE;
|
||||
|
||||
if ($product->validate()) {
|
||||
// Проверка пройдена
|
||||
|
||||
if (($_product = $product->validateForUniqueness()) instanceof static) {
|
||||
// Найден документ с такими параметрами
|
||||
|
||||
// Инициализация буфера с параметрами загружаемого товара
|
||||
$vars = $product->getAttributes();
|
||||
|
||||
// Удаление _key, чтобы не перезаписать его при замене параметров документа в буфере
|
||||
unset($vars['_key']);
|
||||
|
||||
// Перенос данных в буфер (существующий в базе данных дубликат)
|
||||
$_product->setAttributes($vars, false);
|
||||
|
||||
// Перезапись существующего документа
|
||||
$_product->update();
|
||||
|
||||
$updated++;
|
||||
} else {
|
||||
// Не найден документ с такими параметрами
|
||||
|
||||
// Запись нового документа
|
||||
if ($product->save()) $created++;
|
||||
}
|
||||
} else {
|
||||
// Проверка не пройдена
|
||||
|
||||
// Добавление ошибок
|
||||
foreach ($product->errors as $attribute => $error) $this->addError($attribute, $error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Деинициализация
|
||||
$this->file_excel = null;
|
||||
|
||||
// Макрос действий после импорта
|
||||
static::afterImportExcel($created, $updated);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Запись ошибки
|
||||
$this->addError('erros', 'Неизвестная ошибка');
|
||||
|
||||
// Макрос действий после импорта
|
||||
static::afterImportExcel($created, $updated);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск по каталожному номеру
|
||||
*
|
||||
|
@ -509,81 +382,6 @@ class Product extends Document
|
|||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Вызывается после загрузки поставок из excel-документа
|
||||
*
|
||||
* @param int $created Количество созданных документов
|
||||
* @param int $updated Количество обновлённых документов
|
||||
*/
|
||||
public static function afterImportExcel(int $created = 0, int $updated = 0): bool
|
||||
{
|
||||
// Инициализация параметров
|
||||
$model = new Notification;
|
||||
$account = yii::$app->user->identity;
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
// Инициализация даты
|
||||
$date = (new DateTime('now', new DateTimeZone($timezone)))->format('H:i d.m.Y');
|
||||
|
||||
// Настройка
|
||||
$model->text = yii::$app->controller->renderPartial('@app/views/notification/system/afterImportExcel', compact('created', 'updated', 'date'));
|
||||
$model->type = $model::TYPE_NOTICE;
|
||||
|
||||
// Отправка
|
||||
return (bool) $model->write();
|
||||
}
|
||||
|
||||
/**
|
||||
* Вызывается после загрузки поставок из 1С
|
||||
*/
|
||||
public static function afterImport1c(Account|int|null $account = null): bool
|
||||
{
|
||||
// Инициализация
|
||||
$model = new Notification;
|
||||
|
||||
if (is_null($account)) {
|
||||
// Данные аккаунта не переданы
|
||||
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Аккаунт не аутентифицирован
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Аккаунт аутентифицирован
|
||||
|
||||
// Инициализация
|
||||
$account = yii::$app->user->identity;
|
||||
}
|
||||
} else {
|
||||
if (is_int($account)) {
|
||||
// Передан идентификатор (_key) аккаунта (подразумевается)
|
||||
|
||||
// Инициализация (поиск в базе данных)
|
||||
if (!$account = Account::searchById(Account::collectionName() . "/$account")) {
|
||||
// Не удалось инициализировать аккаунт
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
$date = (new DateTime('now', new DateTimeZone($timezone)))->format('H:i d.m.Y');
|
||||
|
||||
// Настройка
|
||||
$model->text = yii::$app->controller->renderPartial('@app/views/notification/system/afterImport1c', compact('date'));
|
||||
$model->type = $model::TYPE_NOTICE;
|
||||
|
||||
// Отправка
|
||||
return (bool) $model->write();
|
||||
}
|
||||
|
||||
/**
|
||||
* Найти по идентификатору поставки
|
||||
*
|
||||
|
@ -863,4 +661,50 @@ class Product extends Document
|
|||
// Возврат (подразумевается ошибка)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализация продукта
|
||||
*
|
||||
* @param string $catn Артикул, каталожный номер
|
||||
*/
|
||||
public static function initEmpty(string $catn): Supply|array
|
||||
{
|
||||
$oemn = self::searchOemn($catn);
|
||||
|
||||
if (count($oemn) === 1) {
|
||||
// Передан только один артикул
|
||||
|
||||
if ($model = Product::searchByCatn($catn)) {
|
||||
// Продукт уже существует
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
// Запись пустого продукта
|
||||
return Product::writeEmpty($catn);
|
||||
}
|
||||
|
||||
// Инициализация
|
||||
$models = [];
|
||||
|
||||
foreach ($oemn as $catn) {
|
||||
// Перебор всех найденных артикулов
|
||||
|
||||
if ($model = Product::searchByCatn($catn)) {
|
||||
// Продукт уже существует
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Запись
|
||||
if ($model = Product::writeEmpty($catn)) {
|
||||
// Записано
|
||||
|
||||
// Запись в массив сохранённых моделей
|
||||
$models[] = $model;
|
||||
}
|
||||
}
|
||||
|
||||
return $models;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,17 +6,25 @@ namespace app\models;
|
|||
|
||||
use yii;
|
||||
|
||||
use app\models\traits\Xml2Array;
|
||||
use app\models\Account;
|
||||
use app\models\Product;
|
||||
use app\models\SupplyEdgeProduct;
|
||||
use app\models\traits\Xml2Array;
|
||||
use app\models\Settings;
|
||||
use app\models\Import;
|
||||
use app\models\ImportEdgeSupply;
|
||||
use app\models\ImportEdgeAccount;
|
||||
|
||||
use carono\exchange1c\interfaces\OfferInterface;
|
||||
use carono\exchange1c\interfaces\ProductInterface;
|
||||
use carono\exchange1c\controllers\ApiController;
|
||||
|
||||
use moonland\phpexcel\Excel;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Поставка (выгрузка товаров от поставщиков)
|
||||
|
@ -367,29 +375,236 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Запись продукта из 1С (поставка)
|
||||
* Запись поставок из excel
|
||||
*
|
||||
* @see Supply
|
||||
* На данный момент обрабатывает только импорт из
|
||||
* файлов с расширением .excel
|
||||
*/
|
||||
public function importExcel(Account|int|null $account = null): bool
|
||||
{
|
||||
// Инициализация
|
||||
$data = [];
|
||||
$created = 0;
|
||||
$updated = 0;
|
||||
$account = Account::initAccount($account);
|
||||
|
||||
if ($this->validate()) {
|
||||
// Пройдена проверка
|
||||
|
||||
if (isset($this->file_excel_1)) {
|
||||
// Найден файл в позиции 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', 'Файл для импорта не найден');
|
||||
}
|
||||
|
||||
// Инициализация
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$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/" . (new DateTime('now', new DateTimeZone($timezone)))->getTimestamp();
|
||||
|
||||
// Сохранение на диск
|
||||
if (!file_exists($path))
|
||||
if (!mkdir($path, 0775, true))
|
||||
throw new Exception('Не удалось создать директорию', 500);
|
||||
|
||||
$file->saveAs($path = "$path/" . $filename = $file->baseName . '.' . $file->extension);
|
||||
|
||||
$data[] = Excel::import($path, [
|
||||
'setFirstRecordAsKeys' => true,
|
||||
'setIndexSheetByName' => true,
|
||||
]);
|
||||
|
||||
// Инициализация буфера импортированных товаров
|
||||
$imported = [];
|
||||
|
||||
foreach ($data as $data) {
|
||||
// Перебор конвертированных файлов
|
||||
|
||||
if (count($data) < 1) {
|
||||
// Не найдены строки с товарами
|
||||
|
||||
$this->addError('erros', 'Не удалось найти данные товаров');
|
||||
} else {
|
||||
// Найдены строки с товарами
|
||||
|
||||
foreach ($data as $doc) {
|
||||
// Перебор полученных документов
|
||||
|
||||
// Инициализация буфера документов
|
||||
$_doc = $doc;
|
||||
|
||||
// Поиск всех артикулов (каталожных номеров)
|
||||
$supplies = explode(',', $doc['catn'], 300);
|
||||
|
||||
// Поиск количества товаров
|
||||
$amount = $doc['amnt'] ?? 1;
|
||||
|
||||
foreach ($supplies as $_supply) {
|
||||
// Перебор продуктов (если catn перечислены через запятую)
|
||||
|
||||
$_supply = trim($_supply);
|
||||
|
||||
// Запись артикула (каталожного номера) в буфер
|
||||
$_doc['catn'] = $_supply;
|
||||
|
||||
// Инициализация продукта
|
||||
$supply = new static($_doc);
|
||||
|
||||
$supply->scenario = $supply::SCENARIO_WRITE;
|
||||
|
||||
if ($supply->validate()) {
|
||||
// Проверка пройдена
|
||||
|
||||
if (($_supply = $supply->validateForUniqueness()) instanceof static) {
|
||||
// Найден документ с такими параметрами
|
||||
|
||||
// Инициализация буфера с параметрами загружаемого товара
|
||||
$vars = $supply->getAttributes();
|
||||
|
||||
// Удаление _key, чтобы не перезаписать его при замене параметров документа в буфере
|
||||
unset($vars['_key']);
|
||||
|
||||
// Перенос данных в буфер (существующий в базе данных дубликат)
|
||||
$_supply->setAttributes($vars, false);
|
||||
|
||||
// Перезапись существующего документа
|
||||
$_supply->update();
|
||||
|
||||
// Обновление счётчика
|
||||
$updated++;
|
||||
|
||||
// Запись поставки в буфер
|
||||
$imported[] = $_supply;
|
||||
} else {
|
||||
// Не найден документ с такими параметрами
|
||||
|
||||
if ($supply->save()) {
|
||||
// Поставка записана в базу данных
|
||||
|
||||
// Обновление счётчика
|
||||
$created++;
|
||||
|
||||
// Запись поставки в буфер
|
||||
$imported[] = $supply;
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// Проверка не пройдена
|
||||
|
||||
// Добавление ошибок
|
||||
foreach ($supply->errors as $attribute => $error) $this->addError($attribute, $error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($imported > 0) {
|
||||
// Успешно записана минимум 1 поставка
|
||||
|
||||
// Инициализация инстанции импорта
|
||||
$import = new Import;
|
||||
|
||||
$import->file = $path;
|
||||
$import->name = $filename;
|
||||
$import->pstn = $position;
|
||||
|
||||
if ($import->save()) {
|
||||
// Инстанция импорта успешно загружена
|
||||
|
||||
if (ImportEdgeAccount::write(yii::$app->user->identity->collectionName() . '/' . yii::$app->user->identity->_key, $import->collectionName() . "/$import->_key", data: ['type' => 'loaded'])) {
|
||||
// Записано ребро: АККАУНТ -> ИНСТАНЦИЯ ПОСТАВОК
|
||||
|
||||
// Запись в журнал инстанции импорта
|
||||
$import->journal('connect_with_account', [
|
||||
'target' => yii::$app->user->identity->collectionName() . '/' . yii::$app->user->identity->_key
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ($imported as $supply) {
|
||||
// Перебор импортированных поставок
|
||||
|
||||
if (ImportEdgeSupply::write($import->collectionName() . "/$import->_key", $supply->collectionName() . "/$supply->_key", data: ['type' => 'imported'])) {
|
||||
// Записано ребро: ИНСТАНЦИЯ ПОСТАВОК -> ПОСТАВКА
|
||||
|
||||
// Запись в журнал инстанции импорта
|
||||
$import->journal('connect_with_supply', [
|
||||
'target' => $supply->collectionName() . "/$supply->_key"
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Макрос действий после импорта
|
||||
static::afterImportExcel($created, $updated);
|
||||
|
||||
// Удаление (важно именно задать null для формы в представлении)
|
||||
$this->file_excel_1 = $this->file_excel_2 = $this->file_excel_3 = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Запись ошибки
|
||||
$this->addError('erros', 'Не пройдена проверка параметров');
|
||||
|
||||
// Макрос действий после импорта
|
||||
static::afterImportExcel($created, $updated);
|
||||
|
||||
// Удаление (важно именно задать null для формы в представлении)
|
||||
$this->file_excel_1 = $this->file_excel_2 = $this->file_excel_3 = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись поставок из 1С
|
||||
*
|
||||
* @todo Понять что может храниться внутри "$model->onec['ЗначенияСвойств']['ЗначенияСвойства']" и переписать
|
||||
* Разобраться и создать возможность загрузки от лица другого аккаунта
|
||||
*/
|
||||
public static function createModel1c($product): ?self
|
||||
public static function createModel1c($supply): ?self
|
||||
{
|
||||
// Инициализация
|
||||
$model = self::searchByOcid($id = (string) $product->Ид) ?? new self;
|
||||
$_supply = self::searchByOcid($id = (string) $supply->Ид) ?? new self;
|
||||
$account ?? $account = yii::$app->user->identity;
|
||||
|
||||
// Настройка
|
||||
$model->ocid = $id ?? null;
|
||||
$model->catn = (string) $product->Артикул;
|
||||
$model->dscr = (string) $product->Описание;
|
||||
$model->onec = self::xml2array($product->xml);
|
||||
$_supply->ocid = $id ?? null;
|
||||
$_supply->catn = (string) $supply->Артикул;
|
||||
$_supply->dscr = (string) $supply->Описание;
|
||||
$_supply->onec = self::xml2array($supply->xml);
|
||||
|
||||
if (isset($model->onec['ЗначенияСвойств'])) {
|
||||
if (isset($_supply->onec['ЗначенияСвойств'])) {
|
||||
// Свойства инициализированы
|
||||
|
||||
foreach ($model->onec['ЗначенияСвойств'] as $property) {
|
||||
foreach ($_supply->onec['ЗначенияСвойств'] as $property) {
|
||||
// Перебор всех свойств
|
||||
|
||||
if (is_array($property)) {
|
||||
|
@ -397,22 +612,37 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
|||
// Если идентификатор свойства совпадает с указанным в настройках свойства хранящего OEM номера
|
||||
|
||||
// Настройка
|
||||
$model->oemn = array_merge(self::searchOemn($property['Значение']), self::searchOemn((string) $product->Артикул));
|
||||
$_supply->oemn = array_merge(self::searchOemn($property['Значение']), self::searchOemn((string) $supply->Артикул));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Запись
|
||||
if ($model->save()) {
|
||||
if ($_supply->write()) {
|
||||
// Поставка успешно сохранена
|
||||
|
||||
return $model;
|
||||
return $supply;
|
||||
}
|
||||
|
||||
// Запись
|
||||
if ($_supply->save()) {
|
||||
// Поставка успешно сохранена
|
||||
|
||||
return $supply;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function write($context = null)
|
||||
{
|
||||
return $this->onec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $context
|
||||
* @return array
|
||||
|
@ -422,52 +652,6 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
|||
return $this->onec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализация продукта
|
||||
*
|
||||
* @param string $catn Артикул, каталожный номер
|
||||
*/
|
||||
public static function initEmpty(string $catn): Product|array
|
||||
{
|
||||
$oemn = self::searchOemn($catn);
|
||||
|
||||
if (count($oemn) === 1) {
|
||||
// Передан только один артикул
|
||||
|
||||
if ($model = Product::searchByCatn($catn)) {
|
||||
// Продукт уже существует
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
// Запись пустого продукта
|
||||
return Product::writeEmpty($catn);
|
||||
}
|
||||
|
||||
// Инициализация
|
||||
$models = [];
|
||||
|
||||
foreach ($oemn as $catn) {
|
||||
// Перебор всех найденных артикулов
|
||||
|
||||
if ($model = Product::searchByCatn($catn)) {
|
||||
// Продукт уже существует
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Запись
|
||||
if ($model = Product::writeEmpty($catn)) {
|
||||
// Записано
|
||||
|
||||
// Запись в массив сохранённых моделей
|
||||
$models[] = $model;
|
||||
}
|
||||
}
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск OEM номеров
|
||||
*
|
||||
|
@ -564,34 +748,34 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
|||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Прочитать стоимость
|
||||
*
|
||||
* @param Product|null $product Товар для поиска по вершинам
|
||||
*
|
||||
* @return array|null Данные о ценах
|
||||
*/
|
||||
public function readCost(Product $product = null): ?array
|
||||
{
|
||||
return static::readCostById($this->readId(), $product);
|
||||
}
|
||||
// /**
|
||||
// * Прочитать стоимость
|
||||
// *
|
||||
// * @param Product|null $product Товар для поиска по вершинам
|
||||
// *
|
||||
// * @return array|null Данные о ценах
|
||||
// */
|
||||
// public function readCost(Product $product = null): ?array
|
||||
// {
|
||||
// return static::readCostById($this->readId(), $product);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Прочитать стоимость по идентификатору поставки
|
||||
*
|
||||
* @param string $_id Идентификатор поставки
|
||||
* @param Product|null $product Товар для поиска по вершинам
|
||||
*
|
||||
* @return array|null Данные о ценах
|
||||
*/
|
||||
public static function readCostById(string $_id, Product $product = null): ?array
|
||||
{
|
||||
if (isset($product)) {
|
||||
return SupplyEdgeProduct::searchByVertex($_id, $product->readId(), type: 'connect', limit: 1)['onec']['Цены']['Цена'];
|
||||
}
|
||||
// /**
|
||||
// * Прочитать стоимость по идентификатору поставки
|
||||
// *
|
||||
// * @param string $_id Идентификатор поставки
|
||||
// * @param Product|null $product Товар для поиска по вершинам
|
||||
// *
|
||||
// * @return array|null Данные о ценах
|
||||
// */
|
||||
// public static function readCostById(string $_id, Product $product = null): ?array
|
||||
// {
|
||||
// if (isset($product)) {
|
||||
// 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']['Цены']['Цена'];
|
||||
// }
|
||||
|
||||
/**
|
||||
* Найти аккаунт владельца
|
||||
|
@ -617,4 +801,79 @@ class Supply extends Product implements ProductInterface, OfferInterface
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Вызывается после загрузки поставок из excel-документа
|
||||
*
|
||||
* @param int $created Количество созданных документов
|
||||
* @param int $updated Количество обновлённых документов
|
||||
*/
|
||||
public static function afterImportExcel(int $created = 0, int $updated = 0): bool
|
||||
{
|
||||
// Инициализация параметров
|
||||
$model = new Notification;
|
||||
$account = yii::$app->user->identity;
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
// Инициализация даты
|
||||
$date = (new DateTime('now', new DateTimeZone($timezone)))->format('H:i d.m.Y');
|
||||
|
||||
// Настройка
|
||||
$model->text = yii::$app->controller->renderPartial('@app/views/notification/system/afterImportExcel', compact('created', 'updated', 'date'));
|
||||
$model->type = $model::TYPE_NOTICE;
|
||||
|
||||
// Отправка
|
||||
return (bool) $model->write();
|
||||
}
|
||||
|
||||
/**
|
||||
* Вызывается после загрузки поставок из 1С
|
||||
*/
|
||||
public static function afterImport1c(Account|int|null $account = null): bool
|
||||
{
|
||||
// Инициализация
|
||||
$model = new Notification;
|
||||
|
||||
if (is_null($account)) {
|
||||
// Данные аккаунта не переданы
|
||||
|
||||
if (yii::$app->user->isGuest) {
|
||||
// Аккаунт не аутентифицирован
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Аккаунт аутентифицирован
|
||||
|
||||
// Инициализация
|
||||
$account = yii::$app->user->identity;
|
||||
}
|
||||
} else {
|
||||
if (is_int($account)) {
|
||||
// Передан идентификатор (_key) аккаунта (подразумевается)
|
||||
|
||||
// Инициализация (поиск в базе данных)
|
||||
if (!$account = Account::searchById(Account::collectionName() . "/$account")) {
|
||||
// Не удалось инициализировать аккаунт
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
|
||||
$date = (new DateTime('now', new DateTimeZone($timezone)))->format('H:i d.m.Y');
|
||||
|
||||
// Настройка
|
||||
$model->text = yii::$app->controller->renderPartial('@app/views/notification/system/afterImport1c', compact('date'));
|
||||
$model->type = $model::TYPE_NOTICE;
|
||||
|
||||
// Отправка
|
||||
return (bool) $model->write();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace app\models\traits;
|
||||
|
||||
use yii;
|
||||
|
||||
use ArangoDBClient\Document;
|
||||
|
||||
use Exception;
|
||||
|
||||
trait SearchByEdge
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -8,10 +8,20 @@ use yii\helpers\Html;
|
|||
|
||||
use app\models\Notification;
|
||||
use app\models\Account;
|
||||
use app\models\Product;
|
||||
use app\models\Settings;
|
||||
use app\models\Supply;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
|
||||
// Инициализация
|
||||
$panel ?? $panel = 'profile_panel_input_notifications';
|
||||
$panel ?? $panel = 'profile_panel_input_accounts';
|
||||
$panel_accounts ?? $panel_accounts = 'profile_panel_input_accounts_control';
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
?>
|
||||
|
||||
<link href="/css/pages/profile.css" rel="stylesheet">
|
||||
|
@ -26,9 +36,11 @@ $panel ?? $panel = 'profile_panel_input_notifications';
|
|||
<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 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_suppliers_choose('profile_panel_input_notifications');">Уведомления</label>
|
||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_input_suppliers" onclick="return page_profile_panel_input_suppliers_requests_init();">Поставщики</label>
|
||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_input_settings" onclick="return page_profile_panel_suppliers_choose('profile_panel_input_settings');">Настройки</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>
|
||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_input_accounts" onclick="return page_profile_panel_choose('profile_panel_input_accounts');">Аккаунты</label>
|
||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_input_products" onclick="return page_profile_panel_choose('profile_panel_input_products');">Товары</label>
|
||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_input_supplies" onclick="return page_profile_panel_choose('profile_panel_input_supplies');">Поставки</label>
|
||||
<label class="btn button_white mb-0 mr-2" for="profile_panel_input_settings" onclick="return page_profile_panel_choose('profile_panel_input_settings');">Настройки</label>
|
||||
</div>
|
||||
<div class="profile_panel_content">
|
||||
<input type="radio" id="profile_panel_input_notifications" name="main_panel" <?= $panel === 'profile_panel_input_notifications' ? 'checked' : null ?> />
|
||||
|
@ -76,14 +88,175 @@ $panel ?? $panel = 'profile_panel_input_notifications';
|
|||
<?php ActiveForm::end(); ?>
|
||||
</div>
|
||||
|
||||
|
||||
<input type="radio" id="profile_panel_input_suppliers" name="main_panel" <?= $panel === 'profile_panel_input_suppliers' ? 'checked' : null ?> />
|
||||
<input type="radio" id="profile_panel_input_accounts" name="main_panel" <?= $panel === 'profile_panel_input_accounts' ? 'checked' : null ?> />
|
||||
<div class="profile_panel_input_accounts_menu mb-4">
|
||||
<label class="mb-0 mr-2 px-2 py-1 btn button_white_small" for="profile_panel_input_accounts_control" onclick="return page_profile_panel_accounts_choose('profile_panel_input_accounts_control');">Пользователи</label>
|
||||
<label class="mb-0 mr-2 px-2 py-1 btn button_white_small" for="profile_panel_input_accounts_suppliers" onclick="return page_profile_panel_accounts_choose('profile_panel_input_accounts_suppliers');">Поставщики</label>
|
||||
</div>
|
||||
<input type="radio" id="profile_panel_input_accounts_control" name="main_panel_accounts" <?= $panel_accounts === 'profile_panel_input_accounts_control' ? 'checked' : null ?> />
|
||||
<div class="col">
|
||||
<h5>Заявки на регистрацию</h5>
|
||||
<div class="dropdown-divider mb-3"></div>
|
||||
<h5>Список пользователей</h5>
|
||||
<div class="dropdown-divider mb-4"></div>
|
||||
<div id="profile_panel_input_accounts_list" class="px-3">
|
||||
<?php
|
||||
// Инициализация счетчика аккаунтов
|
||||
$amount = 0;
|
||||
|
||||
// Чтение аккаунтов
|
||||
$accounts = Account::read(limit: 100, order: ['desc']);
|
||||
?>
|
||||
<?php foreach ($accounts ?? [] as $account) : ?>
|
||||
<?php
|
||||
foreach ($account->jrnl ?? [] as $jrnl) {
|
||||
// Перебор записей в журнале
|
||||
|
||||
if ($jrnl['action'] === 'create') {
|
||||
// Найдена дата создания
|
||||
|
||||
// Инициализация даты
|
||||
$create = (new DateTime())->setTimestamp($jrnl['date'])->setTimezone(new DateTimeZone($timezone))->format('d.m.Y') ?? 'Неизвестно';
|
||||
|
||||
// Выход из цикла
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<div class="pr-0 col-auto"><?= ++$amount ?>.</div>
|
||||
<div class="pr-0 col overflow-hidden" title="<?= $account->name ?? 'Неизвестно' ?>">
|
||||
<?= $account->name ?? 'Неизвестно' ?>
|
||||
</div>
|
||||
<div class="my-auto pr-0 col-auto">
|
||||
<?= $account->indx ?? '' ?>
|
||||
</div>
|
||||
<div class="my-auto pr-0 col-auto">
|
||||
<?= $account->agnt ? 'Поставщик' : 'Покупатель' ?>
|
||||
</div>
|
||||
<div class="mr-3 my-auto pr-0 col-2">
|
||||
<?= $account->type() ?>
|
||||
</div>
|
||||
<div class="my-auto pr-0 col-auto text-right">
|
||||
<?= $create ?? 'Неизвестно' ?>
|
||||
</div>
|
||||
<a class="my-auto col-auto fas fa-trash-alt text-dark" type="button" onclick="page_profile_supplies_delete()"></a>
|
||||
</div>
|
||||
|
||||
<? if ($amount < count($accounts)) : ?>
|
||||
<div class="dropdown-divider mb-3"></div>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="radio" id="profile_panel_input_accounts_suppliers" name="main_panel_accounts" <?= $panel_accounts === 'profile_panel_input_accounts_suppliers' ? 'checked' : null ?> />
|
||||
<div class="col">
|
||||
<h5>Заявки на регистрацию поставщиков</h5>
|
||||
<div class="dropdown-divider mb-4"></div>
|
||||
<div id="profile_panel_input_suppliers_requests"></div>
|
||||
</div>
|
||||
|
||||
<input type="radio" id="profile_panel_input_products" name="main_panel" <?= $panel === 'profile_panel_input_products' ? 'checked' : null ?> />
|
||||
<div class="col">
|
||||
<h5>Список товаров</h5>
|
||||
<div class="dropdown-divider mb-4"></div>
|
||||
<?php
|
||||
// Инициализация счетчика аккаунтов
|
||||
$amount = 0;
|
||||
|
||||
// Чтение аккаунтов
|
||||
$products = Product::read(limit: 100, order: ['desc']);
|
||||
?>
|
||||
<?php foreach ($products ?? [] as $product) : ?>
|
||||
<?php
|
||||
|
||||
foreach ($product->jrnl ?? [] as $jrnl) {
|
||||
// Перебор записей в журнале
|
||||
|
||||
if ($jrnl['action'] === 'create') {
|
||||
// Найдена дата создания
|
||||
|
||||
// Инициализация даты
|
||||
$create = (new DateTime())->setTimestamp($jrnl['date'])->setTimezone(new DateTimeZone($timezone))->format('H:i d.m.Y') ?? 'Неизвестно';
|
||||
|
||||
// Выход из цикла
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<div class="pr-0 col-auto"><?= ++$amount ?>.</div>
|
||||
<div class="pr-0 col overflow-hidden" title="<?= $product->name ?? 'Неизвестно' ?>">
|
||||
<?= $product->catn ?? 'Неизвестно' ?>
|
||||
</div>
|
||||
<div class="my-auto pr-0 col-auto text-right">
|
||||
<?= $create ?? 'Неизвестно' ?>
|
||||
</div>
|
||||
<a class="my-auto col-auto fas fa-trash-alt text-dark" type="button" onclick="page_profile_supplies_delete()"></a>
|
||||
</div>
|
||||
|
||||
<? if ($amount < count($products)) : ?>
|
||||
<div class="dropdown-divider mb-3"></div>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
|
||||
<input type="radio" id="profile_panel_input_supplies" name="main_panel" <?= $panel === 'profile_panel_input_supplies' ? 'checked' : null ?> />
|
||||
<div class="col">
|
||||
<h5>Список поставок</h5>
|
||||
<div class="dropdown-divider mb-4"></div>
|
||||
<?php
|
||||
// Инициализация счетчика аккаунтов
|
||||
$amount = 0;
|
||||
|
||||
// Чтение аккаунтов
|
||||
$supplies = Supply::read(limit: 100, order: ['desc']);
|
||||
?>
|
||||
<?php foreach ($supplies ?? [] as $supply) : ?>
|
||||
<?php
|
||||
foreach ($supply->jrnl ?? [] as $jrnl) {
|
||||
// Перебор записей в журнале
|
||||
|
||||
if ($jrnl['action'] === 'create') {
|
||||
// Найдена дата создания
|
||||
|
||||
// Инициализация даты
|
||||
$create = (new DateTime())->setTimestamp($jrnl['date'])->setTimezone(new DateTimeZone($timezone))->format('H:i d.m.Y') ?? 'Неизвестно';
|
||||
|
||||
// Выход из цикла
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<div class="pr-0 col-auto"><?= ++$amount ?>.</div>
|
||||
<div class="pr-0 col-2 overflow-hidden" title="<?= $supply->name ?? 'Неизвестно' ?>">
|
||||
<?= $supply->catn ?? 'Неизвестно' ?>
|
||||
</div>
|
||||
<div class="my-auto pr-0 col">
|
||||
<?= $supply->dscr ?? 'Без описания' ?>
|
||||
</div>
|
||||
<div class="my-auto pr-0 col-auto">
|
||||
<?= $supply->amnt ?? '0' ?> шт
|
||||
</div>
|
||||
<div class="my-auto pr-0 col-auto">
|
||||
<?= $supply->cost ?? '0' ?> р
|
||||
</div>
|
||||
<div class="my-auto pr-0 col-auto text-right">
|
||||
<?= $create ?? 'Неизвестно' ?>
|
||||
</div>
|
||||
<a class="my-auto col-auto fas fa-trash-alt text-dark" type="button" onclick="page_profile_supplies_delete()"></a>
|
||||
</div>
|
||||
|
||||
<? if ($amount < count($supplies)) : ?>
|
||||
<div class="dropdown-divider mb-3"></div>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
|
||||
<input type="radio" id="profile_panel_input_settings" name="main_panel" <?= $panel === 'profile_panel_input_settings' ? 'checked' : null ?> />
|
||||
<div class="col">
|
||||
<?php
|
||||
|
@ -162,6 +335,12 @@ $panel ?? $panel = 'profile_panel_input_notifications';
|
|||
<script src="/js/textarea.js" defer></script>
|
||||
<script defer>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Загружен документ
|
||||
|
||||
// Инициализация активной вкладки
|
||||
page_profile_panel_choose('<?= $panel ?? '' ?>');
|
||||
|
||||
// Инициализация панели для ввода текста (тест уведомлений для администратора)
|
||||
initTextarea(
|
||||
'#notification-text',
|
||||
'#notification-text-current',
|
||||
|
|
|
@ -34,7 +34,7 @@ use app\models\SupplyEdgeProduct;
|
|||
|
||||
echo <<<HTML
|
||||
<dt>
|
||||
<a class="row text-dark button_white button_white_hover px-3 py-3 py-lg-2 font-weight-normal" title="Панель управления сайтом" href="$targetUrl" role="button" onclick="return false;"><i class="fas fa-user-shield my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Панель управления</span></a>
|
||||
<a class="row text-dark button_white hover px-3 py-3 py-lg-2 font-weight-normal" title="Панель управления сайтом" href="$targetUrl" role="button" onclick="return false;"><i class="fas fa-user-shield my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Панель управления</span></a>
|
||||
</dt>
|
||||
HTML;
|
||||
} else {
|
||||
|
@ -56,7 +56,7 @@ use app\models\SupplyEdgeProduct;
|
|||
// Запрошена та же страница от которой послан запрос (текущая)
|
||||
|
||||
echo <<<HTML
|
||||
<a class="row text-dark button_white button_white_hover px-3 py-3 py-lg-2 font-weight-normal" title="Управление поставками" href="$targetUrl" role="button" onclick="return false;"><i class="fas fa-truck my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Поставки</span></a>
|
||||
<a class="row text-dark button_white hover px-3 py-3 py-lg-2 font-weight-normal" title="Управление поставками" href="$targetUrl" role="button" onclick="return false;"><i class="fas fa-truck my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Поставки</span></a>
|
||||
HTML;
|
||||
} else {
|
||||
echo <<<HTML
|
||||
|
@ -75,7 +75,7 @@ use app\models\SupplyEdgeProduct;
|
|||
// Запрошена та же страница от которой послан запрос (текущая)
|
||||
|
||||
echo <<<HTML
|
||||
<a class="row text-dark button_white button_white_hover px-3 py-3 py-lg-2 font-weight-normal" title="Мониторинг и журналирование" href="$targetUrl" role="button" onclick="return false;"><i class="fas fa-eye my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Мониторинг</span></a>
|
||||
<a class="row text-dark button_white hover px-3 py-3 py-lg-2 font-weight-normal" title="Мониторинг и журналирование" href="$targetUrl" role="button" onclick="return false;"><i class="fas fa-eye my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Мониторинг</span></a>
|
||||
HTML;
|
||||
} else {
|
||||
echo <<<HTML
|
||||
|
@ -93,7 +93,7 @@ use app\models\SupplyEdgeProduct;
|
|||
// Запрошена та же страница от которой послан запрос (текущая)
|
||||
|
||||
echo <<<HTML
|
||||
<a class="row text-dark button_white button_white_hover px-3 py-3 py-lg-2 font-weight-normal" title="Настройки аккаунта" href="$targetUrl" role="button" onclick="return false;"><i class="fas fa-sliders-h my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Настройки</span></a>
|
||||
<a class="row text-dark button_white hover px-3 py-3 py-lg-2 font-weight-normal" title="Настройки аккаунта" href="$targetUrl" role="button" onclick="return false;"><i class="fas fa-sliders-h my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Настройки</span></a>
|
||||
HTML;
|
||||
} else {
|
||||
echo <<<HTML
|
||||
|
|
|
@ -2,10 +2,17 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use app\models\Account;
|
||||
use yii;
|
||||
use yii\bootstrap\ActiveForm;
|
||||
|
||||
use app\models\Account;
|
||||
use app\models\Document;
|
||||
use app\models\Import;
|
||||
use app\models\Settings;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
|
||||
// Инициализация
|
||||
$panel ?? $panel = 'profile_panel_supplies_input_import';
|
||||
|
||||
|
@ -36,52 +43,161 @@ $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 ?> />
|
||||
<div class="col">
|
||||
<h5>Импорт из Excel-документа</h5>
|
||||
<div class="dropdown-divider mb-3"></div>
|
||||
<?php
|
||||
$form = ActiveForm::begin([
|
||||
'id' => 'form_product_import_excel',
|
||||
'action' => false,
|
||||
'fieldConfig' => [
|
||||
'template' => '{label}{input}',
|
||||
'options' => ['class' => '']
|
||||
],
|
||||
'options' => [
|
||||
'class' => 'mb-3',
|
||||
'onsubmit' => 'return false;'
|
||||
]
|
||||
]);
|
||||
?>
|
||||
<div class="dropdown-divider mb-4"></div>
|
||||
|
||||
<?php if (Account::isMinimalAuthorized()) : ?>
|
||||
<?= $form->field($model, 'account', ['options' => ['class' => "mb-4 col-4"]])->input('text', ['placeholder' => yii::$app->user->identity->_key]); ?>
|
||||
<?php
|
||||
$form = ActiveForm::begin([
|
||||
'id' => 'form_product_import_excel',
|
||||
'action' => false,
|
||||
'fieldConfig' => [
|
||||
'template' => '{label}{input}',
|
||||
'options' => ['class' => '']
|
||||
],
|
||||
'options' => [
|
||||
'class' => 'px-3 mb-3',
|
||||
'onsubmit' => 'return false;'
|
||||
]
|
||||
]);
|
||||
?>
|
||||
<?= $form->field($supply, 'account', ['options' => ['class' => "mb-4 col-4"]])->input('text', ['placeholder' => yii::$app->user->identity->_key]); ?>
|
||||
<?php ActiveForm::end(); ?>
|
||||
<?php
|
||||
// Инициализация счетчика инстанций импорта
|
||||
$amount = 0;
|
||||
|
||||
// Чтение истанций импорта
|
||||
$imports = Import::read(limit: 100, order: ['desc']);
|
||||
|
||||
// Инициализация часового пояса
|
||||
preg_match_all('/UTC([\+\-0-9:]*)/', $account->zone ?? Settings::searchActive()['timezone_default'] ?? 'UTC+3', $timezone);
|
||||
$timezone = $timezone[1][0];
|
||||
?>
|
||||
<?php foreach ($imports as $import) : ?>
|
||||
<?php
|
||||
foreach ($import->jrnl as $jrnl) {
|
||||
// Перебор записей в журнале
|
||||
|
||||
if ($jrnl['action'] === 'create') {
|
||||
// Найдена дата создания
|
||||
|
||||
// Инициализация даты
|
||||
$create = (new DateTime())->setTimestamp($jrnl['date'])->setTimezone(new DateTimeZone($timezone))->format('H:i d.m.Y') ?? 'Неизвестно';
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($import->jrnl as $jrnl) {
|
||||
// Перебор записей в журнале
|
||||
|
||||
if ($jrnl['action'] === 'connect_with_account') {
|
||||
// Найдена дата создания
|
||||
|
||||
// Инициализация даты
|
||||
$account = $jrnl['data']['target'];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<div class="col-auto"><?= ++$amount ?>.</div>
|
||||
<div class="col">
|
||||
<?= $import->name ?? 'Без названия' ?>
|
||||
</div>
|
||||
<div class="col-3 px-0 text-right">
|
||||
<?= $create ?? 'Неизвестно' ?>
|
||||
</div>
|
||||
<a class="pr-0 my-auto col-auto fas fa-user text-dark" href="<?= $date_connect_with_account ?? 'Неизвестно' ?>"></a>
|
||||
<a class="pr-0 my-auto col-auto fas fa-file-download text-dark" type="button" onclick="page_profile_supplies_download()"></a>
|
||||
<a class="my-auto col-auto fas fa-trash-alt text-dark" type="button" onclick="page_profile_supplies_delete()"></a>
|
||||
</div>
|
||||
|
||||
<? if ($amount < count($imports)) : ?>
|
||||
<div class="dropdown-divider mb-3"></div>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
<?php else : ?>
|
||||
<?php
|
||||
$form = ActiveForm::begin([
|
||||
'id' => 'form_product_import_excel',
|
||||
'action' => false,
|
||||
'fieldConfig' => [
|
||||
'template' => '{label}{input}',
|
||||
'options' => ['class' => '']
|
||||
],
|
||||
'options' => [
|
||||
'class' => 'px-3 mb-3',
|
||||
'onsubmit' => 'return false;'
|
||||
]
|
||||
]);
|
||||
?>
|
||||
<?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="col-auto">2.</div>
|
||||
<div class="col">
|
||||
<?= $import_2[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">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' => 'Исправьте их и попробуйте снова'*/]); ?>
|
||||
|
||||
<?php ActiveForm::end(); ?>
|
||||
|
||||
<?php endif ?>
|
||||
|
||||
<div class="mb-3 row">
|
||||
<div class="col-auto">1.</div>
|
||||
<div class="col">
|
||||
Тест импорта.xlsx
|
||||
</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>
|
||||
<div class="dropdown-divider mb-3"></div>
|
||||
<div class="mb-3 row">
|
||||
<div class="col-auto">2.</div>
|
||||
<div class="col">
|
||||
<?= $form->field($model, 'file_excel_1', ['enableLabel' => false])->fileInput(['multiple' => true, 'onChange' => 'page_profile_supplies_import_excel(this.parentElement.parentElement, \'profile_panel_supplies_input_import\')']) ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-divider mb-3"></div>
|
||||
<div class="row">
|
||||
<div class="col-auto">3.</div>
|
||||
<div class="col">
|
||||
<?= $form->field($model, 'file_excel_2', ['enableLabel' => false])->fileInput(['multiple' => true, 'onChange' => 'page_profile_supplies_import_excel(this.parentElement.parentElement, \'profile_panel_supplies_input_import\')']) ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= $form->errorSummary($model, ['header' => 'В документе были допущены ошибки:' /*, 'footer' => 'Исправьте их и попробуйте снова'*/]); ?>
|
||||
|
||||
<?php ActiveForm::end(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -171,25 +171,23 @@ main {
|
|||
transition: 0s;
|
||||
}
|
||||
|
||||
.button_white {
|
||||
.button_white,
|
||||
.button_white_small {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.button_white:hover {
|
||||
:is(.button_white, .button_white_small):is(.hover,:hover) {
|
||||
background-color: #eaebee;
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
.button_white:active,
|
||||
.button_white:focus {
|
||||
:is(.button_white, .button_white_small):is(.active, :active, :focus) {
|
||||
background-color: #cfd3dd;
|
||||
transition: 0s;
|
||||
}
|
||||
|
||||
.button_white_hover {
|
||||
/* Что я натворил? */
|
||||
background-color: #eaebee !important;
|
||||
transition: 0s;
|
||||
.button_white_small {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.button_grey {
|
||||
|
|
Binary file not shown.
|
@ -52,35 +52,78 @@ function page_profile_panel_write(form) {
|
|||
return false;
|
||||
};
|
||||
|
||||
function page_profile_panel_input_suppliers_requests_init() {
|
||||
// Инициализация скриптов при открытии вкладки "Поставщики"
|
||||
function page_profile_panel_choose(button = 'profile_panel_input_accounts') {
|
||||
// Деинициализация всех вкладок
|
||||
document.getElementById('profile_panel_input_supplies').checked =
|
||||
document.getElementById('profile_panel_input_products').checked =
|
||||
document.getElementById('profile_panel_input_accounts').checked =
|
||||
document.getElementById('profile_panel_input_settings').checked =
|
||||
document.getElementById('profile_panel_input_notifications').checked = false;
|
||||
|
||||
// Выбор панели
|
||||
page_profile_panel_suppliers_choose('profile_panel_input_suppliers');
|
||||
document.getElementById('profile_panel_input_supplies').setAttribute('onclick', 'return page_profile_panel_choose(\'profile_panel_input_supplies\');');
|
||||
document.getElementById('profile_panel_input_products').setAttribute('onclick', 'return page_profile_panel_choose(\'profile_panel_input_products\');');
|
||||
document.getElementById('profile_panel_input_notifications').setAttribute('onclick', 'return page_profile_panel_choose(\'profile_panel_input_notifications\');');
|
||||
document.getElementById('profile_panel_input_accounts').setAttribute('onclick', 'return page_profile_panel_choose(\'profile_panel_input_accounts\');');
|
||||
document.getElementById('profile_panel_input_settings').setAttribute('onclick', 'return page_profile_panel_choose(\'profile_panel_input_settings\');');
|
||||
|
||||
// Инициализация панели
|
||||
page_profile_panel_input_suppliers_requests_init();
|
||||
document.querySelector('[for="profile_panel_input_supplies"]').classList.remove('active');
|
||||
document.querySelector('[for="profile_panel_input_products"]').classList.remove('active');
|
||||
document.querySelector('[for="profile_panel_input_accounts"]').classList.remove('active');
|
||||
document.querySelector('[for="profile_panel_input_notifications"]').classList.remove('active');
|
||||
document.querySelector('[for="profile_panel_input_settings"]').classList.remove('active');
|
||||
|
||||
return false;
|
||||
};
|
||||
if (button === 'disable') {
|
||||
// Инициализация активной подвкладки вкладки "Аккаунты"
|
||||
page_profile_panel_accounts_choose('disable', true);
|
||||
|
||||
function page_profile_panel_suppliers_choose(button) {
|
||||
if (button === 'profile_panel_input_suppliers') {
|
||||
document.getElementById('profile_panel_input_notifications').addAttribute('onclick', 'return page_profile_panel_input_suppliers_notifications_init();');
|
||||
document.getElementById('profile_panel_input_settings').addAttribute('onclick', 'return page_profile_panel_input_suppliers_settings_init();');
|
||||
} else if (button === 'profile_panel_input_notifications') {
|
||||
document.getElementById('profile_panel_input_suppliers').addAttribute('onclick', 'return page_profile_panel_input_suppliers_requests_init();');
|
||||
document.getElementById('profile_panel_input_settings').addAttribute('onclick', 'return page_profile_panel_input_suppliers_settings_init();');
|
||||
} else if (button === 'profile_panel_input_settings') {
|
||||
document.getElementById('profile_panel_input_notifications').addAttribute('onclick', 'return page_profile_panel_input_suppliers_notifications_init();');
|
||||
document.getElementById('profile_panel_input_suppliers').addAttribute('onclick', 'return page_profile_panel_input_suppliers_requests_init();');
|
||||
return;
|
||||
} else if (button === 'profile_panel_input_accounts') {
|
||||
// Инициализация активной подвкладки вкладки "Аккаунты"
|
||||
page_profile_panel_accounts_choose(undefined, true);
|
||||
} else if (button !== 'profile_panel_input_accounts') {
|
||||
// Инициализация активной подвкладки вкладки "Аккаунты"
|
||||
page_profile_panel_accounts_choose('disable', true);
|
||||
}
|
||||
|
||||
// Инициализация запрошенной вкладки
|
||||
document.getElementById(button).checked = true;
|
||||
document.getElementById(button).removeAttribute('onclick');
|
||||
document.querySelector('[for="' + button + '"]').classList.add('active');
|
||||
}
|
||||
|
||||
function page_profile_panel_accounts_choose(button = 'profile_panel_input_accounts_control', active = false) {
|
||||
if (active === false) {
|
||||
// Вкладка не активна
|
||||
|
||||
// Открытие вкладки с этими подвкладками
|
||||
page_profile_panel_choose('profile_panel_input_accounts');
|
||||
}
|
||||
|
||||
// Деинициализация всех вкладок
|
||||
document.getElementById('profile_panel_input_accounts_suppliers').checked =
|
||||
document.getElementById('profile_panel_input_accounts_control').checked = false
|
||||
|
||||
document.getElementById('profile_panel_input_accounts_suppliers').setAttribute('onclick', 'return page_profile_panel_accounts_choose(\'profile_panel_input_accounts_suppliers\');');
|
||||
document.getElementById('profile_panel_input_accounts_control').setAttribute('onclick', 'return page_profile_panel_accounts_choose(\'profile_panel_input_accounts_control\');');
|
||||
|
||||
document.querySelector('[for="profile_panel_input_accounts_suppliers"]').classList.remove('active');
|
||||
document.querySelector('[for="profile_panel_input_accounts_control"]').classList.remove('active');
|
||||
|
||||
if (button === 'disable') {
|
||||
return;
|
||||
} else if (button === 'profile_panel_input_accounts_suppliers') {
|
||||
// Инициализация содержимого блока "Заявки на регистрацию поставщиков"
|
||||
page_profile_panel_input_suppliers_requests_init();
|
||||
}
|
||||
|
||||
// Инициализация запрошенной вкладки
|
||||
document.getElementById(button).checked = true;
|
||||
document.getElementById(button).removeAttribute('onclick');
|
||||
document.querySelector('[for="' + button + '"]').classList.add('active');
|
||||
}
|
||||
|
||||
function page_profile_panel_input_suppliers_requests_init(wrap = 'profile_panel_input_suppliers_requests') {
|
||||
// Инициализация блока "Заявки на регистрацию" (поставщиков)
|
||||
// Инициализация содержимого блока "Заявки на регистрацию поставщиков"
|
||||
|
||||
// Инициализация оболочки
|
||||
wrap = document.getElementById(wrap);
|
||||
|
@ -612,7 +655,7 @@ function profile_panel_input_suppliers_requests_block_regen(_key, target) {
|
|||
* @param {*} target
|
||||
* @returns
|
||||
*/
|
||||
function profile_panel_input_suppliers_requests_block_accept(_key) {
|
||||
function profile_panel_input_suppliers_requests_block_accept(_key) {
|
||||
$.ajax({
|
||||
url: `/${_key}/accept`,
|
||||
type: 'post',
|
||||
|
|
Reference in New Issue