Reservas en la tabla de productos WooCommerce: carrito y límites de cantidad
Las reservas (backorders) en una tabla de productos WooCommerce siguen reglas más estrictas que en la página de producto. Un producto con stock controlado en 0 que admite reservas no muestra el botón Añadir al carrito (Add to cart), el campo de cantidad se detiene en el número de unidades en stock y la columna Estado del stock (Stock status) muestra la misma marca de verificación para En reserva (On backorder) que para En stock (In stock). Nada de esto es un ajuste que hayas pasado por alto: la tabla construye su botón y su campo de cantidad a partir de la cantidad en stock. A continuación se explica con exactitud cómo decide, y cómo vender productos en reserva desde la tabla sin editar los archivos del plugin.
Cómo decide la tabla si muestra Añadir al carrito
Para cada fila, la tabla comprueba el producto y después construye en el navegador un campo de cantidad y un botón. Para los productos simples y para las filas de variaciones de la ventana emergente de variaciones, las reglas son estas:
| Producto | Botón | Cantidad máxima |
|---|---|---|
| No se puede comprar (sin precio) o Agotado (Out of stock) | No | - |
| Stock sin controlar, estado En stock (In stock) o En reserva (On backorder) | Sí | 9999 |
| Stock controlado, cantidad superior a 0 | Sí | La cantidad en stock, aunque se admitan reservas |
| Stock controlado, cantidad 0, reservas permitidas | No | - |
| Stock controlado, cantidad inferior a 0 (después de recibir reservas) | Sí, pero falla al añadir | La cantidad negativa |
La última fila explica un mensaje desconcertante. El campo de cantidad recibe como máximo el número de stock y, cuando un cliente pide más, la tabla lo rechaza antes de contactar con el servidor con el mensaje Cantidad máxima de productos (Max count of products is:) seguido de ese número, por ejemplo -3. Los productos variables y agrupados muestran un botón que abre su ventana emergente; se oculta cuando el producto padre controla su propio stock y esa cantidad es 0. Los productos externos siempre muestran su botón.
Por tanto, la tabla está pensada para vender lo que hay en el almacén. Si las reservas forman parte de tu negocio, cámbiala de una de las formas siguientes.
Sin código: dejar de controlar el stock de los productos en reserva
Si no necesitas que WooCommerce cuente el stock de un producto, ábrelo, ve a Inventario (Inventory), desactiva el control de stock (Realizar seguimiento de la cantidad en stock de este producto (Track stock quantity for this product) en las versiones actuales de WooCommerce) y establece el estado del stock en En reserva (On backorder). La tabla mostrará entonces el botón y permitirá hasta 9999 por clic. El precio a pagar es que WooCommerce deja de contar el stock de ese producto y no marca sus líneas de pedido como en reserva. Cuando necesites ambas cosas, el recuento de stock y las reservas, usa el fragmento de la sección siguiente.
Mostrar Añadir al carrito en los productos que admiten reservas
El fragmento sustituye el contenido de la columna Carrito (Cart) mediante el filtro woot_profile_extend, solo para los productos y variaciones que controlan el stock y admiten reservas (Permitir (Allow) o Permitir, pero avisar al cliente (Allow, but notify customer)). Para ellos imprime el mismo marcador que la tabla imprime para cualquier producto simple, con la cantidad vacía, de modo que el propio script de la tabla construye su campo de cantidad, su casilla y su botón habituales sin límite de stock. Todos los demás productos conservan el botón normal.
/*
* Products tables: Add to cart for products that track stock and allow
* backorders, also at 0 or negative stock, without a quantity cap.
* Child theme functions.php or a code snippets plugin.
*/
add_filter('woot_profile_extend', function ($fields, $action, $shortcode_args) {
if (!isset($fields['add_to_cart']['action'])) {
return $fields;
}
$original = $fields['add_to_cart']['action'];
$fields['add_to_cart']['action'] = function ($post_id) use ($original) {
$product = wc_get_product($post_id);
if ($product
&& $product->is_type(['simple', 'variation'])
&& $product->is_purchasable()
&& $product->managing_stock()
&& $product->backorders_allowed()) {
// As the table option "After to cart adding":
// 0 stay on the page, 1 redirect to the cart, 2 redirect to the checkout
$redirect = 0;
// The table's own button placeholder; an empty quantity means no cap
return sprintf(
'<span class="woot-button-buy-pack" data-instant-redirect="%d" data-sold-individually="%d" data-about="simple,%d,,%s"></span>',
$redirect,
(int) $product->is_sold_individually(),
$product->get_id(),
esc_attr($product->get_sku())
);
}
return $original($post_id);
};
return $fields;
}, 33, 3);
Notas sobre este fragmento:
- Establece
$redirectcon el valor que usa tu tabla en Opciones (Options) → Después de añadir al carrito (After to cart adding); el fragmento no puede leer esa opción por ti. - WooCommerce sigue comprobando cada adición. Los productos se añaden mediante la propia solicitud de añadir al carrito de WooCommerce, así que solo se aceptan porque el producto admite reservas. Con Permitir, pero avisar al cliente (Allow, but notify customer), el carrito y el pedido los marcan como en reserva, igual que en la página de producto.
- Un producto variable cuyo stock se controla en el producto padre con valor 0 sigue ocultando el botón de su ventana emergente. Controla el stock en las variaciones.
- El fragmento reutiliza el marcado del botón de la tabla. Pruébalo después de las actualizaciones importantes del plugin, como harías con cualquier personalización.
No consigas el mismo resultado editando profiles/woocommerce/views/add_to_cart.php o woocommerce-cart.js en la carpeta del plugin. Funciona hasta la siguiente actualización, que restaura en silencio los archivos originales.
Mostrar «En reserva» en la columna Estado del stock
La columna Estado del stock (Stock status) muestra una marca de verificación tanto para En stock (In stock) como para En reserva (On backorder), y una cruz para Agotado (Out of stock). Para avisar a los clientes de que un producto se enviará más tarde, sustituye la salida de la columna con el mismo filtro. El texto procede de WooCommerce, por lo que ya está traducido al idioma de tu tienda:
/*
* Products tables: show "On backorder" instead of the check mark
* in the Stock status column. Child theme functions.php or a code snippets plugin.
*/
add_filter('woot_profile_extend', function ($fields, $action, $shortcode_args) {
if (isset($fields['stock_status']['action'])) {
$fields['stock_status']['action'] = function ($post_id) {
$product = wc_get_product($post_id);
$status = $product ? $product->get_stock_status() : 'outofstock';
if ('onbackorder' === $status) {
$labels = wc_get_product_stock_status_options();
return '<span class="woot-stock-backorder">' . esc_html($labels['onbackorder']) . '</span>';
}
if ('instock' === $status) {
return '<span class="woot-html-check"><i class="woot-icon"></i></span>';
}
return '<span class="woot-html-cross"><i class="woot-icon"></i></span>';
};
}
return $fields;
}, 33, 3);
Da estilo a la etiqueta con la clase woot-stock-backorder en la pestaña CSS personalizado (Custom CSS) de la tabla o en tu tema, por ejemplo en naranja.
Productos en reserva que faltan en la tabla
Si los productos en reserva no aparecen en absoluto, revisa la pestaña Predefinición (Predefinition). Su interruptor Solo en stock (In stock only) conserva únicamente los productos cuyo estado del stock es exactamente En stock (In stock), por lo que oculta los productos en reserva junto con los agotados (consulta cómo mostrar solo los productos en stock). El interruptor Estado del stock (Stock status) del filtro del front-end funciona de otro modo: oculta solo los productos Agotado (Out of stock). Para ocultar únicamente los productos agotados en una tabla sin filtro, desactiva Solo en stock (In stock only) y añade esto:
/*
* Products tables: hide out-of-stock products, keep products on backorder.
* Child theme functions.php or a code snippets plugin.
*/
add_filter('woot_wp_query_args', function ($args, $table_id) {
if (in_array((int) $table_id, [5, 8], true)) { // IDs of your tables
$args['meta_query'][] = [
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => '!=',
];
}
return $args;
}, 10, 2);
Límites de cantidad: stock, máximo personalizado y plugins de mín/máx/paso
El campo de cantidad de la tabla siempre empieza en 1 y avanza de 1 en 1. Su máximo es la cantidad en stock para los productos con stock controlado y 9999 en los demás; en los productos que se venden de forma individual, el campo queda bloqueado en 1. Pedir más que el máximo muestra Cantidad máxima de productos (Max count of products is:) sin añadir nada. Elevar el máximo por encima del stock solo tiene sentido para los productos que admiten reservas, algo que el fragmento anterior ya hace, porque el propio WooCommerce rechaza cantidades superiores al stock en todos los demás.
Para fijar un máximo inferior por clic, por ejemplo 10, cambia los campos después de que la tabla haya dibujado sus filas:
/*
* Products tables: at most 10 items per click (or the stock, if lower).
* Site footer: a JavaScript snippet in a code snippets plugin,
* or the footer scripts field of your theme.
*/
document.addEventListener('table23-after-build-rows', function (e) {
var table = e.detail.otable.table;
// wait until the table has created its quantity boxes
setTimeout(function () {
table.querySelectorAll('.woot-add-to-cart-input').forEach(function (input) {
var max = parseInt(input.getAttribute('max'), 10) || 10;
input.setAttribute('max', Math.min(max, 10));
});
}, 0);
});
Esto limita un clic, no el pedido: el cliente puede volver a hacer clic. Un límite real por pedido corresponde a WooCommerce, normalmente mediante un plugin de reglas de cantidad.
Estos plugins establecen valores mínimo, máximo y de paso en los campos de cantidad propios de WooCommerce. El campo de la tabla no lee esos valores. Si el plugin también comprueba las cantidades cuando se añade un producto al carrito, mediante la validación de añadir al carrito de WooCommerce, una cantidad incorrecta procedente de la tabla se rechaza y la tabla muestra su mensaje de que el producto no se puede añadir; el campo en sí sigue empezando en 1 y avanzando de 1 en 1. Si necesitas el campo del plugin en la tabla, muestra el formulario de añadir al carrito del propio producto en una columna personalizada, como se describe en cómo añadir una columna personalizada a las tablas.
Lista de comprobación
- Productos en reserva con stock controlado en 0 o menos: el fragmento
woot_profile_extendpara la columna Carrito (Cart) está activo, o el control de stock está desactivado para ellos. $redirecten el fragmento coincide con Después de añadir al carrito (After to cart adding) de tu tabla.- Solo en stock (In stock only) en Predefinición está desactivado si hay que mostrar los productos en reserva.
- La columna Estado del stock (Stock status) muestra En reserva (On backorder) donde corresponde.
- Probado sin sesión iniciada, tras vaciar la caché de páginas: aparece el botón, se puede añadir más que la cantidad en stock y, con Permitir, pero avisar al cliente (Allow, but notify customer), el carrito marca los artículos como en reserva.
Si un producto en reserva sigue sin poder añadirse desde la tabla, pregunta en el foro de soporte de WOOT indicando sus ajustes de stock y el mensaje que muestra la tabla.