Ten Customizations That Belong in an Engineering-Led Plant
Engineering-led manufacturers — companies where the CTO sits next to the COO and the codebase is treated like a product, not a stopgap — have a different bar for Odoo work. Quick patches and monkey-patches do not survive an upgrade. The ten customizations below assume a clean, modular approach: configure first, extend with OWL components or server actions next, and ship custom modules only when the edge of your business genuinely lives outside standard Odoo. All ten work on Odoo 19 and survive a release migration when written this way.
Octura packages these as fixed-price custom-module engineering with senior engineers on every project — no junior consultants billed at senior rates.
Tiered Customization Stack — Configure, OWL, Then Custom Modules
The most valuable customization an engineering-led plant adopts is a discipline, not a feature: a tiered customization stack. Tier one is configuration — Studio fields, automated actions, server actions inside the database. Tier two is presentation — OWL 3 components, custom views, JavaScript widgets that live in a thin frontend module. Tier three, and only tier three, is a full custom Python module with new models, security, and ORM logic. The rule: never reach for a higher tier when a lower tier solves it. The upgrade cost of a tier-three module is 10x a tier-two widget; the upgrade cost of a tier-two widget is 10x a tier-one server action. Document the stack in your internal engineering wiki and enforce it in code review.
AI-Driven Server Actions for Non-Trivial Business Rules
When a business rule is too complex for an automated action but too small for a module — pricing tiers that depend on three customer attributes, a lead-time computation across a routing graph, a credit hold that checks four signals — reach for an AI-driven server action. A Python snippet runs inside the Odoo environment with full ORM access; the LLM call (Claude, GPT, or local) is reserved for the genuinely fuzzy part of the rule (classify this email, summarize this MO history, draft this customer note). Keep the deterministic logic in Python, keep the AI scoped to one signal, and log every prompt and response. This is where engineering-led teams stop writing 200-line if/elif trees.
IoT Drivers for Shop-Floor Hardware
The plant has sensors, scales, scanners, label printers, torque guns, vision systems — most of them speak Modbus, OPC-UA, or serial. Odoo's IoT Box framework handles the connection layer; the customization is the device driver on top: a small Python class that translates the device protocol into Odoo events. Once the driver lives in your custom module, the device becomes a first-class citizen in the manufacturing order — weight captures land on the work order, torque values feed the Quality Point, scanner reads advance the operation. This is the single highest-leverage shop-floor customization an engineering-led company ships.
Custom Dashboards with OWL + Spreadsheets Module
The COO wants a dashboard. The default response is a custom module with charts. The correct response is the Spreadsheets module plus a small OWL 3 component. Spreadsheets gives a live Odoo data source with formulas, pivots, and conditional formatting that any finance user can edit. OWL gives the bespoke widget you actually need — a real-time work-center utilisation tile, a quality first-pass-yield gauge, a cash conversion tracker. Wire them together inside a kiosk view. No Python module, no upgrade cost, and the COO can edit the dashboard themselves.
Internal-System Integrations via REST API + Webhooks
Engineering-led companies already run a stack — a CAD vault, a PLM, a homegrown shop-floor app, a data warehouse, a custom portal. Integration belongs on the REST API and webhook layer, not in a side-channel ETL. Odoo exposes an XML-RPC and JSON-RPC API by default; layer a clean REST controller on top with versioned routes, schema validation, and OAuth2 tokens. Pair with outbound webhooks on key events (MO confirmed, lot shipped, invoice posted) so downstream systems react instead of poll. This is the single integration pattern that does not break on Odoo upgrades.
Migration Scripts on Every Release
The reason most Odoo customizations break on upgrade is not the customization — it is the schema drift. The fix is to ship a migration script in every custom module: a migrations/<version>/ folder with pre- and post-migration Python that handles every field rename, model split, or data backfill the release introduced. Run it in CI against a copy of production. Engineering-led companies treat the migration script as part of the feature definition of done — no migration script, no merge. The first release after this discipline lands, your upgrade cost drops by an order of magnitude.
CI/CD with GitHub Actions Against Real PostgreSQL
Custom modules deserve the same pipeline as any product: CI/CD with GitHub Actions running automated tests against a real PostgreSQL instance, not SQLite or a mock. The workflow installs the module on a fresh Odoo container, runs the test suite, executes the migration script, and posts coverage to the PR. Add a staging deployment stage that mirrors production on every merge to main, and a manual production promotion gated by a tag. The investment pays back the first time a junior engineer ships a regression and the pipeline catches it before review. Walk-through in CI/CD with GitHub Actions.
OCA App Auditing Before Pulling Third-Party Modules
The Odoo Community Association ships hundreds of useful modules. They are not all equal. Before any third-party module enters your repo, run an OCA app audit: read the source for security smells (raw SQL, missing access rules, dangerous sudo), check compatibility against your Odoo version, verify the maintainer cadence, and confirm tests exist. An OCA module is upstream code that you now own — treat it like a dependency, not a freebie. The five extra hours of audit per module are the cheapest insurance an engineering-led company buys.
Module-Development Discipline: Models, Views, Security
When a tier-three custom module is genuinely warranted, scaffold it correctly the first time: a clean __manifest__.py, models in models/, views in views/ split by record type, security in security/ir.model.access.csv plus record rules, data in data/, demos in demo/, tests in tests/. Every model gets _description, _order, _sql_constraints where appropriate, and at minimum a unit test on the constraint. Engineering-led teams ship modules that read like Odoo's own — because that is the codebase they will be migrated against. Pattern in custom module development.
Performance — Query Planner Mastery and Indexing Strategy
Custom modules become performance problems exactly when the data grows past dev. The fix is not to throw hardware at it — it is PostgreSQL query planner mastery. Run EXPLAIN ANALYZE on every slow ORM call your module makes; add index=True on every field that filters or joins; create composite indexes for the multi-field WHERE clauses Odoo's ORM generates; profile with the Odoo SQL log in production. The engineering-led plant ships a custom module with two B-tree indexes thought through up front; the average plant ships the same module and adds three indexes a year later under fire. Walk-through in mastering the Odoo query planner.
How to Evaluate an Odoo Partner Without Getting Burned
The features matter; the partner shipping them matters more. Eight checks separate the partners who deliver from the ones who learn on your budget:
- Official Odoo certification (Ready, Silver, or Gold) — not just "we work with Odoo".
- Discovery-call person is the build person. Account-manager handoffs lose scope.
- Fixed-price scope after discovery. Time-and-materials is a budget vacuum on ERP work.
- Senior engineers on the project. Octura runs seniors only — ask any prospective partner who actually writes your code.
- Two reference customers willing to take a call. "We have many clients" without a name is a red flag.
- Vertical specialism in manufacturing. A generalist who ships one plant a quarter is not the right partner for a plant project.
- Documented multi-phase methodology. Discovery → configuration → customization → migration → go-live → hyper-care.
- Transparent published rates. "Custom quote" is fine; refusing to share a starting number is not.
The longer version is in the Odoo partner audit.