What this report is for
An engineer closes a job on a tablet at 4pm. The job system now says "complete". Nothing in the accounts says anything at all, and nothing will until someone raises an invoice. Between those two events the work is done, the cost is spent, and the cash is not even owed yet, because the customer has not been asked for it.
An unbilled jobs report lists every job in that gap. It is not a debtors report. Aged debt starts the day an invoice exists; this report covers the days before that, when the money does not appear on any ledger and so tends to go unnoticed. For a finance director the question it answers is simple: what have we finished that we have not asked to be paid for, and why?
The report only works if it compares two systems. The job system (Uptick, Simpro, Joblogic or similar) knows what was completed. The accounting system (Xero, Sage, QuickBooks) knows what was invoiced. Neither can produce the list alone, which is why it usually ends up as a monthly spreadsheet exercise rather than a daily one.
The data model
Fields you need from each system
| Source | Record | Fields used |
|---|---|---|
| Job system | Job | job ref, customer, site, job type, status, completed date, job value (net), quote ref, customer PO, contract ref, signed-off flag |
| Job system | Quote | quote ref, accepted value, deposit or stage terms |
| Job system or CRM | Contract | contract ref, billing basis (in advance, in arrears, per visit), billing schedule |
| Accounts | Invoice | invoice number, date, customer, net amount, reference field (job ref), PO |
| Accounts | Credit note | credit note number, date, net amount, invoice it credits |
The single most useful field is the job reference on the invoice. If your team types it into the invoice reference every time, matching is mostly mechanical. If they don't, you fall back to weaker keys, and the report has to say so.
The joins
| From | To | Join key | Strength |
|---|---|---|---|
| Job | Invoice | job ref = invoice reference | Exact |
| Job | Invoice | customer + PO + net amount | Probable, needs a person to confirm |
| Job | Quote | quote ref | Exact; gives the value to bill and any deposit already taken |
| Job | Contract | contract ref | Exact; decides whether the visit is billed separately at all |
| Invoice | Credit note | credited invoice number | Exact; nets the invoice back to zero or less |
The rules, in order
- Exclude jobs billed some other way. Planned maintenance visits under a contract invoiced quarterly or annually in advance will never have their own invoice. Flag them by contract ref and leave them out. Contracts billed per visit stay in.
- Exclude jobs with nothing to bill. Warranty call-backs, recalls to fix your own work, and no-charge goodwill visits. These should carry a job type or a zero value in the job system; if they don't, that is the first data fix.
- Net invoiced = sum of invoices carrying the job ref − sum of credit notes against those invoices.
- Unbilled value = job value − net invoiced, where job value is the accepted quote or the priced job sheet. A positive result is an exception.
- Reason code for each exception: no invoice found; part-invoiced (a deposit or stage bill, but no final); invoice credited and not re-raised; awaiting customer sign-off; awaiting a customer PO; probable match on PO and amount.
- Days unbilled = report date − completed date.
A credit note deserves its own reason. When an invoice is credited because it went to the wrong site or had the wrong rate, the replacement often never gets raised, and the job quietly looks billed if you only check whether an invoice ever existed.
Ageing and cash impact
Age every exception from the completion date, not the job creation date. Five buckets are enough: 0–7 days, 8–14, 15–30, 31–60 and over 60. The first bucket is normal working lag. Anything in the last two is either a process failure or a dispute nobody has written down.
The cash cost of delay can be kept to arithmetic without inventing an interest rate:
| Measure | Formula |
|---|---|
| Pound-days | Σ (unbilled value × days unbilled) |
| Value-weighted delay | pound-days ÷ total unbilled value |
| Held back per extra day | total unbilled value |
| Already due if billed on completion | Σ unbilled value where days unbilled ≥ payment terms |
The last line is the one boards understand. Every day of invoicing lag pushes the payment due date back by the same day, so on 30-day terms any job completed 30 or more days ago would already be due for payment if it had been invoiced when the engineer left site.
Daily check · 5 November 2026
Unbilled jobs report · Larkfield Fire & Security (fictional)
£36,425 of completed work
has no invoice yet.
14 jobs marked complete with nothing, or not enough, raised against them in the accounts. Contract, warranty and no-charge jobs are excluded.
- Unbilled value
- £36,425
- 14 completed jobs
- Over 30 days
- £5,795
- Since completion
- Weighted delay
- 17.9 days
- Value × days ÷ value
- Due by now if billed
- £12,640
- On 30-day terms
Ageing since completion
- 0–7 days£14,230 · 6 jobs
- 8–14 days£8,135 · 2 jobs
- 15–30 days£8,265 · 2 jobs
- 31–60 days£4,795 · 3 jobs
- Over 60 days£1,000 · 1 job
Cash impact
Each job’s unbilled value × days since completion, summed: 650,505 pound-days. Divided by £36,425, that is a value-weighted delay of 17.9 days.
On 30-day terms, £12,640 would already be due today had those jobs been invoiced on the day they were completed. Every further day without invoices holds back £36,425.
Exceptions, largest cash delay first
| Job | Customer | Days | Unbilled | Reason · to |
|---|---|---|---|---|
| J-31281Install | Brindle & Shaw Offices | 30 | £6,845 | No invoice foundFinance: Raise invoice |
| J-31307Remedial | Orchard Lane Care Homes | 57 | £2,135 | No invoice foundFinance: Raise invoice |
| J-31235Install | Ashcombe Academy Trust | 28 | £2,845 | Probable match, no job ref on invoiceFinance: Confirm match |
| J-31333Reactive | Ashcombe Academy Trust | 72 | £1,000 | No invoice foundFinance: Raise invoice |
| J-31269Install | Wexley Distribution | 34 | £1,890 | Part-invoiced (deposit only)Finance: Invoice balance |
| J-31213Install | Orchard Lane Care Homes | 9 | £6,920 | Awaiting customer sign-offOperations: Chase signed job sheet |
| J-31208Reactive | Ashcombe Academy Trust | 45 | £770 | No invoice foundFinance: Raise invoice |
| J-31324Reactive | Fenwick Cold Stores | 23 | £1,420 | Invoice credited, not re-raisedFinance: Re-raise or confirm write-off |
| J-31202Install | Tamsin Road Studios | 3 | £5,025 | Awaiting customer POAccount manager: Chase PO number |
| J-31295Remedial | Ashcombe Academy Trust | 7 | £1,685 | Awaiting customer POAccount manager: Chase PO number |
| J-31261Reactive | Lowther Medical Centre | 8 | £1,215 | No invoice foundFinance: Raise invoice |
| J-31249Install | Lowther Medical Centre | 4 | £2,375 | Part-invoiced (deposit only)Finance: Invoice balance |
| J-31232Remedial | Wexley Distribution | 3 | £2,170 | Awaiting customer sign-offOperations: Chase signed job sheet |
| J-31309Remedial | Tamsin Road Studios | 2 | £2,035 | No invoice foundFinance: Raise invoice |
| J-31241Remedial | Wexley Distribution | 1 | £940 | Awaiting customer sign-offOperations: Chase signed job sheet |
£2,845 in a probable match (invoice with no job reference) is listed for review but not counted until a person confirms it.
Deskless daily check · run log
Job management system + Accounting system
- 06:00Read completed jobs (job system, last 90 days)48 jobsSynced
- 06:01Read invoices and credit notes (accounts)31 invoices · 1 credit noteSynced
- 06:02Exclude contract visits billed by schedule7 jobsDone
- 06:02Exclude warranty, recall and no-charge jobs4 jobsDone
- 06:03Match on job reference, net of credit notes22 fully invoicedDone
- 06:03Match unreferenced invoices on PO and amount1 probable, not linkedFor review
- 06:04Build exception list and ageing14 jobs · £36,425Done
- 06:05Send list to Finance10 jobs · £22,530Delivered
- 06:05Send list to Operations3 jobs · £10,030Delivered
- 06:05Send list to Account manager2 jobs · £6,710Delivered
- 06:05Raise or alter invoicesOff in this set-up: finance decidesSkipped
Worked example (illustrative, fictional)
A fictional contractor runs the report on Wednesday 4 November 2026. Payment terms are 30 days. Seven jobs completed in the window:
| Job | Completed | Job value | Invoiced (net) | Status | Unbilled | Days | Pound-days |
|---|---|---|---|---|---|---|---|
| J-1041 reactive | 30 Sep | £1,850 | £0 | No invoice found | £1,850 | 35 | 64,750 |
| J-1056 install | 14 Oct | £6,400 | £3,200 deposit | Part-invoiced | £3,200 | 21 | 67,200 |
| J-1063 remedial | 27 Oct | £920 | £0 | Awaiting sign-off | £920 | 8 | 7,360 |
| J-1070 PPM visit | 29 Oct | n/a | n/a | Contract, billed quarterly in advance | excluded | ||
| J-1072 recall | 30 Oct | £0 | n/a | No charge | excluded | ||
| J-1078 reactive | 22 Oct | £1,240 | £1,240 − £1,240 credit | Credited, not re-raised | £1,240 | 13 | 16,120 |
| J-1081 reactive | 3 Nov | £480 | £0 | No invoice found | £480 | 1 | 480 |
Totals:
- Unbilled value: £1,850 + £3,200 + £920 + £1,240 + £480 = £7,690 across five jobs.
- Pound-days: 64,750 + 67,200 + 7,360 + 16,120 + 480 = 155,910.
- Value-weighted delay: 155,910 ÷ 7,690 = 20.3 days.
- Ageing: 0–7 days £480; 8–14 days £2,160 (J-1063 and J-1078); 15–30 days £3,200; 31–60 days £1,850; over 60 days £0. The buckets add back to £7,690.
- Already due if billed on completion: only J-1041 is 30 or more days old, so £1,850 would have been due on 30 October and is instead not yet invoiced.
- Every further day with none of these invoiced holds back £7,690; a one-week slip adds 7 × 7,690 = 53,830 pound-days.
If all five were raised today on 30-day terms, the earliest any of this cash is due is 4 December. Raised on completion, the money would on average have been due 20.3 days sooner.
The daily exception workflow
A monthly unbilled report finds problems after the month has closed. Run daily, the list stays short and each item is still fresh enough that someone remembers the job.
| Reason | Goes to | What a person decides |
|---|---|---|
| No invoice found | Finance | Raise it, or record why it should not be billed |
| Part-invoiced | Finance | Invoice the balance, or agree a retention with the customer |
| Credited, not re-raised | Finance | Re-raise to the right site or rate, or approve the write-off |
| Awaiting sign-off | Operations | Chase the signed job sheet or completion certificate |
| Awaiting PO | Account manager | Get the PO number from the customer |
| Probable match | Finance | Confirm the link so the invoice carries the job ref next time |
The decisions in the right-hand column belong to people. Whether a disputed job gets billed, whether a credit note was right, whether a goodwill visit really was free: those are commercial calls, and a report should present them rather than make them.
How to automate it with IVP.ai and Deskless
The IVP.ai Data Layer pulls completed jobs from your job system and invoices and credit notes from your accounts each night, keeps the job reference, quote and contract keys aligned, and applies the rules above. Uptick users can read how that connection works on the Uptick integration page.
A Deskless by IVP.ai agent then runs the check each morning, sends finance, operations and account managers only their own lines, and flags probable matches for review rather than linking them itself. In this set-up it doesn't raise, credit or change invoices. That's a configuration choice, not a limit: Deskless can be set up to raise invoices for jobs that match cleanly if you want it to, with the rest still routed to a person. Starting read-only follows the approach in agents that know when to stop: agents won't sign off anything they can't fully check, and a person keeps the decisions. More on how Deskless works.
Unbilled value is one line in a wider set of measures; the field service KPIs template shows where it sits, and engineer utilisation covers the labour side of the same jobs. The full list of templates is on the field service reporting hub.
To see this report on your own data, start with the free 48-hour build. We connect up to three sources, typically your job system and accounts, clean the data and set one report or agent running within 48 hours of read-only access. You then have 14 days of access to decide whether to choose a plan or walk away.