public ActionResult Edit(ApplicationViewModel ViewModel)
        {
            Application application = db.Applications.Find(ViewModel.application.id);
            Program program = application.Program;
            StudentProfile student = application.StudentProfile;

            if (DateTime.Now > program.application_end_time && !User.IsInRole("Advising"))
            {
                Session["FlashMessage"] = ("Application deadline passed. ");
                return RedirectToAction("Record");
            }

            db.Entry(application).CurrentValues.SetValues(ViewModel.application);

            var SavedStatus = db.ApplicationStatus.Where(s => s.name == "Saved").SingleOrDefault();
            var SubmittedStatus = db.ApplicationStatus.Where(s => s.name == "Submitted").SingleOrDefault();
            if (ModelState.IsValid || application.status_id == SavedStatus.id)
            {
                application.modified = DateTime.Now;
                application.modified_by = User.Identity.Name;
                if (application.status_id == SubmittedStatus.id)
                {
                    application.submitted = DateTime.Now;
                }

                foreach (var item in program.ProgramOptionValues)
                {
                    ApplicationOptionValue option = ViewModel.options.Where(o => o.option_value_id == item.id).SingleOrDefault();
                    if (option.id == 0)
                    {
                        db.ApplicationOptionValues.Add(option);
                    }
                    else
                    {
                        db.Entry(option).State = EntityState.Modified;
                    }
                }

                foreach (var item in program.ProgramApplicationAttachments)
                {
                    ApplicationAttachment attachment = ViewModel.attachments.Where(a => a.program_application_attachment_id == item.id).SingleOrDefault();
                    if (attachment.id == 0) //Application Attachment not exist in DB
                    {
                        if (!String.IsNullOrEmpty(attachment.filename))
                        {
                            var sourcePath = Server.MapPath("~/App_Data/" + attachment.filepath);
                            var sourceFilepath = Path.Combine(sourcePath, attachment.filename);
                            var destPath = Server.MapPath("~/App_Data/" + "Attachments/Application/" + application.id);
                            var destFilepath = Path.Combine(destPath, attachment.filename);
                            try
                            {
                                Directory.CreateDirectory(destPath);
                            }
                            catch (Exception e)
                            {
                                Session["FlashMessage"] = "Failed to create directory." + e.Message;
                            }
                            try
                            {
                                System.IO.File.Move(sourceFilepath, destFilepath);
                                attachment.filepath = "Attachments/Application/" + application.id;
                            }
                            catch (Exception e)
                            {
                                Session["FlashMessage"] = "Failed to move file." + e.Message;
                            }

                        }
                        db.ApplicationAttachments.Add(attachment);
                    }
                    else //Application Attachment exists in DB
                    {
                        ApplicationAttachment att = db.ApplicationAttachments.Find(attachment.id);
                        if (att.filename != attachment.filename || att.filepath != attachment.filepath)
                        {
                            if (!String.IsNullOrEmpty(att.filename)) //delete only if current file exist
                            {
                                var path = Server.MapPath("~/App_Data/" + att.filepath);
                                var filepath = Path.Combine(path, att.filename);
                                if (System.IO.File.Exists(filepath))
                                {
                                    try
                                    {
                                        System.IO.File.Delete(filepath);
                                    }
                                    catch (Exception e)
                                    {
                                        Session["FlashMessage"] = "Failed to delete attachment." + e.Message;
                                    }
                                }
                            }

                            if (!String.IsNullOrEmpty(attachment.filename)) //move uploaded file
                            {
                                var sourcePath = Server.MapPath("~/App_Data/" + attachment.filepath);
                                var sourceFilepath = Path.Combine(sourcePath, attachment.filename);
                                var destPath = Server.MapPath("~/App_Data/" + "Attachments/Application/" + application.id);
                                var destFilepath = Path.Combine(destPath, attachment.filename);
                                try
                                {
                                    Directory.CreateDirectory(destPath);
                                }
                                catch (Exception e)
                                {
                                    Session["FlashMessage"] = "Failed to create directory." + e.Message;
                                }
                                try
                                {
                                    System.IO.File.Move(sourceFilepath, destFilepath);
                                    attachment.filepath = "Attachments/Application/" + application.id;
                                }
                                catch (Exception e)
                                {
                                    Session["FlashMessage"] = "Failed to move file." + e.Message;
                                }
                            }
                        }
                        db.Entry(att).CurrentValues.SetValues(attachment);
                    }
                }

                //clear temp files uploaded but not used
                if (Directory.Exists(Server.MapPath("~/App_Data/Temp/Application/" + application.id)))
                {
                    var files = Directory.GetFiles(Server.MapPath("~/App_Data/Temp/Application/" + application.id));
                    foreach (var file in files)
                    {
                        System.IO.File.Delete(file);
                    }
                }

                if (program.require_exchange_option)
                {
                    for (int i = 0; i < ViewModel.no_of_exchange_options; i++)
                    {
                        var exchangeoption = ViewModel.exchange_options.SingleOrDefault(e => e.priority == i);
                        if (exchangeoption.id == 0)
                        {
                            db.ApplicationExchangeOptions.Add(exchangeoption);
                        }
                        else
                        {
                            db.Entry(exchangeoption).State = EntityState.Modified;
                        }
                    }
                }

                if (program.require_appointment)
                {
                    if (SavedStatus != null && application.status_id != SavedStatus.id)
                    {
                        var appointment = db.Appointments.Find(ViewModel.application.appointment_id);
                        var advising_student = db.StudentProfiles.Find(application.student_id);
                        if (advising_student != null)
                        {
                            if (appointment.student_id == null)
                            {
                                appointment.student_id = advising_student.id;
                            }
                            else
                            {
                                Session["FlashMessage"] = "The consultation session that you have selected is no longer available. Please select another session. <br/><br/>***Your application is not submitted";
                                application.status_id = SavedStatus.id;
                            }
                        }
                        db.SaveChanges();
                    }
                }

                try
                {
                    db.SaveChanges();
                    if (application.status_id == SavedStatus.id)
                    {
                        if (Session["FlashMessage"] == null)
                        {
                            Session["FlashMessage"] = "Application saved successfully.<br/><br/>Should you encounter any technical difficulty, please contact us at <a href='*****@*****.**'>[email protected]</a>.";
                        }
                    }
                    if (application.status_id == SubmittedStatus.id)
                    {
                        if (Session["FlashMessage"] == null)
                        {
                            Session["FlashMessage"] = "Application submitted successfully.<br/><br/>Should you encounter any technical difficulty, please contact us at <a href='*****@*****.**'>[email protected]</a>.";
                            SendNotification(CreateNotification("ApplicationSubmitted", application));
                        }
                    }
                    if (User.IsInRole("Advising"))
                    {
                        return RedirectToAction("Index");
                    }
                    else
                    {
                        return RedirectToAction("Record");
                    }
                }
                catch (Exception e)
                {
                    Session["FlashMessage"] = "Failed to save modified application to database." + e.Message;
                    if (User.IsInRole("Advising"))
                    {
                        return RedirectToAction("Index");
                    }
                    else
                    {
                        return RedirectToAction("Record");
                    }
                }

            }

            Session["FlashMessage"] = "Failed to edit application.";
            if (User.IsInRole("Advising"))
            {
                return RedirectToAction("Index");
            }
            else
            {
                return RedirectToAction("Record");
            }
        }
        public ActionResult Review(int id = 0)
        {
            Application application = db.Applications.Find(id);
            if (application == null)
            {
                return HttpNotFound("Application not found");
            }

            Program program = db.Programs.Find(application.program_id);
            if (program == null)
            {
                return HttpNotFound("Program not found");
            }

            ApplicationViewModel ViewModel = new ApplicationViewModel();
            ViewModel.application = application;
            ViewModel.program = program;
            ViewModel.student = application.StudentProfile;

            ViewModel.options = new List<ApplicationOptionValue>();
            application.ApplicationOptionValues.ToList().ForEach(o => ViewModel.options.Add(o));

            ViewModel.attachments = new List<ApplicationAttachment>();
            application.ApplicationAttachments.ToList().ForEach(a => ViewModel.attachments.Add(a));

            ViewModel.exchange_options = new List<ApplicationExchangeOption>();
            if (program.require_exchange_option)
            {
                ViewBag.ExchangeOptionList = new SelectList(db.ExchangeOptions.Where(e => e.status), "id", "name");
                application.ApplicationExchangeOptions.ToList().ForEach(e => ViewModel.exchange_options.Add(e));
            }

            Interview interview = application.Interviews.FirstOrDefault();
            if (interview != null)
            {
                ViewModel.interview_id = interview.id;
            }
            else
            {
                ViewModel.interview_id = -1;
            }

            if (program.require_appointment)
            {
                var app = db.Appointments.Where(a => a.student_id == application.student_id && a.AppointmentConcerns.Any(c => c.program_id == program.id)).FirstOrDefault();
                if (app != null)
                {
                    ViewBag.appointment_start_time = app.start_time;
                }
            }
            ViewBag.statusList = new SelectList(db.ApplicationStatus, "id", "name");
            ViewBag.interviewList = new SelectList(db.Interviews.Where(i => i.program_id == application.program_id && (i.Applications.Count() < i.no_of_interviewee || i.id == ViewModel.interview_id)), "id", "start_time");

            return PartialView(ViewModel);
        }
        public ActionResult Details(int id = 0)
        {
            Application application = db.Applications.Find(id);
            if (application == null)
            {
                return HttpNotFound("Application not found.");
            }

            Program program = db.Programs.Find(application.program_id);
            if (program == null)
            {
                return HttpNotFound("Program not found.");
            }

            ApplicationViewModel ViewModel = new ApplicationViewModel();
            ViewModel.application = application;
            ViewModel.program = program;
            ViewModel.student = application.StudentProfile;

            ViewModel.options = new List<ApplicationOptionValue>();
            application.ApplicationOptionValues.ToList().ForEach(o => ViewModel.options.Add(o));

            ViewModel.attachments = new List<ApplicationAttachment>();
            application.ApplicationAttachments.ToList().ForEach(a => ViewModel.attachments.Add(a));

            ViewModel.exchange_options = new List<ApplicationExchangeOption>();
            if (program.require_exchange_option)
            {
                ViewBag.ExchangeOptionList = new SelectList(db.ExchangeOptions.Where(e => e.status), "id", "name");
                application.ApplicationExchangeOptions.OrderBy(e => e.priority).ToList().ForEach(e => ViewModel.exchange_options.Add(e));
            }

            if (program.require_appointment)
            {
                var app = db.Appointments.Where(a => a.student_id == application.student_id && a.AppointmentConcerns.Any(c => c.program_id == program.id)).FirstOrDefault();
                if (app != null)
                {
                    ViewBag.appointment_start_time = app.start_time;
                }
            }

            return PartialView(ViewModel);
        }
        public ActionResult Edit(int id = 0)
        {
            bool authorizedToEdit = User.IsInRole("Admin") || User.IsInRole("Advising") || User.IsInRole("StudentDevelopment");
            Application application = db.Applications.Where(a => (a.created_by == User.Identity.Name || authorizedToEdit) && (a.id == id)).FirstOrDefault();
            if (application == null)
            {
                return HttpNotFound("Application not found or not authorized to edit.");
            }
            int savedStatusId = 0;
            try
            {
                savedStatusId = db.ApplicationStatus.FirstOrDefault(s => s.name == "Saved").id;
            }
            catch (Exception e)
            {
                Session["FlashMessage"] = "Saved Status not found." + e.Message;
            }
            if (application.status_id != savedStatusId && !authorizedToEdit)
            {
                return HttpNotFound("Application exists but not allow to be edited.");
            }

            Program program = db.Programs.Find(application.program_id);
            if (program == null)
            {
                return HttpNotFound("Program not found.");
            }

            ApplicationViewModel ViewModel = new ApplicationViewModel();
            ViewModel.application = application;
            ViewModel.program = program;
            ViewModel.student = application.StudentProfile;

            ViewModel.options = new List<ApplicationOptionValue>();
            foreach (var item in program.ProgramOptionValues)
            {
                var option = application.ApplicationOptionValues.Where(o => o.option_value_id == item.id).SingleOrDefault();
                if (option == null)
                {
                    option = new ApplicationOptionValue
                    {
                        option_value_id = item.id,
                        ProgramOptionValue = item,
                        application_id = application.id
                    };
                }
                ViewModel.options.Add(option);
            }

            ViewModel.attachments = new List<ApplicationAttachment>();
            foreach (var item in program.ProgramApplicationAttachments)
            {
                var attachment = application.ApplicationAttachments.Where(a => a.program_application_attachment_id == item.id).SingleOrDefault();
                if (attachment == null)
                {
                    attachment = new ApplicationAttachment
                    {
                        program_application_attachment_id = item.id,
                        ProgramApplicationAttachment = item,
                        application_id = application.id
                    };
                }
                ViewModel.attachments.Add(attachment);
            }

            ViewModel.exchange_options = new List<ApplicationExchangeOption>();
            if (program.require_exchange_option)
            {
                ViewBag.ExchangeOptionList = new SelectList(db.ExchangeOptions.Where(e => e.status).OrderBy(e => e.name), "id", "name");
                for (int i = 0; i < ViewModel.no_of_exchange_options; i++)
                {
                    var exchangeoption = application.ApplicationExchangeOptions.Where(e => e.priority == i).SingleOrDefault();
                    if (exchangeoption == null)
                    {
                        exchangeoption = new ApplicationExchangeOption
                        {
                            application_id = application.id,
                            priority = i
                        };
                    }
                    ViewModel.exchange_options.Add(exchangeoption);
                }
            }

            if (program.require_appointment)
            {
                //application appointment_id exist, but already booked by others
                if (db.Appointments.Any(o => o.student_id != null && o.id == ViewModel.application.appointment_id))
                {
                    ViewBag.booked = "Y";
                    ViewModel.application.appointment_id = null;
                }
                ViewBag.AppointmentList = db.Appointments.Where(a => a.student_id == null && a.AppointmentConcerns.Any(c => c.program_id == program.id));
            }

            return PartialView(ViewModel);
        }
 public ActionResult DeleteConfirmed(ApplicationViewModel ViewModel)
 {
     Application application = db.Applications.Find(ViewModel.application.id);
     application.status_id = ViewModel.application.status_id;
     try
     {
         db.Entry(application).State = EntityState.Modified;
         db.SaveChanges();
     }
     catch (Exception e)
     {
         Session["FlashMessage"] = "Failed to update application delete status." + e.Message;
     }
     return RedirectToAction("Record");
 }
        public ActionResult Delete(int id = 0)
        {
            Application application = db.Applications.Find(id);
            if (application == null)
            {
                return HttpNotFound("Application not found");
            }

            Program program = db.Programs.Find(application.program_id);
            if (program == null)
            {
                return HttpNotFound("Program not found");
            }

            ApplicationViewModel ViewModel = new ApplicationViewModel();
            ViewModel.application = application;
            ViewModel.program = program;
            ViewModel.student = application.StudentProfile;

            ViewModel.options = new List<ApplicationOptionValue>();
            application.ApplicationOptionValues.ToList().ForEach(o => ViewModel.options.Add(o));

            ViewModel.attachments = new List<ApplicationAttachment>();
            application.ApplicationAttachments.ToList().ForEach(a => ViewModel.attachments.Add(a));

            ViewModel.exchange_options = new List<ApplicationExchangeOption>();
            if (program.require_exchange_option)
            {
                ViewBag.ExchangeOptionList = new SelectList(db.ExchangeOptions.Where(e => e.status), "id", "name");
                application.ApplicationExchangeOptions.ToList().ForEach(e => ViewModel.exchange_options.Add(e));
            }

            return PartialView(ViewModel);
        }
        public ActionResult Create(ApplicationViewModel ViewModel)
        {
            Application application = ViewModel.application;
            Program program = db.Programs.Find(application.program_id);
            StudentProfile student = db.StudentProfiles.Find(application.student_id);
            var SavedStatus = db.ApplicationStatus.Where(s => s.name == "Saved").SingleOrDefault();
            var SubmittedStatus = db.ApplicationStatus.Where(s => s.name == "Submitted").SingleOrDefault();
            if (SavedStatus == null || SubmittedStatus == null)
            {
                Session["FlashMessage"] = "Saved or Submitted Status not found.";
                return RedirectToAction("Record");
            }

            if (!IsEligible(program, student))
            {
                Session["FlashMessage"] = "Not eligible to apply.";
                return RedirectToAction("Record");
            }

            if (DateTime.Now > program.application_end_time)
            {
                Session["FlashMessage"] = "Application deadline has passed. ";
                return RedirectToAction("Record");
            }

            //201403241714 fai: prevent duplicated application
            if (student.Applications.Any(a => a.program_id == program.id))
            {
                Session["FlashMessage"] = "Application of [" + program.name + "] already exists. You may Edit/View your application from the list.";
                return RedirectToAction("Record");
            }

            if (ModelState.IsValid || application.status_id == SavedStatus.id)
            {
                application.created = DateTime.Now;
                application.created_by = User.Identity.Name;
                application.modified = DateTime.Now;
                application.modified_by = User.Identity.Name;
                if (application.status_id == SubmittedStatus.id)
                {
                    application.submitted = DateTime.Now;
                }
                db.Applications.Add(application);
                try
                {
                    db.SaveChanges();
                }
                catch (Exception e)
                {
                    Session["FlashMessage"] = "Failed to create application. " + e.Message;
                }

                foreach (var item in program.ProgramOptionValues)
                {
                    ApplicationOptionValue option = ViewModel.options.Where(o => o.option_value_id == item.id).SingleOrDefault();
                    option.application_id = application.id;
                    db.ApplicationOptionValues.Add(option);
                }

                foreach (var item in program.ProgramApplicationAttachments)
                {
                    ApplicationAttachment attachment = ViewModel.attachments.Where(a => a.program_application_attachment_id == item.id).SingleOrDefault();
                    attachment.application_id = application.id;

                    if (!String.IsNullOrEmpty(attachment.filename))
                    {
                        var sourcePath = Server.MapPath("~/App_Data/" + attachment.filepath);
                        var sourceFilepath = Path.Combine(sourcePath, attachment.filename);
                        var destPath = Server.MapPath("~/App_Data/" + "Attachments/Application/" + application.id);
                        var destFilepath = Path.Combine(destPath, attachment.filename);
                        try
                        {
                            Directory.CreateDirectory(destPath);
                        }
                        catch (Exception e)
                        {
                            Session["FlashMessage"] = "Failed to create directory." + e.Message;
                        }
                        try
                        {
                            System.IO.File.Move(sourceFilepath, destFilepath);
                            attachment.filepath = "Attachments/Application/" + application.id;
                        }
                        catch (Exception e)
                        {
                            Session["FlashMessage"] = "Failed to move file." + e.Message;
                        }

                    }

                    db.ApplicationAttachments.Add(attachment);
                }

                //clear temp files uploaded but not used
                if (Directory.Exists(Server.MapPath("~/App_Data/Temp/Application/" + User.Identity.Name)))
                {
                    var files = Directory.GetFiles(Server.MapPath("~/App_Data/Temp/Application/" + User.Identity.Name));
                    foreach (var file in files)
                    {
                        System.IO.File.Delete(file);
                    }
                }

                if (program.require_exchange_option)
                {
                    for (int i = 0; i < ViewModel.no_of_exchange_options; i++)
                    {
                        ApplicationExchangeOption exchange_option = ViewModel.exchange_options.Where(e => e.priority == i).SingleOrDefault();
                        exchange_option.application_id = application.id;
                        db.ApplicationExchangeOptions.Add(exchange_option);
                    }
                }

                if (program.require_appointment)
                {
                    if (SavedStatus != null && application.status_id != SavedStatus.id)
                    {
                        var appointment = db.Appointments.Find(ViewModel.application.appointment_id);
                        var advising_student = db.StudentProfiles.Find(application.student_id);
                        if (advising_student != null)
                        {
                            if (appointment.student_id == null)
                            {
                                appointment.student_id = advising_student.id;
                            }
                            else
                            {
                                Session["FlashMessage"] = "The consultation session that you have selected is no longer available. Please select another session. <br/><br/>Your application is not submitted";
                                application.status_id = SavedStatus.id;
                            }
                        }
                        db.SaveChanges();
                    }
                }

                try
                {
                    db.SaveChanges();
                    if (application.status_id == SavedStatus.id)
                    {
                        if (Session["FlashMessage"] == null)
                        {
                            Session["FlashMessage"] = "Application saved successfully.";
                        }
                    }
                    if (application.status_id == SubmittedStatus.id)
                    {
                        if (Session["FlashMessage"] == null)
                        {
                            Session["FlashMessage"] = "Application submitted successfully.";

                            SendNotification(CreateNotification("ApplicationSubmitted", application));
                        }
                    }
                    return RedirectToAction("Record");
                }
                catch (Exception e)
                {
                    Session["FlashMessage"] = "Failed to save Attachment/Optional Field to database." + e.Message;
                    return RedirectToAction("Record");
                }
            }

            Session["FlashMessage"] = "Failed to create application.";
            return RedirectToAction("Record");
        }
        public ActionResult Create(int id = 0)
        {
            Program program = db.Programs.Find(id);
            if (program == null)
            {
                return HttpNotFound("Program not found.");
            }

            StudentProfile student = db.StudentProfiles.Find(User.Identity.Name);
            if (student == null)
            {
                return HttpNotFound("Student not found.");
            }

            if (!IsEligible(program, student))
            {
                return HttpNotFound("Not eligible to apply this program.");
            }

            if (program.application_end_time < DateTime.Now)
            {
                return HttpNotFound("Application deadline expired.");
            }

            Application application = db.Applications.Where(a => (a.student_id == student.id && a.program_id == program.id)).FirstOrDefault();
            if (application != null)
            {
                return RedirectToAction("Edit", "Application", new { id = application.id });
            }

            ApplicationViewModel ViewModel = new ApplicationViewModel();
            ViewModel.application = new Application();
            ViewModel.application.program_id = program.id;
            ViewModel.application.student_id = student.id;
            ViewModel.program = program;
            ViewModel.student = student;

            ViewModel.options = new List<ApplicationOptionValue>();
            foreach (var option in program.ProgramOptionValues)
            {
                ViewModel.options.Add(new ApplicationOptionValue {
                    option_value_id = option.id,
                    ProgramOptionValue = option
                });
            }

            ViewModel.attachments = new List<ApplicationAttachment>();
            foreach (var attachment in program.ProgramApplicationAttachments)
            {
                ViewModel.attachments.Add(new ApplicationAttachment
                {
                    program_application_attachment_id = attachment.id,
                    ProgramApplicationAttachment = attachment
                });
            }

            ViewModel.exchange_options = new List<ApplicationExchangeOption>();
            if (program.require_exchange_option)
            {
                ViewBag.ExchangeOptionList = new SelectList(db.ExchangeOptions.Where(e => e.status).OrderBy(e => e.name), "id", "name");
                for (int i = 0; i < ViewModel.no_of_exchange_options; i++)
                {
                    ViewModel.exchange_options.Add(new ApplicationExchangeOption{
                        priority = i
                    });
                }
            }

            if (program.require_appointment)
            {
                ViewBag.AppointmentList = db.Appointments.Where(a => a.student_id == null && a.AppointmentConcerns.Any(c => c.program_id == program.id));
            }

            return PartialView(ViewModel);
        }
 public ActionResult Review(ApplicationViewModel ViewModel)
 {
     Application application = db.Applications.Find(ViewModel.application.id);
     var SavedStatus = db.ApplicationStatus.Where(s => s.name == "Saved").SingleOrDefault();
     if (application != null)
     {
         application.modified = DateTime.Now;
         application.modified_by = User.Identity.Name;
         application.status_id = ViewModel.application.status_id;
         //status backward handling, remove appointment relationship, reset saved appointment_id selection
         if (application.status_id == SavedStatus.id)
         {
             var appointment = db.Appointments.Where(a => a.student_id == application.student_id && a.AppointmentConcerns.Any(c => c.program_id == application.program_id)).SingleOrDefault();
             if (appointment != null)
             {
                 appointment.student_id = null;
             }
             application.appointment_id = null;
             db.SaveChanges();
             Session["FlashMessage"] += "Related consultation session (if any) is released";
         }
         application.Interviews.Clear();
         application.Interviews.Add(db.Interviews.Find(ViewModel.interview_id));
         try
         {
             db.Entry(application).State = EntityState.Modified;
             Session["FlashMessage"] += "<br/>Application Status changed successfully.";
             db.SaveChanges();
         }
         catch (Exception e)
         {
             Session["FlashMessage"] = "Failed to update application to database." + e.Message;
             return View(application);
         }
         return RedirectToAction("Index");
     }
     return View(application);
 }