Schedule of Rates
A subcontractor contract’s Schedule of Rates is a set of pre-agreed unit-rate items that define what the subcontractor will be paid for each type of work they perform. The step lives in the Contract Builder alongside Classifications and Equipment Rates — it does not replace them.
Where it fits in the contract editor
Subcontractor (agreement_type = subcontractor) contracts share the same editor flow as labour-hire contracts, with one additional step:
| Step | Name | Notes |
|---|---|---|
| 1 | Ordinary Hours | Shared with labour_hire / plant_hire. |
| 2 | Classifications | Shared with labour_hire. |
| 3 | Equipment Rates | Shared with labour_hire. |
| 4 | Schedule of Rates | Subcontractor-only. Backed by contract_scheduled_items. |
| 5 | Cost Allocation | Shared; gains scheduled_item as a root entity type. |
What a scheduled item is
Each item in the schedule represents a distinct scope element — an earthworks cut, a concrete pour, a structural steel erection activity, or any other defined unit of subcontract work.
| Column | Required? | Notes |
|---|---|---|
| Name | Yes | Free text, case-insensitive unique within the contract (≤ 255 chars). |
| Description | No | Multi-line specification or scope notes. |
| Meter type | Yes | One of shift-duration, engine-hours, km, metres, loads, custom. Drives the pricing engine’s rate calculation. |
| Custom unit label | Cond. | Required when meter_type = custom. Displayed on the docket line (e.g. m³, tonne, panel). |
| Base rate | Yes | Per-unit dollar rate (NUMERIC(14,4), non-negative). |
| Minimum engagement | No | Floor quantity billed per docket line. When entered_qty < minimum_engagement, the engine bills the minimum. |
| Monthly minimum SMU | No | Contractual monthly floor (informational; priced in the SMU-reconciliation pass). |
| Pro-rata formula | No | Free text; stored verbatim on the row. No formula validation. |
Global overtime and penalty rules (configured on the contract or award) apply at pricing time — scheduled items ride the same 8-stage engine as equipment rates.
Authoring inline
Click + Add item on the Schedule of Rates step header to open the inline row editor. Fill in the columns, save, and the row appears immediately. Rows can be edited in place (click the row) or deleted (row action → Delete).
Bulk import (CSV / XLSX)
Supplier rate schedules are often large. The step ships the same bulk-import drawer as the Equipment Schedule:
-
Formats:
.csv,.xlsx(≤ 10 MB). Parsed server-side; the drawer renders a per-row preview before commit. -
Template: click Download template for a CSV with the exact header row:
name,description,meter_type,custom_unit_label,base_rate,minimum_engagement,monthly_minimum_smu,pro_rata_formula -
Validation:
meter_typemust be a known value;custom_unit_labelis required whenmeter_type = custom; negative rates and case-insensitive name duplicates surface as red pills. Valid rows are shown in green. -
Semantics: append-only, partial-import — valid rows are committed even when some rows fail. Failed rows can be downloaded as CSV for fix-in-place.
-
Guard: the import endpoint is subcontractor-only server-side. Posting the scheduled-items template to a labour_hire or plant_hire contract returns
400.
Import from rate source
Click Import from rate source on the step header. This copies the supplier’s active supplier_payment_method_lines for this contract’s project into the Schedule of Rates — the same mechanic as the Equipment Schedule Import for labour_hire contracts.
- Each line’s
description(falling back tocode) becomes the item name; the lineratebecomesbase_rate. - You pick a default meter type applied to every imported row, then confirm.
- Same dedupe and append-only semantics as file upload.
- The
link_project_idis resolved server-side from the contract — the request carries no client-supplied IDs. This is a deliberate zero-trust boundary (see Equipment Schedule Import — Security note).
After a successful import, refreshContractMatches runs automatically so the new rows appear immediately as allocation rows in the Cost Allocation step.
Cost Allocation step
After saving the Schedule of Rates, the editor’s Cost Allocation step gains scheduled_item rows alongside any classification and equipment-rate rows already present. Allocation works identically:
- Rows are scheduled items; columns are
supplier_payment_method_lineentries on the supplier-link-project. - Click a cell to bind; confirm to flip the pill from Unconfirmed (amber) to Confirmed (green).
- Status pills: Unallocated (red), Unconfirmed (amber,
confirmed_at IS NULL), Confirmed (green), Orphaned (red, PM line deleted). - Unconfirmed allocations do not block docket creation but surface an Unconfirmed allocation pill on the docket until resolved.
Scope boundary — what ships later
Docket-level consumption (creating a subcontractor docket, picking scheduled items on it, having the pricing engine price them) ships in Slice 3 alongside the subcontractor docket type (SUB- prefix), the workbench tab, and the Diary integration. This slice delivers contract-level authoring, import, and cost allocation only.
Related
- Overview — module architecture and persona breakdown.
- Equipment Schedule Import — the shared import mechanic (CSV/XLSX + rate-source) that this step reuses.
- Ordinary Hours — the first step shared with subcontractor contracts.
- Spec:
docs/superpowers/specs/(subcontractor-crews-dockets branch).