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<ResponseT> => {
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<RowDataPacket[]>(
sqlSelectQuery1,
[course_id, teacher_id]
);
if (enrollments.length > 0) {
const resp: ICode<IEnrollmentLogs> =
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<RowDataPacket[]>(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<RowDataPacket[]>(
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<RowDataPacket[]>(
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<IEnrollmentLogs> =
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<ResponseT> => {
try {
const sqlInsertQuery =
'INSERT INTO enrollments (course_id, teacher_id, school_id) VALUES (?, ?, ?)';
const result: any = await db.query<ResultSetHeader[]>(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<IEnrollmentLogs> =
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<ResponseT> => {
try {
const sqlDeleteQuery =
'DELETE FROM enrollments WHERE teacher_id = ? AND course_id = ?';
const [result]: any = await db.query<RowDataPacket[]>(sqlDeleteQuery, [
teacher_id,
course_id,
]);
if (result.affectedRows === 0) {
const resp: ICode<IEnrollmentLogs> =
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<IEnrollmentLogs> =
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<ResponseT> => {
try {
const sqlDeleteQuery = 'DELETE FROM enrollments WHERE enrollment_id = ?';
const [result]: any = await db.query<RowDataPacket[]>(sqlDeleteQuery, [
enrollment_id,
]);
if (result.affectedRows === 0) {
const resp: ICode<IEnrollmentLogs> =
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<IEnrollmentLogs> =
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<ResponseT> => {
try {
const sqlSelectQuery = 'SELECT * FROM enrollments';
const [enrollments]: any = await db.query<RowDataPacket[]>(
sqlSelectQuery
);
const resp: ICode<IEnrollmentLogs> =
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<ResponseT> => {
try {
const sqlSelectQuery =
'SELECT * FROM enrollments WHERE course_id = ? AND school_id = ?';
const [enrollments]: any = await db.query<RowDataPacket[]>(
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<RowDataPacket[]>(
sqlSelectQuery2,
[enrollment.teacher_id]
);
enrollment.teacher = teacher[0];
})
);
const resp: ICode<IEnrollmentLogs> =
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
);
}
};
}