How to Create Custom Product Type in Magento2

By default in Magento 2, there are six types of products available named simple, configurable, virtual, downloadable, bundle and grouped products. Each of these product types has multiple unique features and attributes. All these product types may fulfil the merchant needs. But in some cases, as a store owner, you may require to create a new custom product type to extend the need in your Magento 2 store. By using this blog, you can create a new product type in Magento 2 based on your need.

Define a new module

To create a new product type in Magento 2, you have to develop a module with an installable script. In order to create a new module based on Magento 2 structure, first, create an XML file named module.xml like a below file path to define the new module,

Sample File Path: app/code/BlogTreat/CustomProductType/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="BlogTreat_CustomProductType" setup_version="1.0.0">
    </module>
</config>

Then, create a PHP file named registration.php like a file path below,

Sample File Path: app/code/BlogTreat/CustomProductType/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'BlogTreat_CustomProductType',
    __DIR__
);

Add Custom Product Type

Create an XML file named product_types.xml like a below file path to define a custom product type,

Sample File Path: app/code/BlogTreat/CustomProductType/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="custom_product_type" label="Custom Product Type" modelInstance="BlogTreat\CustomProductType\Model\Product\Type\CustomType" indexPriority="100" sortOrder="100" isQty="true">
    </type>
    <composableTypes>
        <type name="custom_product_type" />
    </composableTypes>
</config>

In the above code,

  • name: defines the custom product code which is used in code and in the database.
  • label: defines the product type label.
  • modelInstance: custom product type model specifies custom business logic.
  • indexPriority: priority index.
  • sortOrder: position number in the sort list.
  • isQty: whether it has a quantity or not.

Then, create modelInstance file named CustomType.php like a file path below, it must inherit from the \Magento\Catalog\Model\Product\Type\AbstractType base class.

Sample File Path: app/code/BlogTreat/CustomProductType/Model/Product/Type/CustomType.php

<?php
namespace BlogTreat\CustomProductType\Model\Product\Type;

class CustomType extends \Magento\Catalog\Model\Product\Type\AbstractType {
 
    const TYPE_ID = 'custom_product_type';
     
    /**
     * {@inheritdoc}
     */
    public function deleteTypeSpecificData(\Magento\Catalog\Model\Product $product)
    {
        // method intentionally empty
    }
}

In the above script, deleteTypeSpecificData is an abstract method, this can be used to delete the data specific for the product type. You can also override any method from the \Magento\Catalog\Model\Product\Type\AbstractType class for your custom logic code.

Create Installable Script

Finally, create a setup installer file named InstallData.php like a file path below,

Sample File Path: app/code/BlogTreat/CustomProductType/Setup/InstallData.php

<?php
namespace BlogTreat\CustomProductType\Setup;
 
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
 
/**
 * Class InstallData
 *
 * @package 
 */
class InstallData implements InstallDataInterface
{
    /**
     * EAV setup factory
     *
     * @var EavSetupFactory
     */
    private $eavSetupFactory;
 
    /**
     * Init
     *
     * @param EavSetupFactory $eavSetupFactory
     */
    public function __construct(
        EavSetupFactory $eavSetupFactory
    ) {
        $this->eavSetupFactory = $eavSetupFactory;
    }
 
    /**
     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
 
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
 
        // associate these attributes with new product type
        $attributes = [
            'price',
            'special_price',
            'special_from_date',
            'special_to_date',
            'tier_price',
            'cost',
            'weight',
            'tax_class_id'
        ];
 
        // make these attributes applicable to new product type
        foreach ($attributes as $attributeCode) {
            $relatedProductTypes = explode(
                ',',
                $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode, 'apply_to')
            );
            if (!in_array(\BlogTreat\CustomProductType\Model\Product\Type\CustomType::TYPE_ID, $relatedProductTypes)) {
                $relatedProductTypes[] = \BlogTreat\CustomProductType\Model\Product\Type\CustomType::TYPE_ID;
                $eavSetup->updateAttribute(
                    \Magento\Catalog\Model\Product::ENTITY,
                    $attributeCode,
                    'apply_to',
                    implode(',', $relatedProductTypes)
                );
            }
        }
    }
}

After completing the above steps, run the following SSH command in CLI to upgrade the setup,

php magento setup:upgrade

Then, clear the cache and check your store admin panel.

Hope this helps.

Leave a Reply

Your email address will not be published. Required fields are marked *