Reponer stock en WooCommerce al cancelar un pedido

Otras publicaciones que te pueden interesar

Si esta leyendo esto es porque estas preocupado de las inconsistencias en el stock de tu tienda WooCommerce. Has visto que al cancelar pedidos el stock no se repone y comienzan las diferencias entre el stock real y el stock de WooCommerce.

Si bien la documentacion de WooCommerce explica que el stock se repone cuando un administrador o cliente cancela un pedido, hemos comprobado que esto no es asi.

Aqui debemos aclarar un punto importante, la funcionalidad que encontramos en Ajustes > Productos > Inventario: «Mantener en inventario» – Debe estar desactivado. Lo que hace esa opcion es reservar el stock por determinada cantidad de tiempo mientras el pedido no se ha pagado. Insisto que si un administrador esta cancelando un pedido el stock deberia reponerse y eso no sucede. Pero vale aclarar que la reserva de stock en WooCommerce existe a interfiere con el stock de los pedidos sin pagar.

Ademas siempre debemos asegurarnos que ningun otro pligin este interfiriendo con lo antes mencionado. Son muchos los plugins que se ofrecen y que con diferentes intenciones se meten con la gestion de ordenes y automatizaciones de stock.

Dos diferencias importantes: Cancelaciones manuales o automaticas.

Para WooCommerce las cancelaciones automaticas de pedidos generadas bajo cualquier contexto no son razon para reponer stock por medio de el propio WooCommerce. En cambio la cancelaciones manuales por adminisrtradores si deben reponer stock como ya mencionamos.

Cual seria una cancelacion automatica?

  1. Si tienes mantener inventario activado y se alcanza el limite, la orden se va a cancelar.
  2. Si un gateway de pago crea la orden, descuenta stock por concecuecia pero luego el pago falla y la orden se cancela por un tema del gateway. Es el gateway quien debe reponer el stock. Esto ultimo lo vimos en el sitio de un cliente que tenia un gateway de pago con un banco. Hubo que pedir al desarrollador que haga algo bueno por eso y si cancela la orden que tambien reponga stock.

Vayamos a una solución fácil

Con la siguiente funcion añadiendola a tu archivo functions.php de tu child-theme cada vez que se cancele una orden se va a reponer el stock. 🙂 

remove_filter( 'woocommerce_cancel_unpaid_orders', 'wc_cancel_unpaid_orders' );
add_filter( 'woocommerce_cancel_unpaid_orders', 'override_cancel_unpaid_orders' );

function override_cancel_unpaid_orders() {
$held_duration = get_option( 'woocommerce_hold_stock_minutes' );

if ( $held_duration < 1 || 'yes' !== get_option( 'woocommerce_manage_stock' ) ) { return; } $data_store = WC_Data_Store::load( 'order' ); $unpaid_orders = $data_store->get_unpaid_orders( strtotime( '-' . absint( $held_duration ) . ' MINUTES', current_time( 'timestamp' ) ) );

if ( $unpaid_orders ) {
foreach ( $unpaid_orders as $unpaid_order ) {
$order = wc_get_order( $unpaid_order );

if ( apply_filters( 'woocommerce_cancel_unpaid_order', 'checkout' === $order->get_created_via(), $order ) ) {
//Cancel Order
$order->update_status( 'cancelled', __( 'Unpaid order cancelled - time limit reached.', 'woocommerce' ) );

//Restock
foreach ($order->get_items() as $item_id => $item) {
// Get an instance of corresponding the WC_Product object
$product = $item->get_product();
$qty = $item->get_quantity(); // Get the item quantity
wc_update_product_stock($product, $qty, 'increase');
}
}
}
}
wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );
wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}

Deja un comentario