Create new product type

  • Simple Proudct
    a simple product can be sold individually, or as part of a grouped, configurable, or bundle product.
    A simple product can have custom options with a variety of input controls, which makes it possible to sell many product variations from a single SKU
  • Configurable Product
    A configurable product allows the shopper to choose options from drop-down lists. Each option in a configurable product represents a separate, simple product with a distinct SKU, which makes it possible to track inventory for each variation.
    Each drop-down list value is based on an attribute of the “Dropdown” input type(You can choose from (Dropdown /visual swatch / text swatch)). The drop-down attributes must be included in the attribute set, which is then used as a template for the configurable product.
    The thumbnail image in the shopping cart can be set to display the image from the configurable product record, or from the product variation.
    Simple and virtual products that are part of a configurable product cannot have custom options.
  • Group Product
    A grouped product is essentially a collection of simple associated products.
    Simple and virtual products that are part of a grouped product cannot have custom options.
    Each item purchased appears individually in the shopping cart, rather than as part of the group.
    The thumbnail image in the shopping cart can be set to display the image from the grouped parent product, or the associated product.
    For example with demo data: http://example.com/set-of-sprite-yoga-straps.html
  • Bundled Product
    The main point that distinguishes bundled product from grouped products is that when items are bundled together, it is hardly possible for any of the products to be removed from the set. In simple words, one product cannot live without the other, would hardly function if the other is missing. One product complements the other.
    For example with demo data: http://example.com/sprite-yoga-companion-kit.html
  • Downloadable Products
    Downloadable products can be uploaded to the server, or linked to from another server on the Internet.
    You can determine the number of times a customer can download a product.
    Customers who purchase a downloadable product can be required to log in before going through checkout.
    The delivery of a downloadable product can be made when the order is in either a “Pending” or “Invoiced” state.
  • Virtual Products
    Virtual products are used for non-tangible products such as services, subscriptions, and warranties.
    Virtual products are much like simple products, but without the Weight.
    Shipping Options do not appear during checkout unless there is a tangible product in the cart.

Experients

Config XML

etc/product_types.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/product_types.xsd">
    <type name="new_product_type" label="New Product Type" modelInstance="VendorName\TestModule\Model\Product\Type\NewProductType" indexPriority="60" sortOrder="80" isQty="true">
        <priceModel instance="VendorName\TestModule\Model\Product\Price" />
    </type>
</config>

The type node has three required attributes.

  • name: This attribute defines the custom product code which is used in code and in the database.
  • label: Defines the product type label in the Magento admin.
  • modelInstance: Specifies the fully qualified namespace of the corresponding product type model.

Product Type Model

Each product instance is associated with an instance of the corresponding product type model. This model has the opportunity to modify product type behavior and attributes and is called during many product manipulation processes.

<?php
namespace VendorName\TestModule\Model\Product\Type;

class NewProductType extends \Magento\Catalog\Model\Product\Type\AbstractType
{
    const TYPE_ID = 'new_product_type';

    public function deleteTypeSpecificData(\Magento\Catalog\Model\Product $product)
    {

    }

}

A product model must inherit from the \Magento\Catalog\Model\Product\Type\AbstractType base class. The base class has only one abstract method: deleteTypeSpecificData. This oddly specific method is called during a product instance save if its type has changed, and gives the original product type the opportunity to clean up any type-specific data before the type change is finalized.

Price Model

<?php
namespace VendorName\TestModule\Model\Product;

class Price extends \Magento\Catalog\Model\Product\Type\Price
{

    public function getPrice($product)
    {
        return $product->getData('price') + 200;
    }
}

Associate With Price Attributes

<?php
namespace VendorName\TestModule\Setup\Patch\Data;

use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;

class CustomProductTypePatch implements DataPatchInterface
{
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        CustomerSetupFactory $customerSetupFactory,
        EavSetupFactory $eavSetupFactory,
        AttributeSetFactory $attributeSetFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->customerSetupFactory = $customerSetupFactory;
        $this->eavSetupFactory = $eavSetupFactory;
        $this->attributeSetFactory = $attributeSetFactory;
    }

    public function getAliases()
    {
        /**
         * This internal Magento method, that means that some patches with time can change their names,
         * but changing name should not affect installation process, that's why if we will change name of the patch
         * we will add alias here
         */
        return [];
    }

    public function apply()
    {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);

        //associate these attributes with new product type
        $fieldList = [
            'price',
            'special_price',
            'special_from_date',
            'special_to_date',
            'minimal_price',
            'cost',
            'tier_price',
            'weight',
        ];

        // make these attributes applicable to new product type
        foreach ($fieldList as $field) {
            $applyTo = explode(
                ',',
                $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $field, 'apply_to')
            );
            if (!in_array(\VendorName\TestModule\Model\Product\Type\NewProductType::TYPE_ID, $applyTo)) {
                $applyTo[] = \VendorName\TestModule\Model\Product\Type\NewProductType::TYPE_ID;
                $eavSetup->updateAttribute(
                    \Magento\Catalog\Model\Product::ENTITY,
                    $field,
                    'apply_to',
                    implode(',', $applyTo)
                );
            }
        }
    }

    public static function getDependencies()
    {
        /**
         * This is dependency to another patch. Dependency should be applied first
         * One patch can have few dependencies
         * Patches do not have versions, so if in old approach with Install/Ugrade data scripts you used
         * versions, right now you need to point from patch with higher version to patch with lower version
         * But please, note, that some of your patches can be independent and can be installed in any sequence
         * So use dependencies only if this important for you
         */
        // return [
        //     SomeDependency::class
        // ];
        return [];
    }

}

After bin/magento setup:upgrade. Now we create a new product using custom product type.



The product type instance and product price type is used in Magento\Catalog\Model\Product

Practices Tests

You need to create a custom price calculator for simple products. You have already created the new price model.
Keeping simplicity in mind, what additional steps do you take to implement this? (Multiple Choice)
A. Make your new price model extend \Magento\Catalog\Model\Product\Type\Price.
B. Update the frontend templates to use the new price methods.
C. Create a plugin for the getPriceModel() method and return your price model.
D. In your product_types.xml module, reference the simple product type, and set a value for the priceModel attribute

Answer A D

References

Manage Magento 2 Product Types and Catalog Data
Custom Product Types in Magento 2
How to Create a New Product Type in Magento 2

发表评论

电子邮件地址不会被公开。 必填项已用*标注