# US-MGN-007-001-002: Enviar Cotización por Email

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

---

## User Story

**Como** vendedor,
**Quiero** enviar cotizaciones por email con PDF adjunto,
**Para** compartir la cotización con el cliente y cambiar su estado a "sent".

---

## Descripción Detallada

Esta funcionalidad permite enviar la cotización al cliente por email con:
- Asunto y cuerpo personalizables
- PDF de la cotización adjunto
- Cambio automático de estado de draft → sent
- Registro de la fecha de envío (date_sent)
- Histórico de envíos en chatter/mensajes

El email se envía al contacto principal del partner (partner.email). El PDF se genera on-the-fly usando un template HTML.

---

## Criterios de Aceptación

### Escenario 1: Enviar cotización en draft (Camino Feliz)
**Dado que** tengo cotización id=1 en estado draft,
**Cuando** ejecuto action "Send by Email" con to="cliente@example.com", subject="Cotización #QT/2024/0001",
**Entonces** sistema envía email con PDF adjunto, cambia estado a sent, registra date_sent.

### Escenario 2: Validar que cotización está en estado válido
**Dado que** cotización está en estado cancelled,
**Cuando** intento enviar por email,
**Entonces** sistema retorna error 400 "No se puede enviar cotización cancelada".

### Escenario 3: Validar que partner tiene email
**Dado que** partner.email es nulo,
**Cuando** intento enviar cotización,
**Entonces** sistema retorna error 400 "El cliente no tiene email configurado".

### Escenario 4: Generar PDF automáticamente
**Dado que** cotización tiene líneas con productos y totales,
**Cuando** se envía por email,
**Entonces** sistema genera PDF con logo empresa, datos cliente, líneas, totales.

### Escenario 5: Template de email personalizable
**Dado que** existe template "quotation_email" configurado,
**Cuando** se envía cotización,
**Entonces** sistema usa el template con variables: {customer_name}, {quotation_number}, {total}.

### Escenario 6: Registrar envío en chatter
**Dado que** cotización se envía exitosamente,
**Cuando** se completa el envío,
**Entonces** sistema crea mensaje en chatter: "Cotización enviada a cliente@example.com".

---

## Reglas de Negocio

- **RN-1:** Solo cotizaciones en draft o sent pueden enviarse por email.
- **RN-2:** Al enviar, estado cambia automáticamente a sent.
- **RN-3:** date_sent se actualiza con timestamp del envío.
- **RN-4:** Partner debe tener email válido configurado.
- **RN-5:** PDF se genera dinámicamente, no se almacena.
- **RN-6:** Se registra mensaje en chatter con detalles del envío.
- **RN-7:** Permisos: sales_user o superior.

---

## Tareas Técnicas

### Backend
- [ ] Endpoint: `POST /api/v1/sales/quotations/:id/send-email`
- [ ] Service: `QuotationService.sendByEmail(id, emailDto)`
- [ ] Service: `PdfGeneratorService.generateQuotationPdf(quotation)`
- [ ] Service: `EmailService.sendWithAttachment(to, subject, body, pdfBuffer)`
- [ ] DTO: `SendQuotationEmailDto` (to, cc?, subject, body)
- [ ] Validar estado de cotización (draft o sent)
- [ ] Validar email de partner existe
- [ ] Generar PDF usando Puppeteer o similar
- [ ] Template HTML para PDF
- [ ] Actualizar estado a sent y date_sent
- [ ] Crear mensaje en chatter
- [ ] Unit tests (>80%)
- [ ] Integration tests
- [ ] Swagger docs

### Frontend
- [ ] Componente: `SendQuotationEmailDialog.tsx`
- [ ] Modal con: destinatario, asunto, cuerpo editable
- [ ] Preview del email antes de enviar
- [ ] Botón "Send by Email" en vista de cotización
- [ ] API client: `quotationApi.sendEmail(id, data)`
- [ ] Notificación toast de éxito/error
- [ ] Component tests
- [ ] E2E test: "should send quotation by email"

### Database
- [ ] Columna: `sales.quotations.date_sent` (timestamp)
- [ ] Columna: `sales.quotations.sent_count` (int, contador de envíos)
- [ ] Índice: `idx_quotations_date_sent`

---

## Mockups / Wireframes

**Modal Enviar Email:**
```
┌────────────────────────────────────────────┐
│ Enviar Cotización QT/2024/0001             │
├────────────────────────────────────────────┤
│ Para: [Input: cliente@example.com] *      │
│ CC: [Input: opcional]                      │
│                                            │
│ Asunto: [Input: Cotización QT/2024/0001]  │
│                                            │
│ Mensaje:                                   │
│ ┌────────────────────────────────────────┐ │
│ │ Estimado cliente,                      │ │
│ │                                        │ │
│ │ Adjunto encontrará la cotización      │ │
│ │ solicitada.                           │ │
│ │                                        │ │
│ │ Saludos,                              │ │
│ │ [Nombre Vendedor]                     │ │
│ └────────────────────────────────────────┘ │
│                                            │
│ Adjunto: quotation_QT_2024_0001.pdf       │
│                                            │
│ [Vista Previa PDF] [Enviar] [Cancelar]    │
└────────────────────────────────────────────┘
```

---

## Casos de Prueba

### Funcionales
1. **TC-001:** Enviar cotización draft exitosamente
2. **TC-002:** Error al enviar cotización cancelada
3. **TC-003:** Error si partner no tiene email
4. **TC-004:** PDF se genera correctamente con datos de cotización
5. **TC-005:** Estado cambia a sent después de envío
6. **TC-006:** date_sent se actualiza correctamente
7. **TC-007:** Mensaje se registra en chatter
8. **TC-008:** Template de email se aplica correctamente

### No Funcionales
1. **Performance:** < 3s para generar PDF y enviar email
2. **Seguridad:** JWT + permiso sales_user

---

## Dependencias

- **US bloqueantes:**
  - US-MGN-007-001-001 (Crear Cotización)
  - US-MGN-014-006-001 (Templates de Email) - Opcional
- **Módulos requeridos:** MGN-003, MGN-014
- **Servicios externos:** SMTP configurado

---

## Notas de Implementación

- Usar Puppeteer o @react-pdf/renderer para generar PDF
- Template HTML debe incluir: logo, dirección empresa, datos cliente, tabla de líneas, totales
- Considerar usar cola (Bull/BullMQ) para envíos asíncronos si hay muchas cotizaciones
- Almacenar historial de envíos en tabla separada si se requiere auditoría completa
- Validar formato de email con regex RFC 5322

---

## Estimación Detallada

| Tarea | Horas |
|-------|-------|
| Backend | 1.5 |
| Frontend | 1 |
| PDF Template | 1 |
| Testing | 0.5 |
| Code Review | 0.5 |
| **TOTAL** | **4.5 horas = 2 SP** |

---

## Definition of Done

- [ ] Código implementado según ET
- [ ] Tests pasando (>80%)
- [ ] Code review aprobado
- [ ] PDF se genera correctamente
- [ ] Email se envía con SMTP configurado
- [ ] Estado cambia a sent
- [ ] Mensaje en chatter creado
- [ ] Swagger docs actualizado
- [ ] QA validado
- [ ] PO aprobado

---

## Referencias

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