Items, UPCs, Scanning & Stock — Step by Step

Inventory HQ · West Coast Select — the complete data-entry walkthrough, from an empty catalog to counted freezers. Companion to the full Manual.
1 · How the backend thinks (3 minutes) 2 · SKU vs UPC — what goes in which box 3 · Adding items, one at a time 4 · Adding a whole shelf fast 5 · Adding items in bulk (CSV import) 6 · Entering quantities — the phone walk 7 · Entering quantities — desk & paper 8 · Entering quantities — in bulk (CSV) 9 · The scanner, screen by screen 10 · Making everything scannable (labels) 11 · The day-one recipe, start to finish 12 · Conventions that keep it clean

1 · How the backend thinks (3 minutes)

Everything in the system is built from three kinds of record. Understand these and nothing will ever feel like magic:

RecordWhat it isExample
ItemOne entry in the catalog — the definition of a thing we handle. Holds SKU, UPC, name, size, case pack, unit of measure, shelf life, allergens. An item has no quantity of its own.JS14H-WC — Wild Sockeye Jerky, Original, 70g
LotA real batch of that item sitting somewhere: quantity + location + lot number + pack date + best-by. One item can have many lots.Lot 260901-A · 48 units · Main Freezer · best-by 2027-03-01
MovementOne line in the permanent diary: what changed, by how much, why, who, when. Receiving writes a +, shipping writes a −, a count writes the correction.+48 · received · JS14H-WC · lot 260901-A · from Ocean Fisheries · ryder

"On hand" is never typed anywhere. The number you see beside an item is simply the sum of its lots — and every lot got its quantity from movements. That's why the system can always answer "why does it say 48?": open Activity and read the diary.

Backend: these live in the products, lots, and movements tables in our own Supabase (Postgres) database. Movements are append-only — nothing is ever edited or deleted, corrections are new entries. Every row carries the email of the person who made it. That's the entire trust model.

2 · SKU vs UPC — what goes in which box

SKUUPC
WhatOur internal code for the item. We invent it. Every item must have one, and it must be unique.The manufacturer's barcode number printed on retail packaging — usually 12 digits under the bars.
Where it comes fromYou (or the suggest one link). Existing items keep their Shopify-era SKUs like JS14H-WC.The package itself. Read the digits under the barcode, or scan it straight into the field.
Required?Yes, always.No. Raw fish, bulk cases and packaging usually have none — that's fine (see §10).
What the scanner does with itScans our own printed labels (the SKU rendered as a Code 128 barcode).Scans the retail barcode directly.
Fastest way to capture a UPC with zero typos: when adding the item on a phone, tap into the UPC field and scan the package with a USB/Bluetooth scanner — or type the 12 digits from under the bars. The in-app camera scanner is for finding items once they exist; the UPC field is filled by keyboard or hardware scanner.
Backend: when a barcode is scanned anywhere in the app, matching is tried in this order: exact UPC → exact SKU. Formats the camera reads: UPC-A, UPC-E, EAN-13, EAN-8, and Code 128 (our own labels).

3 · Adding items, one at a time

Products page → + Item (admin). Field by field, top to bottom:

FieldWhat to enterWhy it matters
SectionProduct / Packaging / FishWhich page it lives on. Fish = raw seafood tracked by weight; Packaging = boxes, sleeves, labels; Product = everything finished.
NameWhat a person would call it — "Wild Sockeye Jerky Original 70g"Shows on every screen, label and report.
SKUYour code, or click suggest one for the next free number in the categoryThe item's permanent identity. Saved uppercase.
UPCThe 12 digits under the retail barcode; blank if there isn't oneMakes the camera scanner find it instantly.
CategoryShort group code — JERKY, SMOKED, CANDY, CANS, FRESH…Filters, count sheets, and the SKU-suggester all group by it.
Size"70g", "1kg", "50 lb case"…Appears on labels and pick lists so nobody grabs the wrong format.
Case packUnits per case (e.g. 12)Purchase suggestions round to whole cases; exports show case counts.
Unit of measureunits for things you count by the piece; lb or kg for things you weighUnits round to whole numbers; weights keep one decimal. Fish defaults to lb.
Reorder pointLeave 0 for nowOnce real demand flows, Admin's Apply suggested ROPs sets these from actual math.
Lead time (days)How long a resupply takes, if you know itFeeds safety-stock math. Blank = 14-day default.
Shelf life (days)e.g. 365 for jerky, 730 for cansThe best time-saver in the app: receiving auto-fills every best-by date as pack date + shelf life.
AllergensTick what it contains (fish, soy, sesame…)Powers the allergen matrix and the production-run carry-over warnings.
Photo URLOptional — a web image linkShows on the phone count card; Shopify-linked items already have theirs.
Custom fieldsWhatever Ryder has defined in Settings (e.g. Country of origin)Appear automatically on every item.

Press Save. The item now exists — with zero on hand, because quantity only ever comes from counts and receipts (§6–8).

Backend: one row inserted into products. Any later edit to the important fields (SKU, UPC, size, case pack…) is recorded in product_audit — who changed what, from what, to what.

4 · Adding a whole shelf fast

  1. Stand in front of the shelf. Open + Item.
  2. Fill the first item, but press Save & add another instead of Save.
  3. The form clears but keeps the Section and Category — because you're probably still on the same shelf. Name → SKU (suggest one gives you the next number) → UPC → size → save & next.
  4. Rhythm: about 20–30 seconds per item once you're going. A 40-item shelf is a coffee-length job.
Doing packaging? Same flow with Section = Packaging. Boxes and sleeves have no UPC — skip it; they'll get scannable shelf labels in §10.

5 · Adding items in bulk (CSV import)

For a list that already exists in a spreadsheet (Sage item lists, a supplier's product sheet), skip the typing entirely. Import page (admin):

  1. Get your list into columns. Only sku is mandatory; everything else is optional. Recognized columns (Sage's names work automatically):
    ColumnAlso accepted as
    skuItem, Item No, Item Number, Item Code, Part Number, Number
    nameDescription, Item Description, Product
    sectiontype — product / packaging / fish
    category, size, upcbarcode → upc
    case_packcasepack
    uomunit, units — values: units / lb / kg
    shelf_lifeshelflife, shelf life days
    reorderreorderpoint
    qty + location + lot + best_bysee §8 — these book opening stock
  2. Copy the whole sheet (with the header row) and paste into the Import box.
  3. Press Check. Nothing is written yet. You get a preview: how many rows parsed, how many update existing SKUs, how many create new items, how many carry opening quantities.
  4. If the preview reads right, press Apply. Rows that match an existing SKU update it; new SKUs are created; failures are counted and reported, never silently skipped.
There's a ready-made starting file in this folder: WCS-Opening-Stock-Template.csv — and HOW-TO-load-your-Sage-data.md shows real Sage-flavoured examples.

6 · Entering quantities — the phone walk (the way that wins)

Quantities enter the system as counts. A count says: "I physically looked, and there are X." Here is the whole loop, tap by tap:

  1. Open Count on your phone. On a phone it's automatically one-item-at-a-time card mode.
  2. Top of the screen: pick the location you are physically standing in (Main Freezer, Cooler…). Every count you save goes into that location — change it when you walk to the next room. The app remembers your last location, even between sessions.
  3. Set the scope: Never counted for a first stocktake (it lists exactly what's still untouched — the list shrinks as you go), or Due for count for the weekly routine.
  4. Tap 📷 Scan → point the camera at the case. The item's card appears: photo, SKU, name, size, and what the system currently believes.
  5. Count what's actually there and type it. Whole numbers for unit items; weights take decimals (e.g. 412.5).
  6. Lot number: it pre-fills with a dated stocktake lot (COUNT-260907). If the case shows a real lot number, type that instead — real lots make recalls sharper. If not, the dated one is exactly right.
  7. Best-by: type it if it's on the case; skip if not.
  8. Save count → the next item slides in. Skip → passes without writing anything.
  9. No barcode on the item? Don't stop — search it by name in the box at the top, count it, and put it on the §10 label list.
  10. Freezer killed the wifi? Keep going. Counts save on the phone and upload themselves automatically when you're back in range — you'll see the toast when they land.
Backend, per save: (1) a lots row is created (or updated if that item+lot+location already exists) with your quantity; (2) a movements row records the difference between what the system believed and what you counted — reason count, your name, timestamp. If the system said 0 and you counted 48, the movement is +48. If it said 50 and you counted 48, the movement is −2. Zero-difference counts are logged too — they're the proof of accuracy on the Count-variance report.
A count is the strongest statement in the system — it overrides everything. That's why it's also the universal fix: whenever numbers are wrong for any reason, counting the item sets the truth.

7 · Entering quantities — desk & paper

Desk table

  1. Count → 🖥 Desk mode (a computer shows this by default). Every item in scope is a row: system quantity, then empty boxes for your count, lot, best-by.
  2. Type the count, press Enter — it saves and jumps to the next row. Spreadsheet speed.

Clipboard first, keyboard after

  1. Reports → Count sheets → print. Items grouped by section and category, with the system's number and blank columns for count / lot / notes.
  2. Walk with the clipboard, then enter the results in Desk mode. Two people make this very fast: one reads, one types.

8 · Entering quantities — in bulk (CSV)

The Import page books opening stock in the same pass that creates items. Add these columns to your §5 sheet:

  1. qty — the counted quantity. Any row with a positive qty books stock; rows without qty just create/update the item.
  2. location — optional; matches your location names loosely ("main" finds "Main Freezer"). Blank = your first location.
  3. lot — optional; blank gets the dated COUNT- lot.
  4. best_by — optional; takes 2027-03-01 or most spreadsheet date formats.
  5. Check first — the preview tells you exactly how many rows will carry an opening quantity — then Apply.
Backend: identical to a phone count — each qty row creates the lot and logs a count movement noted "Opening balance import". The audit trail never has gaps, no matter which door the data came in through.

9 · The scanner, screen by screen

One 📷 Scan button, three behaviors depending on where you are:

Where you scanWhat happens
ProductsJumps to that item's section, opens its row with all its lots showing. "What is this and how much do we have?"
CountJumps the count card straight to that item — the freezer-walk loop of §6.
Receiving sheet (📷 Scan cases)Continuous mode — the camera stays on and every case scanned adds 1 to that item's line. Unload the truck scanning as you go, then fill in lots and dates.
Ship sheet (📷 Scan cases)Same continuous mode going the other way — scan each case as it's loaded and the outgoing lines build themselves, with live availability beside each.
TraceRuns a trace on the code — scan a lot label here and you get the lot's full history, mass balance, and hold button.

10 · Making everything scannable (labels)

Three label printers, all built-in, no special hardware — any office printer works:

LabelWhereUse for
Shelf & bin labelsReports → Shelf & bin labelsOne per item, whole catalog, 3-across grid. Barcode = UPC if the item has one, otherwise the SKU as Code 128. Tape to shelves/bins — this makes packaging and no-UPC items scannable.
Case / lot labels🏷 Labels on the receiving sheetOne per received line: item, SKU, LOT number as a barcode, packed & best-by dates. Tape to each case as it comes off the truck.
Reprints🏷 on any lot row (Products)Label got wet/torn, case repacked — two clicks reprints it.
Backend: lot barcodes are the lot number itself in Code 128 — which is why scanning one in Trace resolves instantly to that exact batch.

11 · The day-one recipe, start to finish

The exact order that gets an empty system to a running one, fastest:

  1. Finish the catalog first (§3–5): every product, packaging item, and fish form gets its item row — SKU always, UPC where the package has one, shelf life wherever you know it. Don't enter any quantities yet.
  2. Print Shelf & bin labels (§10) and tape them up — 20 minutes that makes every future count a scan instead of a search.
  3. Walk the building with Count → "Never counted" (§6): one location at a time, scan-count-save until the Never-counted list reads zero. Split rooms between people — each picks their location at the top.
  4. Verify: Reports → Count variance shows every count you just made; the Dashboard tiles come alive; the daily watchdog's "shipped with no stock on record" alarm goes quiet.
  5. Then let it run: from this moment, receive every delivery (§ Manual 5), ship everything through orders, and just keep up with the small "Due for count" list each week. The system stays true from here by itself.
After step 3, the reorder engine, expiry alerts, turns, and ✨ Suggest order all switch from silence to real numbers — they were waiting for stock to exist.

12 · Conventions that keep it clean

Companion: the complete Manual (every screen), WCS-Opening-Stock-Template.csv, HOW-TO-load-your-Sage-data, WCS-Cheat-Sheet. Questions → Ryder.