timboon timboon - 2 months ago 27
PHP Question

Add text to order summary based on a custom field value in WooCommerce

I have added successfully a custom field to my WooCommerce checkout page that is a selector for different stores that the customer can choose to collect their items from. At the moment it is showing this field on the checkout page and I am using jQuery to add information below the selector and updating the shipping cost accordingly.

What I need to do next is to add the field + additional info about each pickup location on the customer's order email. so for instance if the customer selects location 1 the order email should show:


Delivery location = Location 1

Address = 123 street

Info = Pickup order between 4pm and 7pm weekdays



I am just not sure how to add the fields of "Info" and "address" to array and then be able to call them out in the email.

This is my code so far:

add_filter( 'woocommerce_checkout_fields' , 'custom_store_pickup_field');

function custom_store_pickup_field( $fields ) {

$fields['billing']['store_pickup'] = array(
'type' => 'select',
'options' => array(
'option_0'=> 'Please Select a Delivery Option',
'option_1' => 'Delivery',
'option_2' => 'Gym1',
'option_3' => 'Gym2'
),
'label' => __('Store Pick Up Location (Optional)', 'woocommerce'),
'required' => true,
'class' => array('store-pickup form-row-wide'),
'id' => 'store_pickup_val',
'clear' => true
);

return $fields;
}

//* Process the checkout
add_action('woocommerce_checkout_process',
'wps_select_checkout_field_process');
function wps_select_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error.
if ($_POST['store_pickup'] == "option_0")
wc_add_notice( '<strong>Please select a Delivery option</strong>', 'error'
);
}


add_action( 'woocommerce_after_checkout_form', 'gym_opening_hours', 6);

function gym_opening_hours() {

?>
<script type="text/javascript">
jQuery('#store_pickup_val').change(function(){

jQuery('body').trigger('update_checkout');


jQuery( ".gym-collection" ).remove();

if (this.value == 'option_1') {
jQuery('#shipping_method_0_flat_rate1').prop('checked', true);
}

if (this.value == 'option_2') {
jQuery( "<p>Order can be collected between 4pm - 7pm on Tuesdays</p>" ).addClass("gym-collection").insertAfter( "#store_pickup_val" );
jQuery('#shipping_method_0_local_pickup3').prop('checked', true);
}
if (this.value == 'option_3') {
jQuery( "<p>Order can be collected between 4pm - 7pm on Tuesdays</p>" ).addClass("gym-collection").insertAfter( "#store_pickup_val" );
jQuery('#shipping_method_0_local_pickup3').prop('checked', true);
}
else {

}

});
</script>
<?php

}

Answer Source

This is what you need:

  • Format and save the "pickup data" as order meta data (for the customer - front end)
  • Save the "pickup location" for admin order edit pages (for backend).
  • Display the "pickup location" in admin order edit pages (in backend).
  • Display the "pickup html formatted data" in order view and received pages (front end).
  • Display the "pickup html formatted data" in email notifications (with embedded styles).

I have also revisited lightly your code:

add_filter( 'woocommerce_checkout_fields' , 'custom_store_pickup_field');
function custom_store_pickup_field( $fields ) {
    $fields['billing']['store_pickup'] = array(
        'type'     => 'select',
        'id'       => 'store_pickup_val',
        'label'    => __('Store Pick Up Location (Optional)', 'woocommerce'),
        'required' => true,
        'class'    => array('store-pickup form-row-wide'),
        'options'  => array(
            ''=> 'Please Select a Delivery Option',
            'option_1' => 'Delivery',
            'option_2' => 'Gym1',
            'option_3' => 'Gym2'
        ),
        'clear'     => true,
    );
    return $fields;
}

//* Process the checkout
add_action('woocommerce_checkout_process',  'wps_select_checkout_field_process');
function wps_select_checkout_field_process() {
    // Check if set, if its not set add an error.
    if ( $_POST['store_pickup'] == "option_0" )
        wc_add_notice( '<strong>Please select a Delivery option</strong>', 'error' );
}


add_action( 'woocommerce_after_checkout_form', 'gym_opening_hours', 6 );
function gym_opening_hours() {
     ?>
    <script type="text/javascript">
        (function($){
            $('#store_pickup_val').change( function(){
                $( ".gym-collection" ).remove();
                if (this.value == 'option_1') {
                    $('#shipping_method_0_flat_rate1').prop('checked', true);
                } else if (this.value == 'option_2') {
                     $( "<p>Order can be collected between 4pm - 7pm on Tuesdays</p>" ).addClass("gym-collection").insertAfter( "#store_pickup_val" );
                     $('#shipping_method_0_local_pickup3').prop('checked', true);
                } else if (this.value == 'option_3') {
                    $( "<p>Order can be collected between 4pm - 7pm on Tuesdays</p>" ).addClass("gym-collection").insertAfter( "#store_pickup_val" );
                    $('#shipping_method_0_local_pickup3').prop('checked', true);
                }
                $('body').trigger('update_checkout');
            });
        })(jQuery);
    </script>
<?php
}

Now the code you need to complete this process:

// Save the delivery location data to the order meta
add_action( 'woocommerce_checkout_update_order_meta', 'store_pickup_field_update_order_meta', 10, 1 );
function store_pickup_field_update_order_meta( $order_id ) {

    // BELOW update the data
    if ( $_POST['store_pickup'] == 'option_2' )
        $data = array( 
            'location' => 'Location 1', 
            'address' => '123 Beverly street<br> 90001 Los Angeles' 
        );
    elseif ( $_POST['store_pickup'] == 'option_3' )
        $data = array( 
        'location' => 'Location 2', 
        'address' => '456 Trumpet street<br> 90056 Los Angeles' 
    );

    $collect_info = 'Order can be collected between 4pm - 7pm on Tuesdays';

    if ( $_POST['store_pickup'] == 'option_2' || $_POST['store_pickup'] == 'option_3' ){
        // HTML
        $store_pickup = "<h3>Pickup Information</h3>
        <table class='pickup td' cellspacing='0' cellpadding='6'>
            <tr>
                <th>Location:</th>
                <td>".$data['location']."</td>
            </tr>
            <tr>
                <th><strong>Adress:</strong></th>
                <td>".$data['address']."</td>
            </tr>
            <tr>
                <th><strong>Info:</strong></th>
                <td>".$collect_info."</td>
            </tr>
        </table>";

        // Save pickup html data (front end)
        update_post_meta( $order_id, '_store_pickup_data', $store_pickup );
        // Save pickup location (backend)
        update_post_meta( $order_id, '_store_pickup_location', $data['location'] );
    }
}

// Display 'pickup location' on the order edit page (backend)
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_store_pickup_location_on_order_edit_pages', 10, 1 );
function display_store_pickup_location_on_order_edit_pages( $order ){
    $pickup_location = get_post_meta( $order->get_id(), '_store_pickup_location', true );
    if( ! empty( $pickup_location ) )
        echo '<p><strong>Store pickup location: </strong> ' . $pickup_location . '</p>';
}

// Display 'pickup html data' in "Order received" and "Order view" pages (frontend)
add_action( 'woocommerce_order_details_after_order_table', 'display_store_pickup_data_in_orders', 10 );
function display_store_pickup_data_in_orders( $order ) {
    $pickup_data = get_post_meta( $order->get_id(), '_store_pickup_data', true );
    if( ! empty( $pickup_data ) )
        echo $pickup_data;
}

// Display 'pickup html data' in Email notifications (frontend)
add_action( 'woocommerce_email_order_meta', 'display_store_pickup_data_in_emails', 10 );
function display_store_pickup_data_in_emails( $order ) {
    $pickup_data = get_post_meta( $order->get_id(), '_store_pickup_data', true );
    if( ! empty( $pickup_data ) ){
        // Email CSS style rules
        echo '<style>
        table.pickup{width: 100%; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif;
            color: #737373; border: 1px solid #e4e4e4;}
        table.pickup th, table.pickup td{text-align: left; border-top-width: 4px;
            color: #737373; border: 1px solid #e4e4e4; padding: 12px;}
        table.pickup td{text-align: left; border-top-width: 4px; color: #737373; border: 1px solid #e4e4e4; padding: 12px;}
        </style>';
        // Html data
        echo $pickup_data;
    }

}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works on WooCommerce 3+. So you will get this:

In Admin edit order page:

enter image description here

In Order view and order received pages:

enter image description here

In email notifications:

enter image description here