adding fat
This commit is contained in:
parent
7e5ce73bed
commit
13a3054fd1
@ -86,13 +86,14 @@ if (!empty($_GET['search'])) {
|
|||||||
|
|
||||||
$where_clause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';
|
$where_clause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';
|
||||||
|
|
||||||
// Calculate Total Sum and Total Commission for filtered orders
|
// Calculate Total Sum and Total Commission and Total VAT for filtered orders
|
||||||
$sum_query = "SELECT SUM(total_amount) as total_sum, SUM(commission_amount) as total_commission FROM orders o $where_clause";
|
$sum_query = "SELECT SUM(total_amount) as total_sum, SUM(commission_amount) as total_commission, SUM(vat) as total_vat FROM orders o $where_clause";
|
||||||
$stmt_sum = $pdo->prepare($sum_query);
|
$stmt_sum = $pdo->prepare($sum_query);
|
||||||
$stmt_sum->execute($params);
|
$stmt_sum->execute($params);
|
||||||
$sum_data = $stmt_sum->fetch(PDO::FETCH_ASSOC);
|
$sum_data = $stmt_sum->fetch(PDO::FETCH_ASSOC);
|
||||||
$total_sum = (float)($sum_data['total_sum'] ?? 0);
|
$total_sum = (float)($sum_data['total_sum'] ?? 0);
|
||||||
$total_commission = (float)($sum_data['total_commission'] ?? 0);
|
$total_commission = (float)($sum_data['total_commission'] ?? 0);
|
||||||
|
$total_vat_sum = (float)($sum_data['total_vat'] ?? 0);
|
||||||
|
|
||||||
// Main Query
|
// Main Query
|
||||||
$query = "SELECT o.*, ot.name as outlet_name, pt.name as payment_type_name, u.username as cashier_name,
|
$query = "SELECT o.*, ot.name as outlet_name, pt.name as payment_type_name, u.username as cashier_name,
|
||||||
@ -107,9 +108,6 @@ $query = "SELECT o.*, ot.name as outlet_name, pt.name as payment_type_name, u.us
|
|||||||
$orders_pagination = paginate_query($pdo, $query, $params);
|
$orders_pagination = paginate_query($pdo, $query, $params);
|
||||||
$orders = $orders_pagination['data'];
|
$orders = $orders_pagination['data'];
|
||||||
|
|
||||||
// Add total sum to pagination object for rendering
|
|
||||||
$orders_pagination['total_amount_sum'] = $total_sum;
|
|
||||||
|
|
||||||
$settings = get_company_settings();
|
$settings = get_company_settings();
|
||||||
$commission_enabled = !empty($settings['commission_enabled']);
|
$commission_enabled = !empty($settings['commission_enabled']);
|
||||||
|
|
||||||
@ -170,7 +168,6 @@ include 'includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($commission_enabled): ?>
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card border-0 shadow-sm">
|
<div class="card border-0 shadow-sm">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -179,15 +176,14 @@ include 'includes/header.php';
|
|||||||
<i class="bi bi-percent fs-4"></i>
|
<i class="bi bi-percent fs-4"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow-1 ms-3">
|
<div class="flex-grow-1 ms-3">
|
||||||
<h6 class="text-muted mb-0 small text-uppercase fw-bold">Total Commission</h6>
|
<h6 class="text-muted mb-0 small text-uppercase fw-bold">Total VAT</h6>
|
||||||
<div class="fs-4 fw-bold text-warning"><?= format_currency($total_commission) ?></div>
|
<div class="fs-4 fw-bold text-warning"><?= format_currency($total_vat_sum) ?></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<div class="col-md-3">
|
||||||
<div class="col-md-<?= $commission_enabled ? '3' : '4' ?>">
|
|
||||||
<div class="card border-0 shadow-sm">
|
<div class="card border-0 shadow-sm">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
@ -202,7 +198,7 @@ include 'includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-<?= $commission_enabled ? '3' : '4' ?>">
|
<div class="col-md-3">
|
||||||
<div class="card border-0 shadow-sm">
|
<div class="card border-0 shadow-sm">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
@ -279,7 +275,7 @@ include 'includes/header.php';
|
|||||||
<th>Cashier</th>
|
<th>Cashier</th>
|
||||||
<th>Customer</th>
|
<th>Customer</th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<th>Source</th>
|
<th>VAT</th>
|
||||||
<th>Total</th>
|
<th>Total</th>
|
||||||
<?php if ($commission_enabled): ?>
|
<?php if ($commission_enabled): ?>
|
||||||
<th>Commission</th>
|
<th>Commission</th>
|
||||||
@ -326,11 +322,7 @@ include 'includes/header.php';
|
|||||||
<span class="badge <?= $badge ?> text-dark bg-opacity-25 border border-<?= str_replace('bg-', '', $badge) ?>"><?= ucfirst($order['order_type']) ?></span>
|
<span class="badge <?= $badge ?> text-dark bg-opacity-25 border border-<?= str_replace('bg-', '', $badge) ?>"><?= ucfirst($order['order_type']) ?></span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<?php if ($order['order_type'] === 'dine-in' && $order['table_number']): ?>
|
<span class="text-muted small"><?= format_currency($order['vat']) ?></span>
|
||||||
<span class="badge bg-secondary">Table <?= htmlspecialchars((string)($order['table_number'] ?? '')) ?></span>
|
|
||||||
<?php else: ?>
|
|
||||||
<span class="badge bg-light text-dark border"><?= ucfirst($order['order_type']) ?></span>
|
|
||||||
<?php endif; ?>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="fw-bold"><?= format_currency($order['total_amount']) ?></td>
|
<td class="fw-bold"><?= format_currency($order['total_amount']) ?></td>
|
||||||
<?php if ($commission_enabled): ?>
|
<?php if ($commission_enabled): ?>
|
||||||
|
|||||||
@ -15,6 +15,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||||||
$name_ar = $_POST['name_ar'] ?? '';
|
$name_ar = $_POST['name_ar'] ?? '';
|
||||||
$category_id = (int)$_POST['category_id'];
|
$category_id = (int)$_POST['category_id'];
|
||||||
$price = (float)$_POST['price'];
|
$price = (float)$_POST['price'];
|
||||||
|
$vat_percent = (float)($_POST['vat_percent'] ?? 0);
|
||||||
$cost_price = (float)($_POST['cost_price'] ?? 0);
|
$cost_price = (float)($_POST['cost_price'] ?? 0);
|
||||||
$stock_quantity = (int)($_POST['stock_quantity'] ?? 0);
|
$stock_quantity = (int)($_POST['stock_quantity'] ?? 0);
|
||||||
$description = $_POST['description'] ?? '';
|
$description = $_POST['description'] ?? '';
|
||||||
@ -48,16 +49,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
|
|||||||
if (!has_permission('products_edit')) {
|
if (!has_permission('products_edit')) {
|
||||||
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to edit products.</div>';
|
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to edit products.</div>';
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("UPDATE products SET name = ?, name_ar = ?, category_id = ?, price = ?, cost_price = ?, stock_quantity = ?, description = ?, image_url = ?, promo_discount_percent = ?, promo_date_from = ?, promo_date_to = ?, is_loyalty = ? WHERE id = ?");
|
$stmt = $pdo->prepare("UPDATE products SET name = ?, name_ar = ?, category_id = ?, price = ?, vat_percent = ?, cost_price = ?, stock_quantity = ?, description = ?, image_url = ?, promo_discount_percent = ?, promo_date_from = ?, promo_date_to = ?, is_loyalty = ? WHERE id = ?");
|
||||||
$stmt->execute([$name, $name_ar, $category_id, $price, $cost_price, $stock_quantity, $description, $image_url, $promo_discount_percent, $promo_date_from, $promo_date_to, $is_loyalty, $id]);
|
$stmt->execute([$name, $name_ar, $category_id, $price, $vat_percent, $cost_price, $stock_quantity, $description, $image_url, $promo_discount_percent, $promo_date_from, $promo_date_to, $is_loyalty, $id]);
|
||||||
$message = '<div class="alert alert-success">Product updated successfully!</div>';
|
$message = '<div class="alert alert-success">Product updated successfully!</div>';
|
||||||
}
|
}
|
||||||
} elseif ($action === 'add_product') {
|
} elseif ($action === 'add_product') {
|
||||||
if (!has_permission('products_add')) {
|
if (!has_permission('products_add')) {
|
||||||
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to add products.</div>';
|
$message = '<div class="alert alert-danger">Access Denied: You do not have permission to add products.</div>';
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("INSERT INTO products (name, name_ar, category_id, price, cost_price, stock_quantity, description, image_url, promo_discount_percent, promo_date_from, promo_date_to, is_loyalty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
$stmt = $pdo->prepare("INSERT INTO products (name, name_ar, category_id, price, vat_percent, cost_price, stock_quantity, description, image_url, promo_discount_percent, promo_date_from, promo_date_to, is_loyalty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
$stmt->execute([$name, $name_ar, $category_id, $price, $cost_price, $stock_quantity, $description, $image_url, $promo_discount_percent, $promo_date_from, $promo_date_to, $is_loyalty]);
|
$stmt->execute([$name, $name_ar, $category_id, $price, $vat_percent, $cost_price, $stock_quantity, $description, $image_url, $promo_discount_percent, $promo_date_from, $promo_date_to, $is_loyalty]);
|
||||||
$message = '<div class="alert alert-success">Product created successfully!</div>';
|
$message = '<div class="alert alert-success">Product created successfully!</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,6 +185,7 @@ include 'includes/header.php';
|
|||||||
<th class="ps-4"><?= t('product') ?></th>
|
<th class="ps-4"><?= t('product') ?></th>
|
||||||
<th><?= t('category') ?></th>
|
<th><?= t('category') ?></th>
|
||||||
<th><?= t('price') ?></th>
|
<th><?= t('price') ?></th>
|
||||||
|
<th><?= t('VAT') ?></th>
|
||||||
<th><?= t('stock') ?></th>
|
<th><?= t('stock') ?></th>
|
||||||
<th><?= t('promotion') ?></th>
|
<th><?= t('promotion') ?></th>
|
||||||
<th class="text-end pe-4"><?= t('actions') ?></th>
|
<th class="text-end pe-4"><?= t('actions') ?></th>
|
||||||
@ -223,6 +225,9 @@ include 'includes/header.php';
|
|||||||
<small class="text-muted"><?= t('cost') ?>: <?= format_currency($product['cost_price']) ?></small>
|
<small class="text-muted"><?= t('cost') ?>: <?= format_currency($product['cost_price']) ?></small>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="badge bg-light text-dark border"><?= (float)$product['vat_percent'] ?>%</span>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<?php if ($product['stock_quantity'] <= 5): ?>
|
<?php if ($product['stock_quantity'] <= 5): ?>
|
||||||
<span class="badge bg-danger bg-opacity-10 text-danger border border-danger rounded-pill px-3"><?= $product['stock_quantity'] ?></span>
|
<span class="badge bg-danger bg-opacity-10 text-danger border border-danger rounded-pill px-3"><?= $product['stock_quantity'] ?></span>
|
||||||
@ -256,7 +261,7 @@ include 'includes/header.php';
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php if (empty($products)): ?>
|
<?php if (empty($products)): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="text-center py-5 text-muted">
|
<td colspan="7" class="text-center py-5 text-muted">
|
||||||
<i class="bi bi-inbox fs-1 d-block mb-2 opacity-25"></i>
|
<i class="bi bi-inbox fs-1 d-block mb-2 opacity-25"></i>
|
||||||
<?= t('none') ?>
|
<?= t('none') ?>
|
||||||
</td>
|
</td>
|
||||||
@ -306,7 +311,7 @@ include 'includes/header.php';
|
|||||||
<input type="text" name="name_ar" id="productNameAr" class="form-control rounded-3 border-0 bg-light" dir="rtl">
|
<input type="text" name="name_ar" id="productNameAr" class="form-control rounded-3 border-0 bg-light" dir="rtl">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-4">
|
||||||
<label class="form-label small fw-bold text-muted"><?= t('category') ?> <span class="text-danger">*</span></label>
|
<label class="form-label small fw-bold text-muted"><?= t('category') ?> <span class="text-danger">*</span></label>
|
||||||
<select name="category_id" id="productCategoryId" class="form-select rounded-3 border-0 bg-light" required>
|
<select name="category_id" id="productCategoryId" class="form-select rounded-3 border-0 bg-light" required>
|
||||||
<option value=""><?= t('select') ?> <?= t('category') ?></option>
|
<option value=""><?= t('select') ?> <?= t('category') ?></option>
|
||||||
@ -316,22 +321,32 @@ include 'includes/header.php';
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-2">
|
||||||
<label class="form-label small fw-bold text-muted"><?= t('price') ?> <span class="text-danger">*</span></label>
|
<label class="form-label small fw-bold text-muted"><?= t('price') ?> <span class="text-danger">*</span></label>
|
||||||
<input type="number" step="0.01" name="price" id="productPrice" class="form-control rounded-3 border-0 bg-light" required>
|
<input type="number" step="0.01" name="price" id="productPrice" class="form-control rounded-3 border-0 bg-light" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-2">
|
||||||
|
<label class="form-label small fw-bold text-muted"><?= t('VAT') ?> (%)</label>
|
||||||
|
<select name="vat_percent" id="productVatPercent" class="form-select rounded-3 border-0 bg-light">
|
||||||
|
<option value="0">0%</option>
|
||||||
|
<option value="5">5%</option>
|
||||||
|
<option value="10">10%</option>
|
||||||
|
<option value="15">15%</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-2">
|
||||||
<label class="form-label small fw-bold text-muted"><?= t('cost') ?> <?= t('price') ?></label>
|
<label class="form-label small fw-bold text-muted"><?= t('cost') ?> <?= t('price') ?></label>
|
||||||
<input type="number" step="0.01" name="cost_price" id="productCostPrice" class="form-control rounded-3 border-0 bg-light">
|
<input type="number" step="0.01" name="cost_price" id="productCostPrice" class="form-control rounded-3 border-0 bg-light">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-4">
|
<div class="col-md-2">
|
||||||
<label class="form-label small fw-bold text-muted"><?= t('stock') ?> <?= t('quantity') ?></label>
|
<label class="form-label small fw-bold text-muted"><?= t('stock') ?> <?= t('quantity') ?></label>
|
||||||
<input type="number" name="stock_quantity" id="productStockQuantity" class="form-control rounded-3 border-0 bg-light">
|
<input type="number" name="stock_quantity" id="productStockQuantity" class="form-control rounded-3 border-0 bg-light">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-8">
|
<div class="col-12">
|
||||||
<label class="form-label small fw-bold text-muted"><?= t('description') ?></label>
|
<label class="form-label small fw-bold text-muted"><?= t('description') ?></label>
|
||||||
<input type="text" name="description" id="productDescription" class="form-control rounded-3 border-0 bg-light">
|
<input type="text" name="description" id="productDescription" class="form-control rounded-3 border-0 bg-light">
|
||||||
</div>
|
</div>
|
||||||
@ -400,6 +415,7 @@ function prepareEditForm(p) {
|
|||||||
document.getElementById('productNameAr').value = p.name_ar || '';
|
document.getElementById('productNameAr').value = p.name_ar || '';
|
||||||
document.getElementById('productCategoryId').value = p.category_id;
|
document.getElementById('productCategoryId').value = p.category_id;
|
||||||
document.getElementById('productPrice').value = p.price;
|
document.getElementById('productPrice').value = p.price;
|
||||||
|
document.getElementById('productVatPercent').value = parseFloat(p.vat_percent || 0);
|
||||||
document.getElementById('productCostPrice').value = p.cost_price || '';
|
document.getElementById('productCostPrice').value = p.cost_price || '';
|
||||||
document.getElementById('productStockQuantity').value = p.stock_quantity || '0';
|
document.getElementById('productStockQuantity').value = p.stock_quantity || '0';
|
||||||
document.getElementById('productDescription').value = p.description || '';
|
document.getElementById('productDescription').value = p.description || '';
|
||||||
|
|||||||
@ -74,6 +74,15 @@ $tables_pagination = paginate_query($pdo, $query);
|
|||||||
$tables = $tables_pagination['data'];
|
$tables = $tables_pagination['data'];
|
||||||
|
|
||||||
include 'includes/header.php';
|
include 'includes/header.php';
|
||||||
|
|
||||||
|
// Base URL for QR codes
|
||||||
|
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https') ? "https://" : "http://";
|
||||||
|
$host = $_SERVER['HTTP_HOST'];
|
||||||
|
// Calculate project root
|
||||||
|
$current_dir = dirname($_SERVER['PHP_SELF']); // /admin
|
||||||
|
$project_root = dirname($current_dir); // /
|
||||||
|
if ($project_root === DIRECTORY_SEPARATOR) $project_root = '';
|
||||||
|
$baseUrl = $protocol . $host . $project_root;
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
@ -102,6 +111,7 @@ include 'includes/header.php';
|
|||||||
<th>Area</th>
|
<th>Area</th>
|
||||||
<th>Capacity</th>
|
<th>Capacity</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
|
<th>QR Code</th>
|
||||||
<th class="text-end pe-4">Actions</th>
|
<th class="text-end pe-4">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -121,6 +131,12 @@ include 'includes/header.php';
|
|||||||
<span class="badge bg-secondary-subtle text-secondary px-3"><?= ucfirst($table['status']) ?></span>
|
<span class="badge bg-secondary-subtle text-secondary px-3"><?= ucfirst($table['status']) ?></span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-info"
|
||||||
|
onclick="showTableQR('<?= $table['id'] ?>', '<?= htmlspecialchars($table['table_number']) ?>')">
|
||||||
|
<i class="bi bi-qr-code"></i> View QR
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
<td class="text-end pe-4">
|
<td class="text-end pe-4">
|
||||||
<?php if (has_permission('tables_add')): ?>
|
<?php if (has_permission('tables_add')): ?>
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary me-1"
|
<button type="button" class="btn btn-sm btn-outline-primary me-1"
|
||||||
@ -136,7 +152,7 @@ include 'includes/header.php';
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php if (empty($tables)): ?>
|
<?php if (empty($tables)): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="text-center py-4 text-muted">No tables found.</td>
|
<td colspan="7" class="text-center py-4 text-muted">No tables found.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -197,6 +213,33 @@ include 'includes/header.php';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- QR Modal -->
|
||||||
|
<div class="modal fade" id="qrModal" tabindex="-1" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-sm">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Table QR Code</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body text-center" id="printableQR">
|
||||||
|
<h4 class="fw-bold mb-3" id="qrTableNumber">Table</h4>
|
||||||
|
<div id="qrContainer" class="mb-3">
|
||||||
|
<!-- QR Image will be loaded here -->
|
||||||
|
</div>
|
||||||
|
<p class="small text-muted mb-0">Scan to Order</p>
|
||||||
|
<div class="mt-2 small text-break text-muted" id="qrLink" style="font-size: 0.7rem;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer justify-content-center">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="printQR()">
|
||||||
|
<i class="bi bi-printer"></i> Print
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function prepareAddForm() {
|
function prepareAddForm() {
|
||||||
@ -216,7 +259,35 @@ function prepareEditForm(table) {
|
|||||||
document.getElementById('tableCapacity').value = table.capacity || 2;
|
document.getElementById('tableCapacity').value = table.capacity || 2;
|
||||||
document.getElementById('tableStatus').value = table.status || 'available';
|
document.getElementById('tableStatus').value = table.status || 'available';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showTableQR(id, number) {
|
||||||
|
const baseUrl = '<?= $baseUrl ?>';
|
||||||
|
const qorderUrl = baseUrl + '/qorder.php?table_id=' + id;
|
||||||
|
const qrCodeUrl = "https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=" + encodeURIComponent(qorderUrl);
|
||||||
|
|
||||||
|
document.getElementById('qrTableNumber').innerText = 'Table ' + number;
|
||||||
|
document.getElementById('qrContainer').innerHTML = '<img src="' + qrCodeUrl + '" alt="QR Code" class="img-fluid shadow-sm" style="max-width: 200px;">';
|
||||||
|
document.getElementById('qrLink').innerText = qorderUrl;
|
||||||
|
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById('qrModal'));
|
||||||
|
modal.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function printQR() {
|
||||||
|
const content = document.getElementById('printableQR').innerHTML;
|
||||||
|
const printWindow = window.open('', '_blank');
|
||||||
|
printWindow.document.write('<html><head><title>Print Table QR</title>');
|
||||||
|
printWindow.document.write('<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">');
|
||||||
|
printWindow.document.write('<style>body { text-align: center; padding: 50px; }</style>');
|
||||||
|
printWindow.document.write('</head><body>');
|
||||||
|
printWindow.document.write(content);
|
||||||
|
printWindow.document.write('</body></html>');
|
||||||
|
printWindow.document.close();
|
||||||
|
setTimeout(() => {
|
||||||
|
printWindow.print();
|
||||||
|
printWindow.close();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<?php endif; ?>
|
|
||||||
|
|
||||||
<?php include 'includes/footer.php'; ?>
|
<?php include 'includes/footer.php'; ?>
|
||||||
@ -29,11 +29,11 @@ try {
|
|||||||
$table_number = null;
|
$table_number = null;
|
||||||
|
|
||||||
if ($order_type === 'dine-in') {
|
if ($order_type === 'dine-in') {
|
||||||
$tid = $data['table_number'] ?? null; // Front-end sends ID as table_number
|
$tid = $data['table_id'] ?? ($data['table_number'] ?? null); // Support both table_id and table_number as numeric ID
|
||||||
if ($tid) {
|
if ($tid) {
|
||||||
// Validate table exists AND belongs to the correct outlet
|
// Validate table exists AND belongs to the correct outlet
|
||||||
$stmt = $pdo->prepare(
|
$stmt = $pdo->prepare(
|
||||||
"SELECT t.id, t.name
|
"SELECT t.id, t.table_number
|
||||||
FROM tables t
|
FROM tables t
|
||||||
JOIN areas a ON t.area_id = a.id
|
JOIN areas a ON t.area_id = a.id
|
||||||
WHERE t.id = ? AND a.outlet_id = ?"
|
WHERE t.id = ? AND a.outlet_id = ?"
|
||||||
@ -42,7 +42,7 @@ try {
|
|||||||
$table = $stmt->fetch(PDO::FETCH_ASSOC);
|
$table = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
if ($table) {
|
if ($table) {
|
||||||
$table_id = $table['id'];
|
$table_id = $table['id'];
|
||||||
$table_number = $table['name'];
|
$table_number = $table['table_number'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ try {
|
|||||||
if (!$table_id) {
|
if (!$table_id) {
|
||||||
// Optional: try to find the first available table for this outlet
|
// Optional: try to find the first available table for this outlet
|
||||||
$stmt = $pdo->prepare(
|
$stmt = $pdo->prepare(
|
||||||
"SELECT t.id, t.name
|
"SELECT t.id, t.table_number
|
||||||
FROM tables t
|
FROM tables t
|
||||||
JOIN areas a ON t.area_id = a.id
|
JOIN areas a ON t.area_id = a.id
|
||||||
WHERE a.outlet_id = ?
|
WHERE a.outlet_id = ?
|
||||||
@ -60,7 +60,7 @@ try {
|
|||||||
$table = $stmt->fetch(PDO::FETCH_ASSOC);
|
$table = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
if ($table) {
|
if ($table) {
|
||||||
$table_id = $table['id'];
|
$table_id = $table['id'];
|
||||||
$table_number = $table['name'];
|
$table_number = $table['table_number'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +105,8 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Total amount will be recalculated on server to be safe
|
// Total amount will be recalculated on server to be safe
|
||||||
$calculated_total = 0;
|
$calculated_subtotal = 0;
|
||||||
|
$calculated_vat = 0;
|
||||||
|
|
||||||
// First, process items to calculate real total and handle loyalty
|
// First, process items to calculate real total and handle loyalty
|
||||||
$processed_items = [];
|
$processed_items = [];
|
||||||
@ -126,6 +127,7 @@ try {
|
|||||||
if (!$product) continue;
|
if (!$product) continue;
|
||||||
|
|
||||||
$unit_price = get_product_price($product);
|
$unit_price = get_product_price($product);
|
||||||
|
$vat_percent = floatval($product['vat_percent'] ?? 0);
|
||||||
|
|
||||||
$variant_name = null;
|
$variant_name = null;
|
||||||
// Add variant adjustment
|
// Add variant adjustment
|
||||||
@ -150,6 +152,7 @@ try {
|
|||||||
'variant_name' => $variant_name,
|
'variant_name' => $variant_name,
|
||||||
'quantity' => $qty,
|
'quantity' => $qty,
|
||||||
'unit_price' => $unit_price,
|
'unit_price' => $unit_price,
|
||||||
|
'vat_percent' => $vat_percent,
|
||||||
'is_loyalty' => (bool)$product['is_loyalty']
|
'is_loyalty' => (bool)$product['is_loyalty']
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -230,14 +233,22 @@ try {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculate Subtotal and Earned Points
|
// Recalculate Subtotal, VAT and Earned Points
|
||||||
foreach ($processed_items as $pi) {
|
foreach ($processed_items as &$pi) {
|
||||||
$calculated_total += $pi['unit_price'] * $pi['quantity'];
|
$item_subtotal = $pi['unit_price'] * $pi['quantity'];
|
||||||
|
$item_vat = $item_subtotal * ($pi['vat_percent'] / 100);
|
||||||
|
|
||||||
|
$pi['vat_amount'] = $item_vat;
|
||||||
|
|
||||||
|
$calculated_subtotal += $item_subtotal;
|
||||||
|
$calculated_vat += $item_vat;
|
||||||
|
|
||||||
// Award points for PAID loyalty items
|
// Award points for PAID loyalty items
|
||||||
if ($pi['is_loyalty'] && $pi['unit_price'] > 0 && $pi['quantity'] > 0) {
|
if ($pi['is_loyalty'] && $pi['unit_price'] > 0 && $pi['quantity'] > 0) {
|
||||||
$points_awarded += $pi['quantity'] * $points_per_product;
|
$points_awarded += $pi['quantity'] * $points_per_product;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unset($pi);
|
||||||
|
|
||||||
// Award Points
|
// Award Points
|
||||||
if ($customer_id && $loyalty_enabled && $points_awarded > 0) {
|
if ($customer_id && $loyalty_enabled && $points_awarded > 0) {
|
||||||
@ -250,8 +261,7 @@ try {
|
|||||||
$award_history_id = $pdo->lastInsertId();
|
$award_history_id = $pdo->lastInsertId();
|
||||||
}
|
}
|
||||||
|
|
||||||
$vat = isset($data['vat']) ? floatval($data['vat']) : 0.00;
|
$final_total = max(0, $calculated_subtotal + $calculated_vat);
|
||||||
$final_total = max(0, $calculated_total + $vat);
|
|
||||||
|
|
||||||
// User/Payment info
|
// User/Payment info
|
||||||
$user = get_logged_user();
|
$user = get_logged_user();
|
||||||
@ -266,7 +276,7 @@ try {
|
|||||||
$userStmt->execute([$user_id]);
|
$userStmt->execute([$user_id]);
|
||||||
$commission_rate = (float)$userStmt->fetchColumn();
|
$commission_rate = (float)$userStmt->fetchColumn();
|
||||||
if ($commission_rate > 0) {
|
if ($commission_rate > 0) {
|
||||||
$commission_amount = $calculated_total * ($commission_rate / 100);
|
$commission_amount = $calculated_subtotal * ($commission_rate / 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,21 +298,21 @@ try {
|
|||||||
$stmt = $pdo->prepare("UPDATE orders SET
|
$stmt = $pdo->prepare("UPDATE orders SET
|
||||||
outlet_id = ?, table_id = ?, table_number = ?, order_type = ?,
|
outlet_id = ?, table_id = ?, table_number = ?, order_type = ?,
|
||||||
customer_id = ?, customer_name = ?, customer_phone = ?,
|
customer_id = ?, customer_name = ?, customer_phone = ?,
|
||||||
payment_type_id = ?, total_amount = ?, discount = ?, user_id = ?,
|
payment_type_id = ?, total_amount = ?, discount = ?, vat = ?, user_id = ?,
|
||||||
commission_amount = ?, status = 'pending'
|
commission_amount = ?, status = 'pending'
|
||||||
WHERE id = ?");
|
WHERE id = ?");
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
$outlet_id, $table_id, $table_number, $order_type,
|
$outlet_id, $table_id, $table_number, $order_type,
|
||||||
$customer_id, $customer_name, $customer_phone,
|
$customer_id, $customer_name, $customer_phone,
|
||||||
$payment_type_id, $final_total, $vat, $user_id,
|
$payment_type_id, $final_total, 0, $calculated_vat, $user_id,
|
||||||
$commission_amount, $order_id
|
$commission_amount, $order_id
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$delStmt = $pdo->prepare("DELETE FROM order_items WHERE order_id = ?");
|
$delStmt = $pdo->prepare("DELETE FROM order_items WHERE order_id = ?");
|
||||||
$delStmt->execute([$order_id]);
|
$delStmt->execute([$order_id]);
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("INSERT INTO orders (outlet_id, table_id, table_number, order_type, customer_id, customer_name, customer_phone, payment_type_id, total_amount, discount, user_id, commission_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')");
|
$stmt = $pdo->prepare("INSERT INTO orders (outlet_id, table_id, table_number, order_type, customer_id, customer_name, customer_phone, payment_type_id, total_amount, discount, vat, user_id, commission_amount, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')");
|
||||||
$stmt->execute([$outlet_id, $table_id, $table_number, $order_type, $customer_id, $customer_name, $customer_phone, $payment_type_id, $final_total, $vat, $user_id, $commission_amount]);
|
$stmt->execute([$outlet_id, $table_id, $table_number, $order_type, $customer_id, $customer_name, $customer_phone, $payment_type_id, $final_total, 0, $calculated_vat, $user_id, $commission_amount]);
|
||||||
$order_id = $pdo->lastInsertId();
|
$order_id = $pdo->lastInsertId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,13 +327,13 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert Items and Update Stock
|
// Insert Items and Update Stock
|
||||||
$item_stmt = $pdo->prepare("INSERT INTO order_items (order_id, product_id, product_name, variant_id, variant_name, quantity, unit_price) VALUES (?, ?, ?, ?, ?, ?, ?)");
|
$item_stmt = $pdo->prepare("INSERT INTO order_items (order_id, product_id, product_name, variant_id, variant_name, quantity, unit_price, vat_percent, vat_amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
$stock_stmt = $pdo->prepare("UPDATE products SET stock_quantity = stock_quantity - ? WHERE id = ?");
|
$stock_stmt = $pdo->prepare("UPDATE products SET stock_quantity = stock_quantity - ? WHERE id = ?");
|
||||||
|
|
||||||
$order_items_list = [];
|
$order_items_list = [];
|
||||||
|
|
||||||
foreach ($processed_items as $pi) {
|
foreach ($processed_items as $pi) {
|
||||||
$item_stmt->execute([$order_id, $pi['product_id'], $pi['product_name'], $pi['variant_id'], $pi['variant_name'], $pi['quantity'], $pi['unit_price']]);
|
$item_stmt->execute([$order_id, $pi['product_id'], $pi['product_name'], $pi['variant_id'], $pi['variant_name'], $pi['quantity'], $pi['unit_price'], $pi['vat_percent'], $pi['vat_amount']]);
|
||||||
|
|
||||||
// Decrement Stock
|
// Decrement Stock
|
||||||
$stock_stmt->execute([$pi['quantity'], $pi['product_id']]);
|
$stock_stmt->execute([$pi['quantity'], $pi['product_id']]);
|
||||||
|
|||||||
@ -40,6 +40,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const cartItemsContainer = document.getElementById('cart-items');
|
const cartItemsContainer = document.getElementById('cart-items');
|
||||||
const cartTotalPrice = document.getElementById('cart-total-price');
|
const cartTotalPrice = document.getElementById('cart-total-price');
|
||||||
const cartSubtotal = document.getElementById('cart-subtotal');
|
const cartSubtotal = document.getElementById('cart-subtotal');
|
||||||
|
const cartVatAmount = document.getElementById('cart-vat-amount');
|
||||||
|
const cartVatRow = document.getElementById('cart-vat-row');
|
||||||
const cartVatInput = document.getElementById('cart-vat-input');
|
const cartVatInput = document.getElementById('cart-vat-input');
|
||||||
|
|
||||||
const quickOrderBtn = document.getElementById('quick-order-btn');
|
const quickOrderBtn = document.getElementById('quick-order-btn');
|
||||||
@ -504,7 +506,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
addToCart({
|
addToCart({
|
||||||
id: product.id, name: product.name, name_ar: product.name_ar || "",
|
id: product.id, name: product.name, name_ar: product.name_ar || "",
|
||||||
price: parseFloat(product.price), base_price: parseFloat(product.price),
|
price: parseFloat(product.price), base_price: parseFloat(product.price),
|
||||||
hasVariants: false, quantity: 1, variant_id: null, variant_name: null, is_loyalty: parseInt(product.is_loyalty) === 1
|
hasVariants: false, quantity: 1, variant_id: null, variant_name: null,
|
||||||
|
is_loyalty: parseInt(product.is_loyalty) === 1,
|
||||||
|
vat_percent: parseFloat(product.vat_percent || 0)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -526,7 +530,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
addToCart({
|
addToCart({
|
||||||
id: product.id, name: product.name, name_ar: product.name_ar || "",
|
id: product.id, name: product.name, name_ar: product.name_ar || "",
|
||||||
price: finalPrice, base_price: parseFloat(product.price),
|
price: finalPrice, base_price: parseFloat(product.price),
|
||||||
hasVariants: true, quantity: 1, variant_id: v.id, variant_name: v.name, is_loyalty: parseInt(product.is_loyalty) === 1
|
hasVariants: true, quantity: 1, variant_id: v.id, variant_name: v.name,
|
||||||
|
is_loyalty: parseInt(product.is_loyalty) === 1,
|
||||||
|
vat_percent: parseFloat(product.vat_percent || 0)
|
||||||
});
|
});
|
||||||
variantSelectionModal.hide();
|
variantSelectionModal.hide();
|
||||||
};
|
};
|
||||||
@ -572,6 +578,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (cart.length === 0) {
|
if (cart.length === 0) {
|
||||||
cartItemsContainer.innerHTML = `<div class="text-center text-muted mt-5"><i class="bi bi-basket3 fs-1 text-light"></i><p class="mt-2">${_t('cart_empty')}</p></div>`;
|
cartItemsContainer.innerHTML = `<div class="text-center text-muted mt-5"><i class="bi bi-basket3 fs-1 text-light"></i><p class="mt-2">${_t('cart_empty')}</p></div>`;
|
||||||
if (cartSubtotal) cartSubtotal.innerText = formatCurrency(0);
|
if (cartSubtotal) cartSubtotal.innerText = formatCurrency(0);
|
||||||
|
if (cartVatAmount) cartVatAmount.innerText = formatCurrency(0);
|
||||||
|
if (cartVatRow) cartVatRow.classList.add('d-none');
|
||||||
if (cartTotalPrice) cartTotalPrice.innerText = formatCurrency(0);
|
if (cartTotalPrice) cartTotalPrice.innerText = formatCurrency(0);
|
||||||
if (quickOrderBtn) { quickOrderBtn.disabled = true; quickOrderBtn.innerText = _t('quick_pay'); }
|
if (quickOrderBtn) { quickOrderBtn.disabled = true; quickOrderBtn.innerText = _t('quick_pay'); }
|
||||||
if (placeOrderBtn) { placeOrderBtn.disabled = true; placeOrderBtn.innerText = _t('save_bill'); }
|
if (placeOrderBtn) { placeOrderBtn.disabled = true; placeOrderBtn.innerText = _t('save_bill'); }
|
||||||
@ -580,9 +588,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
cartItemsContainer.innerHTML = '';
|
cartItemsContainer.innerHTML = '';
|
||||||
let subtotal = 0;
|
let subtotal = 0;
|
||||||
|
let totalVat = 0;
|
||||||
cart.forEach((item, index) => {
|
cart.forEach((item, index) => {
|
||||||
const itemTotal = item.price * item.quantity;
|
const itemTotal = item.price * item.quantity;
|
||||||
|
const itemVat = itemTotal * (item.vat_percent / 100);
|
||||||
subtotal += itemTotal;
|
subtotal += itemTotal;
|
||||||
|
totalVat += itemVat;
|
||||||
|
|
||||||
const row = document.createElement('div');
|
const row = document.createElement('div');
|
||||||
row.className = 'd-flex justify-content-between align-items-center mb-3 border-bottom pb-2';
|
row.className = 'd-flex justify-content-between align-items-center mb-3 border-bottom pb-2';
|
||||||
const itemName = (LANG === 'ar' && item.name_ar) ? item.name_ar : item.name;
|
const itemName = (LANG === 'ar' && item.name_ar) ? item.name_ar : item.name;
|
||||||
@ -592,7 +604,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
<div class="flex-grow-1 me-2">
|
<div class="flex-grow-1 me-2">
|
||||||
<div class="fw-bold text-truncate" style="max-width: 140px;">${itemName}</div>
|
<div class="fw-bold text-truncate" style="max-width: 140px;">${itemName}</div>
|
||||||
${otherName ? `<div class="text-muted small" style="font-size: 0.75rem;">${otherName}</div>` : ''}
|
${otherName ? `<div class="text-muted small" style="font-size: 0.75rem;">${otherName}</div>` : ''}
|
||||||
<div class="small text-muted">${formatCurrency(item.price)}</div>
|
<div class="small text-muted">${formatCurrency(item.price)} ${item.vat_percent > 0 ? `<span class="badge bg-light text-dark border ms-1" style="font-size: 0.6rem;">${item.vat_percent}% VAT</span>` : ''}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-items-center bg-light rounded px-1">
|
<div class="d-flex align-items-center bg-light rounded px-1">
|
||||||
<button class="btn btn-sm text-secondary p-0" style="width: 24px;" onclick="changeQuantity(${index}, -1)"><i class="bi bi-dash"></i></button>
|
<button class="btn btn-sm text-secondary p-0" style="width: 24px;" onclick="changeQuantity(${index}, -1)"><i class="bi bi-dash"></i></button>
|
||||||
@ -608,11 +620,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (cartSubtotal) cartSubtotal.innerText = formatCurrency(subtotal);
|
if (cartSubtotal) cartSubtotal.innerText = formatCurrency(subtotal);
|
||||||
const vatRate = parseFloat(settings.vat_rate) || 0;
|
if (cartVatAmount) cartVatAmount.innerText = formatCurrency(totalVat);
|
||||||
const vat = subtotal * (vatRate / 100);
|
if (cartVatRow) {
|
||||||
if (cartVatInput) cartVatInput.value = vat.toFixed(2);
|
if (totalVat > 0) cartVatRow.classList.remove('d-none');
|
||||||
const total = subtotal + vat;
|
else cartVatRow.classList.add('d-none');
|
||||||
|
}
|
||||||
|
if (cartVatInput) cartVatInput.value = totalVat.toFixed(3);
|
||||||
|
|
||||||
|
const total = subtotal + totalVat;
|
||||||
if (cartTotalPrice) cartTotalPrice.innerText = formatCurrency(total);
|
if (cartTotalPrice) cartTotalPrice.innerText = formatCurrency(total);
|
||||||
|
|
||||||
if (quickOrderBtn) { quickOrderBtn.disabled = false; quickOrderBtn.innerText = _t('quick_pay'); }
|
if (quickOrderBtn) { quickOrderBtn.disabled = false; quickOrderBtn.innerText = _t('quick_pay'); }
|
||||||
if (placeOrderBtn) { placeOrderBtn.disabled = false; placeOrderBtn.innerText = _t('save_bill'); }
|
if (placeOrderBtn) { placeOrderBtn.disabled = false; placeOrderBtn.innerText = _t('save_bill'); }
|
||||||
}
|
}
|
||||||
@ -648,9 +665,23 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
window.processOrder = function(paymentTypeId, paymentTypeName) {
|
window.processOrder = function(paymentTypeId, paymentTypeName) {
|
||||||
const orderTypeInput = document.querySelector('input[name="order_type"]:checked');
|
const orderTypeInput = document.querySelector('input[name="order_type"]:checked');
|
||||||
const orderType = orderTypeInput ? orderTypeInput.value : 'takeaway';
|
const orderType = orderTypeInput ? orderTypeInput.value : 'takeaway';
|
||||||
const subtotal = cart.reduce((acc, item) => acc + (item.price * item.quantity), 0);
|
|
||||||
const vatRate = parseFloat(settings.vat_rate) || 0;
|
let subtotal = 0;
|
||||||
const vat = subtotal * (vatRate / 100);
|
let totalVat = 0;
|
||||||
|
const itemsData = cart.map(item => {
|
||||||
|
const itemTotal = item.price * item.quantity;
|
||||||
|
const itemVat = itemTotal * (item.vat_percent / 100);
|
||||||
|
subtotal += itemTotal;
|
||||||
|
totalVat += itemVat;
|
||||||
|
return {
|
||||||
|
product_id: item.id,
|
||||||
|
quantity: item.quantity,
|
||||||
|
unit_price: item.price,
|
||||||
|
variant_id: item.variant_id,
|
||||||
|
vat_percent: item.vat_percent,
|
||||||
|
vat_amount: itemVat
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const orderData = {
|
const orderData = {
|
||||||
order_id: currentOrderId,
|
order_id: currentOrderId,
|
||||||
@ -659,9 +690,9 @@ 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 + vat,
|
total_amount: subtotal + totalVat,
|
||||||
vat: vat,
|
vat: totalVat,
|
||||||
items: cart.map(item => ({ product_id: item.id, quantity: item.quantity, unit_price: item.price, variant_id: item.variant_id })),
|
items: itemsData,
|
||||||
redeem_loyalty: isLoyaltyRedemption
|
redeem_loyalty: isLoyaltyRedemption
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -673,10 +704,13 @@ 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: item.price,
|
||||||
|
vat_percent: item.vat_percent,
|
||||||
|
vat_amount: (item.price * item.quantity) * (item.vat_percent / 100)
|
||||||
})),
|
})),
|
||||||
total: subtotal + vat,
|
subtotal: subtotal,
|
||||||
vat: vat,
|
total: subtotal + totalVat,
|
||||||
|
vat: 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' }),
|
||||||
@ -702,7 +736,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
window.printThermalReceipt = function(data) {
|
window.printThermalReceipt = function(data) {
|
||||||
const width = 400;
|
const width = 450;
|
||||||
const height = 800;
|
const height = 800;
|
||||||
const left = (screen.width - width) / 2;
|
const left = (screen.width - width) / 2;
|
||||||
const top = (screen.height - height) / 2;
|
const top = (screen.height - height) / 2;
|
||||||
@ -717,7 +751,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const tr = {
|
const tr = {
|
||||||
'Order': 'الطلب', 'Type': 'النوع', 'Date': 'التاريخ', 'Staff': 'الموظف',
|
'Order': 'الطلب', 'Type': 'النوع', 'Date': 'التاريخ', 'Staff': 'الموظف',
|
||||||
'Table': 'طاولة', 'Payment': 'الدفع', 'ITEM': 'الصنف', 'TOTAL': 'المجموع',
|
'Table': 'طاولة', 'Payment': 'الدفع', 'ITEM': 'الصنف', 'TOTAL': 'المجموع',
|
||||||
'Subtotal': 'المجموع الفرعي', 'VAT': 'ضريبة القيمة المضافة', 'Tax Included': 'شامل الضريبة',
|
'Subtotal': 'المجموع الفرعي', 'VAT': 'الضريبة', 'Tax Included': 'شامل الضريبة',
|
||||||
'THANK YOU FOR YOUR VISIT!': 'شكراً لزيارتكم!', 'Please come again.': 'يرجى زيارتنا مرة أخرى.',
|
'THANK YOU FOR YOUR VISIT!': 'شكراً لزيارتكم!', 'Please come again.': 'يرجى زيارتنا مرة أخرى.',
|
||||||
'Customer Details': 'تفاصيل العميل', 'Tel': 'هاتف', 'takeaway': 'سفري',
|
'Customer Details': 'تفاصيل العميل', 'Tel': 'هاتف', 'takeaway': 'سفري',
|
||||||
'dine-in': 'محلي', 'delivery': 'توصيل', 'VAT No': 'الرقم الضريبي', 'CTR No': 'رقم السجل التجاري'
|
'dine-in': 'محلي', 'delivery': 'توصيل', 'VAT No': 'الرقم الضريبي', 'CTR No': 'رقم السجل التجاري'
|
||||||
@ -730,6 +764,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
${item.variant_name ? `<div style="font-size: 10px; color: #555;">(${item.variant_name})</div>` : ''}
|
${item.variant_name ? `<div style="font-size: 10px; color: #555;">(${item.variant_name})</div>` : ''}
|
||||||
<div style="font-size: 11px;">${item.quantity} x ${formatCurrency(item.price)}</div>
|
<div style="font-size: 11px;">${item.quantity} x ${formatCurrency(item.price)}</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td style="text-align: center; vertical-align: middle; font-size: 11px;">${item.vat_percent > 0 ? item.vat_percent + '%' : '-'}</td>
|
||||||
<td style="text-align: right; vertical-align: middle; font-weight: bold;">${formatCurrency(item.quantity * item.price)}</td>
|
<td style="text-align: right; vertical-align: middle; font-weight: bold;">${formatCurrency(item.quantity * item.price)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
`).join('');
|
`).join('');
|
||||||
@ -761,7 +796,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
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 = settings.logo_url ? `<img src="${BASE_URL}${settings.logo_url}" style="max-height: 80px; max-width: 150px; margin-bottom: 10px;">` : '';
|
const logoHtml = settings.logo_url ? `<img src="${BASE_URL}${settings.logo_url}" style="max-height: 80px; max-width: 150px; margin-bottom: 10px;">` : '';
|
||||||
|
|
||||||
const html = `
|
const html = `
|
||||||
@ -805,14 +839,20 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
<div class="thick-divider"></div>
|
<div class="thick-divider"></div>
|
||||||
${customerHtml}
|
${customerHtml}
|
||||||
<table>
|
<table>
|
||||||
<thead><tr><th style="text-align: left; padding-bottom: 5px;">ITEM / الصنف</th><th style="text-align: right; padding-bottom: 5px;">TOTAL / المجموع</th></tr></thead>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="text-align: left; padding-bottom: 5px;">ITEM / الصنف</th>
|
||||||
|
<th style="text-align: center; padding-bottom: 5px; font-size: 10px;">VAT / الضريبة</th>
|
||||||
|
<th style="text-align: right; padding-bottom: 5px;">TOTAL / المجموع</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
<tbody>${itemsHtml}</tbody>
|
<tbody>${itemsHtml}</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<div class="totals">
|
<div class="totals">
|
||||||
<table style="width: 100%">
|
<table style="width: 100%">
|
||||||
<tr><td>Subtotal / ${tr['Subtotal']}</td><td style="text-align: right">${formatCurrency(subtotal)}</td></tr>
|
<tr><td>Subtotal / ${tr['Subtotal']}</td><td style="text-align: right">${formatCurrency(data.subtotal)}</td></tr>
|
||||||
${Math.abs(data.vat) > 0 ? `<tr><td>${data.vat < 0 ? 'Discount' : 'VAT'} / ${tr['VAT']}</td><td style="text-align: right">${data.vat < 0 ? '-' : '+'}${formatCurrency(Math.abs(data.vat))}</td></tr>` : ''}
|
${Math.abs(data.vat) > 0 ? `<tr><td>VAT / ${tr['VAT']}</td><td style="text-align: right">${formatCurrency(Math.abs(data.vat))}</td></tr>` : ''}
|
||||||
<tr style="font-weight: bold; font-size: 18px;"><td style="padding-top: 10px;">TOTAL / ${tr['TOTAL']}</td><td style="text-align: right; padding-top: 10px;">${formatCurrency(data.total)}</td></tr>
|
<tr style="font-weight: bold; font-size: 18px;"><td style="padding-top: 10px;">TOTAL / ${tr['TOTAL']}</td><td style="text-align: right; padding-top: 10px;">${formatCurrency(data.total)}</td></tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
5
pos.php
5
pos.php
@ -326,6 +326,11 @@ if (!$loyalty_settings) {
|
|||||||
<span class="text-muted small">Subtotal</span>
|
<span class="text-muted small">Subtotal</span>
|
||||||
<span class="fw-bold small" id="cart-subtotal"><?= format_currency(0) ?></span>
|
<span class="fw-bold small" id="cart-subtotal"><?= format_currency(0) ?></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="d-flex justify-content-between mb-1" id="cart-vat-row">
|
||||||
|
<span class="text-muted small">VAT</span>
|
||||||
|
<span class="fw-bold small" id="cart-vat-amount"><?= format_currency(0) ?></span>
|
||||||
|
<input type="hidden" id="cart-vat-input" value="0">
|
||||||
|
</div>
|
||||||
<div class="d-flex justify-content-between mb-3">
|
<div class="d-flex justify-content-between mb-3">
|
||||||
<span class="fs-6 fw-bold">Total</span>
|
<span class="fs-6 fw-bold">Total</span>
|
||||||
<span class="fs-5 fw-bold text-primary" id="cart-total-price"><?= format_currency(0) ?></span>
|
<span class="fs-5 fw-bold text-primary" id="cart-total-price"><?= format_currency(0) ?></span>
|
||||||
|
|||||||
@ -14,7 +14,7 @@ if ($table_id <= 0) {
|
|||||||
|
|
||||||
// Fetch table and outlet info
|
// Fetch table and outlet info
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
SELECT t.id, t.name as table_name, a.outlet_id, o.name as outlet_name
|
SELECT t.id, t.table_number as table_name, a.outlet_id, o.name as outlet_name
|
||||||
FROM tables t
|
FROM tables t
|
||||||
JOIN areas a ON t.area_id = a.id
|
JOIN areas a ON t.area_id = a.id
|
||||||
JOIN outlets o ON a.outlet_id = o.id
|
JOIN outlets o ON a.outlet_id = o.id
|
||||||
@ -303,9 +303,6 @@ foreach ($variants_raw as $v) {
|
|||||||
document.getElementById('lang-btn').textContent = currentLang === 'en' ? 'AR' : 'EN';
|
document.getElementById('lang-btn').textContent = currentLang === 'en' ? 'AR' : 'EN';
|
||||||
if (currentLang === 'ar') {
|
if (currentLang === 'ar') {
|
||||||
document.body.classList.add('lang-ar');
|
document.body.classList.add('lang-ar');
|
||||||
document.body.classList.remove('both-names'); // Optional: hide EN when AR is active?
|
|
||||||
// User said "both", so maybe I should keep both-names active if I want to show both.
|
|
||||||
// But let's follow standard toggle behavior for UI.
|
|
||||||
} else {
|
} else {
|
||||||
document.body.classList.remove('lang-ar');
|
document.body.classList.remove('lang-ar');
|
||||||
}
|
}
|
||||||
@ -458,7 +455,7 @@ foreach ($variants_raw as $v) {
|
|||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
outlet_id: OUTLET_ID,
|
outlet_id: OUTLET_ID,
|
||||||
table_number: TABLE_ID,
|
table_id: TABLE_ID, // Use table_id instead of table_number
|
||||||
order_type: 'dine-in',
|
order_type: 'dine-in',
|
||||||
customer_name: customerName,
|
customer_name: customerName,
|
||||||
items: cart,
|
items: cart,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user