Skip to main content
2 of 2
Added github link
sduif
  • 975
  • 5
  • 13

This is not something Magento can do by default as far as I know. But it's possible to add Catalog Price rule information in the product listing results by modifying the list query using the catalog_block_product_list_collection event.

We can do this with a small custom module, based on an observer from the Magento CatalogRule module itself. (Make sure to replace Vendor with your desired vendor name)

(Edit: I've added all code below to Github for easy download https://github.com/sduif/magento2-279672-catalogruleprice-to-list)

app/code/Vendor/ListPriceRule/registration.php

<?php
 
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_ListPriceRule',
    __DIR__
);

app/code/Vendor/ListPriceRule/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="Vendor_ListPriceRule" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog"/>
            <module name="Magento_CatalogRule"/>
        </sequence>
    </module>
</config>

app/code/Vendor/ListPriceRule/etc/frontend/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='add_catalogrule_to_list_collection' instance='Vendor\ListPriceRule\Model\Observer\ProductListObserver'/>
    </event>    
</config>

app/code/Vendor/ListPriceRule/Model/Observer/ProductListObserver.php

<?php

namespace Vendor\ListPriceRule\Model\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\CatalogRule\Pricing\Price\CatalogRulePrice;

class ProductListObserver implements ObserverInterface
{
    private $storeManager;
    private $resource;
    private $customerSession;
    private $dateTime;
    private $localeDate;

    public function __construct(
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\App\ResourceConnection $resourceConnection,
        \Magento\Customer\Model\Session $customerSession,
        \Magento\Framework\Stdlib\DateTime $dateTime,
        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
    ) {
        $this->storeManager = $storeManager;
        $this->resource = $resourceConnection;
        $this->customerSession = $customerSession;
        $this->dateTime = $dateTime;
        $this->localeDate = $localeDate;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
                
        $collection = $observer->getEvent()->getCollection();
        if (!$collection->hasFlag('added_catalog_rule_data')) {

            $connection = $this->resource->getConnection();
            $store = $this->storeManager->getStore();
            $collection->getSelect()
                ->joinLeft(
                    ['catalog_rule' => $this->resource->getTableName('catalogrule_product_price')],
                    implode(' AND ', [
                        'catalog_rule.product_id = ' . $connection->quoteIdentifier('e.entity_id'),
                        $connection->quoteInto('catalog_rule.website_id = ?', $store->getWebsiteId()),
                        $connection->quoteInto(
                            'catalog_rule.customer_group_id = ?',
                            $this->customerSession->getCustomerGroupId()
                        ),
                        $connection->quoteInto(
                            'catalog_rule.rule_date = ?',
                            $this->dateTime->formatDate($this->localeDate->scopeDate($store->getId()), false)
                        ),
                    ]),
                    [CatalogRulePrice::PRICE_CODE => 'rule_price']
                );

            $collection->setFlag('added_catalog_rule_data', true);
        }

        return $this;        
    }
}

After installing and enabling this module you can now access catalog price rule information in your list.phtml. For example

<?php  echo ($_product->getCatalogRulePrice() ? 'has catalog price rule' : 'regular'); ?>
sduif
  • 975
  • 5
  • 13