product price is calculated dynamically based on certain conditions. while sorting with price it takes only default price not dynamically calculated price. the same issue with the price filter.

I can able to set the calculated price for product using event catalog_block_product_list_collection observer but not able to get products ordered by dynamic price.

<event name="catalog_block_product_list_collection">
    <observer name="product_price_change" instance="[vendor]\[module]\Observer\ProductCollectionDynamicPrice" shared="false" />

Observer - [vendor][module]\Observer\ProductCollectionDynamicPrice

namespace [vendor]\[module]\Observer;

use Magento\Framework\Event\ObserverInterface;

class ProductCollectionDynamicPrice implements ObserverInterface
     * set dynamic price
     * @param \Magento\Framework\Event\Observer $observer
     * @return $this
    public function execute(\Magento\Framework\Event\Observer $observer)
       $productCollection = $observer->getEvent()->getCollection();
       if ($productCollection instanceof \Magento\Framework\Data\Collection) {

       return $this;

     * set dynamic calculated price to product collection
     * @param ProductCollection $collection
     * @return $this
    public function calculatePrice($collection) {

     foreach ($collection as $key => $item) {
        $price = 100;  // here my cuustom logic to calculate dynamic price based on conditions 

     return $collection;


If I echoing min_price then able to get updated min_price but not able to get correct product orders collection sort by price.

Please anyone can help for the issue?

1 Answer 1


I assume, In Category page you are trying to sort by the price and not getting the correct order while you want your prices to be displayed as well as used in sorting.


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
        <plugin name="sortby_extend_default_sort_filters" type="Vendor\Module\Plugin\Toolbar" sortOrder="99" />


namespace Vendor\Module\Plugin;

use Zend\Filter\Boolean;
use Magento\Store\Model\StoreManagerInterface;

 * Product list toolbar plugin
class Toolbar
    protected $test;
    protected $storeManagerInterface;
    protected $_flag = true;

    public function __construct(StoreManagerInterface $storeManagerInterface)
        $this->storeManagerInterface = $storeManagerInterface;

    public function aroundSetCollection(\Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
                                        \Closure $proceed,
        $currentOrder = $subject->getCurrentOrder();
        $result = $proceed($collection);
        $pageSize = $collection->getPageSize();
        if ($pageSize) {
        if ($currentOrder && $currentOrder == 'price' && $this->_flag == false) {
            //Get current store information
            $currentStore = $subject->getCollection()->getStoreId();
            $currency = $this->storeManagerInterface ->getStore($currentStore)->getCurrentCurrencyCode();

            //add you custom calculation here in the result/collection
                    'new_price' => new \Zend_Db_Expr("IF (
                    YOURCONDITION IN DB QUERY,
                    TRUE Value,
                    False Value)"))
            //to reset sorting order 
            $subject->getCollection()->getSelect()->order(new \Zend_Db_Expr('`new_price` ' . $subject->getData('_current_grid_direction')));
        $this->_flag = false;
        return $result;

You've to add your logic using SQL Query/Operators.

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.