0 total for loyalty
This commit is contained in:
parent
9b31c32aba
commit
a7bd1b142a
@ -46,7 +46,8 @@ foreach ($items as $item) {
|
|||||||
$subtotal += $item['unit_price'] * $item['quantity'];
|
$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();
|
$company_settings = get_company_settings();
|
||||||
$vat_rate = (float)($company_settings['vat_rate'] ?? 0);
|
$vat_rate = (float)($company_settings['vat_rate'] ?? 0);
|
||||||
?>
|
?>
|
||||||
@ -191,16 +192,24 @@ $vat_rate = (float)($company_settings['vat_rate'] ?? 0);
|
|||||||
</tbody>
|
</tbody>
|
||||||
<tfoot class="bg-light">
|
<tfoot class="bg-light">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3" class="text-end py-3 ps-4">
|
<td colspan="3" class="text-end py-3 ps-4 border-0">
|
||||||
<div class="text-muted mb-1">Subtotal</div>
|
<div class="text-muted mb-1 small">Subtotal</div>
|
||||||
<div class="text-muted mb-1"><?= ($vat_or_discount >= 0) ? "VAT ($vat_rate%)" : 'Discount' ?></div>
|
<?php if ($vat_amount > 0): ?>
|
||||||
|
<div class="text-muted mb-1 small">VAT</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ($discount_amount > 0): ?>
|
||||||
|
<div class="text-muted mb-1 small">Discount</div>
|
||||||
|
<?php endif; ?>
|
||||||
<h5 class="fw-bold mb-0 text-dark">Total Amount</h5>
|
<h5 class="fw-bold mb-0 text-dark">Total Amount</h5>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end py-3 pe-4">
|
<td class="text-end py-3 pe-4 border-0">
|
||||||
<div class="mb-1"><?= format_currency($subtotal) ?></div>
|
<div class="mb-1 small"><?= format_currency($subtotal) ?></div>
|
||||||
<div class="mb-1 <?= $vat_or_discount < 0 ? 'text-danger' : 'text-primary' ?>">
|
<?php if ($vat_amount > 0): ?>
|
||||||
<?= ($vat_or_discount > 0 ? '+' : '') . format_currency($vat_or_discount) ?>
|
<div class="mb-1 small text-primary">+<?= format_currency($vat_amount) ?></div>
|
||||||
</div>
|
<?php endif; ?>
|
||||||
|
<?php if ($discount_amount > 0): ?>
|
||||||
|
<div class="mb-1 small text-danger">-<?= format_currency($discount_amount) ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
<h5 class="fw-bold mb-0 text-primary"><?= format_currency($order['total_amount']) ?></h5>
|
<h5 class="fw-bold mb-0 text-primary"><?= format_currency($order['total_amount']) ?></h5>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -343,12 +352,13 @@ function printThermalReceipt() {
|
|||||||
];
|
];
|
||||||
}, $items)) ?>,
|
}, $items)) ?>,
|
||||||
total: <?= (float)$order['total_amount'] ?>,
|
total: <?= (float)$order['total_amount'] ?>,
|
||||||
vat: <?= (float)$order['discount'] ?>,
|
vat: <?= (float)$order['vat'] ?>,
|
||||||
|
discount: <?= (float)$order['discount'] ?>,
|
||||||
orderType: '<?= $order['order_type'] ?>',
|
orderType: '<?= $order['order_type'] ?>',
|
||||||
tableNumber: '<?= $order['table_number'] ?>',
|
tableNumber: '<?= $order['table_number'] ?>',
|
||||||
date: '<?= date('M d, Y H:i', strtotime($order['created_at'])) ?>',
|
date: '<?= date('M d, Y H:i', strtotime($order['created_at'])) ?>',
|
||||||
paymentMethod: '<?= $order['payment_type_name'] ?? 'Unpaid' ?>',
|
paymentMethod: '<?= $order['payment_type_name'] ?? 'Unpaid' ?>',
|
||||||
loyaltyRedeemed: <?= ($order['discount'] < 0) ? 'true' : 'false' ?>
|
loyaltyRedeemed: <?= ($order['payment_type_name'] === 'Loyalty Redeem' || (float)$order['total_amount'] <= 0) ? 'true' : 'false' ?>
|
||||||
};
|
};
|
||||||
|
|
||||||
const width = 400;
|
const width = 400;
|
||||||
@ -424,7 +434,6 @@ function printThermalReceipt() {
|
|||||||
|
|
||||||
const loyaltyHtml = data.loyaltyRedeemed ? `<div style="color: #d63384; font-weight: bold; margin: 5px 0; text-align: center;">* Loyalty Reward Applied *</div>` : '';
|
const loyaltyHtml = data.loyaltyRedeemed ? `<div style="color: #d63384; font-weight: bold; margin: 5px 0; text-align: center;">* Loyalty Reward Applied *</div>` : '';
|
||||||
|
|
||||||
const subtotal = data.total - data.vat;
|
|
||||||
const logoHtml = COMPANY_SETTINGS.logo_url ? `<img src="${BASE_URL}${COMPANY_SETTINGS.logo_url}" style="max-height: 80px; max-width: 150px; margin-bottom: 10px;">` : '';
|
const logoHtml = COMPANY_SETTINGS.logo_url ? `<img src="${BASE_URL}${COMPANY_SETTINGS.logo_url}" style="max-height: 80px; max-width: 150px; margin-bottom: 10px;">` : '';
|
||||||
const vatRate = COMPANY_SETTINGS.vat_rate || 0;
|
const vatRate = COMPANY_SETTINGS.vat_rate || 0;
|
||||||
|
|
||||||
@ -519,12 +528,18 @@ function printThermalReceipt() {
|
|||||||
<table style="width: 100%">
|
<table style="width: 100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Subtotal / ${tr['Subtotal']}</td>
|
<td>Subtotal / ${tr['Subtotal']}</td>
|
||||||
<td style="text-align: right">${formatCurrency(subtotal)}</td>
|
<td style="text-align: right">${formatCurrency(data.items.reduce((acc, i) => acc + (i.price * i.quantity), 0))}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
${data.vat > 0 ? `
|
||||||
<tr>
|
<tr>
|
||||||
<td>${data.vat < 0 ? 'Discount' : 'VAT (' + vatRate + '%)'} / ${tr['VAT']}</td>
|
<td>VAT (${vatRate}%) / ${tr['VAT']}</td>
|
||||||
<td style="text-align: right">${data.vat < 0 ? '-' : '+'}${formatCurrency(Math.abs(data.vat))}</td>
|
<td style="text-align: right">+${formatCurrency(data.vat)}</td>
|
||||||
</tr>
|
</tr>` : ''}
|
||||||
|
${data.discount > 0 ? `
|
||||||
|
<tr>
|
||||||
|
<td>Discount / الخصم</td>
|
||||||
|
<td style="text-align: right">-${formatCurrency(data.discount)}</td>
|
||||||
|
</tr>` : ''}
|
||||||
<tr style="font-weight: bold; font-size: 18px;">
|
<tr style="font-weight: bold; font-size: 18px;">
|
||||||
<td style="padding-top: 10px;">TOTAL / ${tr['TOTAL']}</td>
|
<td style="padding-top: 10px;">TOTAL / ${tr['TOTAL']}</td>
|
||||||
<td style="text-align: right; padding-top: 10px;">${formatCurrency(data.total)}</td>
|
<td style="text-align: right; padding-top: 10px;">${formatCurrency(data.total)}</td>
|
||||||
|
|||||||
@ -169,9 +169,11 @@ try {
|
|||||||
|
|
||||||
$total_loyalty_qty = 0;
|
$total_loyalty_qty = 0;
|
||||||
foreach ($processed_items as $item) {
|
foreach ($processed_items as $item) {
|
||||||
if ($item['is_loyalty']) {
|
// Safety check: Redemption orders should only contain loyalty items as per JS logic
|
||||||
$total_loyalty_qty += $item['quantity'];
|
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);
|
$possible_redemptions = floor($current_points / $points_threshold);
|
||||||
@ -266,6 +268,12 @@ try {
|
|||||||
|
|
||||||
$final_total = max(0, $calculated_subtotal + $calculated_vat);
|
$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/Payment info
|
||||||
$user = get_logged_user();
|
$user = get_logged_user();
|
||||||
$user_id = $user ? $user['id'] : null;
|
$user_id = $user ? $user['id'] : null;
|
||||||
|
|||||||
@ -697,8 +697,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
customer_id: selectedCustomerId ? selectedCustomerId.value : null,
|
customer_id: selectedCustomerId ? selectedCustomerId.value : null,
|
||||||
outlet_id: CURRENT_OUTLET ? CURRENT_OUTLET.id : 1,
|
outlet_id: CURRENT_OUTLET ? CURRENT_OUTLET.id : 1,
|
||||||
payment_type_id: paymentTypeId,
|
payment_type_id: paymentTypeId,
|
||||||
total_amount: subtotal + totalVat,
|
total_amount: isLoyaltyRedemption ? 0 : (subtotal + totalVat), // If loyalty redeemed, total is 0 for this transaction
|
||||||
vat: totalVat,
|
vat: isLoyaltyRedemption ? 0 : totalVat,
|
||||||
items: itemsData,
|
items: itemsData,
|
||||||
redeem_loyalty: isLoyaltyRedemption
|
redeem_loyalty: isLoyaltyRedemption
|
||||||
};
|
};
|
||||||
@ -711,17 +711,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
name: item.name,
|
name: item.name,
|
||||||
variant_name: item.variant_name,
|
variant_name: item.variant_name,
|
||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
price: item.price,
|
price: isLoyaltyRedemption ? 0 : item.price, // If loyalty redeemed, price is 0 for this transaction
|
||||||
vat_percent: item.vat_percent,
|
vat_percent: isLoyaltyRedemption ? 0 : item.vat_percent,
|
||||||
vat_amount: (item.price * item.quantity) * (item.vat_percent / 100)
|
vat_amount: isLoyaltyRedemption ? 0 : ((item.price * item.quantity) * (item.vat_percent / 100))
|
||||||
})),
|
})),
|
||||||
subtotal: subtotal,
|
subtotal: isLoyaltyRedemption ? 0 : subtotal,
|
||||||
total: subtotal + totalVat,
|
total: isLoyaltyRedemption ? 0 : (subtotal + totalVat),
|
||||||
vat: totalVat,
|
vat: isLoyaltyRedemption ? 0 : totalVat,
|
||||||
orderType: orderType,
|
orderType: orderType,
|
||||||
tableNumber: (orderType === 'dine-in') ? currentTableName : null,
|
tableNumber: (orderType === 'dine-in') ? currentTableName : null,
|
||||||
date: new Date().toLocaleString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }),
|
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
|
loyaltyRedeemed: isLoyaltyRedemption
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user