Как отменить отложенное платежное поручение через x минут или x час в WooCommerce - PullRequest
0 голосов
/ 31 октября 2019

Продолжение этого вопроса Ответ @LoicTheAztec был отличным решением. Но мне нужно обновить его. Я хочу обновить время задержки до 30 минут или 1 часа вместо 5 дней.

Кроме того, оно должно работать в состоянии ожидания заказа.

Проблема заключается в том, что я пытаюсь использовать этот код для «отложенного платежа» каждый день, когда он выполняет самый последний заказ, автоматически отмененный.

Таким образом, код должен избегать самого последнего заказа или проверять время размещения заказа.

add_action( 'woocommerce_order_status_changed', 'daily_cancel_unpaid_orders', 10, 4 );
    function daily_cancel_unpaid_orders( $order_id, $old_status, $new_status, $order ) {
        // Enable the process to be executed daily
        if( in_array( $new_status, array('processing', 'completed') ) 
            && get_option( 'unpaid_orders_daily_process' ) < time() ) :

        $days_delay = 1; // <=== SET the delay (number of days to wait before cancelation)

        $one_day    = 24 * 60 * 60;
        $today      = strtotime( date('Y-m-d') );

        // Get unpaid orders (5 days old)
        $unpaid_orders = (array) wc_get_orders( array(
            'limit'        => -1,
            'status'       => 'pending',
            'date_created' => '<' . ( $today - ($days_delay * $one_day) ),
        ) );

        if ( sizeof($unpaid_orders) > 0 ) {
            $cancelled_text = __("The order was cancelled due to no payment from customer.", "woocommerce");

            // Loop through WC_Order Objects
            foreach ( $unpaid_orders as $unpaid_order ) {
                $order->update_status( 'cancelled', $cancelled_text );
            }
        }
        // Schedule the process to the next day (executed once restriction)
        update_option( 'unpaid_orders_daily_process', $today + $one_day );

        endif;
    }

1 Ответ

1 голос
/ 31 октября 2019

Поскольку это действие вызывается только при изменении статуса заказа, его нельзя вызывать, если нет нового события в интервале 30 м или 1 ч. В любом случае, если вы хотите изменить интервал на 1 ч, вы должны выполнить что-то вроде этого:

add_action( 'woocommerce_order_status_changed', 'hourly_cancel_unpaid_orders', 10, 4 );
    function hourly_cancel_unpaid_orders( $order_id, $old_status, $new_status, $order ) {
        // Enable the process to be executed daily
        if( in_array( $new_status, array('processing', 'completed') ) 
            && get_option( 'unpaid_orders_hourly_process' ) < time() ) :

        $hours_delay = 1; // <=== SET the delay (number of hours to wait before cancelation)

        $one_hour    = 60 * 60;
        $current_hour      = strtotime( date('Y-m-d H:00:00') );

        // Get unpaid orders (1 hours old)
        $unpaid_orders = (array) wc_get_orders( array(
            'limit'        => -1,
            'status'       => 'pending',
            'date_created' => '<' . ( $current_hout - ($hours_delay * $one_hour) ),
        ) );

        if ( sizeof($unpaid_orders) > 0 ) {
            $cancelled_text = __("The order was cancelled due to no payment from customer.", "woocommerce");

            // Loop through WC_Order Objects
            foreach ( $unpaid_orders as $unpaid_order ) {
                $order->update_status( 'cancelled', $cancelled_text );
            }
        }
        // Schedule the process to the next day (executed once restriction)
        update_option( 'unpaid_orders_hourly_process', $current_hour + $one_hour );

        endif;
    }

Главное, что я изменил, это добавлю также час к строке strtotime( date('Y-m-d H:00:00') ), чтобы она не была такой жекаждый раз, когда функция запускается в течение одного дня.

Если вы хотите иметь интервалы в 30 м, вы должны изменить это так, чтобы это было в моменты времени, такие как 2:30 3:00 ... Я думаю, что код будетбыть таким:

$current_time = strtotime( date('Y-m-d H:i:00') );
$current_time = $current_time - $current_time % (30 * 60);

Пожалуйста, дайте мне знать, выполняет ли этот код то, что вы хотите или нет.

Относительно последнего ордера, который вы говорите, он будет отменен автоматически: я думаю, что это потому, чтоего статус был pending и будет completed. Поэтому мы передаем первое if, и оно также появится в запросе $unpaid_orders. Вы можете проверить, что заказы, которые вы отменяете, не совпадают с этим последним заказом:

foreach ( $unpaid_orders as $unpaid_order ) {
    if ( $unpaid_order->get_id() != $order_id ) {
        $order->update_status( 'cancelled', $cancelled_text );
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...