diff --git a/admin/order_view.php b/admin/order_view.php index eee8ffd..d2cf82d 100644 --- a/admin/order_view.php +++ b/admin/order_view.php @@ -46,7 +46,8 @@ foreach ($items as $item) { $subtotal += $item['unit_price'] * $item['quantity']; } -$vat_or_discount = (float)$order['discount']; +$vat_amount = (float)($order['vat'] ?? 0); +$discount_amount = (float)($order['discount'] ?? 0); $company_settings = get_company_settings(); $vat_rate = (float)($company_settings['vat_rate'] ?? 0); ?> @@ -191,16 +192,24 @@ $vat_rate = (float)($company_settings['vat_rate'] ?? 0);
| Subtotal / ${tr['Subtotal']} | -${formatCurrency(subtotal)} | +${formatCurrency(data.items.reduce((acc, i) => acc + (i.price * i.quantity), 0))} |
| ${data.vat < 0 ? 'Discount' : 'VAT (' + vatRate + '%)'} / ${tr['VAT']} | -${data.vat < 0 ? '-' : '+'}${formatCurrency(Math.abs(data.vat))} | -VAT (${vatRate}%) / ${tr['VAT']} | ++${formatCurrency(data.vat)} | + ` : ''} + ${data.discount > 0 ? ` +
| Discount / الخصم | +-${formatCurrency(data.discount)} | +|
| TOTAL / ${tr['TOTAL']} | ${formatCurrency(data.total)} | @@ -555,4 +570,4 @@ function printThermalReceipt() { win.document.write(html); win.document.close(); } - + \ No newline at end of file diff --git a/api/order.php b/api/order.php index e2db1cb..5f2bea6 100644 --- a/api/order.php +++ b/api/order.php @@ -169,9 +169,11 @@ try { $total_loyalty_qty = 0; foreach ($processed_items as $item) { - if ($item['is_loyalty']) { - $total_loyalty_qty += $item['quantity']; + // Safety check: Redemption orders should only contain loyalty items as per JS logic + if (!$item['is_loyalty']) { + throw new Exception("Loyalty redemption orders can only contain loyalty-eligible products. Please remove non-eligible items."); } + $total_loyalty_qty += $item['quantity']; } $possible_redemptions = floor($current_points / $points_threshold); @@ -265,6 +267,12 @@ try { } $final_total = max(0, $calculated_subtotal + $calculated_vat); + + // Explicitly ensure loyalty redemption orders have 0 total + if ($redeem_loyalty) { + $final_total = 0; + $calculated_vat = 0; + } // User/Payment info $user = get_logged_user(); @@ -420,4 +428,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 834e84d..f0fd0a6 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -697,8 +697,8 @@ document.addEventListener('DOMContentLoaded', () => { customer_id: selectedCustomerId ? selectedCustomerId.value : null, outlet_id: CURRENT_OUTLET ? CURRENT_OUTLET.id : 1, payment_type_id: paymentTypeId, - total_amount: subtotal + totalVat, - vat: totalVat, + total_amount: isLoyaltyRedemption ? 0 : (subtotal + totalVat), // If loyalty redeemed, total is 0 for this transaction + vat: isLoyaltyRedemption ? 0 : totalVat, items: itemsData, redeem_loyalty: isLoyaltyRedemption }; @@ -711,17 +711,17 @@ document.addEventListener('DOMContentLoaded', () => { name: item.name, variant_name: item.variant_name, quantity: item.quantity, - price: item.price, - vat_percent: item.vat_percent, - vat_amount: (item.price * item.quantity) * (item.vat_percent / 100) + price: isLoyaltyRedemption ? 0 : item.price, // If loyalty redeemed, price is 0 for this transaction + vat_percent: isLoyaltyRedemption ? 0 : item.vat_percent, + vat_amount: isLoyaltyRedemption ? 0 : ((item.price * item.quantity) * (item.vat_percent / 100)) })), - subtotal: subtotal, - total: subtotal + totalVat, - vat: totalVat, + subtotal: isLoyaltyRedemption ? 0 : subtotal, + total: isLoyaltyRedemption ? 0 : (subtotal + totalVat), + vat: isLoyaltyRedemption ? 0 : totalVat, orderType: orderType, tableNumber: (orderType === 'dine-in') ? currentTableName : null, date: new Date().toLocaleString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }), - paymentMethod: paymentTypeName || 'Unpaid', + paymentMethod: paymentTypeName || (isLoyaltyRedemption ? 'Loyalty Redeem' : 'Unpaid'), loyaltyRedeemed: isLoyaltyRedemption }; @@ -890,4 +890,4 @@ document.addEventListener('DOMContentLoaded', () => { const modal = new bootstrap.Modal(document.getElementById('qrRatingModal')); modal.show(); }; -}); +}); \ No newline at end of file