Display a collection of rules and shopping cart categories associated with each rule

I want to check if there is a sales promotion on the product, and then stick the advertising label on this product on the category list page. But I donโ€™t know how to go through all the rules of the shopping cart and get the products / categories associated with each rule.

EDITED

Thanks seanbreeden, but I can not pull skus from $conditions . var_dump($conditions); shows it:

 {s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}a:7:{s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";s:10:"conditions";a:1:{i:0;a:7:{s:4:"type";s:42:"salesrule/rule_condition_product_subselect";s:9:"attribute";s:3:"qty";s:8:"operator";s:2:">=";s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";s:10:"conditions";a:1:{i:0;a:5:{s:4:"type";s:32:"salesrule/rule_condition_product";s:9:"attribute";s:12:"category_ids";s:8:"operator";s:2:"==";s:5:"value";s:2:"23";s:18:"is_value_processed";b:0;}}}}}a:7:{s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";s:10:"conditions";a:2:{i:0;a:5:{s:4:"type";s:32:"salesrule/rule_condition_address";s:9:"attribute";s:13:"base_subtotal";s:8:"operator";s:2:">=";s:5:"value";s:2:"45";s:18:"is_value_processed";b:0;}i:1;a:7:{s:4:"type";s:42:"salesrule/rule_condition_product_subselect";s:9:"attribute";s:3:"qty";s:8:"operator";s:2:">=";s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";s:10:"conditions";a:1:{i:0;a:5:{s:4:"type";s:32:"salesrule/rule_condition_product";s:9:"attribute";s:3:"sku";s:8:"operator";s:2:"==";s:5:"value";s:46:"test-config, BLFA0968C-BK001, BLFA0968C-CR033X";s:18:"is_value_processed";b:0;}}}}}a:6:{s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}a:6:{s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}a:7:{s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";s:10:"conditions";a:1:{i:0;a:7:{s:4:"type";s:42:"salesrule/rule_condition_product_subselect";s:9:"attribute";s:3:"qty";s:8:"operator";s:2:">=";s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";s:10:"conditions";a:1:{i:0;a:5:{s:4:"type";s:32:"salesrule/rule_condition_product";s:9:"attribute";s:3:"sku";s:8:"operator";s:2:"==";s:5:"value";s:16:"BLFA0968C-CR033X";s:18:"is_value_processed";b:0;}}}}} 

but when I cross $ conditions, i.e.

 $rules = Mage::getResourceModel('salesrule/rule_collection')->load(); foreach ($rules as $rule) { $conditions = $rule->getConditionsSerialized(); foreach ($conditions as $condition) { var_dump($condition); } } 

he doesnโ€™t show anything, so I donโ€™t know how to pull here.

EDIT2 As Alaxander suggested, I do not use a non-esterialized approach. Now I do it like this:

 $rules = Mage::getResourceModel('salesrule/rule_collection')->load(); foreach ($rules as $rule) { if ($rule->getIsActive()) { //print_r($rule->getData()); $rule = Mage::getModel('salesrule/rule')->load($rule->getId()); $conditions = $rule->getConditions(); $conditions = $rule->getConditions()->asArray(); foreach( $conditions['conditions'] as $_conditions ): foreach( $_conditions['conditions'] as $_condition ): $string = explode(',', $_condition['value']); for ($i=0; $i<count($string); $i++) { $skus[] = trim($string[$i]); } endforeach; endforeach; } } return $skus; 

And then, checking the list page, if sku matches the $ skus array, then display the label. But again, there is a limitation with this approach. I am thinking of a different approach (I'm not sure if this is possible). Thinking of creating a new table (to save products sales rules). Always save the sales rule, catch the save rule event and update the table with the rule name and all related products. Then, on the list page, check that the table, if products exist in the table, shows the corresponding label. Now I think the event is adminhtml_controller_salesrule_prepare_save (not 100% sure), but I donโ€™t know how to get sku from the rule condition in the observer to save in a new table.

+4
source share
4 answers

I suggest you do it like this. When you have the product in the basket, all the rules are checked to calculate the final price and reduction. You can find out what rules apply to each item in your cart. The sales_flat_quote_item table has an applied_rule_ids column. I think you can access this in php using the getAllItemsInCart function or something like this (you need to find out). After you do $item->getAppliedRuleIds() and finally, you can get the name of the rule in relation to the element (product).

Good luck :)

Edit:

I read your request again, and I think my answer does not match your request. Your case is even more complicated. For each product on your catalog page, you must apply all the rules of your website. But the Mage_SalesRule_Model_Validator process expects an item, not a product ... If you have a lot of rules, this task will slow down your catalog, and it really is not good! It would be best to cache this rule label result in the database, maybe in the catalog_category_product table or ... (and even better to create this cache automatically).

Edit2:

Another possibility would be to have a new field in creating a rule where you manually install related products (sku). This data is stored in the salesrule table or in the new salesrule_related_sku table. Then, when you show the directory that you are checking on sku, and if the rule is still active. This solution would be the simplest :-)

+4
source

You can pull getMatchingProductsIds from /app/code/core/Mage/CatalogRule/Model/Rule.php and compare them with the skus list displayed on the category list page.

  $catalog_rule = Mage::getModel('catalogrule/rule')->load(1); // ID of your catalog rule here, or you could leave off ->load(1) and iterate through ->getCollection() instead $catalog_rule_skus = $catalog_rule->getMatchingProductIds(); 

Hth

EDIT

Here you can get serialized conditions:

 $rules = Mage::getResourceModel('salesrule/rule_collection')->load(); foreach ($rules as $rule) { $conditions = $rule->getConditionsSerialized(); var_dump($conditions); } 

EDIT 2

There must be a better way to do this. The only way I could pull this data out is to non-sterilize and then iterate through foreach through each layer. Anyone have any better ideas for this? It works, but very messy.

 $rules = Mage::getResourceModel('salesrule/rule_collection')->load(); foreach ($rules as $rule) { if ($rule->getIsActive()) { $conditions = $rule->getConditionsSerialized(); $unserialized_conditions = unserialize($conditions); $unserialized_conditions_compact = array(); foreach($unserialized_conditions as $key => $value) { $unserialized_conditions_compact[] = compact('key', 'value'); } for ($i=0;$i<count($unserialized_conditions_compact);$i++) { if (in_array("conditions",$unserialized_conditions_compact[$i])) { foreach($unserialized_conditions_compact[$i] as $key => $value) { foreach($value as $key1 => $value1) { foreach($value1 as $key2 => $value2) { foreach($value2 as $key3 => $value3) { $skus[] = explode(",",$value3['value']); } } } } } } } } var_dump($skus); 
+3
source

The rules are tied to the entire product for the website. There are no rules set for specific products / categories in terms of a database. For each product in the basket, Magento will check all the rules that you have for the website. This operation is performed in the Mage_SalesRule_Model_Validator class. The only way to solve your request is to extend the functional process from this class (at least I think so: p).

0
source

I wanted the same as you. I wanted to link SKUs, category identifiers, and any other conditions to generate Google feeds that would be used in Google advertising campaigns.

I used a recursive function to reach the last children of the condition and extract its value.

I check based on the value of the condition attribute. If the attribute value is empty, go one step down and check if the attribute value is present, and if so, select the value, otherwise it will continue to decline.

Here is the code I used to extract the values. This will also work for the case when two conditions are on the same level.

 public function get_value_recursively($value){ foreach($value as $key => $new_value) { if(strlen($new_value[attribute]) == 0){ $value = $new_value[conditions]; return $this->get_value_recursively($value); }else{ $resultSet = array(); if (count($value) > 1){ for ($i=0;$i<count($value);$i++) { $resultSet[] = array('attribute' => $value[$i][attribute], 'value' => $value[$i][value]); } $result = $resultSet; }else{ $result = array('attribute' => $new_value[attribute], 'value' => $new_value[value]); } return json_encode($result, JSON_FORCE_OBJECT); } } } 

according to @seanbreeden answer you can call this function from the first foreach

It will return the result as follows:

 {"0":{"attribute":"category_ids","value":"5, 15"},"1":{"attribute":"sku","value":"msj000, msj001, msj002"}} 

PS I'm not PHP dev. So, ignore the layman style code. :)

0
source

Source: https://habr.com/ru/post/1398819/


All Articles