359 lines
11 KiB
PHP
359 lines
11 KiB
PHP
<?php
|
|
// Ensure session is started
|
|
if (session_status() === PHP_SESSION_NONE) {
|
|
session_start();
|
|
}
|
|
include('../../routes/db_conn.php');
|
|
// Check for database connection
|
|
if (!isset($conn) || $conn->connect_error) {
|
|
error_log("Database connection failed: " . ($conn ? $conn->connect_error : "Connection not established"));
|
|
die("Database connection failed. Please try again later.");
|
|
}
|
|
|
|
// Set error reporting for debugging
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', 1);
|
|
ini_set('log_errors', 1);
|
|
ini_set('error_log', '../../logs/php-errors.log');
|
|
|
|
// Check if user is logged in, redirect to login page if not
|
|
if (!isset($_SESSION['user_id']) || !isset($_SESSION['role'])) {
|
|
// Check if this is an AJAX request
|
|
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
|
// Return JSON error for AJAX requests
|
|
header('Content-Type: application/json');
|
|
echo json_encode(['success' => false, 'message' => 'Session expired. Please login again.', 'redirect' => '/ayula-store/views/login/']);
|
|
exit;
|
|
} else {
|
|
// Redirect for regular requests
|
|
header('Location: /ayula-store/views/login/');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// Set variables for use throughout the application
|
|
$userRole = $_SESSION['role'] ?? ''; // 'user' or 'admin'
|
|
$username = $_SESSION['username'] ?? 'Unknown User';
|
|
$isAdmin = ($userRole === 'admin');
|
|
// Function to get all product types
|
|
function getProductTypes() {
|
|
global $conn;
|
|
|
|
$sql = "SELECT * FROM jenis_barang ORDER BY nama_jenis ASC";
|
|
$result = mysqli_query($conn, $sql);
|
|
|
|
$types = [];
|
|
if ($result && mysqli_num_rows($result) > 0) {
|
|
while ($row = mysqli_fetch_assoc($result)) {
|
|
$types[] = $row;
|
|
}
|
|
}
|
|
|
|
return $types;
|
|
}
|
|
|
|
// Function to get product by ID
|
|
function getProductById($productId) {
|
|
global $conn;
|
|
|
|
$sql = "SELECT b.*, j.nama_jenis
|
|
FROM barang_kasir b
|
|
LEFT JOIN jenis_barang j ON b.id_jenis = j.id_jenis
|
|
WHERE b.id_barangK = ?";
|
|
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
if (!$stmt) {
|
|
error_log("Error preparing statement: " . mysqli_error($conn));
|
|
return null;
|
|
}
|
|
|
|
mysqli_stmt_bind_param($stmt, "i", $productId);
|
|
mysqli_stmt_execute($stmt);
|
|
$result = mysqli_stmt_get_result($stmt);
|
|
|
|
if ($result && mysqli_num_rows($result) > 0) {
|
|
return mysqli_fetch_assoc($result);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// Function to get product by barcode
|
|
function getProductByBarcode($barcode) {
|
|
global $conn;
|
|
|
|
$sql = "SELECT b.*, j.nama_jenis
|
|
FROM barang_kasir b
|
|
LEFT JOIN jenis_barang j ON b.id_jenis = j.id_jenis
|
|
WHERE b.kode_barang = ?";
|
|
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
if (!$stmt) {
|
|
error_log("Error preparing statement: " . mysqli_error($conn));
|
|
return null;
|
|
}
|
|
|
|
mysqli_stmt_bind_param($stmt, "s", $barcode);
|
|
mysqli_stmt_execute($stmt);
|
|
$result = mysqli_stmt_get_result($stmt);
|
|
|
|
if ($result && mysqli_num_rows($result) > 0) {
|
|
return mysqli_fetch_assoc($result);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// Function to get products by type and search query
|
|
function getProducts($typeId = null, $searchQuery = '') {
|
|
global $conn;
|
|
|
|
$sql = "SELECT b.*, j.nama_jenis
|
|
FROM barang_kasir b
|
|
LEFT JOIN jenis_barang j ON b.id_jenis = j.id_jenis
|
|
WHERE 1=1";
|
|
|
|
$params = [];
|
|
$types = "";
|
|
|
|
if ($typeId) {
|
|
$sql .= " AND b.id_jenis = ?";
|
|
$params[] = $typeId;
|
|
$types .= "i";
|
|
}
|
|
|
|
if (!empty($searchQuery)) {
|
|
$searchPattern = "%$searchQuery%";
|
|
$sql .= " AND (b.nama_barang LIKE ? OR b.kode_barang LIKE ?)";
|
|
$params[] = $searchPattern;
|
|
$params[] = $searchPattern;
|
|
$types .= "ss";
|
|
}
|
|
|
|
$sql .= " ORDER BY b.nama_barang ASC";
|
|
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
if (!$stmt) {
|
|
error_log("Error preparing statement: " . mysqli_error($conn));
|
|
return [];
|
|
}
|
|
|
|
if (!empty($params)) {
|
|
mysqli_stmt_bind_param($stmt, $types, ...$params);
|
|
}
|
|
|
|
mysqli_stmt_execute($stmt);
|
|
$result = mysqli_stmt_get_result($stmt);
|
|
|
|
$products = [];
|
|
if ($result && mysqli_num_rows($result) > 0) {
|
|
while ($row = mysqli_fetch_assoc($result)) {
|
|
$products[] = $row;
|
|
}
|
|
}
|
|
|
|
return $products;
|
|
}
|
|
|
|
/**
|
|
* Create a new transaction in the database
|
|
*
|
|
* @param array $items Array of item data with product_id and quantity
|
|
* @param float $total Total amount of the transaction
|
|
* @param float $cashAmount Cash amount received
|
|
* @param float $changeAmount Change amount to return
|
|
* @return array Result with success status and transaction_id if successful
|
|
*/
|
|
function createTransaction($items, $total, $cashAmount, $changeAmount) {
|
|
global $conn;
|
|
|
|
// Start transaction for database consistency
|
|
mysqli_begin_transaction($conn);
|
|
|
|
try {
|
|
// Log values for debugging
|
|
error_log("Creating transaction with total: $total, cash: $cashAmount, change: $changeAmount");
|
|
error_log("Items: " . json_encode($items));
|
|
|
|
// Get current user ID from session
|
|
$userId = isset($_SESSION['id_kasir']) ? $_SESSION['id_kasir'] : null;
|
|
|
|
if (!$userId) {
|
|
error_log("No user ID in session, using default user ID 1");
|
|
// For testing purposes, use a default user ID
|
|
$userId = 1;
|
|
}
|
|
|
|
// Count total items
|
|
$totalItems = 0;
|
|
foreach ($items as $item) {
|
|
$totalItems += $item['quantity'];
|
|
}
|
|
|
|
// Calculate subtotal (same as total for now, but could be different if discounts applied)
|
|
$subtotal = $total;
|
|
|
|
// Generate transaction code
|
|
$transactionCode = 'TRX-' . date('YmdHis') . '-' . rand(1000, 9999);
|
|
|
|
// Insert into transaksi table
|
|
$sql = "INSERT INTO transaksi (kode_transaksi, tanggal, total_item, subtotal, total, cash_amount, change_amount, created_at)
|
|
VALUES (?, NOW(), ?, ?, ?, ?, ?, NOW())";
|
|
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
|
|
if (!$stmt) {
|
|
throw new Exception("Database error: " . mysqli_error($conn));
|
|
}
|
|
|
|
mysqli_stmt_bind_param($stmt, "sidddd", $transactionCode, $totalItems, $subtotal, $total, $cashAmount, $changeAmount);
|
|
|
|
if (!mysqli_stmt_execute($stmt)) {
|
|
throw new Exception("Failed to create transaction: " . mysqli_stmt_error($stmt));
|
|
}
|
|
|
|
// Get the transaction ID
|
|
$transactionId = mysqli_insert_id($conn);
|
|
|
|
if (!$transactionId) {
|
|
throw new Exception("Failed to get transaction ID");
|
|
}
|
|
|
|
// Log transaction ID
|
|
error_log("Transaction created with ID: $transactionId");
|
|
|
|
// Insert items into detail_transaksi table
|
|
foreach ($items as $item) {
|
|
// Get product details
|
|
$product = getProductById($item['product_id']);
|
|
|
|
if (!$product) {
|
|
throw new Exception("Product not found: " . $item['product_id']);
|
|
}
|
|
|
|
// Calculate subtotal
|
|
$itemTotal = floatval($product['harga']) * $item['quantity'];
|
|
|
|
// Insert into detail_transaksi
|
|
$sql = "INSERT INTO detail_transaksi (id_transaksi, id_barangK, jumlah, harga_satuan, total_harga, created_at)
|
|
VALUES (?, ?, ?, ?, ?, NOW())";
|
|
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
|
|
if (!$stmt) {
|
|
throw new Exception("Database error: " . mysqli_error($conn));
|
|
}
|
|
|
|
mysqli_stmt_bind_param($stmt, "iiidd", $transactionId, $item['product_id'], $item['quantity'], $product['harga'], $itemTotal);
|
|
|
|
if (!mysqli_stmt_execute($stmt)) {
|
|
throw new Exception("Failed to add transaction detail: " . mysqli_stmt_error($stmt));
|
|
}
|
|
|
|
// Update product stock
|
|
$newStock = $product['stok'] - $item['quantity'];
|
|
|
|
if ($newStock < 0) {
|
|
throw new Exception("Insufficient stock for product: " . $product['nama_barang']);
|
|
}
|
|
|
|
$sql = "UPDATE barang_kasir SET stok = ? WHERE id_barangK = ?";
|
|
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
|
|
if (!$stmt) {
|
|
throw new Exception("Database error: " . mysqli_error($conn));
|
|
}
|
|
|
|
mysqli_stmt_bind_param($stmt, "ii", $newStock, $item['product_id']);
|
|
|
|
if (!mysqli_stmt_execute($stmt)) {
|
|
throw new Exception("Failed to update product stock: " . mysqli_stmt_error($stmt));
|
|
}
|
|
}
|
|
|
|
// Commit transaction
|
|
mysqli_commit($conn);
|
|
|
|
// Return success response
|
|
return [
|
|
'success' => true,
|
|
'transaction_id' => $transactionId,
|
|
'code' => $transactionCode,
|
|
'items' => count($items),
|
|
'total' => $total,
|
|
'cash_amount' => $cashAmount,
|
|
'change_amount' => $changeAmount
|
|
];
|
|
|
|
} catch (Exception $e) {
|
|
// Rollback transaction on error
|
|
mysqli_rollback($conn);
|
|
|
|
// Log error
|
|
error_log("Transaction creation failed: " . $e->getMessage());
|
|
|
|
// Return error response
|
|
return [
|
|
'success' => false,
|
|
'message' => $e->getMessage()
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get transaction by ID with details
|
|
*
|
|
* @param int $transactionId Transaction ID
|
|
* @return array|null Transaction data with items or null if not found
|
|
*/
|
|
function getTransactionById($transactionId) {
|
|
global $conn;
|
|
|
|
// Get transaction data
|
|
$sql = "SELECT t.* FROM transaksi t
|
|
WHERE t.id_transaksi = ?";
|
|
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
if (!$stmt) {
|
|
error_log("Error preparing statement: " . mysqli_error($conn));
|
|
return null;
|
|
}
|
|
|
|
mysqli_stmt_bind_param($stmt, "i", $transactionId);
|
|
mysqli_stmt_execute($stmt);
|
|
$result = mysqli_stmt_get_result($stmt);
|
|
|
|
if (!$result || mysqli_num_rows($result) == 0) {
|
|
return null;
|
|
}
|
|
|
|
$transaction = mysqli_fetch_assoc($result);
|
|
|
|
// Get transaction details (items)
|
|
$sql = "SELECT d.*, b.nama_barang, b.kode_barang
|
|
FROM detail_transaksi d
|
|
LEFT JOIN barang_kasir b ON d.id_barangK = b.id_barangK
|
|
WHERE d.id_transaksi = ?";
|
|
|
|
$stmt = mysqli_prepare($conn, $sql);
|
|
if (!$stmt) {
|
|
error_log("Error preparing statement: " . mysqli_error($conn));
|
|
return $transaction;
|
|
}
|
|
|
|
mysqli_stmt_bind_param($stmt, "i", $transactionId);
|
|
mysqli_stmt_execute($stmt);
|
|
$result = mysqli_stmt_get_result($stmt);
|
|
|
|
$items = [];
|
|
if ($result && mysqli_num_rows($result) > 0) {
|
|
while ($row = mysqli_fetch_assoc($result)) {
|
|
$items[] = $row;
|
|
}
|
|
}
|
|
|
|
$transaction['items'] = $items;
|
|
|
|
return $transaction;
|
|
} |