我的付款方式之一是ipay88,它只在付款结算后减少库存。
在客户付款期间,订单处于"待付款"状态,库存不会减少。但是,当客户没有及时付款时,订单将自动标记为"取消"。
由于我已经集成了自动补货插件,"待付款"到"取消"将增加库存。
我想问一下,如何防止为ipay88
的特定付款假期重新进货。
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if ( ! class_exists( 'WC_Auto_Stock_Restore' ) ) {
class WC_Auto_Stock_Restore {
public function __construct() {
add_action( 'woocommerce_order_status_processing_to_cancelled', array( $this, 'restore_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_on-hold_to_cancelled', array( $this, 'restore_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_pending_to_cancelled', array( $this, 'restore_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_completed_to_cancelled', array( $this, 'restore_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_processing_to_refunded', array( $this, 'restore_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_completed_to_refunded', array( $this, 'restore_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_on-hold_to_refunded', array( $this, 'restore_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_cancelled_to_completed', array( $this, 'remove_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_cancelled_to_processing', array( $this, 'remove_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_cancelled_to_on-hold', array( $this, 'remove_order_stock' ), 10, 1 );
add_action( 'woocommerce_order_status_cancelled_to_pending', array( $this, 'remove_order_stock' ), 10, 1 );
//add_action( 'woocommerce_order_status_changed', array( $this, 'adjust_order_stock' ), 10, 3 );
} // End __construct()
//public function adjust_order_stock( $order_id, $old_status, $new_status ) {
//$valid_new_statuses = array( 'complete' );
//if ( $old_status == cancelled AND $new_status )
//}
public function remove_order_stock( $order_id ) {
$order = new WC_Order( $order_id );
if ( ! get_option('woocommerce_manage_stock') == 'yes' && ! sizeof( $order->get_items() ) > 0 ) {
return;
}
foreach ( $order->get_items() as $item ) {
if ( $item['product_id'] > 0 ) {
$_product = $order->get_product_from_item( $item );
if ( $_product && $_product->exists() && $_product->managing_stock() ) {
$old_stock = $_product->stock;
$qty = apply_filters( 'woocommerce_order_item_quantity', $item['qty'], $this, $item );
$new_quantity = $_product->reduce_stock( $qty );
do_action( 'woocommerce_auto_stock_restored', $_product, $item );
$order->add_order_note( sprintf( __( 'Item #%s stock decremented from %s to %s.', 'woocommerce' ), $item['product_id'], $old_stock, $new_quantity) );
$order->send_stock_notifications( $_product, $new_quantity, $item['qty'] );
}
}
}
}
public function restore_order_stock( $order_id ) {
$order = new WC_Order( $order_id );
if ( ! get_option('woocommerce_manage_stock') == 'yes' && ! sizeof( $order->get_items() ) > 0 ) {
return;
}
foreach ( $order->get_items() as $item ) {
if ( $item['product_id'] > 0 ) {
$_product = $order->get_product_from_item( $item );
if ( $_product && $_product->exists() && $_product->managing_stock() ) {
$old_stock = $_product->stock;
$qty = apply_filters( 'woocommerce_order_item_quantity', $item['qty'], $this, $item );
$new_quantity = $_product->increase_stock( $qty );
do_action( 'woocommerce_auto_stock_restored', $_product, $item );
$order->add_order_note( sprintf( __( 'Item #%s stock incremented from %s to %s.', 'woocommerce' ), $item['product_id'], $old_stock, $new_quantity) );
$order->send_stock_notifications( $_product, $new_quantity, $item['qty'] );
}
}
}
} // End restore_order_stock()
}
$GLOBALS['wc_auto_stock_restore'] = new WC_Auto_Stock_Restore();
}
针对Wooccommerce版本3+进行了更新、测试和全面功能
自WooCommerce版本3以来,您的代码实际上已经过时了。所以我重新访问了所有的代码…
此外,对于每种状态更改都使用多个钩子,您可以用一个唯一的钩子替换所有钩子:woocommerce_order_status_changed
…
最后,有了这个独特的挂钩,您将需要一个独特的功能,当订单状态从"挂起"更改为"取消"时,可以轻松排除您的'ipay88'
支付网关ID。
对于生成的订单备注,当订单中有多个项目时,最好获得一个唯一的订单备注…
所以这个插件的完整代码是:
## ---- for WooCommerce versions 3+ - Plugin code version ---- ##
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if ( ! class_exists( 'WC_Auto_Stock_Restore' ) ) {
class WC_Auto_Stock_Restore {
public function __construct() {
add_action( 'woocommerce_order_status_changed', array( $this, 'adjust_order_stock' ), 10, 3 );
}
public function adjust_order_stock( $order_id, $old_status, $new_status ) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
if ( ! get_option('woocommerce_manage_stock') == 'yes' && ! count( $items ) > 0 )
return; // We exit
// EXCEPTION for 'ipay88' payment method id, when Order status change from 'pending' to 'cancelled'
if( $order->get_payment_method() == 'ipay88' && $old_status == 'pending' && $new_status == 'cancelled' )
return; // We exit
// We don't need from 'pending' to 'refunded' order status
if( $old_status == 'pending' && $new_status == 'refunded' )
return; // We exit
// Group Order statuses in 2 groups (array)
$statuses_group1 = array( 'processing', 'on-hold', 'pending', 'completed' );
$statuses_group2 = array( 'cancelled', 'refunded' );
$change_stock = false;
$order_note = array();
## 1. Restore Order stock (7 order status change types)
if ( in_array( $old_status, $statuses_group1 ) && in_array( $new_status, $statuses_group2 ) ) {
$change_stock = true;
$change_type = 'increase';
$change_text = __( 'incremented', 'woocommerce' );
}
## 2. Restore Order stock (4 order status change types)
elseif ( $old_status == 'cancelled' && in_array( $new_status, $statuses_group1 ) ) {
$change_stock = true;
$change_type = 'decrease';
$change_text = __( 'decremented', 'woocommerce' );
}
## 3. Other cases
else return; // We exit
if( $change_stock ){
// Iterating through each order 'line_item'
// Since WC 3, $item is a WC_Order_Item_Product object
foreach ( $items as $item ) {
$product_id = $item->get_product_id(); // The product ID
if ( $product_id > 0 ) {
// Get tan instance of the WC_Product object
$product = $item->get_product();
if ( $product && $product->exists() && $product->managing_stock() ) {
// Get the product initial stock quantity (before update)
$initial_stock = $product->get_stock_quantity();
$item_qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $this, $item );
// Update the product stock quantity
// Replace DEPRECATED methods: increase_stock() & discrease_stock()
wc_update_product_stock( $product, $item_qty, $change_type );
// Get the product updated stock quantity
$updated_stock = ( $change_type == 'increase' ) ? $initial_stock + $item_qty : $initial_stock - $item_qty;
do_action( 'woocommerce_auto_stock_restored', $product, $item );
// A unique Order note: Store each order note in an array…
$order_note[] = sprintf( __( 'Product ID #%s stock %s from %s to %s.', 'woocommerce' ), $product_id, $change_text, $initial_stock, $updated_stock);
// DEPRECATED & NO LONGER NEEDED - can be removed
//$order->send_stock_notifications( $product, $updated_stock, $item_qty );
}
}
}
// Adding a unique composite order note (for multiple items)
$order_notes = count($order_note) > 1 ? implode(' | ', $order_note) : $order_note[0];
$order->add_order_note( $order_notes );
}
}
}
$GLOBALS['wc_auto_stock_restore'] = new WC_Auto_Stock_Restore();
}
这应该放在插件php文件中(请参阅与WooCommerce插件创建相关的)。
正常版本(用于主题function.php
文件):
## ---- for WooCommerce versions 3+ - Theme code version ---- ##
add_action( 'woocommerce_order_status_changed', 'adjust_order_stock', 10, 3 );
function adjust_order_stock( $order_id, $old_status, $new_status ) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
if ( ! get_option('woocommerce_manage_stock') == 'yes' && ! count( $items ) > 0 )
return; // We exit
// EXCEPTION for 'ipay88' payment method id, when Order status change from 'pending' to 'cancelled'
if( $order->get_payment_method() == 'ipay88' && $old_status == 'pending' && $new_status == 'cancelled' )
return; // We exit
// We don't need from 'pending' to 'refunded' order status
if( $old_status == 'pending' && $new_status == 'refunded' )
return; // We exit
// Group Order statuses in 2 groups (array)
$statuses_group1 = array( 'processing', 'on-hold', 'pending', 'completed' );
$statuses_group2 = array( 'cancelled', 'refunded' );
$change_stock = false;
$order_note = array();
## 1. Restore Order stock (7 order status change types)
if ( in_array( $old_status, $statuses_group1 ) && in_array( $new_status, $statuses_group2 ) ) {
$change_stock = true;
$change_type = 'increase';
$change_text = __( 'incremented', 'woocommerce' );
}
## 2. Restore Order stock (4 order status change types)
elseif ( $old_status == 'cancelled' && in_array( $new_status, $statuses_group1 ) ) {
$change_stock = true;
$change_type = 'decrease';
$change_text = __( 'decremented', 'woocommerce' );
}
## 3. Other cases
else return; // We exit
if( $change_stock ){
// Iterating through each order 'line_item'
// Since WC 3, $item is a WC_Order_Item_Product object
foreach ( $items as $item ) {
$product_id = $item->get_product_id(); // The product ID
if ( $product_id > 0 ) {
// Get tan instance of the WC_Product object
$product = $item->get_product();
if ( $product && $product->exists() && $product->managing_stock() ) {
// Get the product initial stock quantity (before update)
$initial_stock = $product->get_stock_quantity();
$item_qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $this, $item );
// Update the product stock quantity
// Replace DEPRECATED methods: increase_stock() & discrease_stock()
wc_update_product_stock( $product, $item_qty, $change_type );
// Get the product updated stock quantity
$updated_stock = ( $change_type == 'increase' ) ? $initial_stock + $item_qty : $initial_stock - $item_qty;
do_action( 'woocommerce_auto_stock_restored', $product, $item );
// A unique Order note: Store each order note in an array…
$order_note[] = sprintf( __( 'Product ID #%s stock %s from %s to %s.', 'woocommerce' ), $product_id, $change_text, $initial_stock, $updated_stock);
// DEPRECATED & NO LONGER NEEDED - can be removed
//$order->send_stock_notifications( $product, $updated_stock, $item_qty );
}
}
}
// Adding a unique composite order note (for multiple items)
$order_notes = count($order_note) > 1 ? implode(' | ', $order_note) : $order_note[0];
$order->add_order_note( $order_notes );
}
}
此代码位于活动子主题(或主题)的function.php文件中
所有代码都经过测试,仅适用于WooCommerce版本3+
Wooccommerce订单相关:
- 如何获取WooCommerce订单详细信息
- Wooccommerce 3中的订单项目和WC_Order_Item_Product对象