diff --git a/api/order.php b/api/order.php index 1ff66bf..ae6042a 100644 --- a/api/order.php +++ b/api/order.php @@ -163,7 +163,18 @@ try { throw new Exception("No loyalty-eligible products in the order to redeem."); } + $total_loyalty_qty = 0; + foreach ($processed_items as $item) { + if ($item['is_loyalty']) { + $total_loyalty_qty += $item['quantity']; + } + } + $possible_redemptions = floor($current_points / $points_threshold); + if ($total_loyalty_qty > $possible_redemptions) { + throw new Exception("You are only eligible for $possible_redemptions free product(s). Please reduce quantity in cart."); + } + $redemptions_done = 0; while ($redemptions_done < $possible_redemptions) { @@ -389,4 +400,4 @@ You've earned *{points_earned} points* with this order. if ($pdo->inTransaction()) $pdo->rollBack(); error_log("Order Error: " . $e->getMessage()); echo json_encode(['success' => false, 'error' => $e->getMessage()]); -} +} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index c13533d..52858e6 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -259,20 +259,25 @@ document.addEventListener('DOMContentLoaded', () => { if (loyaltyPointsDisplay) loyaltyPointsDisplay.textContent = currentCustomer.points + ' pts'; if (redeemLoyaltyBtn) { - const hasLoyaltyItem = cart.some(item => item.is_loyalty); + const totalLoyaltyQuantity = cart.reduce((sum, item) => item.is_loyalty ? sum + item.quantity : sum, 0); + const hasLoyaltyItem = totalLoyaltyQuantity > 0; const hasNonLoyaltyItem = cart.some(item => !item.is_loyalty); + const eligibleCount = currentCustomer.eligible_count || 1; - redeemLoyaltyBtn.disabled = !currentCustomer.eligible_for_free_meal || !hasLoyaltyItem || hasNonLoyaltyItem; + const isOverLimit = totalLoyaltyQuantity > eligibleCount; + + redeemLoyaltyBtn.disabled = !currentCustomer.eligible_for_free_meal || !hasLoyaltyItem || hasNonLoyaltyItem || isOverLimit; if (loyaltyMessage) { if (currentCustomer.eligible_for_free_meal) { - const count = currentCustomer.eligible_count || 1; - loyaltyMessage.innerHTML = `Eligible for ${count} Free Product${count > 1 ? 's' : ''}!`; + loyaltyMessage.innerHTML = `Eligible for ${eligibleCount} Free Product${eligibleCount > 1 ? 's' : ''}!`; if (hasNonLoyaltyItem) { loyaltyMessage.innerHTML += '
(Remove non-loyalty products to redeem)
'; } else if (!hasLoyaltyItem) { loyaltyMessage.innerHTML += '
(Add a loyalty product to redeem)
'; + } else if (isOverLimit) { + loyaltyMessage.innerHTML += `
(Maximum ${eligibleCount} free products allowed)
`; } } else { loyaltyMessage.textContent = `${currentCustomer.points_needed || 0} pts away from a free product.`; @@ -838,4 +843,4 @@ document.addEventListener('DOMContentLoaded', () => { const modal = new bootstrap.Modal(document.getElementById('qrRatingModal')); modal.show(); }; -}); \ No newline at end of file +}); diff --git a/assets/js/main.js?offset=254&limit=33 b/assets/js/main.js?offset=254&limit=33 deleted file mode 100644 index fa7a7e6..0000000 --- a/assets/js/main.js?offset=254&limit=33 +++ /dev/null @@ -1,33 +0,0 @@ - - function updateLoyaltyUI() { - if (!loyaltySection || typeof LOYALTY_SETTINGS === 'undefined' || !LOYALTY_SETTINGS.is_enabled) return; - - if (currentCustomer) { - loyaltySection.classList.remove('d-none'); - if (loyaltyPointsDisplay) loyaltyPointsDisplay.textContent = currentCustomer.points + ' pts'; - - if (redeemLoyaltyBtn) { - const hasLoyaltyItem = cart.some(item => item.is_loyalty); - const hasNonLoyaltyItem = cart.some(item => !item.is_loyalty); - - redeemLoyaltyBtn.disabled = !currentCustomer.eligible_for_free_meal || !hasLoyaltyItem || hasNonLoyaltyItem; - - if (loyaltyMessage) { - if (currentCustomer.eligible_for_free_meal) { - const count = currentCustomer.eligible_count || 1; - loyaltyMessage.innerHTML = `Eligible for ${count} Free Product${count > 1 ? 's' : ''}!`; - - if (hasNonLoyaltyItem) { - loyaltyMessage.innerHTML += '
(Remove non-loyalty products to redeem)
'; - } else if (!hasLoyaltyItem) { - loyaltyMessage.innerHTML += '
(Add a loyalty product to redeem)
'; - } - } else { - loyaltyMessage.textContent = `${currentCustomer.points_needed || 0} pts away from a free product.`; - } - } - } - } else { - loyaltySection.classList.add('d-none'); - } - }