Automation is the key component of ERP, and Odoo 19 comes with great features to assist enterprises in reducing mundane tasks. Workflow Triggers form one of the most crucial parts of workflow automation in Odoo. No matter whether an email needs to be sent once a record is created, an action needs to be taken once the value is changed, or even if some activity needs to be scheduled before the expiration of a contract, everything can be done using workflow triggers without the need for coding.
Workflow triggers are defined mostly via Automated Actions in Odoo 19 (or via Odoo Studio). Businesses can set criteria to determine under what circumstances an action will be performed and on which records. In this blog, we discuss every trigger type offered by Odoo 19, configuration steps for them, and use cases.
What Are Workflow Triggers in Odoo 19?
In Odoo 19, the term “workflow trigger” refers to the “when” parameter of automation rules. This is the parameter specifying the event or condition that must occur for the corresponding server action (sending mail, modifying the value in a particular field, creating a record, etc.) to take place.
Triggers work in combination with two other components of an Automated Action:
- Model: The database table the rule monitors (e.g., Sales Order, Invoice, Contact).
- Conditions (Domain Filters): Additional filters to narrow down which specific records qualify.
- Action to Do: What happens when the trigger fires (send email, update record, execute Python code, etc.).
Note:
To access Automated Actions in Odoo 19, you must first enable developer mode.
Navigate to Settings > General Settings > Developer Tools > Activate the Developer Mode. Once enabled, go to Settings > Technical > Automation > Automated Actions.
Types of Workflow Triggers in Odoo 19
Odoo 19 provides six core trigger types in Automated Actions, each suited to different use cases. Below is a quick overview:
- Record Created
Fires once when a new record is saved for the first time on the selected model.
- Record Updated
Fires every time an existing record is edited and saved optionally on specific fields.
- Record Created & Updated
Combines creation and update triggers into a single rule for broader coverage.
- Record Deleted
Fires just before a record is deleted, allowing archiving, logging, or notification.
- Based on Date Field
Time-based trigger that fires before or after a specific date field value on a record.
- After Creation / After Update
Fires a defined period of time after a record is created or last edited.
1. Record Created Trigger
The Record Created trigger activates the automated action immediately after a new record is created and saved in the database. This is one of the most commonly used triggers for onboarding automation such as sending a welcome email when a new customer is added, or assigning a default salesperson when a new lead is created in CRM.
When to Use
Use this trigger when you need to perform an action at the moment a record enters the system. Typical scenarios include: setting default field values, notifying team members of new records, or creating linked records in another model.
Configuration Steps
- Navigate to Automated Actions
Go to Settings > Technical > Automation > Automated Actions and click New.
- Set the Model
Choose the model, e.g., Contact (res.partner) or CRM Lead (crm.lead).
- Select Trigger
In the "When" (Trigger) field, select Record Created.
- Define Action
Set the "Action to Do" — e.g., Send Email, Update Record, or Execute Code.
- Save and Test
Save the rule and create a test record to verify the action fires correctly.
Example: Notify a Salesperson on New Lead
# Action: Execute Python Code
# Trigger: Record Created | Model: CRM Lead
if record.user_id:
record.message_post(
body="New lead assigned to you: %s" % record.name,
partner_ids=[record.user_id.partner_id.id],
message_type='notification',
subtype_xmlid='mail.mt_note'
)
2. Record Updated Trigger
The Record Updated trigger fires every time an existing record is modified and saved. In Odoo 19, you can optionally specify which fields to watch the trigger will then only fire when one of those specific fields is changed. This makes it highly efficient for field-level automation.
When to Use
This trigger is very appropriate when a business process is supposed to respond to change in value in a particular field for instance, to send an email for approval when the total cost in a purchase order surpasses a certain limit or to archive a record when it is Cancelled.
Example: Send Alert When Sales Order Amount Changes
# Trigger: Record Updated | Model: Sale Order
# Watch Fields: amount_total
# Condition: amount_total > 50000
if record.amount_total > 50000:
record.message_post(
body=" Order amount exceeded $50,000. Manager approval required.",
message_type='notification'
)
Note:
In cases where fields are not specified under "When Updated," Odoo will perform the action anytime there is an update to the record. It is recommended that one only selects fields that are necessary for this reason.
3. Record Created & Updated Trigger
This trigger comprises both the “Record Created” and “Record Updated” triggers. This means that it is executed in both cases: creating a record as well as updating the existing one. This can be handy in cases where certain values in a field need to be updated whenever a record is created or edited.
Example: Always Sync a Custom Status Label
# Trigger: Record Created & Updated | Model: Sale Order
# Action: Update Record -- custom_status_label
status_map = {
'draft': 'Quotation Pending',
'sale': 'Order Confirmed',
'done': 'Fully Processed',
'cancel': 'Cancelled',
}
record.custom_status_label = status_map.get(record.state, 'Unknown')
4. Record Deleted Trigger
The Record Deleted trigger is activated right before a record gets deleted from the database. This type of trigger is very helpful in doing audit logging, which involves collecting details of the record before deletion, or in doing cleanup of related models.
Important:
As the trigger runs before the deletion process, the record is still available for the trigger operation. Any database write operations related to the about to be deleted record can fail in the presence of foreign key constraints.
Example: Log Deletion Activity
# Trigger: Record Deleted | Model: res.partner
env['mail.activity'].create({
'res_model_id': env['ir.model'].search([('model', '=', 'res.partner')]).id,
'res_id': record.id,
'activity_type_id': env.ref('mail.mail_activity_data_todo').id,
'summary': 'Record "%s" was deleted by %s' % (record.name, env.user.name),
'user_id': env.user.id,
})
5. Based on Date Field Trigger
The Based on Date Field trigger is a time-based trigger. It fires a defined number of days, hours, or months before or after the value stored in a specific date or datetime field on the record. Odoo's scheduler (cron job) evaluates this condition at regular intervals and fires the action when the time condition is met.
Common use cases include: sending a renewal reminder 30 days before a contract expires, notifying account managers 7 days before a warranty ends, or escalating unresolved tickets 3 days after the deadline passes.
Date Field Value > Offset (Days/Hours) > Trigger Fires > Action Executes
Configuration Example: Contract Expiry Reminder
- Model: To your Contract model (like hr.contract or your custom model).
- Trigger: Choose 'Based on Date Field'.
- Date Field: Choose date_end (End of Contract).
- Offset: Choose '-30' days (fired 30 days before the end of the contract).
- Action: Choose 'Send Email'. Use a pre-designed email template.
6. After Creation and After Last Update Triggers
The above-mentioned two triggers are also time-driven but distinct from the Date Field trigger since rather than tracking a date field saved on the record, they track time elapsed since creation or last update of the record.
- After Creation: Fires a defined period of time after the record was first created and saved.
- After Last Update: Fires a defined period of time after the record was most recently edited and saved.
Example: Archive Inactive Leads After 90 Days
# Trigger: After Last Update | Model: CRM Lead
# Delay: 90 days
# Condition: stage_id.name != 'Won' and active = True
if record.active and record.stage_id.name != 'Won':
record.write({'active': False})
record.message_post(
body="Lead automatically archived after 90 days of inactivity."
)
Trigger Types Summary Table
The table below provides a quick reference for all Odoo 19 workflow trigger types, their nature, and typical use cases:
| Trigger Type | Nature | Typical Use Case | Available In |
| Record Created | Event-based | Welcome emails, default value assignment, activity scheduling | Community & Enterprise |
| Record Updated | Event-based | Stage change notifications, field-level automation, approvals | Community & Enterprise |
| Record Created & Updated | Event-based | Sync fields, maintain computed values, comprehensive tracking | Community & Enterprise |
| Record Deleted | Event-based | Audit logging, cleanup of related records, compliance actions | Community & Enterprise |
| Based on Date Field | Time-based | Contract reminders, warranty expiry, deadline escalations | Community & Enterprise |
| After Creation | Time-based | Follow-up after N days of record creation, delayed onboarding | Community & Enterprise |
| After Last Update | Time-based | Archive stale records, auto-close inactive tickets | Community & Enterprise |
Using Domain Filters with Triggers
Every workflow trigger in Odoo 19 can be further refined using Domain Filters (also called "Apply On" conditions). These filters ensure the action fires only on records that match specific criteria, preventing unnecessary executions and giving you precise control over automation.
Example Domain Filter
# Domain: Only fire for CRM Leads where expected revenue > 10000
# and the lead is not in the Won stage
[
('expected_revenue', '>', 10000),
('stage_id.is_won', '=', False)
]
You can configure domain filters using Odoo's built-in Filter Editor (the visual rule builder), or by switching to Code Editor mode to write domain expressions directly. Domain filters are evaluated before the trigger fires, ensuring only the right records are processed.
Workflow Triggers via Odoo Studio
Those users who would rather not go with the code path can take advantage of the graphical interface in Odoo Studio, where users can define their own triggers without having to write in Python and XML. To do this, users will have to start Studio, head over to the Automations tab, and create a new rule.
The tool can be helpful to those who work on functional consulting and do not require developer help when creating automation rules. All of the six types of triggers are available via Odoo Studio.
Workflow Triggers in Odoo 19 serve as an important foundation in creating intelligent automation of business processes. Once users are familiar with how the six possible workflow trigger types work, including those based on events such as Record Created and Record Updated and time-based triggers like Based on Date Field and After Last Update, they will be able to automate a large number of recurring operations in all Odoo modules.
No matter if you are designing a simple notification workflow or a more complicated series of automated processes, you should be acquainted with Workflow Triggers in Odoo 19.
To read more about A Complete Guide to Extending Workflows in Odoo 19, refer to our blog A Complete Guide to Extending Workflows in Odoo 19.