If you've ever stared at Odoo's Inventory app and thought "why is there a move for THAT?" — this post is for you. I spent my first month with Odoo fighting the inventory module. Receipts, deliveries, internal transfers, dropshipping, resupply — it felt like five apps wearing a trench coat.
Then someone explained the one concept underneath all of it, and the whole module snapped into focus. Here it is:
Every inventory movement in Odoo is a double-entry. Stock never appears or disappears — it moves from one location to another, like a debit and a credit.
That's it. That's the whole secret. Everything else is details.
Accounting, But for Boxes
Think about double-entry bookkeeping. Money never appears from nowhere — every debit has a credit. Odoo applies the identical logic to physical goods.
When you receive 100 units from a vendor, Odoo creates a stock move: 100 units FROM "Vendor Location" TO "Stock." The vendor location is virtual — it represents "the outside world." Your Stock location goes up by 100. The books balance.
When you ship 30 units to a customer: 30 units FROM "Stock" TO "Customer Location." Another virtual location — "the outside world" on the other end. Stock goes down by 30.
Scrap 5 damaged units? 5 units FROM "Stock" TO "Scrap Location." They're not deleted — they're moved somewhere you can see them, count them, and cry about them in the monthly review.
This is why Odoo never lets you just "adjust" quantity without a move. There's no delete key for inventory, because in double-entry there are no one-sided transactions. The inventory adjustment feature? It creates moves from an "Inventory Loss" virtual location. Even corrections are double-entries. Beautiful.
The Diagnostic Question
Here's where this pays rent. Every inventory problem I've ever debugged in Odoo came down to asking: which side of the move is wrong?
Client story: a food distributor called me because their Stock location showed 400 cases of product they swore weren't in the warehouse. Classic phantom inventory. We pulled the stock moves. The receipts were all there — vendor to stock, clean. But the deliveries? Half of them were still in "Waiting" status because the warehouse team was confirming pickings in the app but never validating the delivery orders. The moves existed but never completed their second half. Source decremented on paper, destination never confirmed.
The fix wasn't an adjustment — it was a process fix. Validate your deliveries, people. The system was telling the truth; the humans were telling it half the story.
Another one: negative stock. Odoo shows -15 units of a product. Panic? No — read the moves. Negative stock means a delivery move (Stock → Customer) was validated before its receipt move (Vendor → Stock) arrived. The goods physically came and went, but the paperwork order was backwards. The double-entry model makes this obvious: the outbound half posted before the inbound half. Fix the receiving process, and the negatives disappear.
Locations Are Your Chart of Accounts
In accounting, you design your chart of accounts to match how you think about money. In Odoo, you design your locations to match how you think about goods.
The default setup — one Stock location — works until it doesn't. The moment you have a second warehouse, a quarantine area, a retail shelf, or a van that carries stock, you need location structure. And here's the key insight from the double-entry model: internal transfers are just moves between your own locations. Van restocking isn't special — it's Stock → Van, same as any other move.
I set up a client with three warehouses and a quality-hold area. Their old system tracked "quantity on hand" as a single number per product — which is like tracking "money" as a single number regardless of which bank account it's in. Useless. With Odoo locations, they could see exactly which warehouse held what, what was in quarantine, and what was in transit. Their stock-out rate dropped 60% in a quarter, not because they bought more inventory, but because they could finally SEE it.
Pro tip: name locations the way your warehouse team talks. "WH1/Bulk/Rack-04" beats "Location 7" every time. The people doing the moves have to read these labels at 6 AM.
Valuation Rides on the Moves
One more thing the double-entry model explains: automated inventory valuation. Every move between a virtual location and a real one carries a value. Vendor → Stock at $10/unit adds $1,000 to your inventory valuation. Stock → Customer at the same cost removes $1,000. Your balance sheet inventory number is just the sum of all incomplete move pairs.
This is why your inventory valuation report and your stock quantities can disagree — they're computed from the same moves, but if moves are unvalidated or backdated, the two views diverge. Same diagnostic question: which side of the move is wrong?
The Takeaway
Stop memorizing Odoo's inventory menus. Internalize the model: every move is from somewhere to somewhere, nothing appears or vanishes, and virtual locations represent the outside world. With that one concept, you can read any stock move, diagnose any discrepancy, and design locations that match your actual operation.
It's accounting for boxes. And once it clicks, you'll wonder why every system doesn't work this way.
David Strausser, Dead Brands LLC / Quaint Business Solutions
Want help with your ERP? Book a call — I do Odoo inventory setups that your warehouse team will actually use.
New Dead Brands merch at deadbrands.co — for people who count their stock AND their blessings.




