From dbadfdf4893b774d2565c89f50dfb273d01bb341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hartmut=20N=C3=B6renberg?= Date: Sat, 14 Mar 2026 14:52:21 +0100 Subject: [PATCH] feat: per-line material override in product order wizard Step 3 - Added "Mat Override" column to the review table - Each line has its own dropdown (per-line takes priority over global) - Default shows global override if set, otherwise "No override" - "Clear" option to explicitly remove override on a line when global is set - Amber background when override is active Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/pages/NewProductOrder.tsx | 34 ++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/NewProductOrder.tsx b/frontend/src/pages/NewProductOrder.tsx index 14476b6..23f0c2a 100644 --- a/frontend/src/pages/NewProductOrder.tsx +++ b/frontend/src/pages/NewProductOrder.tsx @@ -50,6 +50,7 @@ export default function NewProductOrderPage() { const [globalPositionSelections, setGlobalPositionSelections] = useState({}) const [notes, setNotes] = useState('') const [materialOverride, setMaterialOverride] = useState('') + const [lineOverrides, setLineOverrides] = useState>({}) const [submitting, setSubmitting] = useState(false) // ---- Step 1: load products with STEP files ---- @@ -383,13 +384,17 @@ export default function NewProductOrderPage() { try { const result = await createOrder({ notes: notes || undefined, - lines: orderLines.map((l) => ({ - product_id: l.product.id, - output_type_id: l.outputType.id, - render_position_id: l.position?.id ?? null, - global_render_position_id: l.globalPosition?.id ?? null, - material_override: materialOverride || null, - })), + lines: orderLines.map((l) => { + const lineOv = lineOverrides[l.key] + const override = lineOv === '__none__' ? null : (lineOv || materialOverride || null) + return { + product_id: l.product.id, + output_type_id: l.outputType.id, + render_position_id: l.position?.id ?? null, + global_render_position_id: l.globalPosition?.id ?? null, + material_override: override, + } + }), }) toast.success(`Draft order ${result.order_number} created — review and submit`) navigate(`/orders/${result.id}`) @@ -773,6 +778,7 @@ export default function NewProductOrderPage() { Position Renderer Format + Mat Override Price @@ -809,6 +815,20 @@ export default function NewProductOrderPage() { {line.outputType.renderer} {line.outputType.output_format} + + + {(() => { const price = getLinePrice(line.product.id, line.outputType.id)