0

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.

3
  • 2
    Magento default allows catalog price rule settings per website level only. website_ids attribute – PЯINCƏ Jan 23 '20 at 20:42
  • @PЯINCƏ I see that that catalogrule table's first column is rule_id which joins with the catalogrule_website table. That table has the column for website_id. So you're very close to answering my question. Now for example; \Magento\CatalogRule\Model\RuleFactory gets the catalogrule table. All I need to know now is the namespace which references the catalogrule_website table. – AlexanderGR Jan 24 '20 at 0:14
  • @PЯINCƏ Nevermind, I found the solution. Posting now. – AlexanderGR Jan 24 '20 at 0:27
1

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');
            }
        }
    }
}

1
  • Working great.This is what i am looking for – usman Aug 19 '20 at 10:44

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.