/* eslint-disable @typescript-eslint/naming-convention */ import Database from '@ioc:Adonis/Lucid/Database'; import { Attachment } from '@ioc:Adonis/Addons/AttachmentLite'; /** * Datatypes */ import CourseStatusEnum from 'App/Datatypes/Enums/CourseStatusEnum'; /** * Models */ import Category from 'App/Models/Category'; import Course from 'App/Models/Course'; import Lesson from 'App/Models/Lesson'; import User from 'App/Models/User'; /** * Validators */ import CreateCourseValidator from 'App/Validators/Course/CreateCourseValidator'; import FetchCoursesValidator from 'App/Validators/Course/FetchCoursesValidator'; import UpdateCourseValidator from 'App/Validators/Course/UpdateCourseValidator'; export default class CourseRepository { private Database: typeof Database; private Course: typeof Course; constructor() { this.Database = Database; this.Course = Course; } /** * Set status on course * * @param id Course id * @returns Data result */ public async setStatus(id: string | number, status: CourseStatusEnum): Promise { const data = await this.Course.query().where('id', id).update({ status }).first(); return data; } /** * Get all courses * * @returns List of courses */ public async getAll(params?: FetchCoursesValidator['schema']['props']): Promise { const { status, category_id } = params || {}; const query = this.Course.query(); if (category_id) { query.andWhereHas('category', q => q.where('id', category_id)); } if (status) { query.andWhere('status', status); } const courses = await query .preload('color') .preload('category') .withCount('students') .withCount('likes') .withCount('lessons'); return courses; } /** * Get course by id * * @param id Course id * @returns Course or null */ public async getById(id: string | number): Promise { const course = await this.Course.query() .preload('teacher') .preload('color') .preload('category', q => q.preload('color')) .preload('lessons', q => q.preload('color').orderBy('display_order', 'asc').withCount('materials')) .preload('students', q => q.preload('roles').preload('contacts')) .withCount('likes') .withCount('lessons') .withCount('students') .where('id', id) .first(); return course; } /** * Get course by id without relations * * @param id Course id * @returns Course or null */ public async getByIdWithoutRelations(id: string | number, params?: any): Promise { const { status }: any = params || {}; const query = this.Course.query().where('id', id); if (status) { query.where('status', status); } const course = await query.first(); return course; } /** * Get likes count of course by id * * @param id Course id * @returns Likes count */ public async getLikesCount(id: string | number): Promise { const likes = await this.Database.query().from('courses_likes').where('course_id', id).count('* as count'); return likes[0].count; } /** * Get teacher of course * * @param id Course id * @returns User or null */ public async getTeacher(id: string | number): Promise { const course = await this.Course.query() .select('teacher_id') .preload('teacher', user => user.preload('contacts').preload('roles')) .where('id', id) .first(); return course && course.teacher; } /** * Get category of course * * @param id Course id * @returns Category or null */ public async getCategory(id: string | number): Promise { const course = await this.Course.query().select('category_id').preload('category').where('id', id).first(); return course && course.category; } /** * Get lessons of course * * @param id Course id * @returns List of lessons or null */ public async getLessons(id: string | number): Promise { const course = await this.Course.query().select('id').preload('lessons').where('id', id).first(); return course && course.lessons; } /** * Get students of course * * @param id Course id * @returns List of users or null */ public async getStudents(id: string | number): Promise { const course = await this.Course.query().preload('students').where('id', id).first(); return course && course.students; } /** * Get count of students * * @param id Course if * @returns Students count */ public async getStudentsCount(id: string | number): Promise { const students = await this.Database.query().from('users_courses').where('course_id', id).count('* as count'); return students[0].count; } /** * Create course * * @param data Data input * @returns Created course */ public async create(data: CreateCourseValidator['schema']['props']): Promise { /** * Create new course */ const course = new this.Course(); course.title = data.title; course.description = data.description; course.education_description = data.education_description; course.status = data.status; course.teacher_id = data.teacher_id; course.category_id = data.category_id; /** * Attach image */ if (data.image) { course.image = Attachment.fromFile(data.image); } await course.save(); return course; } /** * Delete course * * @param id Course id * @returns Deleted course */ public async delete(id: string | number): Promise { const course = await this.Course.query() .preload('category') .withCount('students') .withCount('likes') .withCount('lessons') .where('id', id) .first(); if (course) { await course.delete(); return course; } return null; } /** * Update course * * @param id Course id * @param data Data to update * @returns Updated course or null */ public async update(id: string | number, data: UpdateCourseValidator['schema']['props']): Promise { const course = await this.Course.query() .preload('teacher') .preload('category') .preload('lessons') .where('id', id) .first(); if (course) { /** * Update fields */ course.merge({ title: data.title, description: data.description, education_description: data.education_description, teacher_id: data.teacher_id, category_id: data.category_id, }); /** * Update image */ if (data.image) { course.image = Attachment.fromFile(data.image); } /** * Load other updated data */ course.load('category'); course.load('teacher'); await course.save(); return course; } return null; } }