Update multiple metadata for a limited number of existing orders in WooCommerce

Viewed 204

I added 4 new meta data fields to each order. I can update these fields myself for each order from within the admin panel but there are 200 orders and it will take awhile.

I need automatically populate these meta fields for each order. Future orders will automatically be populated but I need to update all orders at this time.

I wrote the following code but it doesn't do anything:

add_action( 'woocommerce_loaded', 'update_existing_orders_with_new_meta' );

function update_existing_orders_with_new_meta(){

    $order_ids = wc_get_order( $order_id );

    // Loop through product Ids
    foreach ( $order_ids as $order_id ) {

        if ( $order_id->payment_method == 'cheque' ) {
            $order_id->update_meta_data('ji_payment_status', '');
            $order_id->update_meta_data('ji_payment_method', '');
            $order_id->update_meta_data('ji_payment_date', '');
            $order_id->update_meta_data('ji_payment_notes', '');
        } else {
            $order_id->update_meta_data('ji_payment_status', '1');
            $order_id->update_meta_data('ji_payment_method', 'Credit Card');
            $order_id->update_meta_data('ji_payment_date', date('F j, Y'));
            $order_id->update_meta_data('ji_payment_notes', '');
        }
    }
}

Can someone walk me through how to do that?

1 Answers

You're using $order_ids = wc_get_order( $order_id ); while no $order_id has been set.

If it actually concerns 200 orders, you can use the following. When the action is completed, 'done' will appear in the footer. Then the code can be removed.

// Run once, delete afterwards
function set_meta_for_orders () {
    // Get ALL orders (could be extended with multiple conditions)
    // More info: https://github.com/woocommerce/woocommerce/wiki/wc_get_orders-and-WC_Order_Query
    $orders = wc_get_orders( array(
        'limit' => 200, // Get 200 most recent orders
    ));
    
    // NOT empty
    if ( ! empty ( $orders ) ) {
        // Loop     
        foreach ( $orders as $order ) {
            // Payment method = cheque
            if ( $order->get_payment_method() == 'cheque' ) {
                $order->update_meta_data( 'ji_payment_status', '' );
                $order->update_meta_data( 'ji_payment_method', '' );
                $order->update_meta_data( 'ji_payment_date', '' );
                $order->update_meta_data( 'ji_payment_notes', '' );
            } else {
                $order->update_meta_data( 'ji_payment_status', '1' );
                $order->update_meta_data( 'ji_payment_method', 'Credit Card' );
                $order->update_meta_data( 'ji_payment_date', date( 'F j, Y' ) );
                $order->update_meta_data( 'ji_payment_notes', '' );
            }
            
            // Save
            $order->save();
        }

        // Output
        echo 'Done!';
    }
}
// Call function
add_action( 'wp_footer', 'set_meta_for_orders' );

Note: this will work for some limited orders. When it concerns many orders, other solutions such as custom SQL are recommended.

Related