public IActionResult Index() { UserScheduleViewModel model = new UserScheduleViewModel(); // Find our user with the auth token. var user = _userManager.GetUserAsync(User).Result; // Grab schedule from db. var sectionIds = _context.UserSections .Where(us => us.User == user) .Select(us => us.SectionId); // If we have no courses to show, why don't we just stop here? if (sectionIds.Count() == 0) { var emptyReturn = new UserScheduleViewModel { CourseListItems = new List <CourseListItemViewModel>(), ScheduleViewModel = new ScheduleViewModel() }; return(View(emptyReturn)); } var schedule = _context.Sections .Include(s => s.Course) .ThenInclude(c => c.User) .Include(s => s.Course) .ThenInclude(c => c.Sections) .ThenInclude(s => s.Professor) .Include(s => s.Course) .ThenInclude(c => c.Sections) .ThenInclude(s => s.Meetings) .ThenInclude(m => m.Location) .Include(s => s.Course) .ThenInclude(c => c.Cape) .ThenInclude(ca => ca.Professor) .ThenInclude(p => p.RateMyProfessor) .Where(s => sectionIds.Contains(s.Id)) .ToList(); // Populate model with schedule info. if (schedule != null) { model.ScheduleViewModel = FormatRepo.FormatSectionsToCalendarEvent(schedule); model.CourseListItems = schedule.Select(s => new CourseListItemViewModel { CourseId = s.Course.Id, CourseAbbreviation = s.Course.CourseAbbreviation, IsCustomEvent = s.Course.User != null }).ToList(); } // We shouldn't ever get here, because if a user has a user section, then schedule shouldn't be null. else { model.ScheduleViewModel = new ScheduleViewModel(); } return(View(model)); }
public IActionResult CreateCustomEvent([FromBody] CustomEventRequest data) { var modelStateErrors = this.ModelState.Values.SelectMany(m => m.Errors); var user = _userManager.GetUserAsync(User).Result; // Initialize database objects var course = new Course() { CourseAbbreviation = data.Name, User = user }; var section = new Section() { Course = course }; var meeting = new Meeting() { IsUnique = true, MeetingType = MeetingType.CustomEvent, Code = "A00", Days = data.Days, StartTime = new DateTime(1, 1, 1, data.StartTime.Hour, data.StartTime.Minute, 0), EndTime = new DateTime(1, 1, 1, data.EndTime.Hour, data.EndTime.Minute, 0), }; // Add back connections section.Meetings.Add(meeting); course.Sections.Add(section); var userSection = new UserSection() { Section = section, User = user, }; // Add to database _context.Courses.Add(course); _context.Sections.Add(section); _context.Meetings.Add(meeting); _context.UserSections.Add(userSection); _context.SaveChanges(); // Return response object var calendarEvents = FormatRepo.PopulateSectionEventsForBase(new List <Section> { section }, course) .Select(d => d.Value).First(); var response = new CustomEventResponse { CourseId = course.Id, SectionId = section.Id, CourseAbbreviation = course.CourseAbbreviation, CalendarEvents = calendarEvents }; return(Json(response)); }
/// <summary> /// Calculates the number of days the schedule has classes on /// </summary> /// <param name="schedule">A schedule of classes</param> /// <returns> the number of days in the schedule</returns> protected static int NumDays(List <Section> schedule) { int numDays = 0; var allDays = schedule.SelectMany(s => s.Meetings) .Where(m => !FormatRepo.IsOneTimeEvent(m.MeetingType)) .Select(m => m.Days); List <Days> days = Enum.GetValues(typeof(Days)).Cast <Days>().ToList(); foreach (var day in days) { if (allDays.Any(d => d.HasFlag(day))) { numDays++; } } return(numDays); }
/// <summary> /// Calculates the total gap size for a schedule. /// </summary> /// <param name="schedule">Schedule of classes</param> /// <returns>The total time gaps for a particular schedule</returns> protected static TimeSpan TotalGap(List <Section> schedule) { TimeSpan gap = new TimeSpan(0); List <DateTime> Monday = new List <DateTime>(); List <DateTime> Tuesday = new List <DateTime>(); List <DateTime> Wednesday = new List <DateTime>(); List <DateTime> Thursday = new List <DateTime>(); List <DateTime> Friday = new List <DateTime>(); var allMeetings = schedule.SelectMany(s => s.Meetings); foreach (Meeting meeting in allMeetings) { if (!FormatRepo.IsOneTimeEvent(meeting.MeetingType) && meeting.StartTime.Hour != 0 && meeting.EndTime.Hour != 0) { if (meeting.Days.HasFlag(Days.Monday)) { Monday.Add(meeting.StartTime); Monday.Add(meeting.EndTime); } if (meeting.Days.HasFlag(Days.Tuesday)) { Tuesday.Add(meeting.StartTime); Tuesday.Add(meeting.EndTime); } if (meeting.Days.HasFlag(Days.Wednesday)) { Wednesday.Add(meeting.StartTime); Wednesday.Add(meeting.EndTime); } if (meeting.Days.HasFlag(Days.Thursday)) { Thursday.Add(meeting.StartTime); Thursday.Add(meeting.EndTime); } if (meeting.Days.HasFlag(Days.Friday)) { Friday.Add(meeting.StartTime); Friday.Add(meeting.EndTime); } } } // Sort the class times in each schedule by start time. Monday.Sort(); Tuesday.Sort(); Wednesday.Sort(); Thursday.Sort(); Friday.Sort(); // Calculate the gaps in the schedule. for (int i = 1; i < Monday.Count - 1; i += 2) { gap += (Monday[i + 1].TimeOfDay - Monday[i].TimeOfDay); } for (int i = 1; i < Tuesday.Count - 1; i += 2) { gap += (Tuesday[i + 1].TimeOfDay - Tuesday[i].TimeOfDay); } for (int i = 1; i < Wednesday.Count - 1; i += 2) { gap += (Wednesday[i + 1].TimeOfDay - Wednesday[i].TimeOfDay); } for (int i = 1; i < Thursday.Count - 1; i += 2) { gap += (Thursday[i + 1].TimeOfDay - Thursday[i].TimeOfDay); } for (int i = 1; i < Friday.Count - 1; i += 2) { gap += (Friday[i + 1].TimeOfDay - Friday[i].TimeOfDay); } return(gap); }
public FormatServImpl() { formatRepo = Factory.getInstance().getFormatRepo(); }
public IActionResult GenerateSchedule([FromBody] CourseInfoToSchedule courseInfo) { // Get the current user. var user = _userManager.GetUserAsync(User).Result; // Check if there are no course ids, if there arn't remove all courses from schedule. if (courseInfo.CourseIds?.Length == 0) { // Remove all user sections for this user. var sectionsForUser = _context.UserSections.Where(us => us.UserId == user.Id).ToList(); _context.UserSections.RemoveRange(sectionsForUser ?? new List <UserSection>()); _context.SaveChanges(); return(Json(new ScheduleViewModel() { Error = "Please add a class to generate a schedule." })); } Course[] courses = _context.Courses .Include(c => c.Sections) .ThenInclude(s => s.Professor) .Include(c => c.Sections) .ThenInclude(s => s.Meetings) .ThenInclude(m => m.Location) .Include(c => c.Cape) .ThenInclude(ca => ca.Professor) .ThenInclude(p => p.RateMyProfessor) .Where(c => courseInfo.CourseIds.Contains(c.Id)).ToArray(); Optimization optimization = courseInfo.Optimization; var scheduleRepo = new ScheduleRepo(); // Call the schedule finding algorithm. PossibleSchedules schedules = scheduleRepo.FindScheduleForClasses(courses); if (!schedules.Any()) { // TODO: return error return(Json(new ScheduleViewModel() { Error = "No possible schedule for given courses." })); } List <Section> schedule = ScheduleOptimizationFactory.GetOptimization(optimization).Optimize(schedules); // Create user sections to add. var sectionsToAdd = schedule.Select(s => new UserSection { Section = s, User = user }); // Get the schedule sections for this user. var sectionsToRemove = _context.UserSections.Where(us => us.User == user); // Remove old sections. _context.RemoveRange(sectionsToRemove); // Add new ones. _context.AddRange(sectionsToAdd); _context.SaveChanges(); ScheduleViewModel model = FormatRepo.FormatSectionsToCalendarEvent(schedule); model.Error = ""; return(Json(model)); }