34959-vm/daybook.php
Flatlogic Bot e428ea4534 v1
2025-10-14 17:08:20 +00:00

253 lines
10 KiB
PHP

<?php
require_once 'includes/header.php';
require_once 'db/config.php';
$message = '';
$error = '';
// Handle form submission
if (isset($_POST['save_readings'])) {
$date = $_POST['date'];
$prices = $_POST['prices'];
$readings = $_POST['readings'];
$pdo = db();
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare(
"INSERT INTO daybook_readings (date, nozzle_id, opening_reading, closing_reading, price)
VALUES (?, ?, ?, ?, ?)"
);
// Fetch fuel types for nozzles
$nozzle_fuel_types = [];
$nozzles_stmt = $pdo->query("
SELECT n.id, ft.fuel_name
FROM nozzles n
JOIN pumps p ON n.pump_id = p.id
JOIN tanks t ON p.tank_id = t.id
JOIN fuel_types ft ON t.fuel_type_id = ft.id
");
while ($row = $nozzles_stmt->fetch(PDO::FETCH_ASSOC)) {
$nozzle_fuel_types[$row['id']] = $row['fuel_name'];
}
foreach ($readings as $reading) {
$nozzle_id = $reading['nozzle_id'];
$opening = $reading['opening'];
$closing = $reading['closing'];
if ($closing < $opening) {
throw new Exception("Closing reading cannot be less than opening reading for one of the nozzles.");
}
$fuel_name = $nozzle_fuel_types[$nozzle_id] ?? null;
if (!$fuel_name || !isset($prices[$fuel_name])) {
throw new Exception("Could not determine price for nozzle ID: $nozzle_id");
}
$price = $prices[$fuel_name];
$stmt->execute([$date, $nozzle_id, $opening, $closing, $price]);
}
$pdo->commit();
$message = "Daybook readings saved successfully!";
} catch (PDOException $e) {
$pdo->rollBack();
if ($e->errorInfo[1] == 1062) { // Duplicate entry
$error = "Error: Daybook readings for this date and nozzle already exist.";
} else {
$error = "Database error: " . $e->getMessage();
}
} catch (Exception $e) {
$pdo->rollBack();
$error = "Error: " . $e->getMessage();
}
}
// Fetch previous day's closing readings to suggest as opening readings
$previous_day_readings = [];
if (isset($_GET['date'])) {
$current_date = $_GET['date'];
$previous_date = date('Y-m-d', strtotime($current_date . ' -1 day'));
$stmt = db()->prepare("SELECT nozzle_id, closing_reading FROM daybook_readings WHERE date = ?");
$stmt->execute([$previous_date]);
$readings = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($readings as $reading) {
$previous_day_readings[$reading['nozzle_id']] = $reading['closing_reading'];
}
}
// Fetch nozzles and their associated fuel types
$nozzles_stmt = db()->query("
SELECT n.id, n.nozzle_number, ft.fuel_name
FROM nozzles n
JOIN pumps p ON n.pump_id = p.id
JOIN tanks t ON p.tank_id = t.id
JOIN fuel_types ft ON t.fuel_type_id = ft.id
ORDER BY n.id
");
$nozzles = $nozzles_stmt->fetchAll(PDO::FETCH_ASSOC);
// Group nozzles by fuel type
$nozzles_by_fuel = [];
foreach ($nozzles as $nozzle) {
$nozzles_by_fuel[$nozzle['fuel_name']][] = $nozzle;
}
?>
<div class="container-fluid">
<h1 class="h3 mb-4 text-gray-800">Daily Daybook</h1>
<?php if ($message): ?>
<div class="alert alert-success"><?php echo $message; ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo $error; ?></div>
<?php endif; ?>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Enter Readings</h6>
</div>
<div class="card-body">
<form method="GET" action="daybook.php" class="form-inline mb-4">
<div class="form-group mr-2">
<label for="date" class="mr-2">Date:</label>
<input type="date" class="form-control" id="date" name="date" value="<?php echo isset($_GET['date']) ? htmlspecialchars($_GET['date']) : date('Y-m-d'); ?>" required>
</div>
<button type="submit" class="btn btn-primary">Load Readings</button>
</form>
<?php if (isset($_GET['date'])): ?>
<form method="POST" action="daybook.php">
<input type="hidden" name="date" value="<?php echo htmlspecialchars($_GET['date']); ?>">
<?php foreach ($nozzles_by_fuel as $fuel_name => $fuel_nozzles): ?>
<h5 class="mt-4"><?php echo htmlspecialchars($fuel_name); ?></h5>
<div class="form-group row">
<label for="price_<?php echo strtolower($fuel_name); ?>" class="col-sm-2 col-form-label">Price (per Ltr)</label>
<div class="col-sm-4">
<input type="number" step="0.01" class="form-control" id="price_<?php echo strtolower($fuel_name); ?>" name="prices[<?php echo htmlspecialchars($fuel_name); ?>]" required>
</div>
</div>
<div class="table-responsive">
<table class="table table-bordered" width="100%" cellspacing="0">
<thead>
<tr>
<th>Nozzle</th>
<th>Opening Reading</th>
<th>Closing Reading</th>
</tr>
</thead>
<tbody>
<?php foreach ($fuel_nozzles as $nozzle): ?>
<tr>
<td><?php echo htmlspecialchars($nozzle['nozzle_number']); ?></td>
<td>
<input type="hidden" name="readings[<?php echo $nozzle['id']; ?>][nozzle_id]" value="<?php echo $nozzle['id']; ?>">
<input type="number" step="0.01" class="form-control" name="readings[<?php echo $nozzle['id']; ?>][opening]" value="<?php echo $previous_day_readings[$nozzle['id']] ?? '0.00'; ?>" required>
</td>
<td>
<input type="number" step="0.01" class="form-control" name="readings[<?php echo $nozzle['id']; ?>][closing]" required>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endforeach; ?>
<button type="submit" name="save_readings" class="btn btn-success">Save Readings</button>
</form>
<div id="sales_summary" class="mt-4"></div>
<?php endif; ?>
</div>
</div>
</div>
<?php require_once 'includes/footer.php'; ?>
<script>
document.addEventListener('DOMContentLoaded', function () {
const form = document.querySelector('form[method="POST"]');
if (!form) return;
const summaryContainer = document.getElementById('sales_summary');
function calculateSales() {
let totalSalesByFuel = {};
let grandTotalAmount = 0;
const readingInputs = form.querySelectorAll('input[name^="readings["]');
const prices = {};
document.querySelectorAll('input[name^="prices["]').forEach(priceInput => {
const fuelName = priceInput.name.match(/prices\[(.*)\]/)[1];
prices[fuelName] = parseFloat(priceInput.value) || 0;
});
const nozzlesByFuel = <?php echo json_encode($nozzles_by_fuel); ?>;
let salesSummaryHtml = '<h5 class="mt-4">Live Sales Summary</h5>';
for (const fuelName in nozzlesByFuel) {
if (nozzlesByFuel.hasOwnProperty(fuelName)) {
let fuelTotalSaleQty = 0;
let fuelTotalSaleAmount = 0;
nozzlesByFuel[fuelName].forEach(nozzle => {
const openingInput = form.querySelector(`input[name="readings[${nozzle.id}][opening]"]`);
const closingInput = form.querySelector(`input[name="readings[${nozzle.id}][closing]"]`);
const openingReading = parseFloat(openingInput.value) || 0;
const closingReading = parseFloat(closingInput.value) || 0;
const price = prices[fuelName] || 0;
if (closingReading >= openingReading) {
const saleQty = closingReading - openingReading;
const saleAmount = saleQty * price;
fuelTotalSaleQty += saleQty;
fuelTotalSaleAmount += saleAmount;
}
});
totalSalesByFuel[fuelName] = {
qty: fuelTotalSaleQty,
amount: fuelTotalSaleAmount
};
grandTotalAmount += fuelTotalSaleAmount;
}
}
salesSummaryHtml += '<div class="table-responsive"><table class="table table-bordered">' +
'<thead><tr><th>Fuel Type</th><th>Total Sale Qty (Ltr)</th><th>Total Sale Amount</th></tr></thead><tbody>';
for (const fuelName in totalSalesByFuel) {
if (totalSalesByFuel.hasOwnProperty(fuelName)) {
salesSummaryHtml += `<tr>
<td>${fuelName}</td>
<td>${totalSalesByFuel[fuelName].qty.toFixed(2)}</td>
<td>${totalSalesByFuel[fuelName].amount.toFixed(2)}</td>
</tr>`;
}
}
salesSummaryHtml += `</tbody><tfoot><tr>
<th colspan="2" class="text-right">Grand Total</th>
<th>${grandTotalAmount.toFixed(2)}</th>
</tr></tfoot></table></div>`;
summaryContainer.innerHTML = salesSummaryHtml;
}
form.addEventListener('input', calculateSales);
calculateSales(); // Initial calculation
});
</script>
<?php require_once 'includes/footer.php'; ?>