Apuntes DAM
    Tema 4 de 6SGE · 2º DAM

    Sistemas de Gestión Empresarial

    Adaptación de un ERP-CRM

    Parametrizar, personalizar o desarrollar: campos, vistas heredadas con XPath, reglas de automatización, acciones de servidor, informes QWeb y buenas prácticas, con retos XPath sobre una vista de Odoo.

    60 min lecturaIntermedio

    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 🚗

    🎛️
    Parametrizar
    Ajustar el asiento y los espejos: opciones que ya trae el coche.
    🧰
    Personalizar
    Poner accesorios de catálogo: campos, vistas o automatizaciones sin tocar el motor.
    🔧
    Desarrollar
    Modificar el motor en el taller: módulos a medida con código.
    NivelEjemplosQuiénImpacto al actualizar
    ParametrizaciónImpuestos, plazos de pago, rutas de almacén, etapas del CRM, secuenciasConsultor o usuario claveNinguno
    Personalización sin códigoCampos nuevos, vistas modificadas, informes, acciones automatizadas, plantillas de correoConsultor (modo desarrollador o Studio)Bajo, pero conviene revisarlo
    Desarrollo a medidaMódulos con modelos, lógica, vistas y seguridad propios (ver el tema de desarrollo de componentes)ProgramadorAlto: 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écnicoPara qué
    Estructura de la base de datos → Modelos / CamposCrear campos x_ (texto, número, fecha, selección, relación…) en un modelo
    Interfaz de usuario → VistasCrear vistas heredadas que modifican las existentes con XPath
    Acciones → Acciones de servidorOperaciones que se lanzan desde un botón o el menú Acción: actualizar campos, crear registros, código Python
    Automatización → Reglas de automatizaciónDisparadores: al crear, al modificar un campo, cuando se cumple una condición o pasado un plazo
    Automatización → Acciones planificadasTareas periódicas (cron): recordatorios, cierres, sincronizaciones
    Informes → Informes / Vistas QWebPlantillas de los PDF
    Seguridad → Grupos, Derechos de acceso, Reglas de registroQuién ve y modifica qué
    Correo → PlantillasCorreos con campos del registro (asunto, cuerpo, adjuntos)
    accion-servidor.py
    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

    Los cambios hechos desde la interfaz se guardan en la base de datos, no en ficheros: es fácil perder la pista de quién cambió qué. Hay que documentarlos (qué, por qué, dónde) y, si son importantes, trasladarlos a un módulo propio versionado con Git para poder instalarlos en otra base de datos.

    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.

    views/sale_order_views.xml
    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>
    positionEfecto
    after / beforeInserta el contenido detrás / delante del nodo
    insideLo añade como último hijo del nodo (por defecto)
    replaceSustituye el nodo (con cuidado: otros módulos pueden depender de él)
    attributesCambia atributos: invisible, required, readonly, string, groups, widget…
    moveMueve 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:

    XPath sobre una vista de Odoo
    sale_order_form.xml
    expresión XPath

    Retos: localizar nodos para heredar la vista

    🔎XPathEl campo del clienteFácil

    Selecciona el elemento field del cliente (name = partner_id), que es donde se anclaría un campo nuevo que tenga que ir justo debajo.

    sale_order_form.xmlsolo lectura
    expresión XPath
    🔎XPathBotones de la cabeceraFácil

    Devuelve el nombre técnico (atributo name, como texto) de todos los botones de la cabecera, en orden.

    sale_order_form.xmlsolo lectura
    expresión XPath
    🔎XPathColumnas de las líneasMedio

    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).

    sale_order_form.xmlsolo lectura
    expresión XPath
    🔎XPathTítulos de las pestañasMedio

    Devuelve el texto visible (atributo string) de cada pestaña del cuaderno (notebook).

    sale_order_form.xmlsolo lectura
    expresión XPath
    🔎XPathÚltimo campo del grupo de fechasMedio

    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".

    sale_order_form.xmlsolo lectura
    expresión XPath
    🔎XPathCampos de la cabecera del formularioDifícil

    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.

    sale_order_form.xmlsolo lectura
    expresión XPath
    PROGRAMACIÓN ODOO: HERENCIA de vistas XML | Modificar vistas existentes | Xpath e inherit_id Odoo — Josuhe Uh

    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:

    report_saleorder_inherit.xml
    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.

    1. Parametrizar primero: Ventas → Ajustes tiene opciones de bloqueo y aprobación; comprobar si bastan.
    2. Si no, crear el campo x_aprobado (booleano) y mostrarlo solo al grupo de gerencia.
    3. Regla de automatización que crea una actividad para gerencia cuando el pedido supera el importe.
    4. Vista heredada que oculta el botón Confirmar mientras el pedido no esté aprobado (invisible con una condición).
    5. Probar con usuarios de cada perfil, documentar y formar.
    6. Si la lógica crece (validaciones en el servidor, varios niveles), pasarla a un módulo a medida.

    Ocultar no es proteger

    Ocultar un botón o un campo en la vista es solo cosmético: un usuario puede saltárselo desde la API o la importación. Las restricciones de verdad se ponen en la seguridad (grupos y reglas de registro) o en la lógica del modelo en el servidor.

    5. Herramientas y buenas prácticas

    HerramientaUso
    Modo desarrollador (?debug=1)Ver nombres técnicos, editar vistas, ver metadatos de un registro
    odoo-bin scaffoldGenerar el esqueleto de un módulo propio
    odoo-bin shellConsola Python con el entorno del ERP cargado para probar y corregir datos
    -u modulo --dev=xml,reloadActualizar un módulo y recargar vistas y código mientras se desarrolla
    Git y entorno de pruebasVersionar las adaptaciones y probarlas antes de pasarlas a producción
    Odoo Apps / OCABuscar 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

    Ejercicio Práctico
    Fácil

    ¿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.

    Ejercicio Práctico
    Medio

    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.

    Ejercicio Práctico
    Difícil

    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.

    ¿Has terminado este tema?

    Crea una cuenta gratis para guardar qué temas has terminado, subir de nivel y ganar medallas.

    Guardar mi progreso