public async Task<IHttpActionResult> CreatePoll(string name)
        {
            using (var dbContext = new DatabaseContext())
            {
                if (string.IsNullOrWhiteSpace(name))
                    return BadRequest().WithReason("A name is required");

                var exists = await GetPolls(dbContext, DateTime.Now)
                    .AnyAsync(p => p.Name == name);
                if (exists)
                    return StatusCode(HttpStatusCode.Conflict)
                        .WithReason("A poll with the same name already exists");

                var currentUser = await dbContext.Users.SingleAsync(u => u.UserName == User.Identity.Name);
                var poll = new LunchPoll
                {
                    Name = name,
                    Date = DateTime.Now,
                    Voters = new List<User>(),
                    Votes = new List<LunchVote>()
                };
                dbContext.LunchPolls.Add(poll);
                await AddToPoll(dbContext, poll, currentUser);
                await dbContext.SaveChangesAsync();

                LunchHub.OnPollChanged(new LunchPollViewModel(poll));
                return Ok();
            }
        }
 public LunchPollViewModel(LunchPoll poll)
 {
     Id = poll.Id;
     Info = new LunchPollInfoViewModel(poll);
     Options = (
         from vote in poll.Votes
         group vote by vote.Option into g
         select new LunchOptionViewModel(poll.Id, g.Key, g)
     ).ToDictionary(o => o.Id);
 }
        public async Task AddToPoll(DatabaseContext dbContext, LunchPoll poll, User user)
        {
            var existingPolls = await GetPolls(dbContext, DateTime.Now)
                .Where(p => p.Voters.Select(v => v.Id).Contains(user.Id))
                .ToListAsync();
            if (existingPolls.Contains(poll))
                return;

            foreach (var existingPoll in existingPolls)
                RemoveFromPoll(dbContext, existingPoll, user);
            poll.Voters.Add(user);

            LunchHub.OnPollChanged(new LunchPollViewModel(poll));
        }
 public void RemoveFromPoll(DatabaseContext dbContext, LunchPoll poll, User user)
 {
     poll.Voters.Remove(user);
     var userVotes = poll.Votes.Where(v => v.User == user).ToList();
     foreach (var vote in userVotes)
     {
         var remainingVotes = poll.Votes
             .Where(v => v.Option == vote.Option)
             .Except(new[] { vote });
         LunchHub.OnVote(poll.Id, vote.Option, remainingVotes);
         dbContext.LunchVotes.Remove(vote);
     }
     LunchHub.OnPollChanged(new LunchPollViewModel(poll));
 }
 public LunchPollInfoViewModel(LunchPoll poll)
 {
     Id = poll.Id;
     Name = poll.Name;
     Voters = poll.Voters.Select(u => u.UserName).ToList();
 }