1. Posibilidades de adaptación
Ninguna empresa trabaja exactamente como prevé el estándar. Un ERP se adapta a varios niveles, de menor a mayor esfuerzo y riesgo. La regla de oro: usar el estándar siempre que se pueda, porque cada cambio a medida hay que mantenerlo y migrarlo en cada nueva versión.
Adaptar el ERP es como ajustar un coche 🚗
| Nivel | Ejemplos | Quién | Impacto al actualizar |
|---|---|---|---|
| Parametrización | Impuestos, plazos de pago, rutas de almacén, etapas del CRM, secuencias | Consultor o usuario clave | Ninguno |
| Personalización sin código | Campos nuevos, vistas modificadas, informes, acciones automatizadas, plantillas de correo | Consultor (modo desarrollador o Studio) | Bajo, pero conviene revisarlo |
| Desarrollo a medida | Módulos con modelos, lógica, vistas y seguridad propios (ver el tema de desarrollo de componentes) | Programador | Alto: hay que adaptar el código a cada versión |
Qué se puede adaptar
- Datos: campos nuevos en modelos existentes (
x_si se crean desde la interfaz) y modelos nuevos. - Formularios y listas: mostrar, ocultar, reordenar, hacer obligatorio o de solo lectura un campo.
- Procesos: etapas, aprobaciones, acciones automáticas al crear o cambiar un registro, tareas programadas.
- Informes: plantillas PDF (QWeb), vistas pivote y tableros.
- Seguridad: grupos, derechos de acceso y reglas de registro.
- Comunicaciones: plantillas de correo, actividades y notificaciones.
2. Adaptar sin programar
Con el modo desarrollador activo, el menú Ajustes → Técnico da acceso a los objetos internos del ERP. Odoo Enterprise incluye además Studio, un editor visual que hace lo mismo arrastrando elementos.
| Menú técnico | Para qué |
|---|---|
| Estructura de la base de datos → Modelos / Campos | Crear campos x_ (texto, número, fecha, selección, relación…) en un modelo |
| Interfaz de usuario → Vistas | Crear vistas heredadas que modifican las existentes con XPath |
| Acciones → Acciones de servidor | Operaciones que se lanzan desde un botón o el menú Acción: actualizar campos, crear registros, código Python |
| Automatización → Reglas de automatización | Disparadores: al crear, al modificar un campo, cuando se cumple una condición o pasado un plazo |
| Automatización → Acciones planificadas | Tareas periódicas (cron): recordatorios, cierres, sincronizaciones |
| Informes → Informes / Vistas QWeb | Plantillas de los PDF |
| Seguridad → Grupos, Derechos de acceso, Reglas de registro | Quién ve y modifica qué |
| Correo → Plantillas | Correos con campos del registro (asunto, cuerpo, adjuntos) |
1# Código de una regla de automatización «Al modificar» sobre sale.order (Odoo 17/18)
2# Variables disponibles: record/records, env, model, datetime, UserError, log...
3for pedido in records:
4 if pedido.amount_total > 10000 and not pedido.x_aprobado:
5 pedido.activity_schedule(
6 "mail.mail_activity_data_todo",
7 user_id=env.ref("base.user_admin").id,
8 summary="Aprobar pedido de más de 10.000 €",
9 )Documentar cada cambio
3. Herencia de vistas con XPath
Las vistas de Odoo son XML. Nunca se editan las originales: se crea una vista heredada que indica, con una expresión XPath, en qué nodo de la vista original se hace el cambio y con qué position. Así el cambio sobrevive a las actualizaciones del módulo original.
1<record id="view_order_form_inherit_empresa" model="ir.ui.view">
2 <field name="name">sale.order.form.inherit.empresa</field>
3 <field name="model">sale.order</field>
4 <field name="inherit_id" ref="sale.view_order_form"/>
5 <field name="arch" type="xml">
6 <!-- Añadir un campo debajo del cliente -->
7 <xpath expr="//field[@name='partner_id']" position="after">
8 <field name="x_canal_venta"/>
9 </xpath>
10 <!-- Hacer obligatorio el plazo de pago -->
11 <xpath expr="//field[@name='payment_term_id']" position="attributes">
12 <attribute name="required">1</attribute>
13 </xpath>
14 <!-- Ocultar la columna de descuento para quien no sea responsable de ventas -->
15 <xpath expr="//field[@name='order_line']/list/field[@name='discount']" position="attributes">
16 <attribute name="groups">sales_team.group_sale_manager</attribute>
17 </xpath>
18 <!-- Nueva pestaña al final del cuaderno -->
19 <xpath expr="//notebook" position="inside">
20 <page name="obra" string="Datos de la obra">
21 <group>
22 <field name="x_direccion_obra"/>
23 <field name="x_fecha_inicio_obra"/>
24 </group>
25 </page>
26 </xpath>
27 </field>
28</record>| position | Efecto |
|---|---|
| after / before | Inserta el contenido detrás / delante del nodo |
| inside | Lo añade como último hijo del nodo (por defecto) |
| replace | Sustituye el nodo (con cuidado: otros módulos pueden depender de él) |
| attributes | Cambia atributos: invisible, required, readonly, string, groups, widget… |
| move | Mueve un nodo existente a otra posición |
Prueba expresiones XPath sobre una versión simplificada del formulario de pedido de venta. Con string(@name) obtienes el texto de un atributo:
Retos: localizar nodos para heredar la vista
Selecciona el elemento field del cliente (name = partner_id), que es donde se anclaría un campo nuevo que tenga que ir justo debajo.
Devuelve el nombre técnico (atributo name, como texto) de todos los botones de la cabecera, en orden.
Devuelve, como texto, el nombre de los campos que se muestran como columnas en la lista de líneas del pedido (dentro del campo order_line).
Devuelve el texto visible (atributo string) de cada pestaña del cuaderno (notebook).
Selecciona el último campo del grupo llamado fechas: si quieres añadir un campo al final del grupo, ese es el nodo de referencia para position="after".
Cuenta cuántos elementos field hay en el formulario sin contar las columnas de la lista de líneas (los que tienen un ancestro list). El resultado es un número.
4. Adaptar informes y procesos
Informes QWeb
Los PDF (facturas, pedidos, albaranes) son plantillas QWeb: HTML con directivas t-foreach, t-if, t-esc o t-field. Se adaptan también por herencia con XPath:
1<template id="report_saleorder_obra" inherit_id="sale.report_saleorder_document">
2 <xpath expr="//div[@id='informations']" position="after">
3 <div t-if="doc.x_direccion_obra" class="mt-3">
4 <strong>Dirección de la obra:</strong>
5 <span t-field="doc.x_direccion_obra"/>
6 </div>
7 </xpath>
8</template>Adaptar un proceso
Ejemplo: los pedidos de más de 10.000 € necesitan aprobación de la gerencia antes de confirmarse.
- Parametrizar primero: Ventas → Ajustes tiene opciones de bloqueo y aprobación; comprobar si bastan.
- Si no, crear el campo
x_aprobado(booleano) y mostrarlo solo al grupo de gerencia. - Regla de automatización que crea una actividad para gerencia cuando el pedido supera el importe.
- Vista heredada que oculta el botón Confirmar mientras el pedido no esté aprobado (
invisiblecon una condición). - Probar con usuarios de cada perfil, documentar y formar.
- Si la lógica crece (validaciones en el servidor, varios niveles), pasarla a un módulo a medida.
Ocultar no es proteger
5. Herramientas y buenas prácticas
| Herramienta | Uso |
|---|---|
| Modo desarrollador (?debug=1) | Ver nombres técnicos, editar vistas, ver metadatos de un registro |
| odoo-bin scaffold | Generar el esqueleto de un módulo propio |
| odoo-bin shell | Consola Python con el entorno del ERP cargado para probar y corregir datos |
| -u modulo --dev=xml,reload | Actualizar un módulo y recargar vistas y código mientras se desarrolla |
| Git y entorno de pruebas | Versionar las adaptaciones y probarlas antes de pasarlas a producción |
| Odoo Apps / OCA | Buscar primero un módulo existente (la OCA publica cientos, libres) antes de desarrollar |
- Separar entornos: desarrollo → pruebas → producción.
- Nombrar las adaptaciones de forma coherente (prefijo de la empresa en módulos, campos y vistas).
- No modificar nunca el código de los módulos oficiales: siempre herencia.
- Registrar cada adaptación: petición, solución, fecha, responsable y pruebas realizadas.
6. Ejercicios
¿Parametrizar, personalizar o desarrollar?
Clasifica cada petición en parametrización, personalización sin código o desarrollo a medida, y justifícalo: a) Añadir el IVA reducido del 10 %. b) Guardar la matrícula del vehículo en los albaranes. c) Calcular automáticamente el precio de un mueble a partir de sus medidas y materiales. d) Enviar un correo al cliente cuando su pedido pase a «enviado». e) Añadir una etapa «Visita técnica» en el embudo del CRM. f) Sincronizar el stock con la tienda de un marketplace externo.
Adaptar el formulario de clientes
En tu Odoo de pruebas, con el modo desarrollador: crea en res.partner los campos x_codigo_cliente (texto) y x_tipo_cliente (selección: particular, pyme, gran cuenta). Crea una vista heredada del formulario de contacto que los muestre debajo del NIF (vat), haga obligatorio el teléfono y añada una pestaña «Condiciones» con x_tipo_cliente. Escribe el XML de la vista heredada.
Automatizar el seguimiento de presupuestos
Diseña (y si puedes, configura) la adaptación: cuando un presupuesto lleve 7 días enviado sin respuesta, se crea una actividad «Llamar al cliente» para su comercial; a los 15 días se envía un recordatorio por correo al cliente; y en la lista de presupuestos se muestra una columna con los días transcurridos. Indica qué herramientas usas y en qué orden.