Purchase Orders

Last updated on 2026-04-05

The purchase orders module handles the full procurement lifecycle -- from creating new orders through to receiving inventory against them. It includes list views with status filtering, detailed order views with line items, forms for creating and editing, and a receiving workflow for recording delivered goods. All screens share the (dashboard) route group layout.

Purchase Order List

Route: /purchase-orders

The primary PO view with a data table supporting search, status filtering, and sorting.

  • Data table -- columns for PO number (linked to detail), supplier name (linked to supplier detail), order date, expected delivery date, total amount, status badge, items count, and a row actions dropdown
  • Search -- text input filtering by PO number or supplier name
  • Status filter tabs -- pill-style tabs for All, Draft, Submitted, Confirmed, Shipped, Partially Received, Received, and Cancelled
  • Date range filter -- date picker to filter by order date or expected delivery date
  • Sorting -- column header click to sort by PO number, date, total, or status
  • Pagination -- page-based navigation with configurable page size (10, 25, 50)
  • Row actions -- dropdown menu with View, Edit, Receive, and Cancel options; cancel triggers an AlertDialog confirmation
  • Create button -- prominent "New Purchase Order" button in the page header
import { PurchaseOrderTable } from "@/components/inventory/purchase-order-table"
import { PurchaseOrderFilters } from "@/components/inventory/purchase-order-filters"

PO Status Flow

Status Color Description
Draft gray Order created but not yet submitted
Submitted blue Sent to supplier, awaiting confirmation
Confirmed indigo Supplier confirmed the order
Shipped purple Supplier has shipped the goods
Partially Received amber Some line items received, others pending
Received green All items received and checked in
Cancelled red Order cancelled

Data Sources

Data Source Location
Purchase orders purchaseOrders data/seed.ts
Suppliers suppliers data/seed.ts

Purchase Order Detail

Route: /purchase-orders/[id]

A comprehensive view of an individual purchase order with header info, line items table, and status tracking.

  • PO header -- PO number, supplier name (linked to supplier detail), order date, expected delivery date, status badge, and total amount
  • Status timeline -- horizontal progress indicator showing the PO's journey through statuses: Draft, Submitted, Confirmed, Shipped, Received
  • Line items table -- data table showing each ordered item with product name (linked to product detail), SKU, quantity ordered, quantity received (if applicable), unit cost, line total, and receiving status indicator
  • Order summary -- subtotal, tax, shipping cost, and grand total in a summary card
  • Notes section -- freeform notes attached to the order with timestamps
  • Action buttons -- contextual actions based on status:
    • Draft: Submit, Edit, Delete
    • Submitted/Confirmed: Edit, Cancel
    • Shipped: Receive Items
    • Partially Received: Receive Remaining
    • Received: No actions (read-only)
import { PurchaseOrderHeader } from "@/components/inventory/purchase-order-header"
import { PurchaseOrderTimeline } from "@/components/inventory/purchase-order-timeline"
import { LineItemsTable } from "@/components/inventory/line-items-table"
import { OrderSummary } from "@/components/inventory/order-summary"

PO Detail Layout

┌─────────────────────────────────────────────┐
│ PO-2024-0047  Supplier Name        Status   │
│ Order Date     Expected Delivery    Total    │
├─────────────────────────────────────────────┤
│ Draft → Submitted → Confirmed → Shipped → ✓ │
├─────────────────────────────────────────────┤
│ Line Items                                   │
│ ┌─────┬──────┬─────┬──────┬────────┬──────┐ │
│ │ SKU │ Name │ Qty │ Rcvd │ Cost   │ Total│ │
│ ├─────┼──────┼─────┼──────┼────────┼──────┤ │
│ │ ... │ ...  │ ... │ ...  │ ...    │ ...  │ │
│ └─────┴──────┴─────┴──────┴────────┴──────┘ │
├─────────────────────────────────────────────┤
│ Subtotal / Tax / Shipping / Grand Total      │
├─────────────────────────────────────────────┤
│ Notes                                        │
└─────────────────────────────────────────────┘

Create Purchase Order

Route: /purchase-orders/new

A multi-section form for creating a new purchase order.

  • Supplier -- supplier select (searchable dropdown), auto-populates supplier address and payment terms
  • Order Details -- order date (date picker, defaults to today), expected delivery date, reference number (optional)
  • Line Items -- repeatable row group:
    • Product select (searchable, filtered by supplier's product catalog)
    • Quantity (number input)
    • Unit cost (currency input, auto-filled from product's cost price)
    • Line total (auto-calculated: quantity x unit cost)
    • Add row / remove row buttons
  • Costs -- tax percentage, shipping cost (currency input)
  • Notes -- freeform textarea for order notes or special instructions
  • Actions -- "Save as Draft" and "Submit to Supplier" buttons
import { PurchaseOrderForm } from "@/components/inventory/purchase-order-form"
import { LineItemEditor } from "@/components/inventory/line-item-editor"

Edit Purchase Order

Route: /purchase-orders/[id]/edit

A pre-populated form for editing an existing PO. Only available for Draft and Submitted statuses. Shares the same form component as the create page but with pre-filled values.

  • All fields from the create form are available and editable
  • Line items can be added, removed, or modified
  • Changes to quantity or cost automatically recalculate totals

Receiving Workflow

Route: /purchase-orders/[id]/receive

The receiving screen allows warehouse staff to record items as they arrive against a purchase order. This is a critical workflow for updating stock levels.

  • PO reference -- read-only header showing PO number, supplier, and expected delivery date
  • Receiving table -- each line item displayed with:
    • Product name and SKU
    • Quantity ordered
    • Quantity previously received (for partial receives)
    • Quantity to receive (editable number input, defaults to remaining quantity)
    • Receiving warehouse select (dropdown of active warehouses)
    • Condition select (Good, Damaged, Rejected)
    • Notes field per line item
  • Batch receive -- "Receive All" button to set all line quantities to their remaining amounts
  • Partial receive -- adjust individual quantities to receive partial shipments; PO status updates to "Partially Received"
  • Discrepancy handling -- if received quantity differs from ordered, a warning badge appears with options to note the discrepancy
  • Confirmation -- review summary showing total items to receive, warehouse assignments, and any flagged discrepancies before finalizing
  • Stock update -- on confirmation, stock levels at the assigned warehouses are updated and an activity log entry is created
import { ReceivingForm } from "@/components/inventory/receiving-form"
import { ReceivingLineItem } from "@/components/inventory/receiving-line-item"
import { ReceivingSummary } from "@/components/inventory/receiving-summary"

Receiving Workflow Diagram

PO Shipped
    │
    ▼
Open Receive Screen
    │
    ▼
Enter quantities per line item
    │
    ├── All items received → PO status: Received
    │
    └── Partial items received → PO status: Partially Received
                │
                ▼
        Receive remaining later

Data Sources

Data Source Location
Purchase orders purchaseOrders data/seed.ts
Line items purchaseOrderLineItems data/seed.ts
Products products data/seed.ts
Suppliers suppliers data/seed.ts
Warehouses warehouses data/seed.ts

Next Steps