ModulesSubcontractorSchedule of Rates

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:

StepNameNotes
1Ordinary HoursShared with labour_hire / plant_hire.
2ClassificationsShared with labour_hire.
3Equipment RatesShared with labour_hire.
4Schedule of RatesSubcontractor-only. Backed by contract_scheduled_items.
5Cost AllocationShared; 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.

ColumnRequired?Notes
NameYesFree text, case-insensitive unique within the contract (≤ 255 chars).
DescriptionNoMulti-line specification or scope notes.
Meter typeYesOne of shift-duration, engine-hours, km, metres, loads, custom. Drives the pricing engine’s rate calculation.
Custom unit labelCond.Required when meter_type = custom. Displayed on the docket line (e.g. m³, tonne, panel).
Base rateYesPer-unit dollar rate (NUMERIC(14,4), non-negative).
Minimum engagementNoFloor quantity billed per docket line. When entered_qty < minimum_engagement, the engine bills the minimum.
Monthly minimum SMUNoContractual monthly floor (informational; priced in the SMU-reconciliation pass).
Pro-rata formulaNoFree 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_type must be a known value; custom_unit_label is required when meter_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 to code) becomes the item name; the line rate becomes base_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_id is 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_line entries 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.

  • 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).