Skip to content

Inventory management: one ledger, every movement witnessed

Inventory management software where the balance is never stored, only derived. Every movement is a row with a reason and a name, and every number on screen is computed from those rows.

Verified in code 2026-09-03 · v2.0.0 to v2.19.0

Derive, never store

Most inventory systems keep a balance and update it. When the update path has a bug (a double decrement, a missed return, a reconciliation that ran twice) the balance is wrong and nothing in the system knows.

DockingWare does not keep a balance as a fact. It keeps movements. A receive is a row. An allocation is a row. A pick, a shipment, a return, a damage write-off, a cycle-count adjustment: rows, each with a type, a dimension, a quantity, a reference, a user and a time. Every balance on every screen is computed from those rows. If the number is wrong, the row that made it wrong is there to be found, with a name on it.

This is why the slogan is what it is. A warehouse that never lies is a warehouse whose numbers can always be explained.

Dimensions, not just quantities

Stock is not one number per product. It is on hand in the pick face, in bulk storage, allocated to orders, damaged, quarantined, on order from a supplier, on the way in a container, received on the dock and not yet put away. DockingWare keeps each of those as its own dimension and shows them as their own chips (pick available, bulk available, allocated) instead of collapsing them into a single figure that hides where the stock actually is.

Available to promise is computed from those dimensions on the server, once, and every screen reads the same fields. That sounds obvious. It was not always true here. The first version of the product page re-derived bulk availability by subtraction, which agreed with the backend by algebraic identity and therefore could never be caught by a test. The fix was to stop deriving on the client. That lesson is now a rule in the codebase.

Allocation that tells the time

An order that has held its allocation for three weeks is a decision nobody made. DockingWare records when each order was allocated, shows how long it has held its stock, and lists frozen orders in a report by age and by bucket. Each customer can carry its own hold limit. On breach the system notifies. It never releases on its own, because releasing an allocation is a human call, and when a human does release, the reason rides on the ledger row with their name.

Kits complicate this in every warehouse, so they get their own answer. When a component is held by open kit orders, the product page says how much and for which orders, read from the allocation table, not inferred.

Identity that survives the floor

Products have a lifecycle (draft, active, discontinued) and the lifecycle means something. Drafts cannot be sold. Discontinued products sell down and refuse replenishment. Activation needs a base unit and a scannable code. Alternate barcodes let a product answer to a marketplace sticker or a vendor label without ever being renamed: the alias resolves, the ledger names the SKU.

Case conversions are per product. Piece demand reserves exact pieces. A prefix never verifies a scan on any surface, because a warehouse that accepts a partial code eventually ships the wrong product.

Who this is for

Operations teams who have stopped trusting their own number and want a system that can show its work. Brands and 3PLs moving off spreadsheets, or off a system whose balance has drifted so many times that nobody remembers which count was right.

It is not for a team that wants an accounting-grade costing engine first. DockingWare records cost where it touches inventory and hands the books to the accounting system.

What you can verify

Every rule above is enforced in code and covered by a test that fails first, then passes. The changelog lists when each one shipped, by version.

Questions

What does available to promise mean here?
Pick-face stock plus bulk stock, minus what is already allocated to orders, per product. Damaged and quarantined stock are never sellable. Stock received on the dock is not sellable until putaway completes. The backend computes it and every screen reads it. No client re-derives it by subtraction.
Can I see why a number changed?
Yes. Every change is a movement row: type, dimension, quantity, reference, user, time. Physical rows are shown by default. Reservations and pipeline rows sit behind a toggle so a shipment does not look like three movements. A damaged minus five is chipped as damaged and can never pass for a sellable minus five.
How are cases and pieces handled?
Each product has a base unit and conversions. Demand in pieces reserves exact pieces. Case fallback only happens when no conversion exists, and that decision is logged. Fifty-five pieces at fifty-four per case reads as one case and one piece.
What happens to a product I no longer buy?
Mark it discontinued. It sells down what is left, refuses new replenishment with a named reason, and still accepts goods already standing on the dock. A draft product cannot be sold at all until it is activated with a base unit and a scannable code.

Related

See how DockingWare handles this →

Ready to see it on your floor?

Early access. We onboard a small number of operations at a time.

Start Early Access