Built a full demo against a real BuildEase instance and three documented facts turned out to be wrong, each costing a debugging round. buildease installs nothing. Its manifest depends on base alone, so the "depends on nothing and installs the set" line left an empty database with no error to catch it. Route and install every module explicitly. The purge chain had invoices after statements. An invoiced sale.progress refuses action_cancel outright -- cancelling its invoice is what reverts it to approved, the first state it can be cancelled from. The documented order deadlocks on the one statement you invoiced. custom_product_sale, custom_product_bom and bom_on_sale_order_line are absent from mev but present on the Callista demo servers, so "not in the repo" is not the same as "not installable" when pricing. Also records the revision-formula object graph, which no reference covered: the coefficients live on formula.input, not on revision.formula, and that model hangs off either the take-off (contract S, I) or the statement (that period's s, i). That split is what makes "de index van die maand, niet van vandaag" work. Its rows come from an @api.onchange that write() never fires over XML-RPC, and a stale initial_index_value computes a plausible but wildly wrong revision with no guard behind it -- a factor of 65 instead of 1.005 in this build. Plus: percentage is a cumulative fraction not 0-100, index_value truncates to 3 decimals, and button methods return an action dict Odoo cannot marshal over XML-RPC after the transition has already committed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
153 lines
8.0 KiB
Markdown
153 lines
8.0 KiB
Markdown
---
|
|
name: buildease-demo
|
|
description: BuildEase (callista-tools/mev) construction overlay for the callista-odoo-demo skill. Routes the client's pains onto the 34 BuildEase Odoo 19 modules before any custom work is considered, replaces the generic teardown with the take-off → progress-statement chain, and keeps the per-client dataset instead of the old buildease_demo_data bundle. Use for "BuildEase demo", "QTO demo", "quantity take-off demo", "construction Odoo demo", "vorderingsstaat demo", or a follow-up after one.
|
|
---
|
|
|
|
# BuildEase Demo
|
|
|
|
A **vertical overlay** on `callista-odoo-demo`. That skill owns the pipeline — discovery
|
|
brief, build, test, purge, sales docs, follow-through. This one supplies the five things
|
|
that are specific to construction, and nothing else.
|
|
|
|
**Requires** `callista-odoo-demo` installed at `~/.claude/skills/callista-odoo-demo/`
|
|
(Callista's fork of Smetools/odoo-demo-architect). If it is missing, say so and stop —
|
|
do not reimplement its XML-RPC connector, data builder, or pipeline here.
|
|
|
|
> Do **not** substitute an `odoo-demo-architect` install for it. That is upstream, without
|
|
> Phase A's source-agnostic discovery, without Phase C, and without the extension points
|
|
> this file plugs into.
|
|
|
|
**Run `callista-odoo-demo` and apply the overlays below at the named steps.** Everything
|
|
not listed here is that skill's job — follow it as written.
|
|
|
|
---
|
|
|
|
## Overlay 1 — Module routing
|
|
|
|
*Applies at:* **Install modules**, and Phase A's `## Phase 1 scope`.
|
|
|
|
Read `reference/buildease.md` and route the client's pains onto BuildEase modules using
|
|
its pain → module table. Match on **the client's own words** — the table is keyed on what
|
|
they actually say ("we measure in Excel then re-type it into the quote"), not on module
|
|
names they will never utter.
|
|
|
|
Install the routed set **explicitly**, module by module. `buildease` is a marker whose
|
|
manifest depends on `base` alone — it installs none of the other 33, so installing it and
|
|
stopping there leaves an empty database and no error to catch it. Install it alongside the
|
|
routed set if you want the marker; never instead of it.
|
|
|
|
Verify afterwards: read back `ir.module.module` state for every routed name and fail loudly
|
|
on anything not `installed`. `button_immediate_install` also dies on a transient
|
|
`ir_cron` row lock (`LockNotAvailable`) when a cron is mid-run — back off and retry, it is
|
|
not a real failure.
|
|
|
|
## Overlay 2 — Solution precedence
|
|
|
|
*Applies at:* **Research native-vs-custom**.
|
|
|
|
The precedence becomes **BuildEase → native Odoo 19 → custom**, in that order. Most
|
|
construction pains are already solved in mev; custom work is the last resort, and native
|
|
Odoo is the middle tier, not the first question.
|
|
|
|
Odoo 19 only — every mev manifest is `19.0.x`. Do not attempt this against 17 or 18.
|
|
|
|
## Overlay 3 — Demo data policy
|
|
|
|
*Applies at:* **Load demo data**.
|
|
|
|
**Do not install `buildease_demo_data` or `buildease_demo_data_sale_progress`.** They are
|
|
the previous generation of environment setup: one fixed Belgian construction dataset, the
|
|
same for every prospect, dragging in `l10n_be` and `accountant` whether or not the client
|
|
is Belgian. The per-client dataset generated from the discovery brief replaces them — the
|
|
client's own partners, articles, projects and orders, staged so each hero has a record to
|
|
fire on.
|
|
|
|
Install them only if the user explicitly asks for the generic sandbox. The app-level
|
|
dependencies that bundle used to drag in (`sale_management`, `project`, `purchase_stock`,
|
|
`sale_timesheet`, `industry_fsm`, `accountant`, `uom`) still need installing — route them
|
|
from the pain table, not from the demo bundle.
|
|
|
|
**Read `reference/buildease_demo_data.md` before writing the staging script.** It carries
|
|
the QTO → sale order → project → progress statement → invoice object graph from mev source:
|
|
required fields per model, creation order, which transitions are button methods rather than
|
|
writes, and the seven guards that will otherwise stop the chain mid-build.
|
|
|
|
`scripts/build_demo.py` is a per-engagement template, not an engine — it knows nothing about
|
|
take-offs, and it ignores config keys it doesn't recognise. Adapt it; do not assume a
|
|
BuildEase-shaped config will drive it.
|
|
|
|
## Overlay 4 — Purge chain
|
|
|
|
*Applies at:* **Purge test residue**, replacing the generic chain.
|
|
|
|
```
|
|
transient wizard rows → invoices (draft → cancel → unlink)
|
|
→ statements (cancelled only, newest first) → timesheet lines → tasks
|
|
→ projects → sale orders → take-offs → the partner
|
|
```
|
|
|
|
The generic traps still apply. These are the BuildEase-specific ones, each of which cost
|
|
a debugging round:
|
|
|
|
- **Invoices go before statements.** An `invoiced` `sale.progress` refuses `action_cancel`
|
|
outright; cancelling its invoice is what reverts it to `approved`, the first state it can
|
|
be cancelled from. Statements-then-invoices deadlocks on the one statement you invoiced.
|
|
- **Cancel before deleting, on all three.** `unlink()` refuses unless `quantity.take.off` is
|
|
`cancel`, a QTO-linked `sale.order` is `cancel`, and `sale.progress` is `cancelled`.
|
|
- **Guard each step separately and loop until a pass keeps nothing.** One `try` around
|
|
draft → cancel → unlink lets a raise on an already-draft invoice skip the unlink beneath
|
|
it, and the purge then reports success over residue.
|
|
- **Button methods return an unmarshallable action dict** over XML-RPC (`Fault` mentioning
|
|
`Marshal`/`dumps`). The transition already committed — catch it and move on. Retrying
|
|
fails on a state guard and reads like a real error.
|
|
- **Deleting the take-off deletes its sale order** — `quantity.take.off.unlink()` unlinks
|
|
`sale_order_ids` first. The take-off is the handle for both.
|
|
- A take-off with **no** sale order still cancels and deletes normally: call `cancel()`, which
|
|
writes the state directly and no-ops on the empty order. No convert-to-quotation dance.
|
|
- **Statements cancel newest-first only** — `action_cancel` refuses unless it is the last one,
|
|
and `action_draft` refuses if a newer statement exists.
|
|
- Leftover `add.dynamic.article.template.line` rows pin take-offs. Clear them first.
|
|
|
|
Full field-level detail, including the guards, is in `reference/buildease_demo_data.md`.
|
|
|
|
## Overlay 5 — Follow-through framing
|
|
|
|
*Applies at:* **Phase C**.
|
|
|
|
Where an objection is already covered by BuildEase, name the **module and the screen** on
|
|
the objection sheet — "that's `sale_progress_revision_formula`, on the statement's Revision
|
|
tab" lands better than "yes, we support that". Where mev does not cover it, say so and give
|
|
the workaround or the build estimate.
|
|
|
|
Check the scoped quote against `reference/buildease.md`'s gotchas before pricing:
|
|
`custom_product_sale`, `custom_product_bom` and `bom_on_sale_order_line` are **not in the
|
|
mev repo**, so anything under `buildease_custom_product*` is not a "just install it" line.
|
|
|
|
---
|
|
|
|
## BuildEase-specific checks
|
|
|
|
- After installing, **walk Settings once**. `res.config.settings` and `res.company` are
|
|
extended by 8 modules each and several BuildEase behaviours default to off.
|
|
- At the staged-numbers sanity check: **booked hours well under ordered hours**. Over 100%
|
|
makes the progress statement look wrong on screen even when every assertion passed.
|
|
- The spine of every BuildEase demo is QTO → sale order → project → progress statement →
|
|
invoice. If that chain breaks mid-demo you lose the deal, so it is the chain **Test
|
|
heroes** must exercise end to end.
|
|
- `quantity.take.off` inherits `mail.thread` + `mail.activity.mixin` — chatter and
|
|
activities work for free. Cheap demo beats.
|
|
|
|
## Guardrails
|
|
|
|
- Never claim a BuildEase feature works without having seen it work in the demo DB.
|
|
- Never invent a pain quote. `(inferred)` is fine; a fabricated quote read back to the
|
|
client in the demo is not.
|
|
- If something you need is not one of the five overlays above, that is a gap in
|
|
`callista-odoo-demo` — fix it there, so the next vertical gets it free. Do not work
|
|
around it here.
|
|
|
|
## Files
|
|
|
|
- `reference/buildease.md` — the module map, the pain → module routing table, and the mev
|
|
gotchas. Read it at Phase A.
|