Friday 4 July 2014

Add check out time validation in WooCommerce - for delivery or otherwise

Share |

Adding a shipping delivery time check to WooCommerce Plugin - Server side validation


Suppose an online store wants to restrict delivery timings of its online goods. not just in terms of the days that delivery is available, but down to the timings. For example, if catering company ABC only delivers from 8am to 5pm on weekdays, and 4pm to 10pm on weekends.

The extension I happily bought seemed to have many good features. till I realized that it did not have a time slot option. It was disappointing at first, but I thought what the heck, I will hack it myself. So my journey begins.

The date picker extension uses a typical date time picker from jQuery in the front end. So I thought, since its a hack, lets modify this.

jQuery date picker, with Mondays disabled.

Looking in the javascript files, I found just the code that validates this date picker. I realized I would need to add logic to validate the time chosen according to the day of the week, followed by updates to the UI. After spending quite some time (longer than I expected) toying with the script, I managed to do something like this in pseudo code:


if (its a weekday & user selected delivery time between 8am-5pm)
    accept input, otherwise throw validation error and disable the Done button.
else if (its a weekend & user selected delivery time between 4pm to 10pm)
    accept input, otherwise also throw validation error
and disable the Done button.

Then I updated the UI to display the validation as a red error text, and disabled the "Done" button.

I then thought all was good, but well the UI came back to haunt me with issues. For example, the date picker does not work in certain browsers that don't support it for whatever reason, and the user can still enter the wrong time manually into the text field.

In the end, its back to server side validation that saves the day.

jQuery date picker, with validation message and disabled "Done" button

To do server side validation:

 

Create a WooCommerce child theme before editing. I would not elaborate here on how as its implementation is easily available online.
1.  Add a new method to the functions.php file in your WooCommerce template folder. This will validate the delivery time text field, and display the error messages nicely at the top when the user clicks Pay.

//add action hook
   add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');

//new method
   function my_custom_checkout_field_process() {
       global $woocommerce;
        
      $delvTime = $_POST['delivery_time'];   //store user input to variable
  
      $day = date('w', strtotime($delvTime));  //split and store into more variables
      $hour = date('H', strtotime($delvTime));
      $min = date('i', strtotime($delvTime));
     
      //logic for allowed delivery time starts here  

      //if weekday
      if($day>=1 && $day <=5) {
        if(timing is correct)
            return;      
        else
            $woocommerce->add_error( __("Sorry, our weekday delivery hours are between 8am to 5pm only.") );     
      }


      //if weekend    
      if($day==6 || $day==0) {
         if(timing is correct)
            return;
         else
            $woocommerce->add_error( __("Sorry, our weekend delivery hours are between 4pm to 10pm only. ") );
      }
   
}

2. Now we want to make the user experience even better by providing users with also a nice display image of a clock with highlighted delivery timings for easy reference (this i created in photoshop), in addition to the traditional plain text instructions. The image below is just an example.

Find the extension's template file to add the image to the code (delivery-time.php if you use my chosen extension).

Tip: you can try looking for the method that displays the timing text field.

Wall clock display with highlighted delivery timings

3. Now this would not be complete if the chosen delivery timings did not appear in the emails sent would it?

Therefore we edit the email template that is sent to the store admin, and also the one sent to the buyer, for everyone's easy reference. Look in the WooCommerce templates->email folder.

Edit admin-new-order.php and customer-processing-order.php to add our new delivery times. We have php tags here because there is a mixture of html.
//if there is user input, save it
<?php if ( $delivery_time = get_post_meta( $order->id, '_delivery_time', true ) ) : ?>
    <?php
    $option = get_option( 'wdt' );
    $label = isset( $option['label'] ) ? $option['label'] : __( 'Delivery Time', 'woocommerce' );
    ?>

//display the time chosen
    <p><strong><?php echo "Delivery Time"; ?></strong> <?php echo gmdate("F j, Y, g:i a", $delivery_time);?></p>
<?php endif; ?>
You can add the same code to both files, in the line according to where you would like the time to appear in the email.

4. If everything works without compilation errors, presto we are done in just a few steps. Of course, test it out to make sure.

What was used in this post:
  • WooCommerce Plugin
  • WooCommerce Delivery Time Picker for Shipping
  • Adobe Photoshop