Skip to content

Attendance Controller

Overview

The attendance.controller.js module manages attendance operations for students, faculty, and administrators. It supports creation, modification, and retrieval of attendance records, as well as analytics such as attendance percentage calculations, bulk uploads, and pending approval management.

Dependencies

import { Course } from '../models/course.model.js';
import { Attendance } from '../models/attendance.model.js';
import { FacultyCourse } from '../models/course.model.js';
import { StudentCourse } from '../models/course.model.js';
import { Student } from '../models/student.model.js';`

Controller Methods

Student Side

getPercentages

Calculates per-course attendance percentage for a student.

Input: - Header: rollno

Process: 1. Aggregates total and present approved attendance per course. 2. Fetches course names for mapping. 3. Computes percentages for each course.

Key Code Snippet

const totalRecords = await Attendance.aggregate([{ $match: { rollNo } }, { $group: { _id: "$courseCode", totalDays: { $sum: 1 } } }]);
const presentRecords = await Attendance.aggregate([{ $match: { rollNo, isPresent: true, isApproved: true } }, { $group: { _id: "$courseCode", presentDays: { $sum: 1 } } }]);
const percentage = (presentDays / totalDays) * 100;

Output: - Success (200): Attendance percentage per course. - Error (400/500): Missing roll number or internal server error.

getCourse

Fetches full attendance data and statistics for a specific course.

Input: - req.params: courseId - Header: rollno

Process: 1. Fetches course and student attendance records. 2. Computes attendance statistics and events list. 3. Builds response with summary and calendar view format.

Key Code Snippet

const attendanceAll = await Attendance.find({ courseCode: courseId, rollNo: studentId });
const classesAttended = attendanceAll.filter(record => record.isPresent && record.isApproved).length;
const percentage = ((classesAttended / (classesAttended + classesMissed)) * 100).toFixed(2);

Output: - Success (200): Full course attendance details. - Error (400/404/500): Missing or invalid data.

createAttendanceRecord

Creates an individual attendance record for a student.

Input: - Header: rollno - Body: courseCode, date, isPresent, isApproved

Process: 1. Validates existence of course and student. 2. Ensures record for the same date does not already exist. 3. Creates a new attendance document.

Key Code Snippet

const existingRecord = await Attendance.findOne({ courseCode, rollNo, date: new Date(date) });
const newAttendance = new Attendance({ courseCode, rollNo, date: new Date(date), isPresent, isApproved });
await newAttendance.save();

Output: - Success (201): Created record. - Error (400/500): Validation or server error.

createBulkAttendanceRecords

Uploads multiple attendance records in bulk.

Input: - req.body: attendanceRecords[] (each with rollNo, date, status) - req.params: id (courseCode)

Process: 1. Iterates over each record. 2. Converts and validates dates. 3. Internally calls createAttendanceRecord for each.

Key Code Snippet

const [year, month, day] = record.date.split('-');
const mongoDate = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
await createAttendanceRecord(mockReq, mockRes);

Output: - Success (200): Summary of successes and failures. - Error (400/500): Input validation or internal error.

Faculty Side

getFacultyCourses

Fetches faculty-assigned courses along with attendance analytics.

Input: - Header: userid (faculty ID)

Process: 1. Retrieves courses assigned to the faculty. 2. Aggregates attendance data. 3. Computes student count and average attendance.

Key Code Snippet

const attendanceRecords = await Attendance.find({ courseCode: course.courseCode });
const totalPresent = attendanceRecords.filter(record => record.isPresent && record.isApproved).length;
const attendancePercentage = totalAttendance > 0 ? (totalPresent / totalAttendance) * 100 : 0;

Output: - Success (200): Courses with attendance stats. - Error (400/404/500): Faculty not found or internal error.

addFacultyCourse

Assigns a course to a faculty member.

Input: - Body: facultyId, courseCode, year, session, status (optional)

Process: 1. Validates input and year range. 2. Prevents duplicate assignments for session+year. 3. Creates and saves course mapping.

Key Code Snippet

const existingCourse = await FacultyCourse.findOne({ facultyId, courseCode, year, session });
const newFacultyCourse = new FacultyCourse({ facultyId, courseCode, year, session, status: status || 'Ongoing' });
await newFacultyCourse.save();

Output: - Success (201): Mapping created. - Error (400/409/500): Validation or internal error.

getStudents

Returns roll numbers of students enrolled in a course.

Input: - req.params: id (course ID)

Process: 1. Queries StudentCourse collection for approved entries. 2. Extracts roll numbers.

Key Code Snippet

const enrolledStudents = await StudentCourse.find({ courseId, status: 'Approved' }).select('rollNo -_id');

Output: - Success (200): List of student roll numbers. - Error (400/500): Missing course ID or internal error.

modifyAttendanceRecord

Updates attendance for a specific student, date, and course.

Input: - Header: rollno - Body: courseCode, date, isPresent, isApproved

Process: 1. Locates the attendance record for the date. 2. Updates isPresent, isApproved, and timestamp.

Key Code Snippet

const attendanceRecord = await Attendance.findOne({
  courseCode,
  rollNo,
  date: { $gte: startOfDay, $lte: endOfDay }
});
attendanceRecord.isPresent = isPresent;
attendanceRecord.isApproved = isApproved;
await attendanceRecord.save();

Output: - Success (200): Updated record. - Error (400/404/500): Validation failure or not found.

Admin Side

getAllCourses

Fetches minimal course data for UI dropdowns or listings.

Input: - None

Process: 1. Fetches all courses selecting courseCode and courseName.

Key Code Snippet

const courses = await Course.find({}, 'courseCode courseName');

Output: - Success (200): Course data. - Error (500): Internal server error.

getApprovalRequests

Fetches all attendance entries pending approval.

Input: - None

Process: 1. Queries for attendance with isApproved = false. 2. Formats response with courseId, studentId, date, etc.

Key Code Snippet

const pendingApprovals = await Attendance.find({ isApproved: false }).sort({ createdAt: -1 });

Output: - Success (200): List of unapproved entries. - Error (500): Server error.

approveCourse

Approves a specific attendance record.

Input: - Body: courseCode, rollNo, date

Process: 1. Converts date into startOfDay and endOfDay. 2. Updates the matching record to isApproved = true.

Key Code Snippet

const attendanceRecord = await Attendance.findOneAndUpdate(
  { courseCode, rollNo, date: { $gte: startOfDay, $lte: endOfDay } },
  { isApproved: true, updatedAt: Date.now() },
  { new: true }
);

Output: - Success (200): Updated record. - Error (400/404/500): Validation or internal error.

getAllStudents

Returns all registered student roll numbers.

Input: - None

Process: 1. Queries the Student collection and selects rollNo.

Key Code Snippet

const students = await Student.find({}, 'rollNo');

Output: - Success (200): List of roll numbers. - Error (500): Internal server error.

Error Handling Strategy

  • Consistent status codes for all endpoints (400, 404, 500).
  • Validation for required parameters and formats.
  • Descriptive error messages for frontend consumption.
  • Try-catch blocks around all async database calls.

Functional Highlights

  • Student: View attendance stats and course records.
  • Faculty: Manage course attendance and analytics.
  • Admin: Review and approve attendance logs.
  • Bulk upload: Efficient multi-student record processing.