38471-vm/ajax_session_report.php
2026-05-02 17:17:21 +00:00

217 lines
9.0 KiB
PHP

<?php
require_once __DIR__ . '/db/config.php';
// Sessions setup (Must match index.php)
$sessions_dir = __DIR__ . '/sessions';
if (is_dir($sessions_dir) && is_writable($sessions_dir)) {
session_save_path("0;0660;" . $sessions_dir);
}
// Enhanced session security and iframe compatibility (Must match index.php)
if ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')) {
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'None',
]);
}
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
if (!isset($_SESSION['user_id'])) {
http_response_code(403);
echo "Unauthorized";
exit;
}
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if (!$id) {
echo '<div class="modal-header"><h5 class="modal-title">Error</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body text-danger">Invalid Session ID</div>';
exit;
}
// Fetch session details
$stmt = db()->prepare("SELECT s.*, r.name as register_name, u.username
FROM register_sessions s
LEFT JOIN cash_registers r ON s.register_id = r.id
LEFT JOIN users u ON s.user_id = u.id
WHERE s.id = ?");
$stmt->execute([$id]);
$s = $stmt->fetch();
if (!$s) {
echo '<div class="modal-header"><h5 class="modal-title">Error</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body text-danger">Session not found</div>';
exit;
}
?>
<style>
@media print {
body * {
visibility: hidden;
}
#universalSessionReportModal, #universalSessionReportModal * {
visibility: visible;
}
#universalSessionReportModal {
position: absolute;
left: 0;
top: 0;
width: 100%;
margin: 0;
padding: 0;
}
.modal-backdrop { display: none !important; }
.modal-footer { display: none !important; } /* Hide buttons on print */
.btn-close { display: none !important; }
}
</style>
<div class="modal-header">
<h5 class="modal-title">Session Cashflow Report (#<?= $s['id'] ?>)</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body text-start">
<div class="form-grid-3">
<div class="col-md-6">
<p class="mb-1 text-muted small">Register</p>
<h6><?= htmlspecialchars($s['register_name'] ?? 'Unknown') ?></h6>
</div>
<div class="col-md-6">
<p class="mb-1 text-muted small">Cashier</p>
<h6><?= htmlspecialchars($s['username'] ?? 'Unknown') ?></h6>
</div>
<div class="col-md-6">
<p class="mb-1 text-muted small">Opened At</p>
<h6><?= $s['opened_at'] ?></h6>
</div>
<div class="col-md-6">
<p class="mb-1 text-muted small">Closed At</p>
<h6><?= $s['closed_at'] ?? 'Still Open' ?></h6>
</div>
</div>
<hr>
<?php
// Breakdown of sales by payment method (Unified)
$breakdown = db()->prepare("SELECT payment_method, SUM(amount) as total FROM payments p JOIN invoices i ON p.invoice_id = i.id WHERE i.register_session_id = ? AND i.status = 'paid' AND i.is_pos = 1 GROUP BY payment_method");
$breakdown->execute([$s['id']]);
$methods = $breakdown->fetchAll();
$cash_sales = 0;
$card_sales = 0;
$credit_sales = 0;
$bank_transfer_sales = 0;
foreach ($methods as $m) {
$method = strtolower($m['payment_method']);
if ($method === 'cash') $cash_sales = $m['total'];
elseif ($method === 'card' || strpos($method, 'card') !== false) $card_sales = $m['total'];
elseif ($method === 'credit') $credit_sales = $m['total'];
elseif (strpos($method, 'transfer') !== false || strpos($method, 'bank') !== false) $bank_transfer_sales = $m['total'];
else $cash_sales += $m['total'];
}
$total_sales = $cash_sales + $card_sales + $credit_sales + $bank_transfer_sales;
$expected_cash_total = (float)$s['opening_balance'] + $cash_sales;
$total_all = (float)$s['opening_balance'] + $total_sales;
?>
<div class="card border-0 bg-light mb-4">
<div class="card-body">
<h6 class="fw-bold text-uppercase small mb-3">Sales Summary</h6>
<div class="d-flex justify-content-between mb-2">
<span>Opening Balance:</span>
<span class="fw-bold">OMR <?= number_format((float)$s['opening_balance'], 3) ?></span>
</div>
<?php
// Additional totals (Unified)
$extra_stmt = db()->prepare("SELECT SUM(vat_amount) as total_tax, SUM(discount_amount) as total_discount, SUM(total_with_vat) as total_net FROM invoices WHERE register_session_id = ? AND status = 'paid' AND is_pos = 1");
$extra_stmt->execute([$s['id']]);
$extra = $extra_stmt->fetch();
?>
<div class="d-flex justify-content-between mb-2 small text-muted">
<span>Tax Amount:</span>
<span>OMR <?= number_format((float)($extra['total_tax'] ?? 0), 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2 small text-muted">
<span>Discount:</span>
<span>OMR <?= number_format((float)($extra['total_discount'] ?? 0), 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2">
<span>Cash Sale:</span>
<span class="fw-bold">OMR <?= number_format((float)$cash_sales, 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2">
<span>Credit Card:</span>
<span class="fw-bold">OMR <?= number_format((float)$card_sales, 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2">
<span>Credit:</span>
<span class="fw-bold">OMR <?= number_format((float)$credit_sales, 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2">
<span>Bank Transfer:</span>
<span class="fw-bold">OMR <?= number_format((float)$bank_transfer_sales, 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2 border-top pt-2 mt-2 h6 text-primary">
<span>Total Sale:</span>
<span class="fw-bold">OMR <?= number_format((float)$total_sales, 3) ?></span>
</div>
</div>
</div>
<div class="card border-0 bg-primary bg-opacity-10 mb-4">
<div class="card-body">
<h6 class="fw-bold text-uppercase small mb-3 text-primary">Cash Reconciliation</h6>
<div class="d-flex justify-content-between mb-2">
<span>Opening Balance:</span>
<span>OMR <?= number_format((float)$s['opening_balance'], 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2">
<span>(+) Cash Sale:</span>
<span>OMR <?= number_format($cash_sales, 3) ?></span>
</div>
<div class="d-flex justify-content-between mb-2 border-top pt-2 mt-2 h6">
<span>Expected Cash:</span>
<span class="fw-bold">OMR <?= number_format((float)$expected_cash_total, 3) ?></span>
</div>
<?php if ($s['status'] === 'closed'): ?>
<div class="d-flex justify-content-between mb-2">
<span>Actual Cash:</span>
<span>OMR <?= number_format((float)$s['cash_in_hand'], 3) ?></span>
</div>
<?php
$shortage = (float)$s['cash_in_hand'] - $expected_cash_total;
$shortage_class = $shortage < 0 ? 'text-danger' : 'text-success';
?>
<div class="d-flex justify-content-between mb-0 h5 mt-2 <?= $shortage_class ?>">
<span>Balance:</span>
<span class="fw-bold">OMR <?= number_format((float)$shortage, 3) ?></span>
</div>
<?php endif; ?>
</div>
</div>
<!-- Transaction Details REMOVED per user request -->
<hr>
<div class="row g-2 small text-muted">
<div class="col-6">Expected Cash: OMR <?= number_format((float)$expected_cash_total, 3) ?></div>
<div class="col-6 text-end">Actual Cash: OMR <?= number_format((float)($s['cash_in_hand'] ?? 0), 3) ?></div>
</div>
<?php if ($s['notes']): ?>
<hr>
<p class="mb-1 text-muted small">Notes:</p>
<p class="mb-0 small bg-light p-2 rounded"><?= nl2br(htmlspecialchars($s['notes'])) ?></p>
<?php endif; ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="window.print()">Print Report</button>
<button type="button" class="btn btn-light" data-bs-dismiss="modal" data-en="Close" data-ar="إغلاق">Close</button>
</div>