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
    Commented Apr 5, 2021 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
    Commented May 17, 2021 at 2:46
  • @jiheison have u checked in magento 2.4.x Commented May 17, 2021 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
    Commented May 17, 2021 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
    Commented May 17, 2021 at 17:55

2 Answers 2

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.

8
  • i tested but it seems not working for me Commented May 18, 2021 at 6:55
  • 1
    Reindexing after you enable the module, see README.md Commented May 18, 2021 at 7:35
  • reindexing already done Commented May 18, 2021 at 8:02
  • @user1799722 Not sure but for me, all seem to be working fine Commented May 19, 2021 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
    Commented Sep 3, 2021 at 6:09
0

Magento 2 move out of stock products to the end of category page, this solution is Elasticsearch base, suitable for 2.4.x versions. https://github.com/majidiyan/magento2-out-of-stock-move-end-category

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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