Flow
Options for receipts with no counts
1Assume nothing arrived
Inbound looks too high, so the planner under-buys.
2Assume everything arrived
Inbound drops to zero, so the planner buys goods that are still on the way.
3Stop and ask
No made-up number, but no plan for that supplier until a person sorts out the order.
4Close it with a full receipt
If the shipment really finished, a full receipt clears the old partial.
Units already on their way to this store had a slot in the case planner, and the value in it was a plain zero.
It was a placeholder. Probably nothing could fill it yet when I added it. Then it stayed. So every plan looked at stock and sales and assumed nothing was coming. If last week's order is still on a truck, the shelf looks empty, and the planner wants to buy it again.
What counts as sent, and what counts as received
What's on the truck is what you sent minus what you got. The hard part is deciding what each of those words means.
Sent should only mean the latest version of an order that really went out and isn't finished. Skip drafts, cancelled orders and old versions that got replaced. Count delivered orders, because delivered just means the carrier dropped them off. Nobody has counted them onto the shelf yet.
Received has to be per line, not per order. My receipts are stored as JSON in the order's event log, which I'm not proud of. Full receipts are easy. Newer partial receipts list each line and its count. Older ones give no numbers I can read.
And each line has to point at the right planning group by its ID, not its name. Names change. IDs don't.
When a receipt says partial and nothing else
If you guess nothing arrived, you under-buy. If you guess it all arrived, you're back to buying twice. So I don't guess. The planner stops for that supplier rather than guessing.
A partly arrived order whose history is unclear gets listed as needing a person.
It stops for the whole supplier, not just that order, because one case of goods can be split across several stores. A plan built with one store's number missing gives a case count that looks right and isn't.
Stricter receipts going in
I made the receiving side strict in the same change. A partial receipt must list exact lines and whole counts. It can't name a line from another order or go over what was ordered. A partial that finishes the order has to be sent as a full receipt instead. A full receipt can always clear an old vague partial. And the order gets locked while a receipt is saved, so two receipts at once get checked one after the other and can't add up past what was ordered.
Five order states on a real database
Unit tests check the math. An opt-in test on a real database walks orders through sent, partly received, fully received, cancelled and replaced, including two receipts at the same moment. The number I actually care about is how much less the planner orders, and I don't have it yet.