Saltar a contenido

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 campo x_.
  • Vista: abre el formulario en Odoo (o lee la ir.ui.view heredada).
  • Automatización: dispárala sobre un registro y lee el campo modificado.

Referencia de skill: /odoo-tools:odoo-studio-style.