phpwordpresswoocommerceorderswoocommerce-bookings

Add WooCommerce booking date and time to admin orders preview


Hey I am using Woocommerce with an additional extension (Woocommerce Bookings and I wondered if there is custom code that would display the booking date and time (not the order date and time) in the woocommerce order preview

I found several codes mostly by LoicTheAztec that let you insert product and customer information in certain columns.

If you click on the customer the actual booking information is loaded and the code that generates the information might be the one inserted below. Is there anybody that can create a code for the function.php so the information will be displayed in the Woocommerce order preview tables?

As for now my preview looks like that:

enter image description here

But I want the booking information (product information - bookable product) to be shown that is also loaded when clicking on the order number and the full client information (appointment date and time) loads:

enter image description here

    <ul class="wc-booking-summary-list">
        <li>
            <?php echo esc_html( apply_filters( 'wc_bookings_summary_list_date', $booking_date, $booking->get_start(), $booking->get_end() ) ); ?>
            <?php
            if ( wc_should_convert_timezone( $booking ) ) :
                /* translators: %s: timezone name */
                echo esc_html( sprintf( __( 'in timezone: %s', 'woocommerce-bookings' ), $booking_timezone ) );
            endif;
            ?>
        </li>

        <?php if ( $resource ) : ?>
            <li>
            <?php
            /* translators: 1: label 2: resource name */
            echo esc_html( sprintf( __( '%1$s: %2$s', 'woocommerce-bookings' ), $label, $resource->get_name() ) );
            ?>
            </li>
        <?php endif; ?>

        <?php
        if ( $product && $product->has_persons() ) {
            if ( $product->has_person_types() ) {
                $person_types  = $product->get_person_types();
                $person_counts = $booking->get_person_counts();

                if ( ! empty( $person_types ) && is_array( $person_types ) ) {
                    foreach ( $person_types as $person_type ) {

                        if ( empty( $person_counts[ $person_type->get_id() ] ) ) {
                            continue;
                        }

                        ?>
                        <li><?php echo esc_html( sprintf( '%s: %d', $person_type->get_name(), $person_counts[ $person_type->get_id() ] ) ); ?></li>
                        <?php
                    }
                }
            } else {
                ?>
                <li>
                <?php
                /* translators: 1: person count */
                echo esc_html( sprintf( __( '%d Persons', 'woocommerce-bookings' ), array_sum( $booking->get_person_counts() ) ) );
                ?>
                </li>
                <?php
            }
        }
        ?>
    </ul>

Solution

  • Use the following to add the booking details below each order item in WooCommerce order preview:

    function get_booking_id_from_order_item( $item_id ) {
        global $wpdb;
        return (int) $wpdb->get_var( $wpdb->prepare("SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = '_booking_order_item_id' AND meta_value = %d", $item_id ) );
    }
    
    add_filter('woocommerce_admin_order_preview_line_item_columns', 'filter_admin_order_preview_line_item_columns', 10, 2 );
    function filter_admin_order_preview_line_item_columns( $columns, $order ) {
        $first_column = $columns['product'];
        unset($columns['product']);
    
        return array_merge( array('product2' => $first_column ), $columns );
    }
    
    add_filter('woocommerce_admin_order_preview_line_item_column_product2', 'filter_admin_order_preview_line_item_column_product2', 10, 4 );
    function filter_admin_order_preview_line_item_column_product2( $html, $item, $item_id, $order ) {
        $product = is_callable( array( $item, 'get_product' ) ) ? $item->get_product() : null;
    
        $html   .= wp_kses_post( $item->get_name() );
    
        if ( $product ) {
            $html .= '<div class="wc-order-item-sku">' . esc_html( $product->get_sku() ) . '</div>';
        }
    
        if ( $booking_id = get_booking_id_from_order_item( $item_id ) ) :
        $booking      = get_wc_booking( $booking_id );
        $date_format  = wc_date_format();
        $date_format .= ' ' . wc_time_format(); // ==> Comment this line if time is not needed in bookingstart date format
    
        ob_start(); // Start buffering
        ?>
        <div class="wc-booking-summary">
            <strong class="wc-booking-summary-number">
            <?php printf( __( 'Booking #%d', 'woocommerce-bookings' ), $booking_id ); ?>
                <span class="status-<?php echo $booking->get_status(); ?>"><?php echo ucfirst( $booking->get_status() ); ?></span>
            </strong>
            <ul class="wc-booking-summary-list">
            <li>
            <?php echo esc_html( apply_filters( 'wc_bookings_summary_list_date', date_i18n( $date_format, $booking->get_start() ), $booking->get_start(), $booking->get_end() ) );
            if ( wc_should_convert_timezone( $booking ) ) :
                /* translators: %s: timezone name */
                echo esc_html( sprintf( __( 'in timezone: %s', 'woocommerce-bookings' ), $booking->get_local_timezone() ) );
            endif;
            ?>
            </li>
            <?php if ( $resource = $booking->get_resource() ) : ?>
                <li>
                <?php
                $label = method_exists( $resource, 'get_label' ) ? $resource->get_label() : __('Resource', 'woocommerce-bookings');
                /* translators: 1: label 2: resource name */
                echo esc_html( sprintf( __( '%1$s: %2$s', 'woocommerce-bookings' ), $label, $resource->get_name() ) );
                ?>
                </li>
            <?php endif;
    
            if ( $product && $product->has_persons() ) {
                if ( $product->has_person_types() ) {
                    $person_types  = $product->get_person_types();
                    $person_counts = $booking->get_person_counts();
    
                    if ( ! empty( $person_types ) && is_array( $person_types ) ) {
                        foreach ( $person_types as $person_type ) {
    
                            if ( empty( $person_counts[ $person_type->get_id() ] ) ) {
                                continue;
                            }
    
                            ?>
                            <li><?php echo esc_html( sprintf( '%s: %d', $person_type->get_name(), $person_counts[ $person_type->get_id() ] ) ); ?></li>
                            <?php
                        }
                    }
                } else {
                    ?>
                    <li>
                    <?php
                    /* translators: 1: person count */
                    echo esc_html( sprintf( __( '%d Persons', 'woocommerce-bookings' ), array_sum( $booking->get_person_counts() ) ) );
                    ?>
                    </li>
                    <?php
                }
            }
            ?>
        </ul>
        </div>
        <?php
        $html .= ob_get_clean(); // Set back buffered content
        endif;
    
        $meta_data = $item->get_formatted_meta_data( '' );
    
        if ( $meta_data ) {
            $html .= '<table cellspacing="0" class="wc-order-item-meta">';
    
            foreach ( $meta_data as $meta_id => $meta ) {
                if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) {
                    continue;
                }
                $html .= '<tr><th>' . wp_kses_post( $meta->display_key ) . ':</th><td>' . wp_kses_post( force_balance_tags( $meta->display_value ) ) . '</td></tr>';
            }
            $html .= '</table>';
        }
        return $html;
    }
    

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.

    enter image description here