0

I'm trying to show the Top 4 Selling Product(s) with order by qty_ordered DESC in frontend like Admin Dashboard best seller's short view. But it will not displayed data in the exact way like Admin Dashboard. My code is given below:

<?php

namespace Vendorname\Modulename\Block\Product;

use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Block\Product\AbstractProduct;
use Magento\Catalog\Block\Product\Widget\Html\Pager;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Sales\Model\ResourceModel\Report\Bestsellers\CollectionFactory as BestSellersCollectionFactory;
use Magento\Catalog\Pricing\Price\FinalPrice;
use Magento\CatalogWidget\Model\Rule;
use Magento\Framework\App\ActionInterface;
use Magento\Framework\App\Http\Context;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\DataObject\IdentityInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\Url\EncoderInterface;
use Magento\Framework\View\LayoutFactory;
use Magento\Framework\View\LayoutInterface;
use Magento\Rule\Model\Condition\Combine;
use Magento\Rule\Model\Condition\Sql\Builder;
use Magento\Widget\Block\BlockInterface;
use Magento\Widget\Helper\Conditions;

/**
 * Catalog Products List widget block
 *
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @SuppressWarnings(PHPMD.ExcessiveParameterList)
 */

class ProductsList extends \Magento\CatalogWidget\Block\Product\ProductsList //implements \Magento\Widget\Block\BlockInterface
{

/**
 * Instance of pager block
 *
 * @var Pager
 */
protected $pager;

/**
 * @var Context
 */
protected $httpContext;

/**
 * Catalog product visibility
 *
 * @var Visibility
 */
protected $catalogProductVisibility;

/**
 * Product collection factory
 *
 * @var CollectionFactory
 */
protected $productCollectionFactory;

protected $_bestSellersCollectionFactory;

/**
 * @var Builder
 */
protected $sqlBuilder;

/**
 * @var Rule
 */
protected $rule;

/**
 * @var Conditions
 */
protected $conditionsHelper;

/**
 * @var PriceCurrencyInterface
 */
private $priceCurrency;

/**
 * Json Serializer Instance
 *
 * @var Json
 */
private $json;

/**
 * @var LayoutFactory
 */
private $layoutFactory;

/**
 * @var EncoderInterface|null
 */
private $urlEncoder;

/**
 * @var \Magento\Framework\View\Element\RendererList
 */
private $rendererListBlock;

/**
 * @var CategoryRepositoryInterface
 */
private $categoryRepository;

/**
 * @param \Magento\Catalog\Block\Product\Context $context
 * @param CollectionFactory $productCollectionFactory
 * @param Visibility $catalogProductVisibility
 * @param Context $httpContext
 * @param Builder $sqlBuilder
 * @param Rule $rule
 * @param Conditions $conditionsHelper
 * @param CategoryRepositoryInterface $categoryRepository
 * @param array $data
 * @param Json|null $json
 * @param LayoutFactory|null $layoutFactory
 * @param EncoderInterface|null $urlEncoder
 *
 * @SuppressWarnings(PHPMD.ExcessiveParameterList)
 */
public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    CollectionFactory $productCollectionFactory,
    Visibility $catalogProductVisibility,
    Context $httpContext,
    Builder $sqlBuilder,
    Rule $rule,
    Conditions $conditionsHelper,
    CategoryRepositoryInterface $categoryRepository,
    BestSellersCollectionFactory $bestSellersCollectionFactory,
    array $data = [],
    Json $json = null,
    LayoutFactory $layoutFactory = null,
    EncoderInterface $urlEncoder = null
) {
    $this->productCollectionFactory = $productCollectionFactory;
    $this->catalogProductVisibility = $catalogProductVisibility;
    $this->httpContext = $httpContext;
    $this->sqlBuilder = $sqlBuilder;
    $this->rule = $rule;
    $this->conditionsHelper = $conditionsHelper;
    $this->json = $json ?: ObjectManager::getInstance()->get(Json::class);
    $this->layoutFactory = $layoutFactory ?: ObjectManager::getInstance()->get(LayoutFactory::class);
    $this->urlEncoder = $urlEncoder ?: ObjectManager::getInstance()->get(EncoderInterface::class);
    $this->categoryRepository = $categoryRepository;

    $this->_bestSellersCollectionFactory = $bestSellersCollectionFactory;
    parent::__construct(
        $context,
        $productCollectionFactory,
        $catalogProductVisibility,
        $httpContext,
        $sqlBuilder,
        $rule,
        $conditionsHelper,
        $categoryRepository,
        $data
    );
}


public function getBestsellerProductCollection()
{
    
    //$productIds  = [];
    $bestSellers = $this->_bestSellersCollectionFactory->create()
        ->setModel('Magento\Catalog\Model\Product')
        //->addStoreFilter($this->getStoreId())
        //->setPeriod('month');   
        ->setPeriod('year');

    $bestSellers->setPageSize(4);

    $bestSellers->addStoreFilter(1)->getSelect()->order('qty_ordered DESC');
    

    //echo $bestSellers->getSelect()->__toString();

    foreach ($bestSellers as $product) {
        $prodIds[] = $product->getProductId();
    }

    echo "<pre>"; print_r($prodIds); exit();

    //$productIds = array_slice(array_unique($prodIds), 0, 4);
    // //echo "<pre>"; print_r(array_unique($productIds)); exit();
    // echo "<pre>"; print_r($productIds); exit();

    $collection = $this->productCollectionFactory->create()->addIdFilter($productIds);
    $collection->addMinimalPrice()
        ->addFinalPrice()
        ->addTaxPercents()
        ->addAttributeToSelect($this->_catalogConfig->getProductAttributes())
        ->addStoreFilter($this->getStoreId())
        ->addUrlRewrite()
        ->setVisibility($this->catalogProductVisibility->getVisibleInSiteIds());
        //->setPageSize($this->getProductsCount());

    return $collection;
}

}

I cann't understand where I'm wrong to show the Top 4 Seller Products in frontend. If any one knows where there is issue, please give a proper solution(s) or clue(s).

0

try to use this to get best seller product by month and then manipulate this to get top 4:

Create one block file on your custom extension

app\code\Vendor\Module\Block\Test.php

<?php
 
namespace Vendor\Module\Block;
 
use Magento\Catalog\Block\Product\Context;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Sales\Model\ResourceModel\Report\Bestsellers\CollectionFactory as BestSellersCollectionFactory;
use Magento\Framework\View\Element\Template;
use Magento\Store\Model\StoreManagerInterface;
 
class Test extends Template
{
    protected $_bestSellersCollectionFactory;
    protected $_productCollectionFactory;
    protected $_storeManager;
 
    public function __construct(
        Context $context,
        CollectionFactory $productCollectionFactory,
        StoreManagerInterface $storeManager,
        BestSellersCollectionFactory $bestSellersCollectionFactory,
    ) {
        $this->_bestSellersCollectionFactory = $bestSellersCollectionFactory;
        $this->_storeManager = $storeManager;
        $this->_productCollectionFactory $productCollectionFactory;
     parent::__construct($context);
    }
   
    public function getProductCollection()
    {
        $productIds = [];
        $bestSellers = $this->_bestSellersCollectionFactory->create()
            ->setPeriod('month');
        foreach ($bestSellers as $product) {
            $productIds[] = $product->getProductId();
        }
        $collection = $this->_productCollectionFactory->create()->addIdFilter($productIds);
        $collection->addMinimalPrice()
            ->addFinalPrice()
            ->addTaxPercents()
            ->addAttributeToSelect('*')
            ->addStoreFilter($this->getStoreId())
            ->setPageSize(count($productIds));
        return $collection;
    }
 
    public function getStoreId(){
        return $this->_storeManager->getStore()->getId();
    }
}

use this block function getProductCollection to get best seller collection.

4
  • Hi Nihal, Thank you for your reply. Yes, it is also coming fine by the provided code, but not like Admin Dashboard best seller's small short view, means for example, A product qty 100 soled out, B product qty 65 soled out, C product qty 95, D product qty 110, E qty 105, then it should be shown Product D, E, A, C, B. It shows a haphazardly, not according to the requirement if it has been printed out echo "<pre>"; print_r($productIds); exit(); before $collection = ... . Please check it thoroughly. Jan 12 at 15:05
  • you can show the collection in desc on wty basis by using custom sorting on collection array. Jan 12 at 15:16
  • I think you are talking about \Magento\Catalog\Block\Product\ProductList\Toolbar. No, I need this feature in Home page to construct the simple list like admin dashboard best seller's small short view. Jan 12 at 16:09
  • as you have said above you want the result collection to be sorted desc, what iam saying is you can use php sort array function like this $price = array(); foreach ($inventory as $key => $row) { $price[$key] = $row['price']; } array_multisort($price, SORT_DESC, $inventory); after you get the collection Jan 12 at 20:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.