The purchase order CSV, column by column, with the formulas
All 21 columns of the Restock Ops purchase order CSV, why it is one row per line, and formulas for outstanding units, open spend and unpaid invoices.
Shopify will give you a purchase order as a PDF, which is what you send to a supplier. It will not give you a purchase order as a spreadsheet, which is what everyone else wants: the bookkeeper reconciling supplier invoices, the owner asking how much is on order with a supplier right now, the staff member checking which lines of a delivery are still short. Restock Ops has an Export CSV button on the purchase orders list and on each purchase order. This post is the manual for the file it produces: what each column contains, the one design decision that makes it behave in a spreadsheet, and the handful of formulas that turn it into the three reports people actually ask for.
Two things before the columns. The export is a plain CSV, UTF-8, with a header row, that opens in Excel, Numbers and Google Sheets without an import wizard. And it describes the purchase orders as Restock Ops knows them. Inventory quantities are not in it, because Shopify is the system of record for stock; the export is the purchasing paperwork, not the stock count.
Three ways to get the file
- The Export CSV button on the purchase orders list exports what the list is currently showing. The status filter and the supplier filter both apply, so Open plus a supplier gives you one supplier's unfinished orders; Unpaid gives you every order with an invoice still outstanding; All gives you everything, including closed and canceled orders.
- The Export CSV button on a single purchase order exports that one order and names the file after its number, so PO-0042.csv is the file you attach to the email about PO-0042.
- There is no scheduled or emailed export. If you want a weekly snapshot, exporting All on the same day each week and keeping the files is the low-tech version, and the dates in the file make them easy to tell apart.
One row per line, header repeated
A purchase order has information at two levels: the order itself, with its supplier, dates and invoice, and the lines, each a variant with a quantity and a cost. There are two ways to flatten that into a table. You can put the order fields on the first line only and leave them blank on the rest, which looks tidy and breaks the moment you sort or filter. Or you can repeat the order fields on every row, so every row is self-describing. Restock Ops does the second. Each row of the export is one line of one purchase order, carrying the order's number, status, supplier, dates and invoice fields alongside the line's product, quantities and cost.
This is the decision that makes the formulas below work. A pivot table on Supplier sums across all of that supplier's lines because every line knows its supplier. A filter on Invoice status equals UNPAID shows the lines of unpaid orders, not just their first lines. The cost is that a ten-line order is ten rows and the order-level fields are repeated ten times, which is cheap in a spreadsheet and exactly what spreadsheets are built for.
An order with no lines yet, a draft someone started and left, still appears as one row with the order fields filled and the line fields empty, so a count of distinct PO numbers in the file always matches the count of orders exported.
The 21 columns
| Column | Level | What it holds |
|---|---|---|
| PO number | Order | The number Restock Ops assigned, for example PO-0042. Same on every row of the order. |
| Status | Order | One of DRAFT, ORDERED, PARTIAL, RECEIVED, CLOSED, CANCELED. Uppercase codes, not the labels shown in the app. |
| Supplier | Order | The supplier's name as entered in Suppliers. |
| Destination | Order | The Shopify location the goods are being received into. |
| Currency | Order | The order's currency code. Costs in the file are in this currency. |
| Ordered at | Order | Date the order was marked ordered, as YYYY-MM-DD. Blank for drafts. |
| Expected at | Order | The expected delivery date, if one was set. |
| Reference | Order | Your free-text reference, often the supplier's order confirmation number. |
| Invoice number | Order | The supplier invoice number, once recorded. |
| Invoice status | Order | NONE until an invoice is recorded, then UNPAID or PAID. |
| Invoice due | Order | The invoice due date, if recorded. |
| Product | Line | The product title at the time the line was added. |
| Variant | Line | The variant title; blank for single-variant products. |
| SKU | Line | Your Shopify SKU for the variant. |
| Barcode | Line | The variant's barcode as stored in Shopify. |
| Supplier SKU | Line | The supplier's own code for the item, if you recorded one against the supplier. |
| Qty ordered | Line | Units ordered on this line. |
| Qty received | Line | Units received against this line so far, across every receipt. |
| Unit cost | Line | Cost per unit, before tax, in the order's currency. |
| Tax % | Line | The tax rate entered on the line, as a percentage. |
| Line total | Line | Qty ordered times Unit cost, before tax. Not reduced by what has been received. |
Reading the money columns
Line total is the ordered value excluding tax, so a sum of that column is your committed spend before tax for whatever you exported. Tax is not pre-computed; it is Line total multiplied by Tax % divided by a hundred, which keeps the file honest when lines on one order carry different rates, as they do for a mixed delivery of food and non-food in the UK or of books and merchandise in much of Europe. Unit cost is the figure you typed when the line was added, in the order's currency, and it is not converted. If you buy from suppliers in two currencies, the Currency column is there precisely so a pivot table can keep them apart; summing across currencies is the one mistake the file cannot prevent for you.
The shipping cost recorded on a purchase order is an order-level figure, not a line, and it is not in this export; neither are duties or other charges that arrive on a separate invoice. Spreading them across the units you received is a costing decision, and the place to think it through is what to include in cost per item, not a flat file.
Three formulas that answer the usual questions
Assume the header is in row 1 and the columns are in file order, so Qty ordered is Q, Qty received is R, Unit cost is S and Line total is U. The formulas below are written for Google Sheets and work unchanged in Excel.
- Outstanding units per line: add a column with =Q2-R2 and fill down. Filtering to values above zero on an Open export is the list of everything still expected, with supplier and expected date on each row. Summing it per Supplier in a pivot table is the answer to how much is still coming from each.
- Open spend per supplier: =SUMIFS(U:U, C:C, "Acme Ltd", B:B, "ORDERED") plus the same with PARTIAL gives committed value with that supplier that has not fully arrived. Or pivot on Supplier with Line total summed and Status as a filter. Remember this is before tax and in the order's currency.
- Value received but not yet invoiced or paid: filter Invoice status to NONE or UNPAID, then sum a helper column =R2*S2, which is received units times unit cost. That is the amount you owe or will shortly owe, line-accurate even when deliveries were partial. Pair it with Invoice due to sort by what falls due first, the same view the app's invoice tracking gives you, but across every order at once.
Handing it to someone else
The bookkeeper's version of this is usually the Unpaid export at month end: every order with an outstanding invoice, with supplier, invoice number, due date and the line detail to match against the supplier's statement. Because PO number, Reference and Invoice number are all there, the match works whichever number the supplier quotes. The accountant's version is the All export at year end, filtered to RECEIVED and CLOSED for the period, as the purchasing side of cost of goods; the Barcode and SKU columns line up with Shopify's own product export for anyone cross-checking.
The supplier's version is the single-order export when a delivery does not match. Send them PO-0042.csv with Qty ordered and Qty received side by side and the conversation about what was short-shipped is a lot shorter than it would be from a PDF, as described in what to do when a delivery does not match the order.
Finally, the export is yours. There is no plan gate on it and no limit on how often you use it. Restock Ops keeps the purchase orders; the CSV is how you take them anywhere else.
FAQ
Why does my export have more rows than I have purchase orders?
Because each row is one line of a purchase order, with the order's fields repeated on every row. A five-line order is five rows. Count distinct values in the PO number column to get the number of orders; it will match what the list showed.
Does the export include inventory quantities on hand?
No. Shopify is the system of record for stock levels and already exports them. The purchase order export is the purchasing document: what was ordered, from whom, at what cost, and how much of it has been received so far.
Does Line total account for tax or for what has been received?
Neither. Line total is quantity ordered times unit cost, before tax. Tax is computed from the Tax % column, and received value is quantity received times unit cost; both are one short formula in the spreadsheet, and keeping them separate avoids baking a costing decision into the file.
Can I export only one supplier's orders?
Yes. Filter the purchase orders list by supplier, and by status if you like, then press Export CSV. The export respects both filters, so Open plus a supplier gives you exactly that supplier's unfinished orders.
Try it on your store. Restock Ops adds purchase orders with partial receiving, supplier notes, cost history, barcode labels, scanner stocktakes and a reorder report on top of Shopify inventory. From $19/month, 14-day free trial.