- 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>
370 lines
7.5 KiB
Markdown
370 lines
7.5 KiB
Markdown
# 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")
|