Twenty to twenty-five quotations a month, each one a copy of the same workbook, each one about half a day. The estimating logic was sound — it just lived somewhere nobody could govern.
One Excel file per quotation, copied from the last one, versioned by filename.
About half a day of work per quotation, 20 to 25 times a month.
Rates lived inside each copy — so a rate change never reached the copies already out.
No way to tell which version a customer was actually holding.
Final review happened over email, outside any system that recorded it.
Drawings were produced separately, by hand, from the same numbers.
The spreadsheet was not wrong. It was un-auditable, un-versioned and un-shareable.
The workbook's calculation was rebuilt as a pricing engine — with the original spreadsheet cell references kept in the code comments. Any figure the system produces can be traced back to the cell it came from, so the client's own engineers can audit the port against the workbook they already trust. That decision is what made adoption possible.
Drafts save continuously and can be edited freely. Issuing a quotation freezes the payload, the computed totals, and which rate card priced it. Changing rates later never moves the numbers on a document already sent. Correcting an issued quotation means issuing the next revision, which is what the paper process always implied but could not enforce.
The owner's email sign-off became a role in the system: preparers can create and edit everything, only approvers can issue. Drawings generate from the same geometry that priced the job, so the picture and the price cannot drift apart.
Pricing runs in two places. The browser recalculates on every keystroke, so the estimator sees numbers move as they type with no round trip. The server holds the authoritative version — the figures frozen into an issued quotation and printed on the document.
The obvious risk is drift: two implementations of the same arithmetic, and one day a user sees one number on screen and a different one on the printed quotation. That is a quiet, expensive class of bug.
"Don't rely on remembering to update both. Make forgetting fail the build."
So the build extracts the live pricing function out of the front end and runs both engines over twenty tank configurations — every shell type, closure, override and accessory combination — comparing price, weight, thickness and load. Change one without the other and the test suite fails. Eighty-one tests run before any deploy, including tests against the real interface in a headless browser.
One of those tests exists because of a specific bug: a save from the drawing screen once persisted stale values while reporting success. Silent data loss dressed as a green tick is the worst failure mode there is, and it is now pinned by a named regression test.
| Metric | Before | After |
|---|---|---|
| Where the logic lives | Inside every copied workbook | One engine, versioned and tested |
| Rate changes | Never reached copies already out | Central rate card; issued documents keep the card that priced them |
| Which version is live | Filename convention and memory | Immutable revisions |
| Approval | Email, outside the system | Enforced role — only approvers issue |
| Drawings | Produced separately by hand | Generated from the same data that priced the job |
| Confidence in the numbers | Trust in the workbook | 81 tests, plus cell-level traceability to the original |
Status: built and in acceptance testing with the client's engineers validating the pricing port against known quotations. Time-per-quotation figures will be measured once it is live rather than estimated now.
"AI built this system. It doesn't run it — and it consumes nothing in operation."
The build was done with AI coding agents throughout. The shipped product contains no model, makes no inference call, and costs nothing per quotation to run. A price is arithmetic with a right answer, and the client's engineers need to check it against a workbook they already trust. A model in that path would add cost and remove certainty.
Where AI is going next is the input edge, not the calculation: taking scope from a phone call or an email thread and turning it into a structured enquiry the estimator can confirm. That is a genuine language problem, where being approximately right and asking a human to check is exactly the correct behaviour. The pricing underneath stays deterministic.
Where a spreadsheet has become the system of record and nobody dares change it. The migration is not a rewrite — it is a port that stays traceable to the original.
Products with dimensions, options and accessories priced from rules. Immutable revisions matter as soon as a quotation becomes a contract.
Anywhere you may be asked how a figure was calculated eighteen months later, and the honest answer must not be "whatever the spreadsheet said at the time".
Agencies and professional services quoting from a rate card, where the card changes but historic quotations must stay exactly as issued.
90-minute AI Opportunity Audit. No pitch — just findings you can act on.