PBS Haulage — Handbook
Live as a demonstration. haulage.pascoesystems.co.uk runs one demonstration organisation, Gatcombe Vale Haulage & Plant Hire (demo), a made-up Isle of Wight haulage, plant hire, skip, aggregates and waste firm: every customer, site, person, lorry, machine and job in it is fabricated. Its price list is marked Example prices: a sample tariff to show how the app works, not any firm's current prices.
PBS Haulage is one job engine for every haulage job, delivery, collection, skip exchange and hire. For each job it shows what is charged to the customer and — to the people allowed to see it — what it actually cost to run. This handbook has one section for every screen you can reach. Addresses are shown in code font; :id stands for the job, run, checklist or offer number in the address.
Roles. owner · admin · office · driver · customer · readonly. Office roles (owner, admin, office) see the whole menu: Dispatch · Schedule · Hire · Requests · Quote · Jobs · Tickets · Waste notes · Runs · Messages · Money · Equipment · Readiness · Registers · People · Customers · Rates · Price list · Job types. A driver sees only My run and Jobs. A readonly user is offered only the pages it may open: Dispatch · Schedule · Hire · Requests · Jobs · Tickets · Waste notes · Messages · Equipment · Readiness · Registers - the menu follows the same permission each page checks. Money is gated per person: values (what is charged) and costs (what it costs us) are separate permissions, an owner has both, and field roles can never be granted either — the database enforces that, not the screen.
Getting in
Help — /help
This handbook, inside the app. Every screen carries a ? in the top bar that opens this page at that screen's own section. Readable without signing in; it describes the screens and holds no records.
Sign in — /login
Email and password. A driver lands on My run; everyone else on Dispatch. Until PBS Haulage takes new accounts, they are created by your administrator. Create an account and Help sit under the form; Help opens this handbook without signing in.
Every page, sign-in included, carries Privacy and Terms at the foot. A demonstration organisation carries a slim Demonstration strip at the top of every page — a made-up company and data; on a wider screen it adds that every customer, person, vehicle, price and job in it is fabricated. A company that is not a demonstration never carries it.
Create an account — /signup
Until PBS Haulage takes new accounts this page says Accounts open soon and saves nothing. Once it does, you give your business's name, your name, your email and a password; you get your own empty account and the screen says it is waiting for approval. You can sign in once it has been approved.
Approvals — /approvals
For Pascoe Business Systems only — to everyone else this page does not exist. It lists each new company Waiting (company, owner, email, when it asked) with Approve (/approvals/:id/approve), which lets that owner sign in to their own, empty account; and Approved recently, with when and by whom. While new accounts are switched off it says so and lists nothing.
Sign out — /logout
The Sign out button in the header. Ends your session.
Health check — /healthz
Not a screen: answers whether the service is up. Used by monitoring.
The office day
Dispatch — /
The front page for office roles. Today and everything live — every job in progress with its status; Runs today — the rounds going out; Jobs worth a look before they are invoiced — jobs whose costing raised a warning (no rate-card rule for the type, priced below what it costs to run, nothing charged, or driver pay out of proportion), shown only to people who may see values; Off the road today — anything that cannot be booked today, with the reason; Equipment needing attention — vehicles and plant whose MOT, service, tax, insurance or LOLER is expired or due within 28 days. Price and margin columns appear only for people with those permissions.
Schedule — /schedule
Every lorry's day on one board, in the order it is driven. Each lorry is a row: its driver, what it carries, and its stops left to right — Load at the pit or yard, Drop at the customer, Tip at the tip — each with the time the lorry gets there, what is on the lorry afterwards, any wait for a customer's time window, and the time it is back at the yard. A lorry that is off the road or in the workshop says so and takes no work. Jobs not on a lorry lists the day's jobs still to place, each with the reason. Choose another day with Previous day, Next day or the date.
Build the day (/schedule/build) puts every job of the day that is not on a run already issued to a driver onto the lorries on the road. It keeps to four rules: a lorry is never loaded beyond what it carries; nobody is reached after their time window (arriving early means waiting); each lorry is back at the yard by the end of the day; and a job only goes on the kind of lorry it needs. Loads at the pit, drops, tips and back-loads fall into the order that adds the least time, with the work shared across the lorries that are out. A drop with weight but nowhere to load it is loaded at the yard, and the job says so. A job heavier than any lorry that may do it (three grab loads of muck-away) is done in loads: each load gets its own collection and tip, marked "load 2 of 3", and the job says so. Anything that cannot be placed is listed with why.
Moving a job (/schedule/move): drag any of a job's stops onto another lorry's row, or onto another job's stop to put it before that job. Both lorries' days are re-timed. A move that would put more on a lorry than it carries is refused and nothing moves; a move that makes a stop late is made, and the stop is marked after its window. On a phone, or without dragging, use Move a job: choose the job and the lorry.
Road times come from Google — the time a car takes, without live traffic, multiplied by the lorry factor in the settings. Every time looked up is kept, so the same journey is never paid for twice. The page says how many Google lookups have been used this month; it stops well inside Google's free allowance, so road times cost nothing. When it has stopped, or Google cannot be reached, a time is estimated from the straight-line distance, and the stop says time estimated.
The week — /schedule/week
Seven days, one row per lorry: how many drops each lorry has each day, and how many jobs each day are not yet on a lorry. A day's heading opens that day's board.
Schedule settings — /schedule/settings
How much slower a lorry is than a car, when lorries leave the yard and when they must be back, the minutes to load, at a drop and at a tip, and the most Google road-time lookups to use in a month. Owners and administrators change them; everyone else reads them.
Hire desk — /hire
Plant, containers, welfare units and toilets out on hire. Out on hire today, Coming off hire today or tomorrow and Booked to go out at the top; then every hire — its item, customer and site, the days on and off, how many days, the hire charge (to people who may see money) and whether it is booked, on hire or off hire.
Book a hire (/hire): what (each kind shows how many there are), to which site, the on-hire day and the last day on hire, and whether it goes with an operator. It takes the first item of that kind that is free for every day of the hire — not on another hire, not off the road, and with its LOLER examination and MOT in date to the end — or says why none is, and books nothing. It raises two jobs for the schedule: the delivery on the on-hire day (load at the yard, drop at the site, the transport charge) and the collection on the last day (collect from the site, back to the yard). The hire days go on the collection at the price list's rates: the first day, then the day-two-onwards rate, or by the week where that is less — the page says both sums. Days count both ends: Monday to Friday is 5 days. With an operator it is charged by the hour, 8 hours a day.
Off hire (/hire/:id/off): the day it actually comes back. The days are re-priced on the collection, which moves to that day, and the item is free from the day after.
Availability shows each item of a kind across fourteen days: a filled day is on hire (with the hire's number), "off" is off the road, a blank day is free. Under it, that kind's rates from the price list.
Requests — /requests
Calls waiting — what customers have asked for that is not a job yet. Take a request records one: Customer, Job type, Date wanted, Pickup address, Postcode, what3words, What they asked for → Save request. On a waiting request, Make it a job (/requests/:id/convert) turns it into a booked job.
Quote — /quote
Price a job before booking it: Job type, Customer, Service level, Collect from (postcode), Deliver to (postcode), How many items, Weight each (kg) → Work it out. The answer shows The trip (the distance it worked out) and How the price is made up, line by line from the rate card. If you may see costs, it also shows What it costs us, and the margin — the estimated cost to run, the margin in money and as a share of the price, and the cost lines — worked by the same rate card as the price, so the two cannot disagree. No vehicle is on a quote yet, so the cost is driver time, mileage, tip fees and overheads; the vehicle's own running cost joins when one is put on the job. Someone who sees values but not costs gets the price alone. Book it in opens Book a job filled in from the quote — the job type, customer, service level and distance — and carries the quote's collection and delivery postcodes, its items and its time on the job, so the booked job is priced on the same things as the quote.
Jobs — /jobs
Every job, filterable by Reference or customer, Status and Job type. Book a job opens the booking form.
Book a job — /jobs/new
Job type, Customer, Date wanted, Priority, Service level, Distance (miles), Email for updates (optional — where this job's "booked", "delivered" and "could not deliver" emails go; left blank, the customer's account email), Notes → Create job. The job is priced from the rate card as it is created. Opened from a quote, the form arrives filled in and the quote's stops and items go on the job as it is created.
One job — /jobs/:id
Everything about a job on one page:
- Before this goes out — the costing warnings on this job (the same ones the Dispatch card lists).
- Costing — Charged to the customer (price lines) and, if you may see costs, **What it
costs us with the margin. Recost this job** (/jobs/:id/cost) rebuilds both from the current rate card and measurements.
- Progress — the status steps; the buttons post to
/jobs/:id/status. cancelled and
failed ask you to confirm first; the job is kept on record either way — nothing is deleted.
- Measured — Distance (miles), Time on the job (minutes), Waiting (minutes), **Hire
days → Save measurements** (/jobs/:id/measure). What was actually done, against what was quoted.
- Stops — the collection and delivery points (Kind, Name, Address, Town), added
at /jobs/:id/stops; each has Mark done (/stops/:id/done). Once a driver has taken proof at the door, Proof of delivery under the stops shows who signed, when, the signature and the photo.
- Items (or Animals, for a job type that moves livestock) — what is being moved, for job
types that carry items; lines are added at /jobs/:id/items.
- Vehicle, plant and crew — the resources assigned (
/jobs/:id/resources). - Checks to do — the checklists this job type requires, each with Open; a new one is
started by the form that posts to /jobs/:id/checklists (shown only to roles that may progress a job).
- Offer it out — put the job to drivers (
/jobs/:id/offer): Open for (minutes), **Note to
the driver**.
- Payment — record money taken on the job (
/jobs/:id/payments): Method, **Amount
taken, Reference → Record payment**.
/jobs/:id/notify— queues the job's customer message for a given milestone (booked, on its way,
delivered…) without sending it. Booked, completed and failed send their messages by themselves when the job reaches them (see Messages); there is no separate button for this on the page.
Waste transfer notes — /waste
Every waste transfer note, kept for at least two years and never deleted: find one by its note number, a ticket number, the job or the customer. The carrier on every note (/waste/settings) holds the company's name, address and waste carrier registration, which every new note carries; owners and administrators set it.
On a job that moves waste (muck-away, skips, grab hire, tipping), Waste transfer note lists the job's notes and Make the waste transfer note (/jobs/:id/wtn) fills one in from the job: the List of Waste (EWC) code, what the waste is, how it is contained and how much (from the job's tickets); the transferor — the customer, with their SIC code — and the address of the transfer; the carrier and its registration; and the receiving site with its permit. Every one of those is needed or nothing is made, and the page says which is missing. A season ticket covers repeat loads of the same waste between the same parties for up to a year. Hazardous waste — a code with a star, such as asbestos (17 06 05*) — is refused: it needs a hazardous waste consignment note, not this.
A note (/wtn/:id) shows every field, who signed and when, and whether it was emailed; The PDF (/wtn/:id/pdf) is the note in the code of practice's four parts — the waste, the transferor, the transferee, the transfer — with both signatures. Sign it on the phone (/wtn/:id/sign): the driver signs for the carrier, the customer gives their name, confirms the waste hierarchy was applied and signs; both signatures are drawn with a finger. Once both have signed, the note is emailed to the customer as a PDF by itself; Email it again (/wtn/:id/send) sends it again. It says "emailed" only when the email service has taken it. Signing needs signal: the note is kept at the office, not on the phone. A driver's stop that collects waste shows Sign the waste transfer note until it is signed.
The customer's order — /jobs/:id/order
On a job: the customer's Order number and Site reference, as the customer's own paperwork asks for them. Saving puts the order number on the job's tickets that have none. A customer can be marked Order number needed on the Customers page (/customers/:id/order-numbers); a job or ticket of theirs without one is then flagged on the job, on the ticket, under Tickets with no order number on Dispatch, and on Money before a statement is built.
Weighing a load — /jobs/:id/weigh
On a job, under Tickets: Weigh a load takes the Gross and Tare in tonnes (26.40, 11.20), What was loaded from the price list (things sold by the tonne), and a Ticket number — blank takes the next in the 9xxxx series, or type the number the weighbridge printed. Ticket says whether the load was weighed out (loaded) or tipped (at the tip — a tip ticket points back to the load it came from), Came from is the pit or yard (the job's loading stop unless chosen), Batch or grade is optional, and the Customer's order number starts as the job's. It records the ticket with its net weight (gross less tare), the lorry and driver on the job's run, and the customer; puts the net tonnes on the job as a line at the price-list rate; and costs the job again. The job page then says what was recorded. It refuses, in words and recording nothing, a gross that is not more than the tare, something not sold by the tonne, or a ticket number already recorded. A net weight over the lorry's payload is recorded — it is what the weighbridge said — and marked over payload wherever the ticket is shown.
Tickets — /tickets
Every ticket: its number, when, the job, the customer, the lorry and driver, the net weight and what it was — and, for people who may see money, what it was charged. Find one by ticket number, registration, customer or job. Take in a weighbridge export (/tickets/import): paste the weighbridge's export with a header row (ticket, registration, gross, tare, and if it has them date, job and product). A row that names its job and a product sold by the tonne is charged onto that job straight away; any other row is kept as a ticket and listed under Imported, not on a job yet, where Put on the job (/tickets/:id/attach) charges it onto the job you give. A ticket number already recorded is refused, so taking the same export in twice changes nothing.
Each ticket's number also appears on the customer's statement, beside the job it was charged on, and in the statement's files for Xero and QuickBooks.
Where did a source or batch go? Type a pit or yard, or a batch or grade written on the tickets, and the page lists every customer it went to, with how many tickets, the tonnes, the dates and each ticket number. A search that is exactly one ticket's number opens that ticket's chain.
One ticket — the chain — /tickets/:no
Everything a ticket number leads to, on one screen: where it came from (the pit or yard, and its batch or grade), the load (what, gross, tare, net, when), the lorry and its registration, the driver, the job, the customer with their order number and site reference, where and when it was dropped (the pin from the driver's phone when the drop was done, who signed and the pictures), the line it was charged on, and the invoice line — the statement it is on. A tip ticket names the ticket of the load it came from, and a load names the tip tickets it became. A customer who needs an order number on every ticket gets a warning here when this one has none.
When a driver finishes a drop, the job's tickets take the phone's last position and the time; a drop on a job with no ticket at all is given a numbered delivery ticket, so every drop is a record.
A checklist — /checklists/:id
The questions for one check (vehicle walk-round, loading, handover…), Signed by, → Save answers. A job with an unfinished required checklist shows it under Before this goes out.
Runs — /runs
The rounds: a day, a vehicle, a driver and an ordered list of stops. New run (/runs, owners, admins and office): Name, Date, Driver, Vehicle → Make the run; you are taken to the new round to put stops on it.
One run — /runs/:id
The round and Stops in order, each with Done. Worth a look before this goes out flags capacity or distance problems. Plan it (/runs/:id/plan) sequences and times the round from Leaving the yard, Average speed (mph), Minutes at each stop and Road factor (crow-fly miles × this = road miles; 1.3 on Island lanes) → Sequence and time the round. A stop is completed at /runs/:id/stops/:stopId/done.
Add to this round lists the stops still to do on booked and scheduled jobs that are not on a round yet; tick them → Put the ticked stops on this round (/runs/:id/stops). A booked job put on a round becomes scheduled, and the round is put in order and timed (a postcode is looked up to place it on the map). Issue this round to … (/runs/:id/issue) — once it has a driver and at least one stop — sends it to the driver's phone. When the driver has started it, The round shows the van where their phone last said it was.
Messages — /notifications
Customer messages. When a job is booked, completed or failed, its customer is emailed by itself — from your company's name — using the message set up for that milestone, with the tracking link. Each message is kept with what it said, to whom and when, and its status says what really happened: Sent (the email service accepted it, with the time), Waiting, Failed (with the reason), or Not sent with the reason — no email address for the job, text messages not switched on, or a demonstration company, which never emails a made-up address. What each message says lists the messages; words in double braces are filled in from the job. If anything is waiting, Send the waiting messages now posts to /notifications/send.
Money — /money
Cash a driver has taken with Confirm received (/payments/:id/confirm); Statements — choose Customer, From, To → Build statement (/statements); and How people pay, the payment methods in use.
Each statement has CSV for Xero (/statements/:id/xero.csv) and CSV for QuickBooks (/statements/:id/quickbooks.csv) under For your accounts: your accounts package's own sales-invoice import file, one row per job, with UK dates and its UK VAT names. It imports as one invoice, numbered with the statement's reference, for the statement total — the rows always add up to it, because the statement's VAT is the sum of its lines' VAT. In the Xero file every row is coded to account 200, which is Sales in Xero's standard UK chart; if your sales account has another code, change it in the file before importing. PBS Haulage does not send anything to Xero or QuickBooks itself — you download the file and import it there.
A statement — /statements/:id
A statement on screen: each job on it with the customer's order number and site reference, and the tickets behind it — each ticket opens its chain — with the net and VAT, the total due, and the Xero and QuickBooks files.
Equipment — /resources
Vehicles and plant: Name, Kind, Category, Reg, Payload, £/mile, £/hour, £/day, Status, Compliance. Add equipment (/resources/new): Kind, name and details → Add.
Readiness — /readiness
Is it on the road and ready to go, for any day. Every lorry, trailer, machine, skip, container and welfare unit is On the road or Off the road with the reason (and the day it is back, if known), Available or Booked with what it is booked on, and any MOT, service, LOLER examination, tax or insurance due within 28 days. Something is off the road when it has been taken off, is in the workshop, or its MOT, LOLER examination, tax or insurance has run out. Off the road, it cannot be booked: the schedule leaves it out and says why on its row, Dispatch lists it under Off the road today, and putting it on a job or a run is refused with the reason. Plant, skips, containers and welfare units cannot be booked twice for the same day; a lorry can do many jobs in a day through its run. Each kind is a table you open.
Take something off the road (/readiness/off): the asset, why (service, repair, MOT, breakdown, safety inspection, other), from which day, the day it is back (or blank until it is put back), and a note. Back on the road (/readiness/:id/back) ends it early; the record is kept, with who and when.
Registers — /registers
The paperwork the operation must keep: Incidents and complaints, Vehicle checks, cleaning and defects, Consignment and transfer notes. Each is a record of what happened; none is a certificate.
People — /people
The crew: Name, Licences, Cost £/hr, Charge £/hr, Tickets. (Who may see values and costs is set on the person's account by the owner, not on this screen.)
Customers — /customers
The customer list: Name, Account, Rate card, Jobs, Terms. Nothing here is deleted. Archive (/customers/:id/archive), after a confirmation, keeps the customer with all their jobs, statements and payments and takes them out of the lists for new work (booking, quotes, requests); they are listed under Archived, and can still be put on a statement, marked (archived). Reinstate (/customers/:id/reinstate) brings them back.
Erase personal details… (/customers/:id/erase) — owners and administrators only; to everyone else the page does not exist. It is for a formal request to erase a person's data, and it is the one action that asks you to type to confirm: the customer's name. It erases the customer's name, phone, email, account code and notes; the names, addresses, contacts, what3words and map positions on their sites, job stops, requests and calls (a postcode is cut to its district, such as PO30); the email on their statements; the text of messages sent about their jobs; and their jobs' notes and update email and number. It keeps what the law requires a business to keep: their jobs with references, dates and money, statements and payments, the incident register and consignment and transfer notes. It cannot be undone; the page says what it changed, the customer is archived as "Erased customer", and the erasure is recorded with who did it and when.
Rate cards — /rates
Your tariff, and the only place prices come from. Lists every card with its VAT rate and how many rules it carries; the default card is marked. Owners and admins also get New card.
In the demonstration the default card is Example prices: lorry hire by the hour, out-of-hours lorry rates, tipping by the tonne or cubic metre, and aggregates by the tonne, taken from the example price list (see Price list). They show how the app prices a job; they are not any firm's current tariff.
If an hourly rate is below the National Living Wage, the app says so and leaves it alone. It tells you how much short, in money, and shows the floor it compared against. It does not quietly put the rate up: that would hide a typo and make the quote disagree with the card it was built from.
One rate card — /rates/:id
The card's rules in two tables: What the customer pays and What it costs us. The cost table is only shown to someone allowed to see costs, so an office user reads the customer side alone. Each row shows the invoice line, how it is charged, the rate, any band or free allowance, and what it applies to.
Every rule that matches a job is applied — they add up, they do not replace one another. That is how a base charge and a mileage charge work together. It is also the trap: a second weekend surcharge does not overwrite the first, it is added to it.
- Add a rule (
/rates/:id/rules) — the invoice line, the side, how it is charged, the rate,
and optionally a band, a free allowance, what it applies to, and minimum/maximum limits. Only when… narrows a rule without typing anything: weekends or weekdays, out of hours or working hours (the working hours are yours to set; both are judged on the UK clock from the job's own date and time), particular days, postcode areas, at least / at most miles or kg, at least so many items or stops, particular priorities, refrigerated loads. Leave it blank and the rule applies to every job. The card lists each rule's conditions in words (1 October 2026). The screen refuses to save a rule that would be charged on top of one already on the card, names the rule it clashes with, and keeps what you typed so nothing is lost. An unrecognised basis is refused outright rather than quietly changed to something else.
- Edit (
/rates/:id/rules/:ruleId/edit) — opens the rule in the same form, filled in;
Save the change (/rates/:id/rules/:ruleId) changes it in place. The same checks as adding a rule apply: a change that would be charged on top of another rule is refused, naming that rule, and what you typed is kept. A change applies to the next job costed; a job already costed keeps its figures.
- Retire (
/rates/:id/rules/:ruleId/retire) — after a confirmation, the rule stops being charged
and leaves the card; it is kept on record (the card says how many are), so a job costed with it can still be explained. A retired rule never blocks a new one.
Reading a card needs rates:read; changing one needs rates:write (owner or admin). Cost and driver-pay rules can only be added by someone who can see costs.
Price list — /prices
What a customer is quoted, built from the rates; Refresh from the job type, vehicles and checklists rebuilds it. Also lists the Checklists each job type requires.
Job types — /types
Delivery, collection, exchange, hire and any custom type: Type, Code, Direction, Switched on, Jobs, and what each carries (items, weight, volume, animals, hire days).
Your plan — /plan
Owners and administrators only. It shows the company's subscription once one exists. PBS Haulage does not take payment online yet: the page says so and links to Talk to us about your plan, and a request to start a payment (/plan/checkout) is refused with the same words, before anything reaches the payment service.
The driver's day
My run — /me
Today's round in the order the office set on the schedule, the Next stop on top, each with the time the lorry should be there, what will be on the lorry after it, and Mark done; Checks to do before setting off; and Work going spare — jobs offered out, with Take it (/offers/:id/accept) or Pass (/offers/:id/decline). A driver sees no prices or costs anywhere.
When a round has been issued to you for today, it shows at the top with Start my round (/me/runs/:id/start); once started, Finish my round (/me/runs/:id/finish). While the round is on, this page shares your phone's position (/me/location) — your phone asks you to allow it — about every half minute while you move, so the office's map and each customer's tracking page show where the van is; the page says when your position last reached the office. Outside a round, nothing is shared.
Your tickets today lists the tickets recorded against you today: number, time, job, net weight and what it was — no money.
Done, with proof… on a stop takes proof at the door: Signed for by (a name), a signature with a finger in the box (Clear the signature to start again), and an optional Photo from the phone's camera → Save - done, with proof. It works with no signal: the proof is kept on the phone first and sent to the office (/stops/:id/proof) as soon as there is signal — straight away, when the signal comes back, and every half minute. The foot of the page says how many are still on the phone (1 unsynced) or that every proof has reached the office; a stop says the office has the proof only once the office has answered for it. A proof sent twice (a retry after the signal dropped) is kept once. The page itself opens with no signal too: the phone keeps its last copy of My run (/sw.js).
What a customer sees
Tracking — /track/:token
No sign-in; the link is sent in the customer's message. Progress of their job, Where it is (the van's last reported position), Proof of delivery once signed — who signed, when, the signature and the photo (/track/:token/proof/:proofId, which opens only with that job's link) — and History. The token is the only key to it — the page shows one job and nothing else.
What this does not do
- It does not take card payments from your customers. It records what was taken and builds statements.
- It does not send text messages yet — only email. A text is kept as Not sent, with that reason.
- It does not certify a vehicle, a driver or a load. Registers are records, not approvals.