File "manage_bookings.php"

Full path: /home/itsevak/public_html/prepaiddev.itsevak.com/operator/manage_bookings.php
File size: 30.52 B (30.52 KB bytes)
MIME-type: text/x-php
Charset: utf-8

Download   Open   Edit   Advanced Editor   Back

<?php
require_once '../includes/functions.php';

// Require login and operator access
requireLogin();
if ($_SESSION['user_type'] !== 'operator') {
    redirect('/auth/login.php');
}

$user = getCurrentUser();
$db = Database::getInstance();

$errors = [];
$success = '';

// Check if operator has active session
$currentSession = $db->fetch(
    "SELECT os.*, fl.name as from_location_name 
     FROM operator_sessions os 
     JOIN from_locations fl ON os.from_location_id = fl.id 
     WHERE os.operator_id = ? AND os.status = 'active'",
    [$user['id']]
);

if (!$currentSession) {
    redirect('index.php');
}

// Handle status updates
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_status'])) {
    if (!validateCSRFToken($_POST['csrf_token'] ?? '')) {
        $errors[] = 'Invalid request. Please try again.';
    } else {
        $bookingId = (int)($_POST['booking_id'] ?? 0);
        $newStatus = $_POST['new_status'] ?? '';
        
        if (empty($bookingId) || empty($newStatus)) {
            $errors[] = 'Missing booking information.';
        } else {
            try {
                $updateFields = ['status = ?'];
                $params = [$newStatus];
                
                if ($newStatus === 'completed') {
                    $updateFields[] = 'completion_time = NOW()';
                }
                
                $sql = "UPDATE bookings SET " . implode(', ', $updateFields) . " WHERE id = ? AND operator_id = ?";
                $params[] = $bookingId;
                $params[] = $user['id'];
                
                $db->query($sql, $params);
                
                $success = 'Booking status updated successfully!';
            } catch (Exception $e) {
                $errors[] = 'Error updating booking: ' . $e->getMessage();
            }
        }
    }
}

// Get filter parameters
$statusFilter = $_GET['status'] ?? '';
$startDate = $_GET['start_date'] ?? '';
$endDate = $_GET['end_date'] ?? '';

// Build query for bookings
$whereConditions = ['b.operator_id = ?', 'b.from_location_id = ?'];
$params = [$user['id'], $currentSession['from_location_id']];

if ($statusFilter) {
    $whereConditions[] = 'b.status = ?';
    $params[] = $statusFilter;
}

if ($startDate && $endDate) {
    $whereConditions[] = 'DATE(b.created_at) BETWEEN ? AND ?';
    $params[] = $startDate;
    $params[] = $endDate;
} elseif ($startDate) {
    $whereConditions[] = 'DATE(b.created_at) >= ?';
    $params[] = $startDate;
} elseif ($endDate) {
    $whereConditions[] = 'DATE(b.created_at) <= ?';
    $params[] = $endDate;
}

$whereClause = implode(' AND ', $whereConditions);

// Get bookings for current session only
$bookings = $db->fetchAll(
    "SELECT b.*, p.name as passenger_name, p.phone as passenger_phone, 
            tl.name as to_location_name, tl.city as to_city,
            ar.number_plate, ar.unique_local_id, ao.name as owner_name
     FROM bookings b 
     JOIN passengers p ON b.passenger_id = p.id 
     JOIN to_locations tl ON b.to_location_id = tl.id 
     LEFT JOIN auto_rickshaws ar ON b.auto_rickshaw_id = ar.id
     LEFT JOIN auto_owners ao ON ar.owner_id = ao.id
     WHERE $whereClause
     ORDER BY b.created_at DESC",
    $params
);

// Get status counts for current session only
$statusCounts = $db->fetchAll(
    "SELECT status, COUNT(*) as count FROM bookings WHERE operator_id = ? AND from_location_id = ? GROUP BY status",
    [$user['id'], $currentSession['from_location_id']]
);

$statusStats = [];
foreach ($statusCounts as $stat) {
    $statusStats[$stat['status']] = $stat['count'];
}

$pageTitle = 'Manage Bookings';
require_once '../includes/header.php';
?>

<div class="container py-4">
    <!-- Header -->
    <div class="row mb-4">
        <div class="col-12">
            <div class="card">
                <div class="card-body">
                    <h2 class="card-title mb-2">Manage Bookings</h2>
                    <p class="card-text text-muted">
                        Current Location: <?php echo htmlspecialchars($currentSession['from_location_name'] ?? 'Location not set'); ?>
                    </p>
                </div>
            </div>
        </div>
    </div>
    
    <?php if (!empty($errors)): ?>
        <div class="alert alert-danger">
            <ul class="mb-0">
                <?php foreach ($errors as $error): ?>
                    <li><?php echo htmlspecialchars($error); ?></li>
                <?php endforeach; ?>
            </ul>
        </div>
    <?php endif; ?>
    
    <?php if ($success): ?>
        <div class="alert alert-success">
            <?php echo htmlspecialchars($success); ?>
        </div>
    <?php endif; ?>
    
    <!-- Status Statistics -->
    <div class="row mb-4">
        <div class="col-md-3">
            <div class="card text-center">
                <div class="card-body">
                    <h3 class="card-title text-primary"><?php echo $statusStats['confirmed'] ?? 0; ?></h3>
                    <p class="card-text text-muted">Confirmed</p>
                </div>
            </div>
        </div>
        <div class="col-md-3">
            <div class="card text-center">
                <div class="card-body">
                    <h3 class="card-title text-info"><?php echo $statusStats['in_progress'] ?? 0; ?></h3>
                    <p class="card-text text-muted">In Progress</p>
                </div>
            </div>
        </div>
        <div class="col-md-3">
            <div class="card text-center">
                <div class="card-body">
                    <h3 class="card-title text-success"><?php echo $statusStats['completed'] ?? 0; ?></h3>
                    <p class="card-text text-muted">Completed</p>
                </div>
            </div>
        </div>
        <div class="col-md-3">
            <div class="card text-center">
                <div class="card-body">
                    <h3 class="card-title text-warning"><?php echo $statusStats['cancelled'] ?? 0; ?></h3>
                    <p class="card-text text-muted">Cancelled</p>
                </div>
            </div>
        </div>
    </div>
    
    <!-- Filters -->
    <div class="row mb-4">
        <div class="col-12">
            <div class="card">
                <div class="card-body">
                    <form method="GET" action="" class="row g-3">
                        <div class="col-md-4">
                            <label for="status" class="form-label">Status Filter</label>
                            <select class="form-select" id="status" name="status">
                                <option value="">All Statuses</option>
                                <option value="confirmed" <?php echo $statusFilter === 'confirmed' ? 'selected' : ''; ?>>Confirmed</option>
                                <option value="in_progress" <?php echo $statusFilter === 'in_progress' ? 'selected' : ''; ?>>In Progress</option>
                                <option value="completed" <?php echo $statusFilter === 'completed' ? 'selected' : ''; ?>>Completed</option>
                                <option value="cancelled" <?php echo $statusFilter === 'cancelled' ? 'selected' : ''; ?>>Cancelled</option>
                            </select>
                        </div>
                        <div class="col-md-6">
                            <label class="form-label">Date Range</label>
                            <div class="input-group">
                                <input type="date" class="form-control" id="start_date" name="start_date" value="<?php echo htmlspecialchars($startDate); ?>" placeholder="From">
                                <span class="input-group-text">to</span>
                                <input type="date" class="form-control" id="end_date" name="end_date" value="<?php echo htmlspecialchars($endDate); ?>" placeholder="To">
                            </div>
                        </div>
                        <div class="col-md-2">
                            <label class="form-label">&nbsp;</label>
                            <div class="d-grid">
                                <button type="submit" class="btn btn-primary">
                                    <i class="bi bi-funnel"></i> Apply Filters
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
    
    <!-- Bookings Table -->
    <div class="row">
        <div class="col-12">
            <div class="card">
                <div class="card-header d-flex justify-content-between align-items-center">
                    <h5 class="card-title mb-0">
                        <i class="bi bi-list-check"></i> Bookings (<?php echo count($bookings); ?>)
                    </h5>
                    <a href="index.php" class="btn btn-outline-secondary btn-sm">
                        <i class="bi bi-arrow-left"></i> Back to Dashboard
                    </a>
                </div>
                <div class="card-body">
                    <?php if (empty($bookings)): ?>
                        <div class="text-center text-muted py-4">
                            <i class="bi bi-inbox" style="font-size: 3rem;"></i>
                            <p class="mt-2">No bookings found for the selected filters.</p>
                        </div>
                    <?php else: ?>
                        <div class="table-responsive">
                            <table class="table table-hover">
                                <thead>
                                    <tr>
                                        <th>Booking ID</th>
                                        <th>Passenger</th>
                                        <th>Destination</th>
                                        <th>Auto Rickshaw</th>
                                        <th>Amount</th>
                                        <th>Status</th>
                                        <th>Time</th>
                                        <th>Actions</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php foreach ($bookings as $booking): ?>
                                        <tr>
                                            <td>
                                                <strong>#<?php echo $booking['id']; ?></strong>
                                                <br><small class="text-muted"><?php echo ucfirst($booking['booking_type']); ?></small>
                                            </td>
                                            <td>
                                                <?php echo htmlspecialchars($booking['passenger_name']); ?>
                                                <br><small class="text-muted"><?php echo $booking['passenger_phone']; ?></small>
                                            </td>
                                            <td>
                                                <?php echo htmlspecialchars($booking['to_location_name']); ?>
                                                <br><small class="text-muted"><?php echo $booking['to_city']; ?></small>
                                            </td>
                                            <td>
                                                <?php if ($booking['auto_rickshaw_id']): ?>
                                                    <?php echo htmlspecialchars($booking['number_plate']); ?>
                                                    <br><small class="text-muted"><?php echo $booking['owner_name']; ?></small>
                                                <?php else: ?>
                                                    <span class="text-muted">Not assigned</span>
                                                <?php endif; ?>
                                            </td>
                                            <td>
                                                <strong>₹<?php echo number_format($booking['total_amount'], 2); ?></strong>
                                                <br><small class="text-muted">Fare: ₹<?php echo number_format($booking['fare_amount'], 2); ?></small>
                                            </td>
                                            <td>
                                                <?php
                                                $statusClass = [
                                                    'confirmed' => 'bg-warning',
                                                    'in_progress' => 'bg-info',
                                                    'completed' => 'bg-success',
                                                    'cancelled' => 'bg-danger'
                                                ];
                                                $statusText = [
                                                    'confirmed' => 'Confirmed',
                                                    'in_progress' => 'In Progress',
                                                    'completed' => 'Completed',
                                                    'cancelled' => 'Cancelled'
                                                ];
                                                ?>
                                                <span class="badge <?php echo $statusClass[$booking['status']] ?? 'bg-secondary'; ?>">
                                                    <?php echo $statusText[$booking['status']] ?? ucfirst($booking['status']); ?>
                                                </span>
                                            </td>
                                            <td>
                                                <?php echo date('H:i', strtotime($booking['created_at'])); ?>
                                                <br><small class="text-muted"><?php echo date('M d', strtotime($booking['created_at'])); ?></small>
                                            </td>
                                            <td>
                                                <div class="btn-group btn-group-sm">
                                                    <!-- View Booking Button (Always visible) -->
                                                    <button type="button" class="btn btn-outline-primary btn-sm" 
                                                            onclick="viewBooking(<?php echo $booking['id']; ?>)">
                                                        <i class="bi bi-eye"></i> View
                                                    </button>
                                                    
                                                    <?php if ($booking['status'] !== 'completed' && $booking['status'] !== 'cancelled'): ?>
                                                        <?php if ($booking['status'] === 'confirmed'): ?>
                                                            <button type="button" class="btn btn-info btn-sm" 
                                                                    onclick="updateStatus(<?php echo $booking['id']; ?>, 'in_progress')">
                                                                Start Trip
                                                            </button>
                                                        <?php elseif ($booking['status'] === 'in_progress'): ?>
                                                            <button type="button" class="btn btn-success btn-sm" 
                                                                    onclick="updateStatus(<?php echo $booking['id']; ?>, 'completed')">
                                                                Complete
                                                            </button>
                                                        <?php endif; ?>
                                                        <button type="button" class="btn btn-danger btn-sm" 
                                                                onclick="updateStatus(<?php echo $booking['id']; ?>, 'cancelled')">
                                                            Cancel
                                                        </button>
                                                    <?php endif; ?>
                                                </div>
                                            </td>
                                        </tr>
                                    <?php endforeach; ?>
                                </tbody>
                            </table>
                        </div>
                    <?php endif; ?>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Status Update Form (Hidden) -->
<form id="statusUpdateForm" method="POST" action="" style="display: none;">
    <input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
    <input type="hidden" name="update_status" value="1">
    <input type="hidden" name="booking_id" id="updateBookingId">
    <input type="hidden" name="new_status" id="updateNewStatus">
</form>

<!-- View Booking Modal -->
<div class="modal fade" id="viewBookingModal" tabindex="-1" aria-labelledby="viewBookingModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="viewBookingModalLabel">
                    <i class="bi bi-eye"></i> Booking Details
                </h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body" id="viewBookingModalBody">
                <!-- Content will be loaded here -->
                <div class="text-center">
                    <div class="spinner-border" role="status">
                        <span class="visually-hidden">Loading...</span>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                <!-- Print Receipt Button - Only show when status is NOT cancelled -->
                <button type="button" class="btn btn-primary" id="printBookingReceiptBtn" style="display: none;">
                    <i class="bi bi-printer"></i> Print Receipt
                </button>
            </div>
        </div>
    </div>
</div>

<script>
function updateStatus(bookingId, newStatus) {
    if (confirm('Are you sure you want to update this booking status?')) {
        document.getElementById('updateBookingId').value = bookingId;
        document.getElementById('updateNewStatus').value = newStatus;
        document.getElementById('statusUpdateForm').submit();
    }
}

function viewBooking(bookingId) {
    // Show the modal
    const modal = new bootstrap.Modal(document.getElementById('viewBookingModal'));
    modal.show();
    
    // Load booking details via AJAX
    loadBookingDetails(bookingId);
}

function loadBookingDetails(bookingId) {
    const modalBody = document.getElementById('viewBookingModalBody');
    const printBtn = document.getElementById('printBookingReceiptBtn');
    
    // Show loading spinner
    modalBody.innerHTML = `
        <div class="text-center">
            <div class="spinner-border" role="status">
                <span class="visually-hidden">Loading...</span>
            </div>
        </div>
    `;
    
    // Fetch booking details
    fetch(`get_booking_details.php?booking_id=${bookingId}`)
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                displayBookingDetails(data.booking);
                // Set print button functionality for all bookings
                printBtn.onclick = () => printBookingReceipt(data.booking);
            } else {
                modalBody.innerHTML = `
                    <div class="alert alert-danger">
                        <i class="bi bi-exclamation-triangle"></i> ${data.message}
                    </div>
                `;
            }
        })
        .catch(error => {
            console.error('Error:', error);
            modalBody.innerHTML = `
                <div class="alert alert-danger">
                    <i class="bi bi-exclamation-triangle"></i> Error loading booking details
                </div>
            `;
        });
}

function displayBookingDetails(booking) {
    const modalBody = document.getElementById('viewBookingModalBody');
    const printBtn = document.getElementById('printBookingReceiptBtn');
    
    const statusClass = {
        'confirmed': 'bg-warning',
        'in_progress': 'bg-info',
        'completed': 'bg-success',
        'cancelled': 'bg-danger'
    };
    
    const statusText = {
        'confirmed': 'Confirmed',
        'in_progress': 'In Progress',
        'completed': 'Completed',
        'cancelled': 'Cancelled'
    };
    
    // Show/hide print button based on status
    if (booking.status === 'cancelled') {
        printBtn.style.display = 'none';
    } else {
        printBtn.style.display = 'inline-block';
    }
    
    modalBody.innerHTML = `
        <div class="row">
            <div class="col-md-6">
                <div class="card mb-3">
                    <div class="card-header">
                        <h6 class="card-title mb-0">
                            <i class="bi bi-person"></i> Passenger Information
                        </h6>
                    </div>
                    <div class="card-body">
                        <p><strong>Name:</strong> ${booking.passenger_name}</p>
                        <p><strong>Phone:</strong> ${booking.passenger_phone}</p>
                        <p><strong>Booking ID:</strong> #${booking.id}</p>
                        <p><strong>Booking Type:</strong> ${booking.booking_type}</p>
                        <p><strong>Created:</strong> ${new Date(booking.created_at).toLocaleString()}</p>
                    </div>
                </div>
            </div>
            
            <div class="col-md-6">
                <div class="card mb-3">
                    <div class="card-header">
                        <h6 class="card-title mb-0">
                            <i class="bi bi-geo-alt"></i> Location Details
                        </h6>
                    </div>
                    <div class="card-body">
                        <p><strong>From:</strong> ${booking.from_location_name || 'Not set'}</p>
                        <p><strong>To:</strong> ${booking.to_location_name}</p>
                        <p><strong>City:</strong> ${booking.to_city}</p>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="row">
            <div class="col-md-6">
                <div class="card mb-3">
                    <div class="card-header">
                        <h6 class="card-title mb-0">
                            <i class="bi bi-truck"></i> Auto Rickshaw Details
                        </h6>
                    </div>
                    <div class="card-body">
                        ${booking.auto_rickshaw_id ? `
                            <p><strong>Number Plate:</strong> ${booking.number_plate}</p>
                            <p><strong>Owner:</strong> ${booking.owner_name}</p>
                            <p><strong>ID:</strong> ${booking.unique_local_id}</p>
                        ` : '<p class="text-muted">Not assigned yet</p>'}
                    </div>
                </div>
            </div>
            
            <div class="col-md-6">
                <div class="card mb-3">
                    <div class="card-header">
                        <h6 class="card-title mb-0">
                            <i class="bi bi-currency-exchange"></i> Payment Details
                        </h6>
                    </div>
                    <div class="card-body">
                        <p><strong>Commission Amount:</strong> ₹${parseFloat(booking.commission_amount).toFixed(2)}</p>
                        <p><strong>Fare Amount:</strong> ₹${parseFloat(booking.fare_amount).toFixed(2)}</p>
                        <p><strong>Total Amount:</strong> ₹${parseFloat(booking.total_amount).toFixed(2)}</p>
                        <p><strong>Status:</strong> 
                            <span class="badge ${statusClass[booking.status]}">${statusText[booking.status]}</span>
                        </p>
                    </div>
                </div>
            </div>
        </div>
        
        ${booking.confirmation_time ? `
            <div class="row">
                <div class="col-12">
                    <div class="card mb-3">
                        <div class="card-header">
                            <h6 class="card-title mb-0">
                                <i class="bi bi-clock"></i> Trip Timeline
                            </h6>
                        </div>
                        <div class="card-body">
                            <p><strong>Confirmed At:</strong> ${new Date(booking.confirmation_time).toLocaleString()}</p>
                            ${booking.completion_time ? `<p><strong>Completed At:</strong> ${new Date(booking.completion_time).toLocaleString()}</p>` : ''}
                        </div>
                    </div>
                </div>
            </div>
        ` : ''}
    `;
}

function printBookingReceipt(booking) {
    // Create a new window for printing
    const printWindow = window.open('', '_blank');
    
    // Define status text mapping
    const statusText = {
        'confirmed': 'Confirmed',
        'in_progress': 'In Progress',
        'completed': 'Completed',
        'cancelled': 'Cancelled'
    };
    
    const receiptContent = `
        <!DOCTYPE html>
        <html>
        <head>
            <title>Receipt #${booking.id}</title>
            <style>
                @media print {
                    body { margin: 0; padding: 0; }
                    .receipt { border: none; box-shadow: none; }
                }
                body { 
                    font-family: 'Courier New', monospace; 
                    margin: 5px; 
                    font-size: 10px; 
                    line-height: 1.2;
                }
                .receipt { 
                    max-width: 300px; 
                    margin: 0 auto; 
                    border: 1px solid #000; 
                    padding: 8px; 
                }
                .header { 
                    text-align: center; 
                    border-bottom: 1px solid #000; 
                    padding-bottom: 5px; 
                    margin-bottom: 8px; 
                }
                .header h3 { 
                    margin: 0 0 2px 0; 
                    font-size: 12px; 
                    font-weight: bold; 
                }
                .header p { 
                    margin: 1px 0; 
                    font-size: 9px; 
                }
                .row { 
                    border-bottom: 1px solid #ccc; 
                    padding: 3px 0; 
                    font-size: 9px;
                }
                .total { 
                    border-top: 1px solid #000; 
                    padding-top: 5px; 
                    margin-top: 8px; 
                    font-weight: bold; 
                }
                .footer { 
                    text-align: center; 
                    margin-top: 8px; 
                    padding-top: 5px; 
                    border-top: 1px solid #ccc; 
                    font-size: 8px;
                }
                .footer p { margin: 1px 0; }
            </style>
        </head>
        <body>
            <div class="receipt">
                <div class="header">
                    <h3>AUTO RICKSHAW SERVICE</h3>
                    <p>Booking Receipt</p>
                    <p>Date: ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}</p>
                </div>
                
                <div class="row">
                    <strong>Passenger:</strong> ${booking.passenger_name}
                </div>
                <div class="row">
                    <strong>From:</strong> ${booking.from_location_name || 'Not set'}
                </div>
                <div class="row">
                    <strong>To:</strong> ${booking.to_location_name}
                </div>
                ${booking.auto_rickshaw_id ? `
                    <div class="row">
                        <strong>Rickshaw:</strong> ${booking.number_plate}
                    </div>
                    <div class="row">
                        <strong>Driver:</strong> ${booking.owner_name}
                    </div>
                ` : ''}
                
                <div class="total">
                    <div style="display: flex; justify-content: space-between; margin-bottom: 3px;">
                        <span>Commission:</span>
                        <span>₹${parseFloat(booking.commission_amount).toFixed(2)}</span>
                    </div>
                    <div style="display: flex; justify-content: space-between; margin-bottom: 3px;">
                        <span>Fare:</span>
                        <span>₹${parseFloat(booking.fare_amount).toFixed(2)}</span>
                    </div>
                    <div style="display: flex; justify-content: space-between; font-weight: bold; font-size: 16px; margin-top: 8px; padding-top: 8px; border-top: 2px solid #000;">
                        <span>Total:</span>
                        <span>₹${parseFloat(booking.fare_amount).toFixed(2)}</span>
                    </div>
                </div>
                
                <div class="footer">
                    <p>Thank you for using our service!</p>
                    <p>Status: ${statusText[booking.status]}</p>
                </div>
            </div>
        </body>
        </html>
    `;
    
    printWindow.document.write(receiptContent);
    printWindow.document.close();
    
    // Wait for content to load then print
    printWindow.onload = function() {
        printWindow.print();
        printWindow.close();
    };
}
</script>

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