The Money, and the Record That Goes With It
Most small-business CRMs stop at won, and the spreadsheets start. Why an issued invoice freezes, why overdue is computed at read time rather than by a background job, what the margin figure does and does not know, and why an empty section of a client report stays on the page.

The question that opens this section: what happens to a small business at the exact moment its CRM says the word won. What happens is that the software stops and the spreadsheets start. Most small-business CRMs treat the closed deal as the finish line, because the CRM was sold to a sales team and the sales team's job ends there. But for the buyer, won is the start of the part that decides whether the year was any good. The invoice gets written somewhere else. The payment gets recorded somewhere else, often twice and occasionally never. What the work actually cost to deliver is either tracked in a separate system or, far more commonly, is not tracked at all and gets replaced by a feeling. And the report the client is owed at the end of the month gets assembled by hand in a word processor by whoever has the fewest excuses. Every one of those handoffs is a place the number can quietly stop being true. So Canopy runs the rest of it, and the design principle through the whole money layer is that a financial document is a claim somebody else is holding a copy of. That single idea produced most of the decisions here, and it is the reason this section is stricter than any other part of the product. A quote becomes an invoice rather than being retyped as one. The moment an invoice is issued it freezes, and its PDF never changes again. That is the constraint everything else follows from. The alternative, which is what a spreadsheet or a word processor gives you by default, is that the document is editable forever, which means the copy in the client's inbox and the copy in the system can silently disagree and neither party can prove which one is older. A correction in Canopy is therefore a void with a reason attached and a reissue under a new number, never a quiet edit of a document somebody already has. This is slightly more work in the moment and it is not negotiable, because the version that is less work is the version where a client can be told they are looking at an out-of-date invoice they were never sent. Payments recorded against an invoice walk it through its own status without anybody setting one. Nobody marks an invoice paid. The payments are the facts, the status is derived from them, and a partially paid invoice says so with the remainder visible rather than sitting in a bucket somebody chose. This removes a class of error I have watched cost real money: the invoice that is marked paid because a payment was expected, and then the payment does not arrive, and the invoice is now invisible to every overdue view in the system because its status says the matter is closed. Overdue is computed from the due date every time the page renders. It is not written by a background job, and the distinction is not academic. A status that a scheduled job maintains is a status that is correct only if the job ran, and the failure mode when it does not run is the worst one available: the aging report looks healthy, the overdue total looks small, and nothing anywhere indicates that the number is stale. Deriving it at read time means the aging strip cannot be wrong about the calendar, because it asks the calendar every time somebody looks. There is no background process to check on, and no morning where the money view is quietly reporting yesterday. Recurring reminders fire on their due morning and then re-schedule themselves from the original calendar rather than from the moment they fired. That second clause is the one that took a rewrite to get right. A reminder that re-schedules from its actual fire time drifts, and a monthly reminder that misses a day by an hour becomes a reminder that arrives a day later every month until it has walked halfway around the calendar. Re-scheduling from the intended date means a missed day fires once, late, and then the cadence is exactly where it was. A day that goes wrong costs one late reminder rather than a permanently crooked schedule. Delivery cost is logged against the work it belongs to, as hours or as expenses, which is what turns margin from an opinion into a reading. The buyer does not have to guess which client is worth having. Profit and health puts cash received next to what was tracked to earn it, with a twelve-month chart and a per-client table beside it, and the per-client table is usually the one that changes somebody's mind, because almost every service business has at least one client they are proud of and losing money on. The honest exclusion, and it is the most important sentence in this section: the cost side counts what Canopy itself tracks. The margin is a read over the buyer's own operating data, not a books-grade number, and it does not know about the things that never entered the install. It is not an accounting system and I am not going to dress it up as one. The ledger exports to CSV for whoever does the books, and the buyer's accountant remains the authority on what the business earned. What this layer gives the buyer is the ability to see, in the month it is happening, that a particular client is consuming more hours than they are paying for, which is a question an accountant answers in April at the earliest. The monthly client report is assembled from what the install already holds, and the part I care most about is what it does when it has nothing to say. A section with no data stays on the page and states which kind of nothing it is. Measured means the answer is here. Nothing this period means I looked and there genuinely was none. Cannot measure means this is not visible for this client at all. Those are three completely different claims and collapsing them into a blank space or, worse, into a hidden section, is where automated client reporting earns its bad reputation. A section that quietly vanished the month its number got worse does not read to a client as a formatting decision. It reads as something being hidden, and the client is right to read it that way, because on most platforms that is exactly what it is.

The operational consequence the buyer feels is that the chain from quote to margin has no gaps in it where a number can be retyped, rounded, forgotten or improved. The quote becomes the invoice, the payments move the invoice, the cost lands on the work, the margin falls out of the two, and the client's report is built from the same records rather than from a separate act of authorship. Nobody has to reconcile anything at month end, because nothing was ever kept in two places. And every document the buyer has sent to somebody else is still, byte for byte, the document that person is holding.