erp-core/docs/05-user-stories/mgn-005/US-MGN-005-003-001-crear-movimiento-stock.md

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

  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