From 651f1984d9d8bac175dee7769344f2cfb80c248d Mon Sep 17 00:00:00 2001 From: justin Date: Fri, 29 May 2026 14:54:50 -0500 Subject: [PATCH] Fix discount display on DOT order page Order page now fetches discount code from API and shows: - Discount line item with percentage and savings amount - Non-discountable items excluded (D&A) - Auto-fetches on page load if ?code= param present - Re-fetches on promo field blur - Green "You save $X!" text Co-Authored-By: Claude Opus 4.6 (1M context) --- site/public/order/dot-compliance/index.html | 34 ++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/site/public/order/dot-compliance/index.html b/site/public/order/dot-compliance/index.html index 07edec9..54d4b98 100644 --- a/site/public/order/dot-compliance/index.html +++ b/site/public/order/dot-compliance/index.html @@ -442,25 +442,57 @@ var checkboxes = document.querySelectorAll("input[data-slug]"); var totalSection = document.getElementById("pw-total-section"); var totalRows = document.getElementById("pw-total-rows"); +// Non-discountable slugs (passthrough costs) +var nonDiscountable = {"dot-drug-alcohol": true}; + +// Cached discount info +var activeDiscount = null; +function fetchDiscount() { + var code = (document.getElementById("pw-promo").value || "").trim().toUpperCase(); + if (!code) { activeDiscount = null; updateTotal(); return; } + fetch(API + "/api/v1/discount/" + encodeURIComponent(code)).then(function(r) { return r.json(); }).then(function(d) { + if (d.valid) { activeDiscount = d; } else { activeDiscount = null; } + updateTotal(); + }).catch(function() { activeDiscount = null; updateTotal(); }); +} +// Fetch on load if promo pre-filled +if (promoFromUrl) { setTimeout(fetchDiscount, 500); } +// Fetch on blur of promo field +document.getElementById("pw-promo").addEventListener("blur", fetchDiscount); + function updateTotal() { var selected = []; var svcTotal = 0; var govTotal = 0; + var discountable = 0; checkboxes.forEach(function(cb) { if (cb.checked) { var price = parseInt(cb.dataset.price) || 0; var gov = parseInt(cb.dataset.govfee) || 0; svcTotal += price; govTotal += gov; + if (!nonDiscountable[cb.dataset.slug]) { discountable += price; } selected.push(cb.dataset.slug); } }); if (selected.length === 0) { totalSection.hidden = true; return; } totalSection.hidden = false; + var discountAmt = 0; + if (activeDiscount && activeDiscount.discount_type === "percent") { + discountAmt = Math.round(discountable * activeDiscount.discount_value / 100); + } else if (activeDiscount && activeDiscount.discount_type === "flat") { + discountAmt = Math.min(activeDiscount.discount_value * 100, discountable); + } + var html = '
' + selected.length + ' service' + (selected.length > 1 ? 's' : '') + '' + usd(svcTotal) + '
'; if (govTotal > 0) html += '
Government fees (passthrough)' + usd(govTotal) + '
'; - html += '
Total' + usd(svcTotal + govTotal) + '
'; + if (discountAmt > 0) { + html += '
' + activeDiscount.code + ' (' + activeDiscount.discount_value + '% off)-' + usd(discountAmt) + '
'; + } + var finalTotal = svcTotal + govTotal - discountAmt; + html += '
Total' + usd(finalTotal) + '
'; + if (discountAmt > 0) { html += '
You save ' + usd(discountAmt) + '!
'; } totalRows.innerHTML = html; }