const { where, Op } = require("sequelize");
const { TrainingDTO, TrainingDetailsDTO } = require("../dto/training.dto");
const { Category, CourseMaterial, CourseDate } = require("../models");
const db = require("../models");
/**
* Service to create, update, and retrieve training information.
* @module services/training
* @see {@link module:services/training}
*/
const trainingService = {
/**
* Search for trainings based on the provided search terms.
* @memberof module:services/training
* @param {*} terms - The search terms to match against training name.
* @returns {Promise<TrainingDTO[]>} A promise that resolves to an array of Training objects matching the search terms.
* @throws {Error} - If the operation fails or encounters an error.
*/
search: async (terms) => {
const { rows, count } = await db.Training.findAndCountAll({
where: {
name: {
[Op.like]: `%${terms}%`,
},
},
distinct: true,
include: [Category],
});
return {
trainings: rows.map((track) => new TrainingDTO(track)),
count,
};
},
/**
* Retrieve a paginated list of trainings.
* @memberof module:services/training
* @param {number} offset - The number of items to skip before starting to return results.
* @param {number} limit - The maximum number of items to return.
* @returns {Promise<{ students: Array<TrainingDTO>, count: number }>} - A promise that resolves to an object containing an array of TrainingDTO objects representing the teachers and the total count of teachers.
* @throws {Error} - If the operation fails or encounters an error.
*/
getAll: async (offset, limit) => {
const { rows, count } = await db.Training.findAndCountAll({
distinct: true,
offset,
limit,
include: [db.Category, { model: db.Student, include: [db.User] }],
});
console.log("ROWS---", rows);
return {
trainings: rows.map((training) => new TrainingDetailsDTO(training)),
count,
};
},
/**
* Retrieves all trainings belonging to a specific category by category ID.
* @memberof module:services/training
* @param {*} id - The ID of the category to retrieve trainings for.
* @returns {Promise<TrainingDTO[]|null>} - A promise that resolves to a TrainingDTO object representing the trainings if found, or null if no trainings are found.
* @throws {Error} - If the operation fails or encounters an error.
*/
getAllByCategoryId: async (id) => {
const training = await db.Training.findAll(id, {
include: [db.Category, { model: db.Student, include: [db.User] }],
});
return training ? new TrainingDTO(training) : null;
},
/**
* Retrieve the user details with the provided ID.
* @memberof module:services/training
* @param {*} id The ID of the training to retrieve.
* @returns {Promise<TrainingTO|null>} - A promise that resolves to a TrainingDTO object representing the training if found, or null if not found.
* @throws {Error} - If the operation fails or encounters an error.
*/
getById: async (id) => {
const training = await db.Training.findByPk(id, {
include: [
db.Category,
db.Course,
{ model: db.Student, include: [db.User] },
],
});
return training ? new TrainingDetailsDTO(training) : null;
},
/**
* Create a training with the provided data.
* @memberof module:services/training
* @param {*} trainingToAdd - The training data to be added.
* @returns {Promise<TrainingDTO|null>} A promise that resolves to a new TrainingDTO instance representing the created training, or null if creation fails.
* @throws {Error} - If the operation fails or encounters an error.
*/
create: async (trainingToAdd) => {
console.log(trainingToAdd);
const training = await db.Training.create(trainingToAdd);
console.log(training);
return training ? new TrainingDTO(training) : null;
},
/**
* Update training with the provided data.
* @memberof module:services/training
* @param {*} id - The ID of the training to update.
* @param {*} trainingToUpdate - The updated data for the training.
* @returns {Promise<boolean>} - Promise that resolves to true if the training update was successful, or false otherwise.
* @throws {Error} - If the operation fails or encounters an error.
*/
update: async (id, trainingToUpdate) => {
const transaction = await db.sequelize.transaction();
console.log(trainingToUpdate);
// Retrieve the training
const training = await db.Training.findByPk(id, {
include: [],
});
try {
// Remove the Courses associations
training.setCourses([]);
// Update the Courses associations
for (const course of trainingToUpdate.courses) {
await training.addCourse(course.id, { transaction });
}
// Update the Training details
const updatedRow = await db.Training.update(
trainingToUpdate,
{
where: { id },
},
{
include: [db.Category],
}
);
await transaction.commit();
return updatedRow[0] === 1;
} catch (err) {
await transaction.rollback();
return null;
}
},
/**
* Delete training with the provided ID.
* @memberof module:services/training
* @param {*} id - The ID of the training to delete.
* @returns {Promise<boolean>} - Promise that resolves to true if the training deleted was successful, or false otherwise.
* @throws {Error} - If the operation fails or encounters an error.
*/
delete: async (id) => {
const nbDeletedRow = await db.Training.destroy({
where: { id },
});
return nbDeletedRow === 1;
},
/**
* Updates the cover image for a training with the provided ID.
* @memberof module:services/training
* @param {string} id - The ID of the training to update the cover image for.
* @param {string} filename - The filename of the new cover image.
* @returns {Promise<boolean>} - A promise that resolves to true if the cover image update was successful, or false otherwise.
* @throws {Error} - If the operation fails or encounters an error.
*/
updateCover: async (id, filename) => {
const data = {
cover: `/images/covers/${filename}`,
};
const updatedRow = await db.Training.update(data, {
where: { id },
});
return updatedRow[0] === 1;
},
/**
* Checks if a training with the provided name already exists.
* @memberof module:services/training
* @param {string} name - The name of the training to check for existence.
* @returns {Promise<boolean>} - A promise that resolves to true if a training with the provided name already exists, or false otherwise.
* @throws {Error} - If the operation fails or encounters an error.
*/
nameAlreadyExists: async (name) => {
const training = await db.Training.findOne({ where: { name } });
return training ? true : false;
},
/**
* Add a student to training.
* @memberof module:services/training
* @param {string} studentId - The ID of the student to add.
* @param {string} teacherId - The ID of the training.
* @returns {Promise<boolean>} - Promise that resolves to true if the student was added successfully, or false otherwise.
* @throws {Error} - If the operation fails or encounters an error.
*/
addStudent: async (studentId, trainingId) => {
const student = await db.Student.findByPk(studentId);
if (!student) return false;
const training = await db.Training.findByPk(trainingId);
if (!training) return false;
// console.log(student);
// console.log(training);
// Add the student to the training
const mixins = await training.addStudent(student);
console.log(mixins);
return true;
},
/**
* Remove student from training.
* @memberof module:services/training
* @param {*} studentId - The ID of the student to be removed.
* @param {*} trainingId - @param {string} trainingId - The ID of the training from which the student will be removed.
* @returns {Promise<boolean>} - A Promise that resolves to true if the student removal was successful, or false otherwise.
* @throws {Error} - If the operation fails or encounters an error.
*/
removeStudent: async (studentId, trainingId) => {
const student = await db.Student.findByPk(studentId);
if (!student) return false;
const training = await db.Training.findByPk(trainingId);
if (!training) return false;
console.log(student);
console.log(training);
// Add the student to the training
const mixins = await training.removeStudent(student);
console.log(mixins);
return true;
},
};
module.exports = trainingService;