docs: Add comprehensive documentation for all new features
- FEATURES_OVERVIEW.md: Complete summary of all system features - ANALYTICS.md: Analytics and reporting system documentation - ODOO_INTEGRATION.md: Odoo ERP integration guide - AB_TESTING.md: A/B testing system documentation - CONTENT_RECYCLING.md: Content recycling system docs - THREAD_SERIES.md: Thread series and scheduled posts - IMAGE_TEMPLATES.md: Visual template system documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
369
docs/ODOO_INTEGRATION.md
Normal file
369
docs/ODOO_INTEGRATION.md
Normal file
@@ -0,0 +1,369 @@
|
||||
# Integración con Odoo
|
||||
|
||||
Sincronización bidireccional con Odoo ERP para productos, servicios y leads.
|
||||
|
||||
## Descripción General
|
||||
|
||||
La integración permite:
|
||||
- **Importar** productos y servicios desde Odoo
|
||||
- **Exportar** leads generados en redes sociales al CRM de Odoo
|
||||
- **Consultar** resumen de ventas
|
||||
|
||||
## Configuración
|
||||
|
||||
### Variables de Entorno
|
||||
|
||||
```bash
|
||||
# .env
|
||||
ODOO_URL=https://tuempresa.odoo.com
|
||||
ODOO_DB=nombre_base_datos
|
||||
ODOO_USERNAME=usuario@empresa.com
|
||||
ODOO_PASSWORD=api_key_o_password
|
||||
ODOO_SYNC_ENABLED=true # false para deshabilitar
|
||||
```
|
||||
|
||||
### Obtener API Key en Odoo
|
||||
|
||||
1. Ir a **Ajustes > Usuarios**
|
||||
2. Seleccionar tu usuario
|
||||
3. Pestaña **Claves de API**
|
||||
4. Crear nueva clave
|
||||
|
||||
## Modelos de Datos
|
||||
|
||||
### Lead
|
||||
Leads generados desde interacciones en redes sociales.
|
||||
|
||||
```python
|
||||
Lead:
|
||||
id: int
|
||||
interaction_id: int (FK, opcional)
|
||||
platform: str # x, threads, instagram, facebook, manual
|
||||
|
||||
# Contacto
|
||||
name: str
|
||||
email: str
|
||||
phone: str
|
||||
company: str
|
||||
|
||||
# Social
|
||||
username: str
|
||||
profile_url: str
|
||||
|
||||
# Interés
|
||||
interest: str
|
||||
source_content: str
|
||||
notes: str
|
||||
products_interested: [int] # IDs de productos
|
||||
services_interested: [int] # IDs de servicios
|
||||
|
||||
# Estado
|
||||
status: str # new, contacted, qualified, proposal, won, lost
|
||||
priority: str # low, medium, high, urgent
|
||||
|
||||
# Odoo
|
||||
odoo_lead_id: int
|
||||
synced_to_odoo: bool
|
||||
odoo_synced_at: datetime
|
||||
```
|
||||
|
||||
### OdooSyncLog
|
||||
Registro de operaciones de sincronización.
|
||||
|
||||
```python
|
||||
OdooSyncLog:
|
||||
id: int
|
||||
sync_type: str # products, services, leads, sales
|
||||
direction: str # import, export
|
||||
status: str # started, completed, failed, partial
|
||||
records_processed: int
|
||||
records_created: int
|
||||
records_updated: int
|
||||
records_failed: int
|
||||
error_message: str
|
||||
error_details: JSON
|
||||
started_at: datetime
|
||||
completed_at: datetime
|
||||
```
|
||||
|
||||
### Campos Odoo en Product/Service
|
||||
|
||||
```python
|
||||
# En Product
|
||||
odoo_product_id: int (unique)
|
||||
odoo_last_synced: datetime
|
||||
|
||||
# En Service
|
||||
odoo_service_id: int (unique)
|
||||
odoo_last_synced: datetime
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Odoo Status
|
||||
|
||||
#### GET /api/odoo/status
|
||||
Verifica conexión con Odoo.
|
||||
|
||||
**Respuesta exitosa:**
|
||||
```json
|
||||
{
|
||||
"connected": true,
|
||||
"version": "17.0",
|
||||
"uid": 2
|
||||
}
|
||||
```
|
||||
|
||||
**Sin conexión:**
|
||||
```json
|
||||
{
|
||||
"connected": false,
|
||||
"error": "Authentication failed",
|
||||
"configured": true
|
||||
}
|
||||
```
|
||||
|
||||
### Sincronización
|
||||
|
||||
#### POST /api/odoo/sync/products
|
||||
Sincroniza productos desde Odoo.
|
||||
|
||||
**Parámetros:**
|
||||
- `limit` (int, default=100): Máximo de productos
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"message": "Products synced successfully",
|
||||
"success": true,
|
||||
"processed": 50,
|
||||
"created": 10,
|
||||
"updated": 40,
|
||||
"failed": 0
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/odoo/sync/services
|
||||
Sincroniza servicios desde Odoo.
|
||||
|
||||
#### POST /api/odoo/sync/leads
|
||||
Exporta leads sin sincronizar a Odoo CRM.
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"message": "Leads exported successfully",
|
||||
"success": true,
|
||||
"processed": 5,
|
||||
"created": 5,
|
||||
"failed": 0
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /api/odoo/sync/logs
|
||||
Obtiene historial de sincronizaciones.
|
||||
|
||||
**Parámetros:**
|
||||
- `limit` (int, default=20)
|
||||
|
||||
#### GET /api/odoo/sales
|
||||
Obtiene resumen de ventas desde Odoo.
|
||||
|
||||
**Parámetros:**
|
||||
- `days` (int, default=30)
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"period_days": 30,
|
||||
"total_orders": 15,
|
||||
"total_revenue": 125000.00,
|
||||
"avg_order_value": 8333.33,
|
||||
"orders": [...]
|
||||
}
|
||||
```
|
||||
|
||||
### Leads API
|
||||
|
||||
#### GET /api/leads/
|
||||
Lista leads con filtros.
|
||||
|
||||
**Parámetros:**
|
||||
- `status`: new, contacted, qualified, proposal, won, lost
|
||||
- `priority`: low, medium, high, urgent
|
||||
- `platform`: x, threads, instagram, facebook, manual
|
||||
- `synced`: true/false (sincronizado a Odoo)
|
||||
- `limit`, `offset`: Paginación
|
||||
|
||||
#### GET /api/leads/{lead_id}
|
||||
Obtiene un lead específico.
|
||||
|
||||
#### POST /api/leads/
|
||||
Crea lead manualmente.
|
||||
|
||||
**Body:**
|
||||
```json
|
||||
{
|
||||
"name": "Juan Pérez",
|
||||
"email": "juan@empresa.com",
|
||||
"phone": "+52 664 123 4567",
|
||||
"company": "Empresa SA",
|
||||
"platform": "manual",
|
||||
"interest": "Interesado en automatización",
|
||||
"priority": "high"
|
||||
}
|
||||
```
|
||||
|
||||
#### POST /api/leads/from-interaction/{interaction_id}
|
||||
Convierte una interacción en lead.
|
||||
|
||||
**Parámetros:**
|
||||
- `interest` (str): Descripción del interés
|
||||
- `priority` (str): Prioridad
|
||||
- `notes` (str): Notas adicionales
|
||||
|
||||
#### PUT /api/leads/{lead_id}
|
||||
Actualiza un lead.
|
||||
|
||||
#### DELETE /api/leads/{lead_id}
|
||||
Elimina un lead.
|
||||
|
||||
#### POST /api/leads/{lead_id}/sync-odoo
|
||||
Sincroniza un lead específico a Odoo.
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"message": "Lead synced to Odoo successfully",
|
||||
"odoo_lead_id": 1234
|
||||
}
|
||||
```
|
||||
|
||||
#### GET /api/leads/stats/summary
|
||||
Obtiene estadísticas de leads.
|
||||
|
||||
**Respuesta:**
|
||||
```json
|
||||
{
|
||||
"total": 50,
|
||||
"by_status": {
|
||||
"new": 20,
|
||||
"contacted": 15,
|
||||
"qualified": 10,
|
||||
"won": 5
|
||||
},
|
||||
"by_platform": {
|
||||
"x": 25,
|
||||
"threads": 15,
|
||||
"manual": 10
|
||||
},
|
||||
"by_priority": {
|
||||
"high": 10,
|
||||
"medium": 30,
|
||||
"low": 10
|
||||
},
|
||||
"unsynced_to_odoo": 8
|
||||
}
|
||||
```
|
||||
|
||||
## Tareas Programadas
|
||||
|
||||
### sync_products_from_odoo
|
||||
- **Frecuencia:** Diario a las 6:00 AM
|
||||
- **Función:** Importa/actualiza productos desde Odoo
|
||||
- **Límite:** 200 productos por ejecución
|
||||
|
||||
### sync_services_from_odoo
|
||||
- **Frecuencia:** Diario a las 6:05 AM
|
||||
- **Función:** Importa/actualiza servicios desde Odoo
|
||||
- **Límite:** 100 servicios por ejecución
|
||||
|
||||
### export_leads_to_odoo
|
||||
- **Frecuencia:** Cada hora (minuto 30)
|
||||
- **Función:** Exporta leads no sincronizados al CRM
|
||||
|
||||
## Dashboard de Leads
|
||||
|
||||
Accede en `/dashboard/leads`.
|
||||
|
||||
### Características:
|
||||
- Cards de estadísticas (total, nuevos, contactados, etc.)
|
||||
- Filtros por estado, prioridad y plataforma
|
||||
- Lista paginada de leads
|
||||
- Modal para crear/editar leads
|
||||
- Botones de sincronización individual y masiva
|
||||
|
||||
### Estados de Lead
|
||||
|
||||
| Estado | Descripción |
|
||||
|--------|-------------|
|
||||
| `new` | Lead nuevo sin contactar |
|
||||
| `contacted` | Se ha hecho contacto inicial |
|
||||
| `qualified` | Lead calificado con potencial |
|
||||
| `proposal` | Se envió propuesta |
|
||||
| `won` | Lead convertido a cliente |
|
||||
| `lost` | Lead perdido |
|
||||
|
||||
### Prioridades
|
||||
|
||||
| Prioridad | Color |
|
||||
|-----------|-------|
|
||||
| `urgent` | Rojo |
|
||||
| `high` | Naranja |
|
||||
| `medium` | Azul |
|
||||
| `low` | Gris |
|
||||
|
||||
## Ejemplo de Uso
|
||||
|
||||
```python
|
||||
from app.services.odoo_service import odoo_service
|
||||
|
||||
# Verificar conexión
|
||||
status = await odoo_service.test_connection()
|
||||
if status["connected"]:
|
||||
print(f"Conectado a Odoo {status['version']}")
|
||||
|
||||
# Sincronizar productos
|
||||
result = await odoo_service.sync_products(limit=50)
|
||||
print(f"Productos: {result['created']} nuevos, {result['updated']} actualizados")
|
||||
|
||||
# Exportar leads
|
||||
result = await odoo_service.export_leads_to_odoo()
|
||||
print(f"Leads exportados: {result['created']}")
|
||||
|
||||
# Obtener ventas
|
||||
sales = await odoo_service.get_sales_summary(days=30)
|
||||
print(f"Ventas: ${sales['total_revenue']:,.2f}")
|
||||
```
|
||||
|
||||
## Mapeo de Campos
|
||||
|
||||
### Producto Odoo → Local
|
||||
| Odoo | Local |
|
||||
|------|-------|
|
||||
| id | odoo_product_id |
|
||||
| name | name |
|
||||
| description_sale | description |
|
||||
| list_price | price |
|
||||
| categ_id | category |
|
||||
| qty_available | stock |
|
||||
|
||||
### Lead Local → Odoo
|
||||
| Local | Odoo |
|
||||
|-------|------|
|
||||
| interest | name |
|
||||
| name | contact_name |
|
||||
| email | email_from |
|
||||
| phone | phone |
|
||||
| company | partner_name |
|
||||
| (generated) | description |
|
||||
| priority | priority (0-2) |
|
||||
|
||||
## Notas Técnicas
|
||||
|
||||
- La conexión usa XML-RPC (protocolo estándar de Odoo)
|
||||
- Cada sincronización crea un registro en `odoo_sync_logs`
|
||||
- Los productos/servicios se identifican por `odoo_product_id`/`odoo_service_id`
|
||||
- Si un producto local ya existe (mismo ID de Odoo), se actualiza
|
||||
- Los leads se exportan como tipo "lead" (no "opportunity")
|
||||
Reference in New Issue
Block a user