A rental company owns 20 of something. Twenty of these units go to a three-day event. On Monday, 18 come back. On Tuesday the last two arrive. One of the Monday eighteen has a cracked frame.
Everything a rental business needs to know about that item from Monday onwards can be answered from one line:
20 owned = 17 in the warehouse + 2 at the client + 1 in repair + 0 written off
It reads like bookkeeping. It is the whole design. Most inventory software keeps one number per item, a quantity, and adjusts it when things go out and come back. One number cannot tell you that a unit is back but not usable, or out but due today, or gone for good. Four numbers can, as long as they always add up to the fifth.
I built the order system for an equipment rental company with six branches around that line. Here is how each question a rough event raises turns into a move between those four counts, and the two guards that keep the line true.
Who decides a unit is damaged
Whoever does the return check at the warehouse. Not the driver, who saw it loaded in the dark, and not whoever notices three days later.
The check is a short form: for each product on the return, how many are fine, how many repairable, how many unusable. Submitting it moves units out of "at the client" and into "warehouse", "in repair" or "written off" in one step. The person's name, the counts before and after, and the order go into a movement ledger that is never edited.
When sales find out
They do not have to be told. A salesperson quoting for next Friday sees what can be rented, which is warehouse plus at-client (because at-client units are only lent, and the dates decide whether they are back in time). Repair and written-off are not in that number. So the moment the Monday check puts one unit in repair, every quotation built from then on sees 19, not 20, with no message sent and no sheet updated.
That is the point of the four counts over one. A single quantity of 20 would have to be edited down to 19 by someone who remembered, and edited back up when the repair was done, by someone else who remembered.
Half the order is still at the venue
The check does not wait for the whole order. Monday's 18 are checked on Monday; Tuesday's 2 on Tuesday. Each check moves exactly the units it covers.
The reason this is allowed is also the reason it needs a guard: nothing stops a tired supervisor from checking Monday's return twice, and a second check would put the same 18 units back into the warehouse a second time. So each check is tied to the specific return paper it grades, and the system refuses to grade the same return and product twice. Tuesday's check can only grade Tuesday's two.
The first guard: never more back than went out
A return cannot bring back more units than were dispatched for that product, and a check cannot grade more than came back. Obvious, and the first version of the system got the ceiling wrong.
It capped the check at the quantity on the order. Twenty ordered, so at most twenty checked. Then a crew sent two extra units on the day, a replacement for a faulty one and a spare, which crews do. Those extras had left the warehouse on the outward challan, so the counts said 22 at the client. The check would not take more than 20. The two extras had no way back in. They sat on the shelf while the counts said they were still out.
The ceiling is now what actually left the warehouse, not what was ordered. The line still has to add up; it was the cap that was measuring the wrong thing.
The second guard: the database refuses a line that does not add up
Every move above is written as a single transaction: subtract from one count, add to another, write the ledger row. If anything fails halfway, the whole move is rolled back. That stops the half-done case.
It does not stop a bug. A mistake in code can subtract from "at client" and add to "warehouse" a different amount, and both halves will succeed. So the rule is not only in the code. The database itself carries the constraint that warehouse + at client + in repair + written off must equal owned, and refuses any row where it does not. During a data load this month, a check that would have made the counts add up to 12 against 10 owned was refused before it was written, and the error named the item. Without the rule it would have been a quiet drift found weeks later.
I would not ship a rental system without this. Code is where the bugs are. The database is where the rule should live.
Who puts a repaired unit back
A person, on purpose. Someone moves it from "in repair" to the warehouse and has to type a reason. That move, like every other, goes into the ledger with their name and the counts before and after.
The ledger is what makes the four counts trustworthy rather than just four numbers. "Why do we have 17?" can be answered by reading it backwards: a check on this order put one in repair, a check on that order wrote one off, a repair on this date brought one back.
Can the order close with a unit unaccounted for
No. The order stays open until every unit that left the warehouse, including the two extras, has been through a check. Closing an order is not a stock move; the units moved at the check. Closing says only that nothing more is coming back.
The question it does not answer
Who pays for the cracked frame.
The system does not decide this and does not add a damage charge to the bill. What it gives you is the record: against that order, on that date, this person checked the returned units and found one unusable, and here is the movement that followed. Whether you charge the client, absorb it or negotiate is a matter for your contract and the relationship.
If you run rentals and have a rule for that which works — a deposit, a fixed rate per unit, a clause in the contract — I would like to hear it. It is the one question here the four counts cannot answer.