Export — CSV and ERP

Subcontractor dockets reach export parity with labour-plant and materials dockets in Slice 6. Both the docket CSV and the ERP preview / batch / GRN pipeline handle the two billing dimensions on a subcontractor docket: engine-priced worker lines and scheduled-item lines.

For Core’s four-sheet subcontractor workbook, see Subcontractor Dockets Report.

CSV export

Triggering an export

The Subcontractor tab of /admin/dockets shares the same Export CSV flow as Labour & Plant and Materials:

  1. Apply filters on the Subcontractor tab (date range, status, contract, supervisor).
  2. Click Export CSV in the top-right of the filter bar.
  3. Switch to the Exports tab and wait for the job to flip from pending → running → completed.
  4. Click Download to retrieve the file.

Exports expire 30 days after creation. The same 500 000-row and 5-concurrent-export limits that apply to all other docket types apply here.

Row anatomy

The CSV follows the same long-format shape as labour-plant exports — one row per (docket × pricing line × cost-code cell). Subcontractor dockets introduce two resource_type values:

resource_typeWhat it represents
workerAn engine-priced worker line priced through the 8-stage award rule engine.
scheduled_itemA scheduled-item line priced as entered_qty × base_rate, minimum-engagement-floored.

Attendance-only workers (is_attendance_only = true) contribute $0 to the docket total. They are still emitted as resource_type='worker' rows with unit_qty = 0 so head-count and sign-on compliance data survives into the export — exclude them from any billed-dollars formula by filtering unit_qty > 0.

No-activity-hours branch

Subcontractor dockets do not always carry docket_activity_hours rows. Worker lines on dockets with zero activity hours are emitted via a dedicated flat branch that produces one row per worker per docket rather than cross-joining against activity allocations. Scheduled-item lines always use this flat branch — their quantities are a direct measurement independent of activity hours.

This mirrors the materials docket treatment and ensures a subcontractor docket with no recorded activities still appears in full in the CSV.

Reconciliation formulas

You wantFormula
Per-row billed dollars (worker)unit_qty × line_rate × headcount
Per-row billed dollars (sched. item)unit_qty × line_rate (headcount = 1 for scheduled items)
Per-docket grand totalSUMPRODUCT(unit_qty, line_rate, headcount) where resource_type IN ('worker','scheduled_item'), grouped by docket_no
Per-cost-code spend (worker lines)SUMPRODUCT(unit_qty, line_rate, headcount) GROUP BY cost_code
Per-contract scheduled-item spendSUM(unit_qty × line_rate) WHERE resource_type = 'scheduled_item' GROUP BY resource_name

Scheduled-item lines carry an empty cost_code column — see Known limitation below.

Cost-allocation report

Subcontractor costs appear in the cost-allocation report at /admin/reports/cost-allocation (JSON or CSV via the toggle at the top of the page).

Row typeRoot entity typeWhat feeds it
Worker billing linesworkerEngine-priced worker lines resolved through the award engine → supplier_payment_allocations.
Scheduled-item linesscheduled_itemEach docket_scheduled_items row resolved through supplier_payment_allocations.entity_type='scheduled_item'.

Attendance-only workers are excluded from cost-allocation rows — they contribute $0 to the docket and produce no allocation.

If a scheduled item has not been bound to a PM line in the Cost Allocation step, it surfaces in the report as Unallocated, exactly as materials and equipment-rate rows do. Confirm all scheduled-item allocations before pushing dockets to ERP.

ERP preview, batch, and GRN pipeline

Current status

The ERP pipeline for subcontractor dockets ships at design-intent parity with the materials module — the backing schema, line items, and cost-allocation columns are forward-compatible with the COINS GRN payload. The batch gating, preview step, and GRN payload builder are all wired. The live COINS submission is deferred, consistent with materials.

The workbench Subcontractor tab shows a Push to ERP button labelled deferred. It surfaces a tooltip explaining the timeline rather than triggering an action. No schema migration is needed to activate it — the schema, erp_export_batches rows, and GRN payload builder are already correct.

Batch family guard

An ERP batch is typed by docket family. A batch created from the Subcontractor tab cannot contain labour-plant or materials dockets, and vice versa. This 3-family guard is enforced at three layers:

  • The SQL query WHERE docket_type = 'subcontractor' inside getErpExportableDockets for the Subcontractor tab.
  • The Go eligibility.Check function, which rejects any docket whose docket_type does not match the batch’s expected family.
  • The React isDocketEligibleForExport predicate, which renders a disabled-and-greyed checkbox with a tooltip for any cross-family row.

The workbench already filters dockets by tab, so this situation should not arise in normal use — the guard exists as a structural safety net.

Batch and preview

Once the COINS connector is wired, subcontractor dockets follow the same wizard flow as labour-plant pushes — see ERP Integrations. The three-step modal (Review → Push → Report), per-docket eligibility (status='confirmed' AND exported_at IS NULL), and the erp_export_batches / erp_export_batch_dockets tracking tables apply unchanged.

The Step 1 Review surface aggregates subcontractor dockets per contract, per scheduled item, alongside worker-line totals. Warning chips surface the same upstream issues as other docket families: unconfirmed supplier_payment_allocations, missing rates, or over-commits against the contract’s value.

GRN line shape — scheduled items

Scheduled-item lines are emitted as one GRN line per docket_scheduled_items row at the full billed quantity. Unlike worker or plant lines there is no prorating against activity hours — the quantity is already a direct measurement (metres, loads, m³, etc.).

GRN fieldSource
Descriptiondocket_scheduled_items.name_snapshot
Quantitydocket_scheduled_items.billed_qty (≥ minimum_engagement)
Unit pricedocket_scheduled_items.rate_snapshot
Line valuebilled_qty × rate_snapshot
Cost codeEmpty — see Known limitation.

Worker GRN lines use the same payload shape as existing labour-plant worker lines — no change to the format for that dimension.

Known limitation — empty cost code on scheduled-item lines

Scheduled items (contract_scheduled_items) have no cost-code source column today. The cost-allocation step allows binding a scheduled item to a PM line, but the PM line does not carry a COINS-specific cost code in the current schema.

As a result, scheduled-item GRN lines are emitted with an empty cost code — the same fallback used by materials dockets when activity_id IS NULL. Cost controllers should be aware that the COINS journal entry for scheduled items will need a manual cost-code assignment in COINS until a per-line cost-code field is added to contract_scheduled_items in a future enhancement.

Known limitation — worker lines on no-activity, no-cost-code dockets

Subcontractor dockets do not receive an automatic docket-level cost code stamp (unlike plant-register auto-dockets which inherit auto_docket_cost_code). When a subcontractor docket has no activity-hours rows and no docket-level cost code set, worker lines are emitted in both the CSV and the ERP preview/GRN with a blank cost_code column — the behaviour is consistent across both surfaces (no divergence in what is emitted, only in attribution).

This is a pre-existing LM-58 gap: the docket cost-code stamp path was designed for plant-register auto-dockets and is not wired to subcontractor docket creation. Until a per-docket cost-code field is surfaced in the subcontractor docket editor, worker lines on activity-free dockets will carry a blank cost code on both CSV and ERP outputs. Cost controllers should be aware and manually attribute these lines in COINS or the cost-allocation report.

Worker lines on dockets with activity-hours rows carry the activity cost code correctly — the pro-rate split stamps activity.cost_code onto each expanded GRN row and CSV cell.

  • Dockets — docket creation, crew seeding, mobile captain, and lifecycle.
  • Schedule of Rates — authoring scheduled items and cost allocation, the prerequisite for correct ERP payloads.
  • ERP Integrations — full COINS connector walkthrough (current state of labour-plant push).
  • Docket CSV Export — shared CSV format and reconciliation formulas.