2012-02-28 1 views
4

Я хочу проверить, есть ли промоция продвижения продукта, а затем наклейте рекламную этикетку на этом продукте на странице списка категорий. Но я не знаю, как пройти через все правила корзины покупок и получить продукты/категории, связанные с каждым правилом.Показать список правил и категорий продуктов для покупок, связанных с каждым правилом

РЕДАКЦИЯ

Благодаря seanbreeden, но я не могу вытащить SKUs из $conditions. 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 Как предложил Алаксандр, я не использую неэтериализованный подход. Я делаю это, как это сейчас:

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

А затем проверять в странице списка, если ы совпадает в пределах $ SKUs массива затем показать этикетку. Но опять же есть ограничение с этим подходом. Я думаю о другом подходе (я не уверен, что это возможно). Думая о создании новой таблицы (чтобы сохранить продукты правил продаж). Всегда сохраняйте правило продаж, ловите событие правила сохранения и обновите таблицу с именем правила и всеми связанными продуктами. Затем на странице списка проверьте, что таблица, если продукты существуют в таблице, показывает соответствующую метку. Теперь я думаю, что событие - adminhtml_controller_salesrule_prepare_save (не на 100% уверен), но я не знаю, как получить sku из условия правила в наблюдателе, чтобы сохранить в новой таблице.

+0

Вы должны быть очень осторожны с несериализацией данных о правилах. Вы должны проверить правило для каждого из них, и это может быть очень сложным. Например, правило может быть, если sku является «sku001», но может также быть sku не «sku001». И есть также сочетание правил и так далее. Я не думаю, что вы получите хорошее направление ... – Alexandre

+0

Спасибо Alexandre. Я подумал об этом, поэтому теперь не использую unserialized. Я обновил вопрос. См. Edit2 – Hum

+1

Вы также не можете сделать это. Вы должны проверить правило для каждого продукта. Но, честно говоря, я думаю, что это слишком сумасшествие! Потому что тогда у вас может быть много ярлыков для одного продукта. Захват сохранения события будет недостаточным, потому что есть возможная дата окончания вашего правила. – Alexandre

ответ

4

Я предлагаю вам сделать это следующим образом. Когда у вас есть продукт в корзину, все правила проверяются для расчета окончательной цены и сокращения.Вы можете узнать, какие правила применяются к каждому элементу вашей корзины. В таблице sales_flat_quote_item у вас есть столбец applied_rule_ids. Я думаю, вы можете получить доступ к этому в php, с помощью функции getAllItemsInCart или что-то вроде этого (вам нужно узнать). После того, как вы сделаете $item->getAppliedRuleIds() и, наконец, вы можете получить название правила применительно к элементу (продукту).

Удачи :)

Edit:

Я прочитал еще раз вашу просьбу, и я думаю, что мой ответ не соответствует вашему запросу. Ваш случай еще сложнее. Для каждого продукта на странице вашего каталога вы должны применять все правила своего веб-сайта. Но Mage_SalesRule_Model_Validator процесс ожидает товар, а не продукт ... Если у вас есть много правил, эта задача замедлит ваш каталог, и это действительно не хорошо! Лучше всего было бы кэшировать этот результат метки правил в базе данных, может быть в таблице catalog_category_product или ... (и даже лучше создать этот кеш автоматически).

Edit2:

Другая возможность будет иметь новое поле в создании правил, где вы установили вручную соответствующие продукты (ы). Эти данные сохраняются в таблице salesrule или в новой таблице salesrule_related_sku. Затем, когда вы показываете каталог, который вы проверяете на sku, и если правило все еще активно. Это решение было бы самым простым :-)

+0

Имеют смысл. Но я думаю о другом подходе (не знаю, как это выполнить). Думая о создании новой таблицы (чтобы сохранить продукты правил продаж). Всегда сохраняйте правило продаж, ловите событие правила сохранения и обновляйте таблицу с именем правила и всеми связанными продуктами.Затем на странице списка проверьте, что таблица, если продукты существуют в таблице, показывает соответствующую метку. Теперь я думаю, что это adminhtml_controller_salesrule_prepare_save (не на 100% уверен), но я не знаю, как получить sku из условия правила в наблюдателе, чтобы сохранить в новой таблице. – Hum

+0

Я использую adminhtml_controller_salesrule_prepare_save событие. Как получить идентификатор правила, которое я пытаюсь сохранить? Если я могу получить здесь идентификатор, я могу сохранить все связанные с ним skus в новой таблице, а затем может сопоставляться с этой таблицей на странице списка. – Hum

+0

Я создал новое поле в промо-правилах как $ fldSet-> addField ('promo_skus', 'text', array ( 'name' => 'promo_skus', 'label' => Mage :: helper ('rules') -> __ ('Promo SKUs'), 'note' => Mage :: helper ('rules') -> __ ('Список разделенных запятыми идентификаторов sku'), ), 'discount_amount' ) ; , захватив событие adminhtml_block_salesrule_actions_prepareform. Qhen я добавляю skus в кодировках, я хочу, чтобы авто заполнить это поле с ними skus. Не знаю, как это сделать. – Hum

0

Правила связаны со всем продуктом для веб-сайта. Нет правил, установленных для определенных продуктов/категорий с точки зрения базы данных. Для каждого продукта в корзине Magento будет проверять все правила, которые у вас есть для веб-сайта. Эта операция выполняется в классе Mage_SalesRule_Model_Validator. Единственный способ решить ваш запрос - расширить функциональный процесс из этого класса (по крайней мере, я так думаю: p).

+0

Позвольте мне объяснить немного больше. Скажем, я создаю правило BOGOF и в состоянии добавляю только 3 продукта (prod1, prod2, prod3). Это означает, что BOGOF применяется только к этим трем продуктам. На странице списка категорий, скажем, у меня есть 10 продуктов, но я хочу показать ярлык BOGOF только на prod1, prod2 и prod3. Надеюсь, что его бит станет более ясным. – Hum

2

Вы можете потянуть getMatchingProductsIds от /app/code/core/Mage/CatalogRule/Model/Rule.php и сравнить их с skus, отображаемыми на странице списка категорий.

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

НТН

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); 
+0

Я использую правила цен в корзине, а не правила каталога. Просто проверенный /app/code/core/Mage/SalesRule/Model/Rule.php, он не имеет никакой функции GetMatchingProductsIds. – Hum

+0

Я отредактировал этот код. Посмотрите, поможет ли вам идти в правильном направлении. Вы должны пропустить итерацию, чтобы вытащить Skus, чтобы их можно было сравнить в вашем 'list.phtml' – seanbreeden

+0

Спасибо seanbreeden, но я изо всех сил пытаюсь получить skus. Я обновил вопрос. Пожалуйста, совет – Hum