diff --git a/src/components/purchase-orders/EditPurchaseOrderDialog.tsx b/src/components/purchase-orders/EditPurchaseOrderDialog.tsx index 2eb8276..f3098a4 100644 --- a/src/components/purchase-orders/EditPurchaseOrderDialog.tsx +++ b/src/components/purchase-orders/EditPurchaseOrderDialog.tsx @@ -134,13 +134,18 @@ export function EditPurchaseOrderDialog({ open, onOpenChange, order, refreshData })) // Build updated snapshot — keep stable ids + entry mode so the audit - // trail remains meaningful. + // trail remains meaningful. costPrice is the ZAR landed cost, so carry + // the existing value over per row instead of zeroing it; costPriceGBP is + // the price the user sees in the form and is what the PO PDF renders. + const existingSnapshot = order.snapshotItems || [] const updatedSnapshot = normalizedRows.map((r) => ({ stockItemId: r.stockItemId, itemName: r.itemName, sku: r.sku, quantity: r.quantity, - costPrice: 0, + costPrice: Number( + existingSnapshot.find((s) => s.stockItemId === r.stockItemId)?.costPrice || 0, + ), costPriceGBP: r.unitPriceGBP, entryMode: r.entryMode, })) diff --git a/src/components/purchase-orders/PurchaseOrderForm.tsx b/src/components/purchase-orders/PurchaseOrderForm.tsx index acd23cc..fb7a57a 100644 --- a/src/components/purchase-orders/PurchaseOrderForm.tsx +++ b/src/components/purchase-orders/PurchaseOrderForm.tsx @@ -11,6 +11,7 @@ import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group" import { Form, FormControl, + FormDescription, FormField, FormItem, FormLabel, @@ -260,8 +261,12 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro form.setValue(`items.${index}.stockItemId`, selectedStockItem.id, { shouldDirty: true }); form.setValue(`items.${index}.itemName`, selectedStockItem.name, { shouldDirty: true }); form.setValue(`items.${index}.sku`, selectedStockItem.sku, { shouldDirty: true }); - // Use GBP price for purchase orders - form.setValue(`items.${index}.costPrice`, selectedStockItem.costPriceGBP, { shouldDirty: true, shouldValidate: true }); + // Use GBP price for purchase orders. Most stock items only carry a ZAR + // cost price (cost_price), so leave the field BLANK instead of silently + // showing £0.00 — a blank field tells the user the supplier's GBP price + // still has to be entered, whereas "£0.00" looks like a real price. + const gbpPrice = Number(selectedStockItem.costPriceGBP || 0); + form.setValue(`items.${index}.costPrice`, gbpPrice > 0 ? gbpPrice : ("" as any), { shouldDirty: true, shouldValidate: true }); // Leave quantity blank — user types the amount they want. form.setValue(`items.${index}.quantity`, "", { shouldDirty: true, shouldValidate: true }); } @@ -357,8 +362,14 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro itemName: item.itemName, sku: item.sku, quantity: item.quantity, - costPrice: Number(item.costPrice || 0), - costPriceGBP: Number(stockItem?.costPriceGBP || 0), + // ZAR landed cost, for reference only — the PO itself is priced in GBP. + costPrice: Number(stockItem?.costPrice ?? 0), + // The GBP unit price taken from the FORM. This is the only price + // field the PO PDF renders (£${item.costPriceGBP}), so it must be the + // value the user sees and edits. Reading it from the stock item + // instead silently discarded every price typed into the form and + // printed £0.00 on the PO. + costPriceGBP: Number(item.costPrice || 0), entryMode: 'stock', }); } @@ -755,6 +766,11 @@ export function PurchaseOrderForm({ setOpen, refreshData }: PurchaseOrderFormPro onChange={(v) => field.onChange(v)} /> + {!(Number(field.value || 0) > 0) && ( + + No GBP cost price on this stock item — enter the supplier's GBP price. + + )} )}