# BuildEase (callista-tools/mev) — module map & pain routing Odoo **19.0** vertical for construction / contracting. Repo: `git@github.com:callista-tools/mev.git`. 34 modules, all LGPL-3. **`buildease` is a marker, not an installer.** Its manifest depends on `base` and nothing else, so installing it pulls in none of the other 33. Verified on a live 19.0+e instance: `buildease` on its own leaves the database empty and every routed feature missing, with no error to catch it. Always install the routed set explicitly. ## The four core concepts | Concept | Model | What it replaces at the client | |---|---|---| | **Quantity Take-Off (QTO)** | `quantity.take.off`, `.line`, `.line.calculation` | The measurement/estimating spreadsheet that gets re-keyed into a quote | | **Sale Progress** | `sale.progress`, `sale.progress.line` | Monthly progress statements (BE: *vorderingsstaat*) and % -complete invoicing | | **Adjustments** | `adjustment.create` + QTO/SP extensions | Variation orders / change orders (BE: *verrekeningen*) | | **Revision formula** | `revision.formula`, `revision.scheme`, `revision.parameter`, `index.value.date` | Contractual price-indexation formulas on progress statements | A QTO holds lines; lines hold *calculation* lines (the measurement math). QTO → sale order → project → progress statements → invoices is the spine of every demo. ## Pain → module routing Match the client's own words on the left; install the right. | Client says | Install | |---|---| | "we measure in Excel then re-type it into the quote" | `quantity_take_off_base`, `quantity_take_off_sale` | | "every project starts from the same standard items" | + `quantity_take_off_base` template sets (`quantity.take.off.line.template.set`) | | "the same item recalculates from a few parameters" | `quantity_take_off_dynamic_calculation` | | "we add a % for general costs / site overhead" | `quantity_take_off_overhead` (+ `_dynamic_calculation_overhead` if both) | | "we invoice monthly on % complete" / "vorderingsstaat" | `sale_progress_base` | | "prices are indexed per the contract formula" | `sale_progress_revision_formula` | | "extra work / change orders are a mess" | `adjustments_base` (+ `sale_progress_revision_formula_adjustments` if both) | | "hours worked must land on the progress statement" | `sale_progress_base_timesheet`, `adjustments_base_timesheet` | | "subcontractors send us their own progress statements" | `sale_progress_purchase` (`subcontractor.progress.statement.wizard`) | | "we ask 3 suppliers for prices per item" | `quantity_take_off_purchase` (`purchase.request.wizard`, uses `purchase_requisition`) | | "made-to-order items priced from their bill of materials" | `buildease_custom_product`, `buildease_custom_product_bom_price_sync` (+ `_overhead`) | | "the client has to sign off" | `quantity_take_off_sale_signature`, `sale_progress_base_signature` | | "plans and datasheets must be on the site project" | `project_product_documents_link` | | "we track material deliveries to site" | `quantity_take_off_sale_stock`, `_sale_delivery` | | "one project, many purchase orders" | `quantity_take_off_sale_project_purchase`, `_project_stock` | | "our techs do call-outs / maintenance visits" | `quantity_take_off_sale_industry_fsm` | | "recurring maintenance contracts" | `quantity_take_off_sale_subscription` | | "estimates start from a lead" | `quantity_take_off_sale_crm` | | "supplier article numbers differ from ours" | `quantity_take_off_extra_article_nr` | | "same item in several sizes/finishes" | `sale_quantity_takeoff_variant` | | "management wants margin per project" | `sale_progress_quantity_take_off_report` (QTO carries `margin`, `margin_percentage` natively) | | "we live in spreadsheets" | `quantity_take_off_spreadsheet` | ## Demo data — `buildease_demo_data` is the OLD way **Do not install `buildease_demo_data` or `buildease_demo_data_sale_progress` by default.** They are the previous generation of environment setup: one fixed Belgian construction dataset, the same for every prospect. This skill replaces them — demo data is generated per client from the discovery brief and loaded through `callista-odoo-demo`'s `scripts/build_demo.py` / `demo_config.json`. Install them only if the user explicitly asks, or when there is genuinely no client context and a generic sandbox is wanted. If you do, know what comes with them: `sale_management, purchase_stock, project, timesheet_grid, sale_timesheet, maintenance, quantity_take_off_sale, industry_fsm, l10n_be, accountant, uom` — including the Belgian localisation, which is wrong for most non-BE clients. The app-level dependencies that dataset used to drag in (`sale_management`, `project`, `purchase_stock`, `sale_timesheet`, `industry_fsm`, `accountant`, `uom`) still need installing on their own — route them from the pain table above, not from the demo bundle. ## Gotchas - **Three dependencies are not in this repo**: `custom_product_sale`, `custom_product_bom`, `bom_on_sale_order_line`. Anything under `buildease_custom_product*` fails to install without them. Confirm their source before promising a BOM-pricing hero feature. **Not in the repo does not mean not on the instance.** On the Callista demo servers all three are present and installable — they ship with the `demo19-custom` addons path, not with mev. Check the target instance (`ir.module.module` by name) before pricing `buildease_custom_product*` as build work; on a server that already has them it is a install line, and on a client's own Odoo.sh it is not. - **Odoo 19 only.** Manifests are all `19.0.x`; do not attempt against 17/18. - `l10n_be` and `accountant` are pulled in by demo data — the demo DB is Belgian-localised. Wrong-country client → set `demo_config.json` company/fiscal position explicitly, or skip `buildease_demo_data` and stage minimal data instead. - `quantity.take.off` inherits `mail.thread` + `mail.activity.mixin` — chatter and activities work for free, good cheap demo beats. - `res.config.settings` and `res.company` are extended by 8 modules each. After installing, walk Settings once; several BuildEase behaviours are off by default. - `post_migrate.py` sits at repo root — relevant when upgrading an existing demo DB, not a fresh build.