FurnFlowDocs
Open the app →
Docs › Fulfil › Inventory & stock

Inventory & stock

One row per product — every product, including freshly imported ones — with a clear split between what you physically have, what's promised, and what's truly sellable. Plus transfers, cycle counts and the movement ledger.

🏪 The number that matters: available

Left navFulfilInventory

FurnFlow tracks stock as available-to-promise. The moment an order reserves a unit, that unit is committed even though it's still in the building:

On hand
Physically in the building
− Reserved
Committed to open orders
= Available
What you can still sell

So a product can read out of stock and have units arriving — you'll see both. Backlog (units you owe beyond stock) and incoming (units arriving on transfers) are tracked separately.

📋 Every column, explained

ColumnMeaning
On handPhysical units across branches.
ReservedCommitted to open order lines (reserved − already delivered).
AvailableOn hand − reserved. The sellable number.
BacklogOpen procurement quantity — units owed beyond stock.
IncomingUnits arriving on pending transfers.
Reorder pointThe threshold that triggers low-stock & reorder suggestions.
Branches / WarehousesWhich branches hold it and which warehouses serve them.
Healthout_of_stock · low_stock · overstock · healthy

🎨 Variants & the deep view

Products carry variants (colour / fabric / size / finish) with their own stock. Click a product for the deep detail: per-variant and per-branch stock, plus the full movement ledger.

📥 Getting stock in

  • Filter by In / Low / Out and search by name, SKU or category.
  • Import products from CSV/XLSX with column mapping and images — it handles large files and maps every column resiliently.
  • Adjust stock directly with a reason, or move it with a transfer.

🔁 Transfers

FulfilInventoryTransfers
requested approved in_transit completed Can also be rejected or cancelled.
📦

Stock only moves at the edges. It leaves the source on ship (blocked if there isn't enough on hand) and only arrives at the destination on receive (which auto-reserves any waiting backlog). Pick the exact colour/size — the modal shows live source on-hand and prevents over-transfers.

🔢 Cycle counts

  1. Open a count session — scope it to all, low stock, or a category.
  2. Enter counts — record the physical numbers you find.
  3. Submit for review.
  4. Approve — the variance (counted − system) is applied to stock and an audit row records the reconciliation.

Session statuses: opensubmittedapproved (or cancelled).

📒 The movement ledger

Every change to stock is a ledger row, so you can always answer "why is this number what it is?". Movement types include:

ship receive receive_damage receive_quarantine transfer_out transfer_in transfer_cancel_return pick pick_out pick_cancel_in pick_cancel_out putaway putaway_out bin_move bin_move_out return_restock adjustment count_variance

Order reservations are also tracked in the ledger but recorded against the reason order_reservation:<orderId> rather than a movement type.

✏️ Adjustments & reasons

When physical reality differs from the system outside a count or transfer — breakage, samples, found stock — record a direct adjustment with a reason. It posts an adjustment row to the ledger so the change is explained and auditable.

🔑 Who can do what

ActionRoles
View inventoryManager, warehouse, buyer, admin (+ executive read-only).
Adjust stockWarehouse, manager, admin.
Request / approve transfersWarehouse requests; manager approves.
Receive transfers / POsWarehouse, manager.
Run / approve cycle countsWarehouse runs; manager approves.

FAQ

A product shows 0 available but we have units — why?

They're all reserved to open orders. On hand − reserved = available, and available is 0. Fulfil or cancel an order to free them, or bring more stock in.

I shipped a transfer but the destination still shows nothing.

Stock arrives only when the destination receives it. Until then it's in_transit / incoming.