Personalización low-code (Studio-style)¶
Odoo Studio es un editor visual exclusivo de Enterprise. Las personalizaciones que hace (campos, vistas, acciones automatizadas) son registros ordinarios de Odoo guardados en la base de datos. Este plugin crea esos mismos registros por RPC, así que obtienes los resultados comunes de Studio también en Community, sin la licencia.
Alcance honesto
Esto cubre cambios pequeños y low-code: un campo, un ajuste de vista, una automatización simple. No sustituye el desarrollo serio de módulos (código empaquetado, migraciones, pruebas, lógica de negocio compleja). Para eso, construye un módulo. Ver ¿Es como Odoo Studio?.
Novedades en v1.5.0: estas recetas necesitan el perfil builder
El perfil de permisos por defecto (standard) trata los campos, las vistas
y las automatizaciones como personalización: odoo_add_field y
odoo_add_automation no se listan, y un odoo_create sobre ir.ui.view se
rechaza. Estas recetas necesitan el Permission profile builder (o
full), que fijas en /plugin → odoo-tools → Configure options;
luego reconecta el servidor (/mcp). Usa builder solo en sandboxes y
staging: las automatizaciones corren Python en el servidor de Odoo, así
que en confidencialidad builder equivale a full. Claude nunca cambia la
opción ni un archivo de política por su cuenta; si la política rechaza un
paso, te dice qué perfil necesita y se detiene. Ver
Política de permisos.
Dos límites siguen bajo builder: un campo cuyo nombre parece una credencial
(x_api_token) se retiene en las lecturas, y las escrituras en
website.page siguen la regla de delegación hacia su vista (ir.ui.view):
ver Delegación.
Dónde viven los cambios¶
En la instancia/base de datos, exactamente como Studio, no como código de módulo en un repositorio. Sobreviven a las actualizaciones como personalizaciones manuales. Si necesitas código en un repositorio, eso es desarrollo de módulos y queda fuera del alcance de este plugin.
1. Agregar un campo personalizado¶
Usa la herramienta odoo_add_field. Crea un campo con state='manual' y fuerza el
prefijo de nombre requerido x_.
odoo_add_field {
"model": "res.partner",
"name": "loyalty_points",
"label": "Puntos de lealtad",
"field_type": "integer"
}
El nombre loyalty_points se convierte en x_loyalty_points.
Ejemplo relacional:
odoo_add_field { "model": "res.partner", "name": "account_manager",
"label": "Ejecutivo de cuenta", "field_type": "many2one", "relation": "res.users" }
Para un campo selection, pasa selection como [["a","A"],["b","B"]]. Después de
crear el campo, agrégalo a una vista de formulario o lista (paso 2) para que los
usuarios lo vean.
2. Ajustar una vista (heredada)¶
No hay una herramienta dedicada; usa odoo_create sobre ir.ui.view con un arch
heredado para no sobrescribir la vista base. Primero encuentra la vista a extender:
odoo_search_read { "model": "ir.ui.view",
"domain": [["model","=","res.partner"],["type","=","form"]],
"fields": ["name","xml_id"], "limit": 5 }
Luego crea una vista heredada:
odoo_create { "model": "ir.ui.view", "values": {
"name": "res.partner.form.x_loyalty",
"model": "res.partner",
"inherit_id": <id_vista_base>,
"arch_db": "<xpath expr=\"//field[@name='email']\" position=\"after\"><field name=\"x_loyalty_points\"/></xpath>"
}}
Prefiere xpath ... position="after|before|inside|replace" en lugar de reescribir
la vista completa.
3. Agregar una automatización¶
Usa odoo_add_automation. El Python corre bajo el safe_eval de Odoo; la
herramienta lo valida antes de enviarlo, lo que importa sobre todo en Odoo
online/SaaS, donde el Python arbitrario se rechaza del lado del servidor.
odoo_add_automation {
"model": "crm.lead",
"name": "Marcar leads calientes",
"trigger": "on_create_or_write",
"code": "for rec in records:\n if rec.probability and rec.probability > 80:\n rec.write({'priority': '3'})"
}
Reglas de safe_eval (las aplica la herramienta)
El código corre bajo el safe_eval de Odoo. Prohibido: import, def,
class, return, with, el acceso a nombres o atributos que empiezan con
guion bajo o dunder (__) y la asignación de atributos
(rec.campo = valor compila a STORE_ATTR y se rechaza: usa
rec.write({...})). La herramienta rechaza esos constructos antes de
enviar, con una remediación clara, así que te enteras localmente en vez de por
un error del servidor.
Nombres disponibles en ese contexto: env, model, record/records,
datetime, dateutil, time, UserError (Warning en Odoo 10-12).
Para devolver una acción, asigna action = {...} como última sentencia
(nunca return).
Estas recetas requieren administrador
Crear ir.model.fields, ir.ui.view, base.automation
(base.action.rule en Odoo 10) y su ir.actions.server exige permisos
técnicos (Ajustes / Técnico). Con el usuario de negocio de mínimo privilegio
recomendado en Seguridad verás AccessError en cada receta:
ejecuta estas recetas con un administrador. Además del permiso de Odoo, la
política de permisos del plugin debe estar en builder o full.
Enterprise vs Community¶
- Los campos, vistas y automatizaciones creados aquí funcionan en ambas ediciones.
- En Enterprise no aparecerán dentro del editor de Studio (no están etiquetados
como personalizaciones
web_studio), pero se comportan igual en tiempo de ejecución. - Los modelos exclusivos de Enterprise (por ejemplo
documents.document) siguen sin poder usarse en Community: la capa de compatibilidad lanza un error claro.
Verificar (definición de terminado)¶
Lee el registro de vuelta y confirma el efecto:
- Campo:
odoo_fields_get { "model": "<modelo>" }muestra el nuevo campox_. - Vista: abre el formulario en Odoo (o lee la
ir.ui.viewheredada). - Automatización: dispárala sobre un registro y lee el campo modificado.
Referencia de skill: /odoo-tools:odoo-studio-style.