Gestión de Inventario
Gestión de Inventario
Section titled “Gestión de Inventario”Dominio: https://test-api-factura.edw-dev.com
Dominio: https://api-financiero.e-dinky.com
Este endpoint permite agregar inventario a items existentes y gestionar el stock disponible.
Agregar Inventario
Section titled “Agregar Inventario”Endpoint: POST /api/v1/items/add-income
Descripción: Agrega inventario a un item existente, registrando un movimiento de entrada en el kardex.
Headers Requeridos
Section titled “Headers Requeridos”Accept: application/jsonContent-Type: application/jsonAuthorization: Bearer {token}
Cuerpo de la Solicitud
Section titled “Cuerpo de la Solicitud”Campo | Tipo | Requerido | Descripción |
---|---|---|---|
code | string | Sí | Código del item |
quantity | integer | Sí | Cantidad a agregar al inventario |
cost | number | No | Costo unitario del inventario |
description | string | No | Descripción del movimiento |
reference | string | No | Referencia externa (factura de compra, etc.) |
date | string | No | Fecha del movimiento (YYYY-MM-DD), por defecto hoy |
Ejemplos de Solicitud
Section titled “Ejemplos de Solicitud”Ingreso Básico
Section titled “Ingreso Básico”{ "code": "PROD-001", "quantity": 50, "cost": 20.00, "description": "Ingreso de inventario por compra"}
Ingreso con Referencia
Section titled “Ingreso con Referencia”{ "code": "PROD-001", "quantity": 100, "cost": 18.50, "description": "Compra a proveedor ABC", "reference": "COMP-2024-001", "date": "2024-01-15"}
Ingreso de Inventario Inicial
Section titled “Ingreso de Inventario Inicial”{ "code": "PROD-002", "quantity": 200, "cost": 15.75, "description": "Inventario inicial del producto", "reference": "INV-INICIAL-001"}
Ejemplos de Implementación
Section titled “Ejemplos de Implementación”curl -X POST "https://dev-facturacion.e-dinky.test/api/v1/items/add-income" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your_token_here" \ -d '{ "code": "PROD-001", "quantity": 50, "cost": 20.00, "description": "Ingreso de inventario por compra" }'
use Illuminate\Support\Facades\Http;
$inventoryData = [ 'code' => 'PROD-001', 'quantity' => 50, 'cost' => 20.00, 'description' => 'Ingreso de inventario por compra', 'reference' => 'COMP-2024-001', 'date' => now()->format('Y-m-d')];
$response = Http::withHeaders([ 'Accept' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json'])->post('https://dev-facturacion.e-dinky.test/api/v1/items/add-income', $inventoryData);
if ($response->successful()) { $result = $response->json(); echo "Inventario agregado. Nuevo stock: " . $result['payload']['new_stock'];} else { echo "Error: " . $response->json()['message'];}
const axios = require('axios');
const addInventory = async (token, inventoryData) => { try { const response = await axios.post('https://dev-facturacion.e-dinky.test/api/v1/items/add-income', inventoryData, { headers: { 'Accept': 'application/json', 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); return response.data; } catch (error) { console.error('Error:', error.response.data); throw error; }};
// Usoconst inventoryData = { code: 'PROD-001', quantity: 50, cost: 20.00, description: 'Ingreso de inventario por compra', reference: 'COMP-2024-001'};
addInventory(token, inventoryData) .then(result => { console.log('Inventario agregado:', result.payload.new_stock); }) .catch(error => { console.error('Error al agregar inventario:', error.response?.data?.message); });
Respuesta Exitosa (201 Created)
Section titled “Respuesta Exitosa (201 Created)”{ "message": "Inventario agregado exitosamente", "status": "CREATED", "payload": { "item_code": "PROD-001", "movement_id": "MOV-2024-001", "quantity_added": 50, "cost_per_unit": 20.00, "total_cost": 1000.00, "previous_stock": 25, "new_stock": 75, "movement_date": "2024-01-15T10:30:00Z", "description": "Ingreso de inventario por compra", "reference": "COMP-2024-001" }}
Respuesta de Error (404 Not Found)
Section titled “Respuesta de Error (404 Not Found)”{ "message": "Item no encontrado", "status": "NOT_FOUND", "error": "El item con código 'PROD-999' no existe"}
Respuesta de Error (422 Unprocessable Entity)
Section titled “Respuesta de Error (422 Unprocessable Entity)”{ "message": "Error de validación", "status": "UNPROCESSABLE_ENTITY", "errors": { "quantity": [ "La cantidad debe ser mayor a 0" ], "code": [ "El item no permite control de inventario" ] }}
Códigos de Respuesta
Section titled “Códigos de Respuesta”Código | Descripción |
---|---|
201 | Inventario agregado exitosamente |
400 | Error en los datos enviados |
401 | Token de autorización inválido |
404 | Item no encontrado |
422 | Error de validación |
500 | Error interno del servidor |
Validaciones
Section titled “Validaciones”Campos Obligatorios
Section titled “Campos Obligatorios”code
: Debe existir en el sistemaquantity
: Debe ser un número entero positivo
Reglas de Negocio
Section titled “Reglas de Negocio”- El item debe tener
allow_accounting = 1
- El item debe ser de tipo
PRODUCT
- La cantidad debe ser mayor a 0
- El costo debe ser mayor o igual a 0 (puede ser 0 para donaciones)
- La fecha no puede ser futura
Tipos de Movimientos de Inventario
Section titled “Tipos de Movimientos de Inventario”1. Compras
Section titled “1. Compras”{ "code": "PROD-001", "quantity": 100, "cost": 25.00, "description": "Compra a Proveedor XYZ", "reference": "FACT-PROV-001"}
2. Inventario Inicial
Section titled “2. Inventario Inicial”{ "code": "PROD-001", "quantity": 500, "cost": 20.00, "description": "Inventario inicial - migración de sistema", "reference": "INV-INICIAL"}
3. Devoluciones de Clientes
Section titled “3. Devoluciones de Clientes”{ "code": "PROD-001", "quantity": 5, "cost": 30.00, "description": "Devolución de cliente - producto defectuoso", "reference": "DEV-CLI-001"}
4. Ajustes Positivos
Section titled “4. Ajustes Positivos”{ "code": "PROD-001", "quantity": 10, "cost": 22.50, "description": "Ajuste por diferencia en inventario físico", "reference": "AJ-POS-001"}
5. Donaciones Recibidas
Section titled “5. Donaciones Recibidas”{ "code": "PROD-001", "quantity": 25, "cost": 0.00, "description": "Donación recibida de empresa ABC", "reference": "DON-REC-001"}
Gestión de Costos
Section titled “Gestión de Costos”Costo Promedio Ponderado
Section titled “Costo Promedio Ponderado”El sistema calcula automáticamente el costo promedio ponderado:
Nuevo Costo Promedio = (Stock Anterior × Costo Anterior + Cantidad Nueva × Costo Nuevo) / Stock Total
Ejemplo:
Section titled “Ejemplo:”- Stock anterior: 50 unidades a $20.00 = $1,000.00
- Ingreso nuevo: 30 unidades a $25.00 = $750.00
- Stock total: 80 unidades
- Nuevo costo promedio: ($1,000.00 + $750.00) / 80 = $21.875
Consultar Costo Actual
Section titled “Consultar Costo Actual”curl -X GET "https://dev-facturacion.e-dinky.test/api/v1/items/PROD-001" \ -H "Authorization: Bearer $TOKEN"
La respuesta incluirá:
{ "payload": { "code": "PROD-001", "current_cost": 21.88, "count_available": 80, "total_value": 1750.00 }}
Casos de Uso Avanzados
Section titled “Casos de Uso Avanzados”Ingreso Masivo con Lote
Section titled “Ingreso Masivo con Lote”// PHP - Agregar múltiples items$items = [ ['code' => 'PROD-001', 'quantity' => 50, 'cost' => 20.00], ['code' => 'PROD-002', 'quantity' => 30, 'cost' => 15.50], ['code' => 'PROD-003', 'quantity' => 75, 'cost' => 35.25]];
foreach ($items as $item) { $item['description'] = 'Compra lote ' . date('Y-m-d'); $item['reference'] = 'LOTE-' . date('Ymd');
$response = Http::withHeaders([ 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json' ])->post('https://dev-facturacion.e-dinky.test/api/v1/items/add-income', $item);
if ($response->successful()) { echo "✓ {$item['code']}: {$item['quantity']} unidades agregadas\n"; } else { echo "✗ Error en {$item['code']}: " . $response->json()['message'] . "\n"; }}
Validación Previa
Section titled “Validación Previa”// JavaScript - Validar antes de agregarconst validateBeforeAdd = async (token, itemCode, quantity) => { try { // 1. Verificar que el item existe y permite inventario const itemResponse = await axios.get(`https://dev-facturacion.e-dinky.test/api/v1/items/${itemCode}`, { headers: { 'Authorization': `Bearer ${token}` } });
const item = itemResponse.data.payload;
if (item.type !== 'PRODUCT') { throw new Error('Solo se puede agregar inventario a productos'); }
if (item.allow_accounting !== 1) { throw new Error('El item no permite control de inventario'); }
// 2. Agregar inventario const addResponse = await axios.post('https://dev-facturacion.e-dinky.test/api/v1/items/add-income', { code: itemCode, quantity: quantity, cost: 20.00, description: 'Ingreso validado' }, { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } });
return { success: true, data: addResponse.data };
} catch (error) { return { success: false, message: error.message || error.response?.data?.message }; }};
Mejores Prácticas
Section titled “Mejores Prácticas”1. Referencias Consistentes
Section titled “1. Referencias Consistentes”- Usa un formato estándar para referencias:
TIPO-YYYY-NNNN
- Ejemplos:
COMP-2024-0001
,INV-2024-0001
,AJ-2024-0001
2. Descripciones Descriptivas
Section titled “2. Descripciones Descriptivas”- Incluye información relevante: proveedor, motivo, fecha
- Evita descripciones genéricas como “ingreso”
3. Costos Precisos
Section titled “3. Costos Precisos”- Incluye todos los costos asociados (transporte, impuestos)
- Usa el costo real de adquisición
4. Fechas Correctas
Section titled “4. Fechas Correctas”- Usa la fecha real del movimiento, no la fecha de registro
- Mantén consistencia en el formato de fechas
5. Validaciones
Section titled “5. Validaciones”- Siempre valida que el item permita inventario
- Verifica cantidades y costos antes de enviar
Notas Importantes
Section titled “Notas Importantes”- 📦 Solo productos: Los servicios no manejan inventario
- 🔢 Cantidades enteras: No se permiten decimales en cantidades
- 💰 Costo promedio: Se calcula automáticamente
- 📅 Fechas: No se pueden registrar movimientos futuros
- 🔄 Kardex: Cada ingreso genera un movimiento en el kardex
- 📊 Reportes: Los ingresos aparecen en reportes de inventario
- 🔒 Auditoría: Todos los movimientos quedan registrados permanentemente
Troubleshooting
Section titled “Troubleshooting”Error: “Item no permite control de inventario”
Section titled “Error: “Item no permite control de inventario””Solución: Actualizar el item para habilitar inventario:
curl -X PUT "https://dev-facturacion.e-dinky.test/api/v1/items/update" \ -H "Authorization: Bearer $TOKEN" \ -d '{"code": "PROD-001", "allow_accounting": 1, ...}'
Error: “Cantidad debe ser mayor a 0”
Section titled “Error: “Cantidad debe ser mayor a 0””Solución: Verificar que quantity sea un entero positivo
Error: “Item no encontrado”
Section titled “Error: “Item no encontrado””Solución: Verificar que el código del item sea correcto y exista en el sistema