Construction Job Costing With AI: Find Which Jobs Actually Made Money

Coding Liquids tutorial cover featuring Sagnik Bhattacharya for Construction Job Costing With AI: Find Which Jobs Actually Made Money.
Coding Liquids tutorial cover featuring Sagnik Bhattacharya for Construction Job Costing With AI: Find Which Jobs Actually Made Money.

Export every cost line from your accounts with a job tag, add labour hours from timesheets at a blended hourly cost, and total the lot against what each job invoiced. A spreadsheet does the sums. AI builds the formulas, spots lines coded to the wrong job and explains the gaps, so you see which jobs earned their margin.

Expect the first margin table to be wrong. Costs end up on the wrong job, labour hours go missing and a supplier bill gets entered twice, so a job can look like a loser or a star for reasons that have nothing to do with the work. The method below is built around finding those errors before you act on the numbers.

Follow me on Instagram@sagnikteaches

Decide what counts as a job cost before you export anything

A margin table is only as honest as the line between job costs and overheads, so draw it first and write it down. The test is simple: if a cost would not exist without this job, it goes on the job.

Connect on LinkedInSagnik Bhattacharya
  • Job costs: site labour, materials bought for or delivered to the job, subcontractors, plant hire, skips and waste carriage, job-specific fees, and anything you bought only because of the contract.
  • Overheads: rent, office wages, insurance, software, marketing, and the vehicles and tools that serve every job.

The grey list is where margin tables go wrong: fuel, consumables such as fixings and sandpaper, small tools, supervision time and van running costs. Pick one rule for each and keep it. Either charge them to jobs through a flat allowance in your hourly rate, or leave them in overheads and accept that job margins will look better than they are. Mixed treatment makes one month's table impossible to compare with the next.

Subscribe on YouTube@sagnikteaches

Labour needs a rate before it needs hours. A blended hourly cost is wages plus on-costs plus an allowance for the van and tools. An illustrative sum: $26.00 an hour gross pay, plus 22% employer on-costs (payroll taxes, pension and insurance; ask your accountant for your real percentage), gives $31.72. Add $4.10 an hour for vehicle, tools and consumables and the blended cost is $35.82, which the tables below round to $36. If you employ clearly different grades, such as labourers and carpenters, use one rate per grade. Price the owner's own site hours at what a supervisor would cost, or every job looks more profitable than it was.

The Complete Excel Course with AI Integration thumbnail

The Complete Excel Course with AI Integration

From formulas and pivot tables to Power Query, DAX, VBA and AI with Copilot, ChatGPT and Claude — hands-on from the first lesson.

By Sagnik Bhattacharya and Virginia Thorn, Primetime Emmy Award winner

Buy now

Tag costs by job in Xero or QuickBooks, at the point of entry

In Xero, tracking categories are the usual route. Create a category called Job with one option per job, such as J-1041 Rear extension, and tag each bill line, spend-money line and invoice line. Xero's developer documentation says an organisation can have up to two active tracking categories (four in total, counting archived ones) and recommends staying under about 100 options in a category, because longer lists slow report loading. So archive the option when a job closes. Xero's pricing page lists a Projects feature for tracking time and costs against projects on the Established plan ($97 a month at list) and not on Early ($27) or Growing ($59). Its FAQ also mentions usage charges for Xero Projects, so read the terms before relying on it. The page does not list tracking categories by plan, so check Settings on your own plan before building around them.

In QuickBooks Online, Projects are listed on the Plus plan ($140 a month at list) and Advanced ($340). You pick the project in the Customer/Project field on a bill, cheque or expense, and the project profitability report exports to Excel. You switch Projects on under Account and settings, in the Advanced section. Intuit's help article says the equivalent setting in its accountant product cannot be turned off once enabled and is silent on QuickBooks Online itself, so confirm with your bookkeeper before you click. Plus also lists 40 classes and locations, and Advanced lists unlimited ones, which is another way to tag a job if you have fewer than 40 live at once. Simple Start ($38) and Essentials ($85) list neither, so owners on those plans tag in the spreadsheet instead, which is where the AI step below earns its keep. At the other end, Advanced lists a construction financials option (job costing, change orders and work-in-progress reports), which is worth a look before you build anything if you are already on that plan.

Whichever package you use, tag when the bill is entered, not at month end. Whoever approves the bill checks that the job field is filled in, because an untagged bill is a cost that will land on the wrong job later. If tagging is not possible yet, start every bill's reference or description with the job code (J1041 timber), so an export can be sorted by job and an assistant can read the code back out.

The export: which columns to ask for

Run the line-level transaction report your package offers for the date range of the jobs you are reviewing. In Xero that is the Account Transactions report; check that its layout shows your Job tracking category, so every line carries its job. In QuickBooks Online, a transaction detail report filtered to your project customers gives the lines (projects sit under their customer), and the project profitability report under Projects gives each job's totals to check against. Totals by job are useful, but the individual lines are what let AI find mistakes. Aim for one row per cost line with these columns, here with five illustrative rows:

Date,Supplier,Description,Account,Amount,Job,Ref
2026-09-03,Timber merchant,C24 joists and noggins garage roof,Materials,2418.60,J-1046,INV-30417
2026-09-04,Plant hire firm,Mini excavator 3 days,Plant,540.00,J-1049,H-9921
2026-09-08,Plumbing merchant,Kitchen waste and traps,Materials,1186.40,J-1047,INV-30502
2026-09-08,Plumbing merchant,Kitchen waste and traps,Materials,1186.40,J-1047,INV-30502
2026-09-10,Skip hire firm,8-yard skip,Overheads,640.00,,SK-2204

Before anything goes near an assistant, strip bank account numbers and employee names, sort by job and then date, and check one number. The total of the Amount column must equal the job-cost lines of your profit and loss report for the same dates. If the two differ by more than rounding, stop and find out why (a bill dated outside the range, a journal, a report filter), because every margin built on the export inherits the gap. Exports also arrive with merged headers, subtotal rows and dates stored as text, and the tutorial on cleaning messy data deals with those.

Labour: timesheet hours at the blended rate

Labour is usually the biggest cost and the worst recorded. Ask for one timesheet table with four columns: date, worker (initials are enough), job code and hours. Every working hour gets a code, including OVH for yard and office time, so nothing floats free. Then run one control each week: hours on job codes, plus OVH, plus unallocated, must equal the hours paid in payroll. Illustrative controls for three weeks:

WeekPayroll hoursHours on job codesHours coded OVHUnallocatedAction
383122762412Ask the foremen which jobs
39308291170None
40320262223636 hours typed as J-1064, not on the job list

Week 40 is the useful one. The 36 unallocated hours were typed as J-1064, a code that is not on the job list. Ask the assistant to list every timesheet line whose job code is missing from your job list and it will find typos like that in seconds. A look at who worked where that week shows the real job, which here was J-1041. Once the hours are corrected, hours times the blended rate gives labour cost: 640 hours on J-1041 at $36 is $23,040.

Build the margin table, and check it against the books

The figures below are illustrative, for a small contractor with six people on the tools and five completed jobs. Margin means invoiced value minus cost, and margin percentage is margin divided by invoiced value, not markup. The first table shows what the raw export produced and what the corrected costs gave, because the gap between them is the point.

JobInvoicedFirst-run costFirst-run marginCorrected costCorrected margin
J-1041 Rear extension$92,500$73,424.0020.6%$75,360$17,140 (18.5%)
J-1044 Loft conversion$68,000$53,300.0021.6%$53,300$14,700 (21.6%)
J-1046 Bathroom refit$14,800$17,930.60-21.2%$15,512-$712 (-4.8%)
J-1047 Kitchen refit$23,400$20,654.4011.7%$19,468$3,932 (16.8%)
J-1049 Garage conversion$31,200$22,071.4029.3%$24,490$6,710 (21.5%)
Total$229,900$187,380.4018.5%$188,130$41,770 (18.2%)

The corrected costs break down by type like this:

JobLabourMaterialsSubcontractPlant and otherTotal cost
J-1041$23,040$31,870$17,300$3,150$75,360
J-1044$14,760$19,430$16,900$2,210$53,300
J-1046$6,552$5,940$2,400$620$15,512
J-1047$6,768$9,210$2,950$540$19,468
J-1049$9,180$9,870$4,100$1,340$24,490
Total$60,300$76,320$43,650$7,860$188,130

You do not need to write the summary formulas yourself. Describe your sheet to an assistant and ask for SUMIFS formulas plus a control row:

I have a sheet called Costs with columns A to G: Date, Supplier, Description, Account, Amount, Job, Ref. Account values are Labour, Materials, Subcontract, Plant and Overheads.
I have a sheet called Summary with job codes in column A and cost types across row 1.
Write the SUMIFS formula for the first cell, and one for a Total cost column.
Then add a control row that shows the difference between the Summary grand total and SUM of Costs column E. It should show 0 when they agree.

Three totals must agree before you read a single percentage: the sum of every job's cost in the table, the sum of the Amount column on the cleaned Costs sheet, and the job-cost lines of your profit and loss report. In the corrected table the total cost is $188,130 and the total margin is $41,770, which is 18.2% of $229,900 invoiced. If a column of the first table looks too good (the garage conversion at 29.3%), that is a reason to look harder, not to celebrate.

Let AI hunt for coding errors, then decide yourself

Give the assistant the cleaned export and your job list with start dates, finish dates and final invoice dates. Ask it to flag, never to fix. A flag is a question, and you answer it from the bill or the delivery note.

Review the cost lines below against the job list. Do not change anything. Return a table of flags with: Line ref | Issue type | Why flagged | Job it may belong to | Confidence (high, medium, low).

Look for:
1. Possible duplicates: same supplier and amount within 7 days, or the same ref entered twice.
2. Costs dated before the job started or after its final invoice.
3. Description words that do not fit the job (for example a roof described on a bathroom job).
4. Costs in overhead accounts that look job-specific (skips, plant, fuel, site fees).
5. Job codes that are blank or not on the job list.
6. Credit notes with no matching bill.
Supplier deposits are normal. Do not flag them unless the amount is repeated.

JOB LIST: [paste]
COST LINES: [paste]

Illustrative output on the five sample rows plus the timesheet typo:

LineIssueWhy flaggedMay belong toConfidence
INV-30417, $2,418.60Description fitJoists described as "garage roof" on a bathroom jobJ-1049High
INV-30502, $1,186.40DuplicateSame ref and amount entered twice on J-1047Remove one entryHigh
SK-2204, $640.00Overhead that looks like a job costSkip hire in Overheads with no job tag, dated during J-1041J-1041Medium
36 hours, week 40Unknown job codeJ-1064 is not on the job list; same crew had no J-1041 hours that weekJ-1041Medium

Open each bill before accepting a flag. Re-code the line in your accounts as well as in the sheet, or the same error returns next month. If the assistant flags something harmless, such as a genuine deposit paid before the job started, reject it and add a line to the prompt so it stops asking.

The sums show why this step matters. Moving the $2,418.60 timber line from the bathroom to the garage lifts the bathroom from -21.2% to -4.8% and drops the garage from 29.3% to 21.5%. Add the duplicate, the skip and the 36 hours, and the portfolio's total cost only moves by $749.60 (from $187,380.40 to $188,130). Coding errors mostly shuffle money between jobs, which is exactly why they hide the true winners and losers.

Bills that cover two jobs, stock and credit notes

Some costs do not belong to a single job, and written rules stop them being coded by whoever is in a hurry. Tell the assistant your rules in the prompt, so its flags follow your policy rather than its own guess.

  • A merchant's bill covering two sites. Split it line by line from the delivery notes, not 50/50. If the notes are missing, split by each job's share of that material in the estimate, and write the rule you used in the description.
  • Stock bought in bulk. A pallet of plasterboard or a trade-counter order of fixings sits in a stock or overhead account and is charged to jobs when it leaves the yard, using an issue sheet. Otherwise the first job to receive the delivery carries the whole cost.
  • Credit notes. A refund for returned tiles goes back to the job that bought them, with the original bill reference in the description, so that job's net cost is right.
  • Staged subcontractor invoices. Tag every stage to the job, then check that the stages do not add up to more than the subcontract value without a recorded variation.
  • Overtime and travel time. The blended rate uses standard pay. Decide once whether premium pay is a job cost, and if it is, give it its own line so it does not vanish into the average.

Reading the table: why each job landed where it did

A margin figure tells you where to look, not what happened. For any job below your target, compare actual cost with the estimate by cost type. The bathroom refit, estimated at 120 hours of labour, shows the pattern:

Cost typeEstimateActualDifference
Labour (120 hours estimated, 182 used, at $36)$4,320$6,552+$2,232
Materials$6,120$5,940-$180
Subcontract$1,800$2,400+$600
Plant and other$600$620+$20
Total$12,840$15,512+$2,672

The estimate promised a margin of $1,960 (13.2% of the $14,800 invoiced). The job delivered -$712. Ask the assistant to compare estimate and actual and list the three largest variances, then to write questions for the site manager rather than guessing causes. For the bathroom the output might read: labour is 62 hours (about 52%) over the allowance, subcontract is $600 over, no variation was recorded, and the questions are whether the client asked for extra tiling and whether a late delivery cost a day. An unrecorded extra is a pricing leak, which the tutorial on pricing variations and change orders addresses at the source.

Now step back to the portfolio. If overheads run at 14% of turnover and you want an 8% profit, jobs must average a 22% margin before overheads. On $229,900 invoiced, 22% is $50,578 and the five jobs earned $41,770, so they fell about $8,800 short. Split by job, the bathroom refit accounts for $3,968 of that (22% of $14,800 is $3,256, and it lost $712) and the rear extension for $3,210 (22% of $92,500 is $20,350 against $17,140 earned). The bathroom is the louder warning, but the extension's gap is the one to understand before the next extension is priced: 3.5 percentage points looks small until it is applied to a large contract value. The markup versus margin tutorial shows how to turn a target margin into a price.

Two limits. Margin is not cash: retention held by clients and unpaid invoices sit outside this table. And open jobs need a different calculation, because costs to date mean nothing without the work done to date. Use margin tables on completed jobs and the work-in-progress approach in AI in construction accounting on open ones.

A monthly routine that takes about an hour

  1. Finish the bank reconciliation, so every cost is in the books (about 15 minutes of checking if your bookkeeper has already done the work).
  2. Export costs and timesheets, then run the three-total control. Stop if the totals disagree.
  3. Run the flag prompt, open each flagged bill and re-code the real errors in the accounts.
  4. Refresh the summary and read the margin column from lowest to highest.
  5. Spend fifteen minutes with the site manager on the bottom two jobs, using the estimate-versus-actual comparison.
  6. When a job closes, write a three-line closing review (what the estimate missed, what you will change, who owns it), then archive its tag or mark the project complete so stray costs stop landing on it.

An illustrative closing review for the bathroom refit, kept to the three lines it needs: the estimate missed about 62 hours of tiling labour and a second day from the tiler ($600); no variation was raised when the client changed the layout; next time the quote form gets a question on tile pattern and a variation form is signed on the day. Name an owner and a date. A review nobody owns is a note, not a change.

These times are planning figures, not measurements, so time your first month and adjust. The first run takes the longest because the tagging backlog surfaces all at once. If you want a spreadsheet to build the summary in, the job costing sheet in Excel tutorial covers the layout, and the QuickBooks financials tutorial covers where AI sits in that package.

Keeping pay rates and names out of the chat

Job-cost exports can carry employee names, pay rates, bank details and supplier terms, and none of the margin sums needs them. Use initials or staff numbers, work with the blended rate rather than individual wages, and delete bank and payee-detail columns before you upload. Supplier names can stay, because the duplicate and description checks rely on them. On a personal ChatGPT or Claude plan, find the model-training switch in privacy settings and turn it off before the first upload. The business plans (ChatGPT Business, Claude Team) leave your content out of training by default, but each needs at least two seats, so a one-person office may prefer an individual plan with the switch off and the export stripped.

If the cost sheet lives in Excel on a Microsoft 365 business plan, the Copilot side pane can run similar checks inside the workbook: basic access comes with plans eligible for the free Copilot Chat, and the paid Copilot licence adds more. Microsoft retired the COPILOT worksheet function on 14 September 2026, so do not build a process on it.

Job costing questions small contractors ask

Can AI connect straight to Xero or QuickBooks?

Some assistants offer connectors to accounting packages, but an export is the safer first step. You choose exactly which columns leave the books, you can strip names and pay rates, and you can check the export total against your profit and loss report before anything is analysed. Direct connections add convenience once your tagging is clean, not before.

Should overheads be spread across jobs?

Keep job margin before overheads, then compare the total across all jobs with your overhead bill. Spreading rent, office wages and insurance across jobs by formula hides which jobs earn their keep, and one large overhead entry can turn every job red. The sum that matters is whether total job margin covers overheads plus the profit you want.

How many jobs do I need before this is worth doing?

Even three or four jobs show whether your estimates are close, because the value comes from comparing jobs with each other. Start with the last five completed jobs rather than open ones, since their costs are final. Once you have a margin table for those, adding each new job takes minutes.

What should I do about a job that lost money?

Find out which line caused it before you change prices: hours over the allowance, a materials price rise, an unpriced variation or a coding error. Then fix the cause, which might be the estimate, the site supervision or the paperwork, and note it on the job's closing review so the next estimate starts from the real figure.

Further reads

Sources: Xero pricing page and developer documentation on tracking categories; QuickBooks Online pricing page and Intuit help pages on Projects and exporting reports; OpenAI business data page; Anthropic privacy centre.

Want to see which jobs pay before the year ends?

On a 1:1 call we'll look at how your jobs are tagged in your accounts today, pick the cheapest fix for the gaps, and build a monthly margin check your office can run without me.

Book a 1:1 call with me