# US-MGN-005-004-002: Reservar Stock para Pedidos **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:** Stock Quants **Prioridad:** P1 **Story Points:** 4 **Sprint:** Sprint 10 **Estado:** Ready for Development **Fecha:** 2025-11-24 --- ## User Story **Como** sistema de ventas, **Quiero** reservar stock en ubicaciones para pedidos confirmados, **Para** garantizar disponibilidad y evitar sobreventa. --- ## Descripción Detallada La reserva de stock incrementa reserved_quantity en stock_quants sin mover físicamente el producto. Esto asegura que el stock esté comprometido para un pedido específico. Cuando se valida una entrega, la reserva se libera y el stock se mueve físicamente (quantity se decrementa). --- ## Criterios de Aceptación ### Escenario 1: Reservar stock disponible (Camino Feliz) **Dado que** ubicación Zona A tiene product=1, quantity=10, reserved=0, **Cuando** reservo 5 unidades, **Entonces** el sistema actualiza reserved_quantity=5, available=5. ### Escenario 2: Error al reservar más del disponible **Dado que** ubicación tiene quantity=10, reserved=3 (available=7), **Cuando** intento reservar 8 unidades, **Entonces** el sistema retorna error 400 "Stock disponible insuficiente (disponible: 7, solicitado: 8)". ### Escenario 3: Liberar reserva **Dado que** ubicación tiene quantity=10, reserved=5, **Cuando** libero 5 unidades de reserva, **Entonces** el sistema actualiza reserved_quantity=0, available=10. ### Escenario 4: Reservar en múltiples ubicaciones **Dado que** necesito reservar 15 unidades de product=1, **Cuando** hay 10 en Zona A y 8 en Zona B, **Entonces** el sistema reserva 10 de Zona A y 5 de Zona B. --- ## Reglas de Negocio - **RN-1:** reserved_quantity no puede exceder quantity. - **RN-2:** available_quantity = quantity - reserved_quantity. - **RN-3:** Reservas se vinculan a pedidos de venta (sale_order_line_id). - **RN-4:** Liberar reserva restaura available_quantity. - **RN-5:** Reservas pueden distribuirse en múltiples ubicaciones. --- ## Tareas Técnicas ### Backend - [ ] Endpoint: POST /api/v1/inventory/stock-quants/reserve - [ ] Endpoint: POST /api/v1/inventory/stock-quants/unreserve - [ ] Service: QuantService.reserve(productId, quantity, orderId) - [ ] Service: QuantService.unreserve(productId, quantity, orderId) - [ ] Service: QuantService.findAvailableLocations(productId, quantity) - [ ] DTO: ReserveStockDto (product_id, quantity, order_id) - [ ] Validar stock disponible - [ ] Actualizar reserved_quantity - [ ] Manejar reservas en múltiples ubicaciones - [ ] Transaction para atomicidad - [ ] Unit tests - [ ] Integration tests - [ ] Swagger docs ### Frontend - [ ] Componente: ReserveStockButton.tsx - [ ] Modal de confirmación - [ ] API client: quantApi.reserve(data) - [ ] Component tests - [ ] E2E test: "should reserve stock" ### Database - [ ] Tabla: inventory.stock_reservations (opcional - tracking de reservas) - [ ] Transaction isolation level: READ COMMITTED - [ ] Lock: SELECT FOR UPDATE en quants --- ## Mockups / Wireframes **Modal Reservar Stock:** ``` ┌─────────────────────────────────────────────┐ │ Reservar Stock │ ├─────────────────────────────────────────────┤ │ Pedido: SO-00123 │ │ Producto: Laptop HP │ │ Cantidad a Reservar: 15 unidades │ │ │ │ Distribución Propuesta: │ │ ┌───────────────────────────────────────┐ │ │ │Ubicación │Disponible│Reservar │ │ │ ├──────────┼──────────┼────────────────┤ │ │ │Zona A-P1 │ 10 │ 10 [✓] │ │ │ │Zona B-P2 │ 8 │ 5 [✓] │ │ │ └───────────────────────────────────────┘ │ │ │ │ Total Reservado: 15 / 15 ✓ │ ├─────────────────────────────────────────────┤ │ [Confirmar Reserva] [Cancelar] │ └─────────────────────────────────────────────┘ ``` --- ## Casos de Prueba ### Funcionales 1. **TC-001:** Reservar stock disponible exitosamente 2. **TC-002:** Error por stock insuficiente 3. **TC-003:** Liberar reserva exitosamente 4. **TC-004:** Reservar en múltiples ubicaciones 5. **TC-005:** Transaction rollback en caso de error 6. **TC-006:** RLS filtra por empresa ### No Funcionales 1. **Performance:** < 400ms para reservar stock 2. **Seguridad:** JWT + permiso inventory_user --- ## Dependencias - **US bloqueantes:** US-MGN-005-004-001 (Visualizar Quants) - **Módulos requeridos:** MGN-007 (Ventas - opcional) - **Datos maestros:** Ninguno --- ## Notas de Implementación - Usar SELECT FOR UPDATE para evitar condiciones de carrera - Algoritmo de selección de ubicaciones: FIFO (primeras ubicaciones con stock) - Considerar tabla stock_reservations para trazabilidad detallada - Frontend: Mostrar preview de distribución antes de confirmar --- ## Estimación Detallada | Tarea | Horas | |-------|-------| | Backend | 2.5 | | Frontend | 2 | | Testing | 1.5 | | Code Review | 0.5 | | **TOTAL** | **6.5 horas = 4 SP** | --- ## Definition of Done - [ ] Código implementado según ET - [ ] Tests pasando (>80%) - [ ] Code review aprobado - [ ] Documentación actualizada - [ ] Swagger docs completo - [ ] Transaction correctamente implementada - [ ] 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)