sheetscope_
Purchase order extraction

Every purchase order line, in one table you can query

Pull po_number, item_sku and expected_delivery_date out of PO PDFs and supplier confirmations. One row per line, ready to sort, filter, total and export.

your documents 3 files
PDF PO-88214-northwind.pdf

Northwind Supply Co.

PO-8821412 lines
PDF so-confirm-acme.pdf their confirmation

Acme Industrial

PO-88219
XLSX blanket-po-meridian.xlsx

Meridian Components

PO-88231blanket
extract
queryable data 4 rows · 5 columns
#po_numbersupplier_nameitem_skuquantity_orderedunit_price
1PO-88214Northwind Supply Co.NW-44102403.85
2PO-88214Northwind Supply Co.NW-44186012.40
3PO-88219Acme IndustrialAC-220112188.00
4PO-88231Meridian ComponentsMC-710000.42
SELECT po_number, supplier_name, item_sku, quantity_ordered, unit_price FROM "purchase_order_line" ORDER BY po_number, item_sku;
PO IN, LINES OUT

One order in, one row per line out

The grain is the point. A twelve-line PO becomes twelve rows, each carrying the header. And your PO, their confirmation and a blanket order in a workbook all land in the same table.

PDF PO-88214-northwind.pdf

Northwind Supply Co.

PO-8821412 lines
extract
po_numbersupplier_nameitem_skuquantity_orderedunit_price
PO-88214Northwind Supply Co.NW-44102403.85

One row per line. Header repeated on each.

PDF PO-88214-northwind.pdf

Your PO, as you sent it

12 lines
PDF so-confirm-acme.pdf supplier’s form

Their order confirmation

same PO number
XLSX blanket-po-meridian.xlsx

A blanket PO in a workbook

release schedule
WHAT A PO TABLE IS FOR

What a PO folder should tell you

Get open POs into one list

What is on order, from whom, and at what price. One list for the whole folder.

Total what you have committed

Quantity times unit price, grouped by supplier, across every PO you have issued rather than one file at a time.

Check promised dates against reality

Sort on expected_delivery_date to see what is overdue before the supplier tells you.

WHAT A LINE CARRIES

What a PO line has to carry

The starter schema, verbatim: these are the column names your SQL will use.

purchase_order_line: the starter schema in the app, verbatim

  • po_number string
  • order_date string
  • supplier_name string
  • item_sku string
  • item_description string
  • quantity_ordered number
  • unit_price number
  • line_total number
  • expected_delivery_date string

the same orders, one row each

The mock at the top of this page is one row per line. Ask for the header fields only and the same orders come back one row each — line_count counted by the query rather than read off the page.

po_numberorder_datesupplier_nameline_count
PO-882142026-05-02Northwind Supply Co.12
PO-882192026-05-06Acme Industrial3
PO-882312026-05-09Meridian Components1
WHAT ONE TABLE ANSWERS

Questions a folder of POs can’t answer

Once the lines are rows, these are ordinary SQL. Each one runs over the whole folder at once rather than a file at a time.

What am I committed to, by supplier?

SELECT supplier_name, sum(quantity_ordered * unit_price) AS committed FROM "purchase_order_line" GROUP BY 1 ORDER BY 2 DESC;

What was due before today and has not landed?

SELECT po_number, supplier_name, item_sku, expected_delivery_date FROM "purchase_order_line" WHERE expected_delivery_date < '2026-06-01' ORDER BY expected_delivery_date;

Which lines did nobody commit to a date on?

SELECT po_number, supplier_name, item_description FROM "purchase_order_line" WHERE expected_delivery_date IS NULL;

Am I paying the same price for the same part?

SELECT item_sku, min(unit_price) AS low, max(unit_price) AS high FROM "purchase_order_line" GROUP BY 1 HAVING min(unit_price) <> max(unit_price);
THE AWKWARD PARTS

Where purchase orders get awkward

Forty-line orders, supplier confirmations, SKUs nobody formats the same way, and the one thing this does not do.

A PO has forty lines and I need all of them.
One row per line, with the po_number header repeated on each, so a line still means something once it leaves the document.
Suppliers send their own confirmation, not my PO back.
Same schema, different document. The PO number is printed on both, so their form and yours land in the same table.
Every supplier formats SKUs differently.
SKUs come back verbatim. Normalise with upper() or replace() in SQL, where the rule is visible and you can change it.
Some lines have no SKU or no need-by date.
Leave them out of required and they come back empty. WHERE expected_delivery_date IS NULL finds the lines nobody committed to.
Can it match POs against invoices for me?
Not in a query. One query reads one schema, so there are no joins. Extract each side, export both, and match them in your spreadsheet or ERP. This removes the keying, not the matching.

The documents either side of a PO

Get your purchase orders into SQL

Upload a few POs and define the line fields you need.