Search code examples
phpwordpresswoocommercestatusorders

Auto set Woocommerce product to draft status if order is completed


In WooCommerce I would like to set products to draft status when Order is completed… So what I want is to make products to be sold 1 time and passed to draft when order get completed.

Any idea?


Solution

  • Try the following code, that will set the products found in order items with a "draft" status only when order get "processing" or "completed" statuses (paid order statuses):

    add_action( 'woocommerce_order_status_changed', 'action_order_status_changed', 10, 4 );
    function action_order_status_changed( $order_id, $old_status, $new_status, $order ){
        // Only for processing and completed orders
        if( ! ( $new_status == 'processing' || $new_status == 'completed' ) )
            return; // Exit
    
        // Checking if the action has already been done before
        if( get_post_meta( $order_id, '_products_to_draft', true ) )
            return; // Exit
            
        $products_set_to_draft = false; // Initializing variable 
    
        // Loop through order items
        foreach($order->get_items() as $item_id => $item ){
            $product = $item->get_product(); // Get the WC_Product object instance
            if ('draft' != $product->get_status() ){
                $product->set_status('draft'); // Set status to draft
                $product->save(); // Save the product
                $products_set_to_draft = true;
            }
        }
        // Mark the action done for this order (to avoid repetitions)
        if($products_set_to_draft)
            update_post_meta( $order_id, '_products_to_draft', '1' );
    }
    

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

    If you want to target only "completed" orders, you can replace this line:

      if( ! ( $new_status == 'processing' || $new_status == 'completed' ) )
    

    by this one:

      if( $new_status != 'completed' )