Skip to content

Commit

Permalink
Merge pull request #462 from kzi-nastava/feat/examslot-timeslot-db-co…
Browse files Browse the repository at this point in the history
…nnection

feat: connect ExamSlot Entity to database
  • Loading branch information
anasinik authored Jun 14, 2024
2 parents a403967 + a8410bc commit 23ab642
Show file tree
Hide file tree
Showing 22 changed files with 336 additions and 287 deletions.
1 change: 1 addition & 0 deletions LangLang/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public App()
services.AddTransient<ICourseRepository, CourseRepository>();
services.AddTransient<IExamSlotRepository, ExamSlotRepository>();
services.AddTransient<ILanguageLevelRepository, LanguageLevelRepository>();
services.AddTransient<ICourseTimeSlotRepository, CourseTimeSlotRepository>();
services.AddTransient<ITutorRepository, TutorRepository>();
services.AddTransient<ITutorSkillRepository, TutorSkillRepository>();

Expand Down
33 changes: 33 additions & 0 deletions LangLang/BusinessLogic/UseCases/CourseTimeSlotService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using LangLang.Composition;
using LangLang.Domain.RepositoryInterfaces;
using LangLang.Domain.Models;
using System.Collections.Generic;

namespace LangLang.BusinessLogic.UseCases
{
public class CourseTimeSlotService
{
public ICourseTimeSlotRepository _repository;

public CourseTimeSlotService()
{
_repository = Injector.CreateInstance<ICourseTimeSlotRepository>();
}

public void Add(CourseTimeSlot courseTimeSlot)
{
_repository.Add(courseTimeSlot);
}

public List<CourseTimeSlot> GetAll()
{
return _repository.GetAll();
}

public CourseTimeSlot Get(int id)
{
return _repository.Get(id);
}

}
}
212 changes: 102 additions & 110 deletions LangLang/BusinessLogic/UseCases/ExamSlotService.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using LangLang.Composition;
using LangLang.Configuration;
using LangLang.Domain.Enums;
using LangLang.Domain.Models;
using LangLang.Domain.RepositoryInterfaces;
using LangLang.Composition;
using LangLang.Domain.Enums;
using LangLang.Configuration;

using System;
using System.Collections.Generic;
using System.Linq;

namespace LangLang.BusinessLogic.UseCases
{
Expand All @@ -29,11 +28,25 @@ private int GenerateId()
{
return _exams.Get(id);
}

public List<ExamSlot> GetAll()
{
return _exams.GetAll();
}

public void Update(ExamSlot exam)
{
_exams.Update(exam);
}

public void Add(ExamSlot exam)
{
if (!CanCreateExam(exam))
throw new Exception("It's not possible to create exam, try entering different data");
exam.Id = GenerateId();
_exams.Add(exam);
}

public List<ExamSlot> GetGraded()
{
var gradedExams = new List<ExamSlot>();
Expand All @@ -51,21 +64,11 @@ public List<ExamSlot> GetGraded()
// returns all graded exams for a specified language
public List<ExamSlot> GetByLanguage(string language)
{
var exams = GetAll().Where(exam => exam.Language.Equals(language, StringComparison.OrdinalIgnoreCase)).ToList();
var resultService = new ExamResultService();
var languageService = new LanguageLevelService();

return exams.Where(exam => !resultService.GetByExam(exam).All(result => result.Outcome != ExamOutcome.NotGraded && exam.ResultsGenerated)).ToList();
}

//function takes examslot and adds it to dictionary of examslots
//function saves changes and returns if adding was successful
public bool Add(ExamSlot exam)
{
if (!CanCreateExam(exam)) return false;
exam.Id = GenerateId();
_exams.Add(exam);
return true;

var exams = GetAll().Where(exam => languageService.Get(exam.LanguageId).Language.Equals(language, StringComparison.OrdinalIgnoreCase)).ToList();
return exams.Where(exam => resultService.GetByExam(exam).All(result => result.Outcome != ExamOutcome.NotGraded && exam.ResultsGenerated)).ToList();
}

public bool CanCreateExam(ExamSlot exam)
Expand All @@ -77,12 +80,12 @@ public bool CanCreateExam(ExamSlot exam)
public bool CoursesAndExamOverlapp(ExamSlot exam, ref int busyClassrooms)
{
var courseService = new CourseService();
List<Course> courses = courseService.GetAll().ToList();
// Go through courses
foreach (Course course in courses)
var timeService = new TimeSlotService();

foreach (Course course in courseService.GetAll())
{
//check for overlapping
if (course.OverlappsWith(exam.TimeSlot))
if (course.OverlappsWith(timeService.Get(exam.TimeSlotId)))
{
//tutor is busy (has class)
if (course.TutorId == exam.TutorId)
Expand All @@ -94,21 +97,22 @@ public bool CoursesAndExamOverlapp(ExamSlot exam, ref int busyClassrooms)
//all classrooms are busy
if (busyClassrooms == 2)
return true;

}
}
return false;
}

// Checks for any overlaps between other exams and current exam, considering the availability of the exam's tutor and classrooms
public bool ExamsOverlapp(ExamSlot exam, ref int busyClassrooms)
{
// Go through all exams
var timeService = new TimeSlotService();

foreach (ExamSlot currExam in GetAll())
{
if (currExam.Id == exam.Id)
continue;

if (exam.TimeSlot.OverlappsWith(currExam.TimeSlot))
if (timeService.Get(exam.TimeSlotId).OverlappsWith(timeService.Get(currExam.TimeSlotId)))
{
//tutor is busy (has exam)
if (exam.TutorId == currExam.TutorId)
Expand All @@ -125,140 +129,121 @@ public bool ExamsOverlapp(ExamSlot exam, ref int busyClassrooms)
return false;
}

//function takes id of examslot and removes examslot with that id
//function saves changes and returns if removing was successful
public bool Delete(int id)
public void Delete(int id)
{
ExamSlot exam = Get(id);
if (exam == null) return false;

if (!((exam.TimeSlot.Time - DateTime.Now).TotalDays >= Constants.EXAM_MODIFY_PERIOD)) return false;
var timeService = new TimeSlotService();
TimeSlot timeSlot = timeService.Get(exam.TimeSlotId);

if (!((timeSlot.Time - DateTime.Now).TotalDays >= Constants.EXAM_MODIFY_PERIOD))
throw new Exception("$Can't delete exam, there is less than {Constants.EXAM_MODIFY_PERIOD} days before exam.");

_exams.Delete(exam);
return true;

}
//deletes future exams by given tutor

public void DeleteByTutor(Tutor tutor)
{
ExamApplicationService appsService = new();
List<ExamSlot> exams = GetExams(tutor);
foreach (ExamSlot exam in exams)
var applicationService = new ExamApplicationService();
var timeService = new TimeSlotService();

foreach (ExamSlot exam in GetByTutor(tutor))
{
if (exam.TimeSlot.Time > DateTime.Now)
var timeSlot = timeService.Get(exam.TimeSlotId);

if (timeSlot.Time > DateTime.Now)
{
appsService.DeleteByExam(exam);
applicationService.DeleteByExam(exam);
Delete(exam.Id);
}
}
}
public void AddStudent(ExamSlot exam)

public void IncrementApplicants(ExamSlot exam)
{
exam.Applicants++;
_exams.Update(exam);
}

public void RemoveStudent(ExamSlot exam)
public void DecrementApplicants(ExamSlot exam)
{
exam.Applicants--;
_exams.Update(exam);
}
public void Update(ExamSlot exam)

public bool ApplicationsVisible(ExamSlot exam)
{
_exams.Update(exam);
}
var timeSlotService = new TimeSlotService();
TimeSlot timeSlot = timeSlotService.Get(exam.Id);

int daysLeft = (timeSlot.Time - DateTime.Now).Days; // days left until exam
double timeLeft = (timeSlot.GetEnd() - DateTime.Now).TotalMinutes; // time left until end of exam

if (daysLeft > 0 && daysLeft < Constants.PRE_START_VIEW_PERIOD) return true; // applications become visible when there are less than PRE_START_VIEW_PERIOD days left
else if (daysLeft == 0 && timeLeft > 0) return true; // on the exam day, applications are visible until the end of exam
return false;
}

public bool CanBeUpdated(ExamSlot exam)
{
return (exam.TimeSlot.Time - DateTime.Now).TotalDays >= Constants.EXAM_MODIFY_PERIOD;
var timeService = new TimeSlotService();
return (timeService.Get(exam.TimeSlotId).Time - DateTime.Now).TotalDays >= Constants.EXAM_MODIFY_PERIOD;
}


// Method to get all exam slots by tutor ID
//function takes tutor id
public List<ExamSlot> GetExams(Tutor tutor)
public List<ExamSlot> GetByTutor(Tutor tutor)
{
return _exams.GetExams(tutor);
return _exams.GetByTutor(tutor);
}


// Method to check if an exam slot is available
// takes exam slot, returns true if it is availbale or false if it isn't available
public bool IsAvailable(ExamSlot exam)
{
if (HasPassed(exam))
{
return false;
}

if (IsFullyBooked(exam))
{
return false;
}

if (IsLessThanMonthAway(exam))
{
if ( HasPassed(exam) || IsFullyBooked(exam) || IsLessThanMonthAway(exam) )
return false;
}

return true;
}

public bool HasPassed(ExamSlot exam)
public List<ExamSlot> SearchByTutor(Tutor tutor, DateTime examDate, string language, Level? level)
{
return exam.TimeSlot.Time < DateTime.Now;
return Search(GetByTutor(tutor), examDate, language, level);
}

public bool IsFullyBooked(ExamSlot exam)
public List<ExamSlot> SearchByStudent(Student student, DateTime examDate, string courseLanguage, Level? Level)
{
return exam.MaxStudents == exam.Applicants;
return Search(GetAvailableExams(student), examDate, courseLanguage, Level);
}

// Check if exam is less than 30 days away
private bool IsLessThanMonthAway(ExamSlot exam)
private List<ExamSlot> Search(List<ExamSlot> exams, DateTime examDate, string language, Level? level)
{
DateTime currentDate = DateTime.Now;
var languageService = new LanguageLevelService();
var timeService = new TimeSlotService();

TimeSpan difference = exam.TimeSlot.Time - currentDate;

return difference.TotalDays < 30;
return exams.Where(exam => (examDate == default || timeService.Get(exam.TimeSlotId).Time.Date == examDate.Date) &&
(language == "" || languageService.Get(exam.LanguageId).Language == language) &&
(level == null || languageService.Get(exam.LanguageId).Level == level)).ToList();
}
// Method to search exam slots by tutor and criteria
public List<ExamSlot> SearchByTutor(Tutor tutor, DateTime examDate, string language, LanguageLevel? level)
{
List<ExamSlot> exams = _exams.GetAll();

exams = GetExams(tutor);

return Search(exams, examDate, language, level);
public bool HasPassed(ExamSlot exam)
{
var timeService = new TimeSlotService();
return timeService.Get(exam.TimeSlotId).Time < DateTime.Now;
}

private List<ExamSlot> Search(List<ExamSlot> exams, DateTime examDate, string language, LanguageLevel? level)
public bool IsFullyBooked(ExamSlot exam)
{
List<ExamSlot> filteredExams = exams.Where(exam =>
(examDate == default || exam.TimeSlot.Time.Date == examDate.Date) &&
(language == "" || exam.Language == language) &&
(level == null || exam.Level == level)
).ToList();

return filteredExams;
return exam.MaxStudents == exam.Applicants;
}


public bool ApplicationsVisible(int id)
private bool IsLessThanMonthAway(ExamSlot exam)
{
ExamSlot examSlot = Get(id);
return examSlot.ApplicationsVisible();
var timeService = new TimeSlotService();
return (timeService.Get(exam.TimeSlotId).Time - DateTime.Now).TotalDays < 30;
}

public List<ExamSlot> SearchByStudent(Student student, DateTime examDate, string courseLanguage, LanguageLevel? languageLevel)
public List<ExamSlot> GetExamsHeldInLastYear()
{
List<ExamSlot> availableExamSlots = GetAvailableExams(student);
return Search(availableExamSlots, examDate, courseLanguage, languageLevel);
return GetAll().Where(exam => IsHeldInLastYear(exam)).ToList();
}


public List<ExamSlot> GetAvailableExams(Student student)
{
List<ExamSlot> availableExams = new();
Expand All @@ -283,9 +268,11 @@ public List<ExamSlot> GetAvailableExams(Student student)
private bool HasPassedLowerLevel(List<ExamResult> results, ExamSlot exam)
{
var examService = new ExamSlotService();
var languageService = new LanguageLevelService();

return results.Any(result => result.Outcome == ExamOutcome.Passed &&
exam.Language == examService.Get(result.ExamSlotId).Language &&
exam.Level < examService.Get(result.ExamSlotId).Level);
languageService.Get(exam.LanguageId).Language == languageService.Get(examService.Get(result.ExamSlotId).LanguageId).Language &&
languageService.Get(exam.LanguageId).Level < languageService.Get(examService.Get(result.ExamSlotId).LanguageId).Level);
}

private bool HasAttendedRequiredCourse(List<EnrollmentRequest> requests, ExamSlot exam)
Expand All @@ -297,16 +284,21 @@ private bool HasAttendedRequiredCourse(List<EnrollmentRequest> requests, ExamSlo

private bool HasStudentAttendedCourse(Course course, ExamSlot examSlot)
{
return course.Language == examSlot.Language &&
course.Level <= examSlot.Level &&
course.IsCompleted();
var languageService = new LanguageLevelService();
var examLanguage = languageService.Get(examSlot.LanguageId);
var courseLanguage = languageService.Get(course.LanguageLevelId);

return courseLanguage.Language == examLanguage.Language &&
courseLanguage.Level <= examLanguage.Level && course.IsCompleted();
}

public List<ExamSlot> GetExamsHeldInLastYear()
private bool IsHeldInLastYear(ExamSlot exam)
{
return GetAll().Where(exam => exam.IsHeldInLastYear()).ToList();
}
var timeService = new TimeSlotService();
var timeSlot = timeService.Get(exam.TimeSlotId);

return timeSlot.Time > DateTime.Now.AddYears(-1);
}

}
}
Loading

0 comments on commit 23ab642

Please sign in to comment.