6.9 KiB
US-MGN-005-003-002: Validar Movimiento de Stock
RF Asociado: RF-MGN-005-003 Módulo: MGN-005 - Inventario Básico Epic: Movimientos de Stock Prioridad: P0 Story Points: 5 Sprint: Sprint 10 Estado: Ready for Development Fecha: 2025-11-24
User Story
Como usuario de inventario, Quiero validar movimientos de stock en estado draft, Para actualizar las cantidades de stock en las ubicaciones origen y destino (quants).
Descripción Detallada
Validar un movimiento cambia su estado de draft → done y ejecuta la lógica de actualización de stock:
- Resta cantidad de stock_quants en location_from
- Suma cantidad de stock_quants en location_to
- Actualiza state=done y fecha de validación
- Registra trazabilidad del movimiento
Si no hay stock suficiente en origin, el sistema puede permitir stock negativo (configurable) o rechazar el movimiento.
Criterios de Aceptación
Escenario 1: Validar movimiento con stock suficiente (Camino Feliz)
Dado que tengo movimiento en draft: product=1, from=Zona A (stock=10), to=Zona B, qty=5, Cuando valido el movimiento, Entonces el sistema actualiza: Zona A stock=5, Zona B stock=5, state=done.
Escenario 2: Validar movimiento sin stock (permitir negativo)
Dado que ubicación origen tiene stock=3 y movimiento requiere qty=5, Cuando valido y allow_negative_stock=true, Entonces el sistema actualiza: origen stock=-2, destino stock=5, state=done.
Escenario 3: Error al validar sin stock (no permitir negativo)
Dado que ubicación origen tiene stock=3 y movimiento requiere qty=5, Cuando valido y allow_negative_stock=false, Entonces el sistema retorna error 400 "Stock insuficiente en ubicación origen".
Escenario 4: Error al validar movimiento ya validado
Dado que movimiento está en state=done, Cuando intento validar nuevamente, Entonces el sistema retorna error 400 "Movimiento ya fue validado".
Escenario 5: Error al validar movimiento cancelado
Dado que movimiento está en state=cancelled, Cuando intento validar, Entonces el sistema retorna error 400 "No se puede validar un movimiento cancelado".
Reglas de Negocio
- RN-1: Solo movimientos en state=draft pueden validarse.
- RN-2: Validar actualiza stock_quants (resta origen, suma destino).
- RN-3: Stock negativo permitido según configuración de empresa.
- RN-4: Movimiento validado no puede modificarse.
- RN-5: Validación registra fecha y usuario que valida.
- RN-6: Si producto tiene tracking (lot/serial), se requiere especificar lote.
Tareas Técnicas
Backend
- Endpoint: POST /api/v1/inventory/stock-moves/:id/validate
- Service: StockMoveService.validate(moveId)
- Service: StockMoveService.updateQuants(move)
- Service: QuantService.updateQuantity(productId, locationId, quantityDelta)
- Validar movimiento en state=draft
- Verificar stock disponible
- Actualizar quants (origen y destino)
- Actualizar state y fecha
- Transaction para atomicidad
- Unit tests (>80% coverage)
- Integration tests
- Swagger docs
Frontend
- Componente: ValidateStockMoveButton.tsx
- Modal de confirmación con resumen
- Mostrar stock actual antes/después
- API client: stockMoveApi.validate(id)
- Actualizar lista de movimientos tras validar
- Component tests
- E2E test: "should validate stock move and update stock"
Database
- Tabla: inventory.stock_quants (actualización)
- Índices: idx_stock_quants_product_location
- Transaction isolation level: READ COMMITTED
Mockups / Wireframes
Modal Validar Movimiento:
┌─────────────────────────────────────────────┐
│ Validar Movimiento de Stock │
├─────────────────────────────────────────────┤
│ Producto: Laptop HP │
│ Cantidad: 5 unidades │
│ │
│ Ubicación Origen: Zona A │
│ Stock Actual: 10 → Nuevo: 5 │
│ │
│ Ubicación Destino: Zona B │
│ Stock Actual: 3 → Nuevo: 8 │
│ │
│ ⚠ Esta acción no puede deshacerse. │
├─────────────────────────────────────────────┤
│ [Validar] [Cancelar] │
└─────────────────────────────────────────────┘
Casos de Prueba
Funcionales
- TC-001: Validar movimiento con stock suficiente
- TC-002: Validar movimiento con stock negativo (permitido)
- TC-003: Error por stock insuficiente (no permitido)
- TC-004: Error por movimiento ya validado
- TC-005: Error por movimiento cancelado
- TC-006: Transaction rollback en caso de error
- TC-007: RLS filtra por empresa
No Funcionales
- Performance: < 500ms para validar movimiento
- Seguridad: JWT + permiso inventory_validate
Dependencias
- US bloqueantes: US-MGN-005-003-001 (Crear Movimiento Stock)
- Módulos requeridos: MGN-001, MGN-002
- Datos maestros: Stock quants
Notas de Implementación
- Usar transaction para garantizar atomicidad de actualización de quants
- Si quant no existe, crear con quantity (INSERT)
- Si quant existe, actualizar quantity (UPDATE)
- Considerar bloqueo pesimista (SELECT FOR UPDATE) en quants para evitar condiciones de carrera
- Frontend: Polling o WebSocket para refresh automático de stock
Estimación Detallada
| Tarea | Horas |
|---|---|
| Backend | 3 |
| Frontend | 2 |
| Testing | 2 |
| Code Review | 1 |
| TOTAL | 8 horas = 5 SP |
Definition of Done
- Código implementado según ET
- Tests pasando (>80%)
- Code review aprobado
- Documentación actualizada
- Swagger docs completo
- Transaction correctamente implementada
- RLS aplicado
- QA validado
- PO aprobado