1

I want to move out of stock product in last of the category listing, itried below code but same seems not working.

app/code/Meetanshi/StockQuantity/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="Meetanshi_StockQuantity" setup_version="1.0.0"/>
</config>

app/code/Meetanshi/StockQuantity/etc/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
   <event name="catalog_block_product_list_collection">
       <observer name="stockLast" instance="Meetanshi\StockQuantity\Observer\StockLast" />
   </event>
</config>

app/code/Meetanshi/StockQuantity/Observer/StockLast.php

<?php
namespace Meetanshi\StockQuantity\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\Event\Observer;
use Magento\Catalog\Block\Product\ProductList\Toolbar as CoreToolbar;
class StockLast implements ObserverInterface
{
   protected $scopeConfig;
   protected $_storeManager;
   protected $coreToolbar;
   public function __construct(
       ScopeConfigInterface $scopeConfig,
       StoreManagerInterface $storeManager,
       CoreToolbar $toolbar
   )
   {
       $this->scopeConfig = $scopeConfig;
       $this->_storeManager = $storeManager;
       $this->coreToolbar = $toolbar;
   }
   public function execute(Observer $observer)
   {
       $collection = $observer->getEvent()->getData('collection');
       try {
           $websiteId = 0;
           $stockId = 'stock_id';
           $collection->getSelect()->joinLeft(
               array('_inv' => $collection->getResource()->getTable('cataloginventory_stock_status')),
               "_inv.product_id = e.entity_id and _inv.website_id=$websiteId",
               array('stock_status')
           );
           $collection->addExpressionAttributeToSelect('in_stock', 'IFNULL(_inv.stock_status,0)', array());
           $collection->getSelect()->reset('order');
           $collection->getSelect()->order('in_stock DESC');
           //code for Filter Price Low to High or High to Low with stock filter.
           if ($this->coreToolbar->getCurrentOrder() == 'price') {
               $direction = $this->coreToolbar->getCurrentDirection();
               $collection->getSelect()->order("min_price $direction");
           }
       } catch (\Exception $e) {
       }
       return $this;
   }
}
5
  • I'm wondering why you don't use the new ui_component for grid?
    – Jimmy
    Apr 5 '21 at 4:30
  • I tested this code it seems to work, at least as far as generating a SQL query that includes the expected sorting. Perhaps you could provide more specific details about how it is not working for you?
    – jiheison
    May 17 '21 at 2:46
  • @jiheison have u checked in magento 2.4.x May 17 '21 at 7:54
  • @user1799722 good question! I forgot that the project I was working on at the time was 2.3.x. It does not work in a 2.4.x site. Sorry for the confusion there.
    – jiheison
    May 17 '21 at 17:52
  • I tried implementing the code in a plugin for Magento\Catalog\Block\Product\ListProduct that provided an afterGetLoadedProductCollection method. That allowed me to modify the collection query as expected, but the actual product list did not render accordingly. In the collection class, Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection, there is a note: "This collection should be refactored to not have dependencies on MySQL-specific implementation." Maybe this is why modifying the SQL query does not work, i.e. the query is maintained as a legacy, but isn't used for the search? Odd.
    – jiheison
    May 17 '21 at 17:55
3
+100

Since you cannot use the code above to apply to magento 2.4.x because Magento 2.4.x used ElasticSearch as default search engine.

Here I've created a sample module for your purpose

https://github.com/tuyennn/magento2-outofstockatlast

Hope this help.

6
  • i tested but it seems not working for me May 18 '21 at 6:55
  • 1
    Reindexing after you enable the module, see README.md May 18 '21 at 7:35
  • reindexing already done May 18 '21 at 8:02
  • @user1799722 Not sure but for me, all seem to be working fine May 19 '21 at 8:21
  • @TuyenNguyen: I'm getting below error using your module. Do you have any suggestions {"type":"query_shard_exception","reason":"No mapping found for [out_of_stock_at_last] in order to sort on Note: Your module works well in Vanilla Magento2. I'm facing issue in one of my project
    – Pkrishna
    Sep 3 '21 at 6:09

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.