diff --git a/src/app/(app)/orders/[id]/process/page.tsx b/src/app/(app)/orders/[id]/process/page.tsx index 8234358..58e09f2 100644 --- a/src/app/(app)/orders/[id]/process/page.tsx +++ b/src/app/(app)/orders/[id]/process/page.tsx @@ -473,6 +473,25 @@ export default function ProcessOrderPage({ params }: { params: Promise<{ id: str try { const pb = getPocketBase(); + // Determine whether this save should transition the item + // from `pending` to `processed`. The buyer-tasks page + // (`/orders/tasks`) filters Needs PO by + // `item_status = "processed" && purchase_order = ""`, + // so a priced item with no supplier/cost/PO description + // shouldn't surface there yet. Once all three fields are + // filled we promote it. Items already past `processed` + // (stock_booked, po_generated, ready_delivery, etc.) are + // never downgraded by this save. + const currentItem = items.find((it) => it.id === itemId); + const isReadyForBuyer = + committed.supplier.trim() !== "" && + committed.cost_price > 0 && + committed.po_description.trim() !== ""; + const nextStatus = + currentItem?.item_status === "pending" && isReadyForBuyer + ? "processed" + : currentItem?.item_status; + // v3 stock-out flow (Stream E). When the operator has // toggled the line into "fulfill from stock" mode, the // standard order_item update path is wrong — it would @@ -506,6 +525,12 @@ export default function ProcessOrderPage({ params }: { params: Promise<{ id: str pricing_source: committed.pricing_source || null, matched_price_list_id: committed.matched_price_list_id || null, pricing_notes: committed.pricing_notes || null, + // Stock-fulfil path: the subsequent /api/v1/stock/fulfill + // call will overwrite this with stock_booked before the + // buyer ever sees the row on the buyer-tasks page, so + // promoting to processed here is harmless and keeps the + // row coherent if the stock call fails. + item_status: nextStatus, }); // Step 2: stock-fulfil call (mode: "update"). The // route PATCHes the order_item with stock-fulfil @@ -587,6 +612,12 @@ export default function ProcessOrderPage({ params }: { params: Promise<{ id: str supplier: committed.supplier || null, in_stock: committed.in_stock, notes: committed.notes, + // Promote pending → processed when the operator has + // filled supplier + cost + PO description. This is the + // gate that makes the item visible on the buyer-tasks + // Needs PO tab. Items already past `processed` keep + // their current status (no downgrade). + item_status: nextStatus, // Pricing audit trail — round-trip from quote_item when copied, // or stay blank when the operator typed manually. The price // sheet exposes these fields; the Quote Source panel displays