# US-MGN-005-003-001: Crear Movimiento de Stock

**RF Asociado:** [RF-MGN-005-003](../../02-modelado/requerimientos-funcionales/mgn-005/RF-MGN-005-003-movimientos-de-stock.md)
**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
1. **TC-001:** Crear movimiento en draft exitosamente
2. **TC-002:** Error por producto inexistente
3. **TC-003:** Error por ubicación inexistente
4. **TC-004:** Error por cantidad negativa o cero
5. **TC-005:** Error por ubicaciones iguales
6. **TC-006:** RLS filtra por empresa

### No Funcionales
1. **Performance:** < 300ms para crear movimiento
2. **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

---

## Referencias

- [RF-MGN-005-003](../../02-modelado/requerimientos-funcionales/mgn-005/RF-MGN-005-003-movimientos-de-stock.md)
- [ET Backend](../../02-modelado/especificaciones-tecnicas/backend/mgn-005/ET-BACKEND-MGN-005-003-movimientos-de-stock.md)
- [ET Frontend](../../02-modelado/especificaciones-tecnicas/frontend/mgn-005/ET-FRONTEND-MGN-005-003-movimientos-de-stock.md)
- [Traceability](../../02-modelado/trazabilidad/TRACEABILITY-MGN-005.yaml)
- [Schema](../../02-modelado/database-design/schemas/inventory-schema-ddl.sql)
