Improve attendance completion checks and expose recorded counts.
Only count existing enrolled students when deciding if a session is fully recorded, and return per-session attendance totals for the dashboard list.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
const Session = require('./sessionModel');
|
||||
const Course = require('../courses/courseModel');
|
||||
const Class = require('../classes/classModel');
|
||||
const User = require('../users/userModel');
|
||||
const Professor = require('../professors/professorModel');
|
||||
const AppError = require('../../utils/AppError');
|
||||
const eventEmitter = require('../../events/eventEmitter');
|
||||
@@ -124,7 +125,31 @@ const buildStudentsByClassId = async (sessions) => {
|
||||
if (!classIds.length) return new Map();
|
||||
|
||||
const classes = await Class.find({ _id: { $in: classIds } }).select('students').lean();
|
||||
return new Map(classes.map((cls) => [String(cls._id), cls.students || []]));
|
||||
const allStudentIds = [...new Set(
|
||||
classes.flatMap((cls) => (cls.students || []).map(normalizeId)).filter(Boolean)
|
||||
)];
|
||||
|
||||
let existingSet = new Set();
|
||||
if (allStudentIds.length) {
|
||||
const existingUsers = await User.find({ _id: { $in: allStudentIds } }).select('_id').lean();
|
||||
existingSet = new Set(existingUsers.map((user) => normalizeId(user._id)));
|
||||
}
|
||||
|
||||
return new Map(classes.map((cls) => {
|
||||
const validStudentIds = (cls.students || [])
|
||||
.map(normalizeId)
|
||||
.filter((id) => existingSet.has(id));
|
||||
return [String(cls._id), validStudentIds];
|
||||
}));
|
||||
};
|
||||
|
||||
const getValidStudentIdsForClass = async (classItem) => {
|
||||
if (!classItem) return [];
|
||||
const rawIds = (classItem.students || []).map(normalizeId).filter(Boolean);
|
||||
if (!rawIds.length) return [];
|
||||
const existingUsers = await User.find({ _id: { $in: rawIds } }).select('_id').lean();
|
||||
const existingSet = new Set(existingUsers.map((user) => normalizeId(user._id)));
|
||||
return rawIds.filter((id) => existingSet.has(id));
|
||||
};
|
||||
|
||||
const isSessionDue = (session) => {
|
||||
@@ -156,12 +181,21 @@ const hasCompleteAttendance = (session, studentsByClassId = null) => {
|
||||
const isAttendancePending = (session, studentsByClassId = null) =>
|
||||
isSessionDue(session) && !hasCompleteAttendance(session, studentsByClassId);
|
||||
|
||||
const enrichSessionAttendance = (session, studentsByClassId = null) => ({
|
||||
const enrichSessionAttendance = (session, studentsByClassId = null) => {
|
||||
const studentIds = getClassStudentIds(session, studentsByClassId);
|
||||
const recordedIds = getRecordedUserIds(session);
|
||||
const studentSet = new Set(studentIds);
|
||||
const attendanceRecordedCount = recordedIds.filter((id) => studentSet.has(id)).length;
|
||||
|
||||
return {
|
||||
...session,
|
||||
isDue: isSessionDue(session),
|
||||
attendanceTotalCount: studentIds.length,
|
||||
attendanceRecordedCount,
|
||||
attendanceComplete: hasCompleteAttendance(session, studentsByClassId),
|
||||
attendancePending: isAttendancePending(session, studentsByClassId)
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const filterByAttendanceScope = (sessions, scope, studentsByClassId = null) => {
|
||||
const dueSessions = sessions.filter(isSessionDue);
|
||||
@@ -351,7 +385,12 @@ const updateSessionAttendance = async (sessionId, attendanceList, recordedBy = n
|
||||
await session.save();
|
||||
|
||||
const classItem = await Class.findById(session.class).select('students').lean();
|
||||
if (classItem && hasCompleteAttendance({ ...session.toObject(), class: classItem }) && session.status !== 'cancelled') {
|
||||
const validStudentIds = await getValidStudentIdsForClass(classItem);
|
||||
if (
|
||||
classItem
|
||||
&& hasCompleteAttendance({ ...session.toObject(), class: { ...classItem, students: validStudentIds } })
|
||||
&& session.status !== 'cancelled'
|
||||
) {
|
||||
session.status = 'held';
|
||||
await session.save();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user