| (checkbox) | Table selection + DeleteBulkAction | selection | — (bulk delete of selected POs) | — |
| Created date | TextColumn::date()->sortable() + Filter (date range) | date | stored: purchase_orders.created_date; list sorted ascending by it | — |
| Order # | TextColumn::searchable(isIndividual)->url() | string | stored: purchase_orders.order_no (editable; NOT unique — PK is internal id) | — |
| Supplier | TextColumn::searchable(isIndividual) | string (display name) | stored: purchase_orders.supplier_id | suppliers.id |
| Total order value | TextColumn::numeric()->summarize(Sum) | money MYR | derived: Σ po_lines.qty × unit_price in order currency; 0 MYR rows exist | po_lines |
| Expected arrival | TextColumn::date()->color(fn) red when overdue + Filter (date range) | date, editable | stored: purchase_orders.expected_arrival_date; red when past and not fully received | — |
| Billing status | TextColumn::badge() + SelectFilter (inline bill action in Katana) | enum: Billed / Partially billed (n) / Not billed | derived: netting attached supplier bills against order value; n = bill count | supplier_bills |
| Delivery | TextColumn::badge() + SelectFilter (inline receive action in Katana) | enum: Not received / Partially received | derived: received qty vs ordered qty across PO lines; fully received moves PO to Done tab | po_line_receipts |
| Location scope | SelectFilter (header "All locations" dropdown) | FK filter | stored: purchase_orders.location_id | locations.id |
| Draft tab | — (dropped: Draft view not captured) | lifecycle tab | Open/Draft/Done partition POs by lifecycle state | — |