woocommercewoocommerce-theming

How to see my custom product fields in admin order?


Without plugins I added 3 user fields to the product page. Choosing date field, text and textarea. In cart and checkout all works fine - I see them under item name, but I don't see them as meta fields in admin order. And anywhere else in admin order too. Where I made a mistake in the last function?

// Display custom fields on product page
add_action('woocommerce_before_add_to_cart_button', 'add_custom_fields', 9);
function add_custom_fields() {
    global $product;

    // Define the categories to exclude
    $excluded_categories = array(24, 26);

    // Check if the product belongs to the excluded categories
    if (has_term($excluded_categories, 'product_cat', $product->get_id())) {
        return; // Do not add the fields if the product belongs to the excluded categories
    }

    echo '<div class="customer-fields">';
    echo '<div class="customer-field delivery_date">';
    echo '<label for="delivery_date">Delivery Date<span class="req">*</span>:</label>';
    echo '<input type="date" id="delivery_date" name="delivery_date">';
    echo '</div>';

    echo '<div class="customer-field occasion">';
    echo '<label for="occasion occasion">Occasion:</label>';
    echo '<input type="text" id="occasion" name="occasion" placeholder="Occasion">';
    echo '</div>';

    echo '<div class="customer-field custom_note">';
    echo '<label for="custom_note">Enter Your Message:</label>';
    echo '<textarea id="custom_note" name="custom_note" rows="4" cols="50" placeholder="Enter your message here..."></textarea>';
    echo '</div>';
    echo '</div>';
}

// Save custom fields data to order meta
add_action('woocommerce_add_to_cart', 'save_custom_fields', 10, 2);
function save_custom_fields($cart_item_key, $product_id) {
    if (isset($_POST['delivery_date'])) {
        WC()->session->set('delivery_date', sanitize_text_field($_POST['delivery_date']));
    }
    if (isset($_POST['occasion'])) {
        WC()->session->set('occasion', sanitize_text_field($_POST['occasion']));
    }
    if (isset($_POST['custom_note'])) {
        WC()->session->set('custom_note', sanitize_text_field($_POST['custom_note']));
    }
}

add_action('woocommerce_checkout_create_order_line_item', 'add_custom_fields_to_order_items', 10, 4);
function add_custom_fields_to_order_items($item, $cart_item_key, $values, $order) {
    if (WC()->session->__isset('delivery_date')) {
        $item->add_meta_data('Delivery Date', WC()->session->get('delivery_date'));
        WC()->session->__unset('delivery_date');
    }
    if (WC()->session->__isset('occasion')) {
        $item->add_meta_data('Occasion', WC()->session->get('occasion'));
        WC()->session->__unset('occasion');
    }
    if (WC()->session->__isset('custom_note')) {
        $item->add_meta_data('Custom Note', WC()->session->get('custom_note'));
        WC()->session->__unset('custom_note');
    }
}

// Display custom fields in cart and checkout
add_filter('woocommerce_get_item_data', 'display_custom_fields_in_cart', 10, 2);
function display_custom_fields_in_cart($item_data, $cart_item) {
    if (isset($cart_item['delivery_date'])) {
        $item_data[] = array(
            'key'     => __('Delivery Date', 'woocommerce'),
            'value'   => wc_clean($cart_item['delivery_date']),
            'display' => '',
        );
    }
    if (isset($cart_item['occasion'])) {
        $item_data[] = array(
            'key'     => __('Occasion', 'woocommerce'),
            'value'   => wc_clean($cart_item['occasion']),
            'display' => '',
        );
    }
    if (isset($cart_item['custom_note'])) {
        $item_data[] = array(
            'key'     => __('Custom Note', 'woocommerce'),
            'value'   => wc_clean($cart_item['custom_note']),
            'display' => '',
        );
    }
    return $item_data;
}

// Display custom fields in admin order page
add_action('woocommerce_admin_order_data_after_billing_address', 'display_custom_fields_in_admin_order', 10, 1);
function display_custom_fields_in_admin_order($order) {
    $items = $order->get_items();
    foreach ($items as $item_id => $item) {
        $delivery_date = wc_get_order_item_meta($item_id, 'Delivery Date', true);
        $occasion = wc_get_order_item_meta($item_id, 'Occasion', true);
        $custom_note = wc_get_order_item_meta($item_id, 'Custom Note', true);

        if (!empty($delivery_date)) {
            echo '<p><strong>' . __('Delivery Date', 'woocommerce') . ':</strong> ' . $delivery_date . '</p>';
        }
        if (!empty($occasion)) {
            echo '<p><strong>' . __('Occasion', 'woocommerce') . ':</strong> ' . $occasion . '</p>';
        }
        if (!empty($custom_note)) {
            echo '<p><strong>' . __('Custom Note', 'woocommerce') . ':</strong> ' . $custom_note . '</p>';
        }
    }
}

Like that I tried too

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

    // Display the delivery date
    if( $delivery_date = $order->get_meta('delivery_date') )
        echo '<p><strong>'.__('Delivery Date').':</strong> ' . $delivery_date . '</p>';
}

Solution

  • You don't need to set up a custom session. Replace the functions save_custom_fields and add_custom_fields_to_order_items with the following:

    // Save the custom field value to the cart item data
    add_filter('woocommerce_add_cart_item_data', 'save_custom_fields', 10, 2);
    function save_custom_fields($cart_item_data, $product_id) {
    
       if (isset($_POST['delivery_date'])) {
           $cart_item_data['delivery_date'] = sanitize_text_field($_POST['delivery_date']);
       }
       if (isset($_POST['occasion'])) {
           $cart_item_data['occasion'] = sanitize_text_field($_POST['occasion']);
       }
       if (isset($_POST['custom_note'])) {
           $cart_item_data['custom_note'] = sanitize_text_field($_POST['custom_note']);
       }
    
       return $cart_item_data;
    }
    
    
    // Add custom field to order meta
    add_action('woocommerce_checkout_create_order_line_item', 'add_custom_fields_to_order_items', 10, 4);
    function add_custom_fields_to_order_items($item, $cart_item_key, $values, $order) {
        if (isset($values['delivery_date'])) {
            $item->add_meta_data(__('Delivery Date', 'woocommerce'), $values['delivery_date'], true);
        }
        if (isset($values['occasion'])) {
            $item->add_meta_data(__('Occasion', 'woocommerce'), $values['occasion'], true);
        }
        if (isset($values['custom_note'])) {
            $item->add_meta_data(__('Custom Note', 'woocommerce'), $values['custom_note'], true);
        }
    }
    

    Code Tested and worked

    enter image description here