Magento 2: Catalog Rule Collection -> filter by store
-
06-04-2021 - |
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.
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');
}
}
}
}