Search code examples
phpwordpresswoocommerceorders

Display extra order item details in WooCommerce admin edit order


In WooCommerce, I have some custom cart item data that I am able to display on checkout using:

<td class="custom-date-cell">
<?php
if (!empty($cart_item['pickup_date']) && !empty($cart_item['dropoff_date'])) {
    $pickup_date = date('Y-m-d', strtotime(str_replace('/', '-', $cart_item['pickup_date'])));
    $dropoff_date = date('Y-m-d', strtotime(str_replace('/', '-', $cart_item['dropoff_date'])));
    echo $pickup_date . " <br>to<br>" . $dropoff_date;
} else {
    echo 'No dates available';
}
?>
</td>

This will display dates for specific products.

But now I also want to have these dates in WooCommerce order edit pages and should be displayed for each order item.

I tried the following:

add_action('woocommerce_email_order_meta', 'add_booking_dates_to_order_emails', 10, 3);
function add_booking_dates_to_order_emails($order, $sent_to_admin, $plain_text) {

    foreach ($order->get_items() as $item_id => $item) {
        $pickup_date = wc_get_order_item_meta($item_id, 'Pickup Date', true);
        $dropoff_date = wc_get_order_item_meta($item_id, 'Dropoff Date', true);
        
        if ($pickup_date && $dropoff_date) {
            if ($plain_text) {
                echo "Pickup Date: $pickup_date\n";
                echo "Dropoff Date: $dropoff_date\n";
            } 

        }
    }
}

But it doesn't do anything at all.


Solution

  • To make it work, you need first to save those dates as custom order item data, and they will be displayed everywhere (including in order edit pages).

    Try the following (compatible with Checkout Blocks and HPOS):

    // Utility function (Array of dates key / label pairs)
    function shipping_dates_key_labels() {
        return array(
            'pickup_date'  => esc_html__('Pickup Date', 'woocommerce'),
            'dropoff_date' => esc_html__('Dropoff Date', 'woocommerce'),
        )
    }
    
    // Save custom cart item data as order item meta
    add_action( 'woocommerce_checkout_create_order_line_item', 'save_cart_item_dates_as_order_item_meta', 10, 4 );
    function save_cart_item_dates_as_order_item_meta( $item, $cart_item_key, $values, $order ) {
        foreach ( array_keys( shipping_dates_key_labels() ) as $date_key ) {
            if( isset( $values[$date_key] ) ) {
                $item->add_meta_data( $date_key, date('Y-m-d', strtotime( str_replace('/', '-', $values[$date_key]) ) ) );
            }
        }
    }
    
    // Replace custom order item displayed keys with a readable "meta key" label name
    add_filter( 'woocommerce_order_item_display_meta_key', 'filter_order_item_display_meta_key', 10, 3 );
    function filter_order_item_display_meta_key( $display_key, $meta, $item ) {
        foreach ( shipping_dates_key_labels() as $date_key => $readable_label ) {
            if( $item->get_type() === 'line_item' && $meta->key === $date_key ) {
                $display_key = $readable_label;
            }
        }
        return $display_key;
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). It should work.