Generally, the Mage_SalesRule_Model_Rule_Condition_Address model is responsible for validating a customer’s address and adding conditions in the SalesRule.
Say, if you want to create a shipping cart price rule for all the European countries, you need to check whether the country is a part of the EU or not. That can be done by means of rewrite.
I’ve created a module for this task, which will hopefully help you do that in a couple of clicks.
The file that registers the module is the system is located here: app/etc/modules/MageWorx_EuRules.xml:
<config> <modules> <MageWorx_EuRules> <active>true</active> <codePool>community</codePool> <extension_name><![CDATA[EU Extended Rule]]></extension_name> </MageWorx_EuRules> </modules> </config>
The locale file is: app/locale/en_US/MageWorx_EuRules.csv:
"Europe Union Country","Europe Union Country"
And this is the configuring file of the module app/code/community/MageWorx/EuRules/etc/config.xml , where you call the rewrite of the salesrule/rule_condition_address model:
<config> <modules> <MageWorx_EuRules> <version>1.0.0</version> </MageWorx_EuRules> </modules> <global> <models> <mageworx_eurules> <class>MageWorx_EuRules_Model</class> </mageworx_eurules> <salesrule> <rewrite> <rule_condition_address>MageWorx_EuRules_Model_Rule_Condition_Address</rule_condition_address> </rewrite> </salesrule> </models> <helpers> <mageworx_eurules> <class>MageWorx_EuRules_Helper</class> </mageworx_eurules> </helpers> </global> </config>
Note that the Helper stays empty. You just need it, as it is one of Magento requirements when implementing an operation of such a type: app/code/community/MageWorx/EuRules/Helper/Data.php:
class MageWorx_EuRules_Helper_Data extends Mage_Core_Helper_Abstract { }
And this is the model with the main rewrite: app/code/community/MageWorx/EuRules/Model/Rule/Condition/Address.php :
class MageWorx_EuRules_Model_Rule_Condition_Address extends Mage_SalesRule_Model_Rule_Condition_Address { public function loadAttributeOptions() { $attributes = parent::loadAttributeOptions()->getAttributeOption(); $additionalAttributes = array( 'eu' => Mage::helper('mageworx_eurules')->__('Europe Union Country'), ); $attributes = array_merge($attributes, $additionalAttributes); $this->setAttributeOption($attributes); return $this; } public function getInputType() { switch ($this->getAttribute()) { case 'base_subtotal': case 'weight': case 'total_qty': return 'numeric'; case 'shipping_method': case 'payment_method': case 'country_id': case 'region_id': case 'eu': return 'select'; } return 'string'; } public function getValueElementType() { switch ($this->getAttribute()) { case 'shipping_method': case 'payment_method': case 'country_id': case 'region_id': case 'eu': return 'select'; } return 'text'; } public function getValueSelectOptions() { if (!$this->hasData('value_select_options')) { switch ($this->getAttribute()) { case 'country_id': $options = Mage::getModel('adminhtml/system_config_source_country') ->toOptionArray(); break; case 'region_id': $options = Mage::getModel('adminhtml/system_config_source_allregion') ->toOptionArray(); break; case 'shipping_method': $options = Mage::getModel('adminhtml/system_config_source_shipping_allmethods') ->toOptionArray(); break; case 'payment_method': $options = Mage::getModel('adminhtml/system_config_source_payment_allmethods') ->toOptionArray(); break; case 'eu': $options = Mage::getModel('adminhtml/system_config_source_yesno') ->toOptionArray(); break; default: $options = array(); } $this->setData('value_select_options', $options); } return $this->getData('value_select_options'); } /** * Validate Address Rule Condition * * @param Varien_Object $object * @return bool */ public function validate(Varien_Object $object) { $address = $object; if (!$address instanceof Mage_Sales_Model_Quote_Address) { if ($object->getQuote()->isVirtual()) { $address = $object->getQuote()->getBillingAddress(); } else { $address = $object->getQuote()->getShippingAddress(); } } // Eu check start if ('eu' == $this->getAttribute() && !$address->getEu()) { $this->setValue(boolval($this->getValue())); $euCountries = explode(',', Mage::getStoreConfig('general/country/eu_countries')); if (empty($euCountries)) { $euCountries = array(); } $isEu = in_array($address->getCountry(), $euCountries); $address->setEu($isEu); } // Eu check end return parent::validate($address); } }
Below is the explanation of what our modification of the main methods have done:
loadAttributeOptions – now it adds the attribute of the country/ selection of countries. For example, when creating a shopping cart rule for European Union countries, it should be ‘eu‘. This is the code attribute that will be used every time when a customer’s address is passing validation.
getInputType, getValueElementType, getValueSelectOptions – sets the input type as select for a newly created attribute. It lets you use the standard yes/no model and avoid entering ‘1’ (or something else) when defining the value. Also, this method will save you time on entering extra variables (e.g. equals or greater than).
validate – before calling out the standard validation, our modified validate method fills in a customer address with the required value (eu in our case). In order to obtain it, we use the countries from the Admin panel chosen as counties of the European Union and compare them with the current customer’s country. If the county is a part of EU, we set into the address the eu value in TRUE.
The condition for this example will look like that:
Next, we create he corresponding rule and run the check. In my case customers from the EU get a 10% discount (the rule is named – EU RULE).
The first sceen-shot is for the USA, the second one if for the UK:
Hope this will help you in creating custom shopping cart price rule.
Questions? Feel free to add them in the comments section below.