import { getMoodleCourseCompletionStatus, getMoodleUserById } from "./moodle"; import { CronJob } from "cron"; import { DISCORD_ROLES, prisma } from "@repo/db"; import { sendCourseCompletedEmail } from "modules/mail"; import { handleParticipantFinished } from "modules/event"; import { eventCompleted } from "helper/events"; import { addRolesToMember, removeRolesFromMember } from "modules/discord"; const syncMoodleIds = async () => { try { const user = await prisma.user.findMany({ where: { moodleId: null, }, }); await Promise.all( user.map(async (u) => { const moodleUser = await getMoodleUserById(u.id.toString()); const moodleId = moodleUser?.id.toString(); if (u.moodleId === parseInt(moodleId)) return; await prisma.user.update({ where: { id: u.id, }, data: { moodleId: parseInt(moodleId), }, }); }), ); } catch (error) { console.error(error); } }; const updateParticipantMoodleResults = async () => { const participantsMoodlePending = await prisma.participant.findMany({ where: { finisherMoodleCurseCompleted: false, Event: { finisherMoodleCourseId: { not: null, }, }, }, include: { Event: true, User: true, }, }); await Promise.all( participantsMoodlePending.map(async (p) => { if (!p.User) return; if (!p.User.moodleId) return; const quizzResult = await getMoodleCourseCompletionStatus( p.User.moodleId.toString(), p.Event.finisherMoodleCourseId!, ); if (quizzResult?.completionstatus?.completed === true) { return prisma.participant.update({ where: { id: p.id, }, data: { finisherMoodleCurseCompleted: true, statusLog: { push: { event: "Moodle-Kurs abgeschlossen", timestamp: new Date(), user: "system", }, }, }, }); } }), ); }; export const checkFinishedParticipants = async () => { const participantsPending = await prisma.participant.findMany({ where: { completetionWorkflowFinished: false, }, include: { Event: true, User: true, }, }); participantsPending.forEach(async (p) => { if (!p.User) return; const completed = eventCompleted(p.Event, p); if (!completed) return; console.log( `User ${p.User.firstname} ${p.User.lastname} - ${p.User.publicId} finished event ${p.Event.name}`, ); handleParticipantFinished(p.Event, p, p.User); }); }; const checkUnfinishedParticipants = async () => { const participantsPending = await prisma.participant.findMany({ where: { completetionWorkflowFinished: false, }, include: { Event: true, User: { include: { discordAccounts: true, }, }, }, }); participantsPending.forEach(async (p) => { if (!p.User) return; const completed = eventCompleted(p.Event, p); if (completed) return; if (p.User.discordAccounts[0] && p.Event.discordRoleId) { await addRolesToMember(p.User.discordAccounts[0].discordId, [p.Event.discordRoleId]); prisma.participant.update({ where: { id: p.id, }, data: { inscriptionWorkflowCompleted: true, statusLog: { push: { event: "Discord-Rolle hinzugefügt", timestamp: new Date(), user: "system", }, }, }, }); } }); }; const checkDiscordRoles = async () => { const user = await prisma.user.findMany({ where: { discordAccounts: { some: {}, }, }, include: { discordAccounts: true, }, }); for (const u of user) { // Here ony member Roles regarding their rights are checked if (!u.discordAccounts[0]) continue; const discordAccount = u.discordAccounts[0]; // For Pilot if (u.permissions.includes("PILOT")) { await addRolesToMember(discordAccount.discordId, [DISCORD_ROLES.PILOT]); // ONLINE_PILOT } else { await removeRolesFromMember(discordAccount.discordId, [DISCORD_ROLES.PILOT]); // ONLINE_PILOT } // for Dispatcher if (u.permissions.includes("DISPO")) { await addRolesToMember(discordAccount.discordId, [DISCORD_ROLES.DISPATCHER]); // ONLINE_DISPATCHER } else { await removeRolesFromMember(discordAccount.discordId, [DISCORD_ROLES.DISPATCHER]); // ONLINE_DISPATCHER } } }; CronJob.from({ cronTime: "0 * * * *", onTick: syncMoodleIds, start: true }); CronJob.from({ cronTime: "*/1 * * * *", onTick: async () => { await updateParticipantMoodleResults(); await checkFinishedParticipants(); await checkUnfinishedParticipants(); }, start: true, }); CronJob.from({ cronTime: "0 * * * *", onTick: checkDiscordRoles, start: true, });