- Frontend React (SKEEN Brand) con Vite, TypeScript, Tailwind - Frontend Homenest (versión alternativa) - Módulos Odoo 17 custom (citas, pacientes, monedero, pagos, ventas, inventario, whatsapp) - WACRM fork (Next.js 16 + Supabase) - Hermes + Bridge + Skills (Qwen3.6 via Nan Builders) - Scripts de migración y operación - Documentación extensiva en docs/
109 lines
3.0 KiB
Python
109 lines
3.0 KiB
Python
import os
|
|
import xmlrpc.client
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
ODOO_URL = os.environ.get("ODOO_URL", "http://odoo:8069")
|
|
ODOO_DB = os.environ.get("ODOO_DB", "skeen")
|
|
ODOO_API_KEY = os.environ.get("ODOO_API_KEY")
|
|
|
|
|
|
def odoo_api_call(model: str, method: str, args: List = None, kwargs: Dict = None) -> Any:
|
|
"""
|
|
Plugin de Hermes para comunicarse con Odoo via XML-RPC.
|
|
|
|
Uso desde skills:
|
|
odoo_api_call(model="salon.booking", method="get_available_slots",
|
|
args=[service_id, date_from, date_to])
|
|
|
|
Args:
|
|
model: Nombre del modelo Odoo (ej: 'res.partner', 'salon.booking')
|
|
method: Metodo a ejecutar (ej: 'search_read', 'create', 'write')
|
|
args: Lista de argumentos posicionales
|
|
kwargs: Diccionario de argumentos nombrados
|
|
|
|
Returns:
|
|
Resultado de la llamada XML-RPC
|
|
"""
|
|
if args is None:
|
|
args = []
|
|
if kwargs is None:
|
|
kwargs = {}
|
|
|
|
if not ODOO_API_KEY:
|
|
raise ValueError("ODOO_API_KEY no configurada en variables de entorno")
|
|
|
|
# Autenticacion
|
|
common = xmlrpc.client.ServerProxy(f"{ODOO_URL}/xmlrpc/2/common")
|
|
uid = common.authenticate(ODOO_DB, 1, ODOO_API_KEY, {})
|
|
|
|
if not uid:
|
|
raise ValueError("Autenticacion con Odoo fallida")
|
|
|
|
# Ejecutar metodo
|
|
models = xmlrpc.client.ServerProxy(f"{ODOO_URL}/xmlrpc/2/object")
|
|
result = models.execute_kw(
|
|
ODOO_DB, uid, ODOO_API_KEY,
|
|
model, method, args, kwargs
|
|
)
|
|
|
|
return result
|
|
|
|
|
|
def odoo_search_read(model: str, domain: List = None, fields: List[str] = None,
|
|
limit: int = 100) -> List[Dict]:
|
|
"""
|
|
Atajo para search_read en Odoo.
|
|
|
|
Uso:
|
|
odoo_search_read(model="res.partner",
|
|
domain=[["phone", "=", "+526641234567"]],
|
|
fields=["name", "email", "phone"])
|
|
"""
|
|
if domain is None:
|
|
domain = []
|
|
if fields is None:
|
|
fields = []
|
|
|
|
return odoo_api_call(
|
|
model=model,
|
|
method="search_read",
|
|
args=[domain, fields],
|
|
kwargs={"limit": limit}
|
|
)
|
|
|
|
|
|
def odoo_create(model: str, values: Dict) -> int:
|
|
"""
|
|
Atajo para create en Odoo.
|
|
|
|
Uso:
|
|
odoo_create(model="res.partner",
|
|
values={"name": "Sofia Garcia", "phone": "+526641234567"})
|
|
"""
|
|
return odoo_api_call(model=model, method="create", args=[values])
|
|
|
|
|
|
def odoo_write(model: str, ids: List[int], values: Dict) -> bool:
|
|
"""
|
|
Atajo para write en Odoo.
|
|
|
|
Uso:
|
|
odoo_write(model="salon.booking", ids=[123],
|
|
values={"state": "cancelled"})
|
|
"""
|
|
return odoo_api_call(model=model, method="write", args=[ids, values])
|
|
|
|
|
|
# Registro del plugin para Hermes
|
|
PLUGIN_NAME = "odoo_api_call"
|
|
PLUGIN_VERSION = "1.0.0"
|
|
PLUGIN_DESCRIPTION = "Comunicacion con Odoo ERP via XML-RPC"
|
|
|
|
# Herramientas expuestas (para hermes tools)
|
|
TOOLS = {
|
|
"odoo_api_call": odoo_api_call,
|
|
"odoo_search_read": odoo_search_read,
|
|
"odoo_create": odoo_create,
|
|
"odoo_write": odoo_write,
|
|
}
|