Path : /home/vishqocm/pcib.in/student/
File Upload :
Current File : /home/vishqocm//pcib.in/student/attendance_report.php

<?php
$pageTitle = "Attendance Report";
include_once('includes/header.php');

// Check if student is logged in
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'student') {
    header("Location: ../login.php");
    exit();
}

$userId = $_SESSION['user_id'];

// Get course enrollments for filter dropdown
$courses_query = "
    SELECT c.id, c.title 
    FROM courses c
    INNER JOIN enrollments e ON c.id = e.course_id
    WHERE e.user_id = ? AND e.status = 'active'
    ORDER BY c.title
";
$stmt = $conn->prepare($courses_query);
$stmt->bind_param("i", $userId);
$stmt->execute();
$courses_result = $stmt->get_result();
$courses = [];
while ($row = $courses_result->fetch_assoc()) {
    $courses[] = $row;
}

// Default filter for current month
$selected_month = date('m');
$selected_year = date('Y');
$selected_course = 0; // 0 means all courses

// Apply filters if submitted
if (isset($_GET['filter'])) {
    $selected_month = isset($_GET['month']) ? $_GET['month'] : date('m');
    $selected_year = isset($_GET['year']) ? $_GET['year'] : date('Y');
    $selected_course = isset($_GET['course_id']) ? intval($_GET['course_id']) : 0;
}

// Fetch attendance data based on filters
$attendance_query = "
    SELECT a.id, a.date, a.status, a.notes, c.title as course_title
    FROM attendance a
    INNER JOIN enrollments e ON a.enrollment_id = e.id
    INNER JOIN courses c ON e.course_id = c.id
    WHERE e.user_id = ?
";

// Add filter conditions
if ($selected_course > 0) {
    $attendance_query .= " AND e.course_id = ?";
}
if ($selected_month > 0) {
    $attendance_query .= " AND MONTH(a.date) = ?";
}
if ($selected_year > 0) {
    $attendance_query .= " AND YEAR(a.date) = ?";
}

$attendance_query .= " ORDER BY a.date DESC";

// Prepare and bind parameters
$stmt = $conn->prepare($attendance_query);
$param_types = "i";
$params = [$userId];

if ($selected_course > 0) {
    $param_types .= "i";
    $params[] = $selected_course;
}
if ($selected_month > 0) {
    $param_types .= "i";
    $params[] = $selected_month;
}
if ($selected_year > 0) {
    $param_types .= "i";
    $params[] = $selected_year;
}

// Dynamic bind_param
$stmt->bind_param($param_types, ...$params);
$stmt->execute();
$attendance_result = $stmt->get_result();
$attendance_records = [];
while ($row = $attendance_result->fetch_assoc()) {
    $attendance_records[] = $row;
}

// Calculate statistics
$total_records = count($attendance_records);
$present_count = 0;
$absent_count = 0;
$late_count = 0;
$excused_count = 0;

$daily_status = [];
$course_stats = [];

foreach ($attendance_records as $record) {
    $date = date('Y-m-d', strtotime($record['date']));
    $course = $record['course_title'];
    
    // Count by status
    if ($record['status'] === 'present') {
        $present_count++;
    } elseif ($record['status'] === 'absent') {
        $absent_count++;
    } elseif ($record['status'] === 'late') {
        $late_count++;
    } elseif ($record['status'] === 'excused') {
        $excused_count++;
    }
    
    // Prepare data for daily chart
    if (!isset($daily_status[$date])) {
        $daily_status[$date] = ['present' => 0, 'absent' => 0, 'late' => 0, 'excused' => 0];
    }
    $daily_status[$date][$record['status']]++;
    
    // Prepare data for course-wise chart
    if (!isset($course_stats[$course])) {
        $course_stats[$course] = ['present' => 0, 'absent' => 0, 'late' => 0, 'excused' => 0, 'total' => 0];
    }
    $course_stats[$course][$record['status']]++;
    $course_stats[$course]['total']++;
}

// After the main attendance stats calculation section, add the course-wise percentage calculation
foreach ($course_stats as $course => &$stats) {
    if ($stats['total'] > 0) {
        $stats['present_percent'] = round(($stats['present'] / $stats['total']) * 100, 1);
        $stats['absent_percent'] = round(($stats['absent'] / $stats['total']) * 100, 1);
        $stats['late_percent'] = round(($stats['late'] / $stats['total']) * 100, 1);
        $stats['excused_percent'] = round(($stats['excused'] / $stats['total']) * 100, 1);
    } else {
        $stats['present_percent'] = 0;
        $stats['absent_percent'] = 0;
        $stats['late_percent'] = 0;
        $stats['excused_percent'] = 0;
    }
}

// Prepare chart data
$dates = array_keys($daily_status);
$present_data = array_column(array_values($daily_status), 'present');
$absent_data = array_column(array_values($daily_status), 'absent');
$late_data = array_column(array_values($daily_status), 'late');
$excused_data = array_column(array_values($daily_status), 'excused');

$course_names = array_keys($course_stats);
$course_attendance_percent = [];

foreach ($course_names as $course_name) {
    $total = $course_stats[$course_name]['total'];
    if ($total > 0) {
        $course_attendance_percent[$course_name] = round(($course_stats[$course_name]['present'] / $total) * 100, 1);
    } else {
        $course_attendance_percent[$course_name] = 0;
    }
}

// Calculate attendance percentage
$attendance_percentage = $total_records > 0 ? round(($present_count / $total_records) * 100, 1) : 0;
$absent_percentage = $total_records > 0 ? round(($absent_count / $total_records) * 100, 1) : 0;
$late_percentage = $total_records > 0 ? round(($late_count / $total_records) * 100, 1) : 0;
$excused_percentage = $total_records > 0 ? round(($excused_count / $total_records) * 100, 1) : 0;

// Calculate monthly attendance trend
$months = [];
$monthly_percentage = [];

// Get data for last 6 months for trend analysis
for ($i = 5; $i >= 0; $i--) {
    $month = date('m', strtotime("-$i months"));
    $year = date('Y', strtotime("-$i months"));
    $month_name = date('M Y', strtotime("$year-$month-01"));
    
    $monthly_query = "
        SELECT a.status
        FROM attendance a
        INNER JOIN enrollments e ON a.enrollment_id = e.id
        WHERE e.user_id = ? AND MONTH(a.date) = ? AND YEAR(a.date) = ?
    ";
    
    $stmt = $conn->prepare($monthly_query);
    $stmt->bind_param("iii", $userId, $month, $year);
    $stmt->execute();
    $monthly_result = $stmt->get_result();
    
    $month_present = 0;
    $month_total = 0;
    
    while ($row = $monthly_result->fetch_assoc()) {
        $month_total++;
        if ($row['status'] === 'present') {
            $month_present++;
        }
    }
    
    $months[] = $month_name;
    $monthly_percentage[] = $month_total > 0 ? round(($month_present / $month_total) * 100, 1) : 0;
}
?>

<div class="container py-4">
    <h2 class="mb-4">Attendance Report</h2>
    
    <!-- Filter Form -->
    <div class="card mb-4">
        <div class="card-body">
            <form method="GET" class="row g-3">
                <div class="col-md-3">
                    <label for="course_id" class="form-label">Course</label>
                    <select class="form-select" id="course_id" name="course_id">
                        <option value="0" <?php echo $selected_course == 0 ? 'selected' : ''; ?>>All Courses</option>
                        <?php foreach ($courses as $course): ?>
                        <option value="<?php echo $course['id']; ?>" <?php echo $selected_course == $course['id'] ? 'selected' : ''; ?>>
                            <?php echo htmlspecialchars($course['title']); ?>
                        </option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <div class="col-md-3">
                    <label for="month" class="form-label">Month</label>
                    <select class="form-select" id="month" name="month">
                        <option value="0" <?php echo $selected_month == 0 ? 'selected' : ''; ?>>All Months</option>
                        <?php for ($i = 1; $i <= 12; $i++): ?>
                        <option value="<?php echo $i; ?>" <?php echo $selected_month == $i ? 'selected' : ''; ?>>
                            <?php echo date('F', mktime(0, 0, 0, $i, 1)); ?>
                        </option>
                        <?php endfor; ?>
                    </select>
                </div>
                <div class="col-md-3">
                    <label for="year" class="form-label">Year</label>
                    <select class="form-select" id="year" name="year">
                        <?php for ($i = date('Y'); $i >= date('Y') - 5; $i--): ?>
                        <option value="<?php echo $i; ?>" <?php echo $selected_year == $i ? 'selected' : ''; ?>>
                            <?php echo $i; ?>
                        </option>
                        <?php endfor; ?>
                    </select>
                </div>
                <div class="col-md-3">
                    <label class="form-label">&nbsp;</label>
                    <button type="submit" name="filter" class="btn btn-primary w-100">
                        <i class="fas fa-filter me-2"></i>Apply Filter
                    </button>
                </div>
            </form>
        </div>
    </div>
    
    <!-- Attendance Overview Cards -->
    <div class="row mb-4">
        <div class="col-md-3 mb-3">
            <div class="card h-100 shadow-sm">
                <div class="card-body text-center d-flex flex-column justify-content-center">
                    <div class="attendance-chart-container position-relative" style="width: 120px; height: 120px; margin: 0 auto;">
                        <canvas id="attendancePercentDoughnut"></canvas>
                        <div class="position-absolute top-50 start-50 translate-middle">
                            <h3 class="mb-0"><?php echo $attendance_percentage; ?>%</h3>
                            <div class="small text-muted">Present</div>
                        </div>
                    </div>
                    <h5 class="mt-3 mb-0">Overall Attendance</h5>
                    <div class="small text-muted"><?php echo $present_count; ?> out of <?php echo $total_records; ?> days</div>
                </div>
            </div>
        </div>

        <div class="col-md-3 mb-3">
            <div class="card h-100 shadow-sm">
                <div class="card-body p-3">
                    <h6 class="card-title text-muted mb-3">Attendance Breakdown</h6>
                    
                    <div class="mb-2">
                        <div class="d-flex justify-content-between mb-1">
                            <span class="small">Present</span>
                            <span class="small text-success"><?php echo $present_count; ?> (<?php echo $attendance_percentage; ?>%)</span>
                        </div>
                        <div class="progress" style="height: 10px;">
                            <div class="progress-bar bg-success" role="progressbar" style="width: <?php echo $attendance_percentage; ?>%" 
                                 aria-valuenow="<?php echo $attendance_percentage; ?>" aria-valuemin="0" aria-valuemax="100"></div>
                        </div>
                    </div>
                    
                    <div class="mb-2">
                        <div class="d-flex justify-content-between mb-1">
                            <span class="small">Absent</span>
                            <span class="small text-danger"><?php echo $absent_count; ?> (<?php echo $absent_percentage; ?>%)</span>
                        </div>
                        <div class="progress" style="height: 10px;">
                            <div class="progress-bar bg-danger" role="progressbar" style="width: <?php echo $absent_percentage; ?>%" 
                                 aria-valuenow="<?php echo $absent_percentage; ?>" aria-valuemin="0" aria-valuemax="100"></div>
                        </div>
                    </div>
                    
                    <div class="mb-2">
                        <div class="d-flex justify-content-between mb-1">
                            <span class="small">Late</span>
                            <span class="small text-warning"><?php echo $late_count; ?> (<?php echo $late_percentage; ?>%)</span>
                        </div>
                        <div class="progress" style="height: 10px;">
                            <div class="progress-bar bg-warning" role="progressbar" style="width: <?php echo $late_percentage; ?>%" 
                                 aria-valuenow="<?php echo $late_percentage; ?>" aria-valuemin="0" aria-valuemax="100"></div>
                        </div>
                    </div>
                    
                    <div>
                        <div class="d-flex justify-content-between mb-1">
                            <span class="small">Excused</span>
                            <span class="small text-info"><?php echo $excused_count; ?> (<?php echo $excused_percentage; ?>%)</span>
                        </div>
                        <div class="progress" style="height: 10px;">
                            <div class="progress-bar bg-info" role="progressbar" style="width: <?php echo $excused_percentage; ?>%" 
                                 aria-valuenow="<?php echo $excused_percentage; ?>" aria-valuemin="0" aria-valuemax="100"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class="col-md-6 mb-3">
            <div class="card h-100 shadow-sm">
                <div class="card-body">
                    <h6 class="card-title text-muted mb-3">Attendance Trend (6 Months)</h6>
                    <div style="height: 170px;">
                        <canvas id="attendanceTrendChart"></canvas>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <!-- Course-wise Attendance -->
    <?php if (count($course_stats) > 0): ?>
    <div class="card mb-4">
        <div class="card-header">
            <h5 class="mb-0 text-primary font-weight-bold">Course-wise Attendance</h5>
        </div>
        <div class="card-body">
            <div class="row">
                <div class="col-md-6">
                    <div style="height: 300px;">
                        <canvas id="courseAttendanceChart"></canvas>
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="table-responsive">
                        <table class="table table-hover">
                            <thead>
                                <tr>
                                    <th>Course</th>
                                    <th>Present</th>
                                    <th>Absent</th>
                                    <th>Late</th>
                                    <th>Attendance %</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php foreach ($course_stats as $course => $stats): ?>
                                <tr>
                                    <td><?php echo htmlspecialchars($course); ?></td>
                                    <td><?php echo $stats['present']; ?></td>
                                    <td><?php echo $stats['absent']; ?></td>
                                    <td><?php echo $stats['late']; ?></td>
                                    <td>
                                        <div class="d-flex align-items-center">
                                            <div class="progress flex-grow-1 me-2" style="height: 8px;">
                                                <div class="progress-bar bg-success" role="progressbar" 
                                                     style="width: <?php echo $stats['present_percent']; ?>%" 
                                                     aria-valuenow="<?php echo $stats['present_percent']; ?>" 
                                                     aria-valuemin="0" aria-valuemax="100"></div>
                                            </div>
                                            <span class="text-success"><?php echo $stats['present_percent']; ?>%</span>
                                        </div>
                                    </td>
                                </tr>
                                <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <?php endif; ?>
    
    <!-- Daily Attendance Chart -->
    <div class="card mb-4">
        <div class="card-header">
            <h5 class="mb-0 text-primary font-weight-bold">Daily Attendance Report</h5>
        </div>
        <div class="card-body">
            <?php if (count($attendance_records) > 0): ?>
            <div class="mb-4" style="height: 300px;">
                <canvas id="dailyAttendanceChart"></canvas>
            </div>
            <div class="table-responsive">
                <table class="table table-striped table-hover">
                    <thead>
                        <tr>
                            <th>Date</th>
                            <th>Course</th>
                            <th>Status</th>
                            <th>Notes</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($attendance_records as $record): ?>
                        <tr>
                            <td><?php echo date('d M Y', strtotime($record['date'])); ?></td>
                            <td><?php echo htmlspecialchars($record['course_title']); ?></td>
                            <td>
                                <span class="badge bg-<?php 
                                    echo $record['status'] === 'present' ? 'success' : 
                                         ($record['status'] === 'absent' ? 'danger' : 
                                          ($record['status'] === 'late' ? 'warning' : 'info')); ?>">
                                    <?php echo ucfirst($record['status']); ?>
                                </span>
                            </td>
                            <td><?php echo htmlspecialchars($record['notes'] ?? 'No notes'); ?></td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
            <?php else: ?>
            <div class="alert alert-info">
                <i class="fas fa-info-circle me-2"></i> No attendance records found for the selected filters.
            </div>
            <?php endif; ?>
        </div>
    </div>
</div>

<!-- Include Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<script>
document.addEventListener('DOMContentLoaded', function() {
    // Doughnut chart for overall attendance
    new Chart(document.getElementById('attendancePercentDoughnut'), {
        type: 'doughnut',
        data: {
            datasets: [{
                data: [<?php echo $attendance_percentage; ?>, <?php echo 100 - $attendance_percentage; ?>],
                backgroundColor: ['#28a745', '#f0f0f0'],
                borderWidth: 0
            }]
        },
        options: {
            cutout: '75%',
            responsive: true,
            maintainAspectRatio: true,
            plugins: {
                legend: {
                    display: false
                },
                tooltip: {
                    enabled: false
                }
            }
        }
    });
    
    // Course attendance bar chart
    <?php if (count($course_stats) > 0): ?>
    new Chart(document.getElementById('courseAttendanceChart'), {
        type: 'bar',
        data: {
            labels: <?php echo json_encode(array_keys($course_stats)); ?>,
            datasets: [{
                label: 'Attendance %',
                data: <?php echo json_encode(array_column($course_stats, 'present_percent')); ?>,
                backgroundColor: '#28a745',
                borderColor: '#28a745',
                borderWidth: 1
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: true,
            plugins: {
                legend: {
                    display: false
                }
            },
            scales: {
                y: {
                    beginAtZero: true,
                    max: 100,
                    ticks: {
                        callback: function(value) {
                            return value + '%';
                        }
                    }
                }
            }
        }
    });
    <?php endif; ?>
    
    // Daily attendance stacked bar chart
    <?php if (count($daily_status) > 0): ?>
    new Chart(document.getElementById('dailyAttendanceChart'), {
        type: 'bar',
        data: {
            labels: <?php echo json_encode(array_map(function($date) { return date('d M', strtotime($date)); }, $dates)); ?>,
            datasets: [
                {
                    label: 'Present',
                    data: <?php echo json_encode($present_data); ?>,
                    backgroundColor: '#28a745'
                },
                {
                    label: 'Absent',
                    data: <?php echo json_encode($absent_data); ?>,
                    backgroundColor: '#dc3545'
                },
                {
                    label: 'Late',
                    data: <?php echo json_encode($late_data); ?>,
                    backgroundColor: '#ffc107'
                },
                {
                    label: 'Excused',
                    data: <?php echo json_encode($excused_data); ?>,
                    backgroundColor: '#17a2b8'
                }
            ]
        },
        options: {
            responsive: true,
            maintainAspectRatio: true,
            scales: {
                x: {
                    stacked: true
                },
                y: {
                    stacked: true,
                    beginAtZero: true,
                    ticks: {
                        stepSize: 1
                    }
                }
            }
        }
    });
    <?php endif; ?>
    
    // Attendance trend line chart
    new Chart(document.getElementById('attendanceTrendChart'), {
        type: 'line',
        data: {
            labels: <?php echo json_encode($months); ?>,
            datasets: [{
                label: 'Attendance %',
                data: <?php echo json_encode($monthly_percentage); ?>,
                backgroundColor: 'rgba(40, 167, 69, 0.2)',
                borderColor: '#28a745',
                borderWidth: 2,
                tension: 0.3,
                fill: true,
                pointBackgroundColor: '#28a745',
                pointRadius: 4
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: true,
            plugins: {
                legend: {
                    display: false
                }
            },
            scales: {
                y: {
                    beginAtZero: true,
                    max: 100,
                    ticks: {
                        callback: function(value) {
                            return value + '%';
                        }
                    }
                }
            }
        }
    });
});
</script>

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