From b088953133366e36fe232cc9f52bbbe0b96d87ff Mon Sep 17 00:00:00 2001 From: josh Date: Fri, 8 May 2026 09:33:40 -0400 Subject: [PATCH] Auto-derive total cannabinoids from THC + CBD when adding inventory Total cannabinoids % now defaults to THC + CBD and stays in sync as either field changes. Once the user manually edits the total field it stops auto-updating, since some labels list an explicit total that differs from the sum. When autofilling from a previous instance the field is treated as manual (preserving the stored value). Co-Authored-By: Claude Opus 4.6 --- web/src/components/modals/AddInventoryFlow.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/web/src/components/modals/AddInventoryFlow.tsx b/web/src/components/modals/AddInventoryFlow.tsx index 72beadf..473a797 100644 --- a/web/src/components/modals/AddInventoryFlow.tsx +++ b/web/src/components/modals/AddInventoryFlow.tsx @@ -375,7 +375,7 @@ function InstanceDetailsStep({ price: initialPrice, thc: last?.thc ?? (cfg?.showCannabinoidPct !== false ? 22 : 0), cbd: last?.cbd ?? (cfg?.showCannabinoidPct !== false ? 0.4 : 0), - totalCannabinoids: last?.totalCannabinoids ?? (cfg?.showCannabinoidPct !== false ? 26 : 0), + totalCannabinoids: last?.totalCannabinoids ?? (cfg?.showCannabinoidPct !== false ? 22.4 : 0), purchaseDate: getToday(getStoredTimezone()), }); const [newShopName, setNewShopName] = useState(""); @@ -383,10 +383,17 @@ function InstanceDetailsStep({ const [newBinName, setNewBinName] = useState(""); const [newBinCapacity, setNewBinCapacity] = useState(10); const [containerWeight, setContainerWeight] = useState(""); + const [totalCannaManual, setTotalCannaManual] = useState(!!last); const [error, setError] = useState(null); const update = (k: K, v: (typeof form)[K]) => - setForm((f) => ({ ...f, [k]: v })); + setForm((f) => { + const next = { ...f, [k]: v }; + if ((k === "thc" || k === "cbd") && !totalCannaManual) { + next.totalCannabinoids = +(next.thc + next.cbd).toFixed(1); + } + return next; + }); const cpg = !isDiscrete && form.weight > 0 ? form.price / form.weight : 0; const assetIdValid = ASSET_ID_RE.test(assetId); @@ -677,7 +684,10 @@ function InstanceDetailsStep({ type="number" step="0.1" value={form.totalCannabinoids} - onChange={(e) => update("totalCannabinoids", +e.target.value)} + onChange={(e) => { + setTotalCannaManual(true); + update("totalCannabinoids", +e.target.value); + }} />