|
|
|
|
@@ -14,12 +14,18 @@ import {getGradingSystem} from "@/utils/grading.be";
|
|
|
|
|
import {StudentUser, User} from "@/interfaces/user";
|
|
|
|
|
import {calculateBandScore, getGradingLabel} from "@/utils/score";
|
|
|
|
|
import {Module} from "@/interfaces";
|
|
|
|
|
import {uniq} from "lodash";
|
|
|
|
|
import {getUserName} from "@/utils/users";
|
|
|
|
|
import {LevelExam} from "@/interfaces/exam";
|
|
|
|
|
import {getSpecificExams} from "@/utils/exams.be";
|
|
|
|
|
|
|
|
|
|
export default withIronSessionApiRoute(handler, sessionOptions);
|
|
|
|
|
|
|
|
|
|
interface TableData {
|
|
|
|
|
user: string;
|
|
|
|
|
studentID: string;
|
|
|
|
|
passportID: string;
|
|
|
|
|
exams: string;
|
|
|
|
|
email: string;
|
|
|
|
|
correct: number;
|
|
|
|
|
corporate: string;
|
|
|
|
|
@@ -41,7 +47,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
|
if (req.method === "POST") return await post(req, res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const searchFilters = [["email"], ["user"], ["userId"]];
|
|
|
|
|
const searchFilters = [["email"], ["user"], ["userId"], ["assignment"], ["exams"]];
|
|
|
|
|
|
|
|
|
|
async function post(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
|
// verify if it's a logged user that is trying to export
|
|
|
|
|
@@ -64,12 +70,13 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
|
};
|
|
|
|
|
const startDateParsed = startDate ? new Date(startDate) : undefined;
|
|
|
|
|
const endDateParsed = endDate ? new Date(endDate) : undefined;
|
|
|
|
|
const assignments = await getAssignmentsForCorporates(ids, startDateParsed, endDateParsed);
|
|
|
|
|
const assignments = await getAssignmentsForCorporates(req.session.user.type, ids, startDateParsed, endDateParsed);
|
|
|
|
|
|
|
|
|
|
const assignmentUsers = [...new Set(assignments.flatMap((a) => a.assignees))];
|
|
|
|
|
const assignmentUsers = uniq([...assignments.flatMap((x) => x.assignees), ...assignments.flatMap((x) => x.assigner)]);
|
|
|
|
|
const assigners = [...new Set(assignments.map((a) => a.assigner))];
|
|
|
|
|
const users = await getSpecificUsers(assignmentUsers);
|
|
|
|
|
const assignerUsers = await getSpecificUsers(assigners);
|
|
|
|
|
const exams = await getSpecificExams(uniq(assignments.flatMap((x) => x.exams.map((x) => x.id))));
|
|
|
|
|
|
|
|
|
|
const assignerUsersGradingSystems = await Promise.all(
|
|
|
|
|
assignerUsers.map(async (user: User) => {
|
|
|
|
|
@@ -91,7 +98,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
|
if (gradingSystem) {
|
|
|
|
|
const bandScore = calculateBandScore(correct, total, "level", user?.focus || "academic");
|
|
|
|
|
return {
|
|
|
|
|
label: getGradingLabel(bandScore, gradingSystem?.steps || []),
|
|
|
|
|
label: getGradingLabel(bandScore, gradingSystem.steps || []),
|
|
|
|
|
score: bandScore,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
@@ -113,10 +120,12 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
|
const commonData = {
|
|
|
|
|
user: userData?.name || "",
|
|
|
|
|
email: userData?.email || "",
|
|
|
|
|
studentID: (userData as StudentUser).studentID || "",
|
|
|
|
|
studentID: (userData as StudentUser)?.studentID || "",
|
|
|
|
|
passportID: (userData as StudentUser)?.demographicInformation?.passport_id || "",
|
|
|
|
|
userId: assignee,
|
|
|
|
|
exams: a.exams.map((x) => x.id).join(", "),
|
|
|
|
|
corporateId: a.corporateId,
|
|
|
|
|
corporate: corporateUser?.name || "",
|
|
|
|
|
corporate: !corporateUser ? "" : getUserName(corporateUser),
|
|
|
|
|
assignment: a.name,
|
|
|
|
|
level,
|
|
|
|
|
score,
|
|
|
|
|
@@ -130,14 +139,22 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const partsData = userStats.every((e) => e.module === "level")
|
|
|
|
|
? userStats.reduce((acc, e, index) => {
|
|
|
|
|
return {
|
|
|
|
|
...acc,
|
|
|
|
|
[`part${index}`]: `${e.score.correct}/${e.score.total}`,
|
|
|
|
|
};
|
|
|
|
|
}, {})
|
|
|
|
|
: {};
|
|
|
|
|
let data: {total: number; correct: number}[] = [];
|
|
|
|
|
if (a.exams.every((x) => x.module === "level")) {
|
|
|
|
|
const exam = exams.find((x) => x.id === a.exams.find((x) => x.assignee === assignee)?.id) as LevelExam;
|
|
|
|
|
data = exam.parts.map((x) => {
|
|
|
|
|
const exerciseIDs = x.exercises.map((x) => x.id);
|
|
|
|
|
const stats = userStats.filter((x) => exerciseIDs.includes(x.exercise));
|
|
|
|
|
|
|
|
|
|
const total = stats.reduce((acc, curr) => acc + curr.score.total, 0);
|
|
|
|
|
const correct = stats.reduce((acc, curr) => acc + curr.score.correct, 0);
|
|
|
|
|
|
|
|
|
|
return {total, correct};
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const partsData =
|
|
|
|
|
data.length > 0 ? data.reduce((acc, e, index) => ({...acc, [`part${index}`]: `${e.correct}/${e.total}`}), {}) : {};
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
...commonData,
|
|
|
|
|
@@ -169,6 +186,10 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
|
label: "Student ID",
|
|
|
|
|
value: (entry: TableData) => entry.studentID,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: "Passport ID",
|
|
|
|
|
value: (entry: TableData) => entry.passportID,
|
|
|
|
|
},
|
|
|
|
|
...(displaySelection
|
|
|
|
|
? [
|
|
|
|
|
{
|
|
|
|
|
@@ -186,7 +207,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
|
value: (entry: TableData) => (entry.submitted ? "Yes" : "No"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: "Correct",
|
|
|
|
|
label: "Score",
|
|
|
|
|
value: (entry: TableData) => entry.correct,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
@@ -206,7 +227,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
|
|
|
|
|
})),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const filteredSearch = searchText ? search(searchText, searchFilters, tableResults) : tableResults;
|
|
|
|
|
const filteredSearch = !!searchText ? search(searchText, searchFilters, tableResults) : tableResults;
|
|
|
|
|
|
|
|
|
|
worksheet.addRow(headers.map((h) => h.label));
|
|
|
|
|
(filteredSearch as TableData[]).forEach((entry) => {
|
|
|
|
|
|