You can also do it via the collecttotals hook. Not in front of a pc right now, so will update with example in a few hours. An example is in the config.xml of the core rules module.
The information as promised:
In your module config.xml, in the <global>
tag you can place the following, which will allow you to call your model everytime magento does a call to ->collecttotals()
I actually use this in my own gifting module to effect gifting, based on the cart subtotal.
<sales>
<quote>
<totals>
<giftpromo>
<class>giftpromo/promo_gift</class>
<after>subtotal</after>
<before>tax_subtotal,shipping</before>
</giftpromo>
</totals>
</quote>
</sales>
This thus calls my model which is defined as such (added so you can see the class inheritance to make this work):
class ProxiBlue_GiftPromo_Model_Promo_Gift extends Mage_Sales_Model_Quote_Address_Total_Abstract
{
}
In this class you need a public method called collect
, and to this core will pass the current shipping address object. From this you can get the current quote object.
My method is as such:
public function collect(Mage_Sales_Model_Quote_Address $address)
{
parent::collect($address);
$quote = $address->getQuote();
$store = Mage::app()->getStore($quote->getStoreId());
if (!count($quote->getAllVisibleItems())) {
return $this;
}
$this->_validator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $quote->getCouponCode());
$this->_validator->processGiftRules($address);
return $this;
}
Obviously my method references other objects not part of the answer, but it would give you the general idea of how to use the collect totals.
For a core based example, see the class Mage_SalesRule_Model_Quote_Freeshipping
Have a peek in the core Sales module's config.xml, and you will see other examples of how to set the totals hook.
For completeness, here is that code:
<sales>
<quote>
<totals>
<freeshipping>
<class>salesrule/quote_freeshipping</class>
<after>subtotal</after>
<before>tax_subtotal,shipping</before>
</freeshipping>
<discount>
<class>salesrule/quote_discount</class>
<after>subtotal,shipping</after>
<before>grand_total</before>
</discount>
</totals>
<nominal_totals>
<nominal_discount>
<class>salesrule/quote_nominal_discount</class>
<sort_order>550</sort_order>
</nominal_discount>
</nominal_totals>
</quote>
</sales>
Using the collect totals hook (right terminology?) you can easily run some custom code whenever the cart/quote changes totals.
Hope this helps.