phpwoocommercehook-woocommerceordersshipping-method

Customize WooCommerce order shipping item on specific order status change


I am trying in WooCommerce admin order edit pages, when order status is changed to "ready-to-shop", to change shipping item name to "LCS Express". Also, I am trying to update shipping selected options, when editing order shipping items, to include "LCS Express" shipping method

Here is my code:

function customize_order_item_display($product, $item, $item_id) {
    // Get the order ID
    $order_id = $item->get_order_id();

    // Get the order object
    $order = wc_get_order($order_id);

    // Check if the payment status is "ready-to-ship"
    if ($order->get_status() === 'ready-to-ship') {
        // Modify the shipping method
        $new_shipping_method = 'LCS Express'; // Replace with your desired shipping method

        // Get the shipping method data
        $shipping_method_data = $item->get_data()['shipping'];

        // Set the new shipping method name
        $shipping_method_data['name'] = $new_shipping_method;

        // Set the new shipping method ID
        $shipping_method_data['method_id'] = sanitize_title($new_shipping_method);

        // Update the item with the modified shipping method data
        $item->set_props(array('shipping' => $shipping_method_data));
        $item->save();

        // Modify the shipping input fields using JavaScript
        ?>
        <script type="text/javascript">
            jQuery(document).ready(function($){
                // Set the shipping method name in the input field
                $('input.shipping_method_name').val('<?php echo esc_js($new_shipping_method); ?>');
                
                // Set the shipping method ID in the select field
                $('select.shipping_method').val('<?php echo esc_js($shipping_method_data['method_id']); ?>');
            });
        </script>
        <?php
    }
}
add_action('woocommerce_admin_order_item_values', 'customize_order_item_display', 10, 3);

Solution

  • There are multiple mistakes in your code and you are not using the correct hook and the correct way to do it. Always use WC_Order_Item and WC_Order_Item_Shipping available setter methods instead, to make changes to order "shipping" item(s).

    It is better to use one of the dedicated transition order status hooks, to make changes to the order, when the order status is changed to 'ready-to-ship'.

    Try the following:

    // Customize order shipping item(s)
    add_action( 'woocommerce_order_status_ready-to-ship', 'customize_order_shipping_item_on_ready_to_ship', 10, 2 );
    function customize_order_shipping_item_on_ready_to_ship( $order_id, $order ) {
        // Iterating through order shipping items
        foreach( $order->get_items( 'shipping' ) as $item_id => $item ) {
            $method_name = __('LCS Express'); // New shipping method name 
    
            $item->set_name($method_name);
            $item->set_method_title($method_name);
            $item->set_method_id( sanitize_title($method_name) );
            $item->save();
        }
    }
    
    // On edit order shipping item, change 'lcs-express' selected option text to 'LCS Express'
    add_action('admin_footer', 'wc_order_admin_footer_script', 10);
    function wc_order_admin_footer_script() {
        if( isset($_GET['page'], $_GET['action']) && 'wc-orders' === $_GET['page'] && 'edit' === $_GET['action'] ) :
        ?>
        <script>
        jQuery(function($){
            if( $('select.shipping_method').val() === 'lcs-express' ) {
                $('select.shipping_method option[value=lcs-express]').text('LCS Express');
            }
        });
        </script>
        <?php
        endif;
    }
    

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

    Related: