1
votes

On the checkout page, there are delivery methods, if a specific delivery method (only 1) is selected, then a drop-down list with the delivery time should appear. This field is implemented using the ACF plugin with Repeater and the field type is Text. The time selected by the user should be displayed in the order details in the WooCommerce admin panel.

Based on the theme code that I got, I wrote the next code:

  1. In the woocommerce / checkout / form-shipping.php file the following code:
<div id="delivery_times" class="form-group d-none">
   <label class="text-bold" for="select_time">Delivery time: </label>
      <select id="select_time" class="form-control mb-1">
         <option value="" selected>Select time</option>
         <?php
            $delivery_times = get_field('delivery_times', 'options');
            $count = 0;
            foreach ($delivery_times as $delivery_time):
              echo '<option value="'.$delivery_time['range_time'].'" data-pickup="'.$count.'">'.$delivery_time['range_time'].'</option>';
              $count++;
            endforeach;
          ?>
       </select>
</div>
  1. There is a common theme-checkout.js file, in which I added the code:
$("#shipping_speed").change(function(){
    var delivery_time = $(this).children("option:selected").data("type");

    if(delivery_time == "tomorrow"){
       $("#delivery_times").removeClass("d-none");
    }else{
       $("#delivery_times").addClass("d-none");
       $("#select_time option[value='']").prop('selected',true);
    }
});

And now I need to save the selected data and display it somehow in the order details for the administrator, but I don’t found the implementation of something similar in my theme. Please tell me how I can save this data from the ACF field to the order details?

2

2 Answers

0
votes

Data probably it's saved on another php file, it's using the MVC model.

One thing I would say you is that it's a form, so it does have already other data processed, I would suggest you to find where it does process other data and add some properties there...

Makes sense?

0
votes

Updated:

First on your html <select> the attibute name="select_time" is missing, so replace the line:

<select id="select_time" class="form-control mb-1">

by this line:

<select id="select_time" name="select_time" class="form-control mb-1">

Now you can use the following code snippet to save the chosen value as order meta data:

// Save the custom checkout field as the order meta
add_action( 'woocommerce_checkout_create_order', 'custom_checkout_field_update_order_meta', 10, 2 );
function custom_checkout_field_update_order_meta( $order, $data ) {
    if ( isset($_POST['select_time']) ) {
        $order->update_meta_data( 'delivery_time', esc_attr($_POST['select_time']) );
    }
}

Then to display it in admin single order pages under shipping address:

add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_admin_order_select_time_custom_field' );
function display_admin_order_select_time_custom_field( $order ){
    $delivery_time = $order->get_meta('delivery_time');

    if( ! empty($delivery_time) ) {
        echo '<p class="delivery_time"><strong>'. __("Delivery time", "woocommerce").'</strong>: '.$delivery_time.'</p>';
    }
}

Then you can display this delivery time on customer orders and email notifications:

add_filter( 'woocommerce_get_order_item_totals', 'delivery_time_as_order_item_total_row', 10, 3 );
function delivery_time_as_order_item_total_row( $total_rows, $order, $tax_display ){
    $delivery_time  = $order->get_meta( 'delivery_time' ); // Get delivery time
    $new_total_rows = array(); // Initializing

    if( empty($delivery_time) ) {
        return $total_rows; // Exit
    }

    // Loop through total rows
    foreach( $total_rows as $key => $value ){
        if( 'payment_method' == $key ) {
            $new_total_rows['delivery_time'] = array(
                'label' => __("Delivery time", "woocommerce"),
                'value' => $delivery_time,
            );
        }
        $new_total_rows[$key] = $total_rows[$key];
    }
    return $new_total_rows;
}

Code goes in functions.php file of the active child theme (or active theme). It should work.