Создан импорт из 1C, без поддержки групп
This commit is contained in:
parent
94b719b67e
commit
212694c917
|
@ -12,9 +12,9 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.0.0",
|
||||
"php": "^8.0.0",
|
||||
"twbs/bootstrap": ">=4.5",
|
||||
"yiisoft/yii2": ">=2.0.14",
|
||||
"yiisoft/yii2": "2.*",
|
||||
"yiisoft/yii2-bootstrap": ">=2.0.0",
|
||||
"yiisoft/yii2-swiftmailer": ">=2.0.0",
|
||||
"bower-asset/bootstrap": "*",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -68,12 +68,19 @@ $config = [
|
|||
'class' => 'carono\exchange1c\ExchangeModule',
|
||||
'groupClass' => 'app\models\SupplyGroup',
|
||||
'productClass' => 'app\models\Supply',
|
||||
'offerClass' => 'app\models\Product',
|
||||
'offerClass' => 'app\models\SupplyEdgeProduct',
|
||||
'partnerClass' => 'app\models\Account',
|
||||
'documentClass' => 'app\models\Purchase',
|
||||
'auth' => function ($mail, $pswd) {
|
||||
// Необходимо уничтожить AccountForm
|
||||
return (new \app\models\AccountForm())->authentication($mail, $pswd);
|
||||
// return (new \app\models\AccountForm())->authentication($mail, $pswd);
|
||||
|
||||
if ($user = \app\models\Account::findByMail($mail)) {
|
||||
if ($user->validatePassword($pswd)) {
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
]
|
||||
],
|
||||
|
|
|
@ -17,7 +17,16 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
['mail', 'pswd', 'name', 'simc', 'sity', 'comp', 'taxn', 'auth']
|
||||
[
|
||||
'mail',
|
||||
'pswd',
|
||||
'name',
|
||||
'simc',
|
||||
'sity',
|
||||
'comp',
|
||||
'taxn',
|
||||
'auth'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -73,11 +82,16 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
|||
];
|
||||
}
|
||||
|
||||
public function getId()
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->_key;
|
||||
}
|
||||
|
||||
public function readId(): string
|
||||
{
|
||||
return self::collectionName() . '/' . $this->getId();
|
||||
}
|
||||
|
||||
public function getAuthKey()
|
||||
{
|
||||
return $this->auth;
|
||||
|
|
|
@ -2,30 +2,36 @@
|
|||
|
||||
namespace app\models;
|
||||
|
||||
use Yii;
|
||||
use explosivebit\arangodb\ActiveRecord;
|
||||
|
||||
abstract class Document extends ActiveRecord
|
||||
{
|
||||
public function attributes()
|
||||
{
|
||||
return ['_key', 'date'];
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
// [
|
||||
// 'date',
|
||||
// 'required',
|
||||
// 'message' => 'Заполните поле: {attribute}'
|
||||
// ]
|
||||
'_key',
|
||||
'date',
|
||||
'writer'
|
||||
];
|
||||
}
|
||||
|
||||
public function attributeLabels()
|
||||
{
|
||||
return [
|
||||
'date' => 'Дата'
|
||||
'date' => 'Дата',
|
||||
'writer' => 'Аккаунт записавшего'
|
||||
];
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'writer',
|
||||
'string'
|
||||
// Надо добавить проверку существования аккаунта
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -33,16 +39,23 @@ abstract class Document extends ActiveRecord
|
|||
{
|
||||
if (parent::beforeSave($data)) {
|
||||
if ($this->isNewRecord) {
|
||||
$this->date = time();
|
||||
}
|
||||
|
||||
$this->date = time();
|
||||
$this->writer = $this->writer ?? Yii::$app->user->identity->readId();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function readAmount()
|
||||
public function readId(): ?string
|
||||
{
|
||||
return isset($this->_key) ? static::collectionName() . '/' . $this->_key : null;
|
||||
}
|
||||
|
||||
public static function readAmount(): int
|
||||
{
|
||||
return static::find()->count();
|
||||
}
|
||||
|
|
|
@ -4,53 +4,89 @@ namespace app\models;
|
|||
|
||||
use explosivebit\arangodb\ActiveRecord;
|
||||
|
||||
abstract class Edge extends ActiveRecord
|
||||
abstract class Edge extends Document
|
||||
{
|
||||
public function attributes()
|
||||
{
|
||||
return ['_key', '_from', '_to', 'date', 'type', 'account'];
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
[
|
||||
['_from', '_to', 'date', 'type', 'account'],
|
||||
'required',
|
||||
'message' => 'Заполните поле: {attribute}'
|
||||
],
|
||||
[
|
||||
'date',
|
||||
'integer'
|
||||
],
|
||||
[
|
||||
'type',
|
||||
'string'
|
||||
],
|
||||
[
|
||||
'account',
|
||||
'string'
|
||||
// Надо добавить проверку существования аккаунта
|
||||
'_from',
|
||||
'_to',
|
||||
'type'
|
||||
]
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
public function attributeLabels()
|
||||
{
|
||||
return [
|
||||
'date' => 'Дата',
|
||||
'type' => 'Тип',
|
||||
'account' => 'Аккаунт'
|
||||
];
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'date' => 'От кого',
|
||||
'date' => 'К кому',
|
||||
'type' => 'Тип'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
return array_merge(
|
||||
parent::rules(),
|
||||
[
|
||||
[
|
||||
['_from', '_to'],
|
||||
'required',
|
||||
'message' => 'Заполните поле: {attribute}'
|
||||
],
|
||||
[
|
||||
'type',
|
||||
'string'
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Записать
|
||||
*/
|
||||
public function write(string $_from, string $_to, string $type = '', array $data = []): ?static
|
||||
{
|
||||
// Инициализация
|
||||
$edge = isset($this->_key) ? $this : new static;
|
||||
|
||||
// Настройка
|
||||
$edge->_from = $_from;
|
||||
$edge->_to = $_to;
|
||||
$edge->type = $type;
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if(is_int($key)) {
|
||||
// Если ключ задан автоматически
|
||||
|
||||
$edge->{$value} = true;
|
||||
} else {
|
||||
// Иначе ключ записан вручную
|
||||
|
||||
$edge->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Запись
|
||||
$edge->save();
|
||||
|
||||
return $edge;
|
||||
}
|
||||
|
||||
public function beforeSave($data)
|
||||
{
|
||||
if (parent::beforeSave($data)) {
|
||||
if ($this->isNewRecord) {
|
||||
$this->date = time();
|
||||
}
|
||||
|
||||
$this->type = $this->type ?? '';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,30 +3,37 @@
|
|||
namespace app\models;
|
||||
|
||||
use moonland\phpexcel\Excel;
|
||||
use carono\exchange1c\interfaces\ProductInterface;
|
||||
use Zenwalker\CommerceML\Model\Product as Product1c;
|
||||
|
||||
class Product extends Document implements ProductInterface
|
||||
class Product extends Document
|
||||
{
|
||||
const SCENARIO_IMPORT = 'import';
|
||||
const SCENARIO_WRITE = 'write';
|
||||
|
||||
public $file;
|
||||
public $group;
|
||||
|
||||
public static function collectionName()
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'product';
|
||||
}
|
||||
|
||||
public function attributes()
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
['name', 'catn', 'oemn', 'data', 'cost', 'time']
|
||||
[
|
||||
'name',
|
||||
'ocid',
|
||||
'catn',
|
||||
'oemn'
|
||||
// 'data',
|
||||
// 'cost',
|
||||
// 'time'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::rules(),
|
||||
|
@ -35,6 +42,7 @@ class Product extends Document implements ProductInterface
|
|||
['name', 'catn'],
|
||||
'required',
|
||||
'message' => 'Заполните поля: {attribute}',
|
||||
'on' => self::SCENARIO_WRITE,
|
||||
'except' => self::SCENARIO_IMPORT
|
||||
],
|
||||
[
|
||||
|
@ -43,7 +51,7 @@ class Product extends Document implements ProductInterface
|
|||
'message' => 'Заполните поля: {attribute}',
|
||||
'on' => self::SCENARIO_IMPORT
|
||||
],
|
||||
['catn', 'integer', 'message' => '{attribute} должен быть числом'],
|
||||
['catn', 'string', 'message' => '{attribute} должен быть строкой'],
|
||||
// ['oemn', 'integer'], Нужна своя проверка на массив
|
||||
[
|
||||
'file',
|
||||
|
@ -61,37 +69,24 @@ class Product extends Document implements ProductInterface
|
|||
);
|
||||
}
|
||||
|
||||
public function attributeLabels()
|
||||
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)',
|
||||
// 'data' => 'Данные товара (data)',
|
||||
// 'cost' => 'Цены (cost)',
|
||||
// 'time' => 'Сроки доставки (time)',
|
||||
'file' => 'Документ',
|
||||
'group' => 'Группа',
|
||||
'group' => 'Группа'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function beforeSave($data)
|
||||
{
|
||||
if (parent::beforeSave($data)) {
|
||||
if ($this->isNewRecord) {
|
||||
// Надо избавиться от unset();
|
||||
unset($this->_key);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
// Инициализация массива данных
|
||||
|
@ -144,171 +139,6 @@ class Product extends Document implements ProductInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка реквизитов для продукта
|
||||
*/
|
||||
// public function setRequisite1c(string $name, string $value): bool
|
||||
public function setRequisite1c($name, $value): bool
|
||||
{
|
||||
if (!$requisite = Requisite::readByName($name)) {
|
||||
// Реквизиты не найдены
|
||||
|
||||
// Инициализация
|
||||
$requisite = new Requisite();
|
||||
|
||||
$requisite->name = $name;
|
||||
$requisite->value = $value;
|
||||
|
||||
// Запись
|
||||
return $requisite->save();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка группы, где находится продукт
|
||||
*/
|
||||
// public function setGroup1c(ProductGroup $group): bool
|
||||
public function setGroup1c($group): bool
|
||||
{
|
||||
// Чтение группы
|
||||
$group = SupplyGroup::readByOnecName($group->id)[0];
|
||||
|
||||
// Запись ребра: ПОСТАВКА => ГРУППА ПОСТАВОК
|
||||
return static::writeEdgeBetweenGroup(static::collectionName() . '/' . $this->_key, $group->collectionName() . '/' . $group->_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись всех параметров. Вызывается 1 раз при импорте
|
||||
*/
|
||||
public static function createProperties1c($properties): void
|
||||
{
|
||||
// Это нам не нужно, кажется, надо будет тестить
|
||||
|
||||
/**
|
||||
* @var \Zenwalker\CommerceML\Model\Property $property
|
||||
*/
|
||||
// foreach ($properties as $property) {
|
||||
// $propertyModel = Property::createByMl($property);
|
||||
// foreach ($property->getAvailableValues() as $value) {
|
||||
// if (!$propertyValue = PropertyValue::findOne(['onec_name' => $value->id])) {
|
||||
// $propertyValue = new PropertyValue();
|
||||
// $propertyValue->name = (string)$value->Значение;
|
||||
// $propertyValue->property_id = $propertyModel->id;
|
||||
// $propertyValue->onec_name = (string)$value->ИдЗначения;
|
||||
// $propertyValue->save();
|
||||
// unset($propertyValue);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* $property - Свойство товара (import.xml > Классификатор > Свойства > Свойство)
|
||||
* $property->value - Разыменованное значение (string) (import.xml > Классификатор > Свойства > Свойство > Значение)
|
||||
* $property->getValueModel() - Данные по значению, Ид значения, и т.д (import.xml > Классификатор > Свойства > Свойство > ВариантыЗначений > Справочник)
|
||||
*
|
||||
* @param MlProperty $property
|
||||
* @return void
|
||||
*/
|
||||
public function setProperty1c($property): void
|
||||
{
|
||||
// Это тоже нам не нужно
|
||||
|
||||
// $propertyModel = Property::findOne(['onec_name' => $property->id]);
|
||||
// $propertyValue = $property->getValueModel();
|
||||
// if ($propertyAccountingId = (string)$propertyValue->ИдЗначения) {
|
||||
// $value = PropertyValue::findOne(['onec_name' => $propertyAccountingId]);
|
||||
// $attributes = ['property_value_id' => $value->id];
|
||||
// } else {
|
||||
// $attributes = ['value' => $propertyValue->value];
|
||||
// }
|
||||
// $this->addPivot($propertyModel, PvProductProperty::class, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* В этой фукнции мы получаем абсолютный путь до картинки и название изрбражения (для alt аттрибута)
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $caption
|
||||
* @return mixed
|
||||
*/
|
||||
public function addImage1c($path, $caption): bool
|
||||
{
|
||||
// if (!$this->getImages()->andWhere(['md5' => md5_file($path)])->exists()) {
|
||||
// $this->addPivot(FileUpload::startUpload($path)->process(), PvProductImage::class, ['caption' => $caption]);
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* В эту фукнцию отправляется xml данные предложения из файла
|
||||
*/
|
||||
// public function getOffer1c(Supply $offer): Supply
|
||||
public function getOffer1c($offer): Supply
|
||||
{
|
||||
$supply = Supply::createByMl($offer);
|
||||
$supply->product_id = $this->id;
|
||||
if ($supply->getDirtyAttributes()) {
|
||||
$supply->save();
|
||||
}
|
||||
|
||||
return $supply;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MlOffer $offer
|
||||
*/
|
||||
public static function createByMl($offer): Supply
|
||||
{
|
||||
if (!$model = static::readByOnecName($offer->id)) {
|
||||
// Нет записей в базе данных
|
||||
|
||||
// Инициализация
|
||||
$model = new static;
|
||||
|
||||
$model->name = (string) $offer->name;
|
||||
$model->onec_name = (string) $offer->id;
|
||||
}
|
||||
|
||||
$model->remnant = (string) $offer->Количество;
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $product
|
||||
* @return self
|
||||
*/
|
||||
public static function createModel1c($product): static
|
||||
{
|
||||
if (!$model = static::findOne(['onec_name' => $product->id])) {
|
||||
$model = new static();
|
||||
$model->onec_name = $product->id;
|
||||
}
|
||||
$model->name = $product->name;
|
||||
$model->description = (string) $product->Описание;
|
||||
$model->article = (string) $product->Артикул;
|
||||
|
||||
$model->save();
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
public function setRaw1cData($cml, $object)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Название поля в котором хранится ID из 1C
|
||||
*/
|
||||
public static function getIdFieldName1c(): string
|
||||
{
|
||||
return 'onec_name';
|
||||
}
|
||||
|
||||
private static function writeEdgeBetweenGroup(string $from, string $to): bool
|
||||
{
|
||||
// Инициализация
|
||||
|
@ -337,16 +167,14 @@ class Product extends Document implements ProductInterface
|
|||
|
||||
public static function readById(string $_key): ?Product
|
||||
{
|
||||
return Product::findOne(['_key' => $_key]);
|
||||
return self::findOne(['_key' => $_key]);
|
||||
}
|
||||
|
||||
public function getGroup1c(): ProductGroup
|
||||
/**
|
||||
* Поиск по каталожному номеру
|
||||
*/
|
||||
public static function readByCatn(string $catn): ?Product
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
|
||||
public static function readByOnecName(string $name): ?Product
|
||||
{
|
||||
return static::findOne([static::getIdFieldName1c() => $name]);
|
||||
return self::findOne(['catn' => $catn]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class ProductGroup extends Document implements GroupInterface
|
|||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
['name', 'onec_name', 'onec_prnt_name']
|
||||
['name', 'onec_id', 'onec_prnt_id']
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,8 @@ class ProductGroup extends Document implements GroupInterface
|
|||
parent::attributeLabels(),
|
||||
[
|
||||
'name' => 'Название (name)',
|
||||
'onec_name' => 'Название 1C (onec_name)',
|
||||
'onec_prnt_name' => 'Название родителя 1C (onec_prnt_name)',
|
||||
'onec_id' => 'Название 1C (onec_id)',
|
||||
'onec_prnt_id' => 'Название родителя 1C (onec_prnt_id)',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -95,13 +95,13 @@ class ProductGroup extends Document implements GroupInterface
|
|||
*/
|
||||
public static function createByML(Group $group): static|array|null
|
||||
{
|
||||
if (!$model = static::readByOnecName($group->id)) {
|
||||
if (!$model = static::readByOnecId($group->id)) {
|
||||
// Группа не найдена
|
||||
|
||||
// Инициализация
|
||||
$model = new static;
|
||||
|
||||
$model->onec_name = $group->id;
|
||||
$model->onec_id = $group->id;
|
||||
}
|
||||
|
||||
$model->name = $group->name;
|
||||
|
@ -112,11 +112,11 @@ class ProductGroup extends Document implements GroupInterface
|
|||
// Инициализация (рекурсия)
|
||||
$parentModel = static::createByML($parent);
|
||||
|
||||
$model->onec_prnt_name = $parentModel->id;
|
||||
$model->onec_prnt_id = $parentModel->id;
|
||||
|
||||
unset($parentModel);
|
||||
} else {
|
||||
$model->onec_prnt_name = null;
|
||||
$model->onec_prnt_id = null;
|
||||
}
|
||||
|
||||
$model->save();
|
||||
|
@ -165,11 +165,11 @@ class ProductGroup extends Document implements GroupInterface
|
|||
*/
|
||||
public static function getIdFieldName1c(): string
|
||||
{
|
||||
return 'onec_name';
|
||||
return 'onec_id';
|
||||
}
|
||||
|
||||
public static function readByOnecName(string $name): ?Product
|
||||
public static function readByOnecId(string $onec_id): ?ProductGroup
|
||||
{
|
||||
return static::findOne([static::getIdFieldName1c() => $name]);
|
||||
return static::findOne(['onec_id' => $onec_id]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,15 @@ use carono\exchange1c\interfaces\DocumentInterface;
|
|||
|
||||
class Purchase extends Document implements DocumentInterface
|
||||
{
|
||||
public static function collectionName()
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'requisite';
|
||||
return 'purchase';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DocumentInterface[]
|
||||
*/
|
||||
public static function findDocuments1c()
|
||||
public static function findDocuments1c(): ?self
|
||||
{
|
||||
return self::find()->andWhere(['status_id' => 2])->all();
|
||||
}
|
||||
|
@ -22,13 +22,14 @@ class Purchase extends Document implements DocumentInterface
|
|||
/**
|
||||
* @return OfferInterface[]
|
||||
*/
|
||||
public function getOffers1c()
|
||||
public function getOffers1c(): mixed
|
||||
{
|
||||
return $this->offers;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getRequisites1c()
|
||||
public function getRequisites1c(): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,32 +37,15 @@ class Purchase extends Document implements DocumentInterface
|
|||
*
|
||||
* @return PartnerInterface
|
||||
*/
|
||||
public function getPartner1c()
|
||||
public function getPartner1c(): Account
|
||||
{
|
||||
return $this->user;
|
||||
// !!!!!!!!!!!!!!!!!!!
|
||||
return $this->user ?? new Account;
|
||||
}
|
||||
|
||||
public function getExportFields1c($context = null)
|
||||
{
|
||||
return [
|
||||
'Ид' => 'id',
|
||||
'Наименование' => 'login',
|
||||
'ПолноеНаименование' => 'full_name',
|
||||
'Фамилия' => 'surname',
|
||||
'Имя' => 'name',
|
||||
'Контакты' => [
|
||||
[
|
||||
'@name' => 'Контакт',
|
||||
'Тип' => 'Почта',
|
||||
'Значение' => $this->email,
|
||||
],
|
||||
[
|
||||
'@name' => 'Контакт',
|
||||
'Тип' => 'ТелефонРабочий',
|
||||
'Значение' => $this->phone,
|
||||
],
|
||||
],
|
||||
];
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,10 +55,10 @@ class Purchase extends Document implements DocumentInterface
|
|||
*/
|
||||
public static function getIdFieldName1c()
|
||||
{
|
||||
return 'accounting_id';
|
||||
return 'onec["Ид"]';
|
||||
}
|
||||
|
||||
public function setRaw1cData($cml, $object)
|
||||
public function setRaw1cData($cml, $object): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,153 +6,182 @@ use Yii;
|
|||
use app\models\Account;
|
||||
use app\models\Product;
|
||||
use app\models\SupplyEdgeProduct;
|
||||
use carono\exchange1c\interfaces\OfferInterface;
|
||||
use app\models\traits\Xml2Array;
|
||||
use carono\exchange1c\interfaces\ProductInterface;
|
||||
|
||||
class Supply extends Product implements OfferInterface
|
||||
// class Supply extends Product implements OfferInterface
|
||||
class Supply extends Product implements ProductInterface
|
||||
{
|
||||
public static function collectionName()
|
||||
use Xml2Array;
|
||||
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'supply';
|
||||
}
|
||||
|
||||
public function afterSave($data, $vars)
|
||||
public function attributes(): array
|
||||
{
|
||||
if (is_null($product = self::readByCatn($this->catn))) {
|
||||
// Товар не найден
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
[
|
||||
'onec'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'onec' => 'Данные 1C'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function afterSave($data, $vars): void
|
||||
{
|
||||
// Запись ребра: АККАУНТ -> ПОСТАВКА
|
||||
(new AccountEdgeSupply)->write(Yii::$app->user->identity->readId(), $this->readId(), 'import');
|
||||
}
|
||||
|
||||
public function setRequisite1c($name, $value): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка группы, где находится продукт
|
||||
*/
|
||||
public function setGroup1c($group): mixed
|
||||
{
|
||||
// Чтение группы
|
||||
// if ($group = SupplyGroup::readByOnecId($group->id)) {
|
||||
// // Запись ребра: ПОСТАВКА => ГРУППА ПОСТАВОК
|
||||
// return static::writeEdgeBetweenGroup(static::collectionName() . '/' . $this->_key, $group->collectionName() . '/' . $group->_key);
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createProperties1c($properties): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setProperty1c($property): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function addImage1c($path, $caption): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись ребра (предложения от поставки к продукту)
|
||||
*/
|
||||
public function getOffer1c($offer): SupplyEdgeProduct
|
||||
{
|
||||
if (empty($this->catn)) {
|
||||
// Не передан каталожный номер
|
||||
|
||||
// Разработчику библеотеки надо дать по жопе
|
||||
return new SupplyEdgeProduct;
|
||||
} else if (!$catn = Product::readByCatn($this->catn)) {
|
||||
// Продукт не найден
|
||||
|
||||
if (!$this->initProduct()) {
|
||||
// Не удалось инициализировать продукт
|
||||
|
||||
// Разработчику библеотеки надо дать по жопе
|
||||
return new SupplyEdgeProduct;
|
||||
}
|
||||
}
|
||||
|
||||
$catn = Product::readByCatn($this->catn);
|
||||
|
||||
// Запись ребра: ПОСТАВКА -> ПРОДУКТ
|
||||
return (new SupplyEdgeProduct)->write(
|
||||
$this->readId(),
|
||||
$catn->readId(),
|
||||
'sell',
|
||||
[
|
||||
'onec' => self::xml2array($offer->xml)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать продукт
|
||||
*/
|
||||
public static function createModel1c($product): self
|
||||
{
|
||||
// Инициализация
|
||||
$product = (new Product(array_intersect_key($this->getAttributes(), (new Product)->getAttributes())));
|
||||
$model = self::readByOnecId($id = (string) $product->Ид) ?? new self;
|
||||
|
||||
// Настройки
|
||||
$model->ocid = $id ?? null;
|
||||
$model->catn = (string) $product->Артикул;
|
||||
$model->oemn = null;
|
||||
$model->onec = self::xml2array($product->xml);
|
||||
|
||||
// Запись
|
||||
if (!$product->save()) {
|
||||
return false;
|
||||
}
|
||||
$model->save();
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
// Запись рёбер: АККАУНТ => ПОСТАВКА => ТОВАР, и проверка на то, что оба созданы
|
||||
static::writeEdgeBetweenAccount(Account::collectionName() . '/' . Yii::$app->user->identity->_key, static::collectionName() . '/' . $this->_key);
|
||||
static::writeEdgeBetweenProduct(static::collectionName() . '/' . $this->_key, Product::collectionName() . '/' . $product->_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* В этом методе необходимо создать все типы цен, фукнция вызывается один раз
|
||||
*/
|
||||
public static function createPriceTypes1c($types): void
|
||||
protected function initProduct(): bool
|
||||
{
|
||||
foreach ($types as $type) {
|
||||
// PriceType::createByMl($type);
|
||||
}
|
||||
// Надо не забыть сделать выборку полей и ручное подключение
|
||||
|
||||
if (empty($this->catn)) {
|
||||
// Не передан каталожный номер
|
||||
|
||||
return false;
|
||||
} else if (Product::readByCatn($this->catn)) {
|
||||
// Продукт уже был инициализирован
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* offers.xml > ПакетПредложений > Предложения > Предложение > Цены
|
||||
*
|
||||
* Цена товара,
|
||||
* К $price можно обратиться как к массиву, чтобы получить список цен (Цены > Цена)
|
||||
* $price->type - тип цены (offers.xml > ПакетПредложений > ТипыЦен > ТипЦены)
|
||||
*
|
||||
* @param \Zenwalker\CommerceML\Model\Price $price
|
||||
*/
|
||||
// Инициализация
|
||||
$product = new Product();
|
||||
|
||||
// Настройки
|
||||
$product->catn = $this->catn;
|
||||
|
||||
// Запись
|
||||
return $product->save();
|
||||
}
|
||||
|
||||
|
||||
public function setPrice1c($price): void
|
||||
{
|
||||
// $priceType = PriceType::findOne(['accounting_id' => $price->getType()->id]);
|
||||
// $priceModel = Price::createByMl($price, $this, $priceType);
|
||||
// $this->addPivot($priceModel, PvOfferPrice::class);
|
||||
}
|
||||
|
||||
public function setRaw1cData($cml, $object): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function readByOnecId(string $ocid): ?Supply
|
||||
{
|
||||
return self::findOne([self::getIdFieldName1c() => $ocid]);
|
||||
}
|
||||
|
||||
public function getGroup1c(): SupplyGroup
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* offers.xml > ПакетПредложений > Предложения > Предложение > ХарактеристикиТовара > ХарактеристикаТовара
|
||||
*
|
||||
* Характеристики товара
|
||||
* $name - Наименование
|
||||
* $value - Значение
|
||||
*
|
||||
* @param \Zenwalker\CommerceML\Model\Simple $specification
|
||||
* @return void
|
||||
* Название поля в котором хранится ID из 1C
|
||||
*/
|
||||
public function setSpecification1c($specification)
|
||||
public static function getIdFieldName1c(): string
|
||||
{
|
||||
// $specificationModel = Specification::createByMl($specification);
|
||||
// $this->addPivot($specificationModel, PvOfferSpecification::class, ['value' => (string)$specification->Значение]);
|
||||
}
|
||||
|
||||
public function getExportFields1c($context = null)
|
||||
{
|
||||
return [
|
||||
'Ид' => 'id',
|
||||
'Наименование' => 'login',
|
||||
'ПолноеНаименование' => 'full_name',
|
||||
'Фамилия' => 'surname',
|
||||
'Имя' => 'name',
|
||||
'Контакты' => [
|
||||
[
|
||||
'@name' => 'Контакт',
|
||||
'Тип' => 'Почта',
|
||||
'Значение' => $this->email,
|
||||
],
|
||||
[
|
||||
'@name' => 'Контакт',
|
||||
'Тип' => 'ТелефонРабочий',
|
||||
'Значение' => $this->phone,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function writeEdgeBetweenAccount(string $from, string $to): bool
|
||||
{
|
||||
// Инициализация
|
||||
$edge = new AccountEdgeSupply();
|
||||
|
||||
// Настройка
|
||||
$edge->_from = $from;
|
||||
$edge->_to = $to;
|
||||
|
||||
// Запись
|
||||
return $edge->save();
|
||||
}
|
||||
|
||||
private static function writeEdgeBetweenProduct(string $from, string $to): bool
|
||||
{
|
||||
// Инициализация
|
||||
$edge = new SupplyEdgeProduct();
|
||||
|
||||
// Настройка
|
||||
$edge->_from = $from;
|
||||
$edge->_to = $to;
|
||||
|
||||
// Запись
|
||||
return $edge->save();
|
||||
}
|
||||
|
||||
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 readByCatn(string $catn): ?Product
|
||||
{
|
||||
return Product::findOne(['catn' => $catn]);
|
||||
return 'ocid';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,76 @@
|
|||
|
||||
namespace app\models;
|
||||
|
||||
class SupplyEdgeProduct extends Edge
|
||||
use app\models\traits\Xml2Array;
|
||||
use carono\exchange1c\interfaces\OfferInterface;
|
||||
use Zenwalker\CommerceML\Model\Offer;
|
||||
|
||||
class SupplyEdgeProduct extends Edge implements OfferInterface
|
||||
{
|
||||
public static function collectionName()
|
||||
use Xml2Array;
|
||||
|
||||
public static function collectionName(): string
|
||||
{
|
||||
return 'supply_edge_product';
|
||||
}
|
||||
|
||||
public function attributes(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributes(),
|
||||
[
|
||||
'ocid',
|
||||
'onec'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function attributeLabels(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::attributeLabels(),
|
||||
[
|
||||
'ocid' => 'Идентификатор 1C (ocid)',
|
||||
'onec' => 'Данные 1C'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public static function createPriceTypes1c($types): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setPrice1c($price): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setSpecification1c($specification): mixed
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getExportFields1c($context = null): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getGroup1c(): ProductGroup
|
||||
{
|
||||
return $this->group ?? new ProductGroup;
|
||||
}
|
||||
|
||||
public static function readByOnecId(string $ocid): ?Supply
|
||||
{
|
||||
return self::findOne([self::getIdFieldName1c() => $ocid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Название поля в котором хранится ID из 1C
|
||||
*/
|
||||
public static function getIdFieldName1c(): string
|
||||
{
|
||||
return 'ocid';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,9 +34,4 @@ class SupplyGroup extends ProductGroup
|
|||
// Запись
|
||||
return $edge->save();
|
||||
}
|
||||
|
||||
public static function readByOnecName(string $onec_name): ?Product
|
||||
{
|
||||
return static::findOne(['onec_name' => $onec_name]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace app\models\traits;
|
||||
|
||||
trait Xml2Array {
|
||||
protected static function xml2array($xmlObject, $out = [])
|
||||
{
|
||||
foreach ((array) $xmlObject as $index => $node)
|
||||
$out[$index] = (is_object($node) || is_array($node)) ? self::xml2array($node) : $node;
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
Reference in New Issue