I recently needed a very specific shopping cart pricerule that I could not create with the existing logic inthe shopping cart price rules form. Programming to therescue.
What I needed to create was a rule that would allow each itembought after a certain qty to be half price. <wbr>Inmy case the magic qty was two. <wbr>so the rule was:buy two items at full price – get the rest of the qty for that itemat half price. <wbr>The percentage off and step qtyare all controlled via the normal admin rule forms.</wbr></wbr></wbr>
Here’s how I managed to do it for my needs, but you can use thisprocedure to create any type of rule you that you can’t via thedefault logic rules.
There are two spots that normally handlethis job. One for creating the rules in admin and the other forvalidating the shopping cart rules when looking at your cart orchecking out.
- app/code/core/Mage/SalesRule/Model/Validator.php
- app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Actions
The good thing is each of these processes has an event we canobserve to handle our custom code. <wbr>That way wedon’t have to override any files which is always a bonus.</wbr>
The two events we want to observe are:
- adminhtml_block_salesrule_actions_prepareform
- salesrule_validator_process
Starting with your custom module we’ll need a minimum of twofiles to handle this operation.
<config>
<wbr><wbr><span><span><modules<span>></span></span></span><br><wbr><wbr><wbr><wbr><span><span><NameSpace_Module<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><span><span><version<span>></span></span></span>0.1.0<span><span></version<span>></span></span></span><br><wbr><wbr><wbr><wbr><span><span></NameSpace_Module<span>></span></span></span><br><wbr><wbr><span><span></modules<span>></span></span></span><br><br><wbr><wbr><span><span><global<span>></span></span></span><br><wbr><wbr><wbr><wbr><span><span><models<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><span><span><module<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span><class<span>></span></span></span>NameSpace_Module_Model<span><span></class<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><span><span></module<span>></span></span></span><br><wbr><wbr><wbr><wbr><span><span></models<span>></span></span></span><br><wbr><wbr><span><span></global<span>></span></span></span><br><wbr><wbr><span><span><adminhtml<span>></span></span></span><br><wbr><wbr><wbr><wbr><span><span><events<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><span><span><adminhtml_block_salesrule_actions_prepareform<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span><observers<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span><module<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span><class<span>></span></span></span>module/observer<span><span></class<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span><method<span>></span></span></span>prepareForm<span><span></method<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span></module<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span></observers<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><span><span></adminhtml_block_salesrule_actions_prepareform<span>></span></span></span><br><wbr><wbr><wbr><wbr><span><span></events<span>></span></span></span><br><wbr><wbr><span><span></adminhtml<span>></span></span></span><br><wbr><wbr><span><span><frontend<span>></span></span></span><br><wbr><wbr><wbr><wbr><span><span><events<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><span><span><salesrule_validator_process<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span><observers<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span><module<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span><class<span>></span></span></span>module/observer<span><span></class<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span><method<span>></span></span></span>process<span><span></method<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span></module<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span><span></observers<span>></span></span></span><br><wbr><wbr><wbr><wbr><wbr><wbr><span><span></salesrule_validator_process<span>></span></span></span><br><wbr><wbr><wbr><wbr><span><span></events<span>></span></span></span><br><wbr><wbr><span><span></frontend<span>></span></span></span><br><span><span></config<span>></span></span></span></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
classNameSpace_Module_Model_Observer
<wbr><wbr><span>extends</span> Mage_Core_Model_Abstract<br><span>{</span><br><wbr><wbr><span>//<wbr>{{{ prepareForm()</wbr></span><br><br><wbr><wbr><br><wbr><wbr><span>public</span> <span>function</span>prepareForm<span>(</span>Varien_Event_Observer<span>$observer</span><span>)</span><br><wbr><wbr><span>{</span><br><wbr><wbr><wbr><wbr><span>$form</span> <span>=</span> <span>$observer</span><span>-></span><span>getForm</span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$simpleAction</span><span>=</span> <span>$form</span><span>-></span><span>getElement</span><span>(</span><span>'simple_action'</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$values</span> <span>=</span> <span>$simpleAction</span><span>-></span><span>getValues</span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$values</span><span>[</span><span>]</span> <span> =</span><a href="http://www.php.net/array"><span>array</span></a><span>(</span><br><wbr><wbr><wbr><wbr><wbr><wbr><span>'value'</span> <span>=></span> <span> 'new_rule'</span><span>,</span><br><wbr><wbr><wbr><wbr><wbr><wbr><span>'label'</span> <span>=></span> <span> 'NewRule'</span><span>,</span><br><wbr><wbr><wbr><wbr><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$simpleAction</span><span>-></span><span>setValues</span><span>(</span><span>$values</span><span>)</span><span>;</span><br><wbr><wbr><span>}</span><br><br><wbr><wbr><span>//<wbr>}}}</wbr></span><br><wbr><wbr><span>//<wbr>{{{ process()</wbr></span><br><br><wbr><wbr><br><wbr><wbr><span>public</span> <span>function</span>process<span>(</span>Varien_Event_Observer <span>$observer</span><span>)</span><br><wbr><wbr><span>{</span><br><wbr><wbr><wbr><wbr><span>$qty</span> <wbr><wbr><span>=</span> <span>$observer</span><span>-></span><span>getQty</span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$rule</span><wbr><span>=</span> <span>$observer</span><span>-></span><span>getRule</span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$item</span><wbr><span>=</span> <span>$observer</span><span>-></span><span>getItem</span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$result</span> <span>=</span> <span>$observer</span><span>-></span><span>getResult</span><span>(</span><span>)</span><span>;</span><br><br><wbr><wbr><wbr><wbr><span>$x</span> <span>=</span> <span>$rule</span><span>-></span><span>getDiscountStep</span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$y</span> <span>=</span> <span>$rule</span><span>-></span><span>getDiscountAmount</span><span>(</span><span>)</span><span>;</span><br><br><wbr><wbr><wbr><wbr><span>if</span> <span>(</span><span>!</span><span>$x</span><span>)</span> <span>{</span><br><wbr><wbr><wbr><wbr><wbr><wbr><span>return</span><span>;</span><br><wbr><wbr><wbr><wbr><span>}</span><br><br><wbr><wbr><wbr><wbr><span>$full</span> <span>=</span> <span>$discount</span> <span>=</span> <span>0</span><span>;</span><br><wbr><wbr><wbr><wbr><span>while</span> <span>(</span><span>$full</span> <span> +</span> <span>$discount</span> <span><</span> <span>$qty</span><span>)</span> <span> {</span><br><wbr><wbr><wbr><wbr><wbr><wbr><span>if</span> <span>(</span><span>++</span><span>$full</span> <span><</span> <span>$x</span><span>)</span> <span>{</span><br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><span>continue</span><span>;</span><br><wbr><wbr><wbr><wbr><wbr><wbr><span>}</span><br><br><wbr><wbr><wbr><wbr><wbr><wbr><span>++</span><span>$discount</span><span>;</span><br><wbr><wbr><wbr><wbr><span>}</span><br><br><wbr><wbr><wbr><wbr><span>$itemPrice</span><wbr><span>=</span> <span>$item</span><span>-></span><span>getDiscountCalculationPr<wbr>ice</wbr></span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>if</span> <span>(</span><span>$itemPrice</span> <span> !==</span> <span>null</span><span>)</span> <span>{</span><br><wbr><wbr><wbr><wbr><wbr><wbr><span>$baseItemPrice</span> <span>=</span><span>$item</span><span>-></span><span>getBaseDiscountCalculati<wbr>onPrice</wbr></span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>}</span> <span>else</span> <span>{</span><br><wbr><wbr><wbr><wbr><wbr><wbr><span>$itemPrice</span> <span>=</span><span>$item</span><span>-></span><span>getCalculationPrice</span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><wbr><wbr><span>$baseItemPrice</span> <span>=</span><span>$item</span><span>-></span><span>getBaseCalculationPrice</span><span>(</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>}</span><br><br><wbr><wbr><wbr><wbr><span>$rulePercent</span><span>=</span> <a href="http://www.php.net/min"> <span>min</span></a><span>(</span><span>100</span><span>,</span> <span>$rule</span><span>-></span><span>getDiscountAmount</span><span>(</span><span>)</span><span>)</span><span>;</span><br><br><wbr><wbr><wbr><wbr><span>$discountAmount</span><wbr><wbr><span>=</span><span>(</span><span>$discount</span><span>*</span> <span>$itemPrice</span><span>-</span> <span>$item</span><span>-></span><span>getDiscountAmount</span><span>(</span><span>)</span><span>)</span><span>*</span> <span>$rulePercent</span><span>/</span> <span>100</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$baseDiscountAmount</span><span>=</span> <span>(</span><span>$discount</span> <span>*</span> <span>$baseItemPrice</span> <span>-</span> <span>$item</span><span>-></span><span>getBaseDiscountAmount</span><span>(</span><span>)</span><span>)</span><span>*</span> <span>$rulePercent</span><span>/</span> <span>100</span><span>;</span><br><br><wbr><wbr><wbr><wbr><span>$result</span><span>-></span><span>setDiscountAmount</span><span>(</span><span>$discountAmount</span><span>)</span><span>;</span><br><wbr><wbr><wbr><wbr><span>$result</span><span>-></span><span>setBaseDiscountAmount</span><span>(</span><span>$baseDiscountAmount</span><span>)</span><span>;</span><br><wbr><wbr><span>}</span><br><br><wbr><wbr><span>//<wbr>}}}</wbr></span><br><span>}</span></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>