Stock de Productos por Almacén
Consulta la cantidad de stock disponible por producto en un almacén específico. Este endpoint es esencial para verificar disponibilidad antes de crear pedidos.
/v1/client/products/stockEste endpoint te permite obtener la cantidad de stock disponible por producto en el almacén seleccionado. Es necesario proporcionar el header Authorization con el token Bearer obtenido previamente y también proporcionar un query param con el ID del almacén que quieres consultar.
Encabezados
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
Authorization | string | ✅ Sí | Token Bearer obtenido del endpoint /token/generate |
Parámetros de Query
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
warehouse_id | integer | ✅ Sí | ID del almacén a consultar |
Ejemplos
- cURL
- JavaScript
- Python
curl -X GET "https://apisandbox.eonwms.com/v1/client/products/stock?warehouse_id=1" \
-H "Authorization: Bearer TU_TOKEN"
const warehouseId = 1;
const response = await fetch(
`https://apisandbox.eonwms.com/v1/client/products/stock?warehouse_id=${warehouseId}`,
{
method: 'GET',
headers: {
'Authorization': 'Bearer TU_TOKEN'
}
}
);
const stockData = await response.json();
// Mostrar información de stock
stockData.data.forEach(product => {
const { sku, description, stock } = product.attributes;
console.log(`SKU: ${sku}`);
console.log(`Producto: ${description}`);
console.log(`Stock disponible: ${stock.quantity}`);
console.log('---');
});
// Verificar disponibilidad de un SKU específico
function verificarDisponibilidad(sku, cantidadRequerida) {
const producto = stockData.data.find(
p => p.attributes.sku === sku
);
if (!producto) {
return { disponible: false, mensaje: 'Producto no encontrado' };
}
const stockDisponible = producto.attributes.stock.quantity;
if (stockDisponible >= cantidadRequerida) {
return { disponible: true, stockDisponible };
} else {
return {
disponible: false,
stockDisponible,
mensaje: `Stock insuficiente. Disponible: ${stockDisponible}`
};
}
}
import requests
warehouse_id = 1
response = requests.get(
f'https://apisandbox.eonwms.com/v1/client/products/stock?warehouse_id={warehouse_id}',
headers={
'Authorization': 'Bearer TU_TOKEN'
}
)
stock_data = response.json()
# Mostrar información de stock
for product in stock_data['data']:
attrs = product['attributes']
print(f"SKU: {attrs['sku']}")
print(f"Producto: {attrs['description']}")
print(f"Stock disponible: {attrs['stock']['quantity']}")
print("---")
# Verificar disponibilidad de múltiples productos
def verificar_pedido(items_pedido):
"""
items_pedido: lista de diccionarios con 'sku' y 'cantidad'
"""
resultados = []
for item in items_pedido:
producto = next(
(p for p in stock_data['data']
if p['attributes']['sku'] == item['sku']),
None
)
if not producto:
resultados.append({
'sku': item['sku'],
'disponible': False,
'mensaje': 'Producto no encontrado'
})
continue
stock_disponible = producto['attributes']['stock']['quantity']
cantidad_requerida = item['cantidad']
if stock_disponible >= cantidad_requerida:
resultados.append({
'sku': item['sku'],
'disponible': True,
'stock_disponible': stock_disponible
})
else:
resultados.append({
'sku': item['sku'],
'disponible': False,
'stock_disponible': stock_disponible,
'faltante': cantidad_requerida - stock_disponible
})
return resultados
# Ejemplo de uso
pedido = [
{'sku': 'THISISSKU01', 'cantidad': 5},
{'sku': 'THISISSKU2', 'cantidad': 10}
]
disponibilidad = verificar_pedido(pedido)
for item in disponibilidad:
print(f"SKU {item['sku']}: {'Disponible' if item['disponible'] else 'No disponible'}")
Respuestas
200Éxito - Lista de productos con stock
{
"data": [
{
"id": "1",
"type": "product",
"attributes": {
"sku": "THISISSKU01",
"description": "WINGSPAN BOARDGAME",
"stock": {
"quantity": 997
}
}
},
{
"id": "2",
"type": "product",
"attributes": {
"sku": "THISISSKU2",
"description": "WINGSPAN OCEANIA EXPANTION",
"stock": {
"quantity": 500
}
}
}
]
}
401No autorizado - Token inválido
{
"code": 401,
"fault": {
"arguments": {
"Authorization": "invalid"
},
"type": "InvalidAuthorizationException",
"message": "La solicitud no está autorizada, el token de acceso es inválido."
}
}
422No procesable - Almacén inválido
{
"code": 422,
"fault": {
"arguments": {
"warehouse": "invalid"
},
"type": "warehouseParamIsInvalid",
"message": "el cliente no tiene acceso al almacén seleccionado."
}
}
Estructura de la Respuesta
Cada producto en el array data incluye:
Información del Producto
- id: ID interno del producto
- type: Siempre será "product"
- attributes: Contiene los detalles del producto
- sku: Código único del producto (Stock Keeping Unit)
- description: Descripción del producto
- stock: Información de inventario
- quantity: Cantidad disponible en el almacén
Consideraciones de Stock
Stock en Tiempo Real
El stock mostrado es en tiempo real y considera:
- ✅ Inventario físico disponible
- ✅ Reservas de pedidos en proceso
- ✅ Ajustes de inventario recientes
Stock NO Incluye
- ❌ Productos en tránsito al almacén
- ❌ Productos dañados o en cuarentena
- ❌ Reservas futuras programadas
Casos de Uso Comunes
1. Verificación Pre-Pedido
async function validarDisponibilidadPedido(warehouseId, productos) {
// Obtener stock actual
const response = await fetch(
`https://apisandbox.eonwms.com/v1/client/products/stock?warehouse_id=${warehouseId}`,
{
headers: { 'Authorization': 'Bearer TU_TOKEN' }
}
);
const stockData = await response.json();
const problemas = [];
// Verificar cada producto del pedido
for (const item of productos) {
const productoEnStock = stockData.data.find(
p => p.attributes.sku === item.sku
);
if (!productoEnStock) {
problemas.push({
sku: item.sku,
tipo: 'NO_EXISTE',
mensaje: `El producto ${item.sku} no existe en el almacén`
});
continue;
}
const disponible = productoEnStock.attributes.stock.quantity;
if (disponible < item.cantidad) {
problemas.push({
sku: item.sku,
tipo: 'STOCK_INSUFICIENTE',
mensaje: `Solo hay ${disponible} unidades disponibles, se requieren ${item.cantidad}`,
disponible,
requerido: item.cantidad,
faltante: item.cantidad - disponible
});
}
}
return {
pedidoValido: problemas.length === 0,
problemas
};
}
2. Monitor de Stock Bajo
async function monitorearStockBajo(warehouseId, umbralMinimo = 10) {
const response = await fetch(
`https://apisandbox.eonwms.com/v1/client/products/stock?warehouse_id=${warehouseId}`,
{
headers: { 'Authorization': 'Bearer TU_TOKEN' }
}
);
const stockData = await response.json();
const productosConStockBajo = stockData.data
.filter(p => p.attributes.stock.quantity <= umbralMinimo)
.map(p => ({
sku: p.attributes.sku,
descripcion: p.attributes.description,
stockActual: p.attributes.stock.quantity,
estado: p.attributes.stock.quantity === 0 ? 'AGOTADO' : 'STOCK_BAJO'
}));
if (productosConStockBajo.length > 0) {
console.log(`⚠️ Alerta: ${productosConStockBajo.length} productos con stock bajo`);
productosConStockBajo.forEach(p => {
console.log(`- ${p.sku}: ${p.stockActual} unidades (${p.estado})`);
});
}
return productosConStockBajo;
}
3. Reporte de Inventario
async function generarReporteInventario(warehouseId) {
const response = await fetch(
`https://apisandbox.eonwms.com/v1/client/products/stock?warehouse_id=${warehouseId}`,
{
headers: { 'Authorization': 'Bearer TU_TOKEN' }
}
);
const stockData = await response.json();
// Calcular métricas
const totalSKUs = stockData.data.length;
const totalUnidades = stockData.data.reduce(
(sum, p) => sum + p.attributes.stock.quantity, 0
);
const skusAgotados = stockData.data.filter(
p => p.attributes.stock.quantity === 0
).length;
const skusConStock = totalSKUs - skusAgotados;
// Generar reporte
const reporte = {
almacen: warehouseId,
fecha: new Date().toISOString(),
resumen: {
totalSKUs,
skusConStock,
skusAgotados,
totalUnidades,
porcentajeDisponibilidad: ((skusConStock / totalSKUs) * 100).toFixed(2) + '%'
},
detalleProductos: stockData.data.map(p => ({
sku: p.attributes.sku,
descripcion: p.attributes.description,
stock: p.attributes.stock.quantity,
estado: p.attributes.stock.quantity === 0 ? 'Agotado' :
p.attributes.stock.quantity < 10 ? 'Stock Bajo' : 'Disponible'
}))
};
return reporte;
}
4. Sincronización con Sistema Externo
class SincronizadorInventario {
constructor(token, warehouseId) {
this.token = token;
this.warehouseId = warehouseId;
}
async obtenerStockChronos() {
const response = await fetch(
`https://apisandbox.eonwms.com/v1/client/products/stock?warehouse_id=${this.warehouseId}`,
{
headers: { 'Authorization': `Bearer ${this.token}` }
}
);
return await response.json();
}
async sincronizarConSistemaLocal(actualizarCallback) {
try {
const stockChronos = await this.obtenerStockChronos();
for (const producto of stockChronos.data) {
const { sku, stock } = producto.attributes;
// Actualizar sistema local
await actualizarCallback(sku, stock.quantity);
}
return {
exito: true,
productosSincronizados: stockChronos.data.length
};
} catch (error) {
return {
exito: false,
error: error.message
};
}
}
}
// Uso
const sincronizador = new SincronizadorInventario('TU_TOKEN', 1);
await sincronizador.sincronizarConSistemaLocal(async (sku, cantidad) => {
// Actualizar tu base de datos local
await db.productos.update({ sku }, { stockChronos: cantidad });
});
Mejores Prácticas
Frecuencia de Consulta
- Antes de cada pedido: Siempre verifica el stock
- Actualizaciones periódicas: Cada 15-30 minutos para sincronización
- Alertas: Configura verificaciones cada hora para productos críticos
Manejo de Stock Cero
function manejarStockAgotado(sku, alternativas = []) {
// Opciones cuando no hay stock:
// 1. Buscar en otros almacenes
const buscarEnOtrosAlmacenes = async () => {
const warehouses = await obtenerAlmacenesDisponibles();
for (const wh of warehouses) {
const stock = await verificarStock(wh.id, sku);
if (stock > 0) return { almacenId: wh.id, stock };
}
return null;
};
// 2. Sugerir productos alternativos
const sugerirAlternativas = () => {
return alternativas.filter(alt => alt.stock > 0);
};
// 3. Permitir backorder (si está habilitado)
const permitirBackorder = () => {
return {
mensaje: "Producto disponible para pedido. Tiempo de entrega extendido.",
tiempoEstimado: "7-10 días"
};
};
}
Si necesitas verificar múltiples SKUs, es más eficiente hacer una sola consulta y filtrar localmente en lugar de hacer múltiples llamadas por SKU individual.
El stock puede cambiar rápidamente. Siempre verifica la disponibilidad justo antes de crear un pedido, no confíes en datos cacheados por mucho tiempo.
Cuando creas un pedido, el stock se reserva automáticamente. Si el pedido se cancela o no se procesa, el stock se libera después de un tiempo determinado.