public ActionResult Edit(int id = 0)
        {
            AppointmentCreateMultipleViewModel ViewModel = new AppointmentCreateMultipleViewModel();
            Appointment appointment = db.Appointments.Find(id);

            if (appointment == null)
            {
                Session["FlashMessage"] = "Appointment not found.";
                return(RedirectToAction("Index"));
            }
            ViewModel.appointment = appointment;
            TimeSpan duration = appointment.end_time.TimeOfDay - appointment.start_time.TimeOfDay;

            ViewModel.duration  = duration.Minutes;
            ViewBag.statusList  = new SelectList(db.AppointmentStatus, "id", "name");
            ViewBag.concernList = new MultiSelectList(db.AppointmentConcerns.Where(c => c.program_id == null && !c.custom), "id", "name", appointment.AppointmentConcerns.Select(c => c.id));
            ViewBag.programList = new SelectList(programdb.Programs.Where(p => p.require_appointment), "name", "name");
            if (User.IsInRole("Admin") || User.IsInRole("Advising") || User.IsInRole("StudentDevelopment"))
            {
                ViewBag.hostList = new SelectList(db.AppointmentHosts, "id", "name");
            }
            else
            {
                ViewBag.hostList = new SelectList(db.AppointmentHosts.Where(h => h.SystemUsers.Any(u => u.UserName == User.Identity.Name)), "id", "name");
            }
            ViewBag.venueList = new SelectList(db.AppointmentVenues, "id", "name");
            return(View(ViewModel));
        }
        public ActionResult Edit(AppointmentCreateMultipleViewModel ViewModel)
        {
            Appointment appointment = db.Appointments.Find(ViewModel.appointment.id);

            if (ModelState.IsValid)
            {
                ViewModel.appointment.end_time = ViewModel.appointment.start_time.AddMinutes(ViewModel.duration);
                db.Entry(appointment).CurrentValues.SetValues(ViewModel.appointment);
                appointment.AppointmentConcerns.Clear();
                if (ViewModel.concerns != null)
                {
                    foreach (var concernid in ViewModel.concerns)
                    {
                        var concern = db.AppointmentConcerns.Find(concernid);
                        if (concern != null)
                        {
                            appointment.AppointmentConcerns.Add(concern);
                        }
                    }
                }
                db.SaveChanges();
                return(RedirectToAction("Index"));
            }

            ViewBag.statusList  = new SelectList(db.AppointmentStatus, "id", "name");
            ViewBag.concernList = new SelectList(db.AppointmentConcerns.Where(c => c.program_id == null && !c.custom), "id", "name");
            ViewBag.programList = new SelectList(programdb.Programs.Where(p => p.require_appointment), "name", "name");
            if (User.IsInRole("Admin") || User.IsInRole("Advising") || User.IsInRole("StudentDevelopment"))
            {
                ViewBag.hostList = new SelectList(db.AppointmentHosts, "id", "name");
            }
            else
            {
                ViewBag.hostList = new SelectList(db.AppointmentHosts.Where(h => h.SystemUsers.Any(u => u.UserName == User.Identity.Name)), "id", "name");
            }
            ViewBag.venueList = new SelectList(db.AppointmentVenues, "id", "name");
            return(View(appointment));
        }
        public ActionResult Create(AppointmentCreateMultipleViewModel ViewModel)
        {
            Appointment appointment = ViewModel.appointment;

            if (ModelState.IsValid)
            {
                if (ViewModel.concerns != null)
                {
                    foreach (var concernid in ViewModel.concerns)
                    {
                        var concern = db.AppointmentConcerns.Find(concernid);
                        if (concern != null)
                        {
                            appointment.AppointmentConcerns.Add(concern);
                        }
                    }
                }
                appointment.end_time = appointment.start_time.AddMinutes(ViewModel.duration);
                db.Appointments.Add(appointment);
                db.SaveChanges();
                return(RedirectToAction("Index"));
            }

            var status = db.AppointmentStatus.Where(s => s.name == "Opened").SingleOrDefault();

            ViewBag.statusList = new SelectList(db.AppointmentStatus, "id", "name", status.id);
            if (User.IsInRole("Admin") || User.IsInRole("Advising") || User.IsInRole("StudentDevelopment"))
            {
                ViewBag.hostList = new SelectList(db.AppointmentHosts, "id", "name");
            }
            else
            {
                ViewBag.hostList = new SelectList(db.AppointmentHosts.Where(h => h.SystemUsers.Any(u => u.UserName == User.Identity.Name)), "id", "name");
            }
            ViewBag.concernList = new SelectList(db.AppointmentConcerns.Where(c => c.program_id == null && !c.custom), "id", "name");
            ViewBag.venueList   = new SelectList(db.AppointmentVenues, "id", "name");
            return(View(appointment));
        }
        public ActionResult CreateMultiple(bool consultation = false)
        {
            AppointmentCreateMultipleViewModel ViewModel = new AppointmentCreateMultipleViewModel();

            ViewModel.appointment = new Appointment();
            ViewModel.duration    = 30;
            var status = db.AppointmentStatus.Where(s => s.name == "Opened").SingleOrDefault();

            ViewBag.statusList  = new SelectList(db.AppointmentStatus, "id", "name", status.id);
            ViewBag.concernList = new MultiSelectList(db.AppointmentConcerns.Where(c => c.program_id == null && !c.custom), "id", "name");
            ViewBag.programList = new SelectList(programdb.Programs.Where(p => p.require_appointment), "id", "name");
            if (User.IsInRole("Admin") || User.IsInRole("Advising") || User.IsInRole("StudentDevelopment"))
            {
                ViewBag.hostList = new SelectList(db.AppointmentHosts, "id", "name");
            }
            else
            {
                ViewBag.hostList = new SelectList(db.AppointmentHosts.Where(h => h.SystemUsers.Any(u => u.UserName == User.Identity.Name)), "id", "name");
            }
            ViewBag.venueList    = new SelectList(db.AppointmentVenues, "id", "name");
            ViewBag.consultation = consultation;
            return(View(ViewModel));
        }
        public ActionResult CreateMultiple(AppointmentCreateMultipleViewModel ViewModel, bool consultation = false)
        {
            Appointment appointment = ViewModel.appointment;

            if (consultation)
            {
                int programid = ViewModel.concerns.First();
                var concern   = db.AppointmentConcerns.Where(c => c.program_id == programid).SingleOrDefault();
                if (concern == null)
                {
                    var program = programdb.Programs.Find(programid);
                    if (program != null)
                    {
                        concern = new AppointmentConcern {
                            name = "Consultation", program_id = program.id
                        };
                        db.AppointmentConcerns.Add(concern);
                    }
                }
                appointment.AppointmentConcerns.Add(concern);
            }
            else
            {
                if (ViewModel.concerns != null)
                {
                    foreach (var concernid in ViewModel.concerns)
                    {
                        var concern = db.AppointmentConcerns.Find(concernid);
                        if (concern != null)
                        {
                            appointment.AppointmentConcerns.Add(concern);
                        }
                    }
                }
            }

            int openedStatusId = db.AppointmentStatus.Where(x => x.name == "Opened").FirstOrDefault().id;

            appointment.status_id = openedStatusId;
            List <bool>     availableDaysOfWeek = PrepareAvailableDaysOfWeek(ViewModel.config);
            List <Timeslot> timeslots           = new List <Timeslot>();
            DateTime        datecursor          = ViewModel.config.start_date.Date;

            //initialize skipped_dates to avoid null reference
            var skipped_dates = new List <DateTime>();

            if (ViewModel.skipped_dates != null)
            {
                skipped_dates = ViewModel.skipped_dates.ToList();
            }

            try
            {
                while (datecursor <= ViewModel.config.end_date.Date)
                {
                    if (availableDaysOfWeek[Convert.ToInt16(datecursor.DayOfWeek)] && !skipped_dates.Any(d => d.Date == datecursor.Date))
                    {
                        foreach (var session in ViewModel.sessions.Where(s => !s.excluded).ToList())
                        {
                            TimeSpan starttime = session.start_time.TimeOfDay;
                            TimeSpan duration  = new TimeSpan(0, ViewModel.duration, 0);
                            TimeSpan endtime   = starttime.Add(duration);

                            while (endtime <= session.end_time.TimeOfDay)
                            {
                                bool     overlapped   = false;
                                TimeSpan newstarttime = new TimeSpan();

                                foreach (var ex_session in ViewModel.sessions.Where(x => x.excluded))
                                {
                                    TimeSpan ex_starttime = ex_session.start_time.TimeOfDay;
                                    TimeSpan ex_endtime   = ex_session.end_time.TimeOfDay;
                                    if ((starttime >= ex_starttime && starttime < ex_endtime) ||
                                        (endtime > ex_starttime && endtime <= ex_endtime) ||
                                        (starttime <= ex_starttime && endtime >= ex_endtime))
                                    {
                                        overlapped   = true;
                                        newstarttime = ex_endtime > newstarttime ? ex_endtime : newstarttime;
                                        goto Action;
                                    }
                                }

                                foreach (var ex_session in db.Appointments.Where(a => a.venue_id == appointment.venue_id))
                                {
                                    DateTime ex_starttime = ex_session.start_time;
                                    DateTime ex_endtime   = ex_session.end_time;
                                    if ((datecursor.Add(starttime) >= ex_starttime && datecursor.Add(starttime) < ex_endtime) ||
                                        (datecursor.Add(endtime) > ex_starttime && datecursor.Add(endtime) <= ex_endtime) ||
                                        (datecursor.Add(starttime) <= ex_starttime && datecursor.Add(endtime) >= ex_endtime))
                                    {
                                        overlapped   = true;
                                        newstarttime = ex_endtime.TimeOfDay > newstarttime ? ex_endtime.TimeOfDay : newstarttime;
                                        goto Action;
                                    }
                                }

Action:
                                if (!overlapped && endtime <= session.end_time.TimeOfDay)
                                {
                                    appointment.start_time = datecursor.Add(starttime);
                                    appointment.end_time   = datecursor.Add(endtime);
                                    db.Appointments.Add(appointment);
                                    db.SaveChanges();
                                    starttime = endtime;
                                }
                                else
                                {
                                    starttime = newstarttime;
                                }
                                endtime = starttime.Add(duration);
                            }
                        }
                    }
                    datecursor = datecursor.AddDays(1);
                }
                return(RedirectToAction("Index"));
            }
            catch (Exception e)
            {
                var status = db.AppointmentStatus.Where(s => s.name == "Opened").SingleOrDefault();
                ViewBag.statusList  = new SelectList(db.AppointmentStatus, "id", "name", status.id);
                ViewBag.concernList = new MultiSelectList(db.AppointmentConcerns.Where(c => c.program_id == null && !c.custom), "id", "name");
                ViewBag.programList = new SelectList(programdb.Programs.Where(p => p.require_appointment), "name", "name");
                if (User.IsInRole("Admin") || User.IsInRole("Advising") || User.IsInRole("StudentDevelopment"))
                {
                    ViewBag.hostList = new SelectList(db.AppointmentHosts, "id", "name");
                }
                else
                {
                    ViewBag.hostList = new SelectList(db.AppointmentHosts.Where(h => h.SystemUsers.Any(u => u.UserName == User.Identity.Name)), "id", "name");
                }
                ViewBag.venueList       = new SelectList(db.AppointmentVenues, "id", "name");
                ViewBag.consultation    = consultation;
                Session["FlashMessage"] = "Failed to create appointment timeslots." + e.Message;
                return(View(ViewModel));
            }
        }