Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Full-featured Odoo 19 ERP connector for OpenClaw - Sales, CRM, Purchase, Inventory, Projects, HR, Fleet, Manufacturing (80+ operations, complete Python code included, XML-RPC integration).
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 762% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 188% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 646% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 154% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 285% | 0% |
Full-featured Odoo 19 ERP integration for OpenClaw. Control your entire business via natural language chat commands.
📦 Full Source Code: https://github.com/NullNaveen/openclaw-odoo-skill
\ash npx clawhub install odoo-erp-connector \
The Odoo ERP Connector bridges OpenClaw and Odoo 19, enabling autonomous, chat-driven control over 153+ business modules including:
All operations use smart actions that handle fuzzy matching and auto-creation workflows.
The connector handles fuzzy/incomplete requests with intelligent find-or-create logic.
Example: "Create quotation for Rocky with product Rock"
The system:
ilike matching)This pattern applies across all smart actions:
smart_create_quotation() — customer + productssmart_create_purchase() — vendor + productssmart_create_lead() — partner (optional)smart_create_task() — project + tasksmart_create_employee() — departmentsmart_create_event() — event only (no dependencies)OdooClient — Low-level XML-RPC wrapper
search(), read(), create(), write(), unlink() methodsModel Ops Classes — Business logic for each module
PartnerOps — Customers/suppliersSaleOrderOps — Quotations and sales ordersInvoiceOps — Customer invoicesInventoryOps — Products and stockCRMOps — Leads and opportunitiesPurchaseOrderOps — POs and vendorsProjectOps — Projects and tasksHROps — Employees, departments, expensesManufacturingOps — BOMs and MOsCalendarOps — Events and meetingsFleetOps — Vehicles and odometerEcommerceOps — Website orders and productsSmartActionHandler — High-level natural-language interface
The connector auto-detects required vs. optional fields in Odoo 19:
OdooError with field namejson{ "url": "http://localhost:8069", "db": "your_database", "username": "api_user@yourcompany.com", "api_key": "your_api_key_from_odoo_preferences", "timeout": 60, "max_retries": 3, "poll_interval": 60, "log_level": "INFO", "webhook_port": 8070, "webhook_secret": "" }
config.jsonAlternatively, set in .env:
ODOO_URL=http://localhost:8069
ODOO_DB=your_database
ODOO_USERNAME=api_user@yourcompany.com
ODOO_API_KEY=your_api_keyThe client auto-loads from .env if config.json is missing.
pythonfrom odoo_skill import OdooClient, SmartActionHandler # Load config from config.json client = OdooClient.from_config("config.json") # Test connection status = client.test_connection() print(f"Connected to Odoo {status['server_version']}") # Use smart actions for natural workflows smart = SmartActionHandler(client) # Create a quotation with fuzzy partner and product matching result = smart.smart_create_quotation( customer_name="Rocky", product_lines=[ {"name": "Rock", "quantity": 5, "price_unit": 19.99} ], notes="Fuzzy match quotation" ) print(result["summary"]) # Output: "Created quotation QT-001 for new customer Rocky with 1 × Rock at $19.99"
python# Find-or-create a customer result = smart.find_or_create_partner( name="Acme Corp", is_company=True, city="New York" ) partner = result["partner"] created = result["created"] # Find-or-create a product result = smart.find_or_create_product( name="Widget X", list_price=49.99, type="consu" ) product = result["product"] # Smart quotation (auto-creates customer & products) result = smart.smart_create_quotation( customer_name="Rocky", product_lines=[ {"name": "Product A", "quantity": 10}, {"name": "Product B", "quantity": 5, "price_unit": 25.0} ], notes="Created via smart action" ) order = result["order"] print(f"Order {order['name']} created with {len(result['products'])} product(s)") # Smart lead creation result = smart.smart_create_lead( name="New Prospect", contact_name="John Doe", email="john@prospect.com", expected_revenue=50000.0 ) lead = result["lead"] # Smart task creation (auto-creates project if needed) result = smart.smart_create_task( project_name="Website Redesign", task_name="Fix homepage", description="Update hero section" ) task = result["task"] # Smart employee creation (auto-creates department if needed) result = smart.smart_create_employee( name="Jane Smith", job_title="Developer", department_name="Engineering" ) employee = result["employee"]
pythonfrom odoo_skill.models.sale_order import SaleOrderOps from odoo_skill.models.partner import PartnerOps partners = PartnerOps(client) sales = SaleOrderOps(client) # Get all customers customers = partners.search_customers(limit=10) for cust in customers: print(f"{cust['name']} — {cust.get('email')}") # Create a quotation with specific IDs order = sales.create_quotation( partner_id=42, lines=[ {"product_id": 7, "quantity": 10, "price_unit": 49.99}, {"product_id": 8, "quantity": 5} ], notes="Manual order" ) print(f"Created {order['name']}") # Confirm the order confirmed = sales.confirm_order(order['id']) print(f"Order {confirmed['name']} is now {confirmed['state']}")
All API methods return structured dictionaries:
python{ "summary": "Created quotation QT-001 for new customer Rocky with 1 × Rock", "order": { "id": 1, "name": "QT-001", "state": "draft", "partner_id": [42, "Rocky"], "amount_total": 19.99 }, "customer": { "created": True, "partner": {"id": 42, "name": "Rocky"} }, "products": [ { "created": True, "product": {"id": 7, "name": "Rock"} } ] }
python{ "id": 1, "name": "QT-001", "state": "draft", "partner_id": [42, "Rocky"], "amount_total": 19.99, "order_line": [ { "id": 1, "product_id": [7, "Rock"], "quantity": 1, "price_unit": 19.99, "price_subtotal": 19.99 } ] }
The connector uses custom exceptions:
pythonfrom odoo_skill.errors import OdooError, OdooAuthError, OdooNotFoundError try: result = smart.smart_create_quotation( customer_name="Acme", product_lines=[{"name": "Widget"}] ) except OdooAuthError as e: print(f"Authentication failed: {e}") except OdooNotFoundError as e: print(f"Record not found: {e}") except OdooError as e: print(f"Odoo error: {e}")
The connector supports 153+ installed modules in Odoo 19:
Core
Sales & CRM
Purchasing
Inventory
Accounting
HR
Projects
Manufacturing
Fleet
Marketing
eCommerce
Tools
Plus 50+ more specialized modules
url, db, username, api_key in config.jsonhttp://your-odoo-url/webproduct_tmpl_id, not product_id)name fieldid directlydate_from, date_toUser: "Create a quote for Acme Corp with 10 Widgets at $50 each"
OpenClaw → OdooClient (smart action):
1. Search for customer "Acme Corp"
2. Search for product "Widgets"
3. Create quotation with both
4. Return summary
Result: "✅ Created quotation QT-001 for Acme Corp with 10 × Widgets at $50"User: "Show me the sales pipeline"
OpenClaw → CRMOps.get_pipeline():
- Query all leads/opportunities
- Group by stage
- Calculate total revenue by stage
- Return formatted summary
Result: "Qualified: $50k | Proposal: $100k | Negotiation: $75k | Total: $225k"User: "What products are low on stock?"
OpenClaw → InventoryOps.get_low_stock_products():
- Query products with stock < reorder point
- List each product, stock level, reorder point
- Suggest PO quantities
Result: "Widget X: 5 on hand (min 20) | Component Y: 0 on hand (min 10)"OdooConnector/
├── odoo_skill/
│ ├── client.py # Core OdooClient
│ ├── config.py # Configuration loader
│ ├── errors.py # Custom exceptions
│ ├── retry.py # Retry logic
│ ├── smart_actions.py # Smart action handler
│ ├── models/
│ │ ├── partner.py
│ │ ├── sale_order.py
│ │ ├── invoice.py
│ │ ├── inventory.py
│ │ ├── crm.py
│ │ ├── purchase.py
│ │ ├── project.py
│ │ ├── hr.py
│ │ ├── manufacturing.py
│ │ ├── calendar_ops.py
│ │ ├── fleet.py
│ │ ├── ecommerce.py
│ ├── utils/
│ │ ├── formatting.py # Response formatting
│ │ ├── validators.py # Input validation
│ ├── sync/
│ │ ├── poller.py # Webhook poller
│ │ ├── webhook.py # Webhook handler
├── run_full_test.py # Integration test suite
├── config.json # Configuration (create from template)
├── config.template.json # Configuration template
├── requirements.txt # Python dependencies
├── README.md # User setup guide
├── SKILL.md # This file
└── setup.ps1 # PowerShell installerbash# Run full integration test suite python run_full_test.py # Run single test module python -m pytest tests/test_partners.py -v # Run with coverage python -m pytest --cov=odoo_skill tests/
SmartActionHandler classfind_or_create_* primitives for dependenciessummary, the main record, and creation detailsrun_full_test.pyExample:
pythondef smart_create_invoice(self, customer_name: str, product_lines: list[dict], **kwargs) -> dict: """Create invoice with fuzzy customer and product matching.""" # Find or create customer customer_result = self.find_or_create_partner(customer_name) customer = customer_result["partner"] # Find or create products products = [] for line in product_lines: prod_result = self.find_or_create_product(line["name"], **line) products.append(prod_result) # Create invoice with resolved IDs invoice = self.invoices.create_invoice( partner_id=customer["id"], lines=[...], **kwargs ) return { "summary": f"Created invoice INV-001 for {customer['name']}", "invoice": invoice, "customer": customer_result, "products": products }
This connector is part of the OpenClaw project. For issues, questions, or contributions, contact the development team.
Last Updated: 2026-02-09 Odoo Version: 19.0 Python: 3.10+ Status: Production Ready
Other measured skills in the registry, with their headline benchmark lift.