For a specific product I've got a Shopping Cart Rule which makes shipping for it free. It would be logical to not show shipping information and bypass shipping method selection for such product. Is there any easy way to do this?
This can be easily accomplished with an extension module.
/app/etc/modules/YourCompany_SkipShipping.xml
<?xml version="1.0"?>
<config>
<modules>
<YourCompany_SkipShipping>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Checkout />
</depends>
</YourCompany_SkipShipping>
</modules>
</config>
/app/code/local/YourCompany/SkipShipping/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<YourCompany_SkipShipping>
<version>0.0.1</version>
</YourCompany_SkipShipping>
</modules>
<frontend>
<routers>
<checkout>
<modules before="Mage_Checkout">YourCompany_SkipShipping<modules>
</checkout>
</routers>
</frontend>
</config>
/app/code/local/YourCompany/SkipShipping/controllers/OnepageController.php
<?php
include "Mage/Checkout/controller/OnepageController.php"
class YourCompany_SkipShippingMethod_OnepageController
extends Mage_Checkout_OnepageController
{
public function saveBillingAction()
{
if ($this->_expireAjax()) {
return;
}
if ($this->getRequest()->isPost()) {
$data = $this->getRequest()->getPost('billing', array());
$customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
if (isset($data['email'])) {
$data['email'] = trim($data['email']);
}
$result = $this->getOnepage()->saveBilling($data, $customerAddressId);
if (!isset($result['error'])) {
/* check quote for virtual */
if ($this->getOnepage()->getQuote()->isVirtual()) {
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
} elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
$method = $this->getAutoShippingMethod($data, $customerAddressId);
if (!empty($method)) {
$result = $this->getOnepage()->saveShippingMethod($method);
if(!$result) {
Mage::dispatchEvent('checkout_controller_onepage_save_shipping_method', array(
'request'=>$this->getRequest(),
'quote'=>$this->getOnepage()->getQuote()
));
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
}
} else {
$result['goto_section'] = 'shipping_method';
$result['update_section'] = array(
'name' => 'shipping-method',
'html' => $this->_getShippingMethodsHtml()
);
$result['allow_sections'] = array('shipping');
$result['duplicateBillingInfo'] = 'true';
}
} else {
$result['goto_section'] = 'shipping';
}
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
}
public function saveShippingAction()
{
if ($this->_expireAjax()) {
return;
}
if ($this->getRequest()->isPost()) {
$data = $this->getRequest()->getPost('shipping', array());
$customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
$result = $this->getOnepage()->saveShipping($data, $customerAddressId);
if (!isset($result['error'])) {
$method = $this->getAutoShippingMethod($data, $customerAddressId);
if (!empty($method)) {
if(!$result) {
Mage::dispatchEvent('checkout_controller_onepage_save_shipping_method', array(
'request'=>$this->getRequest(),
'quote'=>$this->getOnepage()->getQuote()
));
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
}
} else {
$result['goto_section'] = 'shipping_method';
$result['update_section'] = array(
'name' => 'shipping-method',
'html' => $this->_getShippingMethodsHtml()
);
}
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
}
public function getAutoShippingMethod($data, $customerAddressId)
{
// This is where you put your code to process the cart/order for orders that can auto-select shipping method
// For now, skip
return '';
}
}
I'll leave the specifics of how you check the shipping method to you, but if you cannot figure it out, post a comment and I'll add that as well.
NB: All examples are based on Magento 1.5