# US-MGN-007-003-002: Validar Entrega y Actualizar Stock

**RF Asociado:** [RF-MGN-007-004](../../02-modelado/requerimientos-funcionales/mgn-007/RF-MGN-007-004-entregas-de-ventas.md)
**Módulo:** MGN-007 - Ventas Básico
**Epic:** Entregas de Ventas
**Prioridad:** P0
**Story Points:** 5
**Sprint:** Sprint 17
**Estado:** Ready for Development
**Fecha:** 2025-11-24

---

## User Story

**Como** usuario de almacén,
**Quiero** validar entregas (cambiar draft → done) actualizando cantidades entregadas,
**Para** confirmar el despacho físico y actualizar el stock en tiempo real.

---

## Descripción Detallada

Validar una delivery significa:
- Confirmar las cantidades realmente entregadas (qty_done)
- Cambiar estado draft → done
- Crear movimientos de stock: ubicación_almacén → ubicación_cliente
- Actualizar qty_delivered en sales.order_lines
- Actualizar stock_quants restando del almacén
- Registrar date_done
- Crear mensaje en chatter

Si qty_done < qty_ordered, genera backorder automático para las cantidades pendientes.

---

## Criterios de Aceptación

### Escenario 1: Validar delivery completa (Camino Feliz)
**Dado que** delivery id=1 draft con línea: product_id=1, qty_ordered=50, qty_done=50,
**Cuando** valido delivery,
**Entonces** estado=done, crea stock_moves, actualiza quants (-50 en almacén), actualiza SO.qty_delivered=50.

### Escenario 2: Validar stock disponible antes de validar
**Dado que** línea tiene product_id=1, qty_done=100 pero stock disponible=50,
**Cuando** intento validar,
**Entonces** sistema retorna error 400 "Stock insuficiente en Almacén Principal".

### Escenario 3: Delivery parcial con backorder automático
**Dado que** línea tiene qty_ordered=100, qty_done=60,
**Cuando** valido delivery,
**Entonces** sistema crea backorder DO/2024/0002 con qty_pending=40 en draft.

### Escenario 4: Validar todas las líneas tienen qty_done > 0
**Dado que** línea tiene qty_done=0,
**Cuando** intento validar,
**Entonces** sistema retorna error 400 "Todas las líneas deben tener cantidad entregada > 0".

### Escenario 5: Registrar fecha de validación
**Dado que** valido delivery exitosamente,
**Cuando** se completa validación,
**Entonces** date_done registra timestamp actual.

### Escenario 6: Actualizar estado de SO si 100% entregado
**Dado que** SO tiene qty_total=100, después de validar delivery llega a qty_delivered=100,
**Cuando** se completa validación,
**Entonces** SO.delivery_status cambia a fully_delivered.

---

## Reglas de Negocio

- **RN-1:** Solo deliveries en draft pueden validarse.
- **RN-2:** qty_done debe ser <= qty_ordered por línea.
- **RN-3:** Validación verifica stock disponible en ubicación origen.
- **RN-4:** Si qty_done < qty_ordered, genera backorder automático con diferencia.
- **RN-5:** Crea stock_moves (location_from → location_to) por cada línea.
- **RN-6:** Actualiza sales.order_lines.qty_delivered.
- **RN-7:** date_done registra timestamp de validación.
- **RN-8:** Permisos: stock_user.

---

## Tareas Técnicas

### Backend
- [ ] Endpoint: `POST /api/v1/inventory/deliveries/:id/validate`
- [ ] Service: `DeliveryService.validate(id)`
- [ ] Validar estado draft
- [ ] Validar qty_done > 0 en todas las líneas
- [ ] Validar qty_done <= qty_ordered
- [ ] Validar stock disponible por producto
- [ ] Crear stock_moves (origin → destination)
- [ ] Actualizar stock_quants
- [ ] Actualizar order_lines.qty_delivered
- [ ] Actualizar order.delivery_status si 100%
- [ ] Generar backorder si qty_done < qty_ordered
- [ ] Actualizar state=done, date_done=now()
- [ ] Crear mensaje en chatter
- [ ] Unit tests (>80%)
- [ ] Integration tests
- [ ] Swagger docs

### Frontend
- [ ] Botón: "Validate" en vista de delivery draft
- [ ] Inputs: Editar qty_done por línea antes de validar
- [ ] Validación: qty_done <= qty_ordered
- [ ] Mostrar stock disponible por producto
- [ ] Warning si qty_done < qty_ordered (backorder)
- [ ] API client: `deliveryApi.validate(id)`
- [ ] Notificación toast de éxito
- [ ] Component tests
- [ ] E2E test: "should validate delivery and update stock"

### Database
- [ ] Columna: `inventory.deliveries.date_done` (timestamp)
- [ ] Columna: `inventory.delivery_lines.qty_done` (numeric)
- [ ] Columna: `sales.order_lines.qty_delivered` (numeric)
- [ ] Columna: `sales.orders.delivery_status` (enum: pending, partial, fully_delivered)
- [ ] Trigger: Actualizar SO.delivery_status automáticamente

---

## Mockups / Wireframes

**Vista Delivery con validación:**
```
┌─────────────────────────────────────────────┐
│ Delivery DO/2024/0001       [draft]         │
├─────────────────────────────────────────────┤
│ Orden: SO/2024/0001                         │
│ Origen: Almacén Principal → Cliente ABC     │
│                                             │
│ Líneas:                                     │
│ ┌───────────────────────────────────────┐   │
│ │Producto  │Ordenado│Disponible│Entregado│ │
│ ├──────────┼────────┼──────────┼─────────┤ │
│ │Laptop HP │  50    │   100    │[50]     │ │
│ │Mouse     │  20    │   15 ⚠  │[15]     │ │
│ └───────────────────────────────────────┘   │
│                                             │
│ ⚠ Mouse: Solo 15 disponibles (ordenadas 20)│
│   Se creará backorder para 5 unidades       │
│                                             │
│ [Validate] [Cancel]                         │
└─────────────────────────────────────────────┘
```

---

## Casos de Prueba

### Funcionales
1. **TC-001:** Validar delivery completa exitosamente
2. **TC-002:** Error si stock insuficiente
3. **TC-003:** Error si qty_done=0 en alguna línea
4. **TC-004:** Error si qty_done > qty_ordered
5. **TC-005:** Stock_moves creados correctamente
6. **TC-006:** Stock_quants actualizado (resta en origen)
7. **TC-007:** order_lines.qty_delivered actualizado
8. **TC-008:** Backorder generado si entrega parcial
9. **TC-009:** SO.delivery_status=fully_delivered si 100%
10. **TC-010:** date_done registrado correctamente

### No Funcionales
1. **Performance:** < 1s para validar delivery con 20 líneas
2. **Seguridad:** JWT + permiso stock_user

---

## Dependencias

- **US bloqueantes:**
  - US-MGN-007-003-001 (Crear Delivery)
  - US-MGN-005-003-002 (Validar Movimiento Stock)
- **Módulos requeridos:** MGN-005 (Inventario)

---

## Notas de Implementación

- Usar transacción para garantizar atomicidad (stock_moves + quants + order_lines)
- Validación de stock: `SELECT SUM(quantity) FROM stock_quants WHERE location_id=X AND product_id=Y`
- Backorder: Copiar delivery original con qty_remaining
- Frontend: Permitir editar qty_done antes de validar (default=qty_ordered)

---

## 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
- [ ] Validación funciona correctamente
- [ ] Stock actualizado correctamente
- [ ] order_lines.qty_delivered actualizado
- [ ] Backorder generado si aplica
- [ ] date_done registrado
- [ ] Mensaje en chatter creado
- [ ] Swagger docs actualizado
- [ ] QA validado
- [ ] PO aprobado

---

## Referencias

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