Acciones automatizadas en Odoo: deja que el ERP haga el trabajo aburrido
Acciones de servidor, reglas de automatización y tareas planificadas: las tres piezas para que Odoo reaccione, avise y ejecute solo, sin que nadie se acuerde.
Forma parte de nuestra guía completa: Desarrollo de módulos en Odoo.
Buena parte del valor de un ERP no está en lo que guarda, sino en lo que hace sin que nadie se lo pida. Cambiar un pedido a "en preparación" cuando se confirma. Avisar al comercial si una oferta lleva tres días sin respuesta. Cerrar a fin de mes los registros que quedaron a medias. Todo eso lo hacen las personas a mano en demasiadas empresas, y es justo el tipo de trabajo repetitivo que Odoo automatiza con tres piezas que conviene no confundir: qué se ejecuta, cuándo se dispara y cada cuánto se repite.
La pieza central: la acción de servidor
Una acción de servidor (ir.actions.server) es, simplemente, "un trozo de lógica con nombre" que Odoo puede ejecutar. Puede mandar un email, crear un registro, cambiar un estado… o correr un fragmento de Python que tú escribes. Esto último es lo potente:
# Campo "code" de una ir.actions.server, modelo estate.property.offer
for record in records:
if record.status == "accepted":
continue
record.write({"status": "accepted"})
record.property_id.write({"selling_price": record.price})
record.property_id.message_post(
body="Oferta aceptada por %s" % record.partner_id.name
)
Dentro de ese código tienes a tu disposición un puñado de variables que Odoo te inyecta: records (los registros sobre los que actúas), record (si es uno solo), env (para acceder a cualquier modelo) y model. Es el mismo ORM que usas en un módulo, pero sin escribir un módulo: ideal para automatizaciones que no justifican código desplegado.
El disparador: la regla de automatización
Una acción por sí sola no se ejecuta; necesita un cuándo. Eso lo aporta una regla de automatización (el modelo base.automation), que engancha la acción a un evento: al crear un registro, al cambiar un campo concreto, cuando pasa cierto tiempo desde una fecha. Es lo que convierte "esta lógica existe" en "esta lógica salta sola".
La gran ventaja es que se configura desde la interfaz, sin desplegar nada: defines el modelo, el disparador ("cuando status pase a accepted") y la acción a ejecutar. Para automatizaciones de negocio que cambian a menudo, esto es oro: el cliente las ajusta sin llamarte.
El reloj: tareas planificadas (cron)
El tercer tipo no reacciona a un evento, sino al tiempo. Una tarea planificada (ir.cron) ejecuta un método cada X horas o días: el típico "todas las noches a las 3, revisa los pedidos vencidos".
<record id="cron_expire_offers" model="ir.cron">
<field name="name">Caducar ofertas antiguas</field>
<field name="model_id" ref="model_estate_property_offer"/>
<field name="state">code</field>
<field name="code">model._cron_expire_offers()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
</record>
Y en el modelo, el método que hace el trabajo de verdad:
@api.model
def _cron_expire_offers(self):
deadline = fields.Date.today() - timedelta(days=7)
stale = self.search([("status", "=", "new"), ("create_date", "<", deadline)])
stale.write({"status": "refused"})
El error que convierte una ayuda en un incendio
Aquí va la advertencia que más disgustos evita. Cuando metes lógica en una regla "al modificar un campo" y esa lógica, a su vez, modifica un campo, puedes provocar un bucle: la escritura dispara la regla, que escribe, que vuelve a disparar la regla… Lo he visto tumbar un servidor en minutos. La defensa es escribir automatizaciones idempotentes: que comprueben primero si hay que hacer algo (if record.status == "accepted": continue) y que no se re-disparen en cadena. Una automatización que no es idempotente no es una ayuda; es una bomba con temporizador.
Lo mismo con los cron: si tu tarea nocturna procesa "todo lo pendiente" sin control, el día que se acumulen 100.000 registros tardará horas y se solapará con la siguiente ejecución. Acota siempre el dominio y piensa en volumen.
¿Código o configuración?
Una pregunta que surge siempre: ¿automatizo desde la interfaz o con un módulo? Mi regla práctica: si la lógica es del negocio y cambiará (umbrales, plazos, a quién se avisa), va en una regla de automatización configurable, para que el cliente la toque sin depender de nadie. Si es estructural y crítica —parte de cómo funciona el producto—, va en código versionado, con tests, como cualquier otra pieza del módulo (ver buenas prácticas). Mezclar los dos criterios es como acaban los Odoo donde "nadie sabe por qué pasó esto".
Donde de verdad se nota el retorno
De todo lo que hace un ERP, la automatización es donde el retorno es más visible y más rápido: cada tarea repetitiva que eliminas son horas que tu equipo dedica a otra cosa, y errores humanos que dejan de ocurrir. No hace falta empezar por algo grande; el primer "se hace solo" suele ser el que convence a todo el mundo.
¿Hay un proceso que tu equipo repite a mano todos los días y que huele a automatizable? Cuéntanoslo en una sesión de diagnóstico y te decimos si compensa, o míralo dentro de nuestro desarrollo a medida. Y para entender qué pieza ejecuta qué, repasa los campos calculados, onchange y constraints.
Comentarios (0)
Sé el primero en comentar.
Inicia sesión para dejar un comentario.
AccederLos comentarios se revisan antes de publicarse.
Artículos relacionados
Informes PDF con QWeb en Odoo: del formulario al documento que cierra ventas
QWeb es HTML que se convierte en PDF. Te enseñamos a montar un informe, recorrer registros con t-foreach y por qué t-field te ahorra mil dolores de cabeza.
Herencia en Odoo: la función que decide si tu código sobrevive a las actualizaciones
Extensión clásica, delegación y herencia de vistas. Las tres formas de modificar Odoo sin tocar el core —y por qué heredar en vez de copiar te ahorra cada migración.
Relaciones entre modelos en Odoo: Many2one, One2many y Many2many sin liarte
Las tres relaciones que conectan tus datos, qué guardan de verdad en la base de datos y los comandos para escribirlas sin romper nada.