public async Task<ActionResult> Edit(string slug, Team model) { var team = await db.Teams.Include(i => i.Users).FirstOrDefaultAsync(q => q.Id == model.Id); if (team == null || !Helpers.DbHelper.CanEditTeam(team)) return HttpNotFound(); if (!team.Name.Trim().Equals(model.Name.Trim(), StringComparison.InvariantCultureIgnoreCase)) { var name = model.Name.ToFriendlyUrl().ToString(); var teamExists = await db.Teams.FirstOrDefaultAsync(q => q.Slug.Equals(name, StringComparison.InvariantCultureIgnoreCase)); if (teamExists != null) ModelState.AddModelError(String.Empty, "Team name is not available"); } if (ModelState.IsValid) { team.Name = model.Name.Trim(); team.Slug = model.Name.ToFriendlyUrl(); db.Entry(team).State = EntityState.Modified; await db.SaveChangesAsync(); return RedirectToAction("Index"); } return View(model); }
public static bool CanEditTeam(Team team) { if (team == null || !HttpContext.Current.Request.IsAuthenticated) return false; var userId = HttpContext.Current.User.Identity.GetUserId(); var user = db.Users.FirstOrDefault(q => q.Id == userId); if (team.Users.FirstOrDefault(q => q.Id == user.Id) == null) return false; return true; }
public async Task<ActionResult> Create(string slug, List<string> home, List<string> away, List<int?> homeScore, List<int?> awayScore) { var league = await db.Leagues .Include(i => i.Users) .Include(i => i.Teams.Select(u => u.Users)) .FirstOrDefaultAsync(q => q.Slug.Equals(slug, StringComparison.InvariantCultureIgnoreCase)); if (league == null) return HttpNotFound(); #region Find Users and Teams var userId = User.Identity.GetUserId(); if (home == null) home = new List<string>(); if (away == null) return View(); home.Add(userId); var homeUsers = db.Users.Include(i => i.Teams).Where(q => home.Contains(q.Id)); var awayUsers = db.Users.Include(i => i.Teams).Where(q => away.Contains(q.Id)); var allTeams = db.Teams.Include(i => i.Users); var homeTeam = allTeams.FirstOrDefault(p => !p.Users.Select(u => u.Id).Except(home).Union(home.Except(p.Users.Select(u => u.Id))).Any()); var awayTeam = allTeams.FirstOrDefault(p => !p.Users.Select(u => u.Id).Except(away).Union(away.Except(p.Users.Select(u => u.Id))).Any()); //var homeTeam = allTeams.Where(p => !p.Users.Select(c => c.Id).Except(home).Union(home.Except(p.Users.Select(c => c.Id))).Any()).FirstOrDefault(); //var awayTeam = allTeams.Where(p => !p.Users.Select(c => c.Id).Except(away).Union(away.Except(p.Users.Select(c => c.Id))).Any()).FirstOrDefault(); if (homeTeam == null) { homeTeam = new Team(); foreach (var item in db.Users.Where(q => home.Contains(q.Id))) homeTeam.Users.Add(item); homeTeam.Name = String.Join("+", homeTeam.Users.Select(q => q.UserName)); homeTeam.Slug = homeTeam.Name.ToFriendlyUrl(); db.Teams.Add(homeTeam); } if (awayTeam == null) { awayTeam = new Team(); foreach (var user in db.Users.Where(q => away.Contains(q.Id))) awayTeam.Users.Add(user); awayTeam.Name = String.Join("+", awayTeam.Users.Select(q => q.UserName)); awayTeam.Slug = awayTeam.Name.ToFriendlyUrl(); db.Teams.Add(awayTeam); } foreach (var item in awayTeam.Users.Where(item => !league.Users.Contains(item))) league.Users.Add(item); foreach (var item in homeTeam.Users.Where(item => !league.Users.Contains(item))) league.Users.Add(item); if (!league.Teams.Contains(awayTeam)) league.Teams.Add(awayTeam); if (!league.Teams.Contains(homeTeam)) league.Teams.Add(homeTeam); #endregion #region Sets var sets = new List<Set>(); for (int i = 0; i < homeScore.Count; i++) if (homeScore[i].HasValue && awayScore[i].HasValue) sets.Add(new Set() { HomeScore = homeScore[i].Value, AwayScore = awayScore[i].Value }); var homeWins = sets.Count(q => q.HomeScore > q.AwayScore); var awayWins = sets.Count(q => q.HomeScore < q.AwayScore); #endregion #region Ratings var ratingHome = new List<Tuple<string, int, int, int, int>>(); var ratingAway = new List<Tuple<string, int, int, int, int>>(); foreach (var item in homeTeam.Users) { var latestRating = db.Ratings.OrderByDescending(q => q.Created).FirstOrDefault(q => q.League.Id == league.Id && q.User.Id == item.Id); var rating = latestRating == null ? 1000 : latestRating.Rate; var rank = latestRating == null ? league.Users.Count : latestRating.Rank; ratingHome.Add(new Tuple<string, int, int, int, int>(item.Id, rating, rank, 0, 0)); } foreach (var item in awayTeam.Users) { var latestRating = db.Ratings.OrderByDescending(q => q.Created).FirstOrDefault(q => q.League.Id == league.Id && q.User.Id == item.Id); var rating = latestRating == null ? 1000 : latestRating.Rate; var rank = latestRating == null ? league.Users.Count : latestRating.Rank; ratingAway.Add(new Tuple<string, int, int, int, int>(item.Id, rating, rank, 0, 0)); } var avgHome = ratingHome.Sum(q => q.Item2) / homeTeam.Users.Count; var avgAway = ratingAway.Sum(q => q.Item2) / awayTeam.Users.Count; var homeWon = homeWins > awayWins; var awayWon = awayWins > homeWins; var draw = homeWins == awayWins; var elorating = EloRating.CalculateChange(avgHome, avgAway, homeWins, awayWins); var ratings = new List<Rating>(); foreach (var item in homeTeam.Users) { var latestRating = db.Ratings.OrderByDescending(q => q.Created).FirstOrDefault(q => q.League.Id == league.Id && q.User.Id == item.Id); var ratingChange = homeWon ? System.Math.Abs(elorating) : System.Math.Abs(elorating) * -1; ratings.Add(new Rating() { Draw = draw, Lost = awayWon, Won = homeWon, League = league, User = item, Team = homeTeam, Rank = 0, RankingChange = 0, RankedLast = false, Rate = (latestRating == null ? 1000 : latestRating.Rate) + ratingChange, RatingChange = ratingChange, Score = sets.Sum(q => q.HomeScore) - sets.Sum(q => q.AwayScore) }); } foreach (var item in awayTeam.Users) { var latestRating = db.Ratings.OrderByDescending(q => q.Created).FirstOrDefault(q => q.League.Id == league.Id && q.User.Id == item.Id); var ratingChange = awayWon ? System.Math.Abs(elorating) : System.Math.Abs(elorating) * -1; ratings.Add(new Rating() { Draw = draw, Lost = homeWon, Won = awayWon, League = league, User = item, Team = awayTeam, Rank = 0, RankingChange = 0, RankedLast = false, Rate = (latestRating == null ? 1000 : latestRating.Rate) + ratingChange, RatingChange = ratingChange, Score = sets.Sum(q => q.AwayScore) - sets.Sum(q => q.HomeScore) }); } #endregion var match = new Match() { AwayUsers = awayTeam.Users, AwayTeam = awayTeam, AwayWon = awayWon, Draw = draw, HomeUsers = homeTeam.Users, HomeTeam = homeTeam, HomeWon = homeWon, League = league, Ratings = ratings, Sets = sets }; db.Matches.Add(match); await db.SaveChangesAsync(); #region Update ranking post match foreach (var item in homeTeam.Users) { var rank = Statistics.GetRank(league.Id, item.Id); var rating = ratings.FirstOrDefault(q => q.UserId == item.Id); rating.Rank = rank; rating.RankingChange = ratingHome.FirstOrDefault(q => q.Item1 == item.Id).Item3 - rank; db.Entry(rating).State = EntityState.Modified; } foreach (var item in awayTeam.Users) { var rank = Statistics.GetRank(league.Id, item.Id); var rating = ratings.FirstOrDefault(q => q.UserId == item.Id); rating.Rank = rank; rating.RankingChange = ratingAway.FirstOrDefault(q => q.Item1 == item.Id).Item3 - rank; db.Entry(rating).State = EntityState.Modified; } #endregion await db.SaveChangesAsync(); return RedirectToAction("Details", "League", new { slug = league.Slug }); }