# Odoo 20 Ministock: What It Really Does and When to Use It

> How Odoo 20's Ministock tracks quantity, forecast and value without the Inventory app, why it is driven by invoices and bills, and when a business needs full Inventory instead.

**Date:** 2026-09-22
**Source:** <https://trobz.com/insights/odoo-20-ministock/>

---


For a long time, an Odoo business selling physical products faced an all-or-nothing choice:

- do not track stock in Odoo; or
- install Inventory and adopt receipts, deliveries, locations, stock moves, transfers, operation types and the other concepts of a warehouse management system.

Full Inventory makes sense when a business needs to control physical warehouse operations: locations, traceability, reservations, picking or manufacturing movements. It is harder to justify for a company that mainly wants a simple answer: we had 40 units, bought 20 and sold 12, so how many do we have now?

Ministock fills that gap. It provides basic quantity, forecast and valuation visibility without the full Inventory application.

The important word is **basic**. Ministock is not a smaller warehouse management system. It is a different stock model for businesses that do not run a warehouse process.

It also behaves differently from what most Odoo users expect. In Ministock, stock does not change when goods are received or delivered. It changes when the vendor bill or customer invoice is posted. That design choice says more about who should use Ministock than any missing warehouse feature.

This article is based on the Odoo `20.0` Community branch as reviewed on 21 September 2026. User-interface details may still change in later updates to the branch.

## Where Ministock Lives

Ministock is part of **Odoo Community**, not an Enterprise-only feature.

There is no separate `mini_stock` addon. The behavior is spread across Community modules:

- `product` stores a simple on-hand quantity;
- `sale` calculates the expected outgoing quantity;
- `purchase` calculates the expected incoming quantity;
- `account` changes the on-hand quantity when invoices and bills are posted, and provides simplified valuation; and
- `stock`, when installed later, replaces this simple model with stock moves, quants, locations and warehouse operations.

The Enterprise addon `stock_enterprise` depends on the Community `stock` module and adds advanced views and reporting. It does not contain the core Ministock implementation.

Odoo's description matches the source code: Ministock tracks stock levels and inventory value without transfers or warehouse workflows. Odoo presented it in its 19.3 release material, so the feature emerged during the 19.x cycle and is now part of the Odoo 20 architecture.

## How Ministock Represents Stock

Without the Inventory addon, `product.product` has a company-dependent `qty_available` field. In practice, Odoo stores one on-hand balance per product variant and company.

Users can enable **Track Inventory** on a product and update its **Quantity On Hand** directly from the product form. The interface does not use the name "Ministock"; **Track Inventory** is the setting to look for.

The product model also exposes:

- **On Hand**: the stored quantity currently owned;
- **Incoming**: confirmed purchase quantity not yet billed;
- **Outgoing**: confirmed sales quantity not yet invoiced;
- **Forecasted**: on hand plus incoming minus outgoing; and
- **Free to Use**: on hand minus outgoing, never displayed below zero.

The central calculation is:

```text
Forecasted = On Hand + Incoming - Outgoing
```

This gives business users commercial stock visibility, not a record of physical warehouse activity.

The screenshots in this article come from a local Odoo 20 Community database with Sales and Purchase installed and the full `stock` addon absent. The example uses standard Odoo models and the native interface.

## The Key Implementation Detail: Ministock Is Invoice-Driven

It is easy to describe Ministock as "purchases increase stock and sales decrease stock." That is directionally correct but technically incomplete.

In the Odoo 20 code, the stored on-hand quantity changes when accounting documents are **posted**:

| Posted document      | Effect on Ministock |
| -------------------- | -------------------: |
| Customer invoice     |     Decrease on hand |
| Customer credit note |     Increase on hand |
| Vendor bill          |     Increase on hand |
| Vendor refund        |     Decrease on hand |

This applies to any posted invoice or bill line for a tracked product, whether or not it came from an order. Resetting a posted invoice or bill to draft reverses the quantity update.

In practice, running **Deliver** on a Sales Order (from the Actions menu) or clicking **Receive** on a Purchase Order does not itself change the on-hand balance.

Those actions update the delivered or received quantity on the order line. They support fulfillment status and invoice preparation, but the stock balance changes only when the corresponding invoice or vendor bill is posted.

The simplified lifecycle is therefore closer to this:

```text
Confirmed Sales Order
        │
        ├── adds expected outgoing quantity
        │
        ├── Deliver marks the order line as delivered
        │
        └── posted customer invoice decreases On Hand

Confirmed Purchase Order
        │
        ├── adds expected incoming quantity
        │
        ├── Receive marks the order line as received
        │
        └── posted vendor bill increases On Hand
```

There is a subtle mismatch between the field descriptions and the calculation. The help text refers to purchases "not received" and sales "not delivered," but the Community code calculates the forecast from uninvoiced quantities:

```text
Incoming = confirmed purchase quantity - invoiced purchase quantity

Outgoing = confirmed sales quantity - invoiced sales quantity
```

A received but unbilled Purchase Order can therefore remain in the incoming quantity, and a delivered but uninvoiced Sales Order can remain in the outgoing quantity. Without Inventory, no stock picking or stock move records the physical event, so the invoice or bill is what updates the simple stock ledger. Implementers should make this timing clear during discovery.

This is the most important limitation to understand. The design works well when invoicing closely follows the physical handover of goods. If a business delivers on day 1 and invoices on day 30, On Hand keeps counting those goods as in stock for almost a month. The same drift appears when physical quantities regularly differ from billed quantities.

## A Worked Example

Suppose a small company starts with 12 coffee machines on hand. It confirms a Purchase Order for 8 machines and a Sales Order for 5:

```text
On Hand                 12
Incoming                 8
Outgoing                 5
                        --
Forecasted              15
Free to Use              7
```

{{< img src="/images/insights/odoo-20-ministock/product-forecast-before-billing.png" alt="Odoo 20 Community product showing 12 on hand, 8 incoming, 5 outgoing, a forecast of 15 and 7 free to use" >}}

*Before billing, the product form combines the stored balance with confirmed demand and supply: 12 on hand, 8 incoming, 5 outgoing, 15 forecasted and 7 free to use.*

### 1. Mark the Purchase Order Received

The Purchase Order line becomes received, but On Hand stays at 12. Ministock has not created a warehouse receipt or a stock movement.

{{< img src="/images/insights/odoo-20-ministock/purchase-order-marked-received.png" alt="Odoo 20 Community Purchase Order marked fully received with 8 received and nothing billed" >}}

*The Purchase Order is fully received but unbilled. The product remains at 12 on hand, and the 8 units stay in the incoming forecast.*

### 2. Post the Vendor Bill

On Hand increases from 12 to 20. Because the purchase quantity is now billed, it no longer counts as expected incoming stock.

```text
On Hand                 20
Incoming                 0
Outgoing                 5
Forecasted              15
```

### 3. Mark the Sales Order Delivered

The Sales Order line becomes delivered, but On Hand stays at 20 until the invoice is posted.

{{< img src="/images/insights/odoo-20-ministock/sales-order-marked-delivered.png" alt="Odoo 20 Community Sales Order marked fully delivered with 5 delivered and nothing invoiced" >}}

*The Sales Order is fully delivered but uninvoiced. Delivery status alone does not change the Ministock quantity.*

### 4. Post the Customer Invoice

On Hand decreases from 20 to 15. The invoiced sales quantity no longer counts as expected outgoing stock.

```text
On Hand                 15
Incoming                 0
Outgoing                 0
Forecasted              15
```

{{< img src="/images/insights/odoo-20-ministock/product-after-posted-billing.png" alt="Odoo 20 Community product after posting the vendor bill and customer invoice, showing 15 on hand with no incoming or outgoing quantity" >}}

*After the vendor bill and customer invoice are posted, Odoo shows 15 on hand, with incoming and outgoing both back to zero. The forecast remains 15.*

## Ministock Versus Full Inventory

With full Odoo Inventory, quantity is computed from physical inventory records:

```text
Purchase Order → Receipt → Stock Move → Location / Quant → On Hand

Sales Order → Delivery → Stock Move → Location / Quant → On Hand
```

With Ministock, the model is deliberately flatter:

```text
Product balance
    + posted vendor bills
    - posted customer invoices
    ± refunds and manual corrections
```

Ministock knows the total balance for a product and company, but not where the units are, how they moved or which units fulfilled an order.

| Requirement                            | Ministock |               Full Inventory               |
| -------------------------------------- | :--------: | :----------------------------------------: |
| Total on-hand quantity                 |    Yes     |                    Yes                     |
| Incoming and outgoing forecast         |    Yes     |                    Yes                     |
| Direct product quantity correction     |    Yes     |     Yes, through inventory adjustment      |
| Manual delivered/received status       |    Yes     |       Superseded by stock operations       |
| Approximate inventory value            |    Yes     |                    Yes                     |
| Warehouses, locations and transfers    |     No     |                    Yes                     |
| Receipts, deliveries and reservations  |     No     |                    Yes                     |
| Lots, serials and expiry               |     No     |                    Yes                     |
| Barcode execution                      |     No     | Yes, with the relevant Barcode application |
| Replenishment rules                    |     No     |                    Yes                     |
| Detailed physical traceability         |     No     |                    Yes                     |
| Movement-based valuation               |     No     |          Yes, with Stock Accounting        |

Ministock covers the stage before a business needs warehouse operations.

## Good Use Cases

The best candidate is a business where stock matters but physical logistics stay simple, regardless of company size.

{{< img src="/images/insights/odoo-20-ministock/small-reseller-storeroom.jpg" alt="A small hardware shop with shelves of boxed stock and a ladder" >}}

### A Consulting or Installation Company Selling Equipment

The company mainly sells services but keeps a few laptops, routers, replacement units or accessories in one office. The same person confirms the order, hands over the product and issues the invoice. Total availability matters; bin-level control does not.

### A Small Specialist Reseller

A three-person business sells measuring devices from one storeroom. It needs to see what is available, what has been ordered from suppliers and what has been committed to customers. It has no warehouse team or staged fulfillment process.

### A Clinic With Simple Retail or Operating Supplies

A veterinary clinic could use Ministock for pet food, collars, shampoos, stationery or other simple consumables when it only needs a total balance.

It should not use Ministock for medicines, vaccines or regulated products when lot, expiration, storage, recall or controlled-product traceability is required.

### A Young Business Starting With One Stock Point

Ministock can be the right starting point when one person manages purchases, sales, invoicing and the physical shelf. The business can adopt full Inventory when it introduces locations, warehouse roles, scanning, traceability or distinct fulfillment events.

## When Ministock Is the Wrong Choice

Use full Inventory as soon as the business needs to know where a product is, which lot or serial number a customer received, when it expires, whether it has passed quality control, what is reserved for an order or who should pick and pack it. The same applies when routes, replenishment rules or a complete physical and valuation history matter.

## Simplified Inventory Valuation

Ministock also supports a simplified view of inventory value.

When the product category uses **Average Cost (AVCO)**, posting a vendor bill updates the product cost with a moving-average calculation. The default costing method is **Standard Price**, which leaves the cost unchanged. Without full Inventory and Stock Accounting, Odoo approximates current inventory value as:

```text
Inventory value = Quantity On Hand × Current Product Cost
```

For a past reporting date, Odoo reconstructs the historical quantity by reversing posted invoices and bills with an accounting date after that date. It still applies the current product cost, so this should not be confused with movement-level historical valuation.

Ministock can therefore answer "roughly what is our inventory worth?" It cannot provide the movement-level valuation evidence that full Inventory ties to individual receipts, deliveries, lots or landed costs, and it should not be treated as a substitute for movement-based valuation where the auditability of individual physical movements matters.

## What Happens When Inventory Is Installed Later?

Odoo includes an explicit transition from Ministock to full Inventory.

When `stock` is installed, its post-installation hook reads the stored Ministock quantities and, for each company, creates inventory adjustments in the stock location of that company's first warehouse. From then on, `qty_available` is computed from stock quants and moves instead of being stored as a simple product balance.

The reverse path also exists. If `stock` is uninstalled, Odoo saves the current computed on-hand quantities back into the product-level field.

Before installing `stock`, keep these points in mind:

- Existing Sales, Purchase, Invoice and Bill documents remain in Odoo.
- Ministock cannot provide historical locations, transfers, reservations or lot movements that were never recorded.
- Full stock-movement history begins when the full Inventory process begins.
- Locations, routes, traceability rules, roles and cutover controls still need implementation design.

{{< note title="Technical Note: Multi-Company Databases" >}}
Installing `stock` does not create a warehouse for every existing company. A company without one is skipped and its Ministock quantities are not transferred. Record those companies' quantities before installing `stock` and re-enter them as inventory adjustments once their warehouses exist.
{{< /note >}}

## A Better Discovery Question

During discovery, "Do you need Inventory?" is too blunt a question. A more useful one is: what must Odoo know and control about your physical products?

If the answers are mainly:

```text
How many do we have?
How many are expected from suppliers?
How many are committed to customers?
Will we have enough?
What is the approximate inventory value?
```

Ministock deserves consideration.

If the answers include:

```text
Where is it?
Which unit or batch is it?
Who should move it?
Which order has reserved it?
Which route should it follow?
When does it expire?
What is its complete physical and valuation history?
```

the business needs full Inventory.

This is a more useful distinction than company size, revenue or SKU count alone.

## The Implementation Lesson

Ministock lets an implementation match the organization's operating model. Warehouse steps improve control when a warehouse process exists; when one person sells, hands over and invoices a product in one short flow, those steps may add little value. Complexity should follow a business requirement.

Ministock provides a useful middle ground:

```text
No stock tracking
        ↓
Ministock: commercial and accounting quantity visibility
        ↓
Full Inventory: physical warehouse execution and traceability
```

For a business with simple logistics, that middle layer can reduce configuration and training. A business that needs locations, lots, expiration, reservations, manufacturing or a clear separation between movement and invoicing requires full Inventory.

The conclusion is not that Inventory is optional. Full Inventory is optional only when warehouse operations are optional.

## Technical References

The conclusions above are based on these Odoo 20 Community implementation points:

- `addons/product/models/product_product.py`: stored `qty_available`, forecast fields, base forecast and simple moving-average cost;
- `addons/product/models/product_template.py`: **Track Inventory** and product-template quantity fields;
- `addons/product/views/product_views.xml`: direct on-hand editing without `stock`;
- `addons/sale/models/product_product.py`: outgoing and forecast quantities from confirmed, uninvoiced Sales Order lines;
- `addons/sale/models/sale_order.py`: `deliver_sold_quantity()`, run by the **Deliver** server action;
- `addons/purchase/models/product.py`: incoming and forecast quantities from confirmed, unbilled Purchase Order lines;
- `addons/purchase/models/purchase_order.py`: manual **Receive** action;
- `addons/account/models/account_move.py`: on-hand and average-cost updates when invoices and bills are posted;
- `addons/account/models/company.py`: simplified inventory-value calculation without `stock`;
- `addons/stock/models/product.py`: replacement of the simple quantity with quant- and move-based computation;
- `addons/stock/data/stock_data.xml` and `addons/stock/models/res_company.py`: the warehouse created when `stock` is installed; and
- `addons/stock/__init__.py`: conversion between stored Ministock quantities and full Inventory quantities during installation or uninstallation.

Official product context:

- [Mini stock: Inventory tracking without the complexity](https://www.odoo.com/event/odoo-experience-2026-9099/track/mini-stock-inventory-tracking-without-the-complexity-10518)
- [Webinar: Stock, Barcode & Purchase Release Highlights 19.3](https://www.odoo.com/event/webinar-stock-barcode-purchase-release-highlights-19-3-11544/register)

