The bid felt right. The bank account is not a job report.
A job makes or loses money on its own costs and its own billings. If lumber, labor, and the dumpster all land in one materials account, the company can look busy and you still cannot say whether the kitchen remodel paid for the truck. Retainage makes it worse. You billed it, the customer is holding it, and it is not in the bank, but it is still money owed to you. And the amount you have billed is not always the amount you have earned. Some jobs are billed ahead of the work. Some are behind. Those are different problems, and they do not show up in the checking account.
Every dollar of cost needs a job, or it is overhead on purpose. Materials bought for the Oak Street job, the crew hours on that job, the sub you hired for that job, and the permit for that job belong on that job. A single materials account for the whole company is a shopping total. It cannot tell you the margin. The software already has a place for a job, a customer, or a class. If that place is blank, the purchase is anonymous and the job report is fiction.
Overhead is real, and it is not a job. The office rent, the owner's truck if it is not on a site, the insurance that covers the company rather than one contract: those can sit in overhead and be looked at separately. What you must not do is park a job's lumber there because the job name was annoying to pick at the counter. One lazy code, repeated, is how a loser job hides inside a winner.
When the contract lets the customer hold back part of each bill until the job is done, you have still earned, or at least billed, that part. It is not cash. It is a receivable with a longer fuse. If you only record the cash that arrived, you understate what the customer owes and you understate the job. If you record the full bill as cash, the bank reconciliation breaks. The clean shape is: the full bill is the bill, the cash received is the collection, and the held-back piece sits as retainage receivable until they release it.
Do not net retainage against sales to 'be conservative.' You did the work you billed. The customer kept a portion by contract. Those are two facts. Netting them makes the job look smaller and makes the held money invisible, so when it finally arrives it looks like a surprise sale in a month when nobody was on that site.
Costs and bills do not move on the same day. If you have billed more than the work you have earned so far, you are overbilled. You are holding money for work you still owe. That is a liability, not extra profit. If you have done more than you have billed, you are underbilled. You have earned something that is not on an invoice yet. That is an asset, and it is also a cash problem, because you are funding the job for the customer.
You do not need a complicated percentage to see the shape. For each open job, put three numbers next to each other: cost so far, billed so far, and what the contract says the job is worth. If billed is far ahead of cost and the job is not almost done, you have spent the customer's money early. If cost is far ahead of billed, you are behind on paper and probably behind on cash. The month-end habit is to look at that trio before you call the month profitable.
Send the job list, the last few months of bills you sent, the bank and card statements, and whatever you use to track crew time, even if it is texts and a notebook. A cost code list is useful if you have one. You do not need to rebuild the jobs before you ask. The first pass separates company overhead from job cost, lists retainage that is still open, and flags jobs where billing and cost are obviously out of step.
What you get back is a job list you can read: cost, billed, retainage still out, and a note on which jobs are ahead or behind. The bank will match. The jobs will no longer share one materials bucket. Draws and loan payments stay out of job cost, so a job does not look unprofitable because the truck note was coded to it, and it does not look profitable because a draw was coded as income.
The bill records what the customer owes, including the part they are holding. The cash is recorded when it arrives. Leaving the held portion off the books entirely makes the receivable disappear until a later month, when it looks like found money.
You can, and then you will not know which job lost money until the year is over and the people who knew have forgotten. Coding the job when you buy the material is the whole system. Year-end sorting is a reconstruction, and it is always worse.
Crew time, subcontractors, permits, equipment rented for that site, and the dumpster if it was for that job. If it exists only because that job exists, it belongs on the job. If it would exist with no jobs open, it is overhead.
If your file looks like this, start with a free look: construction QuickBooks cleanup.