Один из моих способов оплаты — ipay88, который сокращает запас только после того, как платеж будет очищен.
В течение времени, когда клиент производит оплату, заказ находится в состоянии «ожидающий платеж», запас которого не уменьшается. Однако, если клиент не выполнит платеж в срок, заказ будет автоматически помечен как «отмененный».
Поскольку я интегрировал с плагином auto-restock, «отложенный платеж» до «отменен» увеличит запас.
Я хотел бы спросить, как предотвратить пополнение запасов для определенного платежа, который 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();
}
Обновленный, протестированный и полностью функциональный для версий Woocommerce 3+
Ваш код действительно устарел со времен WooCommerce версии 3. Так что я пересмотрел весь код …
Также вместо использования нескольких хуков для каждого вида изменения статуса, вы можете заменить все хуки на уникальные: woocommerce_order_status_changed
…
Наконец, с этим уникальным хуком вам понадобится уникальная функция, где можно будет легко исключить ваши 'ipay88'
идентификатор платежного шлюза, когда статус заказа изменяется с «ожидающий» на «отмененный».
Для сгенерированной заметки о заказе лучше получить уникальную заметку о заказе, когда в заказе несколько товаров…
Итак, полный код этого плагина:
## ---- 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+
Woocommerce Order связанный:
Других решений пока нет …