Purchasing — purchase orders and vendors, wired straight into stock and spend
Who it's for
The owner or manager drafts orders, sends them to vendors, and approves the spend. Production staff receive shipments when they arrive — counting boxes is a stock job, not a money job, so receiving doesn't need billing access. Anyone watching the Money hub sees what each order booked to Expenses.
Where it fits
Purchasing sits on the supply side of production: material runs low → you order it → it arrives → stock goes up and the cost lands in your Expenses ledger, all in one motion. See workflow-map.md.
Overview
Two connected pieces:
- Vendors — a proper record for each supplier (contact, email, phone, account number, notes). Purchase orders are addressed to them, and the vendor fields on expense forms autocomplete from this list.
- Purchase orders — a numbered document (
PO-0007) with lines, costs, shipping and tax. It movesDraft → Ordered → (Partially received) → Received, orCancelledif nothing ever arrived. Lines usually link an inventory item, but ad-hoc lines (description + qty + cost) are fine for one-off buys.
The receiving step is the payoff: recording what arrived bumps the linked items' shelf quantities, can update their unit cost to what you actually paid, and books one Material expense for the value received — shipping and tax ride along with the first receipt. Ledger and shelf can never quietly disagree.
Screens & navigation
Shop → Purchasing tab (/shop?tab=purchasing)
- Purchase orders — every PO with status chip, vendor, ETA, received progress and total. Filter chips: Open (default), Draft, Ordered, Partial, Received, All. Buttons: New order and Reorder low stock (with a badge counting items at or under their minimum).
- Vendors — the supplier list with contact details and open-PO counts, plus add/edit dialogs. Inactive vendors stay listed (dimmed) for history but disappear from pickers.
PO detail (/purchasing/[id])
Vendor card, timeline (created/ordered/expected/received), the lines table
(item links, supplier SKUs, ordered vs received, costs), and a cost summary.
The action bar changes with status:
- Draft — Edit, PDF (with a DRAFT watermark), Send to Vendor, Mark Ordered, Cancel.
- Ordered / Partial — Receive Items, PDF, Resend (Ordered only), and Cancel (nothing received yet) or Close Short (something received).
- Received / Cancelled — read-only plus PDF.
Capabilities
- Draft an order — pick a vendor, add lines from inventory (description, unit and cost pre-fill from the item, editable) or ad-hoc lines, set an expected date, shipping, tax, and a note that prints on the PDF.
- Reorder low stock — one click builds draft POs from everything at or under its minimum stock, grouped by each item's preferred vendor, with suggested quantities that restock to twice the threshold. Items without a preferred vendor go in one group you assign before creating.
- Send to vendor — emails a shop-branded PDF of the PO to the vendor's email (with an optional message) and marks it Ordered in the same step. Mark Ordered does the same without the email, for phone/portal orders.
- Receive items — per-line quantities with a Fill remaining button. Partial receipts are normal; the order flips to Partially received and the rest stays open. Each receive event shows exactly what it will book to Expenses before you confirm. An opt-out checkbox updates each received item's unit cost to this order's price (that cost feeds quoting).
- Close short — the vendor shorted you and nothing more is coming: marks the order Received keeping only what actually arrived.
- Cancel — only while nothing has been received.
- Vendor management — create/edit/deactivate; deleting a vendor that has POs or expenses deactivates it instead so history keeps its name. Duplicate names are rejected.
- Inventory tie-ins — items gain a Preferred vendor and Supplier SKU (their part number, printed on the PO). The expense forms' vendor field autocompletes from the vendor list and links the record when the name matches.
- API & webhooks — read
GET /api/v1/purchase-orders(and/{id}); eventspurchase_order.orderedandpurchase_order.received. See api-webhooks.md.
Step-by-step tasks
-
Restock everything that's running low
- Shop → Purchasing → Reorder low stock.
- Uncheck anything you don't want; adjust quantities.
- Create — one draft PO per vendor. Open a draft, review, Send to Vendor.
-
Receive a shipment (even a partial one)
- Open the PO (it's under the Open filter) → Receive Items.
- Enter what arrived per line, or Fill remaining if it all came.
- Check the expense preview line ("Books $X to Expenses"), confirm.
- Stock is on the shelf, the spend is on the Money hub, and the order shows Partially received until the rest arrives.
-
Order something you don't stock
- New order → pick the vendor → add an Ad-hoc line with a description, quantity and cost.
- Ad-hoc lines book their cost when received but never touch inventory.
Settings & permissions
- Inventory permission — vendors, drafting/editing, cancelling, and receiving (production can sign for a delivery).
- Billing permission — Mark Ordered and Send to Vendor: committing money is the gated moment, matching how logging a purchase on a stock adjustment works. Receiving books its expense without a billing check because the spend was approved at order time.
- No new plan gates — Purchasing comes with the Shop hub; the read-only API follows the existing Pro API gate.
Tips & common pitfalls
- Expenses booked by a PO can't be deleted from the Money hub — the PO owns them ("manage this from the purchase order"). This is deliberate: a receive event moves stock across several items at once, and deleting the ledger row couldn't take the stock back.
- Set preferred vendors and supplier SKUs on your regulars. Reorder low stock then groups correctly on its own, and vendors see their own part numbers on your POs.
- A draft PDF carries a DRAFT watermark so a vendor can't mistake it for a commitment — send or mark ordered first if you mean it.
- The vendor needs an email on file before Send to Vendor works; the button tells you if it's missing.
- Zero-cost receipts (free samples) move stock but book no expense — a $0 ledger row is noise.
Related modules
- Inventory — the shelf side: minimum stock levels and unit costs drive reorder suggestions; receiving updates both.
- Invoicing & Billing / Money hub — where the booked expenses appear.
- API & Webhooks — purchase-order reads and events.