Expenses & cost tracking
Where every O&M dollar lands - automatic cost posting from work orders, expenses, purchase orders, invoices, and budgets - building each asset's total cost of ownership.
Cost data in AssetLab is a by-product of doing the work, not a separate bookkeeping chore. If work orders are closed honestly, the spend picture assembles itself - and what it assembles into, asset by asset, is Total Cost of Ownership (TCO): what a thing really costs over its life, not just what it cost to buy.
How costs enter the system
| Path | What it captures |
|---|---|
| Work order completion | Labour hours × rates, parts consumed, contractor amounts - posted to the asset automatically |
| Expenses | Costs not tied to a single work order (utilities allocations, one-off purchases) |
| Purchase orders | Committed spend - parts restocks, contracted purchases - tracked from issue to receipt |
| Invoices | The billed reality, linkable to POs and projects |
| Manual asset costs | Historical or external cost events entered directly on an asset |
Every cost event carries a cost category (labour, materials, contract, utilities…) - the editable catalog that gives spend reports their rows.
What completion actually posts
When a work order completes, the total of its actual cost, parts cost, and labour posts automatically - but only when that total is greater than zero, so a zero-cost close leaves no noise in the ledger. The total is split evenly across every asset linked to the work order: a $600 job on three assets posts $200 to each. The category is inferred from the work order's type, or from a name match on its work category - so "Plumbing Repair" work lands under the right report row without anyone tagging it.
Labour rates
Labour converts to money through hourly rates: each user can carry an effective-dated rate, with a tenant default for everyone unrated. Administrators manage both under Settings → Labour rates. Rate changes take effect from their date forward - a work order completed last year keeps last year's rate, so historical costs never rewrite themselves.
At completion, the work order's hours are split evenly across its assignees, and each share is costed at that person's rate in force on the completion date (the tenant default where they have none). Rates are compensation data: the per-person breakdown is visible to Managers and above.
Where costs roll up
A cost lands on an asset and is immediately visible:
- On the asset's cost history - the lifetime O&M story, next to its replacement value
- By location - building and site totals (hierarchy)
- By system class - "what does HVAC cost us portfolio-wide?"
- On the dashboard - trend, variance, and category breakdowns
Total cost of ownership
The point of all this capture is TCO. An asset's cost history - acquisition, every repair, every PM visit, parts, contractor calls - accumulated against its replacement value turns gut-feel questions into arithmetic:
- Repair or replace? An asset burning 40% of its replacement value in repairs every year makes its own replacement case.
- Which make lasts? Lifetime cost by manufacturer or asset type is a filter, not a debate - and it sharpens the next tender's evaluation.
- What does ownership actually cost? Budget submissions grounded in "this building's mechanical plant costs $X/year to operate" survive scrutiny that estimates don't.
TCO only works if capture is habitual - which is why costs ride along with work order completion instead of living in a separate ledger someone has to remember to feed.
Budgets
Annual funding budgets are set per year, per funding source, and per module (organization-wide, facilities, or infrastructure), and the dashboard's budget tab tracks actuals against them through the year - see Budget. Capital project budgets are separate and richer - see Budgets & financials.
Currency
All money displays in your organization's configured currency (organization settings) - including exports and reports.
Habits that keep the data honest
- Costs at completion, every time. A 30-second estimate beats a blank; blanks compound into "we have no idea what this building costs".
- Use categories consistently - five clean categories outperform twenty vague ones.
- Don't double-post. If a contractor invoice is entered against the work order, it doesn't also go in as a standalone expense.
Programmatic access
invoices:read/write, purchase_orders:read/write, plus asset-cost tools on the REST API and MCP.