# US-MGN-007-002-002: Confirmar Sales Order

**RF Asociado:** [RF-MGN-007-003](../../02-modelado/requerimientos-funcionales/mgn-007/RF-MGN-007-003-gestión-de-órdenes-de-venta.md)
**Módulo:** MGN-007 - Ventas Básico
**Epic:** Órdenes de Venta
**Prioridad:** P0
**Story Points:** 5
**Sprint:** Sprint 16
**Estado:** Ready for Development
**Fecha:** 2025-11-24

---

## User Story

**Como** vendedor,
**Quiero** confirmar una orden de venta (cambiar de draft → confirmed),
**Para** bloquearla para edición y permitir la creación de entregas y facturas.

---

## Descripción Detallada

Confirmar una SO significa:
- Cambiar estado de draft → confirmed
- Registrar fecha de confirmación (date_confirmed)
- Bloquear edición de líneas y datos principales
- Permitir procesos downstream: entregas, facturas
- Reservar stock si apply_reservation=true
- Notificar al cliente y equipo interno

Una vez confirmada, la SO solo puede cancelarse, no editarse.

---

## Criterios de Aceptación

### Escenario 1: Confirmar SO en draft (Camino Feliz)
**Dado que** SO id=1 está en estado draft con líneas válidas,
**Cuando** ejecuto action "Confirm Order",
**Entonces** sistema cambia estado a confirmed, registra date_confirmed, crea mensaje en chatter.

### Escenario 2: Validar que SO está en draft
**Dado que** SO ya está en estado confirmed,
**Cuando** intento confirmar nuevamente,
**Entonces** sistema retorna error 400 "La orden ya está confirmada".

### Escenario 3: Validar que SO tiene líneas
**Dado que** SO no tiene líneas,
**Cuando** intento confirmar,
**Entonces** sistema retorna error 400 "No se puede confirmar orden sin líneas".

### Escenario 4: Validar stock disponible (opcional)
**Dado que** línea tiene product_id=1, quantity=100 pero stock disponible=50,
**Cuando** intento confirmar con check_stock=true,
**Entonces** sistema retorna warning "Stock insuficiente para Producto X" pero permite confirmar.

### Escenario 5: Bloquear edición después de confirmar
**Dado que** SO está en confirmed,
**Cuando** intento actualizar una línea,
**Entonces** sistema retorna error 400 "No se pueden editar órdenes confirmadas".

### Escenario 6: Notificar al cliente
**Dado que** SO se confirma exitosamente,
**Cuando** se completa confirmación,
**Entonces** sistema envía email al cliente con detalles de la orden confirmada.

---

## Reglas de Negocio

- **RN-1:** Solo SO en draft pueden confirmarse.
- **RN-2:** SO confirmadas no pueden editarse (solo cancelarse).
- **RN-3:** date_confirmed registra timestamp de confirmación.
- **RN-4:** Se crea mensaje automático en chatter.
- **RN-5:** Se puede enviar email de confirmación al cliente (opcional).
- **RN-6:** Validación de stock es warning, no bloqueante.
- **RN-7:** Permisos: sales_user puede confirmar sus órdenes, sales_manager puede confirmar cualquiera.

---

## Tareas Técnicas

### Backend
- [ ] Endpoint: `POST /api/v1/sales/orders/:id/confirm`
- [ ] Service: `SalesOrderService.confirm(id, confirmDto)`
- [ ] Validar estado draft
- [ ] Validar que tiene líneas
- [ ] Validar stock disponible (warning, no error)
- [ ] Actualizar state=confirmed, date_confirmed=now()
- [ ] Crear mensaje en chatter
- [ ] Enviar email de confirmación (opcional)
- [ ] Unit tests (>80%)
- [ ] Integration tests
- [ ] Swagger docs

### Frontend
- [ ] Botón: "Confirm Order" en vista de SO draft
- [ ] Modal de confirmación con warnings de stock si aplica
- [ ] Opción: "Send confirmation email to customer"
- [ ] API client: `salesOrderApi.confirm(id, options)`
- [ ] Deshabilitar edición de SO confirmadas
- [ ] Notificación toast de éxito
- [ ] Component tests
- [ ] E2E test: "should confirm sales order"

### Database
- [ ] Columna: `sales.orders.date_confirmed` (timestamp)
- [ ] Índice: `idx_orders_date_confirmed`
- [ ] Trigger: audit_log en cambio de estado

---

## Mockups / Wireframes

**Vista SO con botón Confirmar:**
```
┌─────────────────────────────────────────────┐
│ Sales Order SO/2024/0001    [draft]         │
├─────────────────────────────────────────────┤
│ Cliente: ABC Corp                           │
│ Total: $5,000.00                            │
│                                             │
│ [Líneas de productos...]                    │
│                                             │
│ ⚠ Advertencia: Producto X tiene solo 50    │
│   unidades disponibles (ordenadas: 100)     │
├─────────────────────────────────────────────┤
│ [Edit] [Confirm Order] [Cancel]             │
└─────────────────────────────────────────────┘
```

**Modal de Confirmación:**
```
┌─────────────────────────────────────────────┐
│ Confirmar Orden de Venta                    │
├─────────────────────────────────────────────┤
│ ¿Confirmar orden SO/2024/0001?              │
│                                             │
│ ☑ Enviar email de confirmación al cliente  │
│                                             │
│ Después de confirmar:                       │
│ • La orden no podrá editarse                │
│ • Se podrán crear entregas y facturas       │
│                                             │
│ [Confirmar] [Cancelar]                      │
└─────────────────────────────────────────────┘
```

---

## Casos de Prueba

### Funcionales
1. **TC-001:** Confirmar SO draft exitosamente
2. **TC-002:** Error al confirmar SO ya confirmada
3. **TC-003:** Error al confirmar SO sin líneas
4. **TC-004:** Warning si stock insuficiente pero permite confirmar
5. **TC-005:** date_confirmed se registra correctamente
6. **TC-006:** Mensaje se crea en chatter
7. **TC-007:** Email se envía al cliente si opción activada
8. **TC-008:** SO confirmada no permite edición de líneas

### No Funcionales
1. **Performance:** < 300ms para confirmar orden
2. **Seguridad:** JWT + permiso sales_user

---

## Dependencias

- **US bloqueantes:**
  - US-MGN-007-002-001 (Crear SO desde Cotización)
- **Módulos requeridos:** MGN-005 (Inventario para check stock)

---

## Notas de Implementación

- Check de stock es informativo, no bloqueante (permite confirmar con stock insuficiente)
- Email de confirmación usa template configurable
- Considerar agregar campo `confirmed_by_user_id` para auditoría
- Frontend: Deshabilitar botones de edición cuando state=confirmed

---

## Estimación Detallada

| Tarea | Horas |
|-------|-------|
| Backend | 2 |
| Frontend | 2 |
| Testing | 1.5 |
| Code Review | 0.5 |
| **TOTAL** | **6 horas = 5 SP** |

---

## Definition of Done

- [ ] Código implementado según ET
- [ ] Tests pasando (>80%)
- [ ] Code review aprobado
- [ ] Confirmación funciona correctamente
- [ ] Validaciones aplicadas
- [ ] date_confirmed registrada
- [ ] Mensaje en chatter creado
- [ ] Email opcional funciona
- [ ] Edición bloqueada después de confirmar
- [ ] Swagger docs actualizado
- [ ] QA validado
- [ ] PO aprobado

---

## Referencias

- [RF-MGN-007-003](../../02-modelado/requerimientos-funcionales/mgn-007/RF-MGN-007-003-gestión-de-órdenes-de-venta.md)
- [ET Backend](../../02-modelado/especificaciones-tecnicas/backend/mgn-007/ET-BACKEND-MGN-007-003-ordenes-venta.md)
- [ET Frontend](../../02-modelado/especificaciones-tecnicas/frontend/mgn-007/ET-FRONTEND-MGN-007-003-ordenes-venta.md)
- [Traceability](../../02-modelado/trazabilidad/TRACEABILITY-MGN-007.yaml)
- [Schema](../../02-modelado/database-design/schemas/sales-schema-ddl.sql)
