# 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)