# US-MGN-006-003-002: Validar Recepción de Compra

**RF Asociado:** [RF-MGN-006-004](../../02-modelado/requerimientos-funcionales/mgn-006/RF-MGN-006-004-recepciones-de-compras.md)
**Módulo:** MGN-006 - Compras Básico
**Epic:** Recepciones de Compras
**Prioridad:** P0
**Story Points:** 5
**Sprint:** Sprint 14
**Estado:** Ready for Development
**Fecha:** 2025-11-24

---

## User Story
**Como** usuario de almacén,
**Quiero** validar recepciones de compra,
**Para** actualizar el stock y generar movimientos de inventario.

---

## Descripción Detallada
Validar una recepción:
1. Verifica qty_done de cada línea
2. Genera movimientos de stock (supplier location → input location → stock location)
3. Actualiza stock_quants
4. Cambia estado picking → done
5. Actualiza estado de PO (si todo recibido → done)
6. Opcionalmente crea backorder para cantidades pendientes

---

## Criterios de Aceptación

### Escenario 1: Validar recepción completa (Camino Feliz)
**Dado que** picking tiene todas las líneas con qty_done=qty_expected,
**Cuando** valido,
**Entonces** sistema genera movimientos, actualiza stock, cambia picking state=done, PO state=done.

### Escenario 2: Validar recepción parcial con backorder
**Dado que** línea tiene qty_expected=10, qty_done=7,
**Cuando** valido y acepto crear backorder,
**Entonces** sistema valida 7 unidades, crea picking backorder para 3 unidades.

### Escenario 3: Validar sin backorder (cerrar línea)
**Dado que** línea tiene qty_expected=10, qty_done=7,
**Cuando** valido sin backorder,
**Entonces** sistema valida 7 unidades, cierra línea PO (qty_received=7).

---

## Reglas de Negocio
- **RN-1:** Validar genera movimientos de stock automáticamente.
- **RN-2:** Stock se actualiza en ubicación de entrada (Input Location).
- **RN-3:** Si qty_done < qty_expected, preguntar por backorder.
- **RN-4:** PO pasa a done cuando todas las líneas están recibidas.

---

## Tareas Técnicas

### Backend
- [ ] Endpoint: POST /api/v1/inventory/pickings/:id/validate
- [ ] Service: PickingService.validate(pickingId, createBackorder)
- [ ] Service: StockMoveService.generateFromPicking(picking)
- [ ] Service: PurchaseOrderService.updateReceiptStatus(poId)
- [ ] Crear backorder si aplica
- [ ] Transaction atomicidad
- [ ] Unit tests
- [ ] Integration tests
- [ ] Swagger docs

### Frontend
- [ ] Botón Validar con confirmación
- [ ] Modal para backorder (si qty_done < expected)
- [ ] API client: pickingApi.validate()
- [ ] Component tests
- [ ] E2E test

### Database
- [ ] Transaction isolation
- [ ] Lock: SELECT FOR UPDATE en pickings

---

## 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
- [ ] Stock actualizado correctamente
- [ ] Backorder funciona
- [ ] Transaction implementada
- [ ] QA validado
- [ ] PO aprobado

---

## Referencias
- [RF-MGN-006-004](../../02-modelado/requerimientos-funcionales/mgn-006/RF-MGN-006-004-recepciones-de-compras.md)
- [Traceability](../../02-modelado/trazabilidad/TRACEABILITY-MGN-006.yaml)
