|
Server : LiteSpeed System : Linux terra.hostitbro.com 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64 User : outerorb ( 1091) PHP Version : 8.1.34 Disable Function : mail Directory : /home2/outerorb/assetradar.outerorbittech.com/admin/ | |
|
Path: /home2/outerorb/assetradar.outerorbittech.com/admin/reports.php
Size: 7.29 KB
Permissions: 0666
<?php
// Chart status API for dashboard chart
if (isset($_GET['chart_status']) && $_GET['chart_status'] == '1') {
header('Content-Type: application/json');
$statuses = [];
$counts = [];
$colors = [];
$res = $mysqli->query("SELECT status, COUNT(*) as c FROM tickets GROUP BY status");
while($row = $res->fetch_assoc()) {
$statuses[] = $row['status'];
$counts[] = (int)$row['c'];
}
echo json_encode(['labels' => $statuses, 'counts' => $counts]);
exit;
}
require_once __DIR__ . '/../inc/auth.php';
if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
require __DIR__ . '/../vendor/autoload.php';
}
require_login();
$u = current_user();
require_admin();
$where = '';
if (isset($_GET['category']) && $_GET['category']!='') {
$where = 'WHERE i.category_id='.(int)$_GET['category'];
}
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
$per_page = 20;
$offset = ($page - 1) * $per_page;
$total_res = $mysqli->query('SELECT COUNT(*) as cnt FROM items ' . ($where ? substr($where, 5) : ''));
$total = $total_res ? $total_res->fetch_assoc()['cnt'] : 0;
$res = $mysqli->query('SELECT i.*, c.name as category_name, u.name as assigned_name FROM items i LEFT JOIN categories c ON i.category_id=c.id LEFT JOIN users u ON i.assigned_to=u.id ' . $where . ' ORDER BY i.id DESC LIMIT ' . $per_page . ' OFFSET ' . $offset);
// Export to Excel (.xlsx) using PHPSpreadsheet if available
if (isset($_GET['export']) && $_GET['export']=='xlsx') {
// try to use PhpSpreadsheet if installed via composer
if (class_exists('PhpOffice\PhpSpreadsheet\Spreadsheet') && class_exists('PhpOffice\PhpSpreadsheet\Writer\Xlsx')) {
$spread = new PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spread->getActiveSheet();
$sheet->setCellValue('A1','ID')->setCellValue('B1','Asset Tag')->setCellValue('C1','Name')->setCellValue('D1','Category')->setCellValue('E1','Brand/Model')->setCellValue('F1','Serial')->setCellValue('G1','Condition')->setCellValue('H1','Assigned To');
$row = 2;
$res->data_seek(0);
while($r = $res->fetch_assoc()) {
$sheet->setCellValue('A'.$row, $r['id']);
$sheet->setCellValue('B'.$row, $r['asset_tag']);
$sheet->setCellValue('C'.$row, $r['item_name']);
$sheet->setCellValue('D'.$row, $r['category_name']);
$sheet->setCellValue('E'.$row, $r['brand_model']);
$sheet->setCellValue('F'.$row, $r['serial_number']);
$sheet->setCellValue('G'.$row, $r['condition_status']);
$sheet->setCellValue('H'.$row, $r['assigned_name']);
$row++;
}
$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($spread);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="inventory.xlsx"');
$writer->save('php://output');
exit;
} else {
// fallback to CSV download
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="inventory_fallback.csv"');
$out = fopen('php://output','w');
fputcsv($out, ['ID','Asset Tag','Name','Category','Brand/Model','Serial','Condition','Assigned To']);
$res->data_seek(0);
while($r = $res->fetch_assoc()) {
fputcsv($out, [$r['id'],$r['asset_tag'],$r['item_name'],$r['category_name'],$r['brand_model'],$r['serial_number'],$r['condition_status'],$r['assigned_name']]);
}
fclose($out);
exit;
}
}
define('ADMIN_PAGE', true);
include __DIR__ . '/../inc/header.php';
include __DIR__ . '/admin_menu.php';
?>
<div class="card p-3 card-hero">
<div class="d-flex justify-content-between">
<h5>Reports</h5>
<div>
<a class="btn btn-outline-success btn-sm" href="?export=xlsx">Export to Excel (.xlsx)</a>
</div>
</div>
<div class="mb-2 d-flex flex-wrap gap-2 align-items-center">
<input type="text" id="searchInput" class="form-control w-auto" placeholder="Search..." style="max-width:200px;">
<select id="conditionFilter" class="form-select w-auto" style="max-width:160px;">
<option value="">All Conditions</option>
<option value="Working">Working</option>
<option value="Damaged">Damaged</option>
</select>
<select id="assignedFilter" class="form-select w-auto" style="max-width:160px;">
<option value="">All Assigned</option>
<option value="assigned">Assigned</option>
<option value="unassigned">Unassigned</option>
</select>
</div>
<table class="table table-bordered mt-3" id="inventoryTable">
<thead><tr><th>ID</th><th>Asset</th><th>Name</th><th>Category</th><th>Brand/Model</th><th>Serial</th><th>Condition</th><th>Assigned</th></tr></thead>
<tbody>
<?php while($r = $res->fetch_assoc()): ?>
<tr>
<td><?php echo $r['id']; ?></td>
<td><?php echo esc($r['asset_tag']); ?></td>
<td><?php echo esc($r['item_name']); ?></td>
<td><?php echo esc($r['category_name']); ?></td>
<td><?php echo esc($r['brand_model']); ?></td>
<td><?php echo esc($r['serial_number']); ?></td>
<td><?php echo esc($r['condition_status']); ?></td>
<td><?php echo esc($r['assigned_name']); ?></td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<?php
$num_pages = ceil($total / $per_page);
for ($i = 1; $i <= $num_pages; $i++):
$active = ($i == $page) ? 'active' : '';
$params = $_GET;
$params['page'] = $i;
$url = '?' . http_build_query($params);
?>
<li class="page-item <?php echo $active; ?>"><a class="page-link" href="<?php echo $url; ?>"><?php echo $i; ?></a></li>
<?php endfor; ?>
</ul>
</nav>
<script>
// Simple client-side search and filter
const searchInput = document.getElementById('searchInput');
const conditionFilter = document.getElementById('conditionFilter');
const assignedFilter = document.getElementById('assignedFilter');
const table = document.getElementById('inventoryTable');
searchInput.addEventListener('input', filterTable);
conditionFilter.addEventListener('change', filterTable);
assignedFilter.addEventListener('change', filterTable);
function filterTable() {
const search = searchInput.value.toLowerCase();
const cond = conditionFilter.value;
const assigned = assignedFilter.value;
for (const row of table.tBodies[0].rows) {
let txt = row.innerText.toLowerCase();
let show = (!search || txt.includes(search));
let condVal = row.cells[6].innerText;
let assignedVal = row.cells[7].innerText.trim();
if (cond && condVal !== cond) show = false;
if (assigned === 'assigned' && !assignedVal) show = false;
if (assigned === 'unassigned' && assignedVal) show = false;
row.style.display = show ? '' : 'none';
}
}
</script>
<div class="mt-3"><a class="btn btn-sm btn-outline-info" href="team_audit.php">Team Audit</a> <a class="btn btn-sm btn-outline-warning" href="alerts.php">Alerts & Warranties</a></div>
</div>
<?php include __DIR__ . '/../inc/footer.php'; ?>