35607-vm/pos.php
Flatlogic Bot 9b5a06451f SInarKasih
2025-11-10 04:11:47 +00:00

197 lines
7.9 KiB
PHP

<?php
require_once 'includes/auth.php';
require_login();
require_once 'db/config.php';
require_once __DIR__ . '/includes/header.php';
try {
$stmt = db()->query("SELECT id, name, price, stock FROM products ORDER BY name ASC");
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("Error fetching products: " . $e->getMessage());
}
?>
<div class="container-fluid mt-4">
<div class="row">
<!-- Product Selection -->
<div class="col-md-7">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Products</h5>
</div>
<div class="card-body">
<div class="row" id="product-grid">
<?php if (empty($products)): ?>
<div class="col-12">
<div class="alert alert-info">No products found. Please <a href="product_add.php">add a product</a> first.</div>
</div>
<?php else: ?>
<?php foreach ($products as $product): ?>
<div class="col-md-4 col-lg-3 mb-3">
<div class="card product-card h-100" onclick='addToCart(<?php echo htmlspecialchars(json_encode($product)); ?>)'>
<div class="card-body text-center">
<h6 class="card-title small"><?php echo htmlspecialchars($product['name']); ?></h6>
<p class="card-text small fw-bold">IDR <?php echo number_format($product['price'], 2); ?></p>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
</div>
<!-- Cart -->
<div class="col-md-5">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Cart</h5>
</div>
<div class="card-body">
<div id="cart-items" class="mb-3">
<p class="text-muted text-center">Cart is empty</p>
</div>
<hr>
<div class="d-flex justify-content-between align-items-center mb-2">
<h6 class="mb-0">Subtotal</h6>
<h6 class="mb-0" id="cart-subtotal">IDR 0.00</h6>
</div>
<div class="d-flex justify-content-between align-items-center mb-3">
<h5 class="mb-0">Total</h5>
<h5 class="mb-0" id="cart-total">IDR 0.00</h5>
</div>
<div class="mb-3">
<label for="payment-method" class="form-label">Payment Method</label>
<select id="payment-method" class="form-select">
<option>Cash</option>
<option>Card</option>
<option>QRIS</option>
</select>
</div>
<div class="d-grid">
<button class="btn btn-success btn-lg" id="checkout-btn" disabled>Checkout</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
const cart = [];
function formatCurrency(amount) {
return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', minimumFractionDigits: 2 }).format(amount);
}
function findCartItem(productId) {
return cart.find(item => item.id === productId);
}
function addToCart(product) {
let itemInCart = findCartItem(product.id);
if (itemInCart) {
itemInCart.quantity++;
} else {
cart.push({ id: product.id, name: product.name, price: product.price, quantity: 1 });
}
renderCart();
}
function updateQuantity(productId, change) {
let itemInCart = findCartItem(productId);
if (itemInCart) {
itemInCart.quantity += change;
if (itemInCart.quantity <= 0) {
const itemIndex = cart.findIndex(item => item.id === productId);
cart.splice(itemIndex, 1);
}
}
renderCart();
}
function renderCart() {
const cartItemsContainer = document.getElementById('cart-items');
const subtotalEl = document.getElementById('cart-subtotal');
const totalEl = document.getElementById('cart-total');
const checkoutBtn = document.getElementById('checkout-btn');
if (cart.length === 0) {
cartItemsContainer.innerHTML = '<p class="text-muted text-center">Cart is empty</p>';
subtotalEl.textContent = formatCurrency(0);
totalEl.textContent = formatCurrency(0);
checkoutBtn.disabled = true;
return;
}
cartItemsContainer.innerHTML = cart.map(item => `
<div class="d-flex justify-content-between align-items-center mb-2">
<div>
<h6 class="mb-0 small">${item.name}</h6>
<p class="mb-0 text-muted small">${formatCurrency(item.price)}</p>
</div>
<div class="d-flex align-items-center">
<button class="btn btn-sm btn-outline-secondary" onclick="updateQuantity(${item.id}, -1)">-</button>
<span class="mx-2">${item.quantity}</span>
<button class="btn btn-sm btn-outline-secondary" onclick="updateQuantity(${item.id}, 1)">+</button>
</div>
<h6 class="mb-0 small">${formatCurrency(item.price * item.quantity)}</h6>
</div>
`).join('');
const subtotal = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
subtotalEl.textContent = formatCurrency(subtotal);
totalEl.textContent = formatCurrency(subtotal); // Assuming no tax for now
checkoutBtn.disabled = false;
}
async function handleCheckout() {
const paymentMethod = document.getElementById('payment-method').value;
const checkoutBtn = document.getElementById('checkout-btn');
checkoutBtn.disabled = true;
checkoutBtn.textContent = 'Processing...';
try {
const response = await fetch('_handle_checkout.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ cart: cart, payment_method: paymentMethod })
});
const result = await response.json();
if (result.success) {
const cartContainer = document.querySelector('.col-md-5 .card-body');
cartContainer.innerHTML = `
<div class="text-center">
<h5 class="text-success">Checkout Successful!</h5>
<p>Transaction ID: ${result.transaction_id}</p>
<a href="receipt.php?sale_id=${result.transaction_id}" target="_blank" class="btn btn-primary">Print Receipt</a>
<button onclick="window.location.reload()" class="btn btn-secondary">New Sale</button>
</div>
`;
} else {
alert(`Error: ${result.message}`);
}
} catch (error) {
console.error('Checkout error:', error);
alert('An unexpected error occurred during checkout.');
} finally {
checkoutBtn.disabled = false;
checkoutBtn.textContent = 'Checkout';
}
}
document.getElementById('checkout-btn').addEventListener('click', handleCheckout);
</script>
<?php require_once 'includes/footer.php'; ?>