Magento – How to get best seller product for each category in magento 2

best-sellercategorymagento2

I have a main category "Computer" with 3 sub categories:

  • Laptop
  • Storage
  • Software

I know how can I get a sub category. But I need best the selling product for each category, for example:

Laptop

  • Product Laptop1
  • Product Laptop2 (This 2 product is best seller product for laptop category)

Storage

  • Product Storage1
  • Product Storage2 (This 2 product is best seller product for storage category)

Software

  • Product Software1
  • Product Software2 (This 2 product is best seller product for software category)

My code to get the category list for the main category is:

public function __construct(
        Template\Context $context, 
        \Magento\Catalog\Model\Layer\Resolver $layerResolver, 
        \Magento\Framework\Registry $registry, 
        \Magento\Catalog\Helper\Category $categoryHelper, 
        \Magento\Catalog\Model\CategoryFactory  $categoryFactory,
        array $data = array()) 
    {
        parent::__construct($context, $layerResolver, $registry, $categoryHelper,$data);
        $this->_categoryFactory = $categoryFactory;
        $this->_collectionFactory = $collectionFactory;
     }

    public function getCategoryList()
    {
      $_category  = $this->getCurrentCategory();
      $collection = $this->_categoryFactory->create()->getCollection()->addAttributeToSelect('*')
              ->addAttributeToFilter('is_active', 1)
              ->setOrder('position', 'ASC')
              ->addIdFilter($_category->getChildren());
      return $collection;

    }

Best Answer

Check my code below for more information :

You can also download my extension from Github. https://github.com/hirenrk4/Magento-2-Best-Seller

This way user can get a Category and sub category best the selling product for each category I've created the module following your instructions to Best sellerFilter On category list Page Filter.

app/code/Hiren/BestsellerFilter/Block/Product/ProductList/Toolbar.php

<?php
    namespace Hiren\BestsellerFilter\Block\Product\ProductList;

    class Toolbar extends \Magento\Catalog\Block\Product\ProductList\Toolbar
    {
        public function setCollection($collection)
        {
            if($this->getCurrentOrder()=="bestseller")
            {
                  $collection->getSelect()->joinLeft( 
                    'sales_order_item', 
                    'e.entity_id = sales_order_item.product_id', 
                    array('qty_ordered'=>'SUM(sales_order_item.qty_ordered)')) 
                    ->group('e.entity_id') 
                    ->order('qty_ordered '.$this->getCurrentDirectionReverse());
            }

            $this->_collection = $collection;

            $this->_collection->setCurPage($this->getCurrentPage());

            $limit = (int)$this->getLimit();
            if ($limit) {
                $this->_collection->setPageSize($limit);
            }
            if ($this->getCurrentOrder()) {
                $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
            }
            return $this;
        }

        public function getCurrentDirectionReverse() {
                if ($this->getCurrentDirection() == 'asc') {
                    return 'desc';
                } elseif ($this->getCurrentDirection() == 'desc') {
                    return 'asc';
                } else {
                    return $this->getCurrentDirection();
                }
            }

    }
    ?>

app/code/Hiren/BestsellerFilter/registration.php :

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Hiren_BestsellerFilter',
    __DIR__
);
?>

app/code/Hiren/BestsellerFilter/composer.json

{
    "name": "Hiren/bestsellerfilter",
    "description": "Magento 2 custom module to add custom best seller filter to product list toolbar",
    "require": {
        "magento/framework": "~100.0"
    },
    "type": "magento2-module",
    "version": "3.0.3",
    "license": [
        "proprietary"
    ],
    "autoload": {
        "files": [ "registration.php" ],
        "psr-4": {
            "Hiren\\BestsellerFilter\\": ""
        }
    },
    "extra": {
        "map": [
            [
                "*",
                "Hiren/BestsellerFilter"
            ]
        ]
    }
}

app/code/Hiren/BestsellerFilter/etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Store/etc/config.xsd">
    <default>
        <bestsellerfilter>
            <module>
                <is_enabled>0</is_enabled>
            </module>
        </bestsellerfilter>
    </default>
</config>

app/code/Hiren/BestsellerFilter/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Hiren_BestsellerFilter" setup_version="1.0.0" schema_version="1.0.0">
    </module>
</config>

app/code/Hiren/BestsellerFilter/etc/frontend/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\ProductList\Toolbar" type="Hiren\BestsellerFilter\Block\Product\ProductList\Toolbar"/>
    <preference for="Magento\Catalog\Model\Config" type="Hiren\BestsellerFilter\Model\Config"/>
</config>

app/code/Hiren/BestsellerFilter/Model/Config.php

<?php
namespace Hiren\BestsellerFilter\Model;

class Config extends \Magento\Catalog\Model\Config
{
    public function getAttributeUsedForSortByArray()
    {
       $options = ['bestseller' => __('Best Seller')];
        foreach ($this->getAttributesUsedForSortBy() as $attribute) {
            /* @var $attribute \Magento\Eav\Model\Entity\Attribute\AbstractAttribute */
            $options[$attribute->getAttributeCode()] = $attribute->getStoreLabel();
        }

       return $options;
    }
}
?>