Доработка поиска, поиск аттрибутов
This commit is contained in:
parent
5d18c95dc4
commit
25709ee380
|
@ -22,11 +22,9 @@ class MainController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Displays homepage.
|
||||
*
|
||||
* @return string
|
||||
* Главная страница
|
||||
*/
|
||||
public function actionIndex()
|
||||
public function actionIndex(): string|array
|
||||
{
|
||||
if (Yii::$app->request->isAjax) {
|
||||
// AJAX-POST-запрос
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\controllers;
|
||||
|
||||
|
@ -8,6 +9,7 @@ use yii\web\Controller;
|
|||
use yii\web\Response;
|
||||
use yii\web\Cookie;
|
||||
use yii\web\UploadedFile;
|
||||
|
||||
use app\models\Supply;
|
||||
use app\models\SupplyGroup;
|
||||
|
||||
|
@ -56,10 +58,16 @@ class ProfileController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
public function actionIndex()
|
||||
/**
|
||||
* Страница с настройками аккаунта
|
||||
*/
|
||||
public function actionIndex(): string|array
|
||||
{
|
||||
// Инициализация
|
||||
$model = new Supply(Yii::$app->request->post('Supply') ?? Yii::$app->request->get('Supply'));
|
||||
$model = Yii::$app->user->identity;
|
||||
|
||||
// Генерация
|
||||
$sidebar = $this->renderPartial('sidebar');
|
||||
|
||||
if (Yii::$app->request->isAjax) {
|
||||
// AJAX-POST-запрос
|
||||
|
@ -67,13 +75,39 @@ class ProfileController extends Controller
|
|||
Yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
return [
|
||||
'main' => $this->renderPartial('index'),
|
||||
'main' => $this->renderPartial('index', compact('model', 'sidebar')),
|
||||
'redirect' => '/profile',
|
||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('index', compact('model'));
|
||||
return $this->render('index', compact('model', 'sidebar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Страницка поставок
|
||||
*/
|
||||
public function actionSupplies(): string|array
|
||||
{
|
||||
// Инициализация
|
||||
$model = new Supply(Yii::$app->request->post('Supply') ?? Yii::$app->request->get('Supply'));
|
||||
|
||||
// Генерация
|
||||
$sidebar = $this->renderPartial('sidebar', compact('model'));
|
||||
|
||||
if (Yii::$app->request->isAjax) {
|
||||
// AJAX-POST-запрос
|
||||
|
||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
||||
|
||||
return [
|
||||
'main' => $this->renderPartial('supplies', compact('model', 'sidebar')),
|
||||
'redirect' => '/profile/supplies',
|
||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('supplies', compact('model', 'sidebar'));
|
||||
}
|
||||
|
||||
public function actionImport()
|
||||
|
@ -82,6 +116,9 @@ class ProfileController extends Controller
|
|||
$model = new Supply(Yii::$app->request->post('Supply') ?? Yii::$app->request->get('Supply'));
|
||||
$model->scenario = $model::SCENARIO_IMPORT;
|
||||
|
||||
// Генерация
|
||||
$sidebar = $this->renderPartial('sidebar', compact('model'));
|
||||
|
||||
if (Yii::$app->request->isAjax) {
|
||||
// AJAX-POST-запрос
|
||||
|
||||
|
@ -94,12 +131,12 @@ class ProfileController extends Controller
|
|||
}
|
||||
|
||||
return [
|
||||
'main' => $this->renderPartial('index', compact('model')),
|
||||
'main' => $this->renderPartial('supplies', compact('model', 'sidebar')),
|
||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
||||
];
|
||||
}
|
||||
|
||||
return $this->render('index', compact('model'));
|
||||
return $this->render('supplies', compact('model', 'sidebar'));
|
||||
}
|
||||
|
||||
public static function readGroups()
|
||||
|
|
|
@ -13,7 +13,7 @@ class SearchController extends Controller
|
|||
public function actionIndex(): array|string
|
||||
{
|
||||
// Инициализация
|
||||
$request = Yii::$app->request->post('request') ?? Yii::$app->request->get('q');
|
||||
$query = Yii::$app->request->post('request') ?? Yii::$app->request->get('q');
|
||||
|
||||
if (Yii::$app->request->post('type') === 'product' || Yii::$app->request->get('type') === 'product') {
|
||||
// Поиск по продуктам
|
||||
|
@ -51,8 +51,10 @@ class SearchController extends Controller
|
|||
// Здесь запись истории запросов (в базе данных)
|
||||
//
|
||||
|
||||
if ($response = Product::search($request)) {
|
||||
// Данные найдены
|
||||
$limit = Yii::$app->request->isAjax ? 10 : 30;
|
||||
|
||||
if ($response = Product::searchByCatn($query, $limit)) {
|
||||
// Данные найдены по поиску в полях Каталожного номера
|
||||
|
||||
// Запись ответа
|
||||
$return = [
|
||||
|
@ -66,9 +68,10 @@ class SearchController extends Controller
|
|||
// Запись ответа
|
||||
$return['main'] = $this->renderPartial('/search/index', compact('response'));
|
||||
$return['search_line_window_hide'] = 1;
|
||||
$return['redirect'] = '/search?type=product&q=' . $request;
|
||||
$return['redirect'] = '/search?type=product&q=' . $query;
|
||||
}
|
||||
} else {
|
||||
|
||||
// Данные не найдены
|
||||
|
||||
Yii::$app->response->statusCode = 404;
|
||||
|
|
|
@ -1,23 +1,39 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use Yii;
|
||||
use yii\web\IdentityInterface;
|
||||
|
||||
use carono\exchange1c\interfaces\PartnerInterface;
|
||||
|
||||
/**
|
||||
* Аккаунт
|
||||
*
|
||||
* Реализует аккаунты пользователей и поставщиков
|
||||
*/
|
||||
class Account extends Document implements IdentityInterface, PartnerInterface
|
||||
{
|
||||
public static function collectionName()
|
||||
public $opts;
|
||||
|
||||
/**
|
||||
* Имя коллекции
|
||||
*/
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'account';
|
||||
}
|
||||
|
||||
public function attributes()
|
||||
/**
|
||||
* Свойства
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
[
|
||||
'auth',
|
||||
'mail',
|
||||
'pswd',
|
||||
'name',
|
||||
|
@ -25,12 +41,38 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
'sity',
|
||||
'comp',
|
||||
'taxn',
|
||||
'auth'
|
||||
'onec',
|
||||
'opts'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
/**
|
||||
* Метки свойств
|
||||
*/
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'auth' => 'Аутентификационный хеш',
|
||||
'mail' => 'Почта',
|
||||
'pswd' => 'Пароль',
|
||||
'name' => 'Имя',
|
||||
'simc' => 'Номер',
|
||||
'sity' => 'Город',
|
||||
'comp' => 'Компания',
|
||||
'taxn' => 'ИНН',
|
||||
'onec' => 'Данные 1C',
|
||||
'opts' => 'Параметры'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Правила
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::rules(),
|
||||
|
@ -42,24 +84,13 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
);
|
||||
}
|
||||
|
||||
public function attributeLabels()
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'mail' => 'Почта',
|
||||
'pswd' => 'Пароль',
|
||||
'name' => 'Имя',
|
||||
'simc' => 'Номер',
|
||||
'sity' => 'Город',
|
||||
'comp' => 'Компания',
|
||||
'taxn' => 'ИНН',
|
||||
'auth' => 'Аутентификационный хеш'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function beforeSave($data)
|
||||
/**
|
||||
* Перед сохранением
|
||||
*
|
||||
* @todo Подождать обновление от ебаного Yii2 и добавить
|
||||
* проверку типов передаваемых параметров
|
||||
*/
|
||||
public function beforeSave($data): bool
|
||||
{
|
||||
if (parent::beforeSave($data)) {
|
||||
if ($this->isNewRecord) {
|
||||
|
@ -71,70 +102,143 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
public function getExportFields1c($context = null)
|
||||
/**
|
||||
* Чтение полей для экспорта из 1С
|
||||
*/
|
||||
public function getExportFields1c($context = null): array
|
||||
{
|
||||
return [
|
||||
'Ид' => 'id',
|
||||
'Наименование' => 'username',
|
||||
'ПолноеНаименование' => 'full_name',
|
||||
'Фамилия' => 'surname',
|
||||
'Имя' => 'name',
|
||||
];
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Чтение идентификатора
|
||||
*
|
||||
* @see IdentityInterface
|
||||
*/
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->_key;
|
||||
return self::collectionName() . '/' . $this->_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Чтение идентификатора
|
||||
*/
|
||||
public function readId(): string
|
||||
{
|
||||
return self::collectionName() . '/' . $this->getId();
|
||||
return $this->getId();
|
||||
}
|
||||
|
||||
public function getAuthKey()
|
||||
/**
|
||||
* Чтение аутентификационного ключа
|
||||
*/
|
||||
public function getAuthKey(): string
|
||||
{
|
||||
return $this->auth;
|
||||
}
|
||||
|
||||
public static function findIdentity($_key)
|
||||
/**
|
||||
* Идентификация
|
||||
*
|
||||
* @todo Подождать обновление от ебаного Yii2 и добавить
|
||||
* проверку типов передаваемых параметров
|
||||
*/
|
||||
public static function findIdentity($_id): self
|
||||
{
|
||||
return static::findByKey($_key);
|
||||
return static::findById($_id);
|
||||
}
|
||||
|
||||
public static function findIdentityByAccessToken($pass, $type = null)
|
||||
/**
|
||||
* Поиск по ключу
|
||||
*
|
||||
* @todo Подождать обновление от ебаного Yii2 и добавить
|
||||
* проверку типов передаваемых параметров
|
||||
*/
|
||||
public static function findIdentityByAccessToken($pass, $type = null): self
|
||||
{
|
||||
return static::findOne(['pass' => $pass]);
|
||||
}
|
||||
|
||||
public static function findByMail($mail)
|
||||
/**
|
||||
* Поиск по почте
|
||||
*
|
||||
* @todo Подождать обновление Yii2 и добавить
|
||||
* проверку типов передаваемых параметров
|
||||
*/
|
||||
public static function findByMail($mail): self
|
||||
{
|
||||
return static::findOne(['mail' => $mail]);
|
||||
}
|
||||
|
||||
public static function findByKey($_key)
|
||||
/**
|
||||
* Поиск по идентификатору
|
||||
*
|
||||
* @todo Подождать обновление Yii2 и добавить
|
||||
* проверку типов передаваемых параметров
|
||||
*/
|
||||
public static function findById($_id): self
|
||||
{
|
||||
return static::findOne(['_key' => $_key]);
|
||||
return static::searchById($_id);
|
||||
}
|
||||
|
||||
public static function validateMail($mail)
|
||||
/**
|
||||
* Проверка почты
|
||||
*/
|
||||
public static function validateMail(string $mail): bool
|
||||
{
|
||||
if (static::findByMail($mail)) {
|
||||
// Почта найдена в базе данных
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validatePassword($pswd)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка пароля
|
||||
*/
|
||||
public function validatePassword(string $pswd): bool
|
||||
{
|
||||
return Yii::$app->security->validatePassword($pswd, $this->pswd);
|
||||
}
|
||||
|
||||
public function validateAuthKey($auth)
|
||||
/**
|
||||
* Проверка аутентификационного ключа
|
||||
*
|
||||
* @todo Подождать обновление Yii2 и добавить
|
||||
* проверку типов передаваемых параметров
|
||||
*/
|
||||
public function validateAuthKey($auth): bool
|
||||
{
|
||||
return $this->getAuthKey() === $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Записать параметр
|
||||
*
|
||||
* @param string $name Название параметра
|
||||
* @param mixed $value Значение параметра
|
||||
*/
|
||||
public function writeOption(string $name, mixed $value = null): bool
|
||||
{
|
||||
// Запись
|
||||
$this->opts[$name] = $value;
|
||||
|
||||
// Отправка
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Удалить параметр
|
||||
*
|
||||
* @param string $name Название параметра
|
||||
*/
|
||||
public function deleteOption(string $name): bool
|
||||
{
|
||||
// Удаление
|
||||
unset($this->opts[$name]);
|
||||
|
||||
// Отправка
|
||||
return $this->save();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ class AccountForm extends Model
|
|||
|
||||
$account = $this->getAccount();
|
||||
|
||||
if (!$account || !$account->validateMail($this->mail)) {
|
||||
if (!$account || $account->validateMail($this->mail)) {
|
||||
// Проверка не пройдена
|
||||
|
||||
$this->addError($attribute, 'Почта уже привязана');
|
||||
|
|
|
@ -1,13 +1,31 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use Yii;
|
||||
|
||||
use mirzaev\yii2\arangodb\ActiveRecord;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Документ
|
||||
*/
|
||||
abstract class Document extends ActiveRecord
|
||||
{
|
||||
public function attributes()
|
||||
/**
|
||||
* Имя коллекции
|
||||
*/
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return throw new Exception('Не установлено название коллекции');
|
||||
}
|
||||
|
||||
/**
|
||||
* Свойства
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'_key',
|
||||
|
@ -16,7 +34,10 @@ abstract class Document extends ActiveRecord
|
|||
];
|
||||
}
|
||||
|
||||
public function attributeLabels()
|
||||
/**
|
||||
* Метки свойств
|
||||
*/
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'Дата',
|
||||
|
@ -24,25 +45,36 @@ abstract class Document extends ActiveRecord
|
|||
];
|
||||
}
|
||||
|
||||
public function rules()
|
||||
|
||||
/**
|
||||
* Правила
|
||||
*
|
||||
* @todo Добавить проверку существования аккаунта
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'writer',
|
||||
'string'
|
||||
// Надо добавить проверку существования аккаунта
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function beforeSave($data)
|
||||
/**
|
||||
* Перед сохранением
|
||||
*
|
||||
* @todo Подождать обновление от ебаного Yii2 и добавить
|
||||
* проверку типов передаваемых параметров
|
||||
*/
|
||||
public function beforeSave($data): bool
|
||||
{
|
||||
if (parent::beforeSave($data)) {
|
||||
if ($this->isNewRecord) {
|
||||
}
|
||||
|
||||
$this->date = time();
|
||||
$this->writer = $this->writer ?? Yii::$app->user->identity->readId();
|
||||
$this->writer = $this->writer ?? Yii::$app->user->id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -50,11 +82,25 @@ abstract class Document extends ActiveRecord
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Чтение идентификатора
|
||||
*/
|
||||
public function readId(): ?string
|
||||
{
|
||||
return isset($this->_key) ? static::collectionName() . '/' . $this->_key : null;
|
||||
return isset($this->_key) && static::collectionName() ? static::collectionName() . '/' . $this->_key : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск по идентификатору
|
||||
*/
|
||||
public static function searchById(string $_id): ?static
|
||||
{
|
||||
return static::findOne(['_id' => $_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Чтение количества записей
|
||||
*/
|
||||
public static function readAmount(): int
|
||||
{
|
||||
return static::find()->count();
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
/**
|
||||
* Ребро
|
||||
*/
|
||||
abstract class Edge extends Document
|
||||
{
|
||||
public function attributes()
|
||||
/**
|
||||
* Свойства
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
|
@ -16,7 +23,10 @@ abstract class Edge extends Document
|
|||
);
|
||||
}
|
||||
|
||||
public function attributeLabels()
|
||||
/**
|
||||
* Метки свойств
|
||||
*/
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
|
@ -28,7 +38,10 @@ abstract class Edge extends Document
|
|||
);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
/**
|
||||
* Правила
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::rules(),
|
||||
|
@ -49,10 +62,10 @@ abstract class Edge extends Document
|
|||
/**
|
||||
* Записать
|
||||
*/
|
||||
public function write(string $_from, string $_to, string $type = '', array $data = []): ?static
|
||||
public static function write(string $_from, string $_to, string $type = '', array $data = []): ?static
|
||||
{
|
||||
// Инициализация
|
||||
$edge = isset($this->_key) ? $this : new static;
|
||||
$edge = new static;
|
||||
|
||||
// Настройка
|
||||
$edge->_from = $_from;
|
||||
|
@ -77,7 +90,14 @@ abstract class Edge extends Document
|
|||
return $edge;
|
||||
}
|
||||
|
||||
public function beforeSave($data)
|
||||
|
||||
/**
|
||||
* Перед сохранением
|
||||
*
|
||||
* @todo Подождать обновление от ебаного Yii2 и добавить
|
||||
* проверку типов передаваемых параметров
|
||||
*/
|
||||
public function beforeSave($data): bool
|
||||
{
|
||||
if (parent::beforeSave($data)) {
|
||||
if ($this->isNewRecord) {
|
||||
|
|
|
@ -1,23 +1,52 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use moonland\phpexcel\Excel;
|
||||
|
||||
use mirzaev\yii2\arangodb\Query;
|
||||
|
||||
/**
|
||||
* Продукт (в ассортименте магазина)
|
||||
*
|
||||
* Представляет собой лот состоящий из предложений от поставщиков
|
||||
*
|
||||
* @see Supply Поставки для продуктов
|
||||
*/
|
||||
class Product extends Document
|
||||
{
|
||||
/**
|
||||
* Сценарий импорта из .excel докумекнт
|
||||
*/
|
||||
const SCENARIO_IMPORT = 'import';
|
||||
|
||||
/**
|
||||
* Сценарий записи товара
|
||||
*/
|
||||
const SCENARIO_WRITE = 'write';
|
||||
|
||||
public $file;
|
||||
public $group;
|
||||
/**
|
||||
* Файл .excel для импорта товаров
|
||||
*/
|
||||
public Excel|null $file = null;
|
||||
|
||||
/**
|
||||
* Группа в которой состоит товар
|
||||
*/
|
||||
public ProductGroup|null $group = null;
|
||||
|
||||
/**
|
||||
* Имя коллекции
|
||||
*/
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'product';
|
||||
}
|
||||
|
||||
/**
|
||||
* Свойства
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
|
@ -34,6 +63,30 @@ class Product extends Document
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метки свойств
|
||||
*/
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'name' => 'Название (name)',
|
||||
'ocid' => 'Идентификатор 1C (ocid)',
|
||||
'catn' => 'Каталожный номер (catn)',
|
||||
'oemn' => 'OEM номера (oemn)',
|
||||
// 'data' => 'Данные товара (data)',
|
||||
// 'cost' => 'Цены (cost)',
|
||||
// 'time' => 'Сроки доставки (time)',
|
||||
'file' => 'Документ',
|
||||
'group' => 'Группа'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Правила
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return array_merge(
|
||||
|
@ -70,25 +123,13 @@ class Product extends Document
|
|||
);
|
||||
}
|
||||
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'name' => 'Название (name)',
|
||||
'ocid' => 'Идентификатор 1C (ocid)',
|
||||
'catn' => 'Каталожный номер (catn)',
|
||||
'oemn' => 'OEM номера (oemn)',
|
||||
// 'data' => 'Данные товара (data)',
|
||||
// 'cost' => 'Цены (cost)',
|
||||
// 'time' => 'Сроки доставки (time)',
|
||||
'file' => 'Документ',
|
||||
'group' => 'Группа'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function import()
|
||||
/**
|
||||
* Импорт товаров
|
||||
*
|
||||
* На данный момент обрабатывает только импорт из
|
||||
* файлов с расширением .excel
|
||||
*/
|
||||
public function import(): bool
|
||||
{
|
||||
// Инициализация массива данных
|
||||
$data = [];
|
||||
|
@ -140,47 +181,15 @@ class Product extends Document
|
|||
return false;
|
||||
}
|
||||
|
||||
public static function search(string $text): array
|
||||
{
|
||||
return (new Query)->limit(10)->search('product_search', ['id' => '_key', 'catn' => 'catn'], ['catn' => $text], 1);
|
||||
}
|
||||
|
||||
private static function writeEdgeBetweenGroup(string $from, string $to): bool
|
||||
{
|
||||
// Инициализация
|
||||
$edge = new SupplyEdgeSupplyGroup();
|
||||
|
||||
// Настройка
|
||||
$edge->_from = $from;
|
||||
$edge->_to = $to;
|
||||
|
||||
// Запись
|
||||
return $edge->save();
|
||||
}
|
||||
|
||||
private static function writeEdgeBetweenRequisite(string $from, string $to): bool
|
||||
{
|
||||
// Инициализация
|
||||
$edge = new SupplyEdgeRequisite();
|
||||
|
||||
// Настройка
|
||||
$edge->_from = $from;
|
||||
$edge->_to = $to;
|
||||
|
||||
// Запись
|
||||
return $edge->save();
|
||||
}
|
||||
|
||||
public static function readById(string $_key): ?Product
|
||||
{
|
||||
return self::findOne(['_key' => $_key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск по каталожному номеру
|
||||
*/
|
||||
public static function readByCatn(string $catn): ?Product
|
||||
public static function searchByCatn(string $query, int $limit = 1): Product|array|null
|
||||
{
|
||||
return self::findOne(['catn' => $catn]);
|
||||
if ($limit <= 1) {
|
||||
return static::findOne(['catn' => $query]);
|
||||
}
|
||||
|
||||
return self::find()->limit($limit)->view('product_search', ['id' => '_key', 'catn' => 'catn'], ['catn' => $query], 'START');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,56 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use carono\exchange1c\interfaces\GroupInterface;
|
||||
|
||||
use Zenwalker\CommerceML\Model\Group;
|
||||
|
||||
/**
|
||||
* Группировка продуктов
|
||||
*/
|
||||
class ProductGroup extends Document implements GroupInterface
|
||||
{
|
||||
public static function collectionName()
|
||||
/**
|
||||
* Имя коллекции
|
||||
*/
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'product_group';
|
||||
}
|
||||
|
||||
public function attributes()
|
||||
/**
|
||||
* Свойства
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
['name', 'onec_id', 'onec_prnt_id']
|
||||
[
|
||||
'name'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
/**
|
||||
* Метки свойств
|
||||
*/
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'name' => 'Название (name)'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Правила
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::rules(),
|
||||
|
@ -34,34 +64,18 @@ class ProductGroup extends Document implements GroupInterface
|
|||
);
|
||||
}
|
||||
|
||||
public function attributeLabels()
|
||||
/**
|
||||
* Запись члена группы
|
||||
*/
|
||||
public function writeMember(Product $member): ProductEdgeProductGroup
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'name' => 'Название (name)',
|
||||
'onec_id' => 'Название 1C (onec_id)',
|
||||
'onec_prnt_id' => 'Название родителя 1C (onec_prnt_id)',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function writeMember(Document $member, string $group)
|
||||
{
|
||||
if (isset($member->_key)) {
|
||||
return static::writeEdgeBetweenMember($member->collectionName() . '/' . $member->_key, $this->collectionName() . '/' . $group);
|
||||
}
|
||||
|
||||
return false;
|
||||
return ProductEdgeProductGroup::write($member->readId(), $this->readId(), 'member');
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание дерева групп
|
||||
* в параметр передаётся массив всех групп (import.xml > Классификатор > Группы)
|
||||
* $groups[0]->parent - родительская группа
|
||||
* $groups[0]->children - дочерние группы
|
||||
* Запись рёбер групп
|
||||
*
|
||||
* @param Group[] $groups
|
||||
* Создание взаимоотношений между группами по типу древовидной системы
|
||||
*/
|
||||
public static function createTree1c($groups): Document|null
|
||||
{
|
||||
|
@ -88,10 +102,11 @@ class ProductGroup extends Document implements GroupInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Создаём группу по модели группы CommerceML
|
||||
* проверяем все дерево родителей группы, если родителя нет в базе - создаём
|
||||
* Запись группы
|
||||
*
|
||||
* @param Group $group
|
||||
* Создаём группу по модели группы CommerceML
|
||||
* проверяем все дерево родителей группы,
|
||||
* если родителя нет в базе - создаём
|
||||
*/
|
||||
public static function createByML(Group $group): static|array|null
|
||||
{
|
||||
|
@ -124,19 +139,6 @@ class ProductGroup extends Document implements GroupInterface
|
|||
return $model;
|
||||
}
|
||||
|
||||
private static function writeEdgeBetweenMember(string $from, string $to): bool
|
||||
{
|
||||
// Инициализация
|
||||
$edge = new ProductEdgeProductGroup();
|
||||
|
||||
// Настройка
|
||||
$edge->_from = $from;
|
||||
$edge->_to = $to;
|
||||
|
||||
// Запись
|
||||
return $edge->save();
|
||||
}
|
||||
|
||||
private static function writeEdgeBetweenGroup(string $from, string $to): bool
|
||||
{
|
||||
// Инициализация
|
||||
|
|
|
@ -1,24 +1,46 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use Yii;
|
||||
|
||||
use app\models\Account;
|
||||
use app\models\Product;
|
||||
use app\models\SupplyEdgeProduct;
|
||||
use app\models\traits\Xml2Array;
|
||||
|
||||
use carono\exchange1c\interfaces\ProductInterface;
|
||||
|
||||
// class Supply extends Product implements OfferInterface
|
||||
use mirzaev\yii2\arangodb\Query;
|
||||
|
||||
/**
|
||||
* Поставка (выгрузка товаров от поставщиков)
|
||||
*
|
||||
* Представляет собой предложения от поставщиков которые добавляются
|
||||
* в универсальные лоты товаров в асспортименте магазина
|
||||
*
|
||||
* @see Product Продукт (туда добавляются поставки)
|
||||
*/
|
||||
class Supply extends Product implements ProductInterface
|
||||
{
|
||||
/**
|
||||
* Метод для конвертации XML в Array
|
||||
*/
|
||||
use Xml2Array;
|
||||
|
||||
/**
|
||||
* Имя коллекции
|
||||
*/
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'supply';
|
||||
}
|
||||
|
||||
/**
|
||||
* Свойства
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
|
@ -29,29 +51,38 @@ class Supply extends Product implements ProductInterface
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метки свойств
|
||||
*/
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'onec' => 'Данные 1C'
|
||||
'onec' => 'Данные 1С'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* После сохранения
|
||||
*/
|
||||
public function afterSave($data, $vars): void
|
||||
{
|
||||
// Запись ребра: АККАУНТ -> ПОСТАВКА
|
||||
(new AccountEdgeSupply)->write(Yii::$app->user->identity->readId(), $this->readId(), 'import');
|
||||
(new AccountEdgeSupply)->write(Yii::$app->user->id, $this->readId(), 'import');
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись реквизитов из 1С
|
||||
*/
|
||||
public function setRequisite1c($name, $value): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка группы, где находится продукт
|
||||
* Запись группы из 1С
|
||||
*/
|
||||
public function setGroup1c($group): mixed
|
||||
{
|
||||
|
@ -64,23 +95,66 @@ class Supply extends Product implements ProductInterface
|
|||
return true;
|
||||
}
|
||||
|
||||
public static function createProperties1c($properties): mixed
|
||||
/**
|
||||
* Запись данных свойств по UUID 1C
|
||||
*
|
||||
* Ищет записанные свойства из 1C по их идентификатору и добавляет к ним
|
||||
* недостающие данные. Это костыль оставшийся от реляционных баз данных
|
||||
*/
|
||||
public static function createProperties1c($properties): void
|
||||
{
|
||||
return true;
|
||||
// Инициализация
|
||||
$models = static::searchOnecByAccountId(Yii::$app->user->id, true);
|
||||
$properties = self::xml2array($properties->xml);
|
||||
|
||||
foreach ($models as $model) {
|
||||
// Перебор записей
|
||||
|
||||
// Инициализация
|
||||
$changes = false;
|
||||
|
||||
foreach ($model->onec['ЗначенияСвойств'] as &$attribute) {
|
||||
// Перебор аттрибутов
|
||||
|
||||
foreach ($properties as $property) {
|
||||
// Перебор свойств
|
||||
|
||||
if ($attribute['ЗначенияСвойства']['Ид'] === $property['Свойство']['Ид']) {
|
||||
// Совпадение идентификаторов
|
||||
|
||||
// Объединение данных
|
||||
array_merge($attribute, $property);
|
||||
|
||||
// Запись индикатора наличия изменений
|
||||
$changes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($changes) {
|
||||
$model->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись параметров из 1С
|
||||
*/
|
||||
public function setProperty1c($property): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись изображений из 1С
|
||||
*/
|
||||
public function addImage1c($path, $caption): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись ребра (предложения от поставки к продукту)
|
||||
* Запись ребра (предложения от поставок к продуктам) из 1С
|
||||
*/
|
||||
public function getOffer1c($offer): SupplyEdgeProduct
|
||||
{
|
||||
|
@ -89,7 +163,7 @@ class Supply extends Product implements ProductInterface
|
|||
|
||||
// Разработчику библеотеки надо дать по жопе
|
||||
return new SupplyEdgeProduct;
|
||||
} else if (!$catn = Product::readByCatn($this->catn)) {
|
||||
} else if (!$product = Product::searchByCatn($this->catn)) {
|
||||
// Продукт не найден
|
||||
|
||||
if (!$this->initProduct()) {
|
||||
|
@ -100,12 +174,12 @@ class Supply extends Product implements ProductInterface
|
|||
}
|
||||
}
|
||||
|
||||
$catn = Product::readByCatn($this->catn);
|
||||
$product = Product::searchByCatn($this->catn);
|
||||
|
||||
// Запись ребра: ПОСТАВКА -> ПРОДУКТ
|
||||
return (new SupplyEdgeProduct)->write(
|
||||
$this->readId(),
|
||||
$catn->readId(),
|
||||
$product->readId(),
|
||||
'sell',
|
||||
[
|
||||
'onec' => self::xml2array($offer->xml)
|
||||
|
@ -114,26 +188,27 @@ class Supply extends Product implements ProductInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Создать продукт
|
||||
* Запись продукта из 1С
|
||||
*/
|
||||
public static function createModel1c($product): self
|
||||
public static function createModel1c($product): ?self
|
||||
{
|
||||
// Инициализация
|
||||
$model = self::readByOnecId($id = (string) $product->Ид) ?? new self;
|
||||
$model = self::searchByOnecId($id = (string) $product->Ид) ?? new self;
|
||||
|
||||
// Настройки
|
||||
// Настройка
|
||||
$model->ocid = $id ?? null;
|
||||
$model->catn = (string) $product->Артикул;
|
||||
$model->oemn = null;
|
||||
$model->onec = self::xml2array($product->xml);
|
||||
|
||||
// Запись
|
||||
$model->save();
|
||||
|
||||
return $model;
|
||||
return $model->save() ? $model : null;
|
||||
}
|
||||
|
||||
protected function initProduct(): bool
|
||||
/**
|
||||
* Инициализация продукта
|
||||
*/
|
||||
protected function initProduct(): ?Product
|
||||
{
|
||||
// Надо не забыть сделать выборку полей и ручное подключение
|
||||
|
||||
|
@ -141,7 +216,7 @@ class Supply extends Product implements ProductInterface
|
|||
// Не передан каталожный номер
|
||||
|
||||
return false;
|
||||
} else if (Product::readByCatn($this->catn)) {
|
||||
} else if (Product::searchByCatn($this->catn)) {
|
||||
// Продукт уже был инициализирован
|
||||
|
||||
return true;
|
||||
|
@ -154,34 +229,79 @@ class Supply extends Product implements ProductInterface
|
|||
$product->catn = $this->catn;
|
||||
|
||||
// Запись
|
||||
return $product->save();
|
||||
return $product->save() ? $product : null;
|
||||
}
|
||||
|
||||
|
||||
public function setPrice1c($price): void
|
||||
/**
|
||||
* Запись цены из 1С
|
||||
*/
|
||||
public function setPrice1c($price): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись данных на случай ошибки при экспорте из 1С
|
||||
*/
|
||||
public function setRaw1cData($cml, $object): bool
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function readByOnecId(string $ocid): ?Supply
|
||||
/**
|
||||
* Поиск по идентификатору из 1С
|
||||
*
|
||||
* @param string $ocid Идентификатор из 1С
|
||||
*
|
||||
* @return Supply|null
|
||||
*/
|
||||
public static function searchByOnecId(string $ocid): ?Supply
|
||||
{
|
||||
return self::findOne([self::getIdFieldName1c() => $ocid]);
|
||||
return static::findOne([static::getIdFieldName1c() => $ocid]);
|
||||
}
|
||||
|
||||
public function getGroup1c(): SupplyGroup
|
||||
/**
|
||||
* Чтение группы из 1С
|
||||
*/
|
||||
public function getGroup1c(): ?SupplyGroup
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Название поля в котором хранится ID из 1C
|
||||
* Чтение названия поля в котором хранится идентификатор из 1С
|
||||
*/
|
||||
public static function getIdFieldName1c(): string
|
||||
{
|
||||
return 'ocid';
|
||||
}
|
||||
|
||||
public static function searchOnecByAccountId(string $id, bool $full = false): array
|
||||
{
|
||||
$subquery = static::find()
|
||||
->for(['account', 'account_edge_supply'])
|
||||
->traversal('supply')->in('account_edge_supply')
|
||||
->where(['account._id' => $id])
|
||||
->select('account_edge_supply')
|
||||
->createCommand();
|
||||
|
||||
$query = static::find()
|
||||
->addParams($subquery->getBindVars())
|
||||
->let('account_edge_supply', '(' . (string) $subquery . ')')
|
||||
->where('supply._id == account_edge_supply[0]._to')
|
||||
->andWhere('supply.onec["ЗначенияСвойств"] != null');
|
||||
|
||||
if ($full) {
|
||||
// Если указан полный поиск
|
||||
return $query->select('supply')->all();
|
||||
}
|
||||
|
||||
$query = $query->select('supply.onec["ЗначенияСвойств"]')->createCommand()->execute()->getAll();
|
||||
|
||||
foreach ($query as &$attribute) {
|
||||
$attribute = $attribute->getAll();
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,18 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\models;
|
||||
|
||||
/**
|
||||
* Группировка поставок
|
||||
*/
|
||||
class SupplyGroup extends ProductGroup
|
||||
{
|
||||
public static function collectionName()
|
||||
/**
|
||||
* Имя коллекции
|
||||
*/
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'supply_group';
|
||||
}
|
||||
|
||||
protected static function writeEdgeBetweenMember(string $from, string $to): bool
|
||||
{
|
||||
// Инициализация
|
||||
$edge = new SupplyEdgeSupplyGroup();
|
||||
|
||||
// Настройка
|
||||
$edge->_from = $from;
|
||||
$edge->_to = $to;
|
||||
|
||||
// Запись
|
||||
return $edge->save();
|
||||
}
|
||||
|
||||
protected static function writeEdgeBetweenGroup(string $from, string $to): bool
|
||||
{
|
||||
// Инициализация
|
||||
$edge = new SupplyGroupEdgeSupplyGroup();
|
||||
|
||||
// Настройка
|
||||
$edge->_from = $from;
|
||||
$edge->_to = $to;
|
||||
|
||||
// Запись
|
||||
return $edge->save();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use yii\helpers\Html;
|
||||
use yii\bootstrap\ActiveForm;
|
||||
use app\models\AccountForm;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use yii\bootstrap\ActiveForm;
|
||||
use app\controllers\ProfileController;
|
||||
use app\models\Product;
|
||||
use app\models\Supply;
|
||||
|
||||
?>
|
||||
|
@ -11,21 +10,15 @@ use app\models\Supply;
|
|||
<div id="page_profile" class="container h-100">
|
||||
<div class="row h-100 py-3">
|
||||
<nav class="col-3">
|
||||
<div class="p-3 rounded">
|
||||
<div class="d-flex">
|
||||
<p>Почта: </p>
|
||||
<p class="ml-auto"><?php echo Yii::$app->user->identity->mail ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?= $sidebar ?>
|
||||
</nav>
|
||||
<article class="col-9">
|
||||
<div class="h-100 p-3 rounded">
|
||||
<h4 class="ml-4">Личный кабинет</h4>
|
||||
<div class="dropdown-divider"></div>
|
||||
<p>Не знаю что сюда пока добавить</p>
|
||||
<div class="h-100 p-4 rounded">
|
||||
<h4 class="ml-4 mb-4">Настройки аккаунта</h4>
|
||||
<p>Пока не сделана нормальная панель управления я просто буду добавлять все настройки сюда</p>
|
||||
<?php
|
||||
$form = ActiveForm::begin([
|
||||
'id' => 'form_product_import_excel',
|
||||
'id' => 'form_profile_options',
|
||||
'action' => false,
|
||||
'fieldConfig' => [
|
||||
'template' => '{label}{input}',
|
||||
|
@ -37,20 +30,26 @@ use app\models\Supply;
|
|||
]
|
||||
]);
|
||||
|
||||
$model = $model ?? new Supply;
|
||||
$groups = ProfileController::readGroups();
|
||||
$model = $model ?? Yii::$app->user->identity;
|
||||
var_dump($attributes = Supply::searchOnecByAccountId(Yii::$app->user->id));
|
||||
|
||||
// $list = [];
|
||||
|
||||
// //
|
||||
// foreach ($attributes as $attribute) {
|
||||
// $id = $attribute['ЗначенияСвойства']['Ид'];
|
||||
|
||||
// if (in_array($id, $list, true)) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// $list[] = $id;
|
||||
// }
|
||||
|
||||
?>
|
||||
|
||||
<?= $form->field($model, 'group', ['options' => ['class' => "mb-3"]])->dropDownList($groups ?? ['Нет данных']); ?>
|
||||
<?= $form->field($model, 'file', ['enableLabel' => false])->fileInput(['multiple' => true, 'onChange' => 'supply_import(this.parentElement.parentElement)']) ?>
|
||||
|
||||
<?= $form->errorSummary($model, ['header' => 'В документе были допущены ошибки:' /*, 'footer' => 'Исправьте их и попробуйте снова'*/]); ?>
|
||||
<?= "a" //$form->field($model, 'opts[import_sections_oem]', ['options' => ['class' => "mb-3"]])->dropDownList($list ?? ['Нет данных']); ?>
|
||||
|
||||
<?php ActiveForm::end(); ?>
|
||||
|
||||
<p>Всего товаров: <?php echo Product::readAmount() ?></p>
|
||||
<p>Всего поставок: <?php echo Supply::readAmount() ?></p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Yii;
|
||||
|
||||
use app\models\Product;
|
||||
use app\models\Supply;
|
||||
?>
|
||||
|
||||
<div class="p-3 rounded">
|
||||
<div class="row px-3">
|
||||
<p class="ml-0">Почта: </p>
|
||||
<p class="mr-0"><?= Yii::$app->user->identity->mail ?></p>
|
||||
</div>
|
||||
<div class="dropdown-divider my-3"></div>
|
||||
<dl class="m-0">
|
||||
<dt>
|
||||
<a class="row text-dark mb-3 px-3 font-weight-normal" href="/profile">Настройки аккаунта</a>
|
||||
</dt>
|
||||
<dt>
|
||||
<a class="row text-dark px-3 font-weight-normal" href="/profile/supplies">Управление поставками</a>
|
||||
</dt>
|
||||
</dl>
|
||||
<div class="dropdown-divider my-3"></div>
|
||||
<div class="row px-3">
|
||||
<p class="ml-0">Товары:</p>
|
||||
<p class="mr-0"><?= Product::readAmount() ?></p>
|
||||
</div>
|
||||
<div class="row px-3">
|
||||
<p class="ml-0">Поставки:</p>
|
||||
<p class="mr-0"><?= Supply::readAmount() ?></p>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use yii\bootstrap\ActiveForm;
|
||||
|
||||
use app\controllers\ProfileController;
|
||||
use app\models\Supply;
|
||||
|
||||
?>
|
||||
<link href="/css/pages/profile.css" rel="stylesheet">
|
||||
|
||||
<div id="page_profile" class="container h-100">
|
||||
<div class="row h-100 py-3">
|
||||
<nav class="col-3">
|
||||
<?= $sidebar ?>
|
||||
</nav>
|
||||
<article class="col-9">
|
||||
<div class="h-100 p-4 rounded">
|
||||
<h4 class="ml-4 mb-4">Управление поставками</h4>
|
||||
<?php
|
||||
$form = ActiveForm::begin([
|
||||
'id' => 'form_product_import_excel',
|
||||
'action' => false,
|
||||
'fieldConfig' => [
|
||||
'template' => '{label}{input}',
|
||||
'options' => ['class' => '']
|
||||
],
|
||||
'options' => [
|
||||
'class' => 'mb-3',
|
||||
'onsubmit' => 'return false;'
|
||||
]
|
||||
]);
|
||||
|
||||
$model = $model ?? new Supply;
|
||||
$groups = ProfileController::readGroups();
|
||||
|
||||
?>
|
||||
|
||||
<?= $form->field($model, 'group', ['options' => ['class' => "mb-3"]])->dropDownList($groups ?? ['Нет данных']); ?>
|
||||
<?= $form->field($model, 'file', ['enableLabel' => false])->fileInput(['multiple' => true, 'onChange' => 'supply_import(this.parentElement.parentElement)']) ?>
|
||||
|
||||
<?= $form->errorSummary($model, ['header' => 'В документе были допущены ошибки:' /*, 'footer' => 'Исправьте их и попробуйте снова'*/]); ?>
|
||||
|
||||
<?php ActiveForm::end(); ?>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/profile.js" defer></script>
|
Reference in New Issue