backend_adaptive_learning/controllers/learningControllers/stdLearning.js

675 lines
17 KiB
JavaScript

import response from "../../response.js";
import models from "../../models/index.js";
import { createMonitoring } from "../monitoringControllers/monitoring.js";
export const getStdLearnings = async (req, res) => {
try {
const stdLearning = await models.StdLearning.findAll();
response(200, stdLearning, "Success", res);
} catch (error) {
console.log(error);
response(500, null, "Error retrieving student learning data!", res);
}
};
export const getStdLearningById = async (req, res) => {
try {
const { id } = req.params;
const stdLearning = await models.StdLearning.findByPk(id);
if (!stdLearning) {
return response(404, null, "Student learning data not found", res);
}
response(200, stdLearning, "Success", res);
} catch (error) {
response(500, null, "Internal Server Error", res);
}
};
export const createStdLearning = async (req, res) => {
const { ID_LEVEL } = req.body;
if (!req.user) {
return response(401, null, "User not authenticated", res);
}
const ID = req.user.ID;
try {
if (req.stdLearning) {
return response(
200,
req.stdLearning,
"Student Learning data found and reused",
res
);
}
const level = await models.Level.findByPk(ID_LEVEL);
if (!level) {
return response(404, null, "Level not found", res);
}
const newStdLearning = await models.StdLearning.create({
ID,
ID_LEVEL,
});
response(
201,
newStdLearning,
"Student Learning data created successfully",
res
);
} catch (error) {
console.log(error);
response(500, null, "Internal Server Error", res);
}
};
export const updateStdLearningById = async (req, res) => {
const { id } = req.params;
const { FEEDBACK_STUDENT } = req.body;
try {
const stdLearning = await models.StdLearning.findByPk(id, {
include: [
{
model: models.Level,
as: "level",
},
],
});
if (!stdLearning) {
return response(404, null, "Student Learning record not found", res);
}
if (req.user.ID !== stdLearning.ID) {
return response(403, null, "Unauthorized to update this record", res);
}
stdLearning.STUDENT_FINISH = new Date();
stdLearning.SCORE = req.body.SCORE || stdLearning.SCORE;
stdLearning.NEXT_LEARNING =
req.body.NEXT_LEARNING || stdLearning.NEXT_LEARNING;
stdLearning.IS_PASS = req.body.IS_PASS || stdLearning.IS_PASS;
if (FEEDBACK_STUDENT) {
stdLearning.FEEDBACK_STUDENT = FEEDBACK_STUDENT;
}
await stdLearning.save();
const level6 = await models.Level.findOne({
where: {
NAME_LEVEL: "Level 6",
ID_TOPIC: stdLearning.level.ID_TOPIC,
},
});
if (!level6) {
return response(404, null, "Level 6 not found", res);
}
if (
stdLearning.level.ID_LEVEL === level6.ID_LEVEL &&
stdLearning.IS_PASS === 1
) {
req.body.ID_STUDENT_LEARNING = id;
const existingMonitoring = await models.Monitoring.findOne({
where: { ID_STUDENT_LEARNING: id },
});
if (!existingMonitoring) {
const newMonitoring = await createMonitoring(req);
const { level, ...responseData } = stdLearning.toJSON();
const combinedPayload = {
...responseData,
MONITORING: newMonitoring,
};
return response(
200,
combinedPayload,
"Student Learning record updated and monitoring created successfully",
res
);
}
} else {
const monitoringToDelete = await models.Monitoring.findOne({
where: { ID_STUDENT_LEARNING: id },
});
if (monitoringToDelete) {
await monitoringToDelete.destroy();
}
}
const { level, ...responseData } = stdLearning.toJSON();
response(
200,
responseData,
"Student Learning record updated successfully",
res
);
} catch (error) {
console.log(error);
response(500, null, "Internal Server Error", res);
}
};
export const learningScoreByStdLearningId = async (req, res) => {
try {
if (!req.user) {
return response(401, null, "User not authenticated", res);
}
const { ID } = req.user;
const { stdLearningId } = req.params;
const stdLearning = await models.StdLearning.findOne({
where: {
ID_STUDENT_LEARNING: stdLearningId,
ID: ID,
},
include: [
{
model: models.Level,
as: "level",
attributes: ["ID_LEVEL", "NAME_LEVEL"],
},
{
model: models.Level,
as: "nextLevel",
attributes: ["NAME_LEVEL"],
},
{
model: models.User,
as: "learningUser",
attributes: ["NAME_USERS"],
include: [
{
model: models.Student,
as: "students",
attributes: ["NISN"],
},
],
},
],
});
if (!stdLearning) {
return response(
404,
null,
"No matching learning data found for this user",
res
);
}
if (!stdLearning.NEXT_LEARNING || !stdLearning.nextLevel) {
return response(200, null, "No next learning level found", res);
}
const nextLearningData = {
ID_STUDENT_LEARNING: stdLearning.ID_STUDENT_LEARNING,
NAME_USERS: stdLearning.learningUser.NAME_USERS,
NISN: stdLearning.learningUser.students
? stdLearning.learningUser.students.NISN
: null,
ID_LEVEL: stdLearning.level ? stdLearning.level.ID_LEVEL : null,
CURRENT_LEVEL_NAME: stdLearning.level
? stdLearning.level.NAME_LEVEL
: null,
SCORE: stdLearning.SCORE,
NEXT_LEARNING: stdLearning.NEXT_LEARNING,
NEXT_LEARNING_NAME: stdLearning.nextLevel.NAME_LEVEL,
IS_PASS: stdLearning.IS_PASS,
};
return response(200, nextLearningData, "Success", res);
} catch (error) {
console.log(error);
return response(500, null, "Internal Server Error", res);
}
};
export const learningHistory = async (req, res) => {
const { page = 1, limit = 10 } = req.query;
try {
if (!req.user) {
return response(401, null, "User not authenticated", res);
}
const { ID } = req.user;
const stdLearnings = await models.StdLearning.findAll({
where: {
ID,
STUDENT_FINISH: {
[models.Sequelize.Op.ne]: null,
},
SCORE: {
[models.Sequelize.Op.ne]: null,
},
NEXT_LEARNING: {
[models.Sequelize.Op.ne]: null,
},
},
include: [
{
model: models.Level,
as: "level",
include: [
{
model: models.Topic,
as: "levelTopic",
required: true,
include: [
{
model: models.Section,
as: "topicSection",
required: true,
},
],
},
],
required: true,
},
],
order: [["STUDENT_FINISH", "DESC"]],
});
if (!stdLearnings.length) {
return response(
404,
null,
"No learning history found for this user",
res
);
}
const formattedLearnings = await Promise.all(
stdLearnings.map(async (learning) => {
let nextLevelName = null;
if (learning.NEXT_LEARNING) {
const nextLevel = await models.Level.findOne({
where: { ID_LEVEL: learning.NEXT_LEARNING },
});
if (nextLevel) {
nextLevelName = nextLevel.NAME_LEVEL;
}
}
return {
SCORE: learning.SCORE,
CURRENT_LEVEL: learning.level?.NAME_LEVEL || "No level",
NEXT_LEVEL: nextLevelName,
STUDENT_FINISH: learning.STUDENT_FINISH,
TOPIC_NAME: learning.level?.levelTopic?.NAME_TOPIC || "No topic",
SECTION_NAME:
learning.level?.levelTopic?.topicSection?.NAME_SECTION ||
"No section",
IS_PASS: learning.IS_PASS,
};
})
);
const paginatedLearnings = formattedLearnings.slice(
(page - 1) * limit,
page * limit
);
const totalPages = Math.ceil(formattedLearnings.length / limit);
const currentPage = parseInt(page);
response(
200,
{
history: paginatedLearnings,
currentPage,
totalPages,
totalItems: formattedLearnings.length,
},
"Learning history retrieved successfully",
res
);
} catch (error) {
console.error(error);
response(500, null, "Internal Server Error", res);
}
};
export const learningHistoryBySectionId = async (req, res) => {
const { page = 1, limit = 10 } = req.query;
try {
if (!req.user) {
return response(401, null, "User not authenticated", res);
}
const { ID } = req.user;
const { sectionId } = req.params;
const stdLearnings = await models.StdLearning.findAll({
where: {
ID,
STUDENT_FINISH: {
[models.Sequelize.Op.ne]: null,
},
SCORE: {
[models.Sequelize.Op.ne]: null,
},
NEXT_LEARNING: {
[models.Sequelize.Op.ne]: null,
},
},
include: [
{
model: models.Level,
as: "level",
include: [
{
model: models.Topic,
as: "levelTopic",
include: [
{
model: models.Section,
as: "topicSection",
where: { ID_SECTION: sectionId },
required: true,
},
],
required: true,
},
],
required: true,
},
],
order: [["STUDENT_FINISH", "DESC"]],
});
if (!stdLearnings.length) {
return response(
404,
null,
"No learning history found for the specified section",
res
);
}
const formattedLearnings = await Promise.all(
stdLearnings.map(async (learning) => {
let nextLevelName = null;
if (learning.NEXT_LEARNING) {
const nextLevel = await models.Level.findOne({
where: { ID_LEVEL: learning.NEXT_LEARNING },
});
if (nextLevel) {
nextLevelName = nextLevel.NAME_LEVEL;
}
}
return {
SCORE: learning.SCORE,
CURRENT_LEVEL: learning.level?.NAME_LEVEL || "No level",
NEXT_LEVEL: nextLevelName,
STUDENT_FINISH: learning.STUDENT_FINISH,
TOPIC_NAME: learning.level?.levelTopic?.NAME_TOPIC || "No topic",
SECTION_NAME:
learning.level?.levelTopic?.topicSection?.NAME_SECTION ||
"No section",
IS_PASS: learning.IS_PASS,
};
})
);
const paginatedLearnings = formattedLearnings.slice(
(page - 1) * limit,
page * limit
);
const totalPages = Math.ceil(formattedLearnings.length / limit);
const currentPage = parseInt(page);
response(
200,
{
history: paginatedLearnings,
currentPage,
totalPages,
totalItems: formattedLearnings.length,
},
"Learning history retrieved successfully",
res
);
} catch (error) {
console.log(error);
response(500, null, "Internal Server Error", res);
}
};
export const learningHistoryByTopicId = async (req, res) => {
const { page = 1, limit = 10 } = req.query;
try {
if (!req.user) {
return response(401, null, "User not authenticated", res);
}
const { ID } = req.user;
const { topicId } = req.params;
if (!topicId) {
return response(400, null, "Topic ID is required", res);
}
const stdLearnings = await models.StdLearning.findAll({
where: {
ID,
STUDENT_FINISH: {
[models.Sequelize.Op.ne]: null,
},
SCORE: {
[models.Sequelize.Op.ne]: null,
},
NEXT_LEARNING: {
[models.Sequelize.Op.ne]: null,
},
},
include: [
{
model: models.Level,
as: "level",
include: [
{
model: models.Topic,
as: "levelTopic",
where: { ID_TOPIC: topicId },
required: true,
include: [
{
model: models.Section,
as: "topicSection",
required: true,
},
],
},
],
required: true,
},
],
order: [["STUDENT_FINISH", "DESC"]],
});
if (!stdLearnings.length) {
return response(
404,
null,
"No learning history found for the specified topic",
res
);
}
const formattedLearnings = await Promise.all(
stdLearnings.map(async (learning) => {
let nextLevelName = null;
if (learning.NEXT_LEARNING) {
const nextLevel = await models.Level.findOne({
where: { ID_LEVEL: learning.NEXT_LEARNING },
});
if (nextLevel) {
nextLevelName = nextLevel.NAME_LEVEL;
}
}
return {
SCORE: learning.SCORE,
CURRENT_LEVEL: learning.level?.NAME_LEVEL || "No level",
NEXT_LEVEL: nextLevelName,
STUDENT_FINISH: learning.STUDENT_FINISH,
TOPIC_NAME: learning.level?.levelTopic?.NAME_TOPIC || "No topic",
SECTION_NAME:
learning.level?.levelTopic?.topicSection?.NAME_SECTION ||
"No section",
IS_PASS: learning.IS_PASS,
};
})
);
const paginatedLearnings = formattedLearnings.slice(
(page - 1) * limit,
page * limit
);
const totalPages = Math.ceil(formattedLearnings.length / limit);
const currentPage = parseInt(page);
response(
200,
{
history: paginatedLearnings,
currentPage,
totalPages,
totalItems: formattedLearnings.length,
},
"Learning history retrieved successfully",
res
);
} catch (error) {
console.error(error);
response(500, null, "Internal Server Error", res);
}
};
export const recentStudentActivities = async (req, res) => {
try {
const stdLearnings = await models.StdLearning.findAll({
where: {
STUDENT_FINISH: {
[models.Sequelize.Op.ne]: null,
},
SCORE: {
[models.Sequelize.Op.ne]: null,
},
NEXT_LEARNING: {
[models.Sequelize.Op.ne]: null,
},
},
include: [
{
model: models.User,
as: "learningUser",
attributes: ["ID", "NAME_USERS"],
include: [
{
model: models.Student,
as: "students",
attributes: ["NISN"],
},
],
},
{
model: models.Level,
as: "level",
attributes: ["NAME_LEVEL"],
include: [
{
model: models.Topic,
as: "levelTopic",
attributes: ["NAME_TOPIC"],
include: [
{
model: models.Section,
as: "topicSection",
attributes: ["NAME_SECTION"],
},
],
},
],
},
],
order: [["STUDENT_FINISH", "DESC"]],
limit: 5,
});
const recentActivities = stdLearnings.map((learning) => ({
NISN: learning.learningUser?.students?.NISN || "N/A",
NAME_USERS: learning.learningUser?.NAME_USERS || "N/A",
NAME_SECTION:
learning.level?.levelTopic?.topicSection?.NAME_SECTION || "N/A",
NAME_TOPIC: learning.level?.levelTopic?.NAME_TOPIC || "N/A",
NAME_LEVEL: learning.level?.NAME_LEVEL || "N/A",
SCORE: learning.SCORE || "N/A",
}));
if (!recentActivities.length) {
return res.status(404).json({ message: "No recent activities found" });
}
res.status(200).json({ recentActivities });
} catch (error) {
console.error(error);
res.status(500).json({ message: "Internal Server Error" });
}
};
export const getLastCreatedStdLearningByLevelId = async (req, res) => {
try {
if (!req.user) {
return response(401, null, "User not authenticated", res);
}
const { ID } = req.user;
const { levelId } = req.params;
if (!levelId) {
return response(400, null, "Level ID is required", res);
}
const latestStdLearning = await models.StdLearning.findOne({
where: {
ID: ID,
ID_LEVEL: levelId,
},
order: [["STUDENT_START", "DESC"]],
});
if (!latestStdLearning) {
return response(404, null, "No StdLearning data found", res);
}
response(200, latestStdLearning, "Success", res);
} catch (error) {
console.error(error);
response(500, null, "Internal Server Error", res);
}
};