From 1e5510477a4a521467d9653bd6dfeceb64f1d9bf Mon Sep 17 00:00:00 2001 From: Scott Pouliot Date: Fri, 12 Jun 2026 09:41:06 -0400 Subject: [PATCH] Allow fractional quantities (< 1) in item wizard Catalog, calculated, generic, formula, and AI item types now accept decimal quantities (e.g. 0.25 for a quarter of a catalog set). Sales/ merchandise items remain whole-number only. - Input min changed from 1 to 0.01; step="0.01" added where missing - All parseInt reads on quantity inputs changed to parseFloat so values like 0.25 aren't truncated to 0 before being stored in wz.data - Server-side Quantity is already decimal on all relevant DTOs Co-Authored-By: Claude Sonnet 4.6 --- .../wwwroot/js/item-wizard.js | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/PowderCoating.Web/wwwroot/js/item-wizard.js b/src/PowderCoating.Web/wwwroot/js/item-wizard.js index d98b8ed..cc83999 100644 --- a/src/PowderCoating.Web/wwwroot/js/item-wizard.js +++ b/src/PowderCoating.Web/wwwroot/js/item-wizard.js @@ -435,7 +435,7 @@ function renderProductFields() {
- +
@@ -526,7 +526,7 @@ function renderCalculatedFields() {
- +
@@ -615,7 +615,7 @@ function renderGenericFields() {
- +
@@ -932,7 +932,7 @@ function renderFormulaFields() {
- +
${fieldsHtml}
@@ -1058,7 +1058,7 @@ function renderAiPhotoFields() {
- +
@@ -1490,7 +1490,7 @@ async function aiAnalyze() { } document.getElementById('ai_dimError')?.classList.add('d-none'); - const qty = parseInt(document.getElementById('ai_quantity')?.value) || 1; + const qty = parseFloat(document.getElementById('ai_quantity')?.value) || 1; const color = document.getElementById('ai_color')?.value?.trim() || ''; const coats = parseInt(document.getElementById('ai_coatCount')?.value) || 1; const materialType = document.getElementById('ai_materialType')?.value?.trim() || ''; @@ -1584,7 +1584,7 @@ async function aiSendFollowup() { aiSetLoading(true); document.getElementById('ai_followupSection')?.classList.add('d-none'); - const qty = parseInt(document.getElementById('ai_quantity')?.value) || 1; + const qty = parseFloat(document.getElementById('ai_quantity')?.value) || 1; const color = document.getElementById('ai_color')?.value?.trim() || ''; const coats = parseInt(document.getElementById('ai_coatCount')?.value) || 1; const ref = document.getElementById('ai_referenceDim')?.value?.trim() || ''; @@ -2429,7 +2429,7 @@ function onPowderSelected(i) { function updatePowderNeeded(i) { const sqft = parseFloat(wz.data.surfaceAreaSqFt) || 0; - const qty = parseInt(wz.data.quantity) || 1; + const qty = parseFloat(wz.data.quantity) || 1; if (sqft <= 0) return; // only meaningful for calculated items with surface area const isCustom = document.getElementById(`coat_custom_${i}`)?.checked; @@ -2628,7 +2628,7 @@ function collectStep2() { wz.data.surfaceAreaSqFt = cat ? (parseFloat(cat.approxArea) || 0) : 0; wz.data.estimatedMinutes = cat ? (parseInt(cat.defaultMinutes) || 0) : 0; } - wz.data.quantity = parseInt(document.getElementById('wz_quantity')?.value) || 1; + wz.data.quantity = parseFloat(document.getElementById('wz_quantity')?.value) || 1; const override = parseFloat(document.getElementById('wz_powderCostOverride')?.value); wz.data.powderCostOverride = isNaN(override) ? null : override; } @@ -2654,7 +2654,7 @@ function collectStep2() { wz.data.surfaceAreaSqFt = sqft; } - wz.data.quantity = parseInt(document.getElementById('wz_quantity')?.value) || 1; + wz.data.quantity = parseFloat(document.getElementById('wz_quantity')?.value) || 1; wz.data.estimatedMinutes = parseInt(document.getElementById('wz_estimatedMinutes')?.value) || 30; } @@ -2677,7 +2677,7 @@ function collectStep2() { wz.data.manualUnitPrice = price; } - wz.data.quantity = parseInt(document.getElementById('wz_quantity')?.value) || 1; + wz.data.quantity = parseFloat(document.getElementById('wz_quantity')?.value) || 1; wz.data.notes = document.getElementById('wz_notes')?.value?.trim() || null; wz.data.surfaceAreaSqFt = 0; wz.data.estimatedMinutes = 0; @@ -2723,7 +2723,7 @@ function collectStep2() { wz.data.manualUnitPrice = price; } - wz.data.quantity = parseInt(document.getElementById('wz_quantity')?.value) || 1; + wz.data.quantity = parseFloat(document.getElementById('wz_quantity')?.value) || 1; wz.data.notes = document.getElementById('wz_notes')?.value?.trim() || null; wz.data.surfaceAreaSqFt = 0; wz.data.estimatedMinutes = 0; @@ -2750,7 +2750,7 @@ function collectStep2() { if (valid) { const templates = pageMeta.customFormulaTemplates || []; const tmpl = templates.find(t => t.id === templateId); - const qty = parseInt(document.getElementById('wz_formula_qty')?.value) || 1; + const qty = parseFloat(document.getElementById('wz_formula_qty')?.value) || 1; const descEl = document.getElementById('wz_formula_description'); wz.data.quantity = qty; @@ -2788,7 +2788,7 @@ function collectStep2() { wz.data.surfaceAreaSqFt = sqft; wz.data.complexity = complexity; wz.data.estimatedMinutes = minutes; - wz.data.quantity = parseInt(document.getElementById('ai_quantity')?.value) || 1; + wz.data.quantity = parseFloat(document.getElementById('ai_quantity')?.value) || 1; wz.data.aiReferenceDim = document.getElementById('ai_referenceDim')?.value?.trim() || ''; wz.data.aiColor = document.getElementById('ai_color')?.value?.trim() || ''; wz.data.aiCoatCount = parseInt(document.getElementById('ai_coatCount')?.value) || 1; @@ -2867,7 +2867,7 @@ function collectStep3() { coat.powderToOrder = orderQtyVal ? parseFloat(orderQtyVal) : null; } else { const sqft = parseFloat(wz.data.surfaceAreaSqFt) || 0; - const qty = parseInt(wz.data.quantity) || 1; + const qty = parseFloat(wz.data.quantity) || 1; if (sqft > 0 && coat.coverageSqFtPerLb > 0) { const eff = (coat.transferEfficiency || 65) / 100; coat.powderToOrder = (sqft * qty) / (coat.coverageSqFtPerLb * eff);