← Back to work
2021 · Odoo 11 platform · metadata configurator

Wood

A French Odoo 11 platform for Wood, a pool-equipment supplier — built around a metadata-driven product configurator that lets customers spec a pool through a dynamic questionnaire whose entire shape is rows in the database.

Role
Implementation · long-running maintenance
Duration
Since 2021, ongoing
Team
1 Hazenfield engineer
PROJECT HERO · PLACEHOLDER
FIG. 01
Context

Wood is a French pool-equipment supplier. Their Odoo 11 platform runs the catalogue and the order pipeline — and at its heart, a metadata-driven product configurator that lets customers spec their pool through a dynamic questionnaire whose entire shape is rows in the database.

The configurator is the interesting part. `product.abstract` is the top-level template; `config.block`, `config.fieldset`, `config.question` and `config.question.value` describe the form's shape; `config.condition.*` rows hold the visibility and validation rules as strings, evaluated at runtime; `config.controller` rows wire questions together; `config.global.value` rows hold form-level computed values. `product.abstract.extract()` serialises the whole tree into JSON; a jQuery widget reconstructs the form on the frontend; `sale.order.create_from_vals()` reads it back.

The arrangement gives Wood a configurator they can grow without us — new questions, new conditions, new computed values, all admin-side. It also concentrates business logic in `eval()`-evaluated strings, which is the part that strains as the form expands. We've documented an eight-phase plan in `docs/configurator.md` to move from DB-metadata-driven to code-driven configuration; the plan is there for when the work is ready.

We've been on the platform since 2021. The cadence is light — a handful of commits a year, mostly configurator extensions, occasional invoicing and stock module work, the Dropbox backup integration. Odoo 11 is well past mainstream support; Wood's choice to stay on it is deliberate, and our job is to keep the platform stable on a version the rest of the world has moved past.

Scope

What we built.

nembia_sale01

Core: the configurator data model, quote / order logic, pricing through composition formulas.

nembia_base02

Shared base extensions used by every nembia_* addon.

nembia_invoice03

Invoice customisations with French localisation.

nembia_stock · nembia_stock_sms04

Stock management with SMS notifications for stock events.

nembia_sav05

After-sales service: tickets, follow-up, history.

nembia_web06

Web controller extensions backing the public-facing pages.

dropbox_backup07

Dropbox-backed nightly backups (credentials gitignored).

Configurator runtime08

`product.abstract.extract()` serialises the form tree; the jQuery widget reconstructs the UI; `sale.order.create_from_vals()` reads the answers back.

docs/configurator.md09

Eight-phase migration plan from metadata-driven to code-driven configuration — written when we hit the architecture's ceiling, kept in the repo for the day it becomes the work.

Approach

What the work looked like, in three pieces.

01

A configurator the admin can shape

The customer's pool-spec questionnaire is rows in the database, not lines in code. New questions, new visibility conditions, new computed values — all admin-side. We pay for that flexibility with `eval()`-evaluated condition strings; we earn it with a configurator Wood can grow without us.

02

Long-tail stewardship on a legacy stack

Wood runs on Odoo 11, well past mainstream support. The client's choice to stay there is deliberate — the configurator and the business logic that's built around it. Our job is to keep the platform stable on a version the rest of the world has moved past. The cadence is small; the platform is always reachable.

03

Eight-phase migration plan, documented

We know the configurator's complexity has a ceiling. `docs/configurator.md` lays out an eight-phase plan to move from DB-metadata-driven to code-driven configuration — what we'd change, in what order, and what we'd validate at each step. The plan exists for when the work is ready, not before.

Engineering highlights

A handful of the solves we are proudest of.

01

Runtime-evaluated visibility conditions

Question visibility and field validation live as strings in `config.condition.*` rows, evaluated via `eval()` at runtime. The flexibility is the point; the evaluator is sandboxed to known names so a malformed condition can't break the form.

02

Backend-defined, frontend-reconstructed forms

`product.abstract.extract()` serialises the entire configurator tree into JSON. The jQuery frontend reconstructs the form UI from that payload — visibility, dependencies, computed totals. The backend stays the source of truth; the frontend stays disposable.

03

Order composition from formulas

Pricing comes out of `product.abstract.composer` — composition formulas that read the customer's answers and produce line items. New product variants don't require new code; they require a few new rows in the composer model.

Outcomes

A few shapes, in their raw form.

5 yrs
Maintained since 2021
Odoo 11
Legacy stewardship, stable
Metadata
Configurator that grows admin-side
End-to-end
One Hazenfield engineer

Stack
Odoo 11PythonPostgreSQL 10jQueryDockerDropbox APIPandas

Have a project that deserves this kind of care?

Start a conversation