Application Overview

What Plant & Equipment Asset Management models, and the ideas behind it


Core Operating Chain

Organisation → BusinessUnit / Depot / Person / Supplier      (parties and structure)
AssetClass → Asset                                           THE EQUIPMENT
  Asset → AssetComponent (self-nesting) · AssetAssignment
  BusinessUnit / Depot / Person → Asset

UTILISATION
  Asset → UsageEntry                             (productive / standby / travel hours)
  Asset → MeterReading                           (validated hour / km readings)
  Asset → AvailabilityEvent                      (breakdown · planned · unplanned)
  Asset → FuelTransaction

CONDITION
  AssetClass → InspectionTemplate → InspectionItemTemplate   (the checklist)
  Asset / InspectionTemplate → Inspection → InspectionResponse
    InspectionResponse → Defect                  (a failed item raises a defect)
  Asset / AssetComponent → Defect                (severity restricts the asset)

RESPONSE
  Asset / Defect → WorkRequest                   (a request for action)
  WorkRequest / Asset / AssetMaintenancePlan → WorkOrder      (the planned job)
    WorkOrder → WorkOrderTask                     (the steps)
    WorkOrder → LabourEntry                       (hours booked)
    WorkOrder → PartIssue ← InventoryItem / StoreLocation

STORES & PURCHASING
  Depot → StoreLocation ; InventoryItem / StoreLocation → InventoryBalance
  PurchaseRequisition → PurchaseRequisitionLine · Quote       (three-quote control)
    PurchaseRequisition / Supplier → PurchaseOrder → PurchaseOrderLine
      PurchaseOrder → GoodsReceipt → GoodsReceiptLine
      PurchaseOrder / Supplier → SupplierInvoice              (matched within tolerance)

COST & LIFECYCLE
  Asset / WorkOrder → CostTransaction            (labour · part · fuel · external…)
  Organisation → Budget ; Asset / AssetClass → HireRate
  Asset / AssetClass → Risk
  RenewalProgram → RenewalCandidate ← Asset      (scored: condition · age · use · cost · risk)
  Asset / RenewalCandidate → Disposal            (sale proceeds recorded)

PEOPLE & GOVERNANCE
  Person → OperatorLicence · OperatorCompetency · TrainingRecord
  ServiceLevel → PerformanceResult
  Audit → AuditFinding → ImprovementAction
  Organisation → Approval · IntegrationMessage · Evidence

Key Concepts

Everything accumulates against the one asset. The spine of the model is the Asset, and its whole-of-life record — acquisition and replacement cost, carrying amount, utilisation against target, availability, condition grade, meter, and every cost transaction — lives on that single record. The demo carries the lifecycle end to end for the hero asset, motor grader HP-001: a pre-start inspection raises a hydraulic-leak defect, the defect drives a work request and work order, labour and a part are booked, cost transactions accumulate, a risk is registered, and the renewal program scores the grader for a future replacement. You can read that chain in either direction from any point.

Condition drives work, not the calendar alone. A Defect can originate from a templated Inspection (a failed InspectionResponse links the defect), from an operator observation, or from telemetry. A MAJOR or CRITICAL defect restricts the asset — in the demo the grader's availability_status is set to RESTRICTED and an operating_restriction is recorded until the repair closes. Preventive work is separate: an AssetMaintenancePlan ties a MaintenanceTemplate (250-hour service, 10,000 km service, annual registration) to an asset and carries the next-due date and meter.

Work finishing is not the defect closing. A WorkOrder records the planned and actual start/finish, meter at start/finish, labour hours, downtime and a completion summary, and is quality-checked and closed by (usually) a different person from the mechanic who did the work. Only when the work order completes does the demo mark the linked Defect as REPAIRED and return the asset to AVAILABLE — the effect the pack's WorkOrderCompletion rule describes, applied by the seed rather than enforced.

Purchasing carries its controls. The demo's requisition REQ-00088 is over the $10,000 three-quote threshold, so three Quote rows are compared and one is selected; it converts to purchase order PO-00104, which is receipted in full (GRN-00061) and matched to supplier invoice INV-77321 within the 2% tolerance (status MATCHED, not EXCEPTION). Segregation of duties is visible in the data: the storeperson raises the requisition, the fleet manager approves it, the procurement officer buys, and the finance officer approves the invoice.

Accountability is separable by design. Wherever a decision needs a second person the schema gives it its own column, and tab_config.yaml labels every role so a Person page reads them as distinct facts: a defect is reported_by and closed_by; a work request is requested_by and approved_by; a work order is supervised, quality_checked_by and closed_by; labour is booked by a person and approved_by another; an approval separates requested_by from approver.

The renewal decision is scored, not age-only. A RenewalCandidate carries a condition_score, age_score, utilisation_score, maintenance_cost_score and risk_score that roll into a total_priority_score, plus estimated replacement cost, estimated sale proceeds and the net funding requirement. In the demo the grader scores 66 and is retained to FY2028/29; the unserviceable push mower scores 82 (priority replacement) and is disposed by public auction the same year.

References are stored, live feeds are not. The boundary carried over from the source plan: payroll, the full general ledger, an electronic tender portal, live telematics ingestion, insurance claims and registration-authority integration stay in their source systems. IntegrationMessage and the source_system / source_reference / external_reference columns carry the handles — the hub stores decisions, costs, evidence and outcomes, not the live feeds.

What Is Phase 2

The proforma pack ships workflows {} (defect-to-repair, purchase-to-pay and renewal-and-disposal state machines), rules {} (meter non-reversal, critical-defect auto-restrict, three-quote control, invoice matching, disposal approval, operator authorisation), derived {} (age, utilisation %, maintenance cost YTD, availability %, lifecycle cost, hire-rate build-up), reports {}, dashboards {}, roles {} and permissions {}. None of that is enforced by the schema — the demo data is consistent with those rules rather than validated against them, and the reference numbers (WR-#####, WO-#####, REQ-#####, PO-#####, GRN-#####, DISP-#####) follow the masks by hand. Derived values are stored numbers the seed sets, not roll-ups.

See the header of apps/uralla/schema/uralla.dsl for the full translation record. In summary: the pack's block-style DSL was hand-translated to the native table … { field Type [...] } dialect; uuid ids became Int and the framework provides ids, timestamps, soft delete and audit history; Decimal/money became Float and date became DateTime; the top-level enums {} became inline [enum: …] lists (UPPERCASE); tables were reordered so every foreign key points backward (two true cycles were broken — BusinessUnit.manager_person_id and WorkRequest.work_order_id were dropped); and six short display columns were added or renamed (Person.name, Supplier.name, Defect.name, WorkRequest.name, WorkOrder.name, ImprovementAction.name) so list views show a readable label instead of a whole description paragraph.