Иногда по тем или иным причинам контент-менеджерам необходимо преобразовать тот или иной продукт из Простого в Виртуальный или наоборот, изменить его заданный атрибут и так далее.
Чаще всего это ложится на плечи разработчиков.
И здесь мне бы хотелось описать 1 новую и очень интересную особенность Magento 2, которая никак не описана в официальной документации.
Чтобы изменить тип продукта в Magento 1.*, контент-менеджерам придется создавать новые продукты вручную, делать из них копии исходных продуктов и т. д. или просить разработчиков сделать это с помощью кода.
В Magento 2.* появилась новая «функция» для достижения этой цели.
Прежде чем приступить к этому (я назову это «автоматическое преобразование»), вам следует помнить о нескольких вещах, чтобы получить правильные результаты.
Автоматическое преобразование с точки зрения пользователя
Давайте посмотрим на админку, а точнее на то, как она работает с точки зрения контент-менеджера.Как и прежде, вы можете выбрать тип нового продукта перед его созданием.
В Magento 1 это отображается на странице «Администратор» > «Каталог» > «Управление продуктами» > «Установить атрибут и страницу выбора типа продукта» после нажатия «Добавить продукт».
В Magento 2 для этого на странице «Администратор» > «Продукты» > «Каталог» нажмите стрелку справа от кнопки «Добавить товар».
После выбора необходимого типа Magento покажет вам новую страницу редактирования продукта с предопределенными опциями и/или новыми разделами для выбранного типа.
Если вы выберете тип продукта Простой продукт или просто нажмете «Добавить продукт», вы увидите страницу редактирования простого продукта, но обратите внимание на следующие 3 вещи:
- Атрибут веса
- Раздел Конфигурации
- Раздел загружаемой информации
Magento 2 может автоматически (при сохранении) менять типы товаров как для новых, так и для существующих товаров следующих товаров:
Давайте рассмотрим, что для этого нужно сделать.
Простые и виртуальные продукты
Если вы установите вес «Вес» = «Товар не имеет веса» (веса нет, а не просто убрать значение из поля ввода), то товар сохранится как Виртуальный товар, но как только вы вернитесь на страницу редактирования товара и укажите, что если товар имеет вес, то он будет конвертирован в Простой товар сразу после сохранения.
Загружаемый продукт
Чтобы превратить Простой товар в Загружаемый, вам необходимо установить «Вес» = «Товар не имеет веса» и добавить 1 или несколько ссылок ниже в разделе «Информация о скачивании».
Чтобы превратить этот товар обратно в Простой товар, просто установите «Вес» = «Товар имеет вес» и сохраните товар.
Конфигурируемый продукт
Чтобы превратить Простой товар в Настраиваемый, просто добавьте к нему любой дочерний товар, как указано выше.
А чтобы снова сделать его простым продуктом, просто удалите все конфигурации и нажмите «Сохранить».
Как вы уже поняли, это означает, что в 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. как вы уже догадались, совместимы следующие типы:
- Простой
- Виртуальный
- Загружаемый
- Настраиваемый
.
<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
- Magento\ConfigurableProduct\Model\Product\TypeTransitionManager\Plugin\Configurable
Если да, то его можно загрузить, в противном случае запускается исходный метод. .
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
-
Как Действительно Создать Загрузочный Диск
19 Oct, 24 -
Артоподы
19 Oct, 24 -
Smartos: Полностью Современная Ос
19 Oct, 24 -
Где Мы Будем Делать Скроллер?
19 Oct, 24 -
Видеопожарный Детектор
19 Oct, 24