Odoo is one of the few systems in this series that companies choose deliberately rather than inherit, and it has earned that position. Odoo S.A. has shipped a major version every year while keeping the Community edition genuinely open under LGPLv3, on the same code base as the paid edition, the same PostgreSQL schema and a documented ORM. Of every system we connect, Odoo gives you the most complete access to your own data. Which makes the interesting question not how to get the data out, but what has been done with it once it is out.
At a glance
| System name | Odoo — a modular suite of open-source business apps sharing one database. In accounting and operations, an ERP in every practical sense |
| Vendor | Odoo S.A., Belgium. Sold directly and through its partner network |
| Markets | Global. Fiscal localisation modules for around a hundred countries, including Slovakia, Czech Republic and Poland — though none of the three has dedicated documentation |
| Category | Open-source modular ERP, available as SaaS, as a managed platform, or self-hosted |
| Editions | Community — LGPLv3, the core on which Enterprise is built · Enterprise — shared source, adding support, upgrade services, hosting and further apps |
| Hosting | Odoo Online (SaaS) · Odoo.sh (managed platform, Git-deployed) · on-premise (packages, source or Docker) |
| Pricing model | Per-user subscription — One App Free, Standard, Custom. Two plan boundaries matter for reporting, covered in the hosting section below |
| Database | PostgreSQL. One database per Odoo instance, holding many companies. Model names map to table names by replacing dots with underscores, so account.move is the table account_move |
| Deployment | Companies share one database, separated by a company_id column — not one database per entity. A record with no company is shared across all of them |
| Integration | External JSON-2 API, bearer API key, new in 19.0 · XML-RPC and JSON-RPC, deprecated, removal in Odoo 22 · direct read-only PostgreSQL on-premise · psql through the Odoo.sh shell · dump download on all three hosting types |
| Payroll | A Payroll app, with payroll localisations documented separately from fiscal ones. Coverage for Slovakia, Czechia and Poland is a per-country question to check, not a given |
| Vendor reporting | Pivot and graph views on almost every model · accounting reports with XLSX export and period comparison · Odoo Spreadsheet and Dashboards · Odoo Studio |
| Typical user | Odoo publishes no size band. In our estate it is frequently multi-entity |
| Official | odoo.com · Odoo documentation · External API reference |
What Odoo is
Odoo is a modular open-source ERP: one PostgreSQL database and one application server, on which individual apps — accounting, invoicing, inventory, manufacturing, purchase, sales, projects, e-commerce, HR — are installed as modules against a shared data model . Installing an app does not create a separate system. It adds tables, fields and views to the same database the rest of the business already sits in, which is why an Odoo invoice, an Odoo stock move and an Odoo timesheet can be joined in a single query.
Two editions come off one code base. Community is licensed under LGPLv3 and described by Odoo as the core on which Enterprise is built; Enterprise is shared source, adding functional support, upgrade services, hosting and further apps including Studio. The relationship is unusually clean: moving from Community to Enterprise means installing one module on the same database and entering a subscription code. The schema underneath is continuous.
The release discipline is real, and it bears on reporting. One major version a year, three years of support each, extended support at a mandatory fee after that; Odoo Online customers also receive intermediary SaaS versions every few months. For a finance team the appeal is coherent: one system across operations and the ledger, priced per user, open enough to extend, with partner coverage in every market we work in.
The two editions and the three hosting options
Odoo is one product with three deployment models, and for anyone who has to read the data they are not the same thing. This is the most consequential fact on this page.
| Odoo Online | Odoo.sh | On-premise | |
|---|---|---|---|
| Who runs it | Odoo, as a managed service | Odoo, as a Git-deployed platform | You, or your partner |
| Custom modules | Not compatible with custom modules or Apps Store modules | Yes, deployed from your repository | Yes |
| Direct PostgreSQL access | Not available | Yes, through the container shell — Odoo documents psql as a shell command, over the web shell or SSH | Yes, it is your database server |
| Database export | Backup download from the database manager | Automatic daily production backups, plus manual backups and dump download | Yours |
| Documented read paths | External API, backup download | Shell-mediated SQL, external API, dump download | Direct SQL, external API, dump download |
| Version policy | Major upgrade mandatory every two years; intermediary versions mandatory a few weeks after the next release | Three years of standard support, then two further years to complete the upgrade | You may stay on a version indefinitely |
The absence of a database connection on Odoo Online is not a shortcoming. It is the consequence of running a managed multitenant service — a platform that guarantees a rolling upgrade every two years cannot also guarantee arbitrary code and arbitrary database sessions, which is also why Odoo Online is documented as incompatible with custom modules. Odoo draws the boundary and publishes an alternative: the external JSON-2 API, authenticated with a bearer API key that carries an expiry and rotates. Two documented pricing boundaries belong in the same conversation, because they surprise people: external API access is available only on Custom plans, not on One App Free or Standard, and enabling multi-company on a Standard plan triggers an upsell to Custom. Both are reasonable commercial lines, and both are better established before a reporting project is scoped than after.
Odoo.sh sits usefully in the middle: Odoo runs the platform, you deploy your own modules from Git, and you keep genuine access to the machine — a container shell where psql is a documented command, plus downloadable production dumps. One detail before planning a move between hosting types: Odoo Online’s intermediary versions are not supported on Odoo.sh or on-premise, so a database on an intermediary SaaS version has to reach the next major version first.
Who Odoo fits
Companies that want one system instead of five. Accounting in one tool, stock in a second, a CRM in a third and a spreadsheet holding it together. Odoo’s proposition is that all of it lands in one database, and for a company at that stage it is usually the right call.
Manufacturers and project businesses. Bills of materials, work orders, timesheets and project costing are the depth that separates Odoo from the accounting-led systems in this series. A business that makes things, or delivers work in projects, gets its operational and financial data in the same database — which is exactly the join a profitability question needs.
Companies with development capability, in-house or through a partner. This is Odoo’s distinguishing profile. A custom module or a Studio field can be added in an afternoon, so the system fits the business rather than the business fitting the system. That same flexibility is why no two Odoo databases look alike, and it is what a reporting layer has to be built against.
Slovak, Czech and Polish entities inside international groups. The localisation picture needs care, because it is the picture our market lives in. Odoo lists fiscal localisation modules for all three countries, and all three are eligible for Peppol registration through Odoo — but it publishes country documentation for none of them, where around forty other countries have a dedicated page each. Polish KSeF and JPK filing, and the Slovak and Czech VAT statements, are in practice a matter of partner and Apps Store modules. None of that makes Odoo the wrong choice in these markets. It does mean the estate is Odoo plus named third-party modules, and a reporting layer has to know which.
Groups that grew sideways. Odoo in the company that chose it, POHODA or Money in the Slovak trading entity, Business Central in the parent, something else again in the business acquired last year. Every one of those choices was locally correct. What nobody owns is the view across them, and this is the context in which Odoo most often reaches us.
What Odoo holds — and why it is good material
Before the reporting question, the asset. And here the asset is unusually good.
Odoo’s ORM writes a predictable relational schema. Every model becomes a table whose name is the model name with the dots replaced by underscores — account.move is account_move, account.move.line is account_move_line. Double entry lives in those two tables and nowhere else: the document header in account_move, the debits and credits in account_move_line, joined by a single foreign key. Every record also carries the ORM’s access-log columns — create_date, write_date and their user counterparts — both an audit trail and the incremental extraction watermark you would otherwise have to invent. In data governance
terms, provenance is already in the table.
Multi-company is the fact that changes the commercial argument. Odoo holds multiple companies in one database, separated by a company_id column, and Odoo’s developer reference is precise about what that column means: it “defines whether a record is shared between companies (no value) or only accessible by the users of a given company.” Products and contacts are shared by default; invoices and bills are not. So unlike the systems in this series that put each legal entity in its own database file, a multi-entity Odoo group already has its group data co-located, one join away from being aggregated. What is missing is not access. It is the definitions.
Analytic accounting is the dimension model, and the current terminology matters. From version 16 Odoo has organised it as analytic plans, which group analytic accounts, and analytic distribution, which spreads a journal item across one or more of those accounts by percentage. Plans can be nested as subplans and set to optional, mandatory or unavailable — so a plan such as cost centre can be made compulsory on given account prefixes, with distribution models prefilling it by prefix, partner, product or product category. Used properly this is a genuine multi-dimensional structure sitting directly on the ledger, which is what profitability analysis needs.
And the data quality is usually good. Postings are constrained by the application, the ledgers reconcile because Odoo makes them, and the audit trail report records field-level changes with user and timestamp. Against what we more often meet, a properly run Odoo is a strong starting point — and the quality of a reporting layer is bounded by what feeds it.
What sits outside Odoo’s scope
Odoo is scoped to running a business on one shared database. Three things sit outside that scope, and each boundary is drawn deliberately.
The group view across databases, at management depth. Within one database Odoo does well: a user with access to several companies can select them together and, in Odoo’s own words, generate “reports of aggregated figures without switching interfaces”. The boundary is the database. A group whose entities sit in separate Odoo databases — different hosting, different versions, an acquisition that arrived with its own instance — is outside it, as is any group needing one chart of accounts imposed across entities that each localised their own. For statutory consolidation with a stable structure, in-product aggregation is often enough. For a management group view people interrogate, it is the wrong shape.
The view across systems. Whether e-commerce revenue matches the ledger, whether the payroll run matches headcount in the HR system, whether the CRM pipeline squares with invoiced work. This is worth saying plainly: no ERP does this. Not Odoo, not Business Central, not SAP. Cross-system truth is a layer above every transaction system, which is the point we make at more length here .
Definitions that outlive the release cycle. This is the honest cost of a system that moves forward every year, and Odoo documents it plainly rather than hiding it. A database with custom modules cannot be upgraded until those modules have a version for the target release, and keeping them current is the maintainer’s job rather than Odoo’s — Studio customisations are covered by the upgrade service, in-house and third-party modules are not unless they carry a maintenance contract. The consequence for reporting is simple. A definition of gross margin held inside the ERP as a custom field or a hand-built report gets re-tested every year. The same definition held above the ERP does not.
None of this is a reason to change system. It is a reason to add a layer.
How we elevate it
We connect Odoo across all three hosting types, in single companies and in groups running Odoo next to other systems.
Getting the data out depends on which hosting you have, and being precise about that is most of the job. On-premise our default is a read-only PostgreSQL role — against a replica where one exists — reading account_move, account_move_line, the analytic tables and the master data directly and incrementally, on the write_date watermark the ORM maintains for us. On Odoo.sh the database is reachable but the access is shell-mediated — psql runs inside the platform’s tooling — so extraction there goes through the platform’s supported mechanisms or the API rather than a standing external database role. On Odoo Online there is no database connection and we do not pretend otherwise: the supported route is the external JSON-2 API, called with a bearer key issued to a dedicated read-only bot user, with a one-time historical load taken from a database backup. Read-only throughout, nothing written back, and users notice no difference in how the system performs.
What happens next is the Odoo-specific work.
A management chart of accounts, mapped against the database you actually have
Every Odoo implementation starts from a localisation package and then diverges — accounts added for a new activity, an app that brought its own postings, a custom module that books to somewhere specific. So the first step is a survey rather than a template: which apps are installed, which journals post to which accounts, what has been added in Studio. Then we map the statutory chart to a second structure built to answer management questions — revenue by what you actually sell, cost by what you actually control, margin at the level you actually decide. Mapped once, versioned, owned by a named person, reviewed at each close so it does not drift. Because the schema is readable, the mapping is built against evidence rather than assumption. More on the design problem underneath: chart of accounts architecture .
Analytic plans and distributions, turned into reporting dimensions
Analytic distribution is stored as a distribution rather than as a single code — a journal item can be split 60/30/10 across three analytic accounts in a plan. That is the right model for the ledger and the wrong shape for a report, because a percentage split has to be resolved into allocated amounts before anything can be totalled by cost centre or by project. We resolve it once, in the model: each plan becomes a dimension, each distribution becomes allocated value, and every line carries its dimensions as columns.
Then we audit how consistently they have been filled across history. Where a plan was left optional, coverage will be uneven; where distribution models were added mid-year, the same cost is split one way before a date and another way after it. We surface that, agree what gets enforced going forward, and hold the corrected view in the layer — so the ledger stays internally consistent and the reporting is right at the same time.
One view across companies, databases and systems
Each Odoo company becomes one entity in a common model — beside a second Odoo database on a different version, a POHODA or Money installation, a Business Central environment, an e-commerce platform, a payroll export or a spreadsheet, all producing the same standardised output. Group reporting in any currency with currency translation
applied consistently, reconciliation
across systems, and drill-down from a consolidated total back to the account_move_line behind it.
This is routine rather than aspirational: we work with 70+ companies across 11 countries, on 12+ different ERP and accounting systems. See Group Reporting & Consolidation .
On the governed layer, the rest is the platform doing its standing job: daily reconciliation against the ledger so the close confirms rather than rebuilds, a semantic model that Power BI and AI can both query reliably , and your business context accumulating so answers get sharper the longer it runs.
What becomes answerable
- Which customers and which products are actually profitable, after delivery and service cost — not just gross margin on the invoice?
- What is group EBITDA in one currency, when two companies sit in one Odoo database, a third sits in its own, and a fourth is on something else entirely?
- What did that project cost against what we quoted, while it is still running?
- Why did overhead move this month, ranked by the cost lines that moved most — against budget and against last year?
- Which entities and periods carry analytic distribution gaps, and on which accounts, before the close rather than after it?
- How much cash is tied up in stock that has not moved in six months, across every warehouse in the group?
Every one of these is answered from data Odoo is already holding. The information was there. What was missing was the structure to ask.
What it takes, and what does not change
Connection in days. First reports in the first week. For a single-entity Odoo client, the connection is a read-only login and the first governed reports follow inside a week. A full build — management chart of accounts, dimension repair, consolidation across several entities, the reporting suite — runs in phases over the following months. The distinction matters, and we would rather be precise about it than promise a finished model in a fortnight.
What we need from you: an NDA, read-only access, and a conversation about what the numbers should mean.
What does not change: Odoo stays your system of record. Your accountant keeps working the way they work. No migration, no data cleanse project, no retraining, nothing written back.
Read-only access throughout. Your data stays in an EU-hosted Azure environment, aligned with ISO 27001 and GDPR, governed by you.
In practice
Odoo runs in our client base — MAD is on it, connected the way this page describes: the analytic plans and distributions turned into reporting dimensions that hold their meaning, and the Odoo data joined to whatever else sits beside it in one governed model.
When the system underneath changes
Odoo changes underneath a reporting layer in two ways, and only one of them is a replacement.
The ordinary one is the annual upgrade. A major version a year, mandatory every two years on Odoo Online — every Odoo database moves, on a schedule, whether or not the finance calendar agrees. Because the governed layer sits above the ERP, an upgrade changes the connection and the extraction mapping rather than the definitions: the management chart of accounts, the dimension model, the reports and the consolidation logic carry through. Clients who built the layer first can also prove the upgraded database’s numbers against the old ones, period by period, before going live.
The less ordinary one is a change of system, in either direction — Odoo replacing something a company has outgrown, or a group standardising onto something else as it passes the point Odoo is scoped to serve. The same thing holds. Only the connection changes, and the reporting history survives the move.
This is not a theoretical claim. When JING Tea replaced its operational stack, the reporting layer carried through the change unaltered — the systems underneath moved, the numbers and the reports did not.
How Odoo compares
Odoo is one of several capable systems in the estates we work in. Each gets its own article in the series .
| System | Vendor | Market | How it compares |
|---|---|---|---|
| POHODA | STORMWARE | CZ · SK | Accounting-led and deeply localised, one database per entity; its own article here |
| Money S3 / S5 | Seyfor | CZ · SK | Accounting-led with an ERP tier above it, strong local statutory coverage |
| Helios | Asseco | CZ · SK | Mid-market ERP with production and project depth, strong local fit |
| ABRA Flexi | ABRA | CZ · SK | Cloud-first with a REST API as the primary integration surface |
| Business Central | Microsoft | Global | The system most mid-market groups standardise on; its own article here |
From a data-layer perspective the choice matters less than it appears. Each of these becomes an entity in the same governed model, which means the ERP decision can be made on operational fit rather than on reporting fear. The full matrix — including the Polish stack — is on the series hub .
Frequently asked questions
Do we need to replace Odoo to get proper management reporting? No, and we would usually advise against it. Keep Odoo for what it does well — transaction capture across operations and the ledger, statutory correctness, a system that fits the way you work — and build the reporting layer above it. If you are weighing it up anyway, we wrote about that decision here .
Is Onetribe a replacement for Odoo? No. Odoo remains your system of record and your team keeps using it exactly as they do now. We read from it, never write to it. If you change ERP later, the reporting layer stays.
Is Odoo an ERP or accounting software? An ERP, and one of the more complete at this end of the market — accounting sits alongside inventory, manufacturing, purchasing, sales, projects and e-commerce on one database. Two qualifications keep that honest: what you have depends on which apps are installed, and Community and Enterprise are not the same functional scope, even sharing a schema.
What database does Odoo use, and can we read it directly?
PostgreSQL, one database per instance holding all companies, with table names derived from model names — account.move becomes account_move. Whether you can read it directly depends on hosting, as set out above. It is the first question to settle before scoping an Odoo reporting project.
Can Odoo connect to Power BI? Yes, by the same hosting-dependent route. Where we have PostgreSQL, a read-only role against a replica is the durable pattern; where we do not, the JSON-2 API on a dedicated bot user does the same job with a lower throughput ceiling. In neither case would we point Power BI straight at the ERP — every refresh lands on a live transaction system, and the definitions scatter across files instead of being governed in one model. Power BI on a governed data layer , with the ERP left to run the business, is the arrangement that survives the next upgrade.
Can Odoo consolidate several companies?
Within one database it aggregates well: companies are separated by company_id, users can select several at once, and inter-company transactions can create counterpart documents automatically. Three limits define the edge. It is one database, so a group spread across separate Odoo instances or other systems is outside it. Eliminations, currency policy and a group chart of accounts remain your design problem rather than a feature. And an aggregated figure is not a governed group number until someone owns the definitions behind it.
Does Odoo have an API, and what about payroll? Yes — and in version 19 it changed. The current surface is the external JSON-2 API, authenticated with a bearer API key, exposing the ORM methods available on that database with the user’s access rights applied. The older XML-RPC and JSON-RPC endpoints still work but are deprecated, with removal scheduled for Odoo 22 — anything built on them has a known expiry date. On payroll, Odoo ships a Payroll app and documents payroll localisations separately from fiscal ones; confirm the position for your country before assuming it. The layer reads payroll wherever it lives.
Is Odoo’s own reporting enough? For a single company, often yes — and worth using before adding anything. Pivot and graph views turn almost any model into an ad-hoc analysis in seconds, the accounting reports carry period comparison and drill-down to the entry, Odoo Spreadsheet puts live figures into a spreadsheet, and Studio adds fields and views without a developer. All of it runs out in the same three places: across databases, across systems, and anywhere a definition has to be shared, versioned and audited rather than held in a file. If you rebuild the same dashboard after every release, that is the signal.
Official Odoo resources
- Odoo — product overview
- Odoo 19 documentation
- External API reference — JSON-2, API keys, RPC deprecation
- Standard and extended support
- Upgrade documentation, and what the upgrade service covers
- Odoo.sh branches, shell, backups and dumps
- Multi-company configuration
- Analytic accounting — plans, accounts, distributions
- Fiscal localisations and supported countries
- Licences — LGPLv3 and the Enterprise Edition License v1.0
Onetribe is not an Odoo S.A. partner or reseller. We build the governed data layer above your ERP, whichever ERP that is.
Next steps
- Every source system we connect — the series hub, with the full matrix
- How we consolidate any combination of ERPs — group reporting
- Why your ERP doesn’t govern your data — the cross-system layer, in detail
- Discuss your Odoo estate — free assessment