Woo 2.6 introduced Shipping Zones – and with that we can play with simple PHP (and JQuery) to accomplish lots of “advanced” shipping rules, such as local pickup.

This time, I’ve tested a snippet to add a dropdown to the billing section where users go choose the pickup destination. As a result, the shipping address is automatically populated, and so is the shipping method. What do you think?

1. Advanced Local Pickup – Shipping Zones/Methods Setup

The very first thing you need to do is setup the WooCommerce shipping zones. In this case, each zone will correspond to a Local Pickup Address (e.g. shop #1, shop #2, etc).

In the following example, I’ve added 2 “zones/shops”in Australia, state = “Australian Capital Territory” and 2 specific postcodes.

Each zone has its unique a shipping method (Local Pickup) with cost = $0:

Advanced Local Pickup – WooCommerce Shipping Zones

2. Advanced Local Pickup – PHP/JQuery Snippet

Now that the zones are correctly setup, here comes the hard part. The following is a tested snippet that – however – requires a lot of improvements, so if you spot anything or wish to contribute leave a comment below.


/**
 * @snippet       Advanced Local Pickup - WooCommerce
 * @how-to        Get CustomizeWoo.com FREE
 * @source        https://businessbloomer.com/?p=21534
 * @author        Rodolfo Melogli
 * @compatible    WC 3.4.2
 */

//////////////////////////////////////////////////////////
// 1. New select field @ billing section

add_filter( 'woocommerce_checkout_fields' , 'bbloomer_display_pickup_locations' );

function bbloomer_display_pickup_locations( $fields ) {

$fields['billing']['pick_up_locations'] = array(
   	'type'     => 'select',
	'options'  => array(
        'option_1' => 'Select...',
	'option_2' => 'Melbourne Road Shop',
        'option_3' => 'Perth Road Shop'),
	'label'     => __('Pick Up Location', 'woocommerce'),
	'class'     => array('form-row-wide'),
    	'clear'     => true
     );

return $fields;

}

//////////////////////////////////////////////////////////
// 2. Field to show only when country == Australia

add_action( 'woocommerce_after_checkout_form', 'bbloomer_conditionally_hide_show_pickup', 5);

function bbloomer_conditionally_hide_show_pickup() {
  
  ?>
	<script type="text/javascript">
		jQuery('select#billing_country').live('change', function(){
			
			var country = jQuery('select#billing_country').val();
			
			var check_country = new Array(<?php echo '"AU"'; ?>);
			if (country && jQuery.inArray( country, check_country ) >= 0) {
				jQuery('#pick_up_locations_field').fadeIn();
			} else {
				jQuery('#pick_up_locations_field').fadeOut();
				jQuery('#pick_up_locations_field input').val('');
			}
			
		});
	</script>
	<?php
	  
}

//////////////////////////////////////////////////////////
// 3. "Ship to a different address" opened by default

add_filter( 'woocommerce_ship_to_different_address_checked', '__return_true' );

//////////////////////////////////////////////////////////
// 4. Change shipping address when local pickup location changes

add_action( 'woocommerce_after_checkout_form', 'bbloomer_checkout_update_pickup_address', 10);

function bbloomer_checkout_update_pickup_address() {
        
  		?>
		<script type="text/javascript">

		jQuery('select#pick_up_locations').live('change', function(){

		var location = jQuery('select#pick_up_locations').val();
		
		if (location == 'option_2') {
		
		jQuery('select#shipping_country').val('AU').change();
		jQuery('select#shipping_state').val('ACT').change();
		jQuery('#shipping_city_field input').val('Sidney');
		jQuery('#shipping_address_1_field input').val('Melbourne Road');
		jQuery('#shipping_postcode_field input').val('34500');
		jQuery(".shipping_address input[id^='shipping_']").prop("disabled", true);
		jQuery(".shipping_address select[id^='shipping_']").prop("disabled", true);
		
		} else if (location == 'option_3') {

		jQuery('select#shipping_country').val('AU').change();
		jQuery('select#shipping_state').val('ACT').change();
		jQuery('#shipping_city_field input').val('Sidney');
		jQuery('#shipping_address_1_field input').val('Perth Road');
		jQuery('#shipping_postcode_field input').val('79200');
		jQuery(".shipping_address input[id^='shipping_']").prop("disabled", true);
		jQuery(".shipping_address select[id^='shipping_']").prop("disabled", true);

                } else {

		jQuery(".shipping_address input[id^='shipping_']").prop("disabled", false);
		jQuery(".shipping_address select[id^='shipping_']").prop("disabled", false);

		}
		
		});

		</script>
		<?php
                     
}

As a result, once you select the correct local pickup address form the billing section, you should automatically get the correct shipping method in the checkout:

Advanced Local Pickup – WooCommerce Checkout

Did you test this? Do you have anything useful to add? Let me know!

Share:

Leave a Reply