6.7 KiB
US-MGN-005-003-001: Crear 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 crear movimientos de stock entre ubicaciones (origen → destino), Para registrar transferencias y actualizar el stock en cada ubicación.
Descripción Detallada
Un movimiento de stock (stock_move) registra el traslado de productos entre ubicaciones. Tiene tres estados:
- draft: Borrador, puede editarse
- done: Validado, actualiza stock en quants
- cancelled: Cancelado
Los movimientos se crean en draft y al validarlos actualizan las cantidades en inventory.stock_quants restando de location_from y sumando a location_to.
Criterios de Aceptación
Escenario 1: Crear movimiento de stock en draft (Camino Feliz)
Dado que soy usuario con permiso inventory_user, Cuando creo movimiento: product_id=1, location_from_id=10, location_to_id=20, quantity=5, Entonces el sistema crea movimiento en estado draft sin actualizar stock.
Escenario 2: Validar producto existe
Dado que intento crear movimiento con product_id=999 (no existe), Cuando envío el request, Entonces el sistema retorna error 404 "Producto no encontrado".
Escenario 3: Validar ubicaciones existen
Dado que intento crear movimiento con location_from_id=888 (no existe), Cuando envío el request, Entonces el sistema retorna error 404 "Ubicación origen no encontrada".
Escenario 4: Validar cantidad positiva
Dado que intento crear movimiento con quantity=-5, Cuando envío el request, Entonces el sistema retorna error 400 "La cantidad debe ser positiva".
Escenario 5: Crear movimiento con referencia
Dado que creo movimiento con reference="Transferencia #123", Cuando envío el request, Entonces el sistema guarda la referencia para trazabilidad.
Reglas de Negocio
- RN-1: Movimientos se crean en estado draft por defecto.
- RN-2: Cantidad debe ser mayor a 0.
- RN-3: location_from y location_to deben ser diferentes.
- RN-4: Stock se actualiza solo al validar el movimiento (state=done).
- RN-5: Movimientos draft pueden editarse y eliminarse.
- RN-6: RLS filtra movimientos por empresa.
Tareas Técnicas
Backend
- Endpoint: POST /api/v1/inventory/stock-moves
- Endpoint: GET /api/v1/inventory/stock-moves
- Endpoint: GET /api/v1/inventory/stock-moves/:id
- Service: StockMoveService.create(createStockMoveDto)
- DTO: CreateStockMoveDto (product_id, location_from_id, location_to_id, quantity, reference)
- Validar producto existe
- Validar ubicaciones existen
- Validar cantidad > 0
- Validar ubicaciones diferentes
- Unit tests (>80% coverage)
- Integration tests
- Swagger docs
Frontend
- Componente: CreateStockMoveForm.tsx
- Página: CreateStockMovePage.tsx (/inventory/stock-moves/create)
- Selector de producto
- Selector de ubicación origen/destino
- Input cantidad con validación
- API client: stockMoveApi.create(data)
- State management: useStockMoveStore
- Component tests
- E2E test: "should create stock move in draft"
Database
- Tabla: inventory.stock_moves
- Índices: idx_stock_moves_product_id, idx_stock_moves_location_from, idx_stock_moves_location_to, idx_stock_moves_state
- RLS policy: company_isolation_stock_moves
Mockups / Wireframes
Formulario Crear Movimiento:
┌─────────────────────────────────────────────┐
│ Crear Movimiento de Stock │
├─────────────────────────────────────────────┤
│ Producto: [Select: Laptop HP ▼] * │
│ │
│ Ubicación Origen: [Select: Zona A ▼] * │
│ Ubicación Destino: [Select: Zona B ▼] * │
│ │
│ Cantidad: [Input: 5] unidades * │
│ Referencia: [Input: Opcional] │
│ │
│ Nota: El movimiento se creará en estado │
│ borrador. Deberá validarse para actualizar │
│ el stock. │
├─────────────────────────────────────────────┤
│ [Guardar Borrador] [Cancelar] │
└─────────────────────────────────────────────┘
Casos de Prueba
Funcionales
- TC-001: Crear movimiento en draft exitosamente
- TC-002: Error por producto inexistente
- TC-003: Error por ubicación inexistente
- TC-004: Error por cantidad negativa o cero
- TC-005: Error por ubicaciones iguales
- TC-006: RLS filtra por empresa
No Funcionales
- Performance: < 300ms para crear movimiento
- Seguridad: JWT + permiso inventory_user
Dependencias
- US bloqueantes:
- US-MGN-005-001-001 (Crear Producto)
- US-MGN-005-002-001 (Gestionar Almacenes/Ubicaciones)
- Módulos requeridos: MGN-001, MGN-002
- Datos maestros: Productos, Ubicaciones
Notas de Implementación
- Estado draft no afecta stock_quants
- Validación se hace en US separada (US-MGN-005-003-002)
- Frontend: Mostrar stock disponible en ubicación origen
- Considerar agregar campo date (fecha programada del movimiento)
Estimación Detallada
| Tarea | Horas |
|---|---|
| Backend | 2.5 |
| Frontend | 2.5 |
| 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
- RLS aplicado
- QA validado
- PO aprobado