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.

Sub-Second

Instant execution with smart caching

Parallel

Up to 3x faster with auto-parallelization

5 Step Types

MCP, compute, filter, sort, group

AI Formatted

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.

1

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

2

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.

3

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.

4

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
5

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

6

Test immediately

Type your new slash command in the chat to test it. Results appear instantly!

/weekly-sales

Method 2: Manual Creation (Advanced)

For advanced users who want full control over workflow structure, you can create workflows manually by calling the workflows API:

API EndpointPOST
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

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-sales
View 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

Inventory

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-check
View 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

CRM

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

Finance

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

HR

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-performance

04.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:

ParameterTypeDescription
toolstringAlways "execute_method"
paramsobjectContains model, method, args, kwargs
store_asstringVariable 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 totals
  • map() - Transform array elements
  • Math.* - Mathematical operations
  • Date.* - 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:

  1. Builds dependency graph from variable references (e.g., {{orders}})
  2. Identifies steps that don't depend on each other
  3. Executes independent steps simultaneously
  4. 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.

VariableDescriptionExample Value
{{today}}Current date (ISO format)2025-01-21
{{week_start}}Monday of current week2025-01-20
{{month_start}}First day of current month2025-01-01
{{user_id}}Current authenticated user IDuuid-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-01

Workflow 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, not data)
  • 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.

07.Sharing Workflows

Share your workflows with team members to boost productivity across your organization. Public workflows enable standardized reporting and consistent data access.

Public Workflows

  • Visible to all team members
  • Great for standardized reports
  • Limited to safe step types only
  • Cannot use compute or filter steps

Security: Public workflows cannot execute arbitrary JavaScript for safety

Private Workflows

  • Only visible to you
  • Perfect for personal queries
  • Can use all step types
  • Full JavaScript computation power

Recommended: Start with private workflows, make public after testing

Export & Import

Currently, workflows are stored in your account. Future updates will add export/import capabilities for:

Export to JSON

Download workflow definitions for backup or sharing

Import from JSON

Load workflows from files or templates

Next Steps