Dispatch, Invoicing & Payroll Automation for Total Solution Industries
- Client:
- Total Solution Industries
- Industry:
- Logistics | Field Service
- Duration:
- Ongoing
- Team:
- Senior Python + AI engineer
Total Solution Industries runs a field plumbing crew across multiple Florida metros, with every work order, technician and schedule living in the MobiWork ERP. We built a suite of three production n8n automations on a single backbone: a real-time Dispatch Assistant that finds the best available technician mid-call, an event-driven Invoice Automation that prices and bills a job the moment it closes, and a nightly Payroll Spreadsheet generator. Each automation is an orchestrator plus small, reusable sub-workflows — independently testable, which is what makes a single-production-instance, no-staging environment safe to work in.
THE CHALLENGE
Three back-office processes were manual, slow and error-prone — and the operating environment made them hard to "buy off the shelf".
Manual dispatch, invoicing and payroll
- Dispatch. On every customer call the dispatcher cross-checked the ERP, a schedule spreadsheet and a maps app by hand to decide which technician could take the job — putting the caller on hold while they worked it out.
- Invoicing. Every closed work order was priced by hand from a price list, with the right customer tier applied and the invoice re-keyed into MobiWork — a slow path with a steady stream of pricing and data-entry errors.
- Payroll prep. Each pay period someone rebuilt a per-technician payment spreadsheet by hand from raw work-order data.
A hostile environment
- One production instance, no staging — every change ships straight to prod, so workflows must be defensively built and independently testable.
- A quirky XML ERP API that occasionally returns malformed XML and undocumented or missing fields — nothing can trust the schema.
- Real-world scheduling and pricing — weekday hours plus date overrides, real driving times, per-customer pricing tiers and not-to-exceed caps.
OUR APPROACH
All three automations share one modular, self-hosted stack. Each is an orchestrator workflow plus a set of small, reusable sub-workflows — the orchestrator owns the trigger and the shape of the result, and delegates discrete jobs (fetching data, ranking, upserting an invoice) to sub-workflows that can be tested and reused on their own. The integration layer is shared, not re-implemented per workflow.
Shared backbone
- n8n — self-hosted workflow engine, a single production instance
- MobiWork ERP — system of record for work orders, technicians and schedules, over a token-authenticated XML REST API with malformed-XML tolerance built in
- Google Workspace — Sheets for schedules and reports; Geocoding + Distance Matrix for routing
- PostgreSQL — pricing rules and customer tiers
- OpenAI — natural-language dispatch parsing and line-item invoice pricing
AUTOMATION 1 — DISPATCH ASSISTANT
A chat tool that finds the best available technician for a job while the dispatcher is still on the phone. The dispatcher types the job in plain language — address, date, time window, duration, required level; an AI agent parses it into a structured request, pulls active technicians and their open work orders from MobiWork, reads each tech's working hours from Google Sheets, computes real driving times with Google Maps, and returns a ranked shortlist in 10–50 seconds. The dispatcher makes the final call — the workflow advises, it does not auto-assign.
What makes it hard
- Live schedule synthesis — availability is weekday hours minus booked jobs plus date-specific overrides; gap discovery builds per-day free slots and clamps every gap to the tech's working window
- Route-optimized ranking — Google Distance Matrix driving times drive a dual ranking: minimal total route vs. closest to the requested time
- Three scheduling modes (exact / preferred / deadline), cumulative level filtering, and a whole-day reschedule/coverage finder
AUTOMATION 2 — INVOICE AUTOMATION
End-to-end invoicing the moment a job closes. When a work order is marked Closed in MobiWork a webhook fires; GPT-4o-mini matches the technician's notes and the work description against a PostgreSQL price list, applies the customer's pricing-tier multiplier, and writes the finished invoice back into MobiWork — complete with an itemized internal note and an automatic warning when a job is likely to exceed its not-to-exceed (NTE) cap.
Guardrailed, auditable pricing
- AI matches, math decides — the model proposes line items against the authoritative price list; a deterministic tier multiplier and NTE over-cap check wrap its output so pricing stays bounded
- Idempotent upsert — the invoice API supports add/update/view but no delete, so a create-or-update path keeps re-runs safe on a single production instance
- ~50 work orders auto-priced and invoiced per day (~350/week), each in well under a minute
AUTOMATION 3 — PAYROLL SPREADSHEET
A nightly job that turns the day's completed work into a payroll-ready report. It reads the day's work orders from MobiWork, counts each technician's stops and destinations, and assembles a per-technician payment spreadsheet in Google Sheets — so payroll prep is waiting and ready each morning instead of being built by hand each pay period.
- Runs unattended, nightly at 04:00 on a scheduled cron trigger
- Aggregates per-tech stop/destination counts straight from the day's work orders
RESULTS & SCALE
Route-optimized technician shortlist in 10–50 seconds, mid-call
~50 work orders auto-priced & invoiced per business day (~350/week)
Near-100% invoice success, each order processed in under a minute
Payroll spreadsheet built automatically every night at 04:00, unattended
- A single dispatch query orchestrates four external APIs (MobiWork XML, Google Geocoding, Distance Matrix, Sheets) plus an LLM agent
- Validated by 3 timestamped end-to-end test runs covering 24+ cases — time modes, gap discovery, filters, and edge cases like day-off, over-long jobs, bad addresses and missing coordinates
TECHNICAL CHALLENGES SOLVED
Real-time, multi-API orchestration mid-call
Answering "who can take this job, and when?" used to require a human to consult the ERP, a schedule sheet and a maps app at once. One dispatch query now fans out to MobiWork (XML), Google Geocoding, Distance Matrix and Sheets, plus an LLM parser, and returns a ranked shortlist in 10–50 s.
Surviving a hostile ERP API
MobiWork returns XML that is sometimes malformed, with undocumented or missing fields. Every integration validates what it actually receives and tolerates malformed XML rather than trusting the documented schema.
Trustworthy AI pricing with guardrails
Line-item pricing is judgement-heavy and must respect customer tiers and NTE caps. GPT-4o-mini matches against the authoritative PostgreSQL price list; a deterministic tier multiplier and an NTE over-cap check wrap the model's output so pricing stays bounded and auditable.
TECHNICAL DETAILS
Architecture
A modular orchestrator-plus-sub-workflow design on a single self-hosted n8n instance. Dispatch alone composes a chat orchestrator with a ~25–30 node "find technicians" engine, a name→userId resolver, and a 32-node whole-day reschedule workflow; invoicing is one orchestrator plus four sub-workflows (price match, upsert invoice, update notes, update description).
Technologies used
- Workflow engine: n8n (self-hosted, single production instance)
- ERP / system of record: MobiWork REST API (XML, token auth)
- Google Workspace: Sheets | Geocoding | Distance Matrix
- Data: PostgreSQL (price list, customer tiers)
- AI: OpenAI GPT-4o-mini (invoice pricing) + LLM agent (dispatch parsing)
- Logic: JavaScript Code nodes (scheduling, ranking, tier math, aggregation); webhook + cron triggers on a Linux VPS
ESTIMATED IMPACT
Alongside the figures above — which are derived directly from the production workflows — the business impact estimates below are estimates from the team, to be confirmed with the client, not measured before/after baselines:
- Dispatcher cross-check (ERP + schedule sheet + maps) cut from several minutes to 10–50 seconds per lookup (estimated)
- Manual pricing and invoice data entry removed for ~350 work orders a week, eliminating a common source of billing errors (estimated)
- Per-pay-period payroll assembly replaced by an unattended nightly run (estimated)
THE OUTCOME
Total Solution Industries replaced three slow, manual processes with repeatable engines. Dispatchers answer "who can take this job, and when?" without putting the customer on hold; billing no longer does manual pricing lookups or invoice entry; payroll prep is waiting and ready each morning.
The automations encode TSI's real rules — technician levels, working-hour overrides, customer pricing tiers, NTE caps — rather than a generic template, and the defensive integration layer keeps the suite dependable where every change ships straight to production.
FREQUENTLY ASKED QUESTIONS
How fast is the automated dispatch lookup?
The Dispatch Assistant returns a route-optimized shortlist of available technicians in 10 to 50 seconds, while the dispatcher is still on the phone — replacing a manual cross-check of the ERP, a schedule spreadsheet and a maps app that used to put the caller on hold.
Which systems does the field-service automation suite connect?
An n8n orchestration layer connects the MobiWork ERP (work orders, technicians, schedules) to Google Workspace (Sheets for schedules and reports, Geocoding and Distance Matrix for routing), a PostgreSQL price list, and OpenAI for dispatch language parsing and line-item invoice pricing.
How does it handle an unreliable ERP API?
MobiWork's REST API is XML and can return malformed responses, undocumented fields, or missing documented fields. Every integration validates what it actually receives and tolerates malformed XML rather than trusting the documented schema, so workflows stay reliable on a single production instance with no staging.
How many invoices does the system process?
Roughly 50 closed work orders are auto-priced and invoiced every business day — about 350 a week — each in well under a minute at near-100% success. The moment a job is marked Closed, GPT-4o-mini matches it against a PostgreSQL price list, applies the customer's pricing-tier multiplier, and writes the finished invoice back into MobiWork.
Contact
Have a workflow worth automating?
We build accountable AI automation on senior Python engineering — and we'll tell you when not to. See our AI automation services, or get in touch.
Contact us