Odoo Financial Intelligence
Read-only, Evidence-First, Ledger-Based Reports
Quick Reference: Common Odoo Models
| Model | What It Contains | Use For |
|---|
| INLINECODE0 | Users/Salespeople | Find salesperson by name, get user_id |
| INLINECODE1 |
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 |
Security & Credentials
Security Model
This skill implements a defense-in-depth security model:
- 1. User Invocation Required: This skill CANNOT be invoked autonomously by AI models
- Read-Only Enforcement: All data modifications are blocked at the code level
- Credential Isolation: Credentials stored only in local
.env file, never transmitted elsewhere - Network Boundaries: Only connects to user-specified Odoo URL, no external telemetry
Required Environment Variables
This skill REQUIRES Odoo connection credentials stored in assets/autonomous-cfo/.env:
| Variable | Description | Secret | Required |
|---|
| INLINECODE9 | Odoo instance URL (e.g., https://your-odoo.com) | No | Yes |
| INLINECODE11 |
Odoo database name | No |
Yes |
|
ODOO_USER | Odoo username/email | No |
Yes |
|
ODOO_PASSWORD | Odoo API key (recommended) or password |
Yes |
Yes |
⚠️ CRITICAL: These credentials are REQUIRED. The skill will not function without them.
Setup:
CODEBLOCK0
API Key vs Password
For production, use an Odoo API key:
- 1. Log into Odoo → Settings → Account Security → API Keys
- Generate a new key (e.g., "Financial Reports Skill")
- Use this key as INLINECODE14
Why API keys?
- - Scoped permissions (can be read-only)
- Can be revoked independently
- Don't expose your main password
- Better audit trail in Odoo
Authentication Methods
XML-RPC (Legacy, default):
- - Password/API key sent in XML-RPC request body
- Supported by all Odoo versions
JSON-RPC (Odoo 19+):
- - API key sent as
Authorization: Bearer <api_key> header - More efficient for large datasets
- Use
ODOO_RPC_BACKEND=json2 to enable
Model Invocation Policy
🚫 Model invocation is STRICTLY DISABLED.
Per skill.json:
CODEBLOCK1
This means:
- - AI models CANNOT invoke this skill automatically
- User MUST explicitly request Odoo operations
- Every invocation requires user intent
Read-Only Enforcement
⚠️ IMPORTANT: Client-Side Enforcement Limitation
The skill implements client-side read-only enforcement. This means:
- - Mutating methods are blocked in the Python code
- Blocked methods raise
PermissionError if called - However, a modified or compromised client could bypass this
For Production Security:
- 1. Use a read-only Odoo user (recommended)
- Don't give modify permissions to the API key's user
- Review Odoo access logs regularly
Blocked Methods:
- -
create, write, unlink (CRUD operations) - INLINECODE22 (duplicate records)
- INLINECODE23 ,
action_confirm, button_validate (workflow actions)
Allowed Methods (Read-Only):
- -
search, search_read, read (data retrieval) - INLINECODE29 ,
fields_get (metadata) - INLINECODE31 ,
context_get, default_get (helpers)
Attempting to call blocked methods raises PermissionError.
Data Handling & Privacy
- - No Data Exfiltration: Reports generated locally in INLINECODE35
- No Telemetry: No usage data sent to external servers
- Network Isolation: Only connects to
ODOO_URL specified in INLINECODE37 - Credential Security: Password/API key never logged or displayed
- Local Processing: All chart generation, PDF creation happens locally
Output Security
All outputs are local files only:
- -
output/pdf_reports/ - PDF reports - INLINECODE39 - PNG image cards
- INLINECODE40 - Chart images
- INLINECODE41 - Excel spreadsheets
No cloud upload, no external sharing, no data leaves your machine except to your specified Odoo instance.
Installation
The skill requires a Python virtual environment with specific packages:
CODEBLOCK2
Or manually:
CODEBLOCK3
Dependencies: requests, matplotlib, pillow, fpdf2, INLINECODE46
Critical Rules
- 1. NEVER assume - Always ask clarifying questions before generating reports
- Multi-company check - If multiple companies exist, ASK which one to use
- Ledger-based - Use Chart of Accounts and journal entries (account.move.line), not just invoice summaries
- Verify periods - Confirm date ranges with user before running
- No silent defaults - Every assumption must be confirmed
Before Any Report, Ask:
- 1. "Which company should I use?" (if multiple exist)
- "What period? (from/to dates)"
- "Which accounts or account types to include?"
- "Any specific breakdown needed?" (by account, by partner, by journal, etc.)
- "Output format preference?" (PDF, WhatsApp cards, or both)
Entrypoint
Uses the venv with fpdf2, matplotlib, pillow for proper PDF/chart generation:
CODEBLOCK4
Or from the skill directory:
CODEBLOCK5
Chart of Accounts Based Reporting
Reports should be built from:
- -
account.account - Chart of Accounts structure (code, name, type, internalgroup) - INLINECODE48 - Journal entry lines (debit, credit, accountid, date)
- INLINECODE49 - Source journals (type: sale, purchase, cash, bank, general)
Account Internal Groups
- - ASSET - Assets (current, non-current, cash, receivables)
- LIABILITY - Liabilities (payables, taxes, accrued)
- EQUITY - Owner's equity
- INCOME - Revenue accounts
- EXPENSE - Cost and expense accounts
- OFF_BALANCE - Off-balance sheet accounts
Common Account Types
- -
asset_cash - Bank and cash accounts - INLINECODE51 - Accounts receivable
- INLINECODE52 - Current assets
- INLINECODE53 - Accounts payable
- INLINECODE54 - Revenue
- INLINECODE55 - Expenses
Special Equity Types (Odoo-Specific)
- -
equity - Standard equity accounts (share capital, retained earnings) - INLINECODE57 - 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:
- 1. Equity Proper (type:
equity) - Use ledger balance (credit - debit) - Retained Earnings (prior years) - Ledger balance from INLINECODE60
- Current Year Earnings - Compute real-time: Income - Expenses
CODEBLOCK6
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.
Automatic Reporting Standard Detection
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:
- 1. Query company's country from INLINECODE62
- Map country code to reporting standard
- Apply standard-specific formatting:
- Number format (1,234.56 vs 1.234,56)
- Negative display ((123) vs -123)
- Date format (DD/MM/YYYY vs MM/DD/YYYY)
- Statement titles (Balance Sheet vs Statement of Financial Position)
- Cash flow method (indirect vs direct)
Override:
CODEBLOCK7
Commands
Sales & CRM Queries
CODEBLOCK8
Pre-built Reports
CODEBLOCK9
Direct RPC Queries (Advanced)
For sales/CRM data not covered by pre-built commands, use direct RPC:
CODEBLOCK10
Ad-hoc Reports
CODEBLOCK11
Output Formats
CODEBLOCK12
Automatic Visualizations
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.
Interactive Param Collection
If required params are missing, the skill will ask:
- 1. Company: "Which company?" (list available options)
- Period: "What period? (e.g., 'last month', 'Q4 2024', custom dates)"
- Accounts: "Which accounts or groups?" (e.g., 'all income', 'bank accounts only')
- Breakdown: "Group by? (Month, Customer, Category, Account)"
- Output: "Output format? (WhatsApp cards, PDF, Both)"
How to Use in Chat
Just ask naturally:
Sales & CRM:
- - "How is [name] salesperson performance?"
- "Show me top customers for [salesperson]"
- "Compare sales team performance"
- "Which salesperson has the most orders?"
Financial Reports:
- - "Give me a financial health report for last quarter"
- "Show revenue vs expenses for the past 6 months"
- "What's my AR aging?"
- "Generate an executive summary for this month"
- "Show me profit & loss statement based on chart of accounts"
General Queries:
- - "How many orders did we get this month?"
- "Who are the top 10 customers?"
- "Show invoice status for [customer name]"
The skill will:
- 1. Check for multiple companies and ask which one
- Parse your request
- Ask for any missing info
- Fetch data from Odoo using ledger entries or direct RPC
- Generate charts + WhatsApp cards
- Deliver via WhatsApp cards and/or PDF
Hard Rules
- 1. Odoo RPC output is source of truth
- Strict read-only (no create/write/unlink)
- No proactive actions unless requested
- Every number includes methodology note
- Always verify with user before assuming
- Always include visualizations - If a report benefits from charts/graphs, include them automatically without asking. Reports should be visually complete.
Diagnostics
CODEBLOCK13
Report Themes
- - WhatsApp Cards: "Midnight Ledger" — Navy-black (#0a0e1a), copper glow (#cd7f32)
- PDF Reports: Clean white, copper accents, professional layout
Odoo 财务智能
只读、证据优先、基于分类账的报告
快速参考:常用 Odoo 模型
| 模型 | 包含内容 | 用途 |
|---|
| res.users | 用户/销售人员 | 按姓名查找销售人员,获取 user_id |
| sale.order |
销售订单 | 按销售人员统计收入、订单数量、状态 |
| account.move | 发票/日记账分录 | 发票追踪、付款、损益数据 |
| res.partner | 联系人/客户 | 客户信息、按收入排名前几的客户 |
| product.product | 产品 | 产品销售、库存 |
| account.account | 会计科目表 | 财务报告、资产负债表 |
| account.move.line | 日记账行项 | 详细的分类账条目 |
安全与凭证
安全模型
此技能实现了纵深防御安全模型:
- 1. 需要用户调用:AI 模型不能自主调用此技能
- 强制只读:所有数据修改在代码层面被阻止
- 凭证隔离:凭证仅存储在本地 .env 文件中,绝不传输到其他地方
- 网络边界:仅连接到用户指定的 Odoo URL,无外部遥测
必需的环境变量
此技能需要存储在 assets/autonomous-cfo/.env 中的 Odoo 连接凭证:
| 变量 | 描述 | 秘密 | 必需 |
|---|
| ODOOURL | Odoo 实例 URL(例如 https://your-odoo.com) | 否 | 是 |
| ODOODB |
Odoo 数据库名称 | 否 |
是 |
| ODOO_USER | Odoo 用户名/邮箱 | 否 |
是 |
| ODOO_PASSWORD | Odoo API 密钥(推荐)或密码 |
是 |
是 |
⚠️ 关键:这些凭证是必需的。没有它们,技能将无法运行。
设置:
bash
cd skills/odoo/assets/autonomous-cfo
cp .env.example .env
用您的实际凭证编辑 .env
nano .env
API 密钥与密码
对于生产环境,请使用 Odoo API 密钥:
- 1. 登录 Odoo → 设置 → 账户安全 → API 密钥
- 生成一个新密钥(例如财务报告技能)
- 将此密钥用作 ODOO_PASSWORD
为什么使用 API 密钥?
- - 作用域权限(可以是只读的)
- 可以独立撤销
- 不暴露您的主密码
- 在 Odoo 中有更好的审计追踪
认证方法
XML-RPC(传统,默认):
- - 密码/API 密钥在 XML-RPC 请求体中发送
- 所有 Odoo 版本均支持
JSON-RPC(Odoo 19+):
- - API 密钥作为 Authorization: Bearer key> 标头发送
- 对大数据集更高效
- 使用 ODOORPC_BACKEND=json2 启用
模型调用策略
🚫 严格禁止模型调用。
根据 skill.json:
json
modelInvocation: {
disabled: true,
requiresUserInvocation: true
}
这意味着:
- - AI 模型不能自动调用此技能
- 用户必须明确请求 Odoo 操作
- 每次调用都需要用户意图
只读强制
⚠️ 重要:客户端强制限制
该技能实现了客户端只读强制。这意味着:
- - 变异方法在 Python 代码中被阻止
- 如果调用被阻止的方法,会引发 PermissionError
- 但是,修改过或受损的客户端可以绕过此限制
对于生产环境安全:
- 1. 使用只读 Odoo 用户(推荐)
- 不要给 API 密钥的用户修改权限
- 定期审查 Odoo 访问日志
被阻止的方法:
- - create、write、unlink(CRUD 操作)
- copy(复制记录)
- actionpost、actionconfirm、button_validate(工作流操作)
允许的方法(只读):
- - search、searchread、read(数据检索)
- searchcount、fieldsget(元数据)
- namesearch、contextget、defaultget(辅助方法)
尝试调用被阻止的方法会引发 PermissionError。
数据处理与隐私
- - 无数据泄露: 报告在 assets/autonomous-cfo/output/ 本地生成
- 无遥测: 不会向外部服务器发送使用数据
- 网络隔离: 仅连接到 .env 中指定的 ODOO_URL
- 凭证安全: 密码/API 密钥从不记录或显示
- 本地处理: 所有图表生成、PDF 创建均在本地进行
输出安全
所有输出均为本地文件:
- - output/pdfreports/ - PDF 报告
- output/whatsappcards/ - PNG 图片卡片
- output/charts/ - 图表图片
- output/excel/ - Excel 电子表格
无云上传,无外部共享,除您指定的 Odoo 实例外,数据不会离开您的机器。
安装
该技能需要具有特定包的 Python 虚拟环境:
bash
cd skills/odoo/assets/autonomous-cfo
./install.sh
或手动安装:
bash
cd skills/odoo/assets/autonomous-cfo
python3 -m venv venv
./venv/bin/pip install -r requirements.txt
依赖项: requests、matplotlib、pillow、fpdf2、openpyxl
关键规则
- 1. 绝不假设 - 在生成报告前始终提出澄清性问题
- 多公司检查 - 如果存在多家公司,询问使用哪一家
- 基于分类账 - 使用会计科目表和日记账分录(account.move.line),而不仅仅是发票摘要
- 验证期间 - 运行前与用户确认日期范围
- 无静默默认值 - 每个假设都必须得到确认
在任何报告之前,请询问:
- 1. 我应该使用哪家公司?(如果存在多家)
- 什么期间?(起始/结束日期)
- 包含哪些账户或账户类型?
- 需要任何特定的细分吗?(按账户、按合作伙伴、按日记账等)
- 输出格式偏好?(PDF、WhatsApp 卡片,或两者兼有)
入口点
使用带有 fpdf2、matplotlib、pillow 的虚拟环境进行正确的 PDF/图表生成:
bash
./skills/odoo/assets/autonomous-cfo/venv/bin/python ./skills/odoo/assets/autonomous-cfo/src/tools/cfo_cli.py
或从技能目录:
bash
cd skills/odoo/assets/autonomous-cfo && ./venv/bin/python src/tools/cfo_cli.py
基于会计科目表的报告
报告应基于以下内容构建:
- - account.account - 会计科目表结构(代码、名称、类型、内部组)
- account.move.line - 日记账分录行(借方、贷方、账户 ID、日期)
- account.journal - 来源日记账(类型:销售、采购、现金、银行、总账)
账户内部组
- - ASSET - 资产(流动资产、非流动资产、现金、应收账款)
- LIABILITY - 负债(应付账款、税款、应计费用)
- EQUITY - 所有者权益
- INCOME - 收入账户
- EXPENSE - 成本和费用账户
- OFF_BALANCE - 表外账户
常见账户类型
- - assetcash - 银行和现金账户
- assetreceivable - 应收账款
- assetcurrent - 流动资产
- liabilitypayable - 应付账款
- income - 收入
- expense - 费用
特殊权益类型(Odoo 特有)
- - equity - 标准权益账户(股本、留存收益)
- equity_unaffected - 未分配利润/亏损的暂记账户(例如 999999)
资产负债表的关键:
Odoo 的 equity_unaffected 是一个暂记账户。不要直接使用其分类账余额。
正确的权益计算:
- 1. 权益本身(类型:equity)- 使用分类账余额(贷方 - 借方)
- 留存收益(以前年度)- 来自