Автоматическое Изменение Типов Товаров В Magento 2

Иногда по тем или иным причинам контент-менеджерам необходимо преобразовать тот или иной продукт из Простого в Виртуальный или наоборот, изменить его заданный атрибут и так далее.

Чаще всего это ложится на плечи разработчиков.

И здесь мне бы хотелось описать 1 новую и очень интересную особенность Magento 2, которая никак не описана в официальной документации.

Чтобы изменить тип продукта в Magento 1.*, контент-менеджерам придется создавать новые продукты вручную, делать из них копии исходных продуктов и т. д. или просить разработчиков сделать это с помощью кода.

В Magento 2.* появилась новая «функция» для достижения этой цели.

Прежде чем приступить к этому (я назову это «автоматическое преобразование»), вам следует помнить о нескольких вещах, чтобы получить правильные результаты.



Автоматическое преобразование с точки зрения пользователя

Давайте посмотрим на админку, а точнее на то, как она работает с точки зрения контент-менеджера.

Как и прежде, вы можете выбрать тип нового продукта перед его созданием.

В Magento 1 это отображается на странице «Администратор» > «Каталог» > «Управление продуктами» > «Установить атрибут и страницу выбора типа продукта» после нажатия «Добавить продукт».



Автоматическое изменение типов товаров в Magento 2

В Magento 2 для этого на странице «Администратор» > «Продукты» > «Каталог» нажмите стрелку справа от кнопки «Добавить товар».



Автоматическое изменение типов товаров в Magento 2

После выбора необходимого типа Magento покажет вам новую страницу редактирования продукта с предопределенными опциями и/или новыми разделами для выбранного типа.

Если вы выберете тип продукта Простой продукт или просто нажмете «Добавить продукт», вы увидите страницу редактирования простого продукта, но обратите внимание на следующие 3 вещи:

Автоматическое изменение типов товаров в Magento 2

  1. Атрибут веса
  2. Раздел Конфигурации
  3. Раздел загружаемой информации
Эти 3 раздела определяют тип продукта.

Magento 2 может автоматически (при сохранении) менять типы товаров как для новых, так и для существующих товаров следующих товаров:

Давайте рассмотрим, что для этого нужно сделать.

Простые и виртуальные продукты

Автоматическое изменение типов товаров в Magento 2

Если вы установите вес «Вес» = «Товар не имеет веса» (веса нет, а не просто убрать значение из поля ввода), то товар сохранится как Виртуальный товар, но как только вы вернитесь на страницу редактирования товара и укажите, что если товар имеет вес, то он будет конвертирован в Простой товар сразу после сохранения.

Загружаемый продукт

Автоматическое изменение типов товаров в Magento 2

Чтобы превратить Простой товар в Загружаемый, вам необходимо установить «Вес» = «Товар не имеет веса» и добавить 1 или несколько ссылок ниже в разделе «Информация о скачивании».

Чтобы превратить этот товар обратно в Простой товар, просто установите «Вес» = «Товар имеет вес» и сохраните товар.

Конфигурируемый продукт

Автоматическое изменение типов товаров в Magento 2

Чтобы превратить Простой товар в Настраиваемый, просто добавьте к нему любой дочерний товар, как указано выше.

А чтобы снова сделать его простым продуктом, просто удалите все конфигурации и нажмите «Сохранить».

Как вы уже поняли, это означает, что в Magento 2 не может быть Конфигурируемого продукта без дочерних элементов (как было в Magento 1).

Вот и все.



На заметку

Прежде чем использовать автоконвертацию в настраиваемый товар, необходимо иметь в виду, что в Magento 2 изменен принцип получения цены от Настраиваемого товара.

В Magento 1 Configurable продукты имели свою собственную цену и полностью игнорировали цену связанных с ними продуктов.

Magento 2 использует другой подход. Теперь настраиваемые продукты используют рассчитанную цену из прикрепленных дочерних элементов.

Другая сторона медали в том, что когда вы удаляете все связанные товары, товар конвертируется в Простой товар, но если вы удалите все связанные с ним товары со страницы «Сетка» в админ-панели, товар не конвертируется (я это сделаю).

объясните, почему это так, позже).

Учитывая новую логику, согласно которой продукт является конфигурируемым только в том случае, если у него есть дочерние элементы, в противном случае он «конвертируется» в простой продукт, это может привести к некоторым непредвиденным ошибкам в коде, особенно если вы работаете с импортом продуктов.

* В Magento 2.1 некоторые из этих ошибок были исправлены, и при прямом вызове метода $product-> getFinalPrice() теперь выдается исключение.

  
  
  
  
  
   

Fatal error: Uncaught exception 'Magento\Framework\Exception\LocalizedException' with message 'Configurable product "…sku…" does not have sub-products' in vendor\magento\module-configurable-product\Pricing\Price\ConfigurablePriceResolver.php:52



Для разработчиков

Теперь поговорим о том, как именно все это работает. Хотелось бы начать с самого главного, с класса.

Magento\Каталог\Модель\Продукт\TypeTransitionManager .



.

public function __construct( \Magento\Catalog\Model\Product\Edit\WeightResolver $weightResolver, array $compatibleTypes ) { $this->compatibleTypes = $compatibleTypes; $this->weightResolver = $weightResolver; } public function processProduct(Product $product) { if (in_array($product->getTypeId(), $this->compatibleTypes)) { $product->setTypeInstance(null); $productTypeId = $this->weightResolver->resolveProductHasWeight($product) ? Type::TYPE_SIMPLE : Type::TYPE_VIRTUAL; $product->setTypeId($productTypeId); } } .



Это довольно простой класс, имеющий два метода __construct иprocessProduct. Вся магия заключена во втором методе,processProduct($product).

Как видите, он проверяет, находится ли тип переданного товара в массиве совместимых типов и если товар имеет вес, то это Простой товар, если нет, то это Виртуальный товар.

В Мадженто 2.1. как вы уже догадались, совместимы следующие типы:

  • Простой
  • Виртуальный
  • Загружаемый
  • Настраиваемый
Все они передаются через di.xml

.

<type name="Magento\Catalog\Model\Product\TypeTransitionManager"> <arguments> <argument name="compatibleTypes" xsi:type="array"> <item name="simple" xsi:type="const">Magento\Catalog\Model\Product\Type::TYPE_SIMPLE</item> <item name="virtual" xsi:type="const">Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL</item> </argument> </arguments> </type> .



Это означает, что только эти типы можно преобразовать в простые или виртуальные продукты.

Как указано выше, простой продукт также можно преобразовать в настраиваемый и загружаемый продукт. Вся магия заключена в следующих классах (плагинах):

Magento\Downloadable\Model\Product\TypeTransitionManager\Plugin\Downloadable::aroundProcessProduct() проверяет, что тип продукта — «Простой», «Виртуальный», «Загружаемый», данные с загружаемым ключом были отправлены из внешнего интерфейса и что этот продукт не имеет веса.

Если да, то его можно загрузить, в противном случае запускается исходный метод.

.

public function aroundProcessProduct( \Magento\Catalog\Model\Product\TypeTransitionManager $subject, Closure $proceed, \Magento\Catalog\Model\Product $product ) { $isTypeCompatible = in_array( $product->getTypeId(), [ \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE, \Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL, \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE ] ); $downloadableData = $this->request->getPost('downloadable'); $hasDownloadableData = false; if (isset($downloadableData)) { foreach ($downloadableData as $data) { foreach ($data as $rowData) { if (empty($rowData['is_delete'])) { $hasDownloadableData = true; break 2; } } } } if ($isTypeCompatible && $hasDownloadableData && !$this->weightResolver->resolveProductHasWeight($product)) { $product->setTypeId(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE); return; } $proceed($product); } .



Magento\ConfigurableProduct\Model\Product\TypeTransitionManager\Plugin\Configurable::aroundProcessProduct() Плагин меняет тип товара на «конфигурируемый», если запрос содержит данные с ключом «атрибуты», в противном случае запускается исходный метод.

.

public function aroundProcessProduct( \Magento\Catalog\Model\Product\TypeTransitionManager $subject, Closure $proceed, \Magento\Catalog\Model\Product $product ) { $attributes = $this->request->getParam('attributes'); if (!empty($attributes)) { $product->setTypeId(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE); return; } $proceed($product); } .





Как все это работает

Если вы попытаетесь сохранить товар из админки, как написано выше, он благодаря этому коду изменит свой тип на 1 из указанных выше, но если вы просто попытаетесь сохранить модель товара методом save(), тогда ничего не изменится.

Проблема в контроллере, который занимается сохранением товаров.

Magento\Каталог\Контроллер\Админhtml\Продукт\Сохранить::execute() использует экземпляр класса Magento\Каталог\Модель\Продукт\TypeTransitionManager

.

$product = $this->initializationHelper->initialize($this->productBuilder->build($this->getRequest())); $this->productTypeManager->processProduct($product); … $product->save(); .



Как видите, конвертация товара никак не привязана к методу save() и вызывается непосредственно перед созданием товара.



Вместо заключения

Для пользователей и разработчиков, думаю, стало немного понятнее, как именно работает новая функция Magento 2. Я удивлен, что за все время существования Magento 2 об этом нигде не написали.

Еще хотелось бы добавить, что в Magento 2 довольно легко добавлять новые виды товаров, и если вам может понадобиться разрешить пользователям конвертировать их между собой, то вам достаточно добавить пару строк в di.xml файла свой модуль и создайте свой собственный плагин.

Теги: #magento #magento 2 #admin #Разработка электронной коммерции #magento

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.