diff --git a/src/app/dashboard/financial/purchase-orders/[poId]/page.tsx b/src/app/dashboard/financial/purchase-orders/[poId]/page.tsx index 117825e..ddc9e4b 100644 --- a/src/app/dashboard/financial/purchase-orders/[poId]/page.tsx +++ b/src/app/dashboard/financial/purchase-orders/[poId]/page.tsx @@ -23,13 +23,13 @@ export default async function PurchaseOrderDetailPage({ let po; try { - po = await pb.collection("purchase_orders").getOne(poId, { expand: "site" }); + po = await pb.collection("purchase_orders").getOne(poId, { expand: "site,supplier_ref" }); } catch { notFound(); } // Pull the full graph for this PO - const [items, dns, received] = await Promise.all([ + const [items, dns, received, suppliers] = await Promise.all([ pb.collection("purchase_order_items").getFullList({ filter: `purchase_order='${poId}'`, }), @@ -40,6 +40,8 @@ export default async function PurchaseOrderDetailPage({ pb.collection("delivery_note_items").getFullList({ fields: "id,delivery_note,purchase_order_item,qty_received,condition_notes", }), + // All suppliers, for the unknown-supplier picker on this page. + pb.collection("suppliers").getFullList({ sort: "name" }), ]); // Outstanding is computed from the delivery lines, never stored — see @@ -116,6 +118,9 @@ export default async function PurchaseOrderDetailPage({ projectCode: poProjectCode, projectName: po.expand?.site?.name ?? "", supplier: po.supplier, + supplierRefId: po.supplier_ref ?? null, + supplierRefName: + (po.expand as { supplier_ref?: { name?: string } } | undefined)?.supplier_ref?.name ?? null, requiredByDate: po.required_by_date, orderedBy: po.ordered_by, totalValue: po.total_value, @@ -128,6 +133,8 @@ export default async function PurchaseOrderDetailPage({ totalReceived, }; + const supplierOptions = suppliers.map((s) => ({ id: s.id, name: s.name })); + return ( <> } /> - + ); } \ No newline at end of file diff --git a/src/app/dashboard/financial/purchase-orders/[poId]/po-detail-view.tsx b/src/app/dashboard/financial/purchase-orders/[poId]/po-detail-view.tsx index 268ae4c..ab138d8 100644 --- a/src/app/dashboard/financial/purchase-orders/[poId]/po-detail-view.tsx +++ b/src/app/dashboard/financial/purchase-orders/[poId]/po-detail-view.tsx @@ -18,6 +18,13 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; import { Dialog, DialogContent, @@ -25,7 +32,7 @@ import { DialogTitle, } from "@/components/ui/dialog"; import { SlipPreview } from "@/components/slip-preview"; -import { cn, formatCurrency, formatNumber, isUnknownSupplier } from "@/lib/utils"; +import { cn, formatCurrency, formatNumber } from "@/lib/utils"; import type { DeliveryNoteProcessingStatus } from "@/lib/pb-types"; export interface PoDetailItem { @@ -65,6 +72,10 @@ export interface PoDetail { projectCode: string; projectName: string; supplier: string; + /** Resolved supplier record id, if a match was made at upload or later. */ + supplierRefId: string | null; + /** Display name of the linked supplier (mirrors supplierRefId's record). */ + supplierRefName: string | null; requiredByDate: string; orderedBy: string; totalValue: number; @@ -134,12 +145,22 @@ function FulfilmentBar({ pct }: { pct: number }) { ); } -export function PoDetailView({ detail }: { detail: PoDetail }) { +export function PoDetailView({ + detail, + suppliers, +}: { + detail: PoDetail; + suppliers: Array<{ id: string; name: string }>; +}) { const refresh = () => window.location.reload(); const [state, setState] = React.useState(detail); const handleSupplierSaved = React.useCallback( - (next: string) => { - setState((prev) => ({ ...prev, supplier: next })); + (supplierId: string, supplierName: string) => { + setState((prev) => ({ + ...prev, + supplierRefId: supplierId, + supplierRefName: supplierName, + })); refresh(); }, [], @@ -162,14 +183,14 @@ export function PoDetailView({ detail }: { detail: PoDetail }) {

{state.poNumber}

- {isUnknownSupplier(state.supplier) ? ( + {state.supplierRefId ? ( + {state.supplierRefName} + ) : ( - ) : ( - {state.supplier} )} {state.projectCode || "—"} @@ -500,28 +521,23 @@ function DeliveryNoteCard({ function SupplierEditor({ poId, - currentSupplier, + suppliers, onSaved, }: { poId: string; - currentSupplier: string; - onSaved: (next: string) => void; + suppliers: Array<{ id: string; name: string }>; + onSaved: (supplierId: string, supplierName: string) => void; }) { const [editing, setEditing] = React.useState(false); - const [value, setValue] = React.useState(""); + const [selectedId, setSelectedId] = React.useState(""); const [busy, setBusy] = React.useState(false); const [error, setError] = React.useState(null); - // Only render for the unknown-supplier case. Parent renders the - // plain for known suppliers. - if (!isUnknownSupplier(currentSupplier)) return null; - - const trimmed = value.trim(); - const canSave = !busy && trimmed.length > 0 && trimmed.length <= 200; + const canSave = !busy && selectedId !== ""; const cancel = () => { setError(null); - setValue(""); + setSelectedId(""); setEditing(false); }; @@ -533,7 +549,7 @@ function SupplierEditor({ const res = await fetch(`/api/purchase-orders/${poId}/supplier`, { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ supplier: trimmed }), + body: JSON.stringify({ supplier_id: selectedId }), }); if (!res.ok) { const data: { error?: string } = await res @@ -542,11 +558,10 @@ function SupplierEditor({ setError(data.error ?? `Save failed (${res.status})`); return; } - const data: { supplier?: string } = await res.json(); - const next = (data.supplier ?? trimmed).trim(); - onSaved(next); + const data: { supplier_id: string; supplier_name: string } = await res.json(); + onSaved(data.supplier_id, data.supplier_name); setEditing(false); - setValue(""); + setSelectedId(""); } catch (err) { setError( err instanceof Error ? err.message : "Save failed (network error)", @@ -554,14 +569,14 @@ function SupplierEditor({ } finally { setBusy(false); } - }; + } if (!editing) { return (