Este artículo actualmente está disponible solo en inglés. La traducción estará disponible próximamente.
By the end of this recipe, your Odoo 19 instance will produce an auditor-grade cash flow statement using the indirect method, automatically computed from your existing journal entries with no manual reclassification. Skill required: accounting administrator with Odoo familiarity. Time required: 90 minutes setup + 30 minutes month-end review. ECOSIRE has built this for clients across SaaS, manufacturing, and services — and the recipe below distills the configuration that survives audit by Big-Four firms.
The reason most Odoo cash flow reports are wrong: they default to the direct method (cash in/out per account) which is technically correct but uninformative. The indirect method (start from net income, adjust for non-cash items, layer in working-capital changes) is what every CFO and auditor expects, and it requires tagging accounts in Odoo so the report engine knows what to add back.
What you will need
- Odoo version: 17, 18, or 19. The Financial Reports engine (formerly
account_reportsEnterprise module) covers all three. - Modules:
account_accountant(Enterprise) oraccount_financial_report(OCA Community). - Existing data: at least one fully closed fiscal year with a complete chart of accounts.
- User access: Accounting Manager.
- Time: 90 minutes.
Step-by-step
1. Enable the Financial Reports engine
Go to Apps > search "Accounting Reports" > install. This adds the menu Accounting > Reporting > Statement Reports.
Verification: Cash Flow Statement appears in the Statement Reports menu.
2. Tag accounts with cash flow categories
Open Accounting > Configuration > Chart of Accounts. For each account, set the Account Type and add the appropriate Cash Flow tag:
| Account Type | Default Cash Flow Section |
|---|---|
| Bank and Cash | Cash equivalents |
| Receivable | Operating - Working Capital |
| Payable | Operating - Working Capital |
| Current Assets | Operating - Working Capital |
| Current Liabilities | Operating - Working Capital |
| Fixed Assets | Investing |
| Non-current Liabilities | Financing |
| Equity | Financing |
| Income/Expense | Operating - Net Income |
For depreciation expense and amortization specifically, tag them as "Add back: depreciation". Bulk-tag via SQL on a copy of production:
-- Tag all depreciation accounts
UPDATE account_account
SET tag_ids = array_append(tag_ids, (SELECT id FROM account_account_tag WHERE name='Cash Flow: D&A'))
WHERE code LIKE '6810%' OR code LIKE '6820%';
Verification: open any account form; the Cash Flow tags are visible.
3. Configure the Cash Flow report (indirect method)
Go to Accounting > Reporting > Statement Reports > Cash Flow Statement. By default Odoo Enterprise ships an indirect-method template. Click "Edit Report Lines" if you need to customize. The structure should be:
1. Net Income (from P&L closing balance)
2. + Depreciation & Amortization (add back)
3. + Stock-based Compensation (add back)
4. + Other non-cash items
5. + Change in AR (- if AR increased)
6. + Change in Inventory (- if Inventory increased)
7. + Change in AP (+ if AP increased)
8. + Change in Other Working Capital
= Cash from Operations
9. - Capex
10. + Asset Sales
= Cash from Investing
11. + Loan Drawdowns
12. - Loan Repayments
13. + Equity Issuance
14. - Dividends
= Cash from Financing
= Net Change in Cash
+ Beginning Cash
= Ending Cash
Verification: run the report for the most recent closed month. Ending Cash should equal the bank balance per the trial balance.
4. Reconcile against bank statements
The acid test: ending cash from the report must equal sum of bank balances. If not, you have an untagged account or a misclassified entry.
-- Find accounts with no Cash Flow tag (potential mis-tagging)
SELECT a.code, a.name, a.account_type
FROM account_account a
WHERE NOT EXISTS (
SELECT 1 FROM account_account_account_tag_rel rel
JOIN account_account_tag tag ON rel.account_account_tag_id = tag.id
WHERE rel.account_id = a.id AND tag.name LIKE 'Cash Flow:%'
)
AND a.account_type IN ('asset_current', 'liability_current')
ORDER BY a.code;
Verification: every operating-cycle account has a tag.
5. Add monthly comparison and variance
Use the Date filter at the top of the report: "Comparison" > "Previous Period" or "Previous Year". Variance and percentage columns appear automatically. Verification: the Cash from Operations line shows current month, prior month, $ change, % change.
6. Build the PDF/Excel export
Click Print > PDF or Print > Excel. Both ship with the Financial Reports engine. For monthly board packs, schedule a cron that emails the report to a distribution list every 5th of the month:
from odoo import models, api
from datetime import date, timedelta
class FinancialReportSender(models.TransientModel):
_name = 'financial.report.sender'
@api.model
def _cron_send_monthly_cf(self):
report = self.env.ref('account_reports.cash_flow_report')
prior_month_end = date.today().replace(day=1) - timedelta(days=1)
options = {
'date': {'date_from': prior_month_end.replace(day=1).isoformat(),
'date_to': prior_month_end.isoformat(), 'mode': 'range'},
}
pdf = report.with_context(active_ids=[report.id])._render_qweb_pdf(options)
attachment = self.env['ir.attachment'].create({
'name': f'CashFlow_{prior_month_end.isoformat()}.pdf',
'datas': base64.b64encode(pdf[0]),
'mimetype': 'application/pdf',
})
template = self.env.ref('your_module.email_template_monthly_cf')
template.attachment_ids = [(6, 0, [attachment.id])]
template.send_mail(self.env.user.id, force_send=True)
Verification: the email arrives on the 5th with the PDF attached.
7. Validate against external benchmarks
Compute Free Cash Flow = Cash from Operations - Capex. Compare to the company's reported FCF in Power BI or Excel models. Verification: numbers match within rounding (under 1 percent).
8. Document audit-trail
Every line on the report is clickable and drills into the underlying journal entries. For external audit, export the report to PDF and include a hyperlinked Excel showing the constituent moves per line. Verification: each report total ties to the sum of clicked-through journal entries.
Common mistakes
- Skipping account tagging. The report sums incorrectly because untagged accounts default to "uncategorized".
- Tagging revenue accounts as Operating - Working Capital. They belong in Net Income.
- Forgetting to add back stock-based compensation. Material for VC-backed startups; missing it understates Cash from Operations.
- Running the report without prior-period closing. Beginning Cash is wrong if the prior period isn't locked.
- Manual reclassifications without Odoo support. Auditors hate journal entries that "fix" the report — fix the tags instead.
Going further
Direct method companion report: build a parallel direct-method statement showing actual cash receipts and payments. Useful for treasury operations. Tag bank journal entries with their source category (customer payment, supplier payment, payroll, tax, capex) and aggregate by category × month. The two methods should reconcile to the same Net Change in Cash within rounding.
13-week rolling cash forecast: pair the historical statement with a forward-looking cash forecast in Power BI. Sources: open AR (with predicted payment dates), open AP (due dates), recurring contracts, payroll cycles, scheduled tax payments, capex commitments. Refresh weekly. Visual: stacked bar of inflows and outflows per week, with cumulative cash line overlaid. The treasurer's morning view.
Cash conversion cycle metrics: compute Days Sales Outstanding (DSO = AR / daily revenue), Days Inventory Outstanding (DIO = inventory / daily COGS), Days Payable Outstanding (DPO = AP / daily COGS) alongside the cash flow statement. Cash Conversion Cycle = DSO + DIO - DPO. Target: shrinking trend month-over-month.
Multi-currency consolidation: in a multi-company structure, the Enterprise Consolidation module handles the FX-translation for foreign subsidiary cash flow. Use period-end rate for AP/AR balances, average rate for P&L items, historical rate for equity. The Cumulative Translation Adjustment account balances any residual.
Segment-based cash flow: for businesses with distinct units (e.g., consulting + product), tag every transaction with a segment analytic and produce per-segment cash flow statements. Reveals which business lines actually generate cash vs which consume it.
Free Cash Flow per share: for public-prep companies, compute FCF / fully-diluted shares as a dedicated KPI. Pair with stock price to track FCF yield.
Quality of cash flow analysis: compare Cash from Operations to Net Income over multiple quarters. A healthy ratio (CfO / NI) is between 0.8 and 1.5. Persistent deviations signal accruals quality issues that auditors investigate.
For audit-grade financial reporting setup, ECOSIRE accounting services configure the entire reporting stack including monthly close playbooks. Pair this with how to create a balance sheet template in Odoo.
Frequently Asked Questions
Indirect or direct method?
Indirect for external reporting and most board packs (it explains "why does net income differ from cash"). Direct for treasury operations (it shows actual cash movements). Most ECOSIRE clients run indirect monthly and direct on demand.
Why does my Cash from Operations look weird in the first month after migration?
Beginning balances are imported as opening journal entries. Without proper tagging, those opening entries leak into Operating. Tag them with a special "Opening Balance" tag and exclude from Cash Flow.
Can I customize the report sections?
Yes. The Financial Reports engine is fully configurable via XML records. Add a new section like "Tax Receivable Working Capital" by creating an account.report.line that filters on specific account codes.
How do I handle restricted cash?
Tag restricted cash accounts (escrow, bond reserves) separately. The "Ending Cash" section should show "Total Cash" with subtotals "Available" and "Restricted".
For complex cash flow setups including 13-week forecasts and treasury management, ECOSIRE accounting builds the full finance stack. Or read how to build a balance sheet template for the next core financial report.
Escrito por
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
Transforme su negocio con Odoo ERP
Implementación, personalización y soporte experto de Odoo para optimizar sus operaciones.
Artículos relacionados
Cómo agregar un botón personalizado a una vista de formulario de Odoo (2026)
Agregue botones de acción personalizados a las vistas de formulario de Odoo 19: método de acción de Python, herencia de vistas, visibilidad condicional, cuadros de diálogo de confirmación. Probado en producción.
Cómo agregar un campo personalizado en Odoo sin Studio (2026)
Agregue campos personalizados a través de un módulo personalizado en Odoo 19: herencia de modelo, extensión de vista, campos calculados, decisiones de tienda/no tienda. Código primero, controlado por versiones.
Cómo agregar un informe personalizado en Odoo usando un diseño externo
Cree un informe PDF con su marca en Odoo 19 usando web.external_layout: plantilla QWeb, formato de papel, enlace de acción. Con logotipo impreso + anulaciones de pie de página.