Saltar al contenido
Volver a recursos
guia · operacion

Cómo evitar quiebres de stock vendiendo en varios canales

Los dos números por canal que deciden cuánto stock ve cada marketplace, cuándo sale el empuje de stock y qué queda fuera del alcance del sistema.

5 de septiembre de 2026
9 min de lectura
Por Equipo Astrobit

Lo que se publica no es tu stock: es tu stock menos el piso

El ERP de Astrobit calcula el número que va a cada canal con dos parámetros del canal. El piso (Integration.floorStock, rotulado "Safe Stock" en pantalla) se resta del disponible antes de publicar. El techo (Integration.ceilStock, rotulado "Tope Stock") limita el número hacia arriba. La operación exacta, en updateForeignStocks, es max(0, disponible − piso) y después min(techo, ese resultado) cuando el techo no es nulo.

El piso viene en 0 por defecto: sin configurarlo, cada canal ve todo lo que tienes. El techo viene nulo, es decir, sin límite. Cuando activas la casilla del piso en la pantalla del canal, el campo parte en 1; cuando activas la del techo, parte en 100. La pantalla además impide que el piso supere al techo y que el techo quede bajo el piso.

La consecuencia de poner un piso de 3 es directa: cuando te quedan 3 unidades, el canal muestra 0 y deja de vender. Esas 3 unidades siguen existiendo en la bodega y siguen visibles en el ERP; lo que dejaron de ser es vendibles por ese canal. Eso es un costo real de venta perdida a cambio de no vender lo que no puedes despachar. No hay un valor correcto universal: el piso tiene que ser del tamaño de lo que se te puede vender entre dos empujes de stock.

Hay un tercer lugar donde vive el piso: cada producto tiene su propio Product.floorStock, también rotulado "Safe Stock", con el texto de ayuda "Vacío = usar configuración global del canal". Cuando está lleno, pisa al del canal. Y pisa al de todos los canales: es una sola columna del producto, no una por canal. Si necesitas proteger un SKU frágil en Mercado Libre pero no en tu tienda propia, el piso por producto no te sirve para eso. El piso por producto se puede cargar masivamente: viaja en la importación de productos, junto a costo, peso y código de barras.

ParámetroDónde se configuraPor defectoQué hace
Safe Stock (canal)Configuración → Canales0Se resta del disponible antes de publicar
Tope Stock (canal)Configuración → CanalesSin límiteCorta el número publicado hacia arriba
Safe Stock (producto)Ficha del productoVacíoReemplaza al del canal, en todos los canales
Stock AutomáticoConfiguración → CanalesApagadoHabilita el empuje de stock a esa tienda
Disponible en MKPConfiguración → CanalesVacíoQué bodegas suman al número del canal

Cuándo sale el empuje de stock, y cuándo no sale

El empuje de stock del ERP no corre por reloj: corre por evento. La cola de eventos del cliente se drena con una llamada a /api/consumer, que aplica los cambios de stock del lote (pedidos ingresados, recepciones, movimientos, ajustes) y recién después llama a updateForeignStocks con las bodegas que se movieron. El drenaje es de a uno por cliente: toma un candado en Redis de 840 segundos y una segunda invocación simultánea recibe 409 y se retira.

Para que un canal reciba el empuje se tienen que cumplir dos condiciones al mismo tiempo. Primero, la tienda tiene que tener encendido "Stock Automático" (ContributorMarketplace.autoStock). Segundo, la bodega que se movió tiene que estar entre las bodegas del canal ("Disponible en MKP") o entre los orígenes configurados de esa tienda. Si el movimiento ocurrió en una bodega que ese canal no mira, el canal no se entera y no debe enterarse.

En el payload viajan solo los SKU cuyo stock interno cambió en ese lote. El resto del catálogo no se reenvía. Hay dos excepciones. Una: la sincronización manual, que reenvía todo aunque nada haya cambiado, en tandas de 50 productos. La otra: las cancelaciones de Mercado Libre, que fuerzan un reenvío sin cambio interno de stock, con el propósito explícito de pisar el restock automático del marketplace con el número correcto.

Cada empuje se encola con attempts: 1. Un intento, sin reintentos. Si el canal está caído en ese segundo, ese empuje se pierde y el canal queda publicando un número viejo hasta el próximo movimiento de ese SKU. La recuperación es manual y está en Inventario → Productos: "Sincronizar" para un producto, "Sincronizar Masivo" para un canal completo. Vale la pena tenerlo mapeado como procedimiento y no descubrirlo el día que se necesita.

Qué número viaja: disponible, packs y pareos

Lo que se publica es el disponible (Stock.quantity), no el físico contado en bodega. El disponible se descuenta cuando el pedido entra al ERP, antes del picking, antes de que nadie toque la caja. Ese es el mecanismo que hace que una venta en un canal baje el número publicado en los otros: no es una regla especial, es que todos los canales leen el mismo disponible. El campo outbound, que registra unidades comprometidas a enviar, es informativo y el esquema es explícito en que nunca se le entrega al stock publicado.

Los packs no tienen stock propio: cuando se mueve un material, el ERP recalcula cada pack que lo usa como un valor absoluto, igual al mínimo entre los materiales de piso(stock del material / unidades por pack). Un pack no puede tener otro pack como material: el ERP rechaza la carga con el mensaje «No se permiten packs de packs».

El SKU con el que viaja cada producto sale de la pestaña "Pareos" de la ficha: todos los pareos de ese canal, cada uno con su cantidad. Si el producto no tiene pareo en ese canal, se usa su SKU propio. Si no tiene ninguno de los dos, no se publica nada para ese producto. Y hay una trampa concreta: si dos productos internos apuntan al mismo SKU destino en un canal, solo viaja la cantidad del primero y el segundo se descarta silenciosamente. Un pareo duplicado no da error; da un número equivocado.

Cuántos días te quedan: el reporte Cobertura Simple

El reporte vive en Reportes → Inventario y se llama "Cobertura Simple". La ventana de análisis se elige entre 7 y 365 días, con 30 días por defecto en pantalla y accesos rápidos a 14, 30, 60 y 120 más una opción "Personalizado". Los límites están escritos dos veces, en el cliente y en el servidor, y por la misma razón declarada en el código: las ventanas muy cortas dan estimaciones ruidosas y las muy largas se salen del historial que el sistema conserva.

El cálculo es corto. "Media Ventas" es unidades vendidas dividido por los días de la ventana. "Quiebre en" es el stock dividido por esa media. Dos precisiones que cambian cómo se lee la tabla: el "Stock Total" del reporte suma el disponible más lo que viene en camino, así que "Quiebre en" es optimista por diseño; y cuando un SKU no vendió nada en la ventana, "Quiebre en" dice "sin ventas", no un número gigante. "Sin ventas" significa que el sistema no sabe, no que tengas cobertura de sobra. Cuando los días restantes son cero o menos, la celda dice "QUIEBRE".

Lo que cuenta como venta también importa. Solo suman los movimientos de stock atados a una línea de pedido. Los despachos entre bodegas no cuentan como venta, y por eso una bodega de distribución pura aparece con media de ventas 0 aunque mueva miles de unidades al mes.

La alerta que llega antes del quiebre

La alerta se configura en Configuración → Alertas, sección "Cobertura de Stock", y también desde el menú del propio reporte. Cada alerta tiene cuatro campos: destinatarios, bodegas (se suman entre ellas), "Quiebre en (días)" como umbral, y la ventana de ventas, que acepta 7, 14, 30 o 60 días. Una alerta nueva parte con umbral 7 y ventana 14.

El correo sale cuando un SKU vendió al menos una unidad en la ventana y sus días restantes quedaron por debajo del umbral, ordenado por los que quiebran primero. La alerta calcula con el disponible puro, sin sumar lo que viene en camino: mide más apretado que el reporte. La corre una tarea programada, no el navegador de nadie.

Reponer: la fórmula que usa el ERP

Cuando pides recomendaciones de reposición, el ERP calcula por producto: menor(mayor(mayor(techo(vendidas/ventana × horizonte), 1), surtido mínimo), surtido máximo), y le resta el stock que ya tienes contando lo que viene en camino. El "surtido" es el mínimo y máximo por bodega que configuras en Inventario. Por eso un producto sin ventas igual aparece recomendado si está bajo su surtido mínimo.

Para solicitudes recurrentes hay dos estrategias, y son dos, no más: "Promedio móvil", que usa la fórmula de arriba con la ventana histórica y el horizonte que le des, y "Cumplir assortment", que ignora las ventas y pide lo que falte para llegar al surtido.

Aparte está la reacción automática al quiebre. En cada bodega puedes encender "Solicitar stock automáticamente ante quiebres" (apagado por defecto): cuando una venta deja esa bodega con disponible negativo, el ERP crea al instante la solicitud de envío a sus bodegas proveedoras, en el orden que configuraste, sin esperar al picking. El interruptor hermano es "Proteger el surtido mínimo de esta bodega": por defecto una bodega proveedora sí entrega por debajo de su surtido mínimo, pero solo como último recurso, después de gastar el stock sobrante de todas las demás.

Qué no resuelve este sistema

  • No evita la carrera. Dos canales pueden vender la última unidad en el mismo segundo. El ERP no reserva unidades para ningún canal: Stock.reserved está marcada como muerta en el esquema. El empuje de stock sale después de que la venta ya ocurrió. Contra esa carrera solo está el piso, y el piso es un amortiguador, no una garantía.
  • Un empuje fallido no se reintenta. Se encola con un intento y se descarta al fallar. Se recupera con "Sincronizar Masivo", a mano.
  • La cobertura no tiene estacionalidad. Es un promedio plano de la ventana elegida. El ERP sí tiene tres métodos de proyección —promedio móvil de 3 meses, tendencia lineal por mínimos cuadrados y estacional año contra año, que necesita 13 meses de historial y hasta ahí cae de vuelta a la lineal—, pero son de las proyecciones financieras (Flujo de Caja y Estado de Resultados). El inventario no los usa.
  • La venta se atribuye a la bodega del pedido, no a la que despachó. Esa bodega se fija al ingresar el pedido según el canal. En un cumplimiento cruzado, la cobertura le carga la venta a la bodega equivocada.
  • El piso por cobertura predicha no tiene pantalla. El campo Warehouse.autoSupplierCoverDays existe y, con un valor, cada bodega proveedora se guarda techo(media de ventas × días de tránsito). Viene nulo y no hay interfaz para configurarlo.
  • "Permitir sobreventa" es solo del POS. Viene apagado y controla si la caja deja agregar un producto sin stock. No tiene efecto sobre lo que aceptan los marketplaces.
  • La entrega final al marketplace no es del ERP. El ERP calcula el número y encola el trabajo; quien lo entrega a cada API es un worker que corre aparte.