Доработка поиска, поиск аттрибутов
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) {
|
if (Yii::$app->request->isAjax) {
|
||||||
// AJAX-POST-запрос
|
// AJAX-POST-запрос
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
|
@ -8,6 +9,7 @@ use yii\web\Controller;
|
||||||
use yii\web\Response;
|
use yii\web\Response;
|
||||||
use yii\web\Cookie;
|
use yii\web\Cookie;
|
||||||
use yii\web\UploadedFile;
|
use yii\web\UploadedFile;
|
||||||
|
|
||||||
use app\models\Supply;
|
use app\models\Supply;
|
||||||
use app\models\SupplyGroup;
|
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) {
|
if (Yii::$app->request->isAjax) {
|
||||||
// AJAX-POST-запрос
|
// AJAX-POST-запрос
|
||||||
|
@ -67,13 +75,39 @@ class ProfileController extends Controller
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
Yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('index'),
|
'main' => $this->renderPartial('index', compact('model', 'sidebar')),
|
||||||
'redirect' => '/profile',
|
'redirect' => '/profile',
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_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()
|
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 = new Supply(Yii::$app->request->post('Supply') ?? Yii::$app->request->get('Supply'));
|
||||||
$model->scenario = $model::SCENARIO_IMPORT;
|
$model->scenario = $model::SCENARIO_IMPORT;
|
||||||
|
|
||||||
|
// Генерация
|
||||||
|
$sidebar = $this->renderPartial('sidebar', compact('model'));
|
||||||
|
|
||||||
if (Yii::$app->request->isAjax) {
|
if (Yii::$app->request->isAjax) {
|
||||||
// AJAX-POST-запрос
|
// AJAX-POST-запрос
|
||||||
|
|
||||||
|
@ -94,12 +131,12 @@ class ProfileController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('index', compact('model')),
|
'main' => $this->renderPartial('supplies', compact('model', 'sidebar')),
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => Yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('index', compact('model'));
|
return $this->render('supplies', compact('model', 'sidebar'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function readGroups()
|
public static function readGroups()
|
||||||
|
|
|
@ -13,7 +13,7 @@ class SearchController extends Controller
|
||||||
public function actionIndex(): array|string
|
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') {
|
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 = [
|
$return = [
|
||||||
|
@ -66,9 +68,10 @@ class SearchController extends Controller
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
$return['main'] = $this->renderPartial('/search/index', compact('response'));
|
$return['main'] = $this->renderPartial('/search/index', compact('response'));
|
||||||
$return['search_line_window_hide'] = 1;
|
$return['search_line_window_hide'] = 1;
|
||||||
$return['redirect'] = '/search?type=product&q=' . $request;
|
$return['redirect'] = '/search?type=product&q=' . $query;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Данные не найдены
|
// Данные не найдены
|
||||||
|
|
||||||
Yii::$app->response->statusCode = 404;
|
Yii::$app->response->statusCode = 404;
|
||||||
|
|
|
@ -1,23 +1,39 @@
|
||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\models;
|
namespace app\models;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\web\IdentityInterface;
|
use yii\web\IdentityInterface;
|
||||||
|
|
||||||
use carono\exchange1c\interfaces\PartnerInterface;
|
use carono\exchange1c\interfaces\PartnerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Аккаунт
|
||||||
|
*
|
||||||
|
* Реализует аккаунты пользователей и поставщиков
|
||||||
|
*/
|
||||||
class Account extends Document implements IdentityInterface, PartnerInterface
|
class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
{
|
{
|
||||||
public static function collectionName()
|
public $opts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
{
|
{
|
||||||
return 'account';
|
return 'account';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attributes()
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
return array_merge(
|
return array_merge(
|
||||||
parent::attributes(),
|
parent::attributes(),
|
||||||
[
|
[
|
||||||
|
'auth',
|
||||||
'mail',
|
'mail',
|
||||||
'pswd',
|
'pswd',
|
||||||
'name',
|
'name',
|
||||||
|
@ -25,12 +41,38 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
'sity',
|
'sity',
|
||||||
'comp',
|
'comp',
|
||||||
'taxn',
|
'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(
|
return array_merge(
|
||||||
parent::rules(),
|
parent::rules(),
|
||||||
|
@ -42,24 +84,13 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attributeLabels()
|
/**
|
||||||
{
|
* Перед сохранением
|
||||||
return array_merge(
|
*
|
||||||
parent::attributeLabels(),
|
* @todo Подождать обновление от ебаного Yii2 и добавить
|
||||||
[
|
* проверку типов передаваемых параметров
|
||||||
'mail' => 'Почта',
|
*/
|
||||||
'pswd' => 'Пароль',
|
public function beforeSave($data): bool
|
||||||
'name' => 'Имя',
|
|
||||||
'simc' => 'Номер',
|
|
||||||
'sity' => 'Город',
|
|
||||||
'comp' => 'Компания',
|
|
||||||
'taxn' => 'ИНН',
|
|
||||||
'auth' => 'Аутентификационный хеш'
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function beforeSave($data)
|
|
||||||
{
|
{
|
||||||
if (parent::beforeSave($data)) {
|
if (parent::beforeSave($data)) {
|
||||||
if ($this->isNewRecord) {
|
if ($this->isNewRecord) {
|
||||||
|
@ -71,70 +102,143 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExportFields1c($context = null)
|
/**
|
||||||
|
* Чтение полей для экспорта из 1С
|
||||||
|
*/
|
||||||
|
public function getExportFields1c($context = null): array
|
||||||
{
|
{
|
||||||
return [
|
return [];
|
||||||
'Ид' => 'id',
|
|
||||||
'Наименование' => 'username',
|
|
||||||
'ПолноеНаименование' => 'full_name',
|
|
||||||
'Фамилия' => 'surname',
|
|
||||||
'Имя' => 'name',
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Чтение идентификатора
|
||||||
|
*
|
||||||
|
* @see IdentityInterface
|
||||||
|
*/
|
||||||
public function getId(): string
|
public function getId(): string
|
||||||
{
|
{
|
||||||
return $this->_key;
|
return self::collectionName() . '/' . $this->_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Чтение идентификатора
|
||||||
|
*/
|
||||||
public function readId(): string
|
public function readId(): string
|
||||||
{
|
{
|
||||||
return self::collectionName() . '/' . $this->getId();
|
return $this->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAuthKey()
|
/**
|
||||||
|
* Чтение аутентификационного ключа
|
||||||
|
*/
|
||||||
|
public function getAuthKey(): string
|
||||||
{
|
{
|
||||||
return $this->auth;
|
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]);
|
return static::findOne(['pass' => $pass]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findByMail($mail)
|
/**
|
||||||
|
* Поиск по почте
|
||||||
|
*
|
||||||
|
* @todo Подождать обновление Yii2 и добавить
|
||||||
|
* проверку типов передаваемых параметров
|
||||||
|
*/
|
||||||
|
public static function findByMail($mail): self
|
||||||
{
|
{
|
||||||
return static::findOne(['mail' => $mail]);
|
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)) {
|
if (static::findByMail($mail)) {
|
||||||
// Почта найдена в базе данных
|
// Почта найдена в базе данных
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validatePassword($pswd)
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверка пароля
|
||||||
|
*/
|
||||||
|
public function validatePassword(string $pswd): bool
|
||||||
{
|
{
|
||||||
return Yii::$app->security->validatePassword($pswd, $this->pswd);
|
return Yii::$app->security->validatePassword($pswd, $this->pswd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateAuthKey($auth)
|
/**
|
||||||
|
* Проверка аутентификационного ключа
|
||||||
|
*
|
||||||
|
* @todo Подождать обновление Yii2 и добавить
|
||||||
|
* проверку типов передаваемых параметров
|
||||||
|
*/
|
||||||
|
public function validateAuthKey($auth): bool
|
||||||
{
|
{
|
||||||
return $this->getAuthKey() === $auth;
|
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();
|
$account = $this->getAccount();
|
||||||
|
|
||||||
if (!$account || !$account->validateMail($this->mail)) {
|
if (!$account || $account->validateMail($this->mail)) {
|
||||||
// Проверка не пройдена
|
// Проверка не пройдена
|
||||||
|
|
||||||
$this->addError($attribute, 'Почта уже привязана');
|
$this->addError($attribute, 'Почта уже привязана');
|
||||||
|
|
|
@ -1,13 +1,31 @@
|
||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\models;
|
namespace app\models;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
|
|
||||||
use mirzaev\yii2\arangodb\ActiveRecord;
|
use mirzaev\yii2\arangodb\ActiveRecord;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Документ
|
||||||
|
*/
|
||||||
abstract class Document extends ActiveRecord
|
abstract class Document extends ActiveRecord
|
||||||
{
|
{
|
||||||
public function attributes()
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return throw new Exception('Не установлено название коллекции');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'_key',
|
'_key',
|
||||||
|
@ -16,7 +34,10 @@ abstract class Document extends ActiveRecord
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attributeLabels()
|
/**
|
||||||
|
* Метки свойств
|
||||||
|
*/
|
||||||
|
public function attributeLabels(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'date' => 'Дата',
|
'date' => 'Дата',
|
||||||
|
@ -24,25 +45,36 @@ abstract class Document extends ActiveRecord
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
|
||||||
|
/**
|
||||||
|
* Правила
|
||||||
|
*
|
||||||
|
* @todo Добавить проверку существования аккаунта
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
'writer',
|
'writer',
|
||||||
'string'
|
'string'
|
||||||
// Надо добавить проверку существования аккаунта
|
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function beforeSave($data)
|
/**
|
||||||
|
* Перед сохранением
|
||||||
|
*
|
||||||
|
* @todo Подождать обновление от ебаного Yii2 и добавить
|
||||||
|
* проверку типов передаваемых параметров
|
||||||
|
*/
|
||||||
|
public function beforeSave($data): bool
|
||||||
{
|
{
|
||||||
if (parent::beforeSave($data)) {
|
if (parent::beforeSave($data)) {
|
||||||
if ($this->isNewRecord) {
|
if ($this->isNewRecord) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->date = time();
|
$this->date = time();
|
||||||
$this->writer = $this->writer ?? Yii::$app->user->identity->readId();
|
$this->writer = $this->writer ?? Yii::$app->user->id;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -50,11 +82,25 @@ abstract class Document extends ActiveRecord
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Чтение идентификатора
|
||||||
|
*/
|
||||||
public function readId(): ?string
|
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
|
public static function readAmount(): int
|
||||||
{
|
{
|
||||||
return static::find()->count();
|
return static::find()->count();
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\models;
|
namespace app\models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ребро
|
||||||
|
*/
|
||||||
abstract class Edge extends Document
|
abstract class Edge extends Document
|
||||||
{
|
{
|
||||||
public function attributes()
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
return array_merge(
|
return array_merge(
|
||||||
parent::attributes(),
|
parent::attributes(),
|
||||||
|
@ -16,7 +23,10 @@ abstract class Edge extends Document
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attributeLabels()
|
/**
|
||||||
|
* Метки свойств
|
||||||
|
*/
|
||||||
|
public function attributeLabels(): array
|
||||||
{
|
{
|
||||||
return array_merge(
|
return array_merge(
|
||||||
parent::attributeLabels(),
|
parent::attributeLabels(),
|
||||||
|
@ -28,7 +38,10 @@ abstract class Edge extends Document
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
/**
|
||||||
|
* Правила
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return array_merge(
|
return array_merge(
|
||||||
parent::rules(),
|
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;
|
$edge->_from = $_from;
|
||||||
|
@ -77,7 +90,14 @@ abstract class Edge extends Document
|
||||||
return $edge;
|
return $edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function beforeSave($data)
|
|
||||||
|
/**
|
||||||
|
* Перед сохранением
|
||||||
|
*
|
||||||
|
* @todo Подождать обновление от ебаного Yii2 и добавить
|
||||||
|
* проверку типов передаваемых параметров
|
||||||
|
*/
|
||||||
|
public function beforeSave($data): bool
|
||||||
{
|
{
|
||||||
if (parent::beforeSave($data)) {
|
if (parent::beforeSave($data)) {
|
||||||
if ($this->isNewRecord) {
|
if ($this->isNewRecord) {
|
||||||
|
|
|
@ -1,23 +1,52 @@
|
||||||
<?php
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\models;
|
namespace app\models;
|
||||||
|
|
||||||
use moonland\phpexcel\Excel;
|
use moonland\phpexcel\Excel;
|
||||||
|
|
||||||
use mirzaev\yii2\arangodb\Query;
|
use mirzaev\yii2\arangodb\Query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Продукт (в ассортименте магазина)
|
||||||
|
*
|
||||||
|
* Представляет собой лот состоящий из предложений от поставщиков
|
||||||
|
*
|
||||||
|
* @see Supply Поставки для продуктов
|
||||||
|
*/
|
||||||
class Product extends Document
|
class Product extends Document
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Сценарий импорта из .excel докумекнт
|
||||||
|
*/
|
||||||
const SCENARIO_IMPORT = 'import';
|
const SCENARIO_IMPORT = 'import';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сценарий записи товара
|
||||||
|
*/
|
||||||
const SCENARIO_WRITE = 'write';
|
const SCENARIO_WRITE = 'write';
|
||||||
|
|
||||||
public $file;
|
/**
|
||||||
public $group;
|
* Файл .excel для импорта товаров
|
||||||
|
*/
|
||||||
|
public Excel|null $file = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Группа в которой состоит товар
|
||||||
|
*/
|
||||||
|
public ProductGroup|null $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
public static function collectionName(): string
|
public static function collectionName(): string
|
||||||
{
|
{
|
||||||
return 'product';
|
return 'product';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
public function attributes(): array
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
return array_merge(
|
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
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return array_merge(
|
return array_merge(
|
||||||
|
@ -70,25 +123,13 @@ class Product extends Document
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attributeLabels(): array
|
/**
|
||||||
{
|
* Импорт товаров
|
||||||
return array_merge(
|
*
|
||||||
parent::attributeLabels(),
|
* На данный момент обрабатывает только импорт из
|
||||||
[
|
* файлов с расширением .excel
|
||||||
'name' => 'Название (name)',
|
*/
|
||||||
'ocid' => 'Идентификатор 1C (ocid)',
|
public function import(): bool
|
||||||
'catn' => 'Каталожный номер (catn)',
|
|
||||||
'oemn' => 'OEM номера (oemn)',
|
|
||||||
// 'data' => 'Данные товара (data)',
|
|
||||||
// 'cost' => 'Цены (cost)',
|
|
||||||
// 'time' => 'Сроки доставки (time)',
|
|
||||||
'file' => 'Документ',
|
|
||||||
'group' => 'Группа'
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function import()
|
|
||||||
{
|
{
|
||||||
// Инициализация массива данных
|
// Инициализация массива данных
|
||||||
$data = [];
|
$data = [];
|
||||||
|
@ -140,47 +181,15 @@ class Product extends Document
|
||||||
return false;
|
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
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\models;
|
namespace app\models;
|
||||||
|
|
||||||
use carono\exchange1c\interfaces\GroupInterface;
|
use carono\exchange1c\interfaces\GroupInterface;
|
||||||
|
|
||||||
use Zenwalker\CommerceML\Model\Group;
|
use Zenwalker\CommerceML\Model\Group;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Группировка продуктов
|
||||||
|
*/
|
||||||
class ProductGroup extends Document implements GroupInterface
|
class ProductGroup extends Document implements GroupInterface
|
||||||
{
|
{
|
||||||
public static function collectionName()
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
{
|
{
|
||||||
return 'product_group';
|
return 'product_group';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attributes()
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
return array_merge(
|
return array_merge(
|
||||||
parent::attributes(),
|
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(
|
return array_merge(
|
||||||
parent::rules(),
|
parent::rules(),
|
||||||
|
@ -34,34 +64,18 @@ class ProductGroup extends Document implements GroupInterface
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attributeLabels()
|
/**
|
||||||
|
* Запись члена группы
|
||||||
|
*/
|
||||||
|
public function writeMember(Product $member): ProductEdgeProductGroup
|
||||||
{
|
{
|
||||||
return array_merge(
|
return ProductEdgeProductGroup::write($member->readId(), $this->readId(), 'member');
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Создание дерева групп
|
* Запись рёбер групп
|
||||||
* в параметр передаётся массив всех групп (import.xml > Классификатор > Группы)
|
|
||||||
* $groups[0]->parent - родительская группа
|
|
||||||
* $groups[0]->children - дочерние группы
|
|
||||||
*
|
*
|
||||||
* @param Group[] $groups
|
* Создание взаимоотношений между группами по типу древовидной системы
|
||||||
*/
|
*/
|
||||||
public static function createTree1c($groups): Document|null
|
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
|
public static function createByML(Group $group): static|array|null
|
||||||
{
|
{
|
||||||
|
@ -124,19 +139,6 @@ class ProductGroup extends Document implements GroupInterface
|
||||||
return $model;
|
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
|
private static function writeEdgeBetweenGroup(string $from, string $to): bool
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
|
|
|
@ -1,24 +1,46 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\models;
|
namespace app\models;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
|
|
||||||
use app\models\Account;
|
use app\models\Account;
|
||||||
use app\models\Product;
|
use app\models\Product;
|
||||||
use app\models\SupplyEdgeProduct;
|
use app\models\SupplyEdgeProduct;
|
||||||
use app\models\traits\Xml2Array;
|
use app\models\traits\Xml2Array;
|
||||||
|
|
||||||
use carono\exchange1c\interfaces\ProductInterface;
|
use carono\exchange1c\interfaces\ProductInterface;
|
||||||
|
|
||||||
// class Supply extends Product implements OfferInterface
|
use mirzaev\yii2\arangodb\Query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поставка (выгрузка товаров от поставщиков)
|
||||||
|
*
|
||||||
|
* Представляет собой предложения от поставщиков которые добавляются
|
||||||
|
* в универсальные лоты товаров в асспортименте магазина
|
||||||
|
*
|
||||||
|
* @see Product Продукт (туда добавляются поставки)
|
||||||
|
*/
|
||||||
class Supply extends Product implements ProductInterface
|
class Supply extends Product implements ProductInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Метод для конвертации XML в Array
|
||||||
|
*/
|
||||||
use Xml2Array;
|
use Xml2Array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
public static function collectionName(): string
|
public static function collectionName(): string
|
||||||
{
|
{
|
||||||
return 'supply';
|
return 'supply';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
public function attributes(): array
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
return array_merge(
|
return array_merge(
|
||||||
|
@ -29,29 +51,38 @@ class Supply extends Product implements ProductInterface
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метки свойств
|
||||||
|
*/
|
||||||
public function attributeLabels(): array
|
public function attributeLabels(): array
|
||||||
{
|
{
|
||||||
return array_merge(
|
return array_merge(
|
||||||
parent::attributeLabels(),
|
parent::attributeLabels(),
|
||||||
[
|
[
|
||||||
'onec' => 'Данные 1C'
|
'onec' => 'Данные 1С'
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* После сохранения
|
||||||
|
*/
|
||||||
public function afterSave($data, $vars): void
|
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
|
public function setRequisite1c($name, $value): mixed
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Установка группы, где находится продукт
|
* Запись группы из 1С
|
||||||
*/
|
*/
|
||||||
public function setGroup1c($group): mixed
|
public function setGroup1c($group): mixed
|
||||||
{
|
{
|
||||||
|
@ -64,23 +95,66 @@ class Supply extends Product implements ProductInterface
|
||||||
return true;
|
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
|
public function setProperty1c($property): mixed
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запись изображений из 1С
|
||||||
|
*/
|
||||||
public function addImage1c($path, $caption): mixed
|
public function addImage1c($path, $caption): mixed
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Запись ребра (предложения от поставки к продукту)
|
* Запись ребра (предложения от поставок к продуктам) из 1С
|
||||||
*/
|
*/
|
||||||
public function getOffer1c($offer): SupplyEdgeProduct
|
public function getOffer1c($offer): SupplyEdgeProduct
|
||||||
{
|
{
|
||||||
|
@ -89,7 +163,7 @@ class Supply extends Product implements ProductInterface
|
||||||
|
|
||||||
// Разработчику библеотеки надо дать по жопе
|
// Разработчику библеотеки надо дать по жопе
|
||||||
return new SupplyEdgeProduct;
|
return new SupplyEdgeProduct;
|
||||||
} else if (!$catn = Product::readByCatn($this->catn)) {
|
} else if (!$product = Product::searchByCatn($this->catn)) {
|
||||||
// Продукт не найден
|
// Продукт не найден
|
||||||
|
|
||||||
if (!$this->initProduct()) {
|
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(
|
return (new SupplyEdgeProduct)->write(
|
||||||
$this->readId(),
|
$this->readId(),
|
||||||
$catn->readId(),
|
$product->readId(),
|
||||||
'sell',
|
'sell',
|
||||||
[
|
[
|
||||||
'onec' => self::xml2array($offer->xml)
|
'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->ocid = $id ?? null;
|
||||||
$model->catn = (string) $product->Артикул;
|
$model->catn = (string) $product->Артикул;
|
||||||
$model->oemn = null;
|
$model->oemn = null;
|
||||||
$model->onec = self::xml2array($product->xml);
|
$model->onec = self::xml2array($product->xml);
|
||||||
|
|
||||||
// Запись
|
// Запись
|
||||||
$model->save();
|
return $model->save() ? $model : null;
|
||||||
|
|
||||||
return $model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function initProduct(): bool
|
/**
|
||||||
|
* Инициализация продукта
|
||||||
|
*/
|
||||||
|
protected function initProduct(): ?Product
|
||||||
{
|
{
|
||||||
// Надо не забыть сделать выборку полей и ручное подключение
|
// Надо не забыть сделать выборку полей и ручное подключение
|
||||||
|
|
||||||
|
@ -141,7 +216,7 @@ class Supply extends Product implements ProductInterface
|
||||||
// Не передан каталожный номер
|
// Не передан каталожный номер
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (Product::readByCatn($this->catn)) {
|
} else if (Product::searchByCatn($this->catn)) {
|
||||||
// Продукт уже был инициализирован
|
// Продукт уже был инициализирован
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -154,34 +229,79 @@ class Supply extends Product implements ProductInterface
|
||||||
$product->catn = $this->catn;
|
$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
|
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;
|
return $this->group;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Название поля в котором хранится ID из 1C
|
* Чтение названия поля в котором хранится идентификатор из 1С
|
||||||
*/
|
*/
|
||||||
public static function getIdFieldName1c(): string
|
public static function getIdFieldName1c(): string
|
||||||
{
|
{
|
||||||
return 'ocid';
|
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
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\models;
|
namespace app\models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Группировка поставок
|
||||||
|
*/
|
||||||
class SupplyGroup extends ProductGroup
|
class SupplyGroup extends ProductGroup
|
||||||
{
|
{
|
||||||
public static function collectionName()
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
{
|
{
|
||||||
return 'supply_group';
|
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
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
use yii\helpers\Html;
|
use yii\helpers\Html;
|
||||||
use yii\bootstrap\ActiveForm;
|
use yii\bootstrap\ActiveForm;
|
||||||
use app\models\AccountForm;
|
use app\models\AccountForm;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
use yii\bootstrap\ActiveForm;
|
use yii\bootstrap\ActiveForm;
|
||||||
use app\controllers\ProfileController;
|
use app\controllers\ProfileController;
|
||||||
use app\models\Product;
|
|
||||||
use app\models\Supply;
|
use app\models\Supply;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -11,21 +10,15 @@ use app\models\Supply;
|
||||||
<div id="page_profile" class="container h-100">
|
<div id="page_profile" class="container h-100">
|
||||||
<div class="row h-100 py-3">
|
<div class="row h-100 py-3">
|
||||||
<nav class="col-3">
|
<nav class="col-3">
|
||||||
<div class="p-3 rounded">
|
<?= $sidebar ?>
|
||||||
<div class="d-flex">
|
|
||||||
<p>Почта: </p>
|
|
||||||
<p class="ml-auto"><?php echo Yii::$app->user->identity->mail ?></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
</nav>
|
||||||
<article class="col-9">
|
<article class="col-9">
|
||||||
<div class="h-100 p-3 rounded">
|
<div class="h-100 p-4 rounded">
|
||||||
<h4 class="ml-4">Личный кабинет</h4>
|
<h4 class="ml-4 mb-4">Настройки аккаунта</h4>
|
||||||
<div class="dropdown-divider"></div>
|
<p>Пока не сделана нормальная панель управления я просто буду добавлять все настройки сюда</p>
|
||||||
<p>Не знаю что сюда пока добавить</p>
|
|
||||||
<?php
|
<?php
|
||||||
$form = ActiveForm::begin([
|
$form = ActiveForm::begin([
|
||||||
'id' => 'form_product_import_excel',
|
'id' => 'form_profile_options',
|
||||||
'action' => false,
|
'action' => false,
|
||||||
'fieldConfig' => [
|
'fieldConfig' => [
|
||||||
'template' => '{label}{input}',
|
'template' => '{label}{input}',
|
||||||
|
@ -37,20 +30,26 @@ use app\models\Supply;
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$model = $model ?? new Supply;
|
$model = $model ?? Yii::$app->user->identity;
|
||||||
$groups = ProfileController::readGroups();
|
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;
|
||||||
|
// }
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
<?= "a" //$form->field($model, 'opts[import_sections_oem]', ['options' => ['class' => "mb-3"]])->dropDownList($list ?? ['Нет данных']); ?>
|
||||||
<?= $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(); ?>
|
<?php ActiveForm::end(); ?>
|
||||||
|
|
||||||
<p>Всего товаров: <?php echo Product::readAmount() ?></p>
|
|
||||||
<p>Всего поставок: <?php echo Supply::readAmount() ?></p>
|
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</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