Field workforce: resources, crews, shifts, territories and contractors
This article covers everything the field operation needs BEFORE a work order exists: who can go, with what, on which shift, inside which territory, what happens when nobody accepts a job, and how outside contractors are paid and rated.
This article covers everything the field operation needs BEFORE a work order exists: who can go, with what, on which shift, inside which territory, what happens when nobody accepts a job, and how outside contractors are paid and rated.
Service resources
A resource is anything that has to be allocated to a job. It can be a technician who logs into the CRM, a subcontracted installer with no login at all, a van, or an expensive tool. Open Field service, tab Workforce, sub-tab Resources.
A resource does NOT need to be a user. That is the whole point: before this, a subcontractor had to be given a seat in your CRM just to appear in dispatch. A resource linked to a user is limited to one per person, so the same technician never shows up twice in the candidate list.
Skills come from the same catalogue used by ticket routing (Settings, Skills). A certification with an expiry date in the past stops counting: it still shows on the card, marked expired, and it drops out of the candidate list. Cost per hour is only visible to people who manage settings; it is your cost, not the customer price.
Crews
A crew is a named group of resources with a lead. Allocating a crew to a job does NOT expand it into its members: the composition changes over time, and freezing the names on the order would make it lie the first time the pair changes. Crew capacity adds up only the people; a van does not work eight hours by itself.
Shifts
Shifts answer WHEN somebody works. Schedule capacity (how much fits in a day) stays where it was.
Create a named shift template with a window, the days of the week it applies to, and optionally a rotation of N days from an anchor date (12x36, 4x2, weekend on-call). A rotation wins over days of the week: if you wrote a rotation, you wanted the rotation. A rotation without an anchor date is refused, because it has nothing to count from.
Generate the shifts for a period and a set of people. Generating is idempotent: running it again to extend the period does not duplicate anything and does not rewrite what is already published.
Shifts start as DRAFT. The team sees nothing until you publish. Publishing notifies each person once, with the number of shifts, in their own language. Contractors without a login do not get a bell notification; they see the schedule in the contractor portal.
A person can request a shift swap. The shift only changes owner when the swap is ACCEPTED. A swap to somebody who already works that day and hour is refused with a clear reason, and a shift that has already started cannot be swapped.
Territories
Service zones stay exactly as they were: a flat, editable catalogue. The territory policy adds a parent zone, opening hours of the zone itself, an overflow zone and a minimum coverage.
Hours are inherited: a zone with no hours of its own uses the closest ancestor that declares them, and the screen says which zone the hours came from. A zone that declares nothing anywhere in its ancestry falls back to the company working hours. Cycles are refused when you save, not tolerated when you read.
Coverage per day counts people with a PUBLISHED regular shift whose home zone is that zone, or who are linked to it. A zone under its minimum with no overflow zone is flagged as uncovered.
Escalation when nobody accepts
When a job is broadcast to the technicians of a zone and nobody claims it, the escalation ladder takes over. The ladder is data: a policy matched by job priority (a policy with no priority is the fallback), and numbered steps, each with a wait in minutes and a target: the same zone, the parent zone, the overflow zone, everybody, or a named person. A step can also extend the offer deadline.
Each step ADDS recipients to the SAME offer. It never creates a second offer: two open offers for the same job would allow two winners, and the atomic claim protects one offer, not two. Only one step runs per pass, so a stalled cron does not fire the whole ladder at once. Every step is written to an append-only ledger, which is the answer to "why did this end up with the contractor from the next town at 11 pm?".
When the ladder runs out, the person named as fallback is notified once.
Contractors
A contractor company has its own trades, zones, documents, rates and payout ledger.
Documents carry an expiry date, which is the reason the table exists: an expired insurance policy is the number one reason a contractor cannot enter a customer's home, and nobody remembers the date. Expired documents flag the contractor on screen. The system tells you; it does not silently remove them from the board.
Rates are what the contractor charges YOU, which is different from your price book. When you accrue a payout for a job, the system picks the rate that is in force on that date and is the most specific match (trade plus job type beats trade, which beats a generic rate). With no rate, it falls back to the contractor's default percentage over what was billed. With neither, it accrues nothing and says why, instead of guessing a number.
The payout ledger is append-only. Correcting a payout is a compensating entry, never an edit. The balance is the sum. Rates and balance are only visible to people who manage settings.
Rating is one per job: correcting a rating fixes it, it does not stack a second opinion.
Contractor portal
Add the contractor's email to the portal allowlist and copy the access link. The contractor signs in with a magic link, no password and no account, and sees only their own jobs, published shifts, open offers, payout balance and documents. Removing the email from the allowlist cuts access on the next click.
Field campaigns
A campaign selects equipment from the installed base by type, brand, model, serial range, installation date or zone, and opens a work order for each one. Preview first (how many the filter catches, without writing anything), then enrol (the list freezes into targets), then activate, then generate the work orders. A draft campaign refuses to generate: opening a hundred orders straight from a filter is irreversible in practice.
Serial ranges compare digit blocks, not raw text, so A-99 correctly sorts before A-100. Equipment with no serial number stays out of a campaign that uses a serial range.
Excluding a target does not delete it: it leaves the coverage denominator and the reason stays written.
Public booking page
Publish an address where customers request a visit themselves. The page only exists once you publish it, offers the arrival windows you already use for dispatch, and has a per-hour cap by IP address. Requests land in the same booking queue as before, with the same screening for area and availability.
Working on the job
The order itself gained allocation of resources and crews, comments with mentions (the same comment engine as records, so mentions notify and you can follow or mute), a call for a second technician, an assistant that suggests a diagnosis from the equipment history, and payout accrual plus rating of the contractor who did the work.
The assistant only SUGGESTS. It writes nothing to the order, the report or the equipment, it shows what it based the answer on, and when there is no history it says so instead of inventing one.