import { Injectable, InternalServerErrorException, NotFoundException, ConflictException, Scope, Inject, } from '@nestjs/common'; import { Model, Schema } from 'mongoose'; import { InjectModel } from '@nestjs/mongoose'; import { UserDocument as User } from './schema/user.schema'; import { CreateUserDTO } from './dto/create-user.dto'; import { UpdateUserDTO } from './dto/update-user.dto'; import { CourseDocument as Course } from '../course/schema/course.schema'; import { EnrolledCourseDocument as Enrolled } from '../course/schema/enrolledCourse.schema'; import { CreateEnrolledDTO } from './dto/create-enrolled.dto'; import { UpdateEnrolledDTO } from './dto/update-enrolled.dto'; import { REQUEST } from '@nestjs/core'; import { Request } from 'express'; @Injectable({ scope: Scope.REQUEST }) export class UserService { constructor( @InjectModel('User') private readonly userModel: Model<User>, @InjectModel('Course') private readonly courseModel: Model<Course>, @InjectModel('Enrolled') private readonly enrolledModel: Model<Enrolled>, @Inject(REQUEST) private readonly request: Request, ) {} // fetch all Users async getAllUser(): Promise<User[]> { try { const users = await this.userModel.find().exec(); return users; } catch (e) { throw new InternalServerErrorException(e); } } // fetch all gamification data async getAllGamified(skip: string): Promise<User[]> { try { const skipNum = parseInt(skip, 10); const users = await this.userModel .find({}, { _id: false }, { skip: skipNum, limit: 10 }) .select('first_name last_name score photoUrl') .sort({ score: -1 }) .exec(); return users; } catch (e) { throw new InternalServerErrorException(e); } } // Get a single User async findUserByEmail(query): Promise<User> { try { const { email } = query; const user = await this.userModel.findOne({ email }); if (user) { return user; } else { throw new NotFoundException(`user with email ${email} not Found`); } } catch (e) { throw new InternalServerErrorException(e); } } // Get a single User async getMe(): Promise<User> { try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { return user; } else { throw new NotFoundException("Your email doesn't Exist in database"); } } catch (e) { throw new InternalServerErrorException(e); } } // post a single User async addUser(request, CreateUserDTO: CreateUserDTO): Promise<User> { try { const { email, fId, role } = request['user']; const userExists = await this.userModel.findOne({ email: email }).lean(); if (userExists) { throw new ConflictException(`User with email ${email} already exists`); } const userToBeCreated = { ...CreateUserDTO, email, fId, role }; const newUser = await new this.userModel(userToBeCreated); return newUser.save(); } catch (e) { throw new InternalServerErrorException(e); } } // Edit User details async updateUser(UpdateUserDTO: UpdateUserDTO): Promise<User> { let updatedUser; const filter = { email: this.request['user']['email'] }; try { updatedUser = await this.userModel.findOneAndUpdate( filter, UpdateUserDTO, { new: true, useFindAndModify: false }, ); } catch (e) { throw new InternalServerErrorException(e); } finally { return updatedUser; } } // Delete a User async deleteUser(query: any): Promise<any> { try { const deletedUser = await this.userModel.findOneAndDelete(query); if (deletedUser) { return deletedUser; } else { throw new NotFoundException('User not Found or query not correct!'); } } catch (e) { throw new InternalServerErrorException(e); } } // gets all Enrolled courses async getEnrolledCoursesById(courseId: Schema.Types.ObjectId) { try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { const userId = user.id; const enrolledCourses = await this.enrolledModel.findOne({ studentId: userId, courseId: courseId, }); return enrolledCourses; } else { throw new NotFoundException('User not found'); } } catch (e) { throw new InternalServerErrorException(e); } } // gets all Enrolled courses async getEnrolledCourses() { try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { const userId = user.id; const enrolledCourses = await this.enrolledModel.find({ studentId: userId, }); return enrolledCourses; } else { throw new NotFoundException('User not found'); } } catch (e) { throw new InternalServerErrorException(e); } } // adds Enrolled Course async addCourse(createEnrolledDTO: CreateEnrolledDTO) { try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { const courseIdSearch = await this.enrolledModel .find({ studentId: user.id }) .lean(); courseIdSearch.forEach((singleEnrolled) => { if (singleEnrolled.courseId == createEnrolledDTO['courseId']) { throw new ConflictException('Course Already Enrolled by user'); } }); const newEnrolled = await new this.enrolledModel(createEnrolledDTO); const course = await this.courseModel.findById( createEnrolledDTO.courseId, ); if (course) { newEnrolled['videosWatched'] = new Array(course.video_num).fill( false, ); await newEnrolled.save(); return newEnrolled; } else { throw new NotFoundException('course not found!'); } // a test line to see the populated sets of data /*const newF = await this.enrolledModel.find({}).populate('students'); return newF;*/ } else { throw new NotFoundException('user not found!'); } } catch (e) { throw new InternalServerErrorException(e); } } // gets all wishlisted courses async getWishList(): Promise<any> { try { const userWishList = await this.userModel .findOne({ email: this.request['user']['email'], }) .lean(); return userWishList.wishlist; } catch (e) { throw new InternalServerErrorException(e); } } // adds wishlisted course async addWishlist(cId: Schema.Types.ObjectId) { try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { const doesWishlistExists = await this.courseModel.exists({ _id: cId['cId'], }); if (doesWishlistExists) { const doesUserExistInWishList = user.wishlist.includes(cId['cId']); if (!doesUserExistInWishList) { user.wishlist.push(cId['cId']); await user.save(); return user; } else { throw new ConflictException('Course Already Exists In WishList'); } } else { throw new NotFoundException("Wishlisted Course doesn't exist"); } } else { throw new NotFoundException('User Not Found'); } } catch (e) { throw new InternalServerErrorException(e); } } // Delete a wishList of User async deleteWishList(wishId: Schema.Types.ObjectId): Promise<any> { try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { user.wishlist = user.wishlist.filter((wishlist) => wishlist != wishId); await user.save(); return user; } else { throw new NotFoundException('not found'); } } catch (e) { throw new InternalServerErrorException(e); } } // gets all courses on cartList async getCartList(): Promise<any> { try { const userCartList = await this.userModel .findOne({ email: this.request['user']['email'], }) .lean(); return userCartList.cartList; } catch (e) { throw new InternalServerErrorException(e); } } // adds a course to Cart async addCartList(cId: Schema.Types.ObjectId) { try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { const doesCartListExists = await this.courseModel.exists({ _id: cId['cId'], }); if (doesCartListExists) { const doesUserExistInCartList = user.cartList.includes(cId['cId']); if (!doesUserExistInCartList) { user.cartList.push(cId['cId']); await user.save(); return user; } else { throw new ConflictException('Course Already Exists In Cart'); } } else { throw new NotFoundException("Course doesn't exist"); } } else { throw new NotFoundException('User Not Found'); } } catch (e) { throw new InternalServerErrorException(e); } } // Delete a course from cart of user async deleteCardList(cartId: Schema.Types.ObjectId): Promise<any> { try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { user.cartList = user.cartList.filter((cartList) => cartList != cartId); await user.save(); return user; } else { throw new NotFoundException('User not found'); } } catch (e) { throw new InternalServerErrorException(e); } } // update Enrolled Course async updateCourse( updateEnrolledDto: UpdateEnrolledDTO, courseId: Schema.Types.ObjectId, ): Promise<any> { try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { const userId = user.id; const updatedCourse = await this.enrolledModel.findOneAndUpdate( { studentId: userId, courseId: courseId, }, updateEnrolledDto, { new: true, useFindAndModify: false }, ); return updatedCourse; } else { throw new NotFoundException('User not found'); } } catch (e) { throw new InternalServerErrorException(e); } } // Delete Enrolled Course of User async deleteEnrolledCourse(courseId: Schema.Types.ObjectId): Promise<any> { let deletedFrom; try { const user = await this.userModel.findOne({ email: this.request['user']['email'], }); if (user) { const userId = user.id; deletedFrom = await this.enrolledModel.findOneAndRemove({ studentId: userId, courseId: courseId, }); if (deletedFrom) { return deletedFrom; } else { throw new NotFoundException('not found'); } } else { throw new NotFoundException('User not found'); } } catch (e) { throw new InternalServerErrorException(e); } } }