MishiSpark

Odoo Multi-Company Analytics: Cross-Entity Reporting

Odoo supports multi-company setups but cross-entity analytics is painful. Build unified reports across companies, currencies, and charts of accounts.

Spark by MishiPay Team10 min read

Odoo handles multi-company setups well at the operational level. You can run separate entities — different legal entities, different countries, different business units — within a single Odoo instance. Transactions flow between companies. Access rights keep data separated where needed.

The problem starts when you need analytics across those companies. Consolidated revenue, group-wide inventory, cross-entity customer analysis — these are basic questions for any multi-company business, and Odoo's built-in reports make them surprisingly painful to answer.

How Odoo's multi-company architecture works

Before diving into the analytics challenges, it helps to understand what Odoo gives you out of the box.

The company model

Every record in Odoo can be associated with a company via the company_id field. Sale orders, invoices, journal entries, stock moves — they all belong to a specific company. Some records (like product templates) can be shared across companies or restricted to one.

Users are assigned to one or more companies, and Odoo's access rules ensure they only see data for companies they belong to. A user can switch between companies using the company selector in the top menu.

Inter-company rules

Odoo supports automated inter-company transactions. When Company A creates a sale order to Company B, Odoo can automatically generate the corresponding purchase order in Company B. Similarly, inter-company invoices can be created automatically.

This keeps operational workflows clean, but it creates a challenge for analytics: inter-company transactions inflate revenue and expense figures if you simply sum across entities. A $10,000 sale from Company A to Company B isn't group revenue — it's an internal transfer that needs to be eliminated in consolidation.

Separate chart of accounts

Each company in Odoo can have its own chart of accounts. This is common when companies operate in different countries with different accounting standards, or when entities were set up at different times by different teams.

For analytics, this means "Revenue" in Company A might be account 400000, while in Company B it's account 7000. Summing journal entries across companies without mapping accounts to a common structure gives you meaningless numbers.

Multi-currency support

Odoo handles multi-currency natively. Each company has a base currency, and transactions in foreign currencies are recorded with exchange rates. But when you're consolidating across companies with different base currencies, you need consistent conversion — and Odoo's reports don't aggregate across currencies automatically.

The five challenges of cross-company reporting

1. No built-in consolidation

This is the biggest gap. Odoo does not provide a consolidation module in its standard offering. There's no built-in way to generate a consolidated P&L, balance sheet, or revenue report across multiple companies. Each report runs for a single company at a time.

Merchants work around this by exporting data to spreadsheets, building custom Odoo modules, or purchasing third-party consolidation apps. Each approach has tradeoffs — spreadsheets are manual and error-prone, custom modules require developer time, and third-party apps vary widely in quality.

2. Chart of accounts misalignment

When two companies use different chart structures, you can't simply sum account balances. You need a mapping layer that translates each company's accounts into a unified reporting structure.

For example, Company A (France) uses the French Plan Comptable General with accounts in the 6xx and 7xx range. Company B (US) uses a custom chart with accounts numbered 1000-9000. To build a consolidated income statement, you need to define which accounts in each company map to each line item — revenue, COGS, operating expenses, and so on.

Odoo doesn't provide this mapping out of the box. You either build it manually or use a tool that handles it.

3. Inter-company elimination

Any transaction between entities in your group needs to be eliminated from consolidated figures. Common inter-company transactions include:

  • Sales between entities: Company A sells goods to Company B for resale
  • Management fees: A holding company charges subsidiaries for shared services
  • Intercompany loans: One entity lends to another, creating receivables and payables
  • Inventory transfers: Goods move between warehouses owned by different companies

Failing to eliminate these transactions double-counts revenue, inflates expenses, and creates phantom receivables and payables on a consolidated balance sheet. Identifying and eliminating inter-company transactions in Odoo requires querying both sides of every transaction and netting them out — a process that's tedious to do manually and that Odoo's reports don't automate.

4. Currency conversion consistency

When consolidating across entities with different base currencies, you need a consistent conversion approach:

  • Balance sheet items should be converted at the closing rate (the exchange rate on the reporting date)
  • Income statement items should be converted at the average rate for the period
  • Equity items are typically converted at historical rates

Odoo records exchange rates and handles multi-currency within a single company, but it doesn't apply these consolidation rules when aggregating across companies. A simple sum of USD and EUR figures is meaningless without proper conversion.

5. Fiscal year and period alignment

Different entities may have different fiscal years. Company A runs January-December, Company B runs April-March. Reporting "Q1 revenue" means different date ranges for each company.

Even when fiscal years align, closing schedules might differ. Company A might close its books by the 5th of the following month, while Company B takes until the 15th. Reporting on "last month" might include finalized data for one company and preliminary data for another.

Practical approaches to cross-company analytics

Despite the challenges, multi-company businesses need consolidated views. Here are the approaches that work.

Revenue rollups

The most common need is consolidated revenue. To build this from Odoo data:

  1. Pull sale order data from each company. Query sale.order and sale.order.line for each entity, filtered by state (confirmed or done) and date range.

  2. Convert to a common currency. Apply the average exchange rate for the reporting period to convert non-base-currency amounts. Odoo stores the currency_id and currency_rate on transactions, which helps.

  3. Eliminate inter-company sales. Identify orders where the customer (partner_id) is another company in your group. Remove these from the consolidated total.

  4. Aggregate. Sum the remaining, currency-converted amounts for your consolidated revenue figure.

This process is straightforward in concept but painful in practice if you're doing it manually every reporting period. Each step requires API queries or database access, currency math, and careful filtering.

Inventory across entities

Consolidated inventory reporting requires summing stock quants across companies while keeping warehouse context. The steps:

  1. Query stock quants per company. Each company's quants are already scoped by company_id.

  2. Standardize product references. If companies share product templates, aggregation is clean. If they maintain separate product catalogs (common in acquisitions), you need a mapping between equivalent products.

  3. Convert valuation to a common currency. Inventory valuations are in each company's base currency. Convert using the closing rate for balance sheet consistency.

  4. Watch for inter-company in-transit stock. Goods being transferred between entities may appear as outgoing from one company and not yet received by another. During consolidation, this in-transit inventory needs to be accounted for — not double-counted or lost.

Cross-entity customer analysis

Customers that buy from multiple entities in your group are especially valuable, but Odoo treats them as separate records per company (or shares a single res.partner record with company-specific data). To build a unified customer view:

  1. Identify shared customers. Match by email, VAT number, or a custom external ID. Odoo's res.partner records might share the same contact but have different commercial terms per company.

  2. Aggregate spending. Sum order values across entities for each matched customer, converting currencies as needed.

  3. Build a unified profile. Combine purchase history, payment behavior, and support interactions from all entities into a single customer view.

This cross-entity customer analysis is where multi-company reporting gets genuinely powerful — and where Odoo's single-company reports can't help at all.

Profitability by entity

Comparing profitability across entities requires normalized accounting data:

  1. Map charts of accounts. Define a common reporting structure and map each company's accounts to it. At minimum, you need mappings for revenue, COGS, gross margin, operating expenses, and net income.

  2. Pull journal entry data. Query account.move.line for each company, filtered by date range and posted state.

  3. Apply account mappings. Translate each company's account codes to the common structure.

  4. Convert and consolidate. Apply appropriate exchange rates and sum by reporting category.

The result is a side-by-side profitability comparison that shows which entities are contributing and which are dragging — something that's impossible to see when each company's P&L is locked in its own Odoo reporting silo.

How Spark handles multi-company Odoo data

Spark connects to your Odoo instance and reads data across all companies your user has access to. The platform handles the heavy lifting that makes cross-company analytics painful:

Automatic currency normalization. Spark converts all monetary figures to your chosen reporting currency using appropriate rates — average rates for income statement items, closing rates for balance sheet items. You see consolidated numbers without manual currency math.

Inter-company detection. Spark identifies transactions between entities in your group and can present figures with or without inter-company elimination. Ask "What's our consolidated revenue excluding inter-company sales?" and get a direct answer.

Chart of accounts mapping. Spark's normalization layer handles different chart structures across entities. Revenue is revenue regardless of whether it's coded as 400000 or 7000 in the source system.

Cross-entity queries. You can ask questions that span companies naturally:

  • "What's total group revenue this quarter, broken down by entity?"
  • "Which entity has the highest inventory days-of-supply?"
  • "Show me our top 20 customers across all companies by total spend."
  • "Compare gross margin percentage across entities for the last 6 months."

These questions touch multiple companies, require currency conversion, and need inter-company awareness. In Odoo alone, each one would require custom development or hours of spreadsheet work. In Spark, they're conversational queries.

Getting started with multi-company analytics

If you're running Odoo with multiple companies and struggling with consolidated reporting, start here:

  1. Document your chart of accounts per entity. Before any tool can help, you need to know what accounts exist in each company and what they represent. Export the chart of accounts from each entity and identify the major categories — revenue accounts, COGS accounts, expense accounts.

  2. List your inter-company transaction types. Know what flows between your entities — sales, management fees, loans, inventory transfers. This is the list you'll need to eliminate during consolidation.

  3. Pick a reporting currency. Decide whether you're consolidating in USD, EUR, or another currency. This choice affects every number in your consolidated reports.

  4. Start with revenue consolidation. It's the simplest metric to consolidate and the one most stakeholders ask about first. Get revenue right, then expand to margins, inventory, and the full P&L.

  5. Connect to an analytics tool that handles the complexity. Whether it's Spark or another platform, multi-company consolidation is too complex for manual processes at any meaningful scale. The time you spend building spreadsheets every month is time you could spend acting on the insights.

Multi-company reporting in Odoo isn't impossible — the data is all there. The challenge is purely analytical: aggregating, converting, eliminating, and presenting data that lives in separate company silos. The right tool makes this automatic instead of manual.

Consolidate your multi-company Odoo data

Spark connects to your Odoo instance and delivers cross-entity analytics with currency conversion and inter-company elimination built in.

Ready to double your store sales?

Connect your store in 60 seconds. Get your first AI diagnostic free.