Skip to content

Commit e44d1b1

Browse files
committed
show weekly winners on the students dashboard
1 parent df22940 commit e44d1b1

File tree

2 files changed

+213
-0
lines changed

2 files changed

+213
-0
lines changed

components/student.component.js

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,207 @@ const placeStudentOrder = async (contactId, productId) => {
432432
}
433433
};
434434

435+
const getWeeklyWinners = async (grade) => {
436+
try {
437+
const accessToken = await getZohoTokenOptimized();
438+
const zohoConfig = {
439+
headers: {
440+
"Content-Type": "application/json",
441+
"Access-Control-Allow-Origin": "*",
442+
Authorization: `Bearer ${accessToken}`,
443+
},
444+
};
445+
446+
const today = moment();
447+
const currDay = today.day();
448+
const diff = today.date() - currDay - 6;
449+
const monday = moment(new Date(today.date(diff)));
450+
const sunday = monday.clone().add(6, "days");
451+
452+
const today2 = moment();
453+
const currDay2 = today2.day();
454+
const diff2 = today2.date() - currDay2 - 13;
455+
const monday2 = moment(new Date(today2.date(diff2)));
456+
const sunday2 = monday2.clone().add(13, "days");
457+
458+
const formattedDateStart = `${monday.format("YYYY-MM-DD")}T00:00:00+05:30`;
459+
const formattedDateEnd = `${sunday.format("YYYY-MM-DD")}T23:59:59+05:30`;
460+
let gradeGroup;
461+
let gradeGroup2;
462+
let gradeGroup3;
463+
if (grade === "1" || grade === "2") {
464+
gradeGroup = "1;2";
465+
gradeGroup2 = "(Student_Grade = 1 or Student_Grade = 2)";
466+
gradeGroup3 = "(Contact.Student_Grade = 1 or Contact.Student_Grade = 2)";
467+
} else if (grade === "7" || grade === "8") {
468+
gradeGroup = "7;8";
469+
gradeGroup2 = "(Student_Grade = 7 or Student_Grade = 8)";
470+
gradeGroup3 = "(Contact.Student_Grade = 7 or Contact.Student_Grade = 8)";
471+
} else {
472+
gradeGroup = grade;
473+
gradeGroup2 = `Student_Grade = ${grade}`;
474+
gradeGroup3 = `Contact.Student_Grade = ${grade}`;
475+
}
476+
477+
let currentPage = 0;
478+
const attempts = [];
479+
while (true) {
480+
const attemptsQuery = `select Contact_Name.id as contactId, Contact_Name.Email as Email,Contact_Name.Student_Grade as Student_Grade, Quiz_Score, Contact_Name.Coins as Coins, Session.Number_of_Questions as Total_Questions from Attempts where Session_Date_Time between '${formattedDateStart}' and '${formattedDateEnd}' and Session.Session_Grade = '${gradeGroup}' limit ${
481+
currentPage * 2000
482+
}, 2000`;
483+
const attemptsResponse = await getAnalysisData(attemptsQuery, zohoConfig);
484+
if (attemptsResponse.status === 204) {
485+
return { status: "noattempts" };
486+
}
487+
attempts.push(...attemptsResponse.data.data);
488+
if (!attemptsResponse.data.info.more_records) {
489+
break;
490+
}
491+
currentPage++;
492+
}
493+
const uniqueUsers = {};
494+
attempts.forEach((attempt) => {
495+
if (uniqueUsers[attempt.Email]) {
496+
uniqueUsers[attempt.Email].Quiz_Score += attempt.Quiz_Score;
497+
uniqueUsers[attempt.Email].Total_Questions += attempt.Total_Questions;
498+
} else {
499+
uniqueUsers[attempt.Email] = { ...attempt };
500+
}
501+
});
502+
const uniqueUsersArray = Object.values(uniqueUsers);
503+
504+
const topFiveUsers = uniqueUsersArray
505+
.sort((a, b) => b.Quiz_Score - a.Quiz_Score)
506+
.slice(0, 5);
507+
508+
const filteredGrades = uniqueUsersArray.filter(
509+
(user) => !topFiveUsers.some((topUser) => topUser.Email === user.Email)
510+
);
511+
512+
filteredGrades.forEach((user) => {
513+
user.percentage = Math.floor(
514+
(user.Quiz_Score / user.Total_Questions) * 100
515+
);
516+
});
517+
518+
const topFivePercentageUsers = filteredGrades
519+
.sort((a, b) => b.percentage - a.percentage)
520+
.slice(0, 5);
521+
522+
const contactQuery = `select Email, Student_Grade, Student_Name, Referral_Count from Contacts where ((Referral_Count is not null and Blocked = false) and ${gradeGroup2}) order by Referral_Count desc limit 2000`;
523+
const ordersQuery = `select Contact.Email as Email, Contact.Student_Grade as Student_Grade, Contact.Student_Name as Student_Name from Orders where (${gradeGroup3} and (Order_Date between '${monday.format(
524+
"YYYY-MM-DD"
525+
)}' and '${sunday.format("YYYY-MM-DD")}')) limit 2000`;
526+
527+
const coinsQuery = `select Contact.Email as Email, Contact.Student_Grade as Student_Grade, Contact.Student_Name as Student_Name, Coins from Coins where (((Updated_Date between '${monday.format(
528+
"YYYY-MM-DD"
529+
)}' and '${sunday.format(
530+
"YYYY-MM-DD"
531+
)}') and (Action_Type = 'Credit')) and ${gradeGroup3}) limit 2000`;
532+
533+
const megaLuckyDrawQuery = `select Contact.Email as Email, Contact.Student_Grade as Student_Grade, Contact.Student_Name as Student_Name, Coins, Updated_Date, Description from Coins where (((Updated_Date between '${monday2.format(
534+
"YYYY-MM-DD"
535+
)}' and '${sunday2.format(
536+
"YYYY-MM-DD"
537+
)}') and (Description like '%intro%')) and ${gradeGroup3}) limit 2000`;
538+
539+
const [contact, orders, coins, megaLuckyDrawReq] = await Promise.all([
540+
limit(() => getAnalysisData(contactQuery, zohoConfig)),
541+
limit(() => getAnalysisData(ordersQuery, zohoConfig)),
542+
limit(() => getAnalysisData(coinsQuery, zohoConfig)),
543+
limit(() => getAnalysisData(megaLuckyDrawQuery, zohoConfig)),
544+
]);
545+
546+
let maxReferrals = null;
547+
let maxOrders = null;
548+
let maxCoins = null;
549+
let megaLuckyDraw = null;
550+
551+
if (contact.status === 200) {
552+
maxReferrals = contact.data.data[0];
553+
}
554+
555+
if (orders.status === 200) {
556+
const ordersRes = orders.data.data;
557+
const uniqueOrders = {};
558+
ordersRes.forEach((order) => {
559+
if (uniqueOrders[order.Email]) {
560+
uniqueOrders[order.Email].Total_Orders += 1;
561+
} else {
562+
uniqueOrders[order.Email] = { ...order, Total_Orders: 1 };
563+
}
564+
});
565+
const uniqueOrdersArray = Object.values(uniqueOrders);
566+
maxOrders = uniqueOrdersArray;
567+
}
568+
569+
if (coins.status === 200) {
570+
const coinsRes = coins.data.data;
571+
const uniqueCoins = {};
572+
573+
coinsRes.forEach((coin) => {
574+
if (uniqueCoins[coin.Email]) {
575+
uniqueCoins[coin.Email].Coins += coin.Coins;
576+
} else {
577+
uniqueCoins[coin.Email] = { ...coin };
578+
}
579+
});
580+
const uniqueCoinsArray = Object.values(uniqueCoins);
581+
maxCoins = uniqueCoinsArray.sort((a, b) => b.Coins - a.Coins)[0];
582+
}
583+
584+
if (megaLuckyDrawReq.status === 200) {
585+
megaLuckyDraw = megaLuckyDrawReq.data.data;
586+
}
587+
588+
const totalAttempts = [];
589+
currentPage = 0;
590+
while (true) {
591+
const attemptsQuery = `select Contact_Name.id as contactId, Contact_Name.Email as Email,Contact_Name.Student_Grade as Student_Grade, Quiz_Score, Contact_Name.Coins as Coins, Session.Number_of_Questions as Total_Questions from Attempts where Session.Session_Grade = '${gradeGroup}' limit ${
592+
currentPage * 2000
593+
}, 2000`;
594+
const attemptsResponse = await getAnalysisData(attemptsQuery, zohoConfig);
595+
if (attemptsResponse.status === 204) {
596+
break;
597+
}
598+
totalAttempts.push(...attemptsResponse.data.data);
599+
if (!attemptsResponse.data.info.more_records) {
600+
break;
601+
}
602+
currentPage++;
603+
}
604+
const uniqueQuizTakers = {};
605+
totalAttempts.forEach((attempt) => {
606+
if (uniqueQuizTakers[attempt.Email]) {
607+
uniqueQuizTakers[attempt.Email].Total_Attempts += 1;
608+
} else {
609+
uniqueQuizTakers[attempt.Email] = { ...attempt, Total_Attempts: 1 };
610+
}
611+
});
612+
const uniqueQuizTakersArray = Object.values(uniqueQuizTakers);
613+
const maxQuizTaker = uniqueQuizTakersArray.sort(
614+
(a, b) => b.Total_Attempts - a.Total_Attempts
615+
)[0];
616+
617+
return {
618+
status: 200,
619+
topFiveUsers,
620+
topFivePercentageUsers,
621+
maxReferrals,
622+
maxOrders,
623+
maxCoins,
624+
maxQuizTaker,
625+
megaLuckyDraw,
626+
};
627+
} catch (error) {
628+
throw new Error(error);
629+
}
630+
};
631+
435632
module.exports = {
436633
getStudentDetails,
437634
getStudentOrders,
438635
placeStudentOrder,
439636
updateIntroMeetData,
637+
getWeeklyWinners,
440638
};

controllers/student.controller.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const {
44
getStudentOrders,
55
placeStudentOrder,
66
updateIntroMeetData,
7+
getWeeklyWinners,
78
} = require("../components/student.component");
89
const {
910
getZohoTokenOptimized,
@@ -68,6 +69,20 @@ studentRouter.post("/store/orders", authMiddleware, async (req, res) => {
6869
}
6970
});
7071

72+
studentRouter.post("/weekly/winners", authMiddleware, async (req, res) => {
73+
try {
74+
const { contactId, grade } = req.body;
75+
const data = await getWeeklyWinners(grade);
76+
return res.status(200).send(data);
77+
} catch (error) {
78+
return res.status(error.status || 500).send({
79+
status: "error",
80+
message: error.message,
81+
code: error.status || 500,
82+
});
83+
}
84+
});
85+
7186
studentRouter.post("/store/placeOrder", authMiddleware, async (req, res) => {
7287
try {
7388
const { contactId, productId } = req.body;

0 commit comments

Comments
 (0)