Custom Workflows Guide
Transform your most frequent Odoo operations into instant slash commands. Execute complex queries, calculations, and reports with a single command and get results in milliseconds.
Instant execution with smart caching
Up to 3x faster with auto-parallelization
MCP, compute, filter, sort, group
Beautiful results via your LLM
01.What are Custom Workflows?
Custom workflows are reusable automation scripts that you execute with slash commands like /weekly-sales or /inventory-check. Instead of typing the same complex query every time, you create a workflow once and run it instantly whenever needed.
Benefits of Automation
- Speed: Execute instantly without LLM processing - get results in milliseconds
- Consistency: Same query structure every time - eliminate human error
- Reusability: Create once, use forever - share with team members
- Efficiency: Parallel execution for complex multi-step operations
Common Use Cases
Sales & Revenue
- Weekly/monthly sales reports
- Top customers by revenue
- Sales pipeline analysis
- Revenue forecasting
Inventory & Stock
- Low stock alerts
- Stock valuation reports
- Product movement analysis
- Warehouse capacity checks
Finance & Accounting
- Pending invoice summaries
- Payment status tracking
- Overdue accounts report
- Cash flow projections
Team & HR
- Employee performance metrics
- Attendance summaries
- Leave balance reports
- Team productivity analysis
02.Creating Your First Workflow
You can create workflows in two ways: from a chat conversation (recommended for beginners) or manually via API (for advanced users).
Method 1: Create from Chat (Recommended)
Why this method?
The AI automatically analyzes your conversation, extracts the query logic, generates optimized workflow steps, and handles all technical details. Perfect for users who want automation without writing code.
Start a conversation about a repetitive task
Ask the AI to perform a task you need regularly. Be specific about what data you want and how it should be filtered or sorted.
Example: "Show me all sales orders from this week with their totals, sorted by amount, and tell me which customers ordered the most."
Review the AI's response
The AI executes your query and shows you the results. Verify that this is exactly what you want to automate.
Click "Create Workflow"
After the AI completes your query, you'll see a "Create Workflow" button in the chat interface. Click it to start the workflow creation process.
Review auto-generated workflow
The system analyzes your conversation and automatically generates workflow steps, including:
- MCP calls to query Odoo data
- Calculations and data transformations
- Filtering and sorting operations
- Context variables for dynamic dates
Name and save your workflow
Give your workflow a slash command name (e.g., /weekly-sales) and save it.
Tip: Use descriptive names that match the workflow's purpose. Examples: /top-customers, /low-stock, /pending-invoices
Test immediately
Type your new slash command in the chat to test it. Results appear instantly!
/weekly-salesMethod 2: Manual Creation (Advanced)
For advanced users who want full control over workflow structure, you can create workflows manually by calling the workflows API:
POST /api/workflows
Content-Type: application/json
{
"trigger_command": "/my-custom-report",
"display_name": "My Custom Sales Report",
"description": "Weekly sales with top customers",
"category": "sales",
"workflow_steps": {
"version": "1.0",
"steps": [
{
"type": "mcp_call",
"description": "Get sales orders from this week",
"tool": "execute_method",
"params": {
"model": "sale.order",
"method": "search_read",
"args": [[["state", "=", "sale"], ["date_order", ">=", "{{week_start}}"]]],
"kwargs": {
"fields": ["name", "partner_id", "amount_total", "date_order"],
"order": "amount_total DESC",
"limit": 50
}
},
"store_as": "orders"
},
{
"type": "compute",
"description": "Calculate total revenue",
"expression": "{{orders}}.reduce((sum, o) => sum + o.amount_total, 0)",
"store_as": "total_revenue"
},
{
"type": "group_by",
"description": "Group by customer",
"source": "{{orders}}",
"key": "partner_id",
"aggregate": {
"total": "sum(amount_total)",
"count": "count(id)"
},
"store_as": "by_customer"
}
]
},
"required_params": [],
"is_public": false
}03.Workflow Examples
Real-world workflow examples you can adapt for your needs. Each example includes the complete workflow structure and usage instructions.
/weekly-sales
Get weekly sales report with totals and top customers
What it does:
- Fetches all confirmed sales orders from the current week
- Calculates total revenue for the week
- Groups sales by customer to identify top buyers
- Returns beautifully formatted results via AI
Usage:
/weekly-salesView workflow structure
{
"version": "1.0",
"steps": [
{
"type": "mcp_call",
"description": "Get confirmed sales orders from this week",
"tool": "execute_method",
"params": {
"model": "sale.order",
"method": "search_read",
"args": [[
["state", "=", "sale"],
["date_order", ">=", "{{week_start}}"]
]],
"kwargs": {
"fields": ["name", "partner_id", "amount_total"],
"order": "amount_total DESC"
}
},
"store_as": "orders"
},
{
"type": "compute",
"description": "Calculate total weekly revenue",
"expression": "{{orders}}.reduce((sum, o) => sum + o.amount_total, 0)",
"store_as": "total_revenue"
},
{
"type": "group_by",
"description": "Group by customer",
"source": "{{orders}}",
"key": "partner_id",
"aggregate": {
"revenue": "sum(amount_total)",
"orders": "count(id)"
},
"store_as": "by_customer"
}
]
}/inventory-check
Check products with low stock levels requiring reorder
What it does:
- Queries all products with stock below minimum threshold
- Filters out inactive products
- Sorts by urgency (lowest stock first)
- Returns product names, current stock, and minimum levels
Usage:
/inventory-checkView workflow structure
{
"version": "1.0",
"steps": [
{
"type": "mcp_call",
"description": "Get products with low stock",
"tool": "execute_method",
"params": {
"model": "product.product",
"method": "search_read",
"args": [[
["active", "=", true],
["qty_available", "<", 10]
]],
"kwargs": {
"fields": ["name", "qty_available", "default_code"],
"order": "qty_available ASC",
"limit": 50
}
},
"store_as": "low_stock_products"
},
{
"type": "filter",
"description": "Only show critical items (stock < 5)",
"source": "{{low_stock_products}}",
"condition": "item.qty_available < 5",
"store_as": "critical_items"
}
]
}/customer-analysis
Analyze customer purchase trends and identify VIP customers
What it does:
- Fetches all sales orders from the last 3 months
- Groups by customer to calculate total spend
- Sorts by revenue to identify top customers
- Filters to show only VIP customers (over $10,000)
Usage:
/customer-analysis/invoice-status
Check pending and overdue invoices requiring attention
What it does:
- Queries all unpaid customer invoices
- Filters to show overdue invoices (past due date)
- Calculates total outstanding amount
- Sorts by due date (oldest first)
Usage:
/invoice-status/team-performance
Analyze sales team performance metrics for the month
What it does:
- Fetches all sales orders from current month
- Groups by salesperson to calculate individual totals
- Sorts by revenue to identify top performers
- Calculates average deal size per salesperson
Usage:
/team-performance04.Workflow Step Types
Workflows support five powerful step types that you can chain together to create sophisticated automation scripts. Each step type serves a specific purpose in data processing.
mcp_call
Execute Odoo operations via MCP (Model Context Protocol). This is your primary interface to query and manipulate Odoo data.
Parameters:
| Parameter | Type | Description |
|---|---|---|
| tool | string | Always "execute_method" |
| params | object | Contains model, method, args, kwargs |
| store_as | string | Variable name to store results |
Example:
{
"type": "mcp_call",
"description": "Get sales orders from this week",
"tool": "execute_method",
"params": {
"model": "sale.order",
"method": "search_read",
"args": [[["date_order", ">=", "{{week_start}}"]]],
"kwargs": {
"fields": ["name", "partner_id", "amount_total"],
"order": "amount_total DESC",
"limit": 20
}
},
"store_as": "orders"
}compute
Evaluate JavaScript expressions using workflow variables. Perfect for calculations, transformations, and data manipulation.
Security Note
Compute steps are NOT allowed in public workflows for security reasons. Only private workflows can use JavaScript evaluation.
Common operations:
reduce()- Sum values, calculate totalsmap()- Transform array elementsMath.*- Mathematical operationsDate.*- Date calculations
Examples:
Calculate total revenue:
{
"type": "compute",
"expression": "{{orders}}.reduce((sum, o) => sum + o.amount_total, 0)",
"store_as": "total_revenue"
}Calculate average order value:
{
"type": "compute",
"expression": "{{total_revenue}} / {{orders}}.length",
"store_as": "avg_order_value"
}filter
Filter array items based on a JavaScript condition. Reduce datasets to only the records that match your criteria.
Security Note
Filter steps are NOT allowed in public workflows. Use Odoo domain filters in mcp_call instead.
Examples:
Filter orders over $1000:
{
"type": "filter",
"source": "{{orders}}",
"condition": "item.amount_total > 1000",
"store_as": "large_orders"
}Filter products with critical stock:
{
"type": "filter",
"source": "{{products}}",
"condition": "item.qty_available < 5",
"store_as": "critical_stock"
}sort
Sort array items by field value in ascending or descending order. Optionally limit the number of results.
Examples:
Get top 10 customers by revenue:
{
"type": "sort",
"source": "{{orders}}",
"by": "amount_total",
"order": "DESC",
"limit": 10,
"store_as": "top_orders"
}Sort by date (oldest first):
{
"type": "sort",
"source": "{{invoices}}",
"by": "invoice_date",
"order": "ASC",
"store_as": "sorted_invoices"
}group_by
Group array items by field value and perform aggregations (sum, count, avg, min, max). Essential for analytics and reporting.
Supported aggregations:
sum(field)Calculate total
count(field)Count items
avg(field)Calculate average
min(field)Find minimum
max(field)Find maximum
Example:
Sales by customer with multiple aggregations:
{
"type": "group_by",
"source": "{{orders}}",
"key": "partner_id",
"aggregate": {
"total_revenue": "sum(amount_total)",
"order_count": "count(id)",
"avg_order": "avg(amount_total)",
"largest_order": "max(amount_total)"
},
"store_as": "customer_analytics"
}05.Advanced Workflow Features
Automatic Parallel Execution
Up to 3x Faster Execution
The workflow engine automatically analyzes step dependencies and executes independent steps in parallel for maximum performance. No configuration needed - it just works!
How it works:
- Builds dependency graph from variable references (e.g.,
{{orders}}) - Identifies steps that don't depend on each other
- Executes independent steps simultaneously
- Waits for dependencies before executing dependent steps
Smart Caching System
Workflow results are cached per-user for instant retrieval. Cache is automatically invalidated after 1 hour or when data changes.
Cache Benefits:
- Instant Results: Cached workflows return in milliseconds
- Reduced Load: Fewer database queries = better Odoo performance
- Per-User Isolation: Your cache is private - no cross-user data leakage
- Smart Invalidation: Cache automatically expires after 1 hour
Cache Key Format:
wf:{userId}:{workflowId}:{argsHash}Context Variables & Arguments
Make workflows dynamic with built-in context variables and user-provided arguments. Perfect for date-based queries and parameterized reports.
| Variable | Description | Example Value |
|---|---|---|
| {{today}} | Current date (ISO format) | 2025-01-21 |
| {{week_start}} | Monday of current week | 2025-01-20 |
| {{month_start}} | First day of current month | 2025-01-01 |
| {{user_id}} | Current authenticated user ID | uuid-string |
| {{args}} | User-provided arguments array | ["2025-01"] |
Using Arguments in Workflows
Pass parameters to workflows by typing them after the slash command. Perfect for date ranges, IDs, or any dynamic values.
User types:
/sales-report 2025-01Workflow receives:
args = ["2025-01"]Use in workflow step:
{
"type": "mcp_call",
"params": {
"args": [[
["create_date", ">=", "{{args[0]}}-01"],
["create_date", "<", "{{args[0]}}-31"]
]]
}
}06.Best Practices
Do These Things
- ✓Use context variables like
{{today}}instead of hardcoded dates for dynamic queries - ✓Store intermediate results with descriptive variable names (
orders, notdata) - ✓Write clear step descriptions for debugging and maintenance
- ✓Test workflows with different argument values and edge cases
- ✓Use compute/filter steps to minimize MCP calls and reduce Odoo load
- ✓Leverage parallel execution by keeping steps independent when possible
Avoid These Mistakes
- ✗Hardcode dates that change - use
{{week_start}}instead of "2025-01-20" - ✗Make excessive MCP calls when one comprehensive query would suffice
- ✗Forget to test with edge cases, empty results, or invalid arguments
- ✗Use generic variable names like "data", "result", "temp" - be descriptive!
- ✗Skip step descriptions - they're essential for debugging later
- ✗Create circular dependencies that prevent parallel execution
Performance Optimization Tips
Minimize Odoo Queries
Fetch all needed data in one MCP call with comprehensive filters, then use compute/filter/sort steps to process it locally. One database query beats ten every time.
Use Field Limits
Only request the fields you need in kwargs.fields to reduce data transfer. Don't fetch 50 fields when you only need 5.
Set Record Limits
Add limit parameters to avoid fetching thousands of records when you only need the top 10. Your workflow (and Odoo) will thank you.
Design for Parallelization
Structure workflows so steps don't depend on each other unnecessarily. The optimizer automatically parallelizes independent steps for up to 3x speedup.
Next Steps
Manage Your Workflows
View, edit, and organize all your custom workflows from the dashboard.
Effective Prompts Guide
Learn how to write better queries to create more effective workflows.
Quick Start Guide
New to ood.ooo? Start here to connect Odoo and configure your AI assistant.
Troubleshooting
Encountering issues? Check our troubleshooting guide for solutions.