public async Task<ActionResult> Create()
 {
     var viewModel = new ProjectViewModel
     {
         Project = new Project(),
         PossibleProjectMembers = (await personRepository.Get()).ToList(),
         CurrentUserId = Request.GetOwinContext().Authentication.User.Identity.GetUserId()
     };
                 
     return View(viewModel);
 }
        public async Task<ActionResult> Create(ProjectViewModel projectViewModel)
        {            
            //translate viewmodel to model
            var project = projectViewModel.Project;

            var teamMembers = await personRepository.Find(p => projectViewModel.MemberIds.Any(id => id == p.Id));

            project.TeamMembers = teamMembers;

            //validate model
            ModelState.Clear();
            TryValidateModel(project);

            if (!ModelState.IsValid)
            {
                return View(projectViewModel);
            }

            repository.Add(project);
            await uow.SaveChangesAsync();

            return RedirectToAction("Index");
        }
 public async Task<ActionResult> Edit(string id)
 {
     var project = await repository.Get(id);
     var editProjectViewModel = new ProjectViewModel
     {
         Project = project,
         CurrentUserId = CurrentUserId,
         PossibleProjectMembers = (await personRepository.Get()).ToList()
     };
     return View(editProjectViewModel);
 }
 public async Task<ViewResult> Details(string id)
 {            
     var project = await repository.Get(id);
     var personIds = project.TeamMembers.Select(m => m.Id);
     var members = await personRepository.Find(p => personIds.Contains(p.Id));
     var projectViewModel = new ProjectViewModel
     {
         Project = project,
         PossibleProjectMembers = members.ToList()
     };
     return View(projectViewModel);
 }
        public async Task<ActionResult> Edit(Project project, IEnumerable<string> selectedTeamMemberIds)
        {
            var projectToUpdate = (await repository.Get(p => p.Id == project.Id)).First();

            if(selectedTeamMemberIds == null)
            {
                selectedTeamMemberIds = new string[0];
            }

            var teamMemberIds = selectedTeamMemberIds as string[] ?? selectedTeamMemberIds.ToArray();
            var selectedTeam = await personRepository.Find(p => teamMemberIds.Any(id => id == p.Id));

            projectToUpdate.Name = project.Name;
            projectToUpdate.Code = project.Code;
            
            var currentTeam = new HashSet<string>(projectToUpdate.TeamMembers.Select(p => p.Id));

            //if there are new members selected we must add them to the current team
            foreach (var selectedTeamMember in selectedTeam.Where(selectedTeamMember => currentTeam.All(personId => personId != selectedTeamMember.Id)))
            {
                projectToUpdate.TeamMembers.Add(selectedTeamMember);
            }
            //remove any current team member who is not apart of the selection
            foreach (var personId in currentTeam.Where(personId => selectedTeam.All(p => p.Id != personId)))
            {
                projectToUpdate.TeamMembers.Remove(projectToUpdate.TeamMembers.First(p => p.Id == personId));
            }

            project.TeamMembers = projectToUpdate.TeamMembers;

            ModelState.Clear();
            
            TryValidateModel(projectToUpdate);

            var vm = new ProjectViewModel
            {
                Project = project,                
                CurrentUserId = CurrentUserId,
                PossibleProjectMembers = (await personRepository.Get()).ToList()
            };

            if (!ModelState.IsValid)
            {                
                return View(vm);
            }
            try
            {
                repository.Update(projectToUpdate);
                await uow.SaveChangesAsync();    
            }
            catch (DbEntityValidationException dbEx)
            {
                foreach (var entityValidationError in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in entityValidationError.ValidationErrors)
                    {
                        ModelState.AddModelError(validationError.PropertyName, validationError.ErrorMessage);                        
                    }
                }                
                return View(vm);
            }
            return RedirectToAction("Index");
        }