The Dispatch Board
The daily scheduling screen crews and dispatchers live in — visits, crews, status, and how actual hours get calculated.
On this page
Where it is
CRM → Scheduling → Dispatch Board. The board shows one day at a time — use the week strip at the top to jump between days. It's built for a dispatcher planning today's work and for reviewing what actually happened once crews are done.
Jobs vs. visits
A Job is the overall piece of work for a client (recurring lawn care, a one-time cleanup, a snow contract, etc.). A visit is one specific scheduled occurrence of that job — a single trip out to a property on a single day. A recurring job produces many visits over time; the Dispatch Board only ever shows visits, one day's worth at a time.
Visit status and the status menu
Every visit row shows a status icon in the ST column. Clicking it opens a status menu listing Scheduled, Dispatched, In Progress, Completed, Cancelled, and Skipped, with the current status highlighted. Pick the one you want and the visit changes on the spot — a toast ("Visit marked Dispatched") confirms it. The same statuses are available from the dropdown in the visit's detail sheet.
A single stray click on the icon no longer changes anything — it only opens the menu. That matters because moving a visit to Dispatched isn't just a label: it can fire "visit dispatched" automations and, as of now, writes to the client's Activity timeline, so it should always be a deliberate choice.
| Status | Meaning |
|---|---|
| Scheduled | The default state for a newly created visit. Nothing has happened yet. |
| Dispatched | Sent to a crew — picked from the status menu, set by Dispatch Assigned, or automatically the first time you print or send a crew their day. Dispatching writes a “Visit dispatched” entry to the client's Activity timeline. |
| In Progress | The crew is on site. Picked from the status menu, or set automatically once a crew member clocks in on the crew app. |
| Completed | The visit is done. Picked from the status menu, or set automatically once a crew member clocks out. |
| Skipped | The crew did not perform this visit today, but it's expected to happen another time (weather, client not ready, access issue). Picked from the status menu or the visit detail sheet; you'll be asked for a reason, which is saved on the visit and logged on the client's Activity timeline. |
| Cancelled | The visit was called off entirely and won't be rescheduled as-is. Picked from the status menu or the visit detail sheet; asks for a reason the same way Skipped does. |
Both outcomes ask for a reason. Choosing Skipped or Cancelled — from the status menu, a bulk status change, or the visit sheet — opens a short prompt with Weather, Client requested delay, Crew unavailable, or Other (with a free-text note). The reason is saved on the visit, where it can be edited later from the visit sheet, and is written to the client's Activity timeline as "Visit skipped 9/9 — Weather" (or "Visit cancelled …"), so the office can answer "why didn't you come Tuesday?" from the client record without opening the board.
Skipped and cancelled visits drop out of the day's numbers. The Totals row, each crew's stat card, and the Unassigned card exclude them from AMT and budgeted hours, so a day where three stops rained out shows what the crews actually had in front of them, not what was originally on the calendar. The visits themselves stay on the board (and under the Skipped / Cancelled status tabs) — only the rollups leave them out.
Status also advances itself in a couple of places outside the board: dispatching a crew's day (or printing/sending it) can move visits to Dispatched, and a crew member clocking in or out on the crew app moves the visit to In Progress or Completed automatically.
Crews and assignment
The Team Assignment dialog groups visits into a column per crew, plus an Unassigned column for anything not yet assigned. The header for each crew column shows how many stops that crew has for the day.
There are two ways to move a visit, and they do the same thing:
- Drag a visit card onto a crew's column to assign it, or back onto Unassigned to pull it off.
- Tap to place — tap a visit card to pick it up, then tap the crew column (or Unassigned) it should go to. The card you picked up is outlined, every column you can drop it on is highlighted, and a bar across the top of the dialog names what you're moving. Tap the card again, press Escape, or hit Cancel in that bar to put it back down.
Unassigned cards also carry a shortcut button per crew ("→ Maintenance 1") that assigns in a single tap, and each assigned card has a ✕ in its corner that sends it straight back to Unassigned.
A crew's headcount for a given day comes from its normal roster (set in crew settings), with same-day-only overrides layered on top from the same dialog — useful when someone is on loan to a different crew just for today. Move a person the same two ways: drag their name chip onto another crew, or tap the chip and then tap the crew they should work with. A member reassigned this way turns amber and is flagged as "on loan" for that date only, reverting to their usual crew automatically the next day; the ↩ on an amber chip sends them home immediately. People always belong to a crew, so Unassigned isn't a target for them.
Within a crew, turning on Manual Route mode makes each visit row draggable so you can reorder the crew's stop sequence by hand (drag handle appears once the mode is on). It's off by default so that clicking into a Start/End time field to edit it doesn't accidentally register as a drag.
Moving a visit to a different day — Move to Day, a drag on the board, or a bulk move — writes a "Visit moved 9/7 → 9/8" entry to the client's Activity timeline, so the client record shows when a stop was rescheduled without digging through the board's history.
How actual hours are calculated
The Actual Hrs column is the real number used for job costing and crew productivity reporting — it is not always literally "time on site" unless a crew clocks in and out. The value comes from a fallback chain, checked in this order:
- An explicit override — if a dispatcher has manually typed a number into Actual Hrs for the visit, that value wins outright and nothing below is used.
- Real clock-in/out punches — if a crew member clocked in and out on the crew app for this visit, actual hours = (clock-out time − clock-in time − recorded break) × crew size.
- Scheduled Start/End time, as a fallback — if there's no clock data and no override, actual hours = (scheduled end time − scheduled start time − recorded break) × the number of crew members assigned to the visit. This is the formula used for the vast majority of everyday visits, since most crews don't punch in/out per stop.
Editing a visit's Start or End time clears any stale override so the number recalculates from the new times rather than silently keeping a number measured against the old schedule. It does not touch the Men count: a headcount you've set on the visit is kept, and the times (or the crew's roster) only fill Men in when it was still blank. Hours are shown to two decimals everywhere on the board and in the visit sheet.
Worked example
A visit is scheduled 8:00 AM – 11:00 AM with a 3-person crew. Nobody clocks in or out, and no manual override is set.
| Fallback used | Scheduled Start/End (no clock data) |
| Calculation | (11:00 AM − 8:00 AM) × 3 crew members = 3 hours × 3 = 9 man-hours |
Now suppose the same 3-person crew instead clocks in at 8:15 AM and clocks out at 10:45 AM — real punches exist, so tier 2 takes over and the scheduled window is ignored entirely:
| Fallback used | Real clock-in/out punches |
| Calculation | (10:45 AM − 8:15 AM) × 3 crew members = 2.5 hours × 3 = 7.5 man-hours |
The clocked result (7.5) replaces the scheduled estimate (9) automatically — no manual intervention needed, and no override is written unless a dispatcher deliberately types one in.
Board columns
Which columns are visible is configurable per user via the column-visibility control on the board toolbar, and that choice is now remembered — it's saved to your profile, so it survives a reload instead of resetting to the default set every time.
| Column(s) | What it shows |
|---|---|
| Service, Date, City, Zip | Identify the visit and where it is. |
| Assigned | Which crew (or Unassigned) currently owns the visit. |
| Last Svc | When this client was last serviced for this service — useful for spotting overdue recurring stops. |
| Start / End | Scheduled arrival and departure window, editable inline. |
| B Hrs | Budgeted hours — from the job's linked service (production rate × team size), or the job-level total as a last resort. Shown to two decimals. |
| Actual Hrs | See the dedicated section below — this is the number that matters most for job costing. Shown to two decimals. |
| Hr Variance | Actual minus budgeted, colored red when over and green when under. |
| Men | Crew headcount used in the actual-hours fallback calculation. A value you set here is kept — editing the visit's times only fills Men in when it was blank. |
| Qty, Rate, AMT | Billing quantity, unit rate, and the job's value — the sum of the job's included service lines, the same figure the visit sheet and the client's Jobs card show. |
| Notes/Icons | Call-ahead flags, comments, and other at-a-glance indicators. |
Beyond that fixed set, the column-visibility control also offers a second, SA-style block of optional columns pulled from the client's and property's own records rather than the visit: Priority, Sales Rep, Notes to Crew, Gate/Lock Code, Turf Sq. Ft., Mulch Bed Sq. Ft., Gross Sq. Ft., Linear Ft. of Perimeter, Linear Ft. of Edging, Yards of Mulch, and Parking Lot Sq. Ft. Any org custom field defined under Settings → Custom Client Fields shows up here too, as its own trailing column named after the field (with its unit in parentheses if it has one). These are all off by default — turn on only the ones your crews actually take off of. The same set is available on the Waiting List for consistency.
Products (materials) on a visit
Opening a visit's detail sheet from the board shows a Products section for materials tied to that job — the same editor used on the Job record's own Products tab, not a read-only summary. From here you can add a product, edit its quantity or unit price, and change its status (Used/Invoice, Used, do not Invoice, Not Used/Cancel, or reopen it to Pending) without leaving the board.
Filters, search, and routing
- Status tabs — All, Scheduled, Dispatched, Completed, Cancelled, Skipped — filter the board down to visits in that state.
- Crew filter — a multi-select checklist to show only selected crews (plus "All Crews" to clear it).
- Search — a free-text box for finding a visit by client, address, or similar.
- Date range — an optional end date lets the board span more than a single day when you need to look ahead.
- Stats and Call Ahead panels — Stats gives a quick summary overlay for the visits currently in view; Call Ahead surfaces visits flagged as needing a courtesy call to the client before arrival.
- Print Route Sheets — generates a printable, per-crew stop sheet (client, address, service, time, budgeted hours, and notes to the crew) for the selected day, including a separate sheet for anything still unassigned.
There's no live map view on the board — routing is handled by the crew stop order, the Optimize Route action, and the printed route sheets. See the next section for how all three fit together.
Bulk actions on selected visits
Checking one or more visit rows reveals an Actions (n) button on the toolbar with a Change Status submenu, a Re-assign Crew submenu, and — separately — Email Selected Clients.
Email Selected Clients opens a compose dialog addressed to the distinct clients behind the checked visits — selecting three visits for the same client only addresses that client once. It pulls each recipient's email from their client record and skips (with a reason shown in the dialog) anyone with no address on file or a hard email bounce; a Purpose toggle additionally decides whether clients marked Do Not Market are skipped (Marketing/promotional) or still included (Service notice — for messages about work they've already contracted, with no unsubscribe footer). Subject and body can be typed from scratch or started from a Documents email template (type "Client") — the same block-based template system used for invoice emails — and a row of merge tags can be inserted into the message at the cursor. Sending fires one email per recipient and logs to each client's Activity timeline.
Stop order and Optimize Route
Stop order is per crew. The # column numbers each crew's own stops from 1, so "#3" means that crew's third stop of the day, not the third row on the board. Reordering one crew never renumbers another.
Drag rows in Manual Route mode, or use Reverse to flip the current order, or Group Stops to cluster each crew's stops by zip area. Either way the board shows an "Order changed — not yet saved" banner until you click Save Order.
The order is remembered for next week
Saving an order does two things. It sets today's stop sequence, and it remembers that sequence for that crew on that weekday. The next time the same crew has work on the same weekday — next Monday, the Monday after — the board comes up already in that order instead of an unsorted crew grouping. You only have to route a recurring run once.
Jobs added to the route later — a new client on an established Monday run — also sort to the bottom until you drag them into place and save again. Saving the day always wins over the remembered order, so a one-off change for a single day never overwrites the usual route.
Optimize Route
Optimize Route reorders the stops currently in view by real driving time. The dropdown beside the button controls which way round the crew works the route:
| Direction | What it does |
|---|---|
| Nearest first | Leaves the shop and takes the closest remaining stop each time. Usually the shortest total drive, but the crew can finish the day far from the yard. |
| Furthest first | Drives out to the far end of the route first and works back in, so the crew finishes near the yard at the end of the day. |
Optimize Route solves each crew's tour separately (in parallel) and anchors it at that crew's own starting address (set per crew under Team → Crews) — a mixed-crew day no longer needs to be filtered down to one crew first to get a real route. A crew with no starting address set still gets routed by driving time, just without a shop to start or end at, and the confirmation toast says which crews that applies to. If one crew's route fails to solve (a bad address, a Distance Matrix error), the others still come back — it isn't all-or-nothing.
After optimizing, the banner reports how many crews were routed and the combined driving time between stops and shop legs across all of them. An optimized order is a proposal like any manual drag — it isn't saved, and doesn't become the crew's remembered order, until you click Save Order.
See also
The other half of this screen is the crew's phone: what they see, how clocking on and off works, and how the actual hours that land here are produced. See the Crew App guide.
Jobs without a fixed date — waiting for weather, crew capacity, or a client window — don't live on the Dispatch Board at all until they're given a day and crew. See the Waiting List guide for how those get queued and dispatched.