WorkestraDocs
ModulesField Service

Work Orders

The committed job — customer, asset, lines, and a workflow that drives appointments through to billing.

A work order is the committed job. It captures who the customer is, which asset (if any) is being serviced, the line items (labor, parts, expense, flat fees) that will be billed, and a workflow gate from draftbilled.

Work orders do not carry scheduling themselves — that lives on appointments. One work order can have many appointments (multi-day, follow-ups, retries). Even single-visit jobs are modeled as a work order + one sequence-1 appointment.

Creating a work order

Three paths:

WhenHow
Customer asked, no quote neededOpen a requestConvert to work order
Customer approved a quoteOpen an estimateConvert to work order (lines copy across)
Ad-hoc / dispatcher-initiated/fsm/work-orders/new — fill title, description, priority, service type, then schedule the first appointment from the detail page

Every work order is auto-numbered WO-YYYY-NNNN.

What's on a work order

FieldNotes
NumberWO-YYYY-NNNN, auto-allocated
Title + DescriptionWhat the job is
Service typeFree-text label (drives skill matching in dispatch)
Prioritylow / medium / high / urgent
StatusWorkflow gate — see below
CustomerContact and/or company from CRM
AssetLinked asset under service (optional) — when present, completion writes to the asset's maintenance log
Service contractWhen the WO was generated from a recurring contract
Default locationAddress + lat/lng — copied to the first appointment by default
SLAResponse due + resolution due timestamps; daily breach scan
EstimatedDuration (minutes) + total (money)
Currency3-letter ISO

Work order status

The work order status is the workflow gate. The appointment status is the operational state of each visit. Don't conflate the two.

StatusMeaningTransitions to
draftCreated, no appointments scheduled yetscheduled, cancelled
scheduledAt least one appointment bookeddispatched, cancelled
dispatchedA technician has been notified for at least one appointmentin_progress, cancelled
in_progressWork is happeningcompleted, cancelled
completedAll appointments done; ready to billbilled
billedFinance invoice generated (manual today; auto-bridge queued for Phase 4.8)
cancelledCancelled; no work performed

When the last open appointment transitions to completed, the work order auto-rolls up to completed. You don't need to flip it manually.

Line items

Work-order line items live on fsm_work_order_lines. Four types:

Line typeUse forDriven by
laborTech time on the jobhours × rate_per_hour
partsMaterials consumedquantity × unit_price (FK to a Stock product)
expenseReimbursable pass-throughquantity × unit_price
flat_feeFixed-price itemsquantity × unit_price

When you convert an estimate to a work order, all active estimate lines copy here automatically.

Parts pulls

When a technician consumes a part on site, log it via Parts pulls on the work-order detail page. Each pull:

  1. Writes a fsm_parts_pulls row with the product, quantity, and source location (truck or warehouse).
  2. Fires the fsm_stock bridge to write a stock_movements row (kind=consumption, source_type=fsm_parts_pull).
  3. Reduces stock inventory in the source location.

Parts pulls are idempotent on an idempotency key — replaying the same pull (e.g. on retry) doesn't double-deduct.

Asset maintenance log

If the work order has an asset_id, every completed appointment automatically writes a row to the asset's maintenance log via the assets_fsm bridge. Multi-visit jobs log one maintenance entry per visit (per-appointment marker — idempotent).

SLA tracking

Each work order can have a response due (when a tech must be assigned) and resolution due (when the job must be complete) deadline. A daily cron at 14:30 UTC scans for work orders past either deadline and logs the breach. Webhook delivery + Slack/Teams notification is queued for Phase 4.10.

Cancelling a work order

Open the work-order detail → use the status transitions card → cancel. Cancellation is a terminal state for the work order. In-flight appointments are not auto-cancelled — cancel them individually if needed (e.g. tech is already on site and you want to keep the visit log).