Appearance
Actions: Automation in Odoo
The Power of "It Just Happens"
Your client says: "When a lead is marked as won, I want a project to be created automatically, the account manager notified, and the lead data synced to our accounting software."
Without code, you can make all of this happen. Odoo's action system is one of the most powerful tools for functional consultants.
Three Types of Automation Actions
| Type | Purpose | Trigger | Location |
|---|---|---|---|
| Server Actions | Manual actions from UI | User clicks | Settings > Technical > Actions > Server Actions |
| Scheduled Actions | Time-based recurring tasks | Cron schedule | Settings > Technical > Automation > Scheduled Actions |
| Automated Actions | Event-driven rules | Record changes | Settings > Technical > Automation > Automated Actions |
Server Actions (ir.actions.server)
Server Actions are manual actions that users trigger from the UI. They appear in the "Actions" menu or can be added as buttons.
Action Types Available (Odoo 19)
| Action Type | Technical State | What It Does | Example Use Case |
|---|---|---|---|
| Update Record | object_write | Modify field values on records | Bulk assign salesperson, Mark as priority |
| Create Record | object_create | Create new record with values | Create task from lead |
| Duplicate Record | object_copy | Copy an existing record | Clone template records |
| Execute Code | code | Run custom Python code | Complex calculations, integrations |
| Send Webhook | webhook | POST data to external URL | Notify external system |
| Multi Actions | multi | Execute multiple child actions | Update + email + create task |
Additional Action Types (from modules)
When you install additional modules like Discuss (mail), SMS, or others, more action types become available:
- Send Email - Send email using template (requires
mailmodule) - Add Followers - Add users as followers (requires
mailmodule) - Create Next Activity - Schedule follow-up activity (requires
mailmodule) - Send SMS - Send SMS messages (requires
smsmodule)
Example: Mark Leads as High Priority
Scenario: Sales manager wants a quick action to mark selected leads as high priority.
- Go to Settings > Technical > Actions > Server Actions
- Click Create
- Set Name: "Mark as High Priority"
- Set Model: CRM Lead (
crm.lead) - Set Action Type: Update Record
- Add field update: Priority = "3" (High)
- Click "Create Contextual Action" to add to Actions menu
Usage: Select leads → Actions menu → "Mark as High Priority"
Example: Send Data to External System
Scenario: Sync won opportunities to accounting software.
- Create Server Action on CRM Lead model
- Set Action Type: Send Webhook Notification
- Set Webhook URL:
https://accounting.company.com/api/opportunities - Select Fields to Send: Name, Partner, Expected Revenue, Date Closed
Payload sent:
json
{
"_id": 42,
"_model": "crm.lead",
"_name": "Sync Won Opportunities",
"name": "Website Redesign Project",
"partner_name": "TechCorp Solutions",
"expected_revenue": 250000
}Incremental Mass Edit (List View Feature)
A built-in list view feature that allows you to update multiple records using mathematical operators.
Supported Operators
| Operator | Meaning | Example | Result (if current = 100) |
|---|---|---|---|
+= | Add to current value | +=10 | 110 |
-= | Subtract from current | -=25 | 75 |
*= | Multiply current value | *=1.15 | 115 (15% increase) |
/= | Divide current value | /=2 | 50 |
Example: 10% Price Increase
- Go to Sales > Products > Products
- Select products to update (checkbox)
- Click on the Sales Price column header
- Enter:
*=1.10 - Confirm the update
Result: Each selected product's price increases by 10%.
Scheduled Actions (ir.cron)
Scheduled Actions run automatically at specified intervals. Perfect for maintenance, reports, and batch processing.
Scheduling Options
| Interval Type | Example | Use Case |
|---|---|---|
| Minutes | Every 15 minutes | Real-time monitoring |
| Hours | Every 2 hours | Regular sync jobs |
| Days | Every 1 day at 9:00 AM | Daily reports |
| Weeks | Every Monday | Weekly summaries |
| Months | First of month | Monthly billing |
Key Configuration Fields
| Field | Purpose |
|---|---|
| Execute Every | Interval value (e.g., "2" hours) |
| Interval Unit | Minutes, Hours, Days, Weeks, Months |
| Next Execution Date | When it will run next |
| Number of Calls | -1 = unlimited, or specific count |
| Priority | Lower number = higher priority |
| Active | Must be checked to run |
How Scheduled Actions Work
- Execution: Runs in background worker thread
- User Context: Runs as the "OdooBot" user
- Failure Handling: After 5+ consecutive failures over 7+ days, auto-deactivates
- Manual Trigger: Use "Run Manually" button to test
- Concurrency: Only one instance runs at a time (prevents overlap)
Example: Send Daily Report
- Create Scheduled Action
- Set Model: Sale Order (
sale.order) - Set Execute Every: 1 Day
- Set Next Execution Date: Tomorrow at 9:00 AM
- Create Server Action: Execute Code → Generate and email report
Automated Actions (base.automation)
Automated Actions trigger automatically when specific events occur. They're the backbone of workflow automation.
Trigger Types (Odoo 19)
| Trigger | Technical Name | When It Runs | Example Use Case |
|---|---|---|---|
| Stage is set to | on_stage_set | Specific stage reached | Create project when won |
| User is set | on_user_set | Responsible assigned | Notify assignee |
| Tag is added | on_tag_set | Specific tag added | Notify when "urgent" |
| State is set to | on_state_set | State field changes | Create invoice on confirm |
| Priority is set to | on_priority_set | Priority changes | Alert on high priority |
| On archived | on_archive | Record archived | Log archival, cleanup |
| On unarchived | on_unarchive | Record restored | Re-enable subscriptions |
| On create | on_create | New record created | Assign leads to salesperson |
| On create and edit | on_create_or_write | Created or modified | Validate data |
| On update | on_write | Record modified (deprecated) | Use "On create and edit" instead |
| On deletion | on_unlink | Before record deleted | Archive instead of delete |
| On UI change | on_change | Field changed in form | Real-time validation |
| Based on date field | on_time | X time before/after date | Reminder before deadline |
| After creation | on_time_created | X time after created | Follow-up email 7 days later |
| After last update | on_time_updated | X time after modified | Reminder for stale records |
| On incoming message | on_message_received | Email/message received | Auto-reply (requires mail) |
| On outgoing message | on_message_sent | Email/message sent | Log communications (requires mail) |
| On webhook | on_webhook | External HTTP request | Receive external data |
Before/After Update Filters
For "On Update" triggers, use these domains to detect specific changes:
| Filter | Purpose | Example |
|---|---|---|
| Before Update Filter | State before change | [('state', '=', 'draft')] |
| After Update Filter | State after change | [('state', '=', 'sale')] |
| Trigger Fields | Only trigger for these fields | ['state', 'user_id'] |
Example: Auto-Assign Leads by Region
- Create Automated Action on CRM Lead
- Set Trigger: On Create
- Set Apply on:
[('state_id.name', '=', 'Maharashtra')] - Add Server Action: Update Record → Sales Team = "Pune Regional"
Result: Leads from Maharashtra automatically assigned to Pune team.
Example: Escalate Unassigned Tickets
- Create Automated Action on Helpdesk Ticket
- Set Trigger: After creation (2 hours)
- Set Apply on:
[('user_id', '=', False)] - Add Server Action: Send Email to manager + Update priority
Result: Unassigned tickets escalate after 2 hours.
All Action Types Reference
Odoo has seven distinct action types. While automation actions are most common, understanding all types helps with customization:
| Action Type | Technical Model | Purpose |
|---|---|---|
| Window Actions | ir.actions.act_window | Open views, navigate between records |
| Server Actions | ir.actions.server | Execute business logic |
| URL Actions | ir.actions.act_url | Open external URLs, downloads |
| Client Actions | ir.actions.client | Custom JS widgets, dashboards |
| Report Actions | ir.actions.report | Generate PDF/HTML reports |
| Window Close Actions | ir.actions.act_window_close | Close dialog windows |
| Scheduled Actions | ir.cron | Time-based recurring tasks |
Window Actions (ir.actions.act_window)
Window Actions open views and are used for:
- Menu items linking to list/form views
- Smart buttons that navigate to related records
- Action buttons that open specific records
- Wizards (transient models in popup)
Key fields:
| Field | Purpose | Example |
|---|---|---|
| res_model | Model to display | sale.order |
| domain | Filter which records to show | [('state', '=', 'sale')] |
| context | Pass default values, flags | {'default_partner_id': active_id} |
| view_mode | Available views (comma-separated) | list,form,kanban,calendar |
| target | Where to open | current, new (popup), fullscreen, main |
| res_id | Specific record ID (form view) | 42 |
| limit | Default list view limit | 80 |
| view_id | Specific view to use | Reference to ir.ui.view |
Target options:
current- Replace current view (default)new- Open in modal/popup dialogfullscreen- Full browser windowmain- Main content area only
URL Actions (ir.actions.act_url)
URL Actions open external URLs or trigger downloads.
Key fields:
| Field | Purpose | Values |
|---|---|---|
| url | Target URL | Any valid URL or download path |
| target | How to open | new (new tab), self (same tab), download |
Common use cases:
- Open external documentation:
https://docs.example.com - Download files:
/web/content/model/id/field/filename - Open external applications:
mailto:,tel:
Example - Download attachment:
python
return {
'type': 'ir.actions.act_url',
'url': '/web/content/%s/%s/datas/%s' % (model, record.id, filename),
'target': 'download',
}Client Actions (ir.actions.client)
Client Actions execute custom JavaScript code in the browser. Used for dashboards, custom widgets, and special interfaces.
Key fields:
| Field | Purpose | Example |
|---|---|---|
| tag | Client-side action identifier | board.board, mail.action_discuss |
| context | Data passed to JS | {'default_model': 'sale.order'} |
| params | Additional parameters | Custom JS configuration |
| res_model | Optional related model | For needaction badges |
Built-in client actions:
board.board- Dashboard displaymail.action_discuss- Discuss/messaging interfacewebsite.action_website_edit- Website editoraccount_dashboard.action_account_dashboard_main- Accounting dashboard
Report Actions (ir.actions.report)
Report Actions generate PDF, HTML, or text reports using QWeb templates.
Key fields:
| Field | Purpose | Values/Example |
|---|---|---|
| model | Model the report applies to | sale.order |
| report_type | Output format | qweb-pdf, qweb-html, qweb-text |
| report_name | QWeb template name | sale.report_saleorder |
| print_report_name | Downloaded filename | 'SO - %s' % object.name |
| paperformat_id | Paper size/margins | Reference to report.paperformat |
| attachment | Save as attachment | 'SO_%s.pdf' % object.name |
| attachment_use | Reuse saved attachment | True/False |
Report types:
qweb-pdf- PDF via wkhtmltopdf (most common)qweb-html- HTML rendered in browserqweb-text- Plain text output
Example - Print Sales Order:
xml
<record id="action_report_saleorder" model="ir.actions.report">
<field name="name">Sales Order</field>
<field name="model">sale.order</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">sale.report_saleorder</field>
<field name="print_report_name">'Sale Order - %s' % (object.name)</field>
<field name="binding_model_id" ref="model_sale_order"/>
<field name="binding_type">report</field>
</record>Comparing the Three Automation Types
| Feature | Server Actions | Scheduled Actions | Automated Actions |
|---|---|---|---|
| Trigger | Manual (user clicks) | Time-based (recurring) | Event-driven (automatic) |
| When to use | User controls when | Regular maintenance | Respond to changes |
| Runs on | Selected records | All matching (batch) | Individual record |
| User context | Current user | Scheduler user | User who triggered |
| Visibility | Actions menu, buttons | Background | Background |
| Performance | Only when run | Periodic | Every matching change |
Choosing the Right Action Type
Use Server Actions when:
- Users need to decide when to run
- Works on multiple selected records
- Should not happen automatically
- Examples: Bulk updates, export data, custom workflows
Use Scheduled Actions when:
- Needs to run at specific intervals
- Batch processing is more efficient
- Maintenance-related (cleanup, sync, reports)
- Examples: Daily reports, nightly sync, monthly billing
Use Automated Actions when:
- Response should be immediate
- Rule should apply consistently
- Workflow needs to progress automatically
- Examples: Lead assignment, notifications, escalations
Best Practices
Automation Best Practices
- Use precise domains: Don't trigger on all records; filter to relevant ones
- Avoid infinite loops: Be careful when automation updates fields that trigger other automations
- Specify trigger fields: For "On Update", list specific fields to avoid unnecessary triggers
- Test thoroughly: Use test records to verify automation works
- Keep it simple: Complex logic is better in custom code
- Document rules: Use Description field to explain purpose
- Monitor performance: Too many automation rules can slow saves
Knowledge Check
Q1: Which action type for "10% price increase on selected products"?
Answer: Server Action (Update Record)
Server Actions work on selected records from the Actions menu. Use the incremental mass edit feature (*=1.10) for the actual update.
Q2: Which action type for "Send daily sales report at 9 AM"?
Answer: Scheduled Action
Scheduled Actions run at specified intervals. Set to run daily at 9 AM with a Server Action that generates and emails the report.
Q3: Which action type for "When lead is won, create project"?
Answer: Automated Action
Automated Actions respond to events. Use "Stage is set to" trigger with the "Won" stage, then Create Record action.
Q4: How to detect state change from draft to confirmed?
Answer: Before Update Filter + After Update Filter
Set Before: [('state','=','draft')] and After: [('state','=','sale')] to catch that specific transition.
Q5: Why might an automated action cause performance issues?
Answer: It runs on every matching record change
Unlike scheduled actions (periodic) or server actions (manual), automated actions fire on every save. Too many or complex ones slow down all saves.