👁 查看:stock_deduct.php
路径:/home/boguraj1/public_html/isp/stock_deduct.php
大小:9.33 KB · 修改:2026-06-15 23:28:10 · 权限:0644 · 可写
<?php
session_start();
require_once 'includes/auth.php';
requireAdmin();
require_once 'config/db.php';

// Fetch all products
$all_products = $pdo->query(
    "SELECT id, name, current_stock, unit FROM products ORDER BY name ASC"
)->fetchAll();

// Pre-select product when coming from product list
$preselect_id = (int) ($_GET['product_id'] ?? 0);

$success = '';
$error   = '';

$form = [
    'product_id' => $preselect_id,
    'quantity'   => '',
    'notes'      => '',
];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $form['product_id'] = (int) ($_POST['product_id'] ?? 0);
    $form['quantity']   = trim($_POST['quantity'] ?? '');
    $form['notes']      = trim($_POST['notes'] ?? '');

    $quantity = (int) $form['quantity'];

    if ($form['product_id'] <= 0) {
        $error = 'Please select a product.';
    } elseif ($quantity <= 0) {
        $error = 'Quantity must be a positive number.';
    } else {
        // Fetch fresh product data (prevents race-condition on stock)
        $prod_stmt = $pdo->prepare("SELECT id, name, current_stock, unit FROM products WHERE id = ?");
        $prod_stmt->execute([$form['product_id']]);
        $product = $prod_stmt->fetch();

        if (!$product) {
            $error = 'Selected product not found.';
        } elseif ($quantity > $product['current_stock']) {
            $error = "Cannot deduct {$quantity} — only {$product['current_stock']} {$product['unit']}(s) in stock.";
        } else {
            // Decrease stock
            $pdo->prepare("UPDATE products SET current_stock = current_stock - ? WHERE id = ?")
                ->execute([$quantity, $product['id']]);

            // Log the transaction
            $pdo->prepare(
                "INSERT INTO stock_transactions (product_id, user_id, quantity, type, notes) VALUES (?, ?, ?, 'deducted', ?)"
            )->execute([$product['id'], $_SESSION['user_id'], $quantity, $form['notes']]);

            $remaining = $product['current_stock'] - $quantity;
            $success   = "Deducted {$quantity} {$product['unit']}(s) from \"{$product['name']}\". "
                       . "Remaining stock: {$remaining} {$product['unit']}(s).";

            // Refresh products
            $all_products = $pdo->query(
                "SELECT id, name, current_stock, unit FROM products ORDER BY name ASC"
            )->fetchAll();

            $form = ['product_id' => 0, 'quantity' => '', 'notes' => ''];
        }
    }
}

include 'includes/header.php';
?>

<div class="row mb-3">
    <div class="col">
        <h4 class="page-title"><i class="bi bi-dash-square me-2 text-danger"></i>Deduct Stock</h4>
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb">
                <li class="breadcrumb-item"><a href="dashboard.php">Dashboard</a></li>
                <li class="breadcrumb-item active">Deduct Stock</li>
            </ol>
        </nav>
    </div>
</div>

<div class="row justify-content-center">
    <div class="col-md-7 col-lg-6">
        <div class="card">
            <div class="card-header bg-danger text-white">
                <i class="bi bi-arrow-down-circle me-1"></i> Deduct / Use Stock
            </div>
            <div class="card-body">

                <?php if ($success !== ''): ?>
                <div class="alert alert-success d-flex align-items-start gap-2">
                    <i class="bi bi-check-circle-fill mt-1"></i>
                    <div>
                        <?= htmlspecialchars($success) ?>
                        <div class="mt-2 d-flex gap-2">
                            <a href="stock_deduct.php"  class="btn btn-sm btn-danger">Deduct More</a>
                            <a href="stock_history.php" class="btn btn-sm btn-outline-secondary">View History</a>
                        </div>
                    </div>
                </div>
                <?php endif; ?>

                <?php if ($error !== ''): ?>
                <div class="alert alert-danger d-flex align-items-center gap-2">
                    <i class="bi bi-exclamation-triangle-fill"></i>
                    <?= htmlspecialchars($error) ?>
                </div>
                <?php endif; ?>

                <?php if (empty($all_products)): ?>
                <div class="alert alert-info">
                    No products available. <a href="add_product.php">Add a product first</a>.
                </div>
                <?php else: ?>

                <form method="POST" action="" novalidate>

                    <div class="mb-3">
                        <label for="product_id" class="form-label fw-semibold">
                            Select Product <span class="text-danger">*</span>
                        </label>
                        <select class="form-select" id="product_id" name="product_id" required>
                            <option value="">-- Select a Product --</option>
                            <?php foreach ($all_products as $p): ?>
                            <option value="<?= $p['id'] ?>"
                                    data-stock="<?= $p['current_stock'] ?>"
                                    data-unit="<?= htmlspecialchars($p['unit']) ?>"
                                    <?= (int) $form['product_id'] === (int) $p['id'] ? 'selected' : '' ?>>
                                <?= htmlspecialchars($p['name']) ?>
                                (Stock: <?= number_format($p['current_stock']) ?> <?= $p['unit'] ?>)
                            </option>
                            <?php endforeach; ?>
                        </select>
                    </div>

                    <!-- Dynamic current stock display -->
                    <div class="mb-3">
                        <label class="form-label fw-semibold">Available Stock</label>
                        <div id="stock-display" class="form-control bg-light fw-bold text-success">
                            Select a product above
                        </div>
                    </div>

                    <div class="mb-3">
                        <label for="quantity" class="form-label fw-semibold">
                            Quantity to Deduct <span class="text-danger">*</span>
                        </label>
                        <input type="number"
                               class="form-control"
                               id="quantity"
                               name="quantity"
                               value="<?= htmlspecialchars($form['quantity']) ?>"
                               min="1"
                               placeholder="Enter quantity"
                               required>
                        <div id="qty-warning" class="form-text text-danger d-none">
                            Quantity exceeds available stock!
                        </div>
                    </div>

                    <div class="mb-4">
                        <label for="notes" class="form-label fw-semibold">Reason / Notes (Optional)</label>
                        <input type="text"
                               class="form-control"
                               id="notes"
                               name="notes"
                               value="<?= htmlspecialchars($form['notes']) ?>"
                               placeholder="e.g., Used for customer installation, Faulty unit">
                    </div>

                    <div class="d-grid gap-2">
                        <button type="submit" class="btn btn-danger fw-semibold" id="submitBtn">
                            <i class="bi bi-dash-circle me-1"></i> Deduct Stock
                        </button>
                        <a href="product_list.php" class="btn btn-outline-secondary">Cancel</a>
                    </div>

                </form>

                <?php endif; ?>
            </div>
        </div>
    </div>
</div>

<script>
(function () {
    const select  = document.getElementById('product_id');
    const display = document.getElementById('stock-display');
    const qtyInput  = document.getElementById('quantity');
    const warning   = document.getElementById('qty-warning');
    const submitBtn = document.getElementById('submitBtn');
    if (!select || !display) return;

    let currentStock = 0;

    function updateDisplay() {
        const opt = select.options[select.selectedIndex];
        if (opt && opt.dataset.stock !== undefined) {
            currentStock = parseInt(opt.dataset.stock, 10);
            const unit   = opt.dataset.unit;
            display.textContent = currentStock + ' ' + unit + '(s)';
            display.className = 'form-control bg-light fw-bold ' +
                (currentStock === 0 ? 'text-danger' : (currentStock < 10 ? 'text-warning' : 'text-success'));
        } else {
            currentStock = 0;
            display.textContent = 'Select a product above';
            display.className = 'form-control bg-light fw-bold text-success';
        }
        validateQty();
    }

    function validateQty() {
        if (!qtyInput || !warning || !submitBtn) return;
        const qty = parseInt(qtyInput.value, 10);
        if (qty > 0 && qty > currentStock) {
            warning.classList.remove('d-none');
            submitBtn.disabled = true;
        } else {
            warning.classList.add('d-none');
            submitBtn.disabled = false;
        }
    }

    select.addEventListener('change', updateDisplay);
    if (qtyInput) qtyInput.addEventListener('input', validateQty);
    updateDisplay();
}());
</script>

<?php include 'includes/footer.php'; ?>