using AutoMapper; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.FileProviders; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Tsi1.BusinessLayer.Dtos; using Tsi1.BusinessLayer.Helpers; using Tsi1.BusinessLayer.Interfaces; using Tsi1.DataLayer; using Tsi1.DataLayer.Entities; namespace Tsi1.BusinessLayer.Services { public class CourseService : ICourseService { private readonly Tsi1Context _context; private readonly IMapper _mapper; public CourseService(Tsi1Context context, IMapper mapper) { _context = context; _mapper = mapper; } public async Task<ServiceResult<Course>> Create(CourseCreateDto newCourse) { var result = new ServiceResult<Course>(); var existingCourse = await _context.Courses .FirstOrDefaultAsync(x => x.Name == newCourse.Name && x.TenantId == newCourse.TenantId); if (existingCourse != null) { result.HasError = true; result.Message = string.Format(ErrorMessages.DuplicateCourseName, newCourse.Name); return result; } var course = _mapper.Map<Course>(newCourse); _context.Courses.Add(course); await _context.SaveChangesAsync(); result.Data = course; return result; } public async Task<ServiceResult<List<CoursePreviewDto>>> GetCoursePreviews(int userId, string userType) { var result = new ServiceResult<List<CoursePreviewDto>>(); var courses = new List<Course>(); var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == userId); if (user == null) { result.HasError = true; result.Message = string.Format(ErrorMessages.UserDoesNotExist, userId); return result; } if (userType == UserTypes.Student) { courses = await _context.StudentCourses .Include(x => x.Course) .Where(x => x.StudentId == user.StudentId) .Select(x => x.Course) .ToListAsync(); } else if (userType == UserTypes.Professor) { courses = await _context.ProfessorCourses .Include(x => x.Course) .Where(x => x.ProfessorId == user.ProfessorId) .Select(x => x.Course) .ToListAsync(); } result.Data = _mapper.Map<List<CoursePreviewDto>>(courses); return result; } public async Task<ServiceResult<bool>> Matriculate(int userId, int courseId) { var result = new ServiceResult<bool>(); var user = await _context.Users .Include(x => x.Student) .FirstOrDefaultAsync(x => x.Id == userId); if (user == null || user.Student == null) { result.Message = string.Format(ErrorMessages.UserDoesNotExist, userId); return result; } var course = await _context.Courses.FirstOrDefaultAsync(x => x.Id == courseId); if (course == null) { result.Message = string.Format(ErrorMessages.CourseDoesNotExist, courseId); return result; } var existingStudentCourse = await _context.StudentCourses .FirstOrDefaultAsync(x => x.StudentId == user.StudentId && x.CourseId == course.Id); if (existingStudentCourse != null) { result.HasError = true; result.Message = string.Format(ErrorMessages.StudentCourseAlreadyExists, user.Username, course.Name); return result; } var studentCourse = new StudentCourse { Course = course, Student = user.Student }; _context.StudentCourses.Add(studentCourse); await _context.SaveChangesAsync(); result.Data = true; return result; } public async Task<ServiceResult<bool>> AddProfessorToCourse(ProfessorCourseDto professorCourseDto) { var result = new ServiceResult<bool>(); var user = await _context.Users .Include(x => x.Professor) .FirstOrDefaultAsync(x => x.Id == professorCourseDto.UserId); if (user == null || user.Professor == null) { result.Message = string.Format(ErrorMessages.UserDoesNotExist, user.Username); return result; } var course = await _context.Courses .FirstOrDefaultAsync(x => x.Id == professorCourseDto.CourseId); if (course == null) { result.Message = string.Format(ErrorMessages.CourseDoesNotExist, professorCourseDto.CourseId); return result; } var existingProfessorCourse = await _context.ProfessorCourses .FirstOrDefaultAsync(x => x.ProfessorId == user.ProfessorId && x.CourseId == course.Id); if (existingProfessorCourse != null) { result.HasError = true; result.Message = string.Format(ErrorMessages.ProfessorCourseAlreadyExists, user.Username, course.Name); return result; } var professorCourse = new ProfessorCourse { Course = course, Professor = user.Professor }; _context.ProfessorCourses.Add(professorCourse); await _context.SaveChangesAsync(); result.Data = true; return result; } public async Task<ServiceResult<List<CoursePreviewDto>>> GetAll(int tenantId) { var result = new ServiceResult<List<CoursePreviewDto>>(); var courses = await _context.Courses .Where(x => x.TenantId == tenantId) .ToListAsync(); var coursesDto = _mapper.Map<List<CoursePreviewDto>>(courses); result.Data = coursesDto; return result; } public async Task<ServiceResult<bool>> Modify(int courseId, CourseCreateDto courseDto) { var result = new ServiceResult<bool>(); var course = await _context.Courses .FirstOrDefaultAsync(x => x.Id == courseId); if (course == null) { result.Message = string.Format(ErrorMessages.CourseDoesNotExist, courseId); return result; } _mapper.Map(courseDto, course); await _context.SaveChangesAsync(); result.Data = true; return result; } public async Task<ServiceResult<Course>> Delete(int courseId) { var result = new ServiceResult<Course>(); var course = await _context.Courses .FirstOrDefaultAsync(x => x.Id == courseId); if (course == null) { result.Message = string.Format(ErrorMessages.CourseDoesNotExist, courseId); return result; } _context.Courses.Remove(course); await _context.SaveChangesAsync(); result.Data = course; return result; } public async Task<ServiceResult<bool>> DropOutFromCourse(int userId, int courseId) { var result = new ServiceResult<bool>(); var user = await _context.Users .Include(x => x.Student) .FirstOrDefaultAsync(x => x.Id == userId); if (user == null || user.Student == null) { result.Message = string.Format(ErrorMessages.UserDoesNotExist, userId); return result; } var course = await _context.Courses.FirstOrDefaultAsync(x => x.Id == courseId); if (course == null) { result.Message = string.Format(ErrorMessages.CourseDoesNotExist, courseId); return result; } var studentCourse = await _context.StudentCourses .FirstOrDefaultAsync(x => x.StudentId == user.StudentId && x.CourseId == course.Id); if (studentCourse == null) { result.HasError = true; result.Message = string.Format(ErrorMessages.StudentCourseDoesNotExists, user.Username, course.Name); return result; } _context.StudentCourses.Remove(studentCourse); await _context.SaveChangesAsync(); result.Data = true; return result; } public async Task<ServiceResult<bool>> RemoveProfessorToCourse(ProfessorCourseDto professorCourseDto) { var result = new ServiceResult<bool>(); var user = await _context.Users .Include(x => x.Professor) .FirstOrDefaultAsync(x => x.Id == professorCourseDto.UserId); if (user == null || user.Professor == null) { result.Message = string.Format(ErrorMessages.UserDoesNotExist, user.Username); return result; } var course = await _context.Courses .FirstOrDefaultAsync(x => x.Id == professorCourseDto.CourseId); if (course == null) { result.Message = string.Format(ErrorMessages.CourseDoesNotExist, professorCourseDto.CourseId); return result; } var professorCourse = await _context.ProfessorCourses .FirstOrDefaultAsync(x => x.ProfessorId == user.ProfessorId && x.CourseId == course.Id); if (professorCourse == null) { result.HasError = true; result.Message = string.Format(ErrorMessages.ProfessorCourseDoesNotExists, user.Username, course.Name); return result; } _context.ProfessorCourses.Remove(professorCourse); await _context.SaveChangesAsync(); result.Data = true; return result; } public async Task<ServiceResult<List<UserPreviewDto>>> GetProfessors(int courseId) { var result = new ServiceResult<List<UserPreviewDto>>(); var users = await _context.ProfessorCourses .Include(x => x.Professor) .ThenInclude(x => x.User) .Where(x => x.CourseId == courseId) .Select(x => x.Professor.User) .ToListAsync(); var userDtos = _mapper.Map<List<UserPreviewDto>>(users); result.Data = userDtos; return result; } } }