Question

I have the following block of code that gets all active catalog rules:

$catalog_rule_collection = $objectManager
                         ->create('\Magento\CatalogRule\Model\RuleFactory')
                         ->create()
                         ->getCollection()
                         ->addFieldToFilter('simple_action', 'by_percent')
                         ->addIsActiveFilter(1);

->addFieldToFilter('simple_action', 'by_percent') filters results to catalog rules with a percentage discount.

->addIsActiveFilter(1) filters results to only activated catalog rules.

This simply retrieves table data from the catalogrule table. The following SQL query would achieve the same result:

SELECT discount_amount
FROM catalogrule
WHERE simple_action = 'by_percent' AND is_active = 1

How do I filter results by store-ID-specific catalog rules? So if a catalog rule affects store 1 but not store 2, how can I express the following:

->addStoreFilter(1) //pseudocode

Consider that the catalogrule table does not have a store column, nor is the store ID specified in the conditions_serialized or actions_serialized tables. Yet in Magento 2, catalog rules can be set uniquely by store.

Was it helpful?

Solution

The solution is to JOIN the catalogrule table to the catalogrule_website table. The two tables share a rule_id column, and then the catalogrule_website table has a website_id column which specifies which website id (which == store id) the catalog rule applies to.

Via Magento this would be accomplished simply by adding ->addWebsiteFilter($store_id).

Here is the entirety of my code for anybody who is interested.

$store_id = 1;
$product_id = 101;

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$catalog_rule_collection = $objectManager->create('\Magento\CatalogRule\Model\RuleFactory')
                                         ->create()
                                         ->getCollection()
                                         ->addFieldToFilter('simple_action', 'by_percent')
                                         ->addWebsiteFilter($store_id)
                                         ->addIsActiveFilter(1);

if (!empty($catalog_rule_collection)) {
    foreach ($catalog_rule_collection as $catalog_rule) {
        $sale_applicable_product_ids = $catalog_rule->getMatchingProductIds();
        if (!empty($sale_applicable_product_ids)) {
            if (array_key_exists($product_id, $sale_applicable_product_ids)) {
                $discount_amount = $catalog_rule->getData('discount_amount');
            }
        }
    }
}

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top