Nobody set out to run reporting in Excel. It happens one export at a time. A trial balance goes out to get a subtotal the report screen would not group; a P&L goes out to sit next to last year; an aged receivable goes out because someone wanted it by salesperson. Each export is reasonable on its own. The result is that the pack the board reads and the ledger the auditor reads are two different objects, and reconciling them is a job someone has quietly acquired. The ledger did not lose the numbers. It lost the last mile between the numbers and the page they get printed on.
Reporting that reads the ledger directly rather than a copy of it. General ledger, trial balance, open items, journal ledger, aged partner balance and a VAT report, each run over a date range and each drillable to the entries underneath it, plus a profit and loss and a balance sheet built from account templates you can edit, because a chart of accounts is not the same shape in two companies. Alongside them, the ledger's own working surface: any list, pivot or graph view can be saved as a filter, shared or kept private, and pinned to a dashboard, and the whole database is reachable over RPC or directly in Postgres for whatever you already point at your data.
Two places, and knowing which is which is worth more than a feature grid.
The dashboard and saved-view layer is Odoo Community itself. Saved filters on any model, the four dashboards Odoo ships, digest KPIs, and the RPC and Postgres access, no module to add, no tier to reach, no per-seat fee, and the system runs on infrastructure you own.
The statements are not. Odoo's own financial reporting engine is Enterprise, and
Enterprise is licensed per user for the whole system, never per app. The free
replacement is published by the Odoo Community Association on the 18.0 branch:
account_financial_report for the general ledger, trial balance, open items,
journal ledger, aged partner balance and VAT report, and
mis_template_financial_report on top of mis_builder for the profit and loss
and the balance sheet. We install them. They run on the deployment you own, the
report definitions are data you can edit, and the code stays yours.
That is the shape of the whole stack rather than an exception to it. The statements not being in the base image is not a hole we are patching; it is what it looks like when the missing piece is a free install instead of a renewal conversation. NetSuite's answer to the same gap is a SKU and a per-seat renewal, and that difference is the product.
One thing here comes from nowhere, and this page will not pretend otherwise. The ad-hoc workbook, the analyst's own saved, shared, reusable spreadsheet built over live records, which is what NetSuite markets as SuiteAnalytics Workbook, has no equivalent in either Odoo edition and no free replacement on 18.0. Pivot and graph views are the analysis surface, and they are views, not workbooks. We looked, there is nothing, and it is one of the twelve gaps on the map that are genuinely gaps.
A trial balance lists every account in the general ledger with its debit or credit balance at a point in time, and its purpose is arithmetic: the two columns must agree, which proves the double entry held. A financial statement, a balance sheet or a profit and loss, takes those same balances and arranges them into a presentation a reader outside the accounting team can interpret, grouping accounts into current assets, long-term liabilities, cost of sales and so on, and applying sign conventions and subtotals that the raw account list does not carry. The trial balance is the ledger proving itself. The statement is the ledger explaining itself. This is why two companies with identical transactions can produce identical trial balances and differently shaped statements: the mapping from accounts to statement lines is a decision, not a calculation.
Usually not because the report is wrong, but because it is fixed. A reporting screen answers the question its designer anticipated; the questions that arrive in practice want one more grouping, a comparison against a period that is not on the menu, or a subtotal cut a different way. Exporting is the fastest route to the answer, so it wins, once. The cost lands later and somewhere else: the figure that left the building now lives in a file, the ledger keeps moving, and when the question comes back a week later there are two versions of the number and no automatic way to tell which one is current. The problem to solve is rarely the missing report. It is that the export creates a second copy of the truth, and nothing keeps the copies in step.
Not always in the base package, and the distinction is worth checking rather than assuming, because "open source" describes the licence and not the contents. Odoo Community, for example, ships the full double-entry ledger, the chart of accounts, journals, taxes and reconciliation, but its base image carries no balance sheet or profit and loss report, those are in the paid edition. The replacement is not a purchase. The Odoo Community Association publishes free, openly licensed reporting modules on the same version branch, and they install onto the same deployment. So the practical question to ask a vendor is not whether statements are included, but what closing the gap costs: on a proprietary suite it is a licence tier or a per-user renewal, and on an open-source stack it is an install against code you already hold.
Three questions, in this order. Which reports are in the edition being quoted, as opposed to a higher one, this is where most surprises live, because demos are almost always given on the top tier. Where the report definitions are stored, and whether you can change them without the vendor: a report engine whose templates are editable data behaves very differently at year two from one whose templates are compiled into the product. And what happens to the reports if you stop paying, whether the historical data stays queryable in a format you can reach, or whether the reporting layer was the only door to it. None of these is answered by a feature checklist, and all three are answerable in a conversation.