import enrollmentLogs, { IEnrollmentLogs, enrollmentLogger, } from './enrollment.logs'; import { formatString } from '../../utils/Strings'; import { HttpCodes } from '../../config/Errors'; import { ErrorResponseC, SuccessResponseC } from '../services.response'; import { db } from '../../settings'; import { ResultSetHeader, RowDataPacket } from 'mysql2'; export class EnrollmentServices { /** * @description Assign a teacher to a course * @param course_id - Number * @param teacher_id - Number * @param school_id - Number * @returns ResponseT */ static assignTeacherToCourse = async ( course_id: number, teacher_id: number, school_id: number ): Promise => { try { // check if the teacher is already assinged to this course const sqlSelectQuery1 = 'SELECT * FROM enrollments WHERE course_id = ? AND teacher_id = ?'; const [enrollments]: any = await db.query( sqlSelectQuery1, [course_id, teacher_id] ); if (enrollments.length > 0) { const resp: ICode = enrollmentLogs.FAILED_TO_ASSIGN_TEACHER_TO_COURSE; const msg = formatString(resp.message, { error: 'The teacher is already assigned to the course', }); enrollmentLogger.error(msg, { type: resp.type }); return new ErrorResponseC(resp.type, HttpCodes.BadRequest.code, msg); } const sqlSelectQuery = 'SELECT pack_id FROM orders WHERE course_id = ? AND school_id = ?'; const [[pack]]: any = await db.query(sqlSelectQuery, [ course_id, school_id, ]); const pack_id = pack.pack_id; const sqlSelectQuery2 = 'SELECT nb_teachers_accounts FROM packs WHERE pack_id = ?'; const [[get_nb_teachers]]: any = await db.query( sqlSelectQuery2, [pack_id] ); const nb_teachers_accounts = get_nb_teachers.nb_teachers_accounts; const sqlSelectQuery3 = 'SELECT COUNT(*) as count FROM enrollments WHERE course_id = ? AND school_id = ?'; const [[get_count]]: any = await db.query( sqlSelectQuery3, [course_id, school_id] ); const count = get_count.count; if (count < nb_teachers_accounts) { return EnrollmentServices.createEnrollment( course_id, teacher_id, school_id ); } else { const resp: ICode = enrollmentLogs.FAILED_TO_ASSIGN_TEACHER_TO_COURSE; const msg = formatString(resp.message, { error: 'The number of teachers that are already assigned to the course is greater than or equal to the number of teachers that are allowed to be assigned to the course', }); enrollmentLogger.error(msg, { type: resp.type }); return new ErrorResponseC(resp.type, HttpCodes.BadRequest.code, msg); } } catch (err) { const msg = formatString( enrollmentLogs.ASSIGN_TEACHER_TO_COURSE_ERROR.message, { error: (err as Error)?.message || '', } ); enrollmentLogger.error(msg, err as Error); return new ErrorResponseC( enrollmentLogs.ASSIGN_TEACHER_TO_COURSE_ERROR.type, HttpCodes.InternalServerError.code, msg ); } }; /** * @description Create an enrollment * @param course_id - Number * @param teacher_id - Number * @returns ResponseT */ static createEnrollment = async ( course_id: number, teacher_id: number, school_id: number | null = null ): Promise => { try { const sqlInsertQuery = 'INSERT INTO enrollments (course_id, teacher_id, school_id) VALUES (?, ?, ?)'; const result: any = await db.query(sqlInsertQuery, [ course_id, teacher_id, school_id, ]); const enrollmentId = result[0].insertId; const enrollment: EnrollmentI = { enrollment_id: enrollmentId, course_id, teacher_id, school_id: school_id ?? null, }; const resp: ICode = enrollmentLogs.CREATE_ENROLLMENT_SUCCESS; const msg = formatString(resp.message, { enrollmentId, }); enrollmentLogger.info(msg, { type: resp.type }); return new SuccessResponseC( resp.type, enrollment, 'Teacher has been assigned to the course', HttpCodes.Created.code ); } catch (err) { const msg = formatString(enrollmentLogs.CREATE_ENROLLMENT_ERROR.message, { error: (err as Error)?.message || '', }); enrollmentLogger.error(msg, err as Error); return new ErrorResponseC( enrollmentLogs.CREATE_ENROLLMENT_ERROR.type, HttpCodes.InternalServerError.code, msg ); } }; /** * @description Update an enrollment * @param enrollment_id - Number * @param course_id - Number * @param teacher_id - Number * @returns ResponseT */ static deleteEnrollment = async ( teacher_id: number, course_id: number ): Promise => { try { const sqlDeleteQuery = 'DELETE FROM enrollments WHERE teacher_id = ? AND course_id = ?'; const [result]: any = await db.query(sqlDeleteQuery, [ teacher_id, course_id, ]); if (result.affectedRows === 0) { const resp: ICode = enrollmentLogs.DELETE_ENROLLMENT_ERROR; const msg = formatString(resp.message, { error: 'Enrollment not found', }); enrollmentLogger.error(msg, { type: resp.type }); return new ErrorResponseC(resp.type, HttpCodes.NotFound.code, msg); } const resp: ICode = enrollmentLogs.DELETE_ENROLLMENT_SUCCESS; const msg = formatString(resp.message, { teacher_id, course_id, }); enrollmentLogger.info(msg, { type: resp.type }); return new SuccessResponseC( resp.type, null, msg, HttpCodes.Accepted.code ); } catch (err) { const msg = formatString(enrollmentLogs.DELETE_ENROLLMENT_ERROR.message, { error: (err as Error)?.message || '', }); enrollmentLogger.error(msg, err as Error); return new ErrorResponseC( enrollmentLogs.DELETE_ENROLLMENT_ERROR.type, HttpCodes.InternalServerError.code, msg ); } }; static deleteEnrollmentById = async ( enrollment_id: number ): Promise => { try { const sqlDeleteQuery = 'DELETE FROM enrollments WHERE enrollment_id = ?'; const [result]: any = await db.query(sqlDeleteQuery, [ enrollment_id, ]); if (result.affectedRows === 0) { const resp: ICode = enrollmentLogs.DELETE_ENROLLMENT_ERROR; const msg = formatString(resp.message, { error: 'Enrollment not found', }); enrollmentLogger.error(msg, { type: resp.type }); return new ErrorResponseC(resp.type, HttpCodes.NotFound.code, msg); } const resp: ICode = enrollmentLogs.DELETE_ENROLLMENT_SUCCESS; const msg = formatString(resp.message, { enrollment_id, }); enrollmentLogger.info(msg, { type: resp.type }); return new SuccessResponseC( resp.type, null, 'Teacher has been unassigned from the course', HttpCodes.Accepted.code ); } catch (err) { const msg = formatString(enrollmentLogs.DELETE_ENROLLMENT_ERROR.message, { error: (err as Error)?.message || '', }); enrollmentLogger.error(msg, err as Error); return new ErrorResponseC( enrollmentLogs.DELETE_ENROLLMENT_ERROR.type, HttpCodes.InternalServerError.code, msg ); } }; /** * @description Get all enrollments * @returns ResponseT */ static getEnrollments = async (): Promise => { try { const sqlSelectQuery = 'SELECT * FROM enrollments'; const [enrollments]: any = await db.query( sqlSelectQuery ); const resp: ICode = enrollmentLogs.GET_ENROLLMENTS_SUCCESS; const msg = formatString(resp.message, { count: enrollments.length }); enrollmentLogger.info(msg, { type: resp.type }); return new SuccessResponseC( resp.type, enrollments, msg, HttpCodes.OK.code ); } catch (err) { const msg = formatString(enrollmentLogs.GET_ENROLLMENTS_ERROR.message, { error: (err as Error)?.message || '', }); enrollmentLogger.error(msg, err as Error); return new ErrorResponseC( enrollmentLogs.GET_ENROLLMENTS_ERROR.type, HttpCodes.InternalServerError.code, msg ); } }; static getAssignedTeachersByCourseAndSchool = async ( course_id: number, school_id: number ): Promise => { try { const sqlSelectQuery = 'SELECT * FROM enrollments WHERE course_id = ? AND school_id = ?'; const [enrollments]: any = await db.query( sqlSelectQuery, [course_id, school_id] ); await Promise.all( enrollments.map(async (enrollment: any) => { const sqlSelectQuery2 = 'SELECT t.*, u.firstName, u.lastName, u.user_id, u.email FROM teachers t INNER JOIN users u ON t.user_id = u.user_id WHERE teacher_id = ?'; // 'SELECT * FROM Teachers WHERE teacher_id = ?'; const [teacher]: any = await db.query( sqlSelectQuery2, [enrollment.teacher_id] ); enrollment.teacher = teacher[0]; }) ); const resp: ICode = enrollmentLogs.GET_TEACHERS_BY_COURSE_AND_SCHOOL_SUCCESS; const msg = formatString(resp.message, { course_id, school_id, }); enrollmentLogger.info(msg, { type: resp.type }); return new SuccessResponseC( resp.type, enrollments, msg, HttpCodes.OK.code ); } catch (err) { const msg = formatString( enrollmentLogs.GET_TEACHERS_BY_COURSE_AND_SCHOOL_ERROR.message, { course_id, school_id, error: (err as Error)?.message || '', } ); enrollmentLogger.error(msg, err as Error); return new ErrorResponseC( enrollmentLogs.GET_TEACHERS_BY_COURSE_AND_SCHOOL_ERROR.type, HttpCodes.InternalServerError.code, msg ); } }; }