Query Odoo data including salesperson performance, customer analytics, orders, invoices, CRM, accounting, VAT, inventory, and AR/AP. Generates WhatsApp cards, PDFs, Excel. Use when user explicitly mentions Odoo or asks for Odoo data.
Read-only, Evidence-First, Ledger-Based Reports
| Model | What It Contains | Use For |
|---|---|---|
res.users | Users/Salespeople | Find salesperson by name, get user_id |
sale.order | Sales Orders | Revenue by salesperson, order counts, status |
account.move | Invoices/Journal Entries | Invoice tracking, payments, P&L data |
res.partner | Contacts/Customers | Customer info, top customers by revenue |
product.product | Products | Product sales, inventory |
account.account | Chart of Accounts |
| Financial reporting, balance sheet |
account.move.line | Journal Lines | Detailed ledger entries |
This skill requires Odoo connection credentials stored in assets/autonomous-cfo/.env:
| Variable | Description | Secret |
|---|---|---|
ODOO_URL | Odoo instance URL (e.g., https://your-odoo.com) | No |
ODOO_DB | Odoo database name | No |
ODOO_USER | Odoo username/email | No |
ODOO_PASSWORD | Odoo password or API key | Yes |
Setup:
cd skills/odoo/assets/autonomous-cfo
cp .env.example .env
# Edit .env with your actual credentials
nano .env
Model invocation is DISABLED per skill.json policy. This skill handles sensitive financial data and external Odoo connections — it must be explicitly invoked by the user.
Data Handling: All queries are read-only. No data is modified or exfiltrated.
create, write, unlink, etc.) are blocked at the client levelassets/autonomous-cfo/output/.envThe skill requires a Python virtual environment with specific packages:
cd skills/odoo/assets/autonomous-cfo
./install.sh
Or manually:
cd skills/odoo/assets/autonomous-cfo
python3 -m venv venv
./venv/bin/pip install -r requirements.txt
Dependencies: requests, matplotlib, pillow, fpdf2, openpyxl
Uses the venv with fpdf2, matplotlib, pillow for proper PDF/chart generation:
./skills/odoo/assets/autonomous-cfo/venv/bin/python ./skills/odoo/assets/autonomous-cfo/src/tools/cfo_cli.py <command>
Or from the skill directory:
cd skills/odoo/assets/autonomous-cfo && ./venv/bin/python src/tools/cfo_cli.py <command>
Reports should be built from:
account.account - Chart of Accounts structure (code, name, type, internal_group)account.move.line - Journal entry lines (debit, credit, account_id, date)account.journal - Source journals (type: sale, purchase, cash, bank, general)asset_cash - Bank and cash accountsasset_receivable - Accounts receivableasset_current - Current assetsliability_payable - Accounts payableincome - Revenueexpense - Expensesequity - Standard equity accounts (share capital, retained earnings)equity_unaffected - Suspense account for undistributed profits/losses (e.g., 999999)CRITICAL for Balance Sheet:
Odoo's equity_unaffected is a SUSPENSE account. Do NOT use its ledger balance directly.
Correct Equity Calculation:
equity) - Use ledger balance (credit - debit)equity_unaffectedTotal Equity = Equity Proper + Retained Earnings + Current Year Earnings
Where Current Year Earnings = Σ(income credit-debit) - Σ(expense debit-credit)
Why this matters: Odoo computes Current Year Earnings in real-time on the Balance Sheet. Using only the equity_unaffected ledger balance will cause the balance sheet to NOT balance.
The skill automatically detects the company's accounting standard based on country/jurisdiction and formats reports accordingly.
Supported Standards:
| Standard | Jurisdiction | Notes |
|---|---|---|
| IFRS | International | Default for most countries |
| US GAAP | United States | SEC registrants |
| Ind-AS | India | Indian GAAP converged with IFRS |
| UK GAAP | United Kingdom | FRS 102 |
| SOCPA | Saudi Arabia | IFRS adopted |
| EU IFRS | European Union | IAS Regulation |
| CAS | China | Chinese Accounting Standards |
| JGAAP | Japan | Japanese GAAP |
| ASPE | Canada | Private enterprises |
| AASB | Australia | Australian standards |
Detection Logic:
res.companyOverride:
# Force a specific standard
reporter.generate(..., standard="US_GAAP")
# Salesperson performance - use direct RPC for flexibility
./venv/bin/python -c "
from src.visualizers.whatsapp_cards import WhatsAppCardGenerator
# Query sale.order by user_id, aggregate by month/status
# Generate cards with generate_kpi_card() and generate_comparison_card()
"
# Example RPC query for salesperson:
# - sale.order (user_id, amount_total, state, date_order)
# - account.move (invoice_user_id, amount_total, payment_state)
# - res.users (salesperson info)
# - res.partner (customer info)
# Financial Health - cash flow, liquidity, burn rate, runway
cfo_cli.py health --from YYYY-MM-DD --to YYYY-MM-DD --company-id ID
# Revenue Analytics - MoM trends, top customers
cfo_cli.py revenue --from YYYY-MM-DD --to YYYY-MM-DD --company-id ID
# AR/AP Aging - overdue buckets
cfo_cli.py aging --as-of YYYY-MM-DD --company-id ID
# Expense Breakdown - by vendor/category
cfo_cli.py expenses --from YYYY-MM-DD --to YYYY-MM-DD --company-id ID
# Executive Summary - one-page CFO snapshot
cfo_cli.py executive --from YYYY-MM-DD --to YYYY-MM-DD --company-id ID
For sales/CRM data not covered by pre-built commands, use direct RPC:
# Query sales orders by salesperson
orders = jsonrpc('sale.order', 'search_read',
[[('user_id', '=', SALESPERSON_ID)]],
{'fields': ['name', 'partner_id', 'amount_total', 'state', 'date_order']})
# Query invoices by salesperson
invoices = jsonrpc('account.move', 'search_read',
[[('invoice_user_id', '=', SALESPERSON_ID), ('move_type', '=', 'out_invoice')]],
{'fields': ['name', 'partner_id', 'amount_total', 'payment_state']})
# Find salesperson by name
users = jsonrpc('res.users', 'search_read',
[[('name', 'ilike', 'name_here')]],
{'fields': ['id', 'name', 'login']})
# Custom comparison
cfo_cli.py adhoc --from YYYY-MM-DD --to YYYY-MM-DD --metric-a "revenue" --metric-b "expenses"
# Examples:
cfo_cli.py adhoc --metric-a "cash in" --metric-b "cash out"
cfo_cli.py adhoc --metric-a "direct expenses" --metric-b "indirect expenses"
--output whatsapp # Dark theme 1080x1080 PNG cards
--output pdf # Light theme A4 PDF
--output excel # Excel workbook (.xlsx)
--output both # PDF + WhatsApp cards
--output all # PDF + Excel + WhatsApp cards
Reports always include appropriate visualizations by default:
| Report | Auto-Included Charts |
|---|---|
| Financial Health | Cash position, burn rate trend, runway |
| Revenue | MoM trend, top customers, growth KPI |
| AR/AP Aging | Aging buckets pie, overdue highlights |
| Expenses | Category breakdown, trend, top vendors |
| Executive | All KPI cards, summary charts |
| Balance Sheet | Asset/liability composition |
| P&L | Revenue vs expense, margin trend |
| Cash Flow | Operating breakdown, cash trend |
Rule: If visualization makes the report clearer, include it automatically. Never ask "do you want charts?" — just add them.
If required params are missing, the skill will ask:
Just ask naturally:
Sales & CRM:
Financial Reports:
General Queries:
The skill will:
python3 ./skills/odoo/assets/autonomous-cfo/src/tools/cfo_cli.py doctor