/*
         * returns users with current UserState(user) for mainGroup(group)
         * if checkName then checks if groupName == null (userHasn't any group) || comparesName - user is in current Group 
         */
        public async Task RefreshGroupOfUsersTypeAsync(IEnumerable<String> userNames, Group group, ApplicationDbContext appContext, CourseUsers userType, CourseUsers defaultType)
        {
            if (userNames == null)
            {
                Group[] groups = await appContext.Groups
                .Where(g => String.Compare(g.Name, group.Name, false) == 0 && g.UserState_ID == (Int32)userType).ToArrayAsync();
                foreach (var gr in groups)
                {
                    gr.UserState_ID = (Int32)defaultType;
                    gr.Name = null;
                    appContext.Entry(gr).State = EntityState.Modified;
                }
            }
            else
            {
                /*updating role for users*/
                Int32 currentRole = (Int32)userType;
                Group[] groups = await appContext.Users
                    .Where(u => userNames.Contains(u.UserName))
                    .Select(u => u.Groups.FirstOrDefault(g => g.Course_ID == group.Course_ID))
                    .ToArrayAsync();
                foreach (var i in groups)
                {
                    i.Name = group.Name;
                    i.UserState_ID = (Int32)userType;
                    appContext.Entry(i).State = EntityState.Modified;
                }

                ApplicationUser[] users = await appContext.Users
                    .Where(u => !userNames.Contains(u.UserName)).ToArrayAsync();
                Group selected = null;
                if (users != null)
                {
                    foreach (var user in users)
                    {
                        if (user.Groups.Any(g => String.Compare(g.Name, group.Name, false) == 0 && g.UserState_ID == currentRole))
                        {
                            selected = user.Groups.First(g => String.Compare(g.Name, group.Name, false) == 0 && g.UserState_ID == currentRole);
                            selected.Name = null;
                            selected.UserState_ID = (Int32)defaultType;
                            appContext.Entry(selected).State = EntityState.Modified;
                        }
                    }
                }
            }
        }
 public async Task<ActionResult> Join(String userName, Int32? id)
 {
     try
     {
         if (id != null)
         {
             Course course = await appContext.Courses.FindAsync(id);
             await appContext.Users.LoadAsync();
             ApplicationUser user = await appContext.Users.Where(u => String.Compare(u.UserName, userName, false) == 0).FirstAsync();
             if (user != null)
             {
                 if (!await appContext.Groups.AnyAsync(g => g.Course_ID == id && String.Compare(g.User.Id, user.Id, false) == 0))
                 {
                     Group group = new Group
                     {
                         Course_ID = course.ID,
                         Course = course,
                         UserState_ID = (Int32)CourseUsers.Learner,
                         User = user,
                         Duration = DateTime.Now,
                         Start = DateTime.Now,
                         Finish = DateTime.Now,
                         TotalScore = 0
                     };
                     appContext.Groups.Add(group);
                     await appContext.SaveChangesAsync();
                     return RedirectToAction("Details", new { id = course.ID, join = "Вашу заявку прийнято." });
                 }
                 else if (user.Groups.Any(g => g.Course_ID == id && g.Name != null))
                     return RedirectToAction("Index", "Topics", new { id = course.ID });
             }
             return RedirectToAction("Details", new { id = course.ID, join = "Ви вже подавали заявку." });
         }
         return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Can't find this course , please, try again later!");
     }
     catch (InvalidOperationException)
     {
         //first error
         return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Can't find user, please try to log in");
     }
 }
 public async Task<IList<Group>> UpdateUserStatsInGroupAsync(IEnumerable<String> users, Group mainGroup, ApplicationDbContext appContext, ApplicationUserManager userManager, params String[] checkableRoles)
 {
     if (users != null && mainGroup != null && appContext != null)
     {
         Course groupCourse = await appContext.Courses.FindAsync(mainGroup.Course_ID);
         if (groupCourse != null)
         {
             IList<String> userRoles = null;
             List<Group> groups = new List<Group>();
             CourseUsers user;
             for (Int32 i = 0; i < users.Count(); i++)
             {
                 userRoles = await userManager.GetRolesAsync(await GetUsersIdFromName(users.ElementAt(i), appContext));
                 user = CheckUserForRoles(checkableRoles, userRoles, CourseUsers.Student);
                 IList<Group> gr = await ChangeCourseUserGroupAsync(new String[] { users.ElementAt(i) }, appContext, groupCourse, user, false);
                 if (gr.Count > 0)
                 {
                     CopyMainDataOfGroupTo(mainGroup, gr.First());
                     groups.Add(gr.First());
                 }
             }
             return groups;
         }
     }
     return new List<Group>();
 }
 /*
  * Updates all users group stats to new, for example learner -> teacher or learner -> student
  * checkableRoles - list of roles to check in userManager, for example:
  * learner can't be a teacher or if user has teachers role he will be automatically add to teachers of this group
  * this method also updates all group info: name, dates etc.... for each user with role of student or teacher
  */
 public async Task RefreshAllGroupsDataAsync(String oldName, Group group, ApplicationDbContext appContext)
 {
     if (oldName != null && group != null && appContext != null)
     {
         Group[] groups = await appContext.Groups.Where(g => String.Compare(g.Name, oldName, false) == 0).ToArrayAsync();
         foreach (var gr in groups)
         {
             CopyMainDataOfGroupTo(group, gr);
             appContext.Entry(gr).State = EntityState.Modified;
         }
     }
 }
 public Boolean CheckUserForRoleInMainGroup(ApplicationUser user, Group group, params String[] roles)
 {
     CourseUsers uGroupRole;
     for (Int32 i = 0; i < roles.Length; i++)
     {
         if (Enum.TryParse(roles[i], out uGroupRole))
         {
             if (user.Groups.Any(g => g.Course_ID == group.Course_ID && g.UserState_ID == (Int32)uGroupRole))
                 return true;
         }
     }
     return false;
 }
 /*
  * Copies data from one group to another
  * It will be better to override method CopyTo or others in Group entity
  */
 private void CopyMainDataOfGroupTo(Group from, Group to)
 {
     if (from != null && to != null)
     {
         to.Finish = from.Finish;
         to.Start = from.Start;
         to.Duration = from.Duration;
         to.Name = from.Name;
     }
 }
 /*
  * Search users to change their roles
  * for example if someone deleted user from group
  * user status changes to defaultUser status
  * USE DBSAVECHANGES AFTER THIS METHOD
  */
 public async Task<IList<Group>> ClearUsersWithOldRoles(IEnumerable<String> users, Group group, ApplicationDbContext appContext, CourseUsers defaultUser)
 {
     IEnumerable<ApplicationUser> foundUsers = await appContext.Users.Where(u => !users.Contains(u.UserName)).ToArrayAsync();
     List<Group> editableGroups = new List<Group>();
     Course course = await appContext.Courses.FindAsync(group.Course_ID);
     if (foundUsers != null && course != null)
     {
         ApplicationUser foundUser = null;
         for (Int32 i = 0; i < foundUsers.Count(); i++)
         {
             foundUser = foundUsers.ElementAt(i);
             editableGroups.AddRange(await appContext.Groups.Where(g => g.Course_ID == course.ID && g.User.Id == foundUser.Id).ToArrayAsync());
         }
         foreach (var gr in editableGroups)
         {
             gr.UserState_ID = (Int32)defaultUser;
             gr.Name = null;
         }
     }
     return editableGroups;
 }
 public async Task<IList<ApplicationUser>> GetUsersFromMainGroupAsync(ApplicationDbContext appContext, Group group, CourseUsers user, Boolean checkName = false)
 {
     List<ApplicationUser> users = new List<ApplicationUser>();
     try
     {
         if (group != null)
         {
             Int32 userState = (Int32)user;
             /*adds users with groups where names == null which means that user is not in any main group*/
             users.AddRange(await appContext.Users.Where
                 (
                     u => u.Groups
                     .Any(gr => gr.Course_ID == group.Course_ID && gr.UserState_ID == userState && (checkName ? String.Compare(group.Name, gr.Name, false) == 0 : gr.Name == null))
                 )
                 .ToListAsync());
         }
         return users;
     }
     catch (NullReferenceException)
     {
         return users;
     }
 }