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:
parent
78ed1db15a
commit
651f1984d9
1 changed files with 33 additions and 1 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue