Today's business post is about the month end close, and why it is a review when the month was captured as it happened and a rebuild when it was not. The calendar's placeholder for this journal entry was "Month end used to take me a week". I cannot publish that sentence, because I have no record of how long month end took before I had a system, and I do not put a number in a post that I cannot point at on disk. What I do have is the record of the one number I used to pick by hand, and the morning it was found sitting on two clients at once.
The number I picked by hand
Until 16 July this year, my invoice numbers ran as one flat sequence. INV, the year, then a four-digit counter. Each time I raised an invoice I looked at the last one I remembered raising and added one. That worked for exactly as long as I remembered correctly.
On 16 July I found that one number was live on two invoices, to two different clients, at the same time. A second number, further back, was also on two documents. Neither client had noticed, and neither would have, because a client only ever sees their own invoices. It was found by a read of every invoice on disk, not by anything at the moment the number was typed, and the place it would otherwise have surfaced is the close: payments reconciled to invoices, and two documents answering to one reference.
That is the whole shape of a rebuild. The fact was known at the moment the invoice was raised: the number already existed. It was not checked against anything at that moment, so it became an exception to work out later rather than a check to confirm at issue.
What changed the same day
Three things, all on disk with that date on them.
Every new invoice number carries the client's tag. INV, the year, a short code for the client, then a counter that runs per client from 001. A collision across clients is now structurally impossible, because two clients cannot share a sequence, and a collision within one client is visible on sight.
A script chooses the number, and it reads the disk first. Before any invoice is written, a script scans every invoice on disk for that tag and returns the next free number. I use what it returns. The same script, run with no arguments, audits every invoice on disk and exits non-zero if any two share a number. That audit runs as part of the check before any document is reported done.
Nothing a client is holding gets renumbered. The two old collisions stay exactly as they are, and the script knows about them by name and does not flag them. A document a client already has is a fact. You do not repair a record by changing what the other party holds.
The tag alone would not have fixed this. I could have added a tag and still typed the counter from memory. The fix is the read of the disk before the write, and that it happens at issue, not at month end.
The pattern, three times over
Once I had that shape I started seeing it in the other checks I run.
On 18 August a proposal went out that had been verified and reported as fully checked, and it had no logo on it. Every check that was written for that document passed. The check that would have caught it had not been written, because I wrote the checklist fresh for that document and simply did not think of the logo. The fix was the same as the invoice fix: one script that checks every document against the same list, run before anything is reported done, and any new failure gets added to the script so it is caught forever. I wrote about what that gate checks on 16 September.
On 15 September I put three enquiries on hold rather than into the pipeline register, because the register records proposals and invoices, not every email that lands. Same shape again: the register is a place that will be read at month end, so what goes into it is decided at the moment of the event, by a rule, not reconstructed later from an inbox.
Invoice number, document gate, register entry. Three different checks, one rule under them: the fact is written down at the moment it is known, by something that reads what already exists, so the close reads the record instead of rebuilding it.
What my month end checks now
It is short, and every line is a confirmation rather than a search.
- The invoice audit exits zero. If it does not, that is the first thing to fix. I ran it while writing this and it exited zero.
- Every document that went out this month passed the gate before it left. That check ran at the time; the close does not repeat it.
- The register's status column is true today for every open row. I rewrite the sentence, not the row, when something has moved.
- Next month's SARS dates were computed once, from the SARS page, with the weekend rule applied, when the deadlines post went out at the end of August. The business post explains the rule.
None of that takes a week. I still will not say how long it used to take, because I did not measure it then. I measure it now, and I will put that number in a post when there are enough months behind it to mean something.
The line I would give a client
If your month end is a rebuild, the question is not how to close faster. It is which facts you knew during the month and did not write down where the close would look. Find those, move each one to the moment it happens, and let something that reads the disk choose the number. The close becomes a review because there is nothing left to reconstruct.
Chat soon.