You are here

Dependent Shipping

Commerce flat rate allows for easy shipping methods, like 'Pickup at store'.
But letting your customer fill in a shipping address when he is going to pick it up at store is not exactly what you call usability.
You could disable that pane in checkout settings but when you also have other shipping options, you probably want something more like this:

This can be done easily because the shipping service pane is already handled via ajax when selecting an shipping method.
The code to that in a custom module:

<?php
function dependent_shipping_form_commerce_checkout_form_checkout_alter(&$form, &$form_state, $form_id) {
  
 
// Get the shipping service on witch we need to hide.
 
$shipping_service = variable_get('dependent_shipping_service', 'pickup_at_store');

 
// Set a new validator to allow to update the values before submitting.
 
$form['commerce_shipping']['#element_validate'] = array('dependent_shipping_validate');


  if(isset(
$form_state['values']['commerce_shipping']['shipping_service'])) {
    if(
$form_state['values']['commerce_shipping']['shipping_service']
        !=
$shipping_service) {
     
// Adding the shipping information field to the service details container.
     
$form['commerce_shipping']['service_details']['customer_profile_shipping'] =
     
$form['customer_profile_shipping'];
    }
    else {
     
// We need to unset it, because people tend to change their minds sometimes.
     
unset($form['commerce_shipping']['service_details']['customer_profile_shipping']);
    }

  }
  else {
   
// If our service is the default value we need to show the shipping pane right away.
   
if ($form['commerce_shipping']['shipping_service']['#default_value']
        !=
$shipping_service) {
     
$form['commerce_shipping']['service_details']['customer_profile_shipping']
        =
$form['customer_profile_shipping'];
    }
   
// We don't want the shipping pane to show at its original place.
   
$form['customer_profile_shipping']['#access'] = false;
  }

}

function
dependent_shipping_validate($element, &$form_state, $form) {

 
$shipping_service = variable_get('dependent_shipping_service', 'pickup_at_store');
 
 
// If there is no available shipping address we use the one from billing.
 
if($form_state['values']['commerce_shipping']['shipping_service']
      ==
$shipping_service) {
   
$address = $form_state['values']['customer_profile_billing']
      [
'commerce_customer_address']['und'][0];
   
$address['element_key'] = $form_state['values']['customer_profile_shipping']
      [
'commerce_customer_address']['und'][0]['element_key'];
   
$form_state['values']['customer_profile_shipping']
      [
'commerce_customer_address']['und'][0] = $address;
  }
 
// Set the shipping back to it original place in the form
 
else {
   
$form['customer_profile_shipping'] =
     
$form['commerce_shipping']['service_details']['customer_profile_shipping'];
  }
 
}
?>