Proper Spreadsheets

Templates › Business

Inventory & Stock Control

Made for small shops and makers holding stock.

A stock list with cost, selling price and quantity on hand, a log of stock coming in and going out, and a summary showing what is running low and what the stock is worth. The summary carries a chart that redraws itself as you type.

Of the 29 columns, you fill in 18 and the other 11 work themselves out, and all 13 figures on the summary do too. There is room for 2,300 rows of your own.

£4.99one payment, yours to keep

  • Opens in Excel, Google Sheets and Numbers
  • Delivered straight away
  • No macros, nothing to install
  • Change it free before you buy

Payment is handled by Stripe. Your card details go to them and never to us. Sales are final, which is why every tab, column and calculation is shown on this page first.

Already have a spreadsheet of your own? Check it for mistakes, free.

The workbook's summary and the table behind it
A row typed into the real file. Every figure that changes is the spreadsheet's own arithmetic. What the film shows, in order:
  1. A new row is typed into the Products tab, one cell at a time, in the white cells a person fills in.
  2. The shaded cells in that row fill themselves in.
  3. The figures on the Summary tab change to include the new row.
  4. The chart, Stock value by category, redraws with it.
The chart, drawn from the totals in the table beside it. See it full size
Where you type, and the shaded columns that work themselves out. See it full size

Everything inside, before you pay

This is the whole design: every tab, every column and how each calculated one is worked out. White cells are yours to fill in; the shaded ones work themselves out and are locked so a formula cannot be overwritten by accident. There is room for 2,300 rows. Open any tab to see its columns.

Products

18 columns

One row per product you sell. Quantity on hand is worked out from the opening count plus everything logged on the Stock Movements tab. Ready for 300 rows, every one with its formulas in place.

ColumnWhat goes in itWorked out as
SKUYour own code for the product. Any short label works.Type any text.
ProductKeep each name unique. Stock movements are matched to a product by this name.Type any text.
CategoryPick one: Food, Drink, Household, Toiletries, Stationery, Gifts or Other.
SupplierType any text.
UnitPick one: Each, Pack, Box, Kg or Litre.
Cost PriceType an amount in £.
Sell PriceType an amount in £.
MarginProfit as a share of the selling price.Fills itself in.

Worked out from this row's Cost Price and Sell Price.

The formulaIF(OR(ISBLANK([cost_price]),ISBLANK([sell_price])),"",IFERROR(([sell_price]-[cost_price])/[sell_price],0))
Opening CountHow many you had when you started using this file.Type a number.
InFills itself in.

The total of Quantity on Stock Movements where Product matches this row's Product and In Or Out is “In”.

The formulaIF(ISBLANK([product_name]),"",SUMIFS([Stock Movements!quantity],[Stock Movements!product],[product_name],[Stock Movements!movement_type],"In"))
OutFills itself in.

The total of Quantity on Stock Movements where Product matches this row's Product and In Or Out is “Out”.

The formulaIF(ISBLANK([product_name]),"",SUMIFS([Stock Movements!quantity],[Stock Movements!product],[product_name],[Stock Movements!movement_type],"Out"))
In Stock NowFills itself in.

Worked out from this row's Product and Opening Count, using Quantity, Product and In Or Out on Stock Movements.

The formulaIF(ISBLANK([product_name]),"",[opening_stock]+SUMIFS([Stock Movements!quantity],[Stock Movements!product],[product_name],[Stock Movements!movement_type],"In")-SUMIFS([Stock Movements!quantity],[Stock Movements!product],[product_name],[Stock Movements!movement_type],"Out"))
Reorder AtWhen stock falls to this number or below, the product is flagged for reordering.Type a number.
Order Up ToThe level you like to restock to.Type a number.
Units To OrderFills itself in.

Worked out from this row's Product, In Stock Now, Reorder At and Order Up To.

The formulaIF(ISBLANK([product_name]),"",IF([on_hand]<=[reorder_level],MAX(0,[target_stock]-[on_hand]),0))
Value At CostFills itself in.

Worked out from this row's Product, In Stock Now and Cost Price.

The formulaIF(ISBLANK([product_name]),"",ROUND([on_hand]*[cost_price],2))
Value At RetailFills itself in.

Worked out from this row's Product, In Stock Now and Sell Price.

The formulaIF(ISBLANK([product_name]),"",ROUND([on_hand]*[sell_price],2))
StatusFills itself in.

Worked out from this row's Product, In Stock Now and Reorder At.

The formulaIF(ISBLANK([product_name]),"",IF([on_hand]<=0,"Out of stock",IF([on_hand]<=[reorder_level],"Reorder now","In stock")))

Stock Movements

11 columns

Every delivery in and every sale, breakage or write off going out. Pick the product from the dropdown so it counts against the right line. Ready for 2,000 rows, every one with its formulas in place.

ColumnWhat goes in itWorked out as
DateType a date.
ProductPick one of the Product entries on Products.
In Or OutPick one: In or Out.
ReasonPick one: Purchase, Sale, Customer return, Return to supplier, Wastage or Stocktake adjustment.
QuantityType a number.
Unit CostWhat each unit cost you on this movement.Type an amount in £.
Line ValueFills itself in.

The Quantity times the Unit Cost.

The formulaIF(ISBLANK([quantity]),"",ROUND([quantity]*[unit_cost],2))
ChangePositive for stock coming in, negative for stock going out.Fills itself in.

Worked out from this row's Quantity and In Or Out.

The formulaIF(ISBLANK([quantity]),"",IF([movement_type]="Out",-[quantity],[quantity]))
MonthFills itself in.

Worked out from this row's Date.

The formulaIF(ISBLANK([movement_date]),"",TEXT([movement_date],"YYYY-MM"))
ReferenceDelivery note, order number or till receipt.Type any text.
NotesType any text.

Summary

13 figures

What the stock is worth and what needs ordering, updating as you fill the other two tabs in.

FigureWorked out as
Products tracked

The number of rows on Products with Product filled in.

The formulaCOUNTA([Products!product_name])
Units in stock

The total of In Stock Now on Products.

The formulaSUM([Products!on_hand])
Stock value at costWhat you paid for everything currently on the shelves.

The total of Value At Cost on Products.

The formulaSUM([Products!stock_value])
Stock value at retail

The total of Value At Retail on Products.

The formulaSUM([Products!retail_value])
Profit if all sold

Worked out from Value At Retail and Value At Cost on Products.

The formulaSUM([Products!retail_value])-SUM([Products!stock_value])
Average margin

The average of Margin on Products.

The formulaIFERROR(AVERAGE([Products!margin_pct]),0)
Lines to reorderProducts at or below their reorder level.

The number of rows on Products where Status is “Reorder now”.

The formulaCOUNTIF([Products!status],"Reorder now")
Lines out of stock

The number of rows on Products where Status is “Out of stock”.

The formulaCOUNTIF([Products!status],"Out of stock")
Units to order

The total of Units To Order on Products.

The formulaSUM([Products!order_qty])
Units received this month

Worked out from Quantity, Month and In Or Out on Stock Movements.

The formulaSUMIFS([Stock Movements!quantity],[Stock Movements!month_key],TEXT(TODAY(),"YYYY-MM"),[Stock Movements!movement_type],"In")
Units gone out this month

Worked out from Quantity, Month and In Or Out on Stock Movements.

The formulaSUMIFS([Stock Movements!quantity],[Stock Movements!month_key],TEXT(TODAY(),"YYYY-MM"),[Stock Movements!movement_type],"Out")
Cost of stock out this month

Worked out from Line Value, Month and In Or Out on Stock Movements.

The formulaSUMIFS([Stock Movements!line_value],[Stock Movements!month_key],TEXT(TODAY(),"YYYY-MM"),[Stock Movements!movement_type],"Out")
Movements recorded

The number of rows on Stock Movements with Date filled in.

The formulaCOUNT([Stock Movements!movement_date])