updating labels price

This commit is contained in:
Flatlogic Bot 2026-02-19 11:20:36 +00:00
parent e3240af16d
commit 552d635c19
6 changed files with 208 additions and 59 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -0,0 +1,16 @@
-- Add VAT columns to pos_items
ALTER TABLE pos_items ADD COLUMN vat_rate DECIMAL(5,2) DEFAULT 0.00 AFTER unit_price;
ALTER TABLE pos_items ADD COLUMN vat_amount DECIMAL(15,3) DEFAULT 0.000 AFTER vat_rate;
-- Update existing pos_items if possible (optional, but good for consistency)
-- This might not be accurate if items changed their vat rate after transaction,
-- but it's better than nothing.
UPDATE pos_items pi
JOIN stock_items si ON pi.product_id = si.id
SET pi.vat_rate = si.vat_rate;
UPDATE pos_items SET vat_amount = subtotal * (vat_rate / (100 + vat_rate));
-- Update pos_transactions to ensure tax_amount is populated for old transactions
UPDATE pos_transactions pt
SET tax_amount = (SELECT SUM(vat_amount) FROM pos_items WHERE transaction_id = pt.id);

1
debug_sessions.log Normal file
View File

@ -0,0 +1 @@
Where: 1=1 Params: []

View File

@ -90,7 +90,7 @@ $translations = [
'walk_in_customer' => 'Walk-in Customer',
'currency' => 'ر.ع / OMR',
'cash' => 'Cash',
'card' => 'Card',
'card' => 'Credit Card',
'credit' => 'Credit',
],
'ar' => [
@ -183,7 +183,7 @@ $translations = [
'walk_in_customer' => 'عميل نقدي',
'currency' => 'ر.ع / OMR',
'cash' => 'نقد',
'card' => 'بطاقة',
'card' => 'بطاقة ائتمان',
'credit' => 'آجل',
]
];

231
index.php
View File

@ -258,6 +258,7 @@ if (isset($_GET['action']) || isset($_POST['action'])) {
$payments = json_decode($_POST['payments'] ?? '[]', true);
$items = json_decode($_POST['items'] ?? '[]', true);
$total_amount = (float)($_POST['total_amount'] ?? 0);
$tax_amount = (float)($_POST['tax_amount'] ?? 0);
$discount_code_id = !empty($_POST['discount_code_id']) ? (int)$_POST['discount_code_id'] : null;
$discount_amount = (float)($_POST['discount_amount'] ?? 0);
$loyalty_redeemed = (float)($_POST['loyalty_redeemed'] ?? 0);
@ -266,18 +267,30 @@ if (isset($_GET['action']) || isset($_POST['action'])) {
$transaction_no = 'POS-' . time() . rand(10, 99);
$session_id = $_SESSION['register_session_id'] ?? null;
if (!$session_id) {
// Fallback: try to find an open session for this user
$check_session = $db->prepare("SELECT id FROM register_sessions WHERE user_id = ? AND status = 'open' LIMIT 1");
$check_session->execute([$_SESSION['user_id']]);
$session_id = $check_session->fetchColumn() ?: null;
if ($session_id) {
$_SESSION['register_session_id'] = $session_id;
}
}
// Insert Transaction
$stmt = $db->prepare("INSERT INTO pos_transactions (transaction_no, customer_id, total_amount, discount_code_id, discount_amount, loyalty_points_redeemed, net_amount, register_session_id, created_by, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'completed')");
$stmt->execute([$transaction_no, $customer_id, $total_amount, $discount_code_id, $discount_amount, $loyalty_redeemed, $net_amount, $session_id, $_SESSION['user_id']]);
$stmt = $db->prepare("INSERT INTO pos_transactions (transaction_no, customer_id, total_amount, tax_amount, discount_code_id, discount_amount, loyalty_points_redeemed, net_amount, register_session_id, created_by, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'completed')");
$stmt->execute([$transaction_no, $customer_id, $total_amount, $tax_amount, $discount_code_id, $discount_amount, $loyalty_redeemed, $net_amount, $session_id, $_SESSION['user_id']]);
$transaction_id = (int)$db->lastInsertId();
// Insert Items & Update Stock
$stmtItem = $db->prepare("INSERT INTO pos_items (transaction_id, product_id, quantity, unit_price, subtotal) VALUES (?, ?, ?, ?, ?)");
$stmtItem = $db->prepare("INSERT INTO pos_items (transaction_id, product_id, quantity, unit_price, vat_rate, vat_amount, subtotal) VALUES (?, ?, ?, ?, ?, ?, ?)");
$stmtStock = $db->prepare("UPDATE stock_items SET stock_quantity = stock_quantity - ? WHERE id = ?");
foreach ($items as $item) {
$sub = (float)$item['price'] * (float)$item['qty'];
$stmtItem->execute([$transaction_id, $item['id'], $item['qty'], $item['price'], $sub]);
$vr = (float)($item['vat_rate'] ?? 0);
$va = (float)($item['vat_amount'] ?? 0);
$stmtItem->execute([$transaction_id, $item['id'], $item['qty'], $item['price'], $vr, $va, $sub]);
$stmtStock->execute([$item['qty'], $item['id']]);
}
@ -1911,10 +1924,30 @@ switch ($page) {
case 'register_sessions':
$where = ["1=1"];
$params = [];
// Filter by user if provided and user has permission
if (isset($_GET['user_id']) && !empty($_GET['user_id'])) {
if (can('users_view')) {
$where[] = "s.user_id = ?";
$params[] = $_GET['user_id'];
}
}
if (!can('users_view')) {
$where[] = "s.user_id = ?";
$params[] = $_SESSION['user_id'];
}
// Filter by date range
if (isset($_GET['date_from']) && !empty($_GET['date_from'])) {
$where[] = "s.opened_at >= ?";
$params[] = $_GET['date_from'] . ' 00:00:00';
}
if (isset($_GET['date_to']) && !empty($_GET['date_to'])) {
$where[] = "s.opened_at <= ?";
$params[] = $_GET['date_to'] . ' 23:59:59';
}
$whereSql = implode(" AND ", $where);
$stmt = db()->prepare("SELECT s.*, r.name as register_name, u.username
FROM register_sessions s
@ -1925,6 +1958,7 @@ switch ($page) {
$stmt->execute($params);
$data['sessions'] = $stmt->fetchAll();
$data['cash_registers'] = db()->query("SELECT * FROM cash_registers WHERE status = 'active'")->fetchAll();
$data['users'] = db()->query("SELECT id, username FROM users ORDER BY username ASC")->fetchAll();
break;
default:
$data['customers'] = db()->query("SELECT * FROM customers WHERE type = 'customer' ORDER BY id DESC LIMIT 5")->fetchAll();
@ -2802,7 +2836,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<tbody>
<?php foreach ($data['items'] as $item): ?>
<tr>
<td><input type="checkbox" class="form-check-input item-checkbox" data-id="<?= $item['id'] ?>" data-sku="<?= htmlspecialchars($item['sku']) ?>" data-name="<?= htmlspecialchars($item['name_en']) ?>" data-price="<?= number_format((float)$item['sale_price'], 3) ?>"></td>
<td><input type="checkbox" class="form-check-input item-checkbox" data-id="<?= $item['id'] ?>" data-sku="<?= htmlspecialchars($item['sku']) ?>" data-name="<?= htmlspecialchars($item['name_en'] . ' - ' . $item['name_ar']) ?>" data-price="<?= number_format((float)$item['sale_price'] * (1 + (float)($item['vat_rate'] ?? 5) / 100), 3) ?>"></td>
<td>
<?php if ($item['image_path']): ?>
<img src="<?= htmlspecialchars($item['image_path']) ?>" alt="item" style="width: 40px; height: 40px; object-fit: cover;" class="rounded">
@ -2839,7 +2873,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<div class="btn-group btn-group-sm">
<button class="btn btn-outline-info" title="View" data-bs-toggle="modal" data-bs-target="#viewItemModal<?= $item['id'] ?>"><i class="bi bi-eye"></i></button>
<button class="btn btn-outline-primary" title="Edit" data-bs-toggle="modal" data-bs-target="#editItemModal<?= $item['id'] ?>"><i class="bi bi-pencil"></i></button>
<button class="btn btn-outline-dark" title="Barcode" onclick="printItemBarcode('<?= htmlspecialchars($item['sku']) ?>', '<?= htmlspecialchars($item['name_en']) ?>', '<?= number_format((float)$item['sale_price'], 3) ?>')"><i class="bi bi-upc"></i></button>
<button class="btn btn-outline-dark" title="Barcode" onclick="printItemBarcode('<?= htmlspecialchars($item['sku']) ?>', '<?= htmlspecialchars($item['name_en'] . ' - ' . $item['name_ar']) ?>', '<?= number_format((float)$item['sale_price'] * (1 + (float)($item['vat_rate'] ?? 5) / 100), 3) ?>')"><i class="bi bi-upc"></i></button>
<form method="POST" class="d-inline" onsubmit="return confirm('Are you sure?')">
<input type="hidden" name="id" value="<?= $item['id'] ?>">
<button type="submit" name="delete_item" class="btn btn-outline-danger" title="Delete"><i class="bi bi-trash"></i></button>
@ -2874,7 +2908,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
</table>
</div>
<div class="modal-footer">
<button class="btn btn-outline-dark" onclick="printItemBarcode('<?= htmlspecialchars($item['sku']) ?>', '<?= htmlspecialchars($item['name_en']) ?>', '<?= number_format((float)$item['sale_price'], 3) ?>')"><i class="bi bi-printer"></i> Print Barcode</button>
<button class="btn btn-outline-dark" onclick="printItemBarcode('<?= htmlspecialchars($item['sku']) ?>', '<?= htmlspecialchars($item['name_en'] . ' - ' . $item['name_ar']) ?>', '<?= number_format((float)$item['sale_price'] * (1 + (float)($item['vat_rate'] ?? 5) / 100), 3) ?>')"><i class="bi bi-printer"></i> Print Barcode</button>
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Close</button>
</div>
</div>
@ -3376,7 +3410,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
const totalVat = this.items.reduce((sum, item) => {
const price = parseFloat(item.price) || 0;
const qty = parseFloat(item.qty) || 0;
const vatRate = item.vatRate || 5;
const vatRate = (item.vatRate !== undefined && item.vatRate !== null) ? item.vatRate : 5;
return sum + (price * qty * (vatRate / (100 + vatRate)));
}, 0);
let discountAmount = 0;
@ -3395,7 +3429,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
items: this.items.map(i => {
const price = parseFloat(i.price) || 0;
const qty = parseFloat(i.qty) || 0;
const vatRate = i.vatRate || 5;
const vatRate = (i.vatRate !== undefined && i.vatRate !== null) ? i.vatRate : 5;
const vatAmount = price * qty * (vatRate / (100 + vatRate));
return {
name: (document.documentElement.lang === 'ar' ? (i.nameAr || i.nameEn) : (i.nameEn || i.nameAr)) || 'Unknown Item',
@ -3680,7 +3714,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
const qty = parseFloat(item.qty) || 0;
const itemTotal = price * qty;
subtotal += itemTotal;
const vatRate = item.vatRate || 5;
const vatRate = (item.vatRate !== undefined && item.vatRate !== null) ? item.vatRate : 5;
const itemVat = itemTotal * (vatRate / (100 + vatRate));
totalVat += itemVat;
const displayName = (lang === 'ar' ? (item.nameAr || item.nameEn) : (item.nameEn || item.nameAr)) || 'Unknown Item';
@ -3850,10 +3884,16 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
},
renderPayments() {
const container = document.getElementById('paymentList');
const methodLabels = {
'cash': 'Cash',
'card': 'Credit Card',
'credit': 'Credit',
'transfer': 'Bank Transfer'
};
container.innerHTML = this.payments.map((p, i) => `
<div class="payment-line">
<div>
<span class="method">${p.method}</span>
<span class="method">${methodLabels[p.method] || p.method}</span>
<span class="ms-2 badge bg-secondary small"><?= __('currency') ?> ${p.amount.toFixed(3)}</span>
</div>
<button class="btn btn-sm btn-outline-danger border-0" onclick="cart.removePaymentLine(${i})">
@ -3937,6 +3977,10 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
btn.innerText = 'PROCESSING...';
const subtotal = this.items.reduce((sum, item) => sum + (parseFloat(item.price) * item.qty), 0);
const totalVat = this.items.reduce((sum, item) => {
const vatRate = (item.vatRate !== undefined && item.vatRate !== null) ? item.vatRate : 5;
return sum + ((parseFloat(item.price) * item.qty) * (vatRate / (100 + vatRate)));
}, 0);
let discountAmount = 0;
if (this.discount) {
discountAmount = this.discount.type === 'percentage' ? subtotal * (parseFloat(this.discount.value) / 100) : parseFloat(this.discount.value);
@ -3949,10 +3993,15 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
formData.append('customer_id', customerId);
formData.append('payments', JSON.stringify(this.payments));
formData.append('total_amount', subtotal);
formData.append('tax_amount', totalVat);
formData.append('discount_code_id', this.discount ? this.discount.id : '');
formData.append('discount_amount', discountAmount);
formData.append('loyalty_redeemed', loyaltyRedeemed);
formData.append('items', JSON.stringify(this.items.map(i => ({id: i.id, qty: i.qty, price: i.price}))));
formData.append('items', JSON.stringify(this.items.map(i => {
const vr = (i.vatRate !== undefined && i.vatRate !== null) ? i.vatRate : 5;
const va = (parseFloat(i.price) * i.qty) * (vr / (100 + vr));
return {id: i.id, qty: i.qty, price: i.price, vat_rate: vr, vat_amount: va};
})));
try {
const resp = await fetch('index.php', { method: 'POST', body: formData });
@ -3987,8 +4036,8 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
const customerName = (customerSelect && customerSelect.selectedIndex >= 0 && customerSelect.value !== '') ? customerSelect.options[customerSelect.selectedIndex].text : '<?= $translations['ar']['walk_in_customer'] ?> / <?= $translations['en']['walk_in_customer'] ?>';
const paymentsHtml = this.payments.map(p => {
let m = p.method.toLowerCase();
let methodAr = m === 'cash' ? 'نقد' : (m === 'card' ? 'بطاقة' : (m === 'credit' ? 'آجل' : m));
let methodEn = m.charAt(0).toUpperCase() + m.slice(1);
let methodAr = m === 'cash' ? 'نقد' : (m === 'card' ? 'بطاقة ائتمان' : (m === 'credit' ? 'آجل' : (m === 'transfer' ? 'تحويل بنكي' : m)));
let methodEn = m === 'cash' ? 'Cash' : (m === 'card' ? 'Credit Card' : (m === 'credit' ? 'Credit' : (m === 'transfer' ? 'Bank Transfer' : m.charAt(0).toUpperCase() + m.slice(1))));
return `
<div class="d-flex justify-content-between small">
<span class="text-uppercase">${methodAr} / ${methodEn}</span>
@ -4000,7 +4049,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
let itemsHtml = this.items.map(item => {
const itemTotal = item.price * item.qty;
const vatRate = item.vatRate || 5; // Default to 5 if not set
const vatRate = (item.vatRate !== undefined && item.vatRate !== null) ? item.vatRate : 5; // Default to 5 if not set
const vatAmount = itemTotal * (vatRate / (100 + vatRate));
const exclVat = itemTotal - vatAmount;
return `
@ -4018,7 +4067,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
const subtotal = this.items.reduce((sum, item) => sum + (item.price * item.qty), 0);
const totalVat = this.items.reduce((sum, item) => {
const vatRate = item.vatRate || 5;
const vatRate = (item.vatRate !== undefined && item.vatRate !== null) ? item.vatRate : 5;
return sum + ((item.price * item.qty) * (vatRate / (100 + vatRate)));
}, 0);
const total = subtotal - discountAmount - loyaltyRedeemed;
@ -6995,7 +7044,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<div class="card p-4 rounded-4 shadow-sm border-0 mb-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h5 class="m-0 fw-bold text-primary" data-en="Register Sessions" data-ar="جلسات الكاشير">Register Sessions</h5>
<h5 class="m-0 fw-bold text-primary"><span data-en="Register Sessions" data-ar="جلسات الكاشير">Register Sessions</span> (<?= count($data['sessions']) ?>)</h5>
<p class="text-muted small mb-0">Manage daily opening and closing of cash registers.</p>
</div>
<div>
@ -7030,6 +7079,50 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
</div>
<?php endif; ?>
<!-- Filter Form -->
<div class="card border-0 bg-light rounded-4 mb-4">
<div class="card-body">
<form action="index.php" method="GET" class="row g-3 align-items-end">
<input type="hidden" name="page" value="register_sessions">
<?php if (can('users_view')): ?>
<div class="col-md-3">
<label class="form-label small fw-bold" data-en="Cashier" data-ar="الكاشير">Cashier</label>
<select name="user_id" class="form-select rounded-3">
<option value="" data-en="All Cashiers" data-ar="كل الكاشير">All Cashiers</option>
<?php foreach ($data['users'] as $u): ?>
<option value="<?= $u['id'] ?>" <?= (isset($_GET['user_id']) && $_GET['user_id'] == $u['id']) ? 'selected' : '' ?>>
<?= htmlspecialchars($u['username']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
<div class="col-md-3">
<label class="form-label small fw-bold" data-en="Date From" data-ar="من تاريخ">Date From</label>
<input type="date" name="date_from" class="form-control rounded-3" value="<?= htmlspecialchars($_GET['date_from'] ?? '') ?>">
</div>
<div class="col-md-3">
<label class="form-label small fw-bold" data-en="Date To" data-ar="إلى تاريخ">Date To</label>
<input type="date" name="date_to" class="form-control rounded-3" value="<?= htmlspecialchars($_GET['date_to'] ?? '') ?>">
</div>
<div class="col-md-3">
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary rounded-3 w-100">
<i class="bi bi-filter me-1"></i> <span data-en="Filter" data-ar="تصفية">Filter</span>
</button>
<a href="index.php?page=register_sessions" class="btn btn-outline-secondary rounded-3 w-100">
<i class="bi bi-x-circle me-1"></i> <span data-en="Clear" data-ar="مسح">Clear</span>
</a>
</div>
</div>
</form>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead>
@ -7040,14 +7133,11 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<th data-en="Opened At" data-ar="وقت الفتح">Opened At</th>
<th data-en="Closed At" data-ar="وقت الإغلاق">Closed At</th>
<th data-en="Opening Bal." data-ar="رصيد الافتتاح">Opening Bal.</th>
<th data-en="Cash Sales" data-ar="مبيعات نقدية">Cash Sales</th>
<th data-en="Card Sales" data-ar="مبيعات الشبكة">Card Sales</th>
<th data-en="Transfer" data-ar="تحويل">Transfer</th>
<th data-en="Cash Sale" data-ar="مبيعات نقدية">Cash Sale</th>
<th data-en="Credit Card" data-ar="بطاقة ائتمان">Credit Card</th>
<th data-en="Credit" data-ar="آجل">Credit</th>
<th data-en="Total Sales" data-ar="إجمالي المبيعات">Total Sales</th>
<th data-en="Expected Cash" data-ar="النقد المتوقع">Expected Cash</th>
<th data-en="Actual Cash" data-ar="النقد الفعلي">Actual Cash</th>
<th data-en="Shortage" data-ar="النقص/الزيادة">Shortage</th>
<th data-en="Total Sale" data-ar="إجمالي المبيعات">Total Sale</th>
<th data-en="Balance" data-ar="الرصيد">Balance</th>
<th data-en="Status" data-ar="الحالة">Status</th>
<th class="text-end" data-en="Report" data-ar="تقرير">Report</th>
</tr>
@ -7082,11 +7172,8 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
?>
<td>OMR <?= number_format($c_total, 3) ?></td>
<td>OMR <?= number_format($cd_total, 3) ?></td>
<td>OMR <?= number_format($tr_total, 3) ?></td>
<td>OMR <?= number_format($cr_total, 3) ?></td>
<td class="fw-bold">OMR <?= number_format($t_sales, 3) ?></td>
<td>OMR <?= number_format($row_expected_cash, 3) ?></td>
<td>OMR <?= number_format((float)($s['cash_in_hand'] ?? 0), 3) ?></td>
<td>
<?php if ($s['status'] === 'closed'):
$diff = (float)($s['cash_in_hand'] ?? 0) - $row_expected_cash;
@ -7100,11 +7187,21 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<?= ucfirst($s['status']) ?>
</span>
</td>
<td class="text-end">
<button class="btn btn-sm btn-light rounded-circle" data-bs-toggle="modal" data-bs-target="#sessionReportModal<?= $s['id'] ?>"><i class="bi bi-file-earmark-text text-primary"></i></button>
<!-- Session Report Modal -->
<div class="modal fade" id="sessionReportModal<?= $s['id'] ?>" tabindex="-1">
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<!-- Modals outside loop for better structure -->
<?php foreach ($data['sessions'] as $s): ?>
<!-- Session Report Modal -->
<div class="modal fade" id="sessionReportModal<?= $s['id'] ?>" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content border-0 shadow">
<div class="modal-header">
@ -7162,12 +7259,26 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<span>Opening Balance:</span>
<span class="fw-bold">OMR <?= number_format((float)$s['opening_balance'], 3) ?></span>
</div>
<?php
// Additional totals
$extra_stmt = db()->prepare("SELECT SUM(tax_amount) as total_tax, SUM(discount_amount) as total_discount, SUM(net_amount) as total_net FROM pos_transactions WHERE register_session_id = ? AND status = 'completed'");
$extra_stmt->execute([$s['id']]);
$extra = $extra_stmt->fetch();
?>
<div class="d-flex justify-content-between mb-2 small text-muted">
<span>Tax Amount:</span>
<span>OMR <?= number_format((float)($extra['total_tax'] ?? 0), 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2 small text-muted">
<span>Discount:</span>
<span>OMR <?= number_format((float)($extra['total_discount'] ?? 0), 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2">
<span>Cash Sales:</span>
<span>Cash Sale:</span>
<span class="fw-bold">OMR <?= number_format($cash_sales, 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2">
<span>Credit Card Sales:</span>
<span>Credit Card:</span>
<span class="fw-bold">OMR <?= number_format($card_sales, 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2">
@ -7179,7 +7290,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<span class="fw-bold">OMR <?= number_format($bank_transfer_sales, 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2 border-top pt-2 mt-2 h6 text-primary">
<span>Total Sales:</span>
<span>Total Sale:</span>
<span class="fw-bold">OMR <?= number_format($total_sales, 3) ?></span>
</div>
</div>
@ -7193,7 +7304,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<span>OMR <?= number_format((float)$s['opening_balance'], 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2">
<span>(+) Cash Sales:</span>
<span>(+) Cash Sale:</span>
<span>OMR <?= number_format($cash_sales, 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2 border-top pt-2 mt-2 h6">
@ -7210,10 +7321,11 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
$shortage_class = $shortage < 0 ? 'text-danger' : ($shortage > 0 ? 'text-info' : 'text-success');
?>
<div class="d-flex justify-content-between mb-0 h5 mt-2 <?= $shortage_class ?>">
<span>Shortage / Overage:</span>
<span>Balance:</span>
<span class="fw-bold">OMR <?= number_format($shortage, 3) ?></span>
</div>
<?php endif; ?>
</div>
</div>
@ -7225,9 +7337,10 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<thead class="bg-light">
<tr>
<th>Time</th>
<th>Order #</th>
<th>Customer</th>
<th>Method</th>
<th>Order #</th>
<th>Customer</th>
<th>Items</th>
<th>Method</th>
<th class="text-end">Amount</th>
</tr>
</thead>
@ -7240,9 +7353,19 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
?>
<tr>
<td><?= date('H:i', strtotime($tx['created_at'])) ?></td>
<td><?= htmlspecialchars($tx['transaction_no']) ?></td>
<td><?= htmlspecialchars($tx['customer_name'] ?: 'Walk-in') ?></td>
<td class="text-capitalize small"><?= htmlspecialchars($tx['methods'] ?: '---') ?></td>
<td><?= htmlspecialchars($tx['transaction_no']) ?></td>
<td><?= htmlspecialchars($tx['customer_name'] ?: 'Walk-in') ?></td>
<td>
<?php
$items_stmt = db()->prepare("SELECT i.name_en, ti.quantity FROM pos_items ti JOIN stock_items i ON ti.item_id = i.id WHERE ti.transaction_id = ?");
$items_stmt->execute([$tx['id']]);
$items = $items_stmt->fetchAll();
foreach ($items as $item) {
echo "<small class='d-block'>" . htmlspecialchars($item['name_en']) . " x " . (float)$item['quantity'] . "</small>";
}
?>
</td>
<td class="text-capitalize small"><?= htmlspecialchars($tx['methods'] ?: '---') ?></td>
<td class="text-end"><?= number_format($tx['net_amount'], 3) ?></td>
</tr>
<?php endforeach; if(empty($txs)): ?>
@ -7272,13 +7395,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
</div>
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php endforeach; ?>
<!-- Open Register Modal -->
<div class="modal fade" id="openRegisterModal" tabindex="-1">
@ -9273,7 +9390,7 @@ document.addEventListener('DOMContentLoaded', function() {
<label class="form-label fw-bold" data-en="Payment Type" data-ar="طريقة الدفع">Payment Type</label>
<select name="payment_type" class="form-select">
<option value="cash">Cash</option>
<option value="card">Card</option>
<option value="card">Credit Card</option>
<option value="bank_transfer">Bank Transfer</option>
<option value="credit">Credit</option>
</select>
@ -9373,7 +9490,7 @@ document.addEventListener('DOMContentLoaded', function() {
<label class="form-label fw-bold" data-en="Payment Type" data-ar="طريقة الدفع">Payment Type</label>
<select name="payment_type" id="edit_payment_type" class="form-select">
<option value="cash">Cash</option>
<option value="card">Card</option>
<option value="card">Credit Card</option>
<option value="bank_transfer">Bank Transfer</option>
<option value="credit">Credit</option>
</select>
@ -9900,7 +10017,7 @@ document.addEventListener('DOMContentLoaded', function() {
<label class="form-label fw-bold" data-en="Payment Method" data-ar="طريقة الدفع">Payment Method</label>
<select name="payment_method" class="form-select select2" required>
<option value="Cash">Cash</option>
<option value="Card">Card</option>
<option value="Card">Credit Card</option>
<option value="Bank Transfer">Bank Transfer</option>
</select>
</div>
@ -10044,7 +10161,7 @@ document.addEventListener('DOMContentLoaded', function() {
</div>
<div class="payment-method-btn" data-method="card" onclick="cart.selectMethod('card', this)">
<i class="bi bi-credit-card"></i>
<span class="small fw-bold">Card</span>
<span class="small fw-bold">Credit Card</span>
</div>
<div class="payment-method-btn" data-method="credit" onclick="cart.selectMethod('credit', this)">
<i class="bi bi-person-badge"></i>
@ -10052,7 +10169,7 @@ document.addEventListener('DOMContentLoaded', function() {
</div>
<div class="payment-method-btn" data-method="transfer" onclick="cart.selectMethod('transfer', this)">
<i class="bi bi-bank"></i>
<span class="small fw-bold">Transfer</span>
<span class="small fw-bold">Bank Transfer</span>
</div>
</div>
@ -10385,7 +10502,7 @@ document.addEventListener('DOMContentLoaded', function() {
const uniqueId = Math.random().toString(36).substr(2, 9);
const svgId = `bc-${sku}-${uniqueId}`;
label.innerHTML = `
<div style="font-size: 10px; font-weight: bold; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%;">${name}</div>
<div style="font-size: 9px; font-weight: bold; margin-bottom: 2px; line-height: 1.1; overflow: hidden; text-overflow: ellipsis; width: 100%;">${name}</div>
<svg id="${svgId}"></svg>
<div style="font-size: 11px; font-weight: bold; margin-top: 2px;">OMR ${price}</div>
`;
@ -10493,7 +10610,7 @@ document.addEventListener('DOMContentLoaded', function() {
padding: 1mm;
}
.label-container:last-child { page-break-after: avoid; }
.label-name { font-size: 10px; font-weight: bold; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.label-name { font-size: 9px; font-weight: bold; margin-bottom: 2px; line-height: 1.1; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.label-price { font-size: 12px; font-weight: bold; margin-top: 2px; }
svg { max-width: 100%; height: auto; max-height: 70%; display: block; }
</style>
@ -10629,7 +10746,7 @@ document.addEventListener('DOMContentLoaded', function() {
const container = document.getElementById('posReceiptContent');
const itemsHtml = inv.items.map(item => {
const itemTotal = item.unit_price * item.quantity;
const vatRate = parseFloat(item.vat_rate || 5);
const vatRate = parseFloat(item.vat_rate !== undefined && item.vat_rate !== null ? item.vat_rate : 5);
const vatAmount = itemTotal * (vatRate / (100 + vatRate));
return `
<tr>
@ -10642,7 +10759,7 @@ document.addEventListener('DOMContentLoaded', function() {
const totalVat = inv.items.reduce((sum, item) => {
const itemTotal = item.unit_price * item.quantity;
const vatRate = parseFloat(item.vat_rate || 5);
const vatRate = parseFloat(item.vat_rate !== undefined && item.vat_rate !== null ? item.vat_rate : 5);
return sum + (itemTotal * (vatRate / (100 + vatRate)));
}, 0);
const subtotal = inv.items.reduce((sum, item) => sum + (item.unit_price * item.quantity), 0);

View File

@ -74,3 +74,18 @@
2026-02-19 07:58:34 - POST: {"open_register":"1","register_id":"1","opening_balance":"11"}
2026-02-19 07:58:46 - POST: {"action":"save_pos_transaction","customer_id":"","payments":"[{\"method\":\"cash\",\"amount\":0.845}]","total_amount":"0.8450000000000001","discount_code_id":"","discount_amount":"0","loyalty_redeemed":"0","items":"[{\"id\":1,\"qty\":1,\"price\":0.3825},{\"id\":3,\"qty\":1,\"price\":0.25},{\"id\":2,\"qty\":1,\"price\":0.2125}]"}
2026-02-19 07:59:08 - POST: {"close_register":"1","session_id":"7","cash_in_hand":"13","notes":""}
2026-02-19 08:20:34 - POST: {"open_register":"1","register_id":"1","opening_balance":"12"}
2026-02-19 08:20:44 - POST: {"action":"save_pos_transaction","customer_id":"","payments":"[{\"method\":\"cash\",\"amount\":0.845}]","total_amount":"0.8450000000000001","discount_code_id":"","discount_amount":"0","loyalty_redeemed":"0","items":"[{\"id\":1,\"qty\":1,\"price\":0.3825},{\"id\":3,\"qty\":1,\"price\":0.25},{\"id\":2,\"qty\":1,\"price\":0.2125}]"}
2026-02-19 08:20:57 - POST: {"close_register":"1","session_id":"8","cash_in_hand":"14","notes":""}
2026-02-19 10:20:51 - POST: {"open_register":"1","register_id":"1","opening_balance":"22"}
2026-02-19 10:21:00 - POST: {"action":"save_pos_transaction","customer_id":"","payments":"[{\"method\":\"cash\",\"amount\":0.845}]","total_amount":"0.8450000000000001","discount_code_id":"","discount_amount":"0","loyalty_redeemed":"0","items":"[{\"id\":1,\"qty\":1,\"price\":0.3825},{\"id\":3,\"qty\":1,\"price\":0.25},{\"id\":2,\"qty\":1,\"price\":0.2125}]"}
2026-02-19 10:21:15 - POST: {"close_register":"1","session_id":"9","cash_in_hand":"10","notes":""}
2026-02-19 10:50:12 - POST: {"open_register":"1","register_id":"2","opening_balance":"10"}
2026-02-19 10:50:49 - POST: {"action":"save_pos_transaction","customer_id":"","payments":"[{\"method\":\"cash\",\"amount\":0.845}]","total_amount":"0.8450000000000001","discount_code_id":"","discount_amount":"0","loyalty_redeemed":"0","items":"[{\"id\":1,\"qty\":1,\"price\":0.3825},{\"id\":3,\"qty\":1,\"price\":0.25},{\"id\":2,\"qty\":1,\"price\":0.2125}]"}
2026-02-19 10:51:45 - POST: {"id":"3","name_en":"Tissue","name_ar":"\u0645\u062d\u0627\u0631\u0645 \u0648\u0631\u0642\u064a\u0629","category_id":"2","unit_id":"2","supplier_id":"6","sale_price":"0.25","purchase_price":"0.2","stock_quantity":"-4","min_stock_level":"0","sku":"760115926272","vat_rate":"0","promotion_start":"","promotion_end":"","promotion_percent":"0","edit_item":""}
2026-02-19 10:52:25 - POST: {"action":"save_pos_transaction","customer_id":"","payments":"[{\"method\":\"cash\",\"amount\":0.845}]","total_amount":"0.8450000000000001","discount_code_id":"","discount_amount":"0","loyalty_redeemed":"0","items":"[{\"id\":1,\"qty\":1,\"price\":0.3825},{\"id\":3,\"qty\":1,\"price\":0.25},{\"id\":2,\"qty\":1,\"price\":0.2125}]"}
2026-02-19 10:54:21 - POST: {"open_register":"1","register_id":"1","opening_balance":"5"}
2026-02-19 10:54:24 - POST: {"open_register":"1","register_id":"1","opening_balance":"5"}
2026-02-19 10:54:25 - POST: {"open_register":"1","register_id":"2","opening_balance":"5"}
2026-02-19 10:54:25 - POST: {"open_register":"1","register_id":"2","opening_balance":"5"}
2026-02-19 10:54:26 - POST: {"open_register":"1","register_id":"2","opening_balance":"5"}