Concorbit HelpAll guides →

Multi-Visit Jobs & Quote Conversion

Multi-visit jobs and quote-to-job conversion

Not every job fits in a single site visit. A boiler replacement might need one visit to survey and rip out, another to install once the customer's approved a revised quote, and a follow-up to commission. Each visit has its own schedule, technician, notes, and activity log, but they all roll up to a single Job with a single customer-facing reference like JOB-0001.

This page covers two related features:

  1. Quote → Job conversion: turning an accepted quote into a job in one click.

  2. Multi-visit jobs: organising work that spans more than one site visit.

Quote → Job conversion

When a customer accepts a quote (deal moves to quote_status = accepted), the outcome picker on the deal page lets you generate a Job as one of the available outcomes. Picking the Job outcome:

  1. Creates a new Job with the deal's customer + contact + deal link pre-populated

  2. Seeds the job's address from the company's primary site (falling back to the company's flat address)

  3. Builds a description from the quote line items (bulleted list: "• 2× Rip out old boiler", "• 1× Install Worcester Greenstar 30i", etc.): the dispatcher can edit on the Show page

  4. Sets priority to medium, status to scheduled

  5. Sends you to the new job so you can pick a schedule date and assign a technician

The job is created with created_via = deal_outcome_picker for reporting. The deal records each generated outcome's ID, so re-running the picker greys out the Job outcome and never creates a second one.

Multi-visit jobs

Any job can become a multi-visit job by adding a visit from the Visits card on the job detail page. The first visit you add flips the job into multi-visit mode; from then on the Visits card drives the lifecycle.

Adding a visit

Click + Add visit. Pick a start date/time, optional end date/time, technician, and a short note about what's planned for this visit. The visit gets a sub-number like V1, V2, V3, displayed alongside the job number as JOB-0001/V2.

Visit lifecycle

Each visit has its own status, independent of the parent job:

  • Scheduled: planned but not yet started

  • In progress: technician is on site (Start action)

  • Completed: visit finished successfully (Complete action)

  • Waiting for parts: follow-up is blocked pending parts (see fix-on-return below)

  • Cancelled: visit abandoned (dispatcher action)

The parent Job auto-completes when the last active visit (not cancelled, not waiting_for_parts) completes. Multi-visit jobs skip the per-field form-completion gate, because these jobs typically capture compliance via certificates. Single-visit jobs still use the normal gate.

Fix-on-return workflow

Sometimes a visit can't finish: the engineer arrives and finds a part isn't in stock, access to a plant room is denied, or the scope has grown. Rather than closing the job, click Require return on the active visit. A small modal captures:

  • Reason: parts needed / access denied / scope expanded / other

  • Notes: what happened, what's still outstanding

  • Follow-up date + technician (optional)

Submitting:

  • Marks the current visit as waiting_for_parts (for parts-needed reasons) or completed (for other reasons)

  • Creates a new visit in scheduled state linked back via parent_visit_id

  • Logs the transition in the job's activity timeline

The follow-up visit inherits the previous visit's technician by default, but the dispatcher can override. Both visits stay on the Job/Show page's Visits list so the history is clear; the follow-up carries a small "follow-up" tag.

Activity, time, and notes per visit

Child records (activities, time entries, notes) carry a nullable visit_id so you can tag each one to a specific visit. V1's UI doesn't surface per-visit filtering explicitly (they all appear in the main activity timeline), but reporting and the mobile app can use the visit_id column to slice later.

Permissions

No new permissions needed: multi-visit operations reuse the existing Jobs permissions:

  • jobs.create: quote-to-job conversion

  • jobs.dispatch: schedule / require-return / cancel visits

  • jobs.edit: start / complete visits

Not yet shipped

  • Dispatch board rendering per-visit blocks: currently shows one block per job regardless of visit count. Planned for a follow-up session (S239b).

  • Mobile RN "Visit 2 of 3" UI: mobile still presents the job as a whole. Visit-aware mobile screens are a follow-up.

  • "Schedule all visits" wizard: for now, dispatchers add visits one at a time. A bulk wizard is a sugar layer.