Skip to content

Multi-Level BOMs and Routing Costs in Odoo Manufacturing

Learn how multi-level BOMs differ from single-level structures, identify common routing errors that inflate costs, and understand Odoo's cost calculation a

Ravi Shanker Singh9 min read

Understanding Multi-Level BOMs vs. Single-Level Structures

A single-level BOM lists the raw materials and components that go directly into a finished product. That's straightforward enough when every input is purchased. It falls apart the moment you manufacture something that is itself built from other manufactured things.

A multi-level BOM — sometimes called a nested or indented BOM — is a bill of materials where one or more of the components is itself the output of another BOM. Think of a furniture manufacturer building a dining chair: the chair BOM calls for a seat cushion assembly and a frame assembly, and each of those has its own BOM with its own components, routings, and work centers. Odoo handles this natively through **sub-manufacturing**, where a component flagged as "Manufacture" rather than "Buy" triggers its own manufacturing order, either automatically via MRP scheduling or manually.

The distinction matters more than most implementation teams admit up front. In a single-level structure, cost errors are contained — get the cost of a purchased screw wrong and you're off by fractions of a cent. In a multi-level structure, an error at level three of the BOM tree doesn't stay at level three. A routing error at the bottom of a five-level BOM doesn't stay put — it multiplies through every batch and every level above it before it reaches the finished good's cost, and it's the finished good's cost that ends up on a customer quote.

A common failure pattern: manufacturers running three or four sub-assembly levels set up Odoo as if everything were single-level — flat BOMs with purchased-looking "components" that were actually internally built. It works until finance asks why gross margin on the flagship product dropped four points in a quarter nobody can explain.

Common Routing Mistakes That Inflate Manufacturing Costs

Routing errors are quieter than BOM errors. A wrong component quantity gets caught the first time someone runs out of stock on the shop floor. A wrong routing time just sits there, silently overstating or understating cost, for months.

The mistakes we see most often, in rough order of frequency:

  • Work center time entered in the wrong unit. Someone enters "45" meaning minutes; Odoo's field is configured in a way that reads it as something else, or a template copied from another product carries over a duration that was never meant for this one.
  • Setup time buried inside cycle time. A CNC operation with an 18-minute changeover and a 3-minute cycle per unit gets entered as a flat 3 minutes per unit, because nobody separated "time per unit" from "time per operation" in the operation type configuration. On a batch of 10, that's a 60% understatement of real machine time.
  • Missing or duplicated operations after a BOM revision. Someone updates the BOM to add a new sub-assembly step but forgets the routing needs a matching operation, or copies a routing from a similar product and never deletes the step that doesn't apply.
  • Work center cost per hour that hasn't been touched since go-live. Energy costs, labor rates, and depreciation schedules all shift. If the work center's cost figure was set in 2022 and never revisited, every manufacturing order since has been costed against 2022 economics.
  • Routing applied to the wrong operation type. In Odoo, routings can differ by BOM (via operation-specific routings on the BOM itself) or be shared across products. Sharing a routing across two products that actually run at different speeds on the same machine quietly misallocates cost between them.

None of these throw an error message. Odoo will happily confirm a manufacturing order with a routing that's wrong by a factor of three. The system computes what you tell it to compute.

How Odoo Calculates Costs Across BOM Levels

Odoo calculates the theoretical cost of a manufactured product by rolling up the cost of every component (bought or sub-manufactured) plus the cost of every routing operation, at every level of the BOM tree. For sub-manufactured components, Odoo doesn't stop at the top level and guess — it walks down into the child BOM, computes its cost the same way, and uses that computed cost as the component cost one level up. This is the "unfolded" or nested cost roll-up, and it's visible in the product form's cost breakdown and in the Manufacturing app's cost reporting.

This is where costing method matters more in multi-level environments than in single-level ones. If your product category uses **Standard Costing**, every unit of a component is valued at the same fixed cost regardless of which actual receipt or production run it came from — useful for planning, dangerous if that fixed cost is stale. Under **Average Cost (AVCO)** or **FIFO**, the valuation moves with actual receipts and production, which is more accurate but harder to forecast against.

One point people get wrong regularly: changing a product category's costing method doesn't erase history, but it isn't a clean slate either. When you switch — say, from Standard to FIFO — Odoo automatically posts a revaluation entry that adjusts the value of on-hand stock to match the new method. What it doesn't do is reach back into stock moves that already happened and recompute their valuation, or touch the manufacturing order costs already posted against them. Those keep whatever figure was assigned at the time. If a category has been miscosted for eight months, switching methods today fixes the value of what's currently sitting in the warehouse — it doesn't rewrite eight months of journal entries and manufacturing order costs that already went through. Plan for that when you're deciding whether to raise the concern in Q1 or wait until year-end close. (See Odoo's documentation on inventory valuation: [odoo.com/documentation/18.0/.../reporting/aging.html](https://www.odoo.com/documentation/18.0/applications/inventory_and_mrp/inventory/warehouses_storage/reporting/aging.html).)

Odoo 18 also added inventory valuation **by lot or serial number**, which matters specifically for multi-level BOMs where a sub-assembly's actual cost varies meaningfully by batch — different raw material lots, different supplier pricing over time. Standard costing, by definition, assigns every unit the same cost regardless of which lot it came from. If your sub-assemblies have real cost variance between batches and you need that precision to flow up through the BOM tree, lot-level valuation is the mechanism built for that, not a workaround with standard costing.

Setting Up Accurate Routings to Prevent Cost Overruns

Getting routings right isn't a one-time setup task. It needs the same periodic recheck as anything else that drifts quietly from what's actually happening on the floor.

  • Separate setup time from cycle time explicitly, using the operation's dedicated fields rather than folding both into a single duration. This alone fixes the majority of small-batch cost distortion we encounter.
  • Time-track a sample of real manufacturing orders against the routing's theoretical duration. Odoo's Manufacturing Orders can log actual duration per work order; compare that against the routing's planned duration quarterly, not once at go-live.
  • Review work center hourly cost alongside your actual cost accounting, not in isolation. If your finance team recalculates overhead absorption rates annually, your Odoo work center costs should move on the same schedule — otherwise the two systems drift apart and nobody notices until an audit.
  • Audit routings whenever a BOM revision happens, as a mandatory step, not an afterthought. Odoo's BOM versioning doesn't automatically validate that the attached routing still matches the operations the new BOM implies.
  • Avoid over-sharing routings across products that run at genuinely different speeds, even on the same machine. It's tempting to reuse a routing to save setup time; the saved ten minutes costs you accurate costing for the life of both products.

The Odoo documentation on routings (Manufacturing > Basic Setup > Routings) covers the mechanics of operation types, work centers, and time computation — worth a re-read even for teams that have been live for years, because defaults and field behavior have shifted across versions.

Real-World Cost Impact: When Routing Errors Go Unnoticed

A Rayong-area electronics subcontractor we worked with ran a three-level BOM for a control panel assembly: purchased components at the bottom, two sub-assemblies in the middle, final assembly at the top. One sub-assembly's routing had a setup time of 25 minutes folded into a "per unit" cycle time field, entered years earlier by a technician who has since left the company.

On paper, unit cost looked fine. In batches of 50, the error washed out enough that margin still looked acceptable. But their sales team had started quoting smaller custom-batch orders — 8 to 12 units — for a premium-tier customer segment. On those batch sizes, the mis-costed setup time inflated theoretical cost by roughly 14%, but because standard costing had frozen the (wrong) figure company-wide, every quote for that segment was priced against a number that had never been true for small batches in the first place. They weren't losing money on paper. They were quietly underpricing an entire product line for about eleven months before a new operations manager cross-checked actual machine-hour logs against the routing and found the gap.

Nobody caught it through Odoo's reporting, because Odoo reported exactly what it was told. The system wasn't wrong. The input was.

Best Practices for BOM and Routing Maintenance

None of this is free, and not every operation needs all of it. A low-mix, high-volume shop running two BOM levels with cost inputs that don't move much quarter to quarter can skip most of the following — the overhead of quarterly time-tracking and monthly reconciliation isn't worth the return there. This list is for operations where BOM depth, batch-size variability, or margin sensitivity make the errors above expensive enough to be worth chasing.

  • Treat BOM and routing accuracy as a recurring finance-operations joint review, not solely an operations task. Cost errors surface on financial statements before anyone on the shop floor notices them, which means finance needs visibility into BOM and routing changes as they happen, not just the resulting numbers three months later.
  • Version your BOMs deliberately and document why each revision happened, so a routing mismatch has a paper trail back to its cause.
  • Reconcile theoretical vs. actual manufacturing order costs monthly, at minimum for high-volume or high-margin-sensitive product lines. Odoo's Manufacturing Analysis reports make this a half-hour job, not a research project.
  • Apply landed costs after receipt, before consumption — a separate but related discipline. Landed cost adjustments retroactively update the valuation of received stock, but only help if applied before that stock is sold or built into something else; miss that window and the cost correction arrives too late to matter.
  • Don't let standard costing hide batch-size sensitivity. If your production runs vary meaningfully in size, model at least one small-batch and one large-batch scenario when validating a routing, rather than assuming the number that worked at 500 units still works at 10.
  • Assign explicit ownership of work center cost rates. Somebody's name, not "operations," should be attached to the responsibility of updating hourly cost figures on a fixed schedule.

The Rayong case cost eleven months of underpriced quotes before anyone caught it, and it was caught by a person cross-checking machine-hour logs against a routing by hand — not by Odoo flagging the discrepancy on its own. Odoo isn't built to question its own inputs. That job still belongs to whoever owns the BOM and the routing, checked against actual shop-floor data on a fixed schedule, not once at go-live and never again.

Sources

  • odoo
  • bill-of-materials
  • manufacturing-costs
  • routing
  • sub-assembly

From our own engineering team

Shopify Odoo Connector

True two-way Shopify ⇄ Odoo sync — products, inventory, orders, customers and refunds, in real time.

$230.98 one-time

View details
Ready?

Let's find out whether Odoo actually fits your business.

A short call, an honest answer. If it isn't the right system for you, we'll say so.

LINE myprofitbook · WhatsApp · Bangkok · New York · Delhi NCR