Skip to content
Advertisement

Add a select field with time intervals based on opening, closing and breaks times in WooCommerce checkout

I am building pizza delivery website with WooCommerce. In fact when customer is checking out, he can select when he want to have food delivered.

The select box should contain 15 minute intervals ranging from the current time and clearing all past hours. The first option I want is to be “As soon as possible”, and then the next option is an hour later (rounded to nearest 15mins), and then 15 mins each time.

Our delivery hours are as below:

  • Monday: Closed
  • Tuesday – Friday 11:30 – 14:00 & 17:00 – 22:00
  • Sat & Sun : 13:00 – 22:00

I succesfully WooCommerce action/hook, but I can’t disable all time slots before the current time.

add_action('woocommerce_before_order_notes', 'wps_add_select_checkout_field');
function wps_add_select_checkout_field( $checkout ) {
    woocommerce_form_field( 'lieferzeit', array(
        'type'          => 'select',
        'class'         => array( 'wps-drop' ),
        'label'         => __( '<div class="gew"><span class="gew-lz">Gewünschte Lieferzeit</span></div>'),
         'options'       => array(
            'asap'      => __( 'So schnell wie möglich', 'wps' ),
            '12:00'                     => __( '12:00', 'wps' ),
            '12:30'                     => __( '12:30', 'wps' ),
            '13:00'                     => __( '13:00', 'wps' ),
            '13:30'                     => __( '13:30', 'wps' ),
            '14:00'                     => __( '14:00', 'wps' ),
            '17:30'                     => __( '17:30', 'wps' ),
            '18:00'                     => __( '18:00', 'wps' ),
            '18:30'                     => __( '18:30', 'wps' ),
            '19:00'                     => __( '19:00', 'wps' ),
            '19:30'                     => __( '19:30', 'wps' ),
            '20:00'                     => __( '20:00', 'wps' ),
            '20:30'                     => __( '20:30', 'wps' ),
            '21:00'                     => __( '21:00', 'wps' ),
            '21:30'                     => __( '21:30', 'wps' ),
            '22:00'                     => __( '22:00', 'wps' ),
                           
        )
    ),

    $checkout->get_value( 'lieferzeit' ));
}

add_action('woocommerce_checkout_update_order_meta', 'wps_select_checkout_field_update_order_meta');
function wps_select_checkout_field_update_order_meta( $order_id ) {

   if ($_POST['lieferzeit']) update_post_meta( $order_id, 'lieferzeit', esc_attr($_POST['lieferzeit']));

}


add_action( 'woocommerce_admin_order_data_after_billing_address', 'wps_select_checkout_field_display_admin_order_meta', 10, 1 );
function wps_select_checkout_field_display_admin_order_meta($order){

    echo '<p><strong>'.__('Delivery option').':</strong> ' . get_post_meta( $order->id, 'lieferzeit', true ) . '</p>';

}

add_filter('woocommerce_email_order_meta_keys', 'wps_select_order_meta_keys');
function wps_select_order_meta_keys( $keys ) {

    $keys['lieferzeit:'] = 'lieferzeit';
    return $keys;
    
}

Advertisement

Answer

For your question about the select field you can use the following

Via the $store_times array you can set the opening and closing hours as well as the hours of the break.

If the store is closed all day, leave all settings for that day empty (see monday)

function action_woocommerce_before_order_notes( $checkout ) {       
    // Open, break and close time   
    $store_times = array(
        array( // Sunday (NO break)
            'open'    => '13:00',
            'break_s' => '',
            'break_e' => '',
            'close'   => '22:00',
        ), 
        array( // Monday (closed, so everything is empty)
            'open'    => '',
            'break_s' => '',
            'break_e' => '',
            'close'   => '',
        ), 
        array( // Tuesday
            'open'    => '11:30',
            'break_s' => '14:00',
            'break_e' => '17:00',
            'close'   => '22:00',
        ), 
        array( // Wednesday
            'open'    => '11:30',
            'break_s' => '14:00',
            'break_e' => '17:00',
            'close'   => '22:00',
        ), 
        array( // Thursday
            'open'    => '11:30',
            'break_s' => '14:00',
            'break_e' => '17:00',
            'close'   => '23:30',
        ), 
        array( // Friday
            'open'    => '11:30',
            'break_s' => '14:00',
            'break_e' => '17:00',
            'close'   => '22:00',
        ),
        array( // Saturday
            'open'    => '13:00',
            'break_s' => '',
            'break_e' => '',
            'close'   => '22:00',
        ), 
    );
    
    // Current time
    $current_time = current_time( 'timestamp' );
    
    // Current day, 0 for Sunday, 6 for Saturday
    $current_day = date( 'w', $current_time );

    // Get values for the current day
    $open_time = strtotime( $store_times[ $current_day][ 'open' ] );
    $break_start = strtotime( $store_times[ $current_day][ 'break_s' ] );
    $break_end = strtotime( $store_times[ $current_day][ 'break_e' ] ); 
    $close_time = strtotime( $store_times[ $current_day][ 'close' ] );
    
    // Open time is empty or before/passed open/close time, so the store is closed
    if ( empty ( $open_time ) || ( $current_time > $close_time || $current_time <= $open_time ) ) {
        // Default value
        $options['closed'] = __( 'Closed', 'woocommerce');
    } else {
        // Default value
        $options[''] = __( 'As soon as possible', 'woocommerce');
        
        // As soon as possible
        $asa_possible = strtotime( '+1 hour', $current_time );
    
        // Round to next 15 minutes (15 * 60 seconds)
        $asa_possible = ceil( $asa_possible / ( 15 * 60 ) ) * ( 15 * 60);
        
        // Add a new option every 15 minutes
        while( $asa_possible <= $close_time && $asa_possible >= $open_time ) {
            // Generate value
            $value = date( 'H:i', $asa_possible );
            
            // NOT between break start & break end
            if ( $value <= date( 'H:i', $break_start ) || $value >= date( 'H:i', $break_end ) ) {
                // Push to array
                $options[$value] = $value;
            }
            
            // Add 15 minutes to the variable in this while loop
            $asa_possible = strtotime( '+15 minutes', $asa_possible );
        }
    }


    // Add field
    woocommerce_form_field( 'delivery_time', array(
        'type'          => 'select',
        'class'         => array( 'wps-drop' ),
        'label'         => __('Desired delivery time', 'woocommerce' ),
        'options'       => $options,
    ), $checkout->get_value( 'delivery_time' ) );
}
add_action( 'woocommerce_before_order_notes', 'action_woocommerce_before_order_notes', 10, 1 );
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement