显示与每个规则关联的购物车规则和产品类别的集合

时间:2012-02-28 13:47:26

标签: magento shopping promotion-code

我想检查产品上是否有促销活动,然后在类别列表页面上粘贴该产品上的促销标签。但我不知道如何遍历所有购物车规则并检索与每个规则相关联的产品/类别。

EDITED

谢谢seanbreeden,但我不能从$conditions拉出skus。 var_dump($conditions);显示了这一点:

{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;}}}}}

但是当我循环通过$条件时,

$rules = Mage::getResourceModel('salesrule/rule_collection')->load();

foreach ($rules as $rule) {
    $conditions = $rule->getConditionsSerialized();
    foreach ($conditions as $condition) {
        var_dump($condition);
    }
}

它没有显示任何东西所以不知道如何在这里拉skus。

EDIT2 正如Alaxandre所说,我没有使用非序列化的方法。我现在这样做了:

$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;

然后检查列表页面,如果sku在$ skus数组中匹配,则显示标签。但同样这种方法也存在局限性。我想到了另一种方法(我不确定这是否可行)。 考虑创建新表(以保存销售规则产品)。每次保存销售规则,捕获保存规则事件并使用规则名称和所有关联产品更新表。然后在列表页面上检查该表,如果表中存在产品,则显示相应的标签。现在我认为事件是adminhtml_controller_salesrule_prepare_save(不是100%肯定),但我不知道如何从观察者的规则条件中获取sku以保存在新表中。

4 个答案:

答案 0 :(得分:4)

我建议你这样做。当您有产品购物车时,会检查每个规则以计算最终价格和减少量。您可以知道哪些规则适用于购物车的每个项目。在表格sales_flat_quote_item中,您有列applied_rule_ids。我认为您可以通过函数getAllItemsInCart或类似的东西(您必须找到)在php中访问它。执行$item->getAppliedRuleIds()后,您最终可以将规则的名称应用于项目(产品)。

祝你好运:)

编辑:

我再次阅读您的请求,我认为我的回答不符合您的要求。 你的情况更复杂。对于目录页面上的每个产品,您必须应用网站的所有规则。但是Mage_SalesRule_Model_Validator处理期望项目而不是产品...... 如果你有很多规则,这个任务会减慢你的目录,这真的不好!最好的方法是将规则标签的结果缓存在数据库中,可以在表catalog_category_product或......中(甚至更好地自动生成此缓存)。

EDIT2:

其他可能性是在规则创建中有一个新字段,您可以手动设置相关产品(sku)。您可以将此数据保存在表salesrule或新表salesrule_related_sku中。 然后,当您显示目录时,检查sku以及规则是否仍处于活动状态。 这个解决方案是最简单的解决方案: - )

答案 1 :(得分:3)

您可以从getMatchingProductsIds中提取/app/code/core/Mage/CatalogRule/Model/Rule.php,并将其与类别列表页面上显示的草图进行比较。

 $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

以下是获取序列化条件的方法:

$rules = Mage::getResourceModel('salesrule/rule_collection')->load();

foreach ($rules as $rule) {
    $conditions = $rule->getConditionsSerialized();
    var_dump($conditions);
}

EDIT 2

必须有更好的方法来做到这一点。我可以提取数据的唯一方法是反序列化,然后使用foreach遍历每一层。任何人对此都有更好的想法?这有效,但非常草率。

$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);

答案 2 :(得分:0)

规则与网站的所有产品相关联。从数据库的角度来看,没有为特定产品/类别设置规则。对于购物车中的每个产品,Magento将验证您对网站的所有规则。此操作在类Mage_SalesRule_Model_Validator中完成。解决您的请求的唯一方法是从这个类扩展函数过程(至少我认为如此:p)。

答案 3 :(得分:0)

我想要你想要的同样的东西。我希望获得关联的SKUS,类别ID和任何其他条件值,以生成用于Google商家促销的Google Feed。

我已经使用递归函数来到达条件的最后一个子节点并获取它的值。

我正在根据条件的属性值进行检查。如果属性值为空,则向下一步并检查属性值是否存在,如果是,则获取它的值,否则继续下降。

以下是我用来获取值的代码。当两个条件处于同一水平时,这也适用于该案例。

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

根据@seanbreeden的回答,您可以从第一个foreach

调用此函数

它将返回如下结果:

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

P.S。我不是PHP dev。所以,忽略外行样式代码。 :)