Home / Guides / Warehouse Operations

Warehouse Operations

Set up your warehouses and bin locations, then keep on-hand numbers honest — counting stock, reconciling what you find, and moving inventory between locations without losing the trail.

Who this is for

Warehouse managers and operations staff. Receiving deliveries against a purchase order is covered in Purchasing & Receiving.

What you'll have when you're done

Stock organized into bins you can actually pick from, a repeatable counting process, and on-hand figures you'd be willing to publish to a sales channel without checking first.

1

How Foundry models a warehouse

Three levels, and it's worth being precise about them because the counting workflow depends on it:

Warehouse

A physical location holding stock. You can have as many as you need. A warehouse can also represent a dropshipper — a vendor location whose stock you sell but never hold. Sales channels can be linked to specific warehouses, so a channel only sells what's available where it can ship from.

Bin

A named location inside a warehouse — a rack, shelf, or pallet position. Names are unique within a warehouse, so "A-01-3" can exist in two buildings without ambiguity. Bins are optional: if you don't use them, stock simply sits at the warehouse level.

Stock item

The intersection — one SKU, in one warehouse, in one bin. This is what actually holds numbers:

  • On hand — physically present
  • Reserved — spoken for by orders, still on the shelf
  • Inbound — expected from open purchase orders
  • Min / max — your reorder thresholds

Because the bin is part of that identity, one SKU can live in several bins at once and each holds its own quantity. Available to sell is on-hand minus reserved — which is why an item can show stock and still be unsellable. Bin locations also print on order and work-order pick lists — see Fulfillment.

2

Set up warehouses and bins

Create the warehouse

From Warehouses → New, give it a name and address. Mark it as a dropshipper if it represents a vendor location rather than a building you control.

Decide your bin naming scheme first

Do this before creating any — renaming bins after stock is in them is tedious. A scheme that sorts correctly and reads unambiguously on a printed sheet:

  • A-01-3 — aisle, bay, level
  • • Pad numbers: 01, not 1, so sorting matches walking order
  • • Avoid characters that read alike — O vs 0, I vs 1

Add the bins

Create them on the warehouse's Bins tab. You don't need every bin up front — the count workflow can create unknown bins for you as they appear on a count sheet.

3

Primary bins and the Unassigned location

Two ideas make bins work without forcing you to name a bin on every transaction. Understanding them explains where automated movements land.

Unassigned

Stock with no bin sits at warehouse level and shows as Unassigned. It counts toward on-hand and availability exactly like binned stock — it just has no shelf address, so it never appears in a pick list's Bin column. Orgs that don't use bins live entirely here, and that's fine. A catalog or inventory import can't assign bins; stock gets a bin through a count sheet, an adjustment with a Location, Move stock, or Add SKU.

Primary bin — the pick face

Each SKU can have one primary bin per warehouse: where it's normally picked from. Set it on the warehouse's Inventory tab with Make primary on a row that already holds the SKU, or mark it with an x in the primary column of a count sheet. When a SKU lives in exactly one bin, that bin becomes primary automatically the first time stock moves through it.

  • • The primary stays primary at zero on-hand — an empty pick face that replenishes from overstock is the normal case, and it still prints on pick lists.
  • • Choosing a different bin moves the designation. There's no "clear"; a blank primary column on a count sheet leaves it as-is.
  • • Deleting a bin requires it to be empty (total on hand exactly zero). Its history is kept and its empty rows fall back to Unassigned.

Where automated movements land

When nothing names a bin, Foundry resolves one in a fixed order: the SKU's primary bin, else its only bin, else its fullest bin, else Unassigned — so stock isn't scattered into Unassigned once you've started binning it.

  • Receiving a PO puts stock in the resolved bin.
  • Fulfilling an order draws from the primary first, then the fullest, never from an empty bin. If the warehouse total is short, the remainder still ships and the primary bin goes negative, flagged "beyond counted stock" in the history — a signal to count that SKU, not a bug.
  • Work orders stamp each component with a bin when created and pick from it at completion. Unlike shipping, a build refuses to complete if a component is short, and tells you which.
  • Transfers between warehouses take stock from the resolved source bin only — if a SKU is split across bins and the primary is short, the transfer fails even though the warehouse has enough. Move stock into one bin first.

Empty locations hide themselves: a bin showing zero for a SKU that has stock elsewhere in the same warehouse is dropped from the Inventory list and the count sheet until stock returns (tick Show empty locations to see them). A SKU never disappears entirely.

4

Run a stock count

The core loop: export a count sheet, count the shelves, upload it, review the differences, apply. Nothing changes until you approve it.

Step 1 — Export the count template

From the warehouse's Inventory tab, export the count template. You get a CSV with these columns:

Column What it's for
sku The match key on re-import. Don't edit it.
internalSku Your own SKU, so counters can identify the item
product, variant Names, for the person holding the sheet
bin Where Foundry thinks it is
currentOnHand What Foundry believes you have
counted Blank — this is the column you fill in
primary Optional. Put an x on the row that should be the SKU's pick face; blank leaves the current primary alone

A SKU stored in three bins gets three rows, one per bin. Items never stocked here appear once at zero, so a surprise find still has somewhere to go.

Choose what to export: all active SKUs, or only what's already stocked in this warehouse. All SKUs for a wall-to-wall count; stocked-only for a faster cycle count.

Step 2 — Count

Fill in counted for every row you actually check. Leave it blank for anything you didn't count — blank means "not counted" and is ignored, whereas a zero means "I looked and there were none," which will write a difference. That distinction is the single most common source of accidental stock wipes.

Step 3 — Preview

Upload the sheet. Foundry shows you a line-by-line diff before touching anything — current on-hand, what you counted, and the delta. It also flags:

  • Unknown SKUs — flagged as errors so a typo can't create phantom stock
  • Unknown bins — offered as new bins you can opt into creating

Read the large deltas before applying. A count that says a fast-moving SKU dropped by 400 is usually a counting error, not a theft.

Step 4 — Apply

Applying writes the new on-hand figures and records a count movement for every change. Nothing is silently overwritten — each adjustment is attributable afterwards, which is what makes the count defensible in an audit.

Count scope decides what happens to locations that aren't on the sheet. Partial (the default) changes only the rows you uploaded — right for cycle counts. Full also zeroes every stocked location in the warehouse that wasn't on the sheet — right for a wall-to-wall count, and only then. Coverage is per location, not per SKU: counting a SKU in A-01-3 doesn't protect its stock in B-02-1 or in Unassigned, so a full count needs every row, including the ones with no change. Unknown bins on the sheet are never dumped into Unassigned — you either create them or their rows are skipped.

5

The spreadsheet trap

Excel and Google Sheets will silently mangle identifiers if you let them. A bin called 0123 becomes 123; an all-numeric SKU loses its leading zeros. On re-import those no longer match — the count lands in a brand-new bin, or fails outright.

Foundry defends against this: identifier columns are exported wrapped so spreadsheets treat them as text, and the importer strips the wrapper on the way back in. So the round trip is safe if you edit the file as exported.

It breaks if you retype the SKU or bin columns by hand, paste values between sheets, or rebuild the file from scratch. If you must, format those columns as Text first. When a count preview shows bins you know exist as "new," this is almost always why.

6

Adjustments, moves, and transfers

Three different operations that people often conflate. Picking the right one keeps your history readable:

Adjustment — the quantity changed

Damage, shrinkage, samples, a found box. Stock enters or leaves your business. Always attach a reason; six months on it's the only thing that explains the number.

Move — same warehouse, different bin

Reslotting. Total on-hand doesn't change, so it never affects what's sellable. Use this rather than adjusting one bin down and another up, which looks like shrinkage plus a mystery gain in your history.

Transfer — between warehouses

Records a transfer out of the source and a transfer in at the destination, as a matched pair. Availability changes at both ends, which matters if your channels are linked to specific warehouses.

Every one of these writes a movement. The variant's movement history is the answer to "why is this number what it is" — receipts, sales, counts, builds, and transfers, in order.

7

Common problems

Bins aren't showing on my inventory screen

Usually the stock genuinely has no bin assigned — it sits at warehouse level, which is valid and displays as blank. Assign bins by exporting the count template, filling in the bin column alongside the counts, and applying. A normal catalog import can't set bin locations; the count workflow is the route.

A count wiped stock I didn't intend to touch

Zeros were entered where the count column should have been left blank — often from filling down a formula, or a spreadsheet replacing blanks with 0 on export. Blank means "not counted"; zero means "counted, none there." Re-count the affected items and apply a correcting count; the movement history shows exactly what the bad count changed.

A full count zeroed a bin I didn't list

That's what Full scope does — every stocked location not on the sheet goes to zero, with a FULL_COUNT_ZEROED movement you can see in the history. Use Partial for cycle counts. To repair, re-apply a count with the real figures for the affected rows; counts are absolute, so re-applying always converges.

Transfer says "insufficient stock" but the warehouse has enough

A transfer draws from one source bin (the primary, or the fullest). If the SKU is split across several bins, that one bin may be short. Move stock to consolidate first, then transfer.

Preview says bins are new, but they exist

A spreadsheet reformatted the bin column — see the spreadsheet trap above. Re-export, edit only the counted column, and try again rather than accepting the new bins.

On-hand looks right but the channel shows less

Reserved quantity is doing its job — those units are committed to orders. Available is on-hand minus reserved. If reserved looks too high, there are open orders holding stock that may need cancelling or fulfilling.

Same SKU in several bins and the totals confuse people

That's the design — each bin holds its own quantity and the variant total is their sum. When counting, make sure each bin row gets its own count. Putting the full building total on one row and leaving the others blank will look like a large gain in one bin.

Next