As you know, Magento supports several product types, each type has different behavior and logic. As the default, there are six types of the products you can set: Simple Product, Grouped ProductConfigurable Product, Bundle Product, Virtual Product, and Downloadable Product.

 

But in some cases, default Magento product type cannot be enough for your business. So depends on your situation, you can create a new Magento 2 product type with the following tutorial.

 

Implementation

 

1. Config XML

 

The first step is defining a custom product type with an XML declaration. Specifically, in the <Vendor>/<Module>/etc/product_types.xml, add an XML snippet of the following form to declare the new product type’s critical information.

 

<?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="product_type_code" label="Product Type Label" modelInstance="Vendor\Module\Model\Product\Type">
    </type>
</config>

 

There are three required attributes.

 

- name: Custom product attribute code used in code and database.

 

- label: Defines the product type label in Magento admin.

 

- modelInstance: Custom product type model specifies custom business logic.

 

2. Product Type Model

 

A product model must inherit from the \Magento\Catalog\Model\Product\Type\AbstractType base class. You can override any method for custom logic code.

 

Method: deleteTypeSpecificData is an abstract method, this method can be used to delete data specific for the product type.

 

<?php
namespace Vendor\Module\Model\Product;
class Type extends \Magento\Catalog\Model\Product\Type\AbstractType
{
    public function deleteTypeSpecificData(\Magento\Catalog\Model\Product $product)
    {
    }
}

 

Some common methods you can override are:

 

- isVirtual: Check is virtual product.

 

- isSaleable: Check is product available for sale.

 

- getWeight: Default action to get weight of product.

 

- hasOptions: Return true of product has options.

 

- hasRequiredOptions: Check if product has required options.

After all of the above steps, when you check the Add new product dropdown, here is what you should see:

 

 

3. Price Model

 

You can specify a price model in product type Config 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_code" label="Custom Product Type Label" modelInstance="Vendor\Module\Model\Product\Type">
    <priceModel instance="Vendor\Module\Model\Product\Price" />
    </type>
</config>

 

The price model referenced should extend \Magento\Catalog\Model\Product\Type\Price. This class has no abstract methods which must be implemented but allows extending classes to interact with nearly every aspect of price calculation.

 

Add attributes for the new product type.

 

Some product attribute only applies for a few default Magento product types, so you need to add your new product type into them.

 

Add this function to this file UpgradeData.php in your module:


This function will add your new attribute code to these product attributes : 'cost', 'price',  'special_price', 'special_from_date', 'special_to_date', 'weight', 'tax_class_id'.

 

private function addAttributeForBookingProductType($setup){
   /** @var EavSetup $eavSetup */
   $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
   $attributes = [
       'cost',
       'price',
       'special_price',
       'special_from_date',
       'special_to_date',
       'weight',
       'tax_class_id'
   ];

   foreach ($attributes as $attributeCode) {
       $relatedProductTypes = explode(
           ',',
           $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode, 'apply_to')
       );
       if (!in_array(custom_product_type_code, $relatedProductTypes)) {
           $relatedProductTypes[] = custom_product_type_code;
           $eavSetup->updateAttribute(
               \Magento\Catalog\Model\Product::ENTITY,
               $attributeCode,
               'apply_to',
               implode(',', $relatedProductTypes)
           );
       }
   }
}

 

 

4. Core Product Types

 

You can extend one of the core product types instead of the abstract directly.

 

The following product type classes are available natively in the core.

 

Simple: \Magento\Catalog\Model\Product\Type\Simple

 

Virtual: \Magento\Catalog\Model\Product\Type\Virtual

 

Configurable: \Magento\ConfigurableProduct\Model\Product\Type\Configurable

 

Grouped: \Magento\GroupedProduct\Model\Product\Type\Grouped

 

Downloadable: \Magento\Downloadable\Model\Product\Type

 

Bundle: \Magento\Bundle\Model\Product\Type

 

Giftcard (Enterprise Edition Only): \Magento\GiftCard\Model\Catalog\Product\Type\Giftcard

 

5. Bottom line

 

Magento 2 provides a framework for creating custom product types. This is very helpful for merchants who want to create custom logic based on different products and services that they are selling.