简体   繁体   中英

WooCommerce: Change order status based on custom Meta Value

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!

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 ), '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 ) '>'. ( 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: 在此处输入图像描述

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM