Magento – Closest Promo Rule

Task : Display a promotional message, when user visits the cart, to promote more purchases on the site, by providing cart discounts.

Solution:

Step-1: Create Module, I named it as ‘Promotions’

Step-2: Add Observer to ‘sales_quote_collect_totals_after’, as follows,

<sales_quote_collect_totals_after>
<observers>
<promotions_message>
<type>singleton</type>
<class>Maniacs_Promotions_Model_Observer_Promo_Message</class>
<method>addNotice</method>
</promotions_message>
</observers>
</sales_quote_collect_totals_after>

Step-3: Create observer class & method

class Maniacs_Promotions_Model_Observer_Promo_Message {
public function addNotice(Varien_Event_Observer $observer) {
$customer = Mage::getSingleton('customer/session')->getCustomer();
$group_id=Mage_Customer_Model_Group::NOT_LOGGED_IN_ID;
if(Mage::helper('customer')->isLoggedIn()) {
$group_id=$customer->getGroupId();
}
$quote = Mage::getSingleton('checkout/session')->getQuote();
$applied_rules = $quote->getAppliedRuleIds();
$attr_match = sprintf('%%%s%%', substr(serialize(array('attribute' => 'base_subtotal')), 5, -1));
$type_match = sprintf('%%%s%%', substr(serialize(array('type' => 'salesrule/rule_condition_address')), 5, -1));
$opr_grt_match = sprintf('%%%s%%', substr(serialize(array('operator' => '>')), 5, -1));
$opr_grteq_match = sprintf('%%%s%%', substr(serialize(array('operator' => '>=')), 5, -1));
$collection = Mage::getResourceModel('salesrule/rule_collection')
->addWebsiteGroupDateFilter(Mage::app()->getWebsite()->getId(), $group_id)
->addFieldToFilter('main_table.coupon_type', Mage_SalesRule_Model_Rule::COUPON_TYPE_NO_COUPON)
->addFieldToFilter('main_table.simple_action', 'custom_promo_cart') //refers to custom action we have added for promotions, can we be ignored
->addFieldToFilter('main_table.conditions_serialized', array(
'like' => $attr_match,
))
->addFieldToFilter('main_table.conditions_serialized', array(
'like' => $type_match,
))
->addFieldToFilter('main_table.conditions_serialized', array(array(
'like' => $opr_grt_match
),array(
'like' => $opr_grteq_match
)))
;
//exclude rules those are already applicable
if($applied_rules) {
$collection->addFieldToFilter('main_table.rule_id',array(
'nin' => explode(",", $applied_rules),
));
}
$rules = $collection->setOrder('main_table.sort_order', Varien_Data_Collection::SORT_ORDER_ASC)->load();
//find sub-total
$totals = $quote->getTotals();
$subtotal=$totals["subtotal"]->getValue();
$offset =0;
foreach ($rules as $rule) {
$conditions = $rule->getConditions();
$conditions = $rule->getConditions()->asArray();
foreach( $conditions['conditions'] as $_conditions ) {
$value = $this->_getConditionVal($_conditions);
if($subtotal < $value && ($offset == 0 || $offset > $value)) {
$offset = $value;
}
}
}
if($offset && $subtotal) {
Mage::getSingleton('checkout/session')->addNotice('Make purchase for another '.Mage::helper('core')->currency($offset-$subtotal,true,false).' and get discounts');
}
return $this;
}
protected function _getConditionVal($condition) {
if(array_key_exists('conditions', $condition)) {
return $this->_getConditionVal($condition['conditions']);
} elseif($condition['type'] == "salesrule/rule_condition_address"
&& $condition['attribute'] == "base_subtotal"
&& in_array($condition['operator'],array(">", ">="))) {
return $condition['value'];
}
return 0;
}
}

Let us know your feedback, if there is scope for improvements.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s