From bf5dd62b3582e4eb5ba746493511df9f9d180f3f Mon Sep 17 00:00:00 2001 From: Joao Ramos Date: Tue, 20 Aug 2024 01:01:50 +0100 Subject: [PATCH] Updated Excel document --- .../api/assignments/[id]/[export]/excel.ts | 120 ++++++++++++++---- 1 file changed, 92 insertions(+), 28 deletions(-) diff --git a/src/pages/api/assignments/[id]/[export]/excel.ts b/src/pages/api/assignments/[id]/[export]/excel.ts index 25a96d4a..bd7da652 100644 --- a/src/pages/api/assignments/[id]/[export]/excel.ts +++ b/src/pages/api/assignments/[id]/[export]/excel.ts @@ -71,6 +71,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) { path: string; version: string; }; + name: string; }; if (!data) { res.status(400).end(); @@ -102,11 +103,41 @@ async function post(req: NextApiRequest, res: NextApiResponse) { // we'll need the user in order to get the user data (name, email, focus, etc); const user = docUser.data() as CorporateUser; - const results = data.results.map((r: any) => r.score.correct); + const allStats = data.results.flatMap((r: any) => r.stats); + + const uniqueExercises = [ + ...new Set(allStats.map((s: any) => s.exercise)), + ]; + + const assigneesData = data.assignees + .map((assignee: string) => { + const userStats = allStats.filter((s: any) => s.user === assignee); + return { + userId: assignee, + user: users.find((u) => u.id === assignee), + ...userStats.reduce( + (acc: any, curr: any) => { + return { + ...acc, + correct: acc.correct + curr.score.correct, + missing: acc.missing + curr.score.missing, + total: acc.total + curr.score.total, + }; + }, + { correct: 0, missing: 0, total: 0 } + ), + stats: userStats, + }; + }) + .sort((a, b) => b.correct - a.correct); + + const results = assigneesData.map((r: any) => r.correct); const highestScore = Math.max(...results); const lowestScore = Math.min(...results); + const averageScore = results.reduce((a, b) => a + b, 0) / results.length; - const dates = data.results + const dates = assigneesData + .flatMap((r: any) => r.stats) .map((r: any) => r.date) .map((d: number) => moment(d)); const firstDate = moment.min(dates); @@ -121,7 +152,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) { label: "Report Download date :", value: moment().format("DD/MM/YYYY"), }, - { label: "Test Information :", value: "TODO" }, + { label: "Test Information :", value: data.name}, { label: "Date of Test :", value: moment(data.startDate).format("DD/MM/YYYY"), @@ -129,6 +160,7 @@ async function post(req: NextApiRequest, res: NextApiResponse) { { label: "Number of Candidates :", value: data.assignees.length }, { label: "Highest score :", value: highestScore }, { label: "Lowest score :", value: lowestScore }, + { label: "Average score :", value: averageScore }, { label: "", value: "" }, { label: "Date and time of First submission :", @@ -152,8 +184,6 @@ async function post(req: NextApiRequest, res: NextApiResponse) { logWorksheetData(worksheet); - const testSectionsArray = [1, 2, 3, 4, 5]; - // Define the static part of the headers (before "Test Sections") const staticHeaders = [ "Sr N", @@ -165,20 +195,23 @@ async function post(req: NextApiRequest, res: NextApiResponse) { ]; // Define additional headers after "Test Sections" - const additionalHeaders = ["Time Spent", "Score", "Level"]; + const additionalHeaders = ["Time Spent", "Score"]; // Calculate the dynamic columns based on the testSectionsArray - const numberOfTestSections = testSectionsArray.length; - const testSectionHeaders = testSectionsArray.map( + const testSectionHeaders = uniqueExercises.map( (section, index) => `Part ${index + 1}` ); - // Add the main header row, merging static columns and "Test Sections" - worksheet.addRow([ + const tableColumnHeadersFirstPart = [ ...staticHeaders, - ...testSectionsArray.map((a) => "Test Sections"), + ...uniqueExercises.map((a) => "Test Sections"), + ]; + // Add the main header row, merging static columns and "Test Sections" + const tableColumnHeaders = [ + ...tableColumnHeadersFirstPart, ...additionalHeaders, - ]); + ]; + worksheet.addRow(tableColumnHeaders); // 1 headers rows const startIndexTable = firstSectionData.length + 1; @@ -187,7 +220,12 @@ async function post(req: NextApiRequest, res: NextApiResponse) { // // Merge "Test Sections" over dynamic number of columns // const tableColumns = staticHeaders.length + numberOfTestSections; - // worksheet.mergeCells(1, staticHeaders.length + 1, 1, tableColumns); + worksheet.mergeCells( + 1, + staticHeaders.length + 1, + 1, + tableColumnHeadersFirstPart.length + ); // logWorksheetData(worksheet); // worksheet.mergeCells(`G1:G3`); // Time Spent @@ -200,32 +238,58 @@ async function post(req: NextApiRequest, res: NextApiResponse) { ...testSectionHeaders, "", "", + ]); + worksheet.addRow([ + ...Array(staticHeaders.length).fill(""), + ...uniqueExercises.map(() => "Grammar & Vocabulary"), + "", "", ]); worksheet.addRow([ ...Array(staticHeaders.length).fill(""), - ...testSectionsArray.map(() => "Grammar"), - "", + ...uniqueExercises.map( + (exercise) => allStats.find((s: any) => s.exercise === exercise).type + ), "", "", ]); // Merging static headers and "Test Sections" over dynamic columns - worksheet.mergeCells(`A${startIndexTable}:A${startIndexTable + 2}`); // "Sr N" - worksheet.mergeCells(`B${startIndexTable}:B${startIndexTable + 2}`); // "Candidate ID" - worksheet.mergeCells(`C${startIndexTable}:C${startIndexTable + 2}`); // "First and Last Name" - worksheet.mergeCells(`D${startIndexTable}:D${startIndexTable + 2}`); // "Passport/ID" - worksheet.mergeCells(`E${startIndexTable}:E${startIndexTable + 2}`); // "Email ID" - worksheet.mergeCells(`F${startIndexTable}:F${startIndexTable + 2}`); // "Gender" + worksheet.mergeCells(`A${startIndexTable}:A${startIndexTable + 3}`); // "Sr N" + worksheet.mergeCells(`B${startIndexTable}:B${startIndexTable + 3}`); // "Candidate ID" + worksheet.mergeCells(`C${startIndexTable}:C${startIndexTable + 3}`); // "First and Last Name" + worksheet.mergeCells(`D${startIndexTable}:D${startIndexTable + 3}`); // "Passport/ID" + worksheet.mergeCells(`E${startIndexTable}:E${startIndexTable + 3}`); // "Email ID" + worksheet.mergeCells(`F${startIndexTable}:F${startIndexTable + 3}`); // "Gender" - // worksheet.addRow(users.map((a) => { - // })) + assigneesData.forEach((data, index) => { + worksheet.addRow([ + index + 1, + data.userId, + data.user.name, + data.user.demographicInformation?.passportId, + data.user.email, + data.user.demographicInformation?.gender, + ...uniqueExercises.map((exercise) => { + const score = data.stats.find( + (s: any) => s.exercise === exercise && s.user === data.userId + ).score; + return `${score.correct}/${score.total}`; + }), + `${ + data.stats.reduce( + (acc: number, curr: any) => acc + curr.timeSpent, + 0 + ) / 60 + } minutes`, + data.correct, + ]); + }); - for ( - let i = 0; - i < staticHeaders.length + additionalHeaders.length + 1; - i++ - ) { + worksheet.addRow([""]); + worksheet.addRow([""]); + + for (let i = 0; i < tableColumnHeaders.length; i++) { worksheet.getColumn(i + 1).width = 30; }