I am using two shipping method Free shipping and flat rate shipping . Here is two condition when a user try to buy "apple" from state "abc" then flat rate shipping available for this user.and another user try to buy same product "apple" from state "xyz" then free shipping is available for this user. I know it can be done by using observer but unable to find any exact solution please help me thanks.
2 Answers
You need to rewrite or copy to the local code pool the following class Mage_Shipping_Model_Shipping
To rewrite:
class Company_Module_Model_Shipping_Shipping extends Mage_Shipping_Model_Shipping
{
public function collectCarrierRates($carrierCode, $request)
{
if (!$this->_isAvailable($carrierCode, $request)) {
return $this;
}
return parent::collectCarrierRates($carrierCode, $request);
}
/**
* @param string $carrierCode
* @param Varien_Object $request
* @return bool
*/
protected function _isAvailable($carrierCode, $request)
{
$regionCode = $request->getDestRegionCode();
switch ($carrierCode) {
case 'flatrate':
if ($regionCode == 'xyz') {
return false;
}
break;
case 'freeshipping':
if ($regionCode == 'abc') {
return false;
}
break;
}
return true;
}
}
If you want to copy the following class to the local code pool, find the method collectCarrierRates
and add the following lines before the core code.
if (!$this->_isAvailable($carrierCode, $request)) {
return $this;
}
Add new method _isAvailable
, you can use the same method as indicated above for the rewriting case.
You can move the hardcoded region dependency to config and make it user friendly.
As far as I can see there are no events in shipping (in payment there is payment_method_is_active
). There are some on checkout level but I don't know appropriate for shipping. So I can suggest you to copy app/code/core/Mage/Shipping/Model/Carrier/Freeshipping.php and app/code/core/Mage/Shipping/Model/Carrier/Flatrate.php to app/code/local and to change them. In Flatrate.php -> public function collectRates
change first line in it:
if (!$this->getConfigFlag('active')) {
to
if (!$this->getConfigFlag('active') || $request->getDestRegionCode() == 'xyz') {
and in Freeshipping.php -> public function collectRates
change again this:
if (!$this->getConfigFlag('active')) {
to
if (!$this->getConfigFlag('active') || $request->getDestRegionCode() == 'abc') {
or something like this. Another solution is to add new setting for region/state in the configuration of the methods and then to add a check for it in app/code/core/Mage/Shipping/Model/Carrier/Abstract.php -> public function checkAvailableShipCountries
.