/home/awneajlw/www/codestechvista.com/admin/orders.php
<?php
session_start();
require_once '../config/database.php';
require_once '../includes/auth.php';
// Check if user is admin
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'admin') {
header('Location: ../login.php');
exit();
}
$database = new Database();
$db = $database->getConnection();
$success_message = '';
$error_message = '';
// Handle Export
if (isset($_GET['export']) && $_GET['export'] == 'csv') {
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="orders_export_' . date('Y-m-d') . '.csv"');
$output = fopen('php://output', 'w');
fputcsv($output, ['ID', 'Tracking ID', 'Patient Name', 'WhatsApp', 'Frame', 'Lens', 'Total Amount', 'Advance', 'Balance', 'Status', 'Delivery Date', 'Created Date']);
$query = "SELECT * FROM orders ORDER BY created_at DESC";
$stmt = $db->prepare($query);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
fputcsv($output, [
$row['id'],
$row['tracking_id'],
$row['patient_name'],
$row['whatsapp_number'],
$row['frame_detail'],
$row['lens_type'],
$row['total_amount'],
$row['advance'],
$row['balance'],
$row['status'],
$row['delivery_date'],
$row['created_at']
]);
}
fclose($output);
exit();
}
// Handle Import
if (isset($_POST['import']) && isset($_FILES['import_file'])) {
$file = $_FILES['import_file'];
if ($file['error'] == 0 && $file['type'] == 'text/csv') {
$handle = fopen($file['tmp_name'], 'r');
$header = fgetcsv($handle); // Skip header
$imported = 0;
while (($data = fgetcsv($handle)) !== FALSE) {
try {
$query = "INSERT INTO orders (tracking_id, patient_name, whatsapp_number, frame_detail, lens_type, total_amount, advance, balance, status, delivery_date, user_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $db->prepare($query);
$stmt->execute([
$data[1], $data[2], $data[3], $data[4], $data[5],
$data[6], $data[7], $data[8], $data[9], $data[10],
$_SESSION['user_id']
]);
$imported++;
} catch (Exception $e) {
// Skip rows with errors
}
}
fclose($handle);
$success_message = "Successfully imported $imported orders!";
} else {
$error_message = "Please upload a valid CSV file!";
}
}
// Handle Status Update
if (isset($_POST['update_status'])) {
$order_id = $_POST['order_id'] ?? 0;
$new_status = $_POST['new_status'] ?? '';
try {
$query = "UPDATE orders SET status = ? WHERE id = ?";
$stmt = $db->prepare($query);
$stmt->execute([$new_status, $order_id]);
$success_message = "Order status updated successfully!";
} catch (Exception $e) {
$error_message = "Error updating status: " . $e->getMessage();
}
}
// Build query with filters
$where_conditions = [];
$params = [];
if (isset($_GET['status']) && !empty($_GET['status'])) {
$where_conditions[] = "o.status = ?";
$params[] = $_GET['status'];
}
if (isset($_GET['search']) && !empty($_GET['search'])) {
$search = '%' . $_GET['search'] . '%';
$where_conditions[] = "(o.tracking_id LIKE ? OR o.patient_name LIKE ? OR o.whatsapp_number LIKE ?)";
$params[] = $search;
$params[] = $search;
$params[] = $search;
}
if (isset($_GET['date_from']) && !empty($_GET['date_from'])) {
$where_conditions[] = "DATE(o.created_at) >= ?";
$params[] = $_GET['date_from'];
}
if (isset($_GET['date_to']) && !empty($_GET['date_to'])) {
$where_conditions[] = "DATE(o.created_at) <= ?";
$params[] = $_GET['date_to'];
}
$where_clause = !empty($where_conditions) ? "WHERE " . implode(" AND ", $where_conditions) : "";
$query = "SELECT o.*, u.name as user_name, u.email as user_email
FROM orders o
LEFT JOIN users u ON o.user_id = u.id
$where_clause
ORDER BY o.created_at DESC";
$stmt = $db->prepare($query);
$stmt->execute($params);
$orders = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Get statistics
$stats_query = "SELECT
COUNT(*) as total,
SUM(CASE WHEN status = 'Pending' THEN 1 ELSE 0 END) as pending,
SUM(CASE WHEN status IN ('Done', 'Completed') THEN 1 ELSE 0 END) as completed,
SUM(total_amount) as total_revenue
FROM orders";
$stats = $db->query($stats_query)->fetch(PDO::FETCH_ASSOC);
$page_title = "Orders Management";
?>
<?php include 'includes/header.php'; ?>
<?php include 'includes/sidebar.php'; ?>
<style>
/* Enhanced Orders Management Styling */
.action-btn {
padding: 8px 14px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 5px;
}
.btn-success-custom {
background: linear-gradient(135deg, #28a745, #20c997);
color: white;
}
.btn-success-custom:hover {
background: linear-gradient(135deg, #218838, #1aa179);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(40, 167, 69, 0.3);
}
.btn-warning-custom {
background: linear-gradient(135deg, #ffc107, #ffb300);
color: #000;
}
.btn-warning-custom:hover {
background: linear-gradient(135deg, #e0a800, #d39e00);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(255, 193, 7, 0.3);
}
.badge-custom {
padding: 8px 16px;
border-radius: 20px;
font-size: 12px;
font-weight: 600;
display: inline-block;
}
.badge-success {
background: linear-gradient(135deg, #d4edda, #c3e6cb);
color: #155724;
border: 1px solid #c3e6cb;
}
.badge-warning {
background: linear-gradient(135deg, #fff3cd, #ffeaa7);
color: #856404;
border: 1px solid #ffeaa7;
}
.badge-danger {
background: linear-gradient(135deg, #f8d7da, #f5c6cb);
color: #721c24;
border: 1px solid #f5c6cb;
}
.badge-info {
background: linear-gradient(135deg, #d1ecf1, #bee5eb);
color: #0c5460;
border: 1px solid #bee5eb;
}
.table-custom tbody tr {
transition: all 0.3s ease;
}
.table-custom tbody tr:hover {
background: #f8f9fa;
transform: scale(1.005);
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.modal-custom .modal-header {
background: linear-gradient(135deg, #169D53 0%, #0d7a3f 100%);
color: white;
padding: 20px 25px;
}
.modal-custom .modal-title {
font-weight: 700;
font-size: 20px;
}
.modal-custom .btn-primary-custom {
background: linear-gradient(135deg, #169D53, #0d7a3f);
border: none;
padding: 12px 24px;
font-weight: 600;
}
.modal-custom .btn-primary-custom:hover {
background: linear-gradient(135deg, #128a43, #0a6331);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(22, 157, 83, 0.3);
}
.content-card {
border: 1px solid #e9ecef;
transition: all 0.3s ease;
}
.content-card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}
/* Filter Form Styling */
.form-control:focus,
.form-select:focus {
border-color: #169D53;
box-shadow: 0 0 0 0.2rem rgba(22, 157, 83, 0.15);
}
/* DataTables Customization */
.dataTables_wrapper .dataTables_filter input {
border: 2px solid #169D53;
border-radius: 6px;
padding: 8px 12px;
}
.dataTables_wrapper .dataTables_filter input:focus {
outline: none;
box-shadow: 0 0 0 0.2rem rgba(22, 157, 83, 0.15);
}
.dataTables_wrapper .dataTables_length select {
border: 2px solid #169D53;
border-radius: 6px;
padding: 6px 10px;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current {
background: linear-gradient(135deg, #169D53, #0d7a3f) !important;
border-color: #169D53 !important;
color: white !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
background: #169D53 !important;
border-color: #169D53 !important;
color: white !important;
}
.stat-card {
border-left-width: 4px;
border-left-style: solid;
}
.stat-card:nth-child(1) {
border-left-color: #169D53;
}
.stat-card:nth-child(2) {
border-left-color: #ffc107;
}
.stat-card:nth-child(3) {
border-left-color: #28a745;
}
.stat-card:nth-child(4) {
border-left-color: #17a2b8;
}
</style>
<div class="main-content">
<!-- Page Header -->
<div class="page-header">
<h1 class="page-title">
<i class="fas fa-shopping-cart"></i> Orders Management
</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="dashboard.php">Dashboard</a></li>
<li class="breadcrumb-item active">Orders</li>
</ol>
</nav>
</div>
<!-- Alert Messages -->
<?php if ($success_message): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="fas fa-check-circle"></i> <?php echo htmlspecialchars($success_message); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<?php if ($error_message): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<i class="fas fa-exclamation-triangle"></i> <?php echo htmlspecialchars($error_message); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<!-- Statistics Cards -->
<div class="row g-4 mb-4">
<div class="col-lg-3 col-md-6">
<div class="stat-card">
<div class="stat-icon">
<i class="fas fa-shopping-bag"></i>
</div>
<div class="stat-value"><?php echo number_format($stats['total']); ?></div>
<div class="stat-label">Total Orders</div>
</div>
</div>
<div class="col-lg-3 col-md-6">
<div class="stat-card">
<div class="stat-icon">
<i class="fas fa-clock"></i>
</div>
<div class="stat-value"><?php echo number_format($stats['pending']); ?></div>
<div class="stat-label">Pending Orders</div>
</div>
</div>
<div class="col-lg-3 col-md-6">
<div class="stat-card">
<div class="stat-icon">
<i class="fas fa-check-circle"></i>
</div>
<div class="stat-value"><?php echo number_format($stats['completed']); ?></div>
<div class="stat-label">Completed Orders</div>
</div>
</div>
<div class="col-lg-3 col-md-6">
<div class="stat-card">
<div class="stat-icon">
<i class="fas fa-dollar-sign"></i>
</div>
<div class="stat-value">Rs. <?php echo number_format($stats['total_revenue']); ?></div>
<div class="stat-label">Total Revenue</div>
</div>
</div>
</div>
<!-- Filters & Actions -->
<div class="content-card mb-4">
<form method="GET" class="row g-3">
<div class="col-md-3">
<label class="form-label">Search</label>
<input type="text" name="search" class="form-control" placeholder="Tracking ID, Name, Phone" value="<?php echo htmlspecialchars($_GET['search'] ?? ''); ?>">
</div>
<div class="col-md-2">
<label class="form-label">Status</label>
<select name="status" class="form-select">
<option value="">All Status</option>
<option value="Pending" <?php echo (isset($_GET['status']) && $_GET['status'] == 'Pending') ? 'selected' : ''; ?>>Pending</option>
<option value="Done" <?php echo (isset($_GET['status']) && $_GET['status'] == 'Done') ? 'selected' : ''; ?>>Done</option>
<option value="Completed" <?php echo (isset($_GET['status']) && $_GET['status'] == 'Completed') ? 'selected' : ''; ?>>Completed</option>
<option value="Cancelled" <?php echo (isset($_GET['status']) && $_GET['status'] == 'Cancelled') ? 'selected' : ''; ?>>Cancelled</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label">From Date</label>
<input type="date" name="date_from" class="form-control" value="<?php echo htmlspecialchars($_GET['date_from'] ?? ''); ?>">
</div>
<div class="col-md-2">
<label class="form-label">To Date</label>
<input type="date" name="date_to" class="form-control" value="<?php echo htmlspecialchars($_GET['date_to'] ?? ''); ?>">
</div>
<div class="col-md-3">
<label class="form-label"> </label>
<div class="d-flex gap-2">
<button type="submit" class="btn-primary-custom flex-grow-1">
<i class="fas fa-filter"></i> Filter
</button>
<a href="orders.php" class="btn btn-secondary">
<i class="fas fa-redo"></i> Reset
</a>
</div>
</div>
</form>
</div>
<!-- Orders Table -->
<div class="content-card">
<div class="card-header-custom">
<h3 class="card-title-custom">
<i class="fas fa-list"></i> All Orders (<?php echo count($orders); ?>)
</h3>
<div class="d-flex gap-2">
<a href="orders.php?export=csv" class="btn-success-custom">
<i class="fas fa-file-export"></i> Export CSV
</a>
<button class="btn-primary-custom" data-bs-toggle="modal" data-bs-target="#importModal">
<i class="fas fa-file-import"></i> Import CSV
</button>
</div>
</div>
<div class="table-responsive">
<table id="ordersTable" class="table table-custom">
<thead>
<tr>
<th>ID</th>
<th>Tracking ID</th>
<th>Patient Name</th>
<th>Phone</th>
<th>Total Amount</th>
<th>Advance</th>
<th>Balance</th>
<th>Status</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($orders)): ?>
<tr>
<td colspan="10" class="text-center">No orders found</td>
</tr>
<?php else: ?>
<?php foreach ($orders as $order): ?>
<tr>
<td><?php echo $order['id']; ?></td>
<td><strong><?php echo htmlspecialchars($order['tracking_id']); ?></strong></td>
<td><?php echo htmlspecialchars($order['patient_name']); ?></td>
<td><?php echo htmlspecialchars($order['whatsapp_number']); ?></td>
<td>Rs. <?php echo number_format($order['total_amount'], 2); ?></td>
<td>Rs. <?php echo number_format($order['advance'], 2); ?></td>
<td>Rs. <?php echo number_format($order['balance'], 2); ?></td>
<td>
<?php
$badge_class = 'badge-info';
if ($order['status'] == 'Done' || $order['status'] == 'Completed') {
$badge_class = 'badge-success';
} elseif ($order['status'] == 'Pending') {
$badge_class = 'badge-warning';
} elseif ($order['status'] == 'Cancelled') {
$badge_class = 'badge-danger';
}
?>
<span class="badge-custom <?php echo $badge_class; ?>">
<?php echo htmlspecialchars($order['status']); ?>
</span>
</td>
<td><?php echo date('M d, Y', strtotime($order['created_at'])); ?></td>
<td>
<div class="action-buttons">
<button class="action-btn btn-success-custom" onclick="viewOrder(<?php echo htmlspecialchars(json_encode($order)); ?>)" title="View Details">
<i class="fas fa-eye"></i>
</button>
<button class="action-btn btn-warning-custom" onclick="updateStatus(<?php echo $order['id']; ?>, '<?php echo $order['status']; ?>')" title="Update Status">
<i class="fas fa-edit"></i>
</button>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- Import Modal -->
<div class="modal fade modal-custom" id="importModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-file-import"></i> Import Orders</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="POST" enctype="multipart/form-data">
<div class="modal-body">
<div class="alert alert-info">
<i class="fas fa-info-circle"></i> Upload a CSV file with columns: ID, Tracking ID, Patient Name, WhatsApp, Frame, Lens, Total Amount, Advance, Balance, Status, Delivery Date, Created Date
</div>
<div class="mb-3">
<label class="form-label">Select CSV File</label>
<input type="file" name="import_file" class="form-control" accept=".csv" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" name="import" class="btn-primary-custom">Import Orders</button>
</div>
</form>
</div>
</div>
</div>
<!-- View Order Modal -->
<div class="modal fade modal-custom" id="viewOrderModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-eye"></i> Order Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body" id="orderDetailsContent">
<!-- Content will be loaded dynamically -->
</div>
</div>
</div>
</div>
<!-- Update Status Modal -->
<div class="modal fade modal-custom" id="updateStatusModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-edit"></i> Update Order Status</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="POST">
<div class="modal-body">
<input type="hidden" name="order_id" id="status_order_id">
<div class="mb-3">
<label class="form-label">New Status</label>
<select name="new_status" id="new_status" class="form-select" required>
<option value="Pending">Pending</option>
<option value="Done">Done</option>
<option value="Completed">Completed</option>
<option value="Cancelled">Cancelled</option>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" name="update_status" class="btn-primary-custom">Update Status</button>
</div>
</form>
</div>
</div>
</div>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<!-- DataTables -->
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
<script>
$(document).ready(function() {
$('#ordersTable').DataTable({
order: [[0, 'desc']],
pageLength: 50,
language: {
search: "Search orders:"
}
});
});
function viewOrder(order) {
const content = `
<div class="row g-3">
<div class="col-md-6">
<h6 class="text-muted">Tracking ID</h6>
<p class="fw-bold">${order.tracking_id}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">Patient Name</h6>
<p class="fw-bold">${order.patient_name}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">WhatsApp Number</h6>
<p>${order.whatsapp_number}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">Frame Detail</h6>
<p>${order.frame_detail || 'N/A'}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">Lens Type</h6>
<p>${order.lens_type || 'N/A'}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">Total Amount</h6>
<p class="fw-bold text-success">Rs. ${parseFloat(order.total_amount).toLocaleString()}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">Advance</h6>
<p>Rs. ${parseFloat(order.advance).toLocaleString()}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">Balance</h6>
<p>Rs. ${parseFloat(order.balance).toLocaleString()}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">Delivery Date</h6>
<p>${order.delivery_date || 'Not set'}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">Status</h6>
<p><span class="badge-custom badge-success">${order.status}</span></p>
</div>
<div class="col-12">
<h6 class="text-muted">Important Note</h6>
<p>${order.important_note || 'No notes'}</p>
</div>
<div class="col-md-6">
<h6 class="text-muted">Created At</h6>
<p>${new Date(order.created_at).toLocaleString()}</p>
</div>
</div>
`;
document.getElementById('orderDetailsContent').innerHTML = content;
new bootstrap.Modal(document.getElementById('viewOrderModal')).show();
}
function updateStatus(orderId, currentStatus) {
document.getElementById('status_order_id').value = orderId;
document.getElementById('new_status').value = currentStatus;
new bootstrap.Modal(document.getElementById('updateStatusModal')).show();
}
</script>
</body>
</html>