1
votes

I know how to add a meta on the order shipping method :

$shippingMethodItem->update_meta_data('num_packages', 0);

But I want to add/update this meta automatically when the order is placed OR when someone add/edit order items manually.

I already tried with no result :

add_action( 'woocommerce_checkout_create_order_shipping_item', [$this, 'actionCheckoutCreateOrderShippingItem'] );

...

public function actionCheckoutCreateOrderShippingItem ($shippingMethodItem, $package_key, $package, $order)
{
    $shippingMethodItem->update_meta_data( 'num_packages', 0);
    $shippingMethodItem->save();
}
1

1 Answers

2
votes

The following will add custom specific order "shipping" item meta data on orders via checkout and/or manual admin orders too:

// For new orders via checkout
add_action( 'woocommerce_checkout_create_order_shipping_item', 'action_checkout_create_order_shipping_item', 10, 4 );
function action_checkout_create_order_shipping_item ( $item, $package_key, $package, $order ){
    $item->update_meta_data( 'num_packages', 0 );
}

// For manual admin orders
add_action( 'woocommerce_saved_order_items', 'action_saved_order_items_callback', 10, 2 );
function action_saved_order_items_callback( $order_id, $items ) {
    if ( isset( $items['shipping_method_id'] ) ) {
        foreach( $items['shipping_method_id'] as $item_id ) {
            $num_packages = wc_get_order_item_meta($item_id, 'num_packages');

            if ( empty($num_packages) || $num_packages != 0 ) {
                wc_update_order_item_meta( $item_id, 'num_packages', 0 );
            }
        }
    }
}

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


To use this code in a plugin with a class (OOP), add the following inside the constructor function:

// For checkout order
add_action( 'woocommerce_checkout_create_order_shipping_item', [$this, 'action_checkout_create_order_shipping_item'], 10, 4 );
// For checkout order
add_action( 'woocommerce_saved_order_items', [$this, 'action_saved_order_items_callback'], 10, 2 );

And the following outside the constructor function:

public function action_checkout_create_order_shipping_item ( $item, $package_key, $package, $order ){
    $item->update_meta_data( 'num_packages', 0 );
}

public function action_saved_order_items_callback( $order_id, $items ) {
    if ( isset( $items['shipping_method_id'] ) ) {
        foreach( $items['shipping_method_id'] as $item_id ) {
            $num_packages = wc_get_order_item_meta($item_id, 'num_packages');

            if ( empty($num_packages) || $num_packages != 0 ) {
                wc_update_order_item_meta( $item_id, 'num_packages', 0 );
            }
        }
    }
}