Guide / for designers
The inventory management system class diagram, done right
Six classes and one decision cover 90% of a sound inventory model. The classes, their relationships, and the movement-first design that separates a real system from a CRUD tutorial.
The key facts
- The core classes: Product, Location, Movement, Order, OrderLine, Party (customer/supplier) — with QuantityOnHand as a derived value, never a stored attribute.
- The one decision: movements are append-only facts; quantities are queries over them. Storing an editable quantity breaks audit, concurrency and traceability at once.
- The extension path: batches/lots as a Movement subtype, PurchaseOrder and Invoice as specialised Orders, Stocktake as a Movement batch with review.
- For context: BSimple is commercial software — this page teaches the model, not our codebase; the ER-diagram companion covers the relational view.
- 01The key facts
- 02The core classes and their relationships
- 03The one decision the diagram must get right
- 04Extensions once the core holds
The core classes and their relationships
Product — the thing you sell or use: SKU, description, unit of measure, par level. Composition aside, it owns nothing about quantity.
Location — where stock can be: warehouse, shop, van, customer site. Self-associating to support hierarchies (a warehouse containing bin locations).
Movement — the heart of the model: an append-only record of a quantity change — direction, quantity, product, location, timestamp, actor, reason — generalising Receipt, Issue, Transfer and Adjustment. Every report, from on-hand to audit trail, is a query over this class.
Order / OrderLine — an order is a header (party, dates, status) with lines (product, quantity, price). Specialise it: CustomerOrder, PurchaseOrder, and Invoice as a state that follows fulfilment. The state machine on the order (placed → checked → picked → packed → invoiced → paid) is behaviour worth diagramming explicitly — the life-cycle page is the prose version.
Party — customers and suppliers as one abstraction with roles; every order references exactly one.
QuantityOnHand — not a class with stored state but a derived view: opening balance plus movements. Draw it as a query/dependency, not an attribute on Product; that arrow is the diagram's moral centre.
The one decision the diagram must get right
Two models compete in tutorials. Model A: Product carries a quantityOnHand attribute; receiving adds to it, selling subtracts. Simple, and broken three ways — no history (why did it change?), no concurrency safety (two simultaneous sales), no audit (who changed it?). Model B: Movement is the fact; on-hand quantity is derived. Same demo behaviour, entirely different production behaviour: every discrepancy has a story, every adjustment an author, every count a baseline to reconcile against.
Every serious system — and BSimple, though as commercial software its code is not on display here — lands on Model B eventually; the only question is whether it is Model A wearing a rebuild. The system diagram and the ER view extend this thinking to the whole application, and the class-diagram cousin for business systems covers the wider scope.
Extensions once the core holds
Batches and lots: a Movement references a Batch; Batch carries expiry and origin. Traceability becomes a graph query — supplier receipt to customer issue — which is exactly how recall questions get answered in minutes (the traceability pattern in practice). Stocktakes: a Stocktake groups counted Movements with variance review before adjustment — the count is a process, not an overwrite. Reservations: a Reservation class between Order and Movement promises stock without consuming it — the difference between "available" and "exists". Multi-level units: Product self-associates (box-of contains units-of) so packs and singles share one truth.
We build BSimple, so weigh that — and the honest closing: if the diagram is for study, build Model B small and real; if it is for a business, weigh the trial against the years the tail of this model always takes.
Frequently Asked Questions
What are the main classes in an inventory management system?
Product, Location, Movement, Order/OrderLine, Party, and — derived, not stored — QuantityOnHand. Extensions add Batch, Stocktake and Reservation once the core is sound.
Should quantity on hand be an attribute of Product?
No — derived from movements. A stored quantity cannot answer why it changed, cannot survive two simultaneous writers, and quietly destroys the audit trail. This is the single decision that sorts real designs from tutorials.
How do batches and expiry fit the class model?
As a class that Movements reference: every receipt, issue and adjustment can name the batch, and the batch carries expiry and origin. Expiry reporting and traceability become queries rather than extra modules.
Where do invoices and purchase orders sit?
As specialisations of Order, each with its own state machine. Keeping them as orders — rather than separate silos — is what lets one movement history serve sales, purchasing and accounting handoff without reconciliation gaps.
Is BSimple built on this model? Can we see its code?
BSimple is commercial software and its code is not public — but its behaviour is: movements with audit history, derived truth, traceability search. The trial demonstrates the model working before you decide anything.
BSimple

