update pos
This commit is contained in:
parent
3f1e18552b
commit
275baf63cd
@ -14,6 +14,7 @@ $customer_id = $input['customer_id'] ?: null;
|
||||
$items = $input['items'] ?? [];
|
||||
$vat_total = (float)($input['vat_total'] ?? 0);
|
||||
$total_price = (float)($input['total_price'] ?? 0);
|
||||
$payment_method = $input['payment_method'] ?? null;
|
||||
$branch_id = $_SESSION['branch_id'];
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
@ -26,10 +27,12 @@ try {
|
||||
$pdo = db();
|
||||
$pdo->beginTransaction();
|
||||
|
||||
$payment_status = ($payment_method && $payment_method !== 'pay_later') ? 'paid' : 'unpaid';
|
||||
|
||||
if ($order_id) {
|
||||
// Update existing order
|
||||
$stmt = $pdo->prepare("UPDATE orders SET customer_id = ?, total_price = ?, vat_total = ? WHERE id = ? AND branch_id = ?");
|
||||
$stmt->execute([$customer_id, $total_price, $vat_total, $order_id, $branch_id]);
|
||||
$stmt = $pdo->prepare("UPDATE orders SET customer_id = ?, total_price = ?, vat_total = ?, payment_status = ? WHERE id = ? AND branch_id = ?");
|
||||
$stmt->execute([$customer_id, $total_price, $vat_total, $payment_status, $order_id, $branch_id]);
|
||||
|
||||
// Remove existing items
|
||||
$stmt = $pdo->prepare("DELETE FROM order_items WHERE order_id = ?");
|
||||
@ -37,8 +40,8 @@ try {
|
||||
} else {
|
||||
// Create new order
|
||||
$stmt = $pdo->prepare("INSERT INTO orders (branch_id, customer_id, user_id, order_number, total_price, vat_total, status, payment_status)
|
||||
VALUES (?, ?, ?, NULL, ?, ?, 'received', 'unpaid')");
|
||||
$stmt->execute([$branch_id, $customer_id, $user_id, $total_price, $vat_total]);
|
||||
VALUES (?, ?, ?, NULL, ?, ?, 'received', ?)");
|
||||
$stmt->execute([$branch_id, $customer_id, $user_id, $total_price, $vat_total, $payment_status]);
|
||||
$order_id = $pdo->lastInsertId();
|
||||
|
||||
// Get branch prefix
|
||||
@ -49,14 +52,12 @@ try {
|
||||
$prefix = strtoupper(str_pad($prefix, 3, 'X'));
|
||||
|
||||
// Determine the next serial number for this branch
|
||||
// We look at existing order numbers for this branch that follow the XXX-###### format
|
||||
$stmt_max = $pdo->prepare("SELECT order_number FROM orders WHERE branch_id = ? AND order_number LIKE ? ORDER BY id DESC LIMIT 100");
|
||||
$stmt_max->execute([$branch_id, "$prefix-%"]);
|
||||
$existing_orders = $stmt_max->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
$max_serial = 0;
|
||||
foreach ($existing_orders as $onum) {
|
||||
// Format is XXX-######.
|
||||
if (preg_match('/' . preg_quote($prefix) . '-(\d{6})/', $onum, $matches)) {
|
||||
$serial = (int)$matches[1];
|
||||
if ($serial > $max_serial) $max_serial = $serial;
|
||||
@ -88,6 +89,12 @@ try {
|
||||
]);
|
||||
}
|
||||
|
||||
// Handle Payment recording
|
||||
if ($payment_method && $payment_method !== 'pay_later') {
|
||||
$stmt_payment = $pdo->prepare("INSERT INTO payments (order_id, amount, payment_method) VALUES (?, ?, ?)");
|
||||
$stmt_payment->execute([$order_id, $total_price, $payment_method]);
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
echo json_encode(['success' => true, 'order_id' => $order_id]);
|
||||
} catch (Exception $e) {
|
||||
|
||||
90
pos.php
90
pos.php
@ -288,6 +288,48 @@ $pageTitle = $edit_order ? ($lang == 'en' ? 'Edit Order #' . $edit_order['order_
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payment Modal -->
|
||||
<div class="modal fade" id="paymentModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content border-0 rounded-4 shadow-lg">
|
||||
<div class="modal-header border-0 pb-0">
|
||||
<h5 class="modal-title fw-bold"><?= $lang == 'en' ? 'Payment' : 'الدفع' ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body p-4">
|
||||
<div class="text-center mb-4">
|
||||
<h3 class="fw-bold text-primary mb-1" id="paymentTotalAmount">0.000</h3>
|
||||
<div class="text-muted small"><?= $lang == 'en' ? 'Total Amount' : 'المبلغ الإجمالي' ?></div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-6">
|
||||
<button class="btn btn-outline-primary w-100 py-3 rounded-3 d-flex flex-column align-items-center" onclick="completeCheckout('cash')">
|
||||
<i class="bi bi-cash-stack mb-1 fs-4"></i>
|
||||
<span class="small fw-bold"><?= $lang == 'en' ? 'Cash' : 'نقداً' ?></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button class="btn btn-outline-primary w-100 py-3 rounded-3 d-flex flex-column align-items-center" onclick="completeCheckout('card')">
|
||||
<i class="bi bi-credit-card mb-1 fs-4"></i>
|
||||
<span class="small fw-bold"><?= $lang == 'en' ? 'Card' : 'بطاقة' ?></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-outline-secondary w-100 py-3 rounded-3 d-flex flex-column align-items-center" onclick="completeCheckout('pay_later')">
|
||||
<i class="bi bi-clock-history mb-1 fs-4"></i>
|
||||
<span class="small fw-bold"><?= $lang == 'en' ? 'Pay Later' : 'الدفع لاحقاً' ?></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hidden Iframe for Printing -->
|
||||
<iframe id="printFrame" style="display:none;"></iframe>
|
||||
|
||||
<script>
|
||||
const itemsData = <?= json_encode((object)$items) ?>;
|
||||
const lang = '<?= $lang ?>';
|
||||
@ -296,6 +338,7 @@ const decimalPrecision = <?= decimals() ?>;
|
||||
const editOrderId = <?= $edit_order_id ?: 'null' ?>;
|
||||
let cart = <?= json_encode($edit_items) ?>;
|
||||
let selectionModal;
|
||||
let paymentModal;
|
||||
|
||||
// If not editing, try to load from local storage
|
||||
if (!editOrderId) {
|
||||
@ -312,6 +355,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
if (typeof bootstrap !== 'undefined') {
|
||||
const modalEl = document.getElementById('selectionModal');
|
||||
if (modalEl) selectionModal = new bootstrap.Modal(modalEl);
|
||||
|
||||
const payModalEl = document.getElementById('paymentModal');
|
||||
if (payModalEl) paymentModal = new bootstrap.Modal(payModalEl);
|
||||
}
|
||||
|
||||
// Category filtering
|
||||
@ -527,14 +573,25 @@ function clearCart() {
|
||||
}
|
||||
}
|
||||
|
||||
async function checkout() {
|
||||
function checkout() {
|
||||
if (cart.length === 0) return;
|
||||
|
||||
let total = 0;
|
||||
cart.forEach(item => {
|
||||
const itemSubtotal = item.price * item.qty;
|
||||
total += itemSubtotal + (itemSubtotal * ((item.vat_percent || 15) / 100));
|
||||
});
|
||||
|
||||
document.getElementById('paymentTotalAmount').innerText = total.toFixed(decimalPrecision) + ' ' + currencyLabel;
|
||||
if (paymentModal) paymentModal.show();
|
||||
}
|
||||
|
||||
async function completeCheckout(paymentMethod) {
|
||||
const cid = document.getElementById('customerId').value;
|
||||
|
||||
let subtotal = 0;
|
||||
let totalVat = 0;
|
||||
|
||||
// Map cart items to the keys expected by checkout.php
|
||||
const itemsToSubmit = cart.map(item => {
|
||||
const itemSubtotal = item.price * item.qty;
|
||||
const itemVat = itemSubtotal * ((item.vat_percent || 15) / 100);
|
||||
@ -552,6 +609,8 @@ async function checkout() {
|
||||
};
|
||||
});
|
||||
|
||||
const totalPrice = subtotal + totalVat;
|
||||
|
||||
try {
|
||||
const response = await fetch('api/checkout.php', {
|
||||
method: 'POST',
|
||||
@ -561,20 +620,43 @@ async function checkout() {
|
||||
customer_id: cid,
|
||||
items: itemsToSubmit,
|
||||
vat_total: totalVat,
|
||||
total_price: subtotal + totalVat
|
||||
total_price: totalPrice,
|
||||
payment_method: paymentMethod
|
||||
})
|
||||
});
|
||||
const res = await response.json();
|
||||
if (res.success) {
|
||||
const orderId = res.order_id || editOrderId;
|
||||
|
||||
// Direct Print
|
||||
printReceipt(orderId);
|
||||
|
||||
if (!editOrderId) {
|
||||
cart = [];
|
||||
updateCart();
|
||||
localStorage.removeItem('pos_cart');
|
||||
}
|
||||
window.location.href = 'order_details.php?id=' + (res.order_id || editOrderId);
|
||||
|
||||
if (paymentModal) paymentModal.hide();
|
||||
|
||||
// Wait a bit for print dialog to start then redirect
|
||||
setTimeout(() => {
|
||||
window.location.href = 'pos.php';
|
||||
}, 2000);
|
||||
} else alert(res.error);
|
||||
} catch (e) { alert('Error'); }
|
||||
}
|
||||
|
||||
function printReceipt(orderId) {
|
||||
const iframe = document.getElementById('printFrame');
|
||||
iframe.src = 'receipt.php?id=' + orderId;
|
||||
|
||||
iframe.onload = function() {
|
||||
iframe.contentWindow.focus();
|
||||
iframe.contentWindow.print();
|
||||
};
|
||||
}
|
||||
|
||||
async function saveCustomer() {
|
||||
const form = document.getElementById('addCustomerForm');
|
||||
if (!form) return;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user