skip to Main Content

I’m trying to run the following function daily, to auto-complete all processing order older than 10 days and who have a specific custom meta value.

I’m using the following snippet, however this will simply not work. Any idea as to why?

function autoComplete(){
    $orders = wc_get_orders( array(
            'status' => 'wc-processing',
            'date_created' => '<' . ( time() - 10 * DAY_IN_SECONDS ),
            'meta_key'     => 'status_us',
            'meta_compare' => '=',
            'meta_value'   => 'Sent to USA',
    ) );

    foreach ($orders as $order){
        $order->update_status( 'completed' );
    }
}

if ( ! wp_next_scheduled( 'autoComplete' ) ) {
    wp_schedule_event( time(), 'daily', 'autoComplete' );
} 

Is there any error I’ve missed? Thanks for your help!

2

Answers


  1. Here is what I do to validate orders based on a CRON task.

    $order->payment_complete('transaction ID string'); //validate payment
    wc_reduce_stock_levels($order->get_id()); //reduce stock
    $woocommerce->cart->empty_cart(); //empty cart
    $order->update_status('completed', 'A order note string'); //change order statyus
    

    I believe that you don’t need the "wc-" prefix.

    Are you sure that your scheduled event is working? and that $orders is filled? Please test your method without the schedule first.

    Login or Signup to reply.
  2. You did a good attempt but you made a few mistakes.

    The following code goes inside your functions.php.

    add_action( 'wp_loaded','start_custom_code' );
    
    // Once everything theme and plugins are loaded we register our cron job.
    function start_custom_code() {
        if ( ! wp_next_scheduled( 'bks_mark_processing_order_complete_if_sent_to_usa' ) ) {
            wp_schedule_event( time(), 'daily', 'bks_mark_processing_order_complete_if_sent_to_usa' );
        }
    }
    
    add_action( 'bks_mark_processing_order_complete_if_sent_to_usa', 'bks_mark_processing_order_complete_if_sent_to_usa' );
    

    Your function has minor errors bks_mark_processing_order_complete_if_sent_to_usa()

    function bks_mark_processing_order_complete_if_sent_to_usa(){
        $args = array(
            'status' => array( 'wc-processing'),
            'limit'  => -1,
            'date_created' => '>' . ( time() - 864000 ), // your mistake 1
            'status_us' => 'Sent to USA', // your mistake 2
        );
    
    
        $orders = wc_get_orders( $args );
    
        foreach ($orders as $order){
            $order->update_status( 'completed' );
            $order->save(); // your mistake 3
        }
    };
    

    Mistake Explanations

    1. While your attempt was in right direction but 'date_created' => '<' . ( time() - 10 * DAY_IN_SECONDS ), you had to use > instead of < also you didn’t acutally set DAY_IN_SECONDS You had to replace it with 86400. So the correct value would be '>' . ( time() - 864000 ). For 10 days 10 * 86400 = 864000. You can read about this explanation here in the WooCommerce documentation.

    2. Here I have created new custom variable for you which is set using woocommerce_order_data_store_cpt_get_orders_query and then queried. Code that needs to be added.

    function handle_custom_query_var( $query, $query_vars ) {
        if ( ! empty( $query_vars['status_us'] ) ) {
            $query['meta_query'][] = array(
                'key' => 'status_us',
                'value' => esc_attr( $query_vars['status_us'] ),
            );
        }
    
        return $query;
    }
    
    add_filter( 'woocommerce_order_data_store_cpt_get_orders_query', 'handle_custom_query_var', 10, 2 );
    
    1. You updated the status but you forgot to save it. $order->save();

    So to summarise you have to add the following code in your functions.php

    add_action( 'wp_loaded','start_custom_code' );
    add_action( 'bks_mark_processing_order_complete_if_sent_to_usa', 'bks_mark_processing_order_complete_if_sent_to_usa' );
    
    
    function start_custom_code() {
        if ( ! wp_next_scheduled( 'bks_mark_processing_order_complete_if_sent_to_usa' ) ) {
            wp_schedule_event( time(), 'daily', 'bks_mark_processing_order_complete_if_sent_to_usa' );
        }
    }
    
    function bks_mark_processing_order_complete_if_sent_to_usa(){
        $args = array(
            'status' => array( 'wc-processing'),
            'limit'  => -1,
            'date_created' => '>' . ( time() - 864000 ),
            'status_us' => 'Sent to USA',
        );
    
    
        $orders = wc_get_orders( $args );
    
        foreach ($orders as $order){
            $order->update_status( 'completed' );
            $order->save();
        }
    };
    
    function handle_custom_query_var( $query, $query_vars ) {
        if ( ! empty( $query_vars['status_us'] ) ) {
            $query['meta_query'][] = array(
                'key' => 'status_us',
                'value' => esc_attr( $query_vars['status_us'] ),
            );
        }
    
        return $query;
    }
    
    add_filter( 'woocommerce_order_data_store_cpt_get_orders_query', 'handle_custom_query_var', 10, 2 );
    

    The above code is TESTED and WORKS.

    Proof:
    enter image description here

    Install WP CRON plugin to check your cron. See above screenshot. You can test by hitting Run Now.

    Caveat :
    WP Cron runs, when somebody visits your website. Thus if nobody visits, ?>the cron never runs.

    Read this : https://wordpress.stackexchange.com/a/179774/204925

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search