Three numbers, three different jobs
A warehouse count, an allocation against an order and the quantity offered for sale answer different questions. Calling all three stock makes a report shorter, but it makes an integration harder to reason about.
Start by writing down what each quantity includes. Does on-hand include quarantined units? Does reserved stock include unpaid orders? When does a returned item become saleable again? The answers belong in the operating model before they become calculations.
Give changes a source
For each change, identify the record that authorizes it. Receiving can increase physical stock. An accepted order may reserve a quantity. Picking and dispatch can move that quantity through different states. A cancellation may release a reservation, but only if another process has not already acted on it.
This is also a question of ownership. If a marketplace and an ERP can both overwrite available stock, decide which direction wins and how a disagreement becomes visible. A timestamp alone is not a complete business rule.
Test the uncomfortable cases
Use a small set of examples before connecting live records: an order that arrives twice, two orders for the last unit, a partial cancellation, a damaged return and a delayed warehouse update. Each example should have an expected quantity, status and next owner.
A useful test does more than check a total. It confirms that the system cannot silently lose a reservation or count the same receipt twice. When a record cannot be safely processed, it should enter a review path with enough context for someone to resolve it.
Make the first release observable
Begin with a narrow workflow and compare the system's records with the source operation. Track unresolved differences as well as successful updates. Agree who can correct a quantity and what evidence accompanies that correction.
The result is a working definition of stock that both people and software can follow. Automation then carries an agreed rule instead of hiding an unresolved disagreement.