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) <noreply@anthropic.com>
This commit is contained in:
justin 2026-05-29 14:54:50 -05:00
parent 78ed1db15a
commit 651f1984d9

View file

@ -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 = '<div class="flex justify-between text-sm mb-1"><span>' + selected.length + ' service' + (selected.length > 1 ? 's' : '') + '</span><span>' + usd(svcTotal) + '</span></div>';
if (govTotal > 0) html += '<div class="flex justify-between text-sm text-gray-500 mb-1"><span>Government fees (passthrough)</span><span>' + usd(govTotal) + '</span></div>';
html += '<div class="flex justify-between font-bold text-lg border-t border-gray-300 pt-2 mt-2"><span>Total</span><span>' + usd(svcTotal + govTotal) + '</span></div>';
if (discountAmt > 0) {
html += '<div class="flex justify-between text-sm text-green-600 font-semibold mb-1"><span>' + activeDiscount.code + ' (' + activeDiscount.discount_value + '% off)</span><span>-' + usd(discountAmt) + '</span></div>';
}
var finalTotal = svcTotal + govTotal - discountAmt;
html += '<div class="flex justify-between font-bold text-lg border-t border-gray-300 pt-2 mt-2"><span>Total</span><span>' + usd(finalTotal) + '</span></div>';
if (discountAmt > 0) { html += '<div class="text-xs text-green-600 text-right mt-1">You save ' + usd(discountAmt) + '!</div>'; }
totalRows.innerHTML = html;
}