Пример #1
0
            public async Task <DrawEnvelope> Handle(Command request, CancellationToken cancellationToken)
            {
                // Validations
                var exist = await _context
                            .Draws
                            .Where(d => d.Name.Equals(request.DrawData.Name, StringComparison.InvariantCultureIgnoreCase) && d.ProgrammedFor == request.DrawData.ProgrammedFor)
                            .AnyAsync(cancellationToken);

                if (exist)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Error = $"Ya existe un sorteo con nombre '{request.DrawData.Name}' programado para el '{request.DrawData.ProgrammedFor.ToShortDateString()}'" });
                }

                // Creating draw
                var draw = new Draw
                {
                    Name        = request.DrawData.Name,
                    Description = request.DrawData.Description,
                    AllowMultipleParticipations = request.DrawData.AllowMultipleParticipations,
                    ProgrammedFor = request.DrawData.ProgrammedFor,
                    GroupName     = request.DrawData.GroupName
                };

                // Saving
                _context.Draws.Add(draw);
                await _context.SaveChangesAsync(cancellationToken);

                // Mapping
                var drawEnvelope = _mapper.Map <Draw, DrawEnvelope>(draw);

                return(drawEnvelope);
            }
Пример #2
0
            public async Task <UserEnvelope> Handle(Command request, CancellationToken cancellationToken)
            {
                // Getting if user exist
                var existUser = await _context
                                .Users
                                .Where(u => u.Login.Equals(request.UserData.Login, StringComparison.InvariantCultureIgnoreCase))
                                .AnyAsync(cancellationToken);

                // Validations
                if (existUser)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Error = $"El usuario {request.UserData.Login} ya se encuentra en uso." });
                }

                // Creating user
                var salt = Guid.NewGuid().ToByteArray();
                var user = new User
                {
                    Login = request.UserData.Login,
                    Hash  = _passwordHasher.Hash(request.UserData.Password, salt),
                    Salt  = salt
                };

                // Saving
                _context.Users.Add(user);
                await _context.SaveChangesAsync(cancellationToken);

                // Mapping
                var userEnvelope = _mapper.Map <User, UserEnvelope>(user);

                userEnvelope.Token = await _jwtTokenGenerator.CreateToken(user.Login);

                return(userEnvelope);
            }
Пример #3
0
            public async Task <Unit> Handle(Command request, CancellationToken cancellationToken)
            {
                // Validation
                var draw = await _context
                           .Draws
                           .FirstOrDefaultAsync(d => d.Id == request.DrawId, cancellationToken);

                if (draw == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, new { Error = $"El sorteo con id '{request.DrawId}' no existe." });
                }

                // Saving
                _context.Draws.Remove(draw);
                await _context.SaveChangesAsync(cancellationToken);

                return(Unit.Value);
            }
Пример #4
0
            public async Task <PrizeEnvelope> Handle(Command request, CancellationToken cancellationToken)
            {
                // Getting the parent draw & your prizes
                var draw = await _context
                           .Draws
                           .Include(d => d.Prizes)
                           .FirstOrDefaultAsync(d => d.Id == request.DrawId, cancellationToken);

                // Validations
                if (draw == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, new { Error = $"El sorteo con id '{ request.DrawId }' no existe." });
                }

                var existPrize = draw.Prizes.Any(p => p.Name.Equals(request.Prize.Name, StringComparison.InvariantCultureIgnoreCase));

                if (existPrize)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Error = $"El premio con nombre '{ request.Prize.Name }' ya existe." });
                }


                // Creating prize
                var prize = new Prize
                {
                    DrawId      = request.DrawId,
                    Name        = request.Prize.Name,
                    Description = request.Prize.Description,
                    AttemptsUntilChooseWinner = request.Prize.AttemptsUntilChooseWinner,
                };

                // Saving
                await _context.Prizes.AddAsync(prize, cancellationToken);

                draw.Prizes.Add(prize);
                await _context.SaveChangesAsync(cancellationToken);

                // Mapping
                var prizeEnvelope = _mapper.Map <Prize, PrizeEnvelope>(prize);

                return(prizeEnvelope);
            }
Пример #5
0
            public async Task <DrawEnvelope> Handle(Command request, CancellationToken cancellationToken)
            {
                // Getting draw
                var draw = await _context
                           .Draws
                           .Include(d => d.Prizes)
                           .ThenInclude(p => p.SelectionSteps)
                           .FirstOrDefaultAsync(d => d.Id == request.DrawId, cancellationToken);

                // Validations
                if (draw == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, new { Error = $"El sorteo con id '{ request.DrawId }' no existe." });
                }

                if (draw.ExecutedOn.HasValue)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Error = $"El sorteo '{ draw.Name }' se encuentra cerrado desde el { draw.ExecutedOn }." });
                }

                if (!draw.IsCompleted)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Error = $"El sorteo '{ draw.Name }' no está completado aún. Faltan ganadores por seleccionar." });
                }

                // Closing
                draw.ExecutedOn = DateTime.Now;

                // Saving
                _context.Update(draw);
                await _context.SaveChangesAsync(cancellationToken);

                // Mapping
                var drawEnvelope = _mappper.Map <Draw, DrawEnvelope>(draw);

                // Getting quantity of entries for the draw.
                drawEnvelope.EntriesQty = await _context.DrawEntries.CountAsync(de => de.DrawId == drawEnvelope.Id, cancellationToken);

                return(drawEnvelope);
            }
Пример #6
0
            public async Task <Unit> Handle(Command request, CancellationToken cancellationToken)
            {
                // Getting prize
                var prize = await _context
                            .Prizes
                            .FirstOrDefaultAsync(p => p.Id == request.PrizeId, cancellationToken);

                // Validation
                if (prize == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, new { Error = $"El premio con id '{request.PrizeId}' no existe." });
                }

                if (prize.DrawId != request.DrawId)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Error = $"El premio con id '{request.PrizeId}' no está asociado al sorteo con id '{request.DrawId}'." });
                }

                // Saving
                _context.Prizes.Remove(prize);
                await _context.SaveChangesAsync(cancellationToken);

                return(Unit.Value);
            }
Пример #7
0
            public async Task <PrizeSelectionStepEnvelope> Handle(Command request, CancellationToken cancellationToken)
            {
                // Getting the parent prize & prizes selection steps
                var prize = await _context
                            .Prizes
                            .Include(p => p.Draw)
                            .Include(p => p.SelectionSteps)
                            .FirstOrDefaultAsync(d => d.Id == request.PrizeId, cancellationToken);

                // Validating prize's existence
                if (prize == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, new { Error = $"El premio con id '{ request.PrizeId}' no existe." });
                }

                // Validating if the draw is already closed.
                if (prize.Draw.ExecutedOn.HasValue)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Error = $"El sorteo '{ prize.Draw.Name }' se encuentra cerrado desde el { prize.Draw.ExecutedOn }." });
                }

                // If prize was delivered, then it is removed the winner existent step for creating a new one
                int removedEntrantId = -1;

                if (prize.Delivered)
                {
                    // Getting winner step
                    var winnerStep = prize
                                     .SelectionSteps
                                     .FirstOrDefault(pss => pss.PrizeSelectionStepType == PrizeSelectionStepType.Winner);

                    if (winnerStep == null)
                    {
                        throw new RestException(HttpStatusCode.BadRequest, new { Error = $"El premio con nombre '{ prize.Name }' ya ha sido entregado pero no existe paso ganador." });
                    }

                    // Getting entrant id for winner step to remove
                    removedEntrantId = winnerStep.EntrantId;

                    // Deleting winner step
                    _context.PrizeSelectionSteps.Remove(winnerStep);
                    await _context.SaveChangesAsync(cancellationToken);
                }

                // Selecting loser steps inside prize
                var previousLoserSteps = prize
                                         .SelectionSteps
                                         .Where(st => st.PrizeSelectionStepType == PrizeSelectionStepType.Loser)
                                         .ToList();

                // Selecting all winners from all prizes that belongs to draw's same group.
                var previousWinnerSteps = await _context
                                          .PrizeSelectionSteps
                                          .Include(pss => pss.Prize)
                                          .ThenInclude(p => p.Draw)
                                          .Include(pss => pss.Entrant)
                                          .Where(pss => pss.PrizeSelectionStepType == PrizeSelectionStepType.Winner && pss.Prize.Draw.GroupName == prize.Draw.GroupName)
                                          .ToListAsync(cancellationToken);

                // Getting all entries for the draw & prize.
                var allEntries = _context
                                 .GetEntriesByDrawExcludingPreviousWinnersAndLosers(prize.DrawId);

                // Excluding the losers steps for the current prize, the prize's winners from others draws that belongs to the same group and the removed entrant id
                var entries = removedEntrantId == - -1
                    ? allEntries
                              .Where(de =>
                                     previousLoserSteps.All(l => l.EntrantId != de.EntrantId) &&
                                     previousWinnerSteps.All(w => w.EntrantId != de.EntrantId)
                                     )
                              .ToList()
                    : allEntries
                              .Where(de =>
                                     removedEntrantId != de.EntrantId &&
                                     previousLoserSteps.All(l => l.EntrantId != de.EntrantId) &&
                                     previousWinnerSteps.All(w => w.EntrantId != de.EntrantId)
                                     )
                              .ToList();

                // Validating the existence of entrants for the draw.
                if (entries.Count == 0)
                {
                    throw new RestException(HttpStatusCode.BadRequest, new { Error = $"No existen participantes disponibles en el sorteo '{ prize.Draw.Name }' para seleccionar un ganador." });
                }

                // Selecting winner entry
                var selectedEntry = _randomSelector
                                    .TakeRandom(entries, 1, entries.Count)
                                    .SingleOrDefault();

                // Validating entry's selection existence
                if (selectedEntry == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, new { Error = "No fue seleccionado ninguna participación." });
                }

                // Getting the whole info of the winner entry
                var winnerEntry = _context
                                  .DrawEntries
                                  .Include(de => de.Entrant)
                                  .SingleOrDefault(de => de.Id == selectedEntry.Id);

                // Creating prize selection step
                var prizeSelectionStep = new PrizeSelectionStep
                {
                    PrizeId                = prize.Id,
                    EntrantId              = winnerEntry.EntrantId,
                    DrawEntryId            = winnerEntry.Id,
                    PrizeSelectionStepType = (previousLoserSteps.Count < prize.AttemptsUntilChooseWinner)
                                                ? PrizeSelectionStepType.Loser
                                                : PrizeSelectionStepType.Winner,
                    RegisteredOn = DateTime.Now,
                };

                // Updating prize
                if (prizeSelectionStep.PrizeSelectionStepType == PrizeSelectionStepType.Winner)
                {
                    prize.ExecutedOn = DateTime.Now;
                }

                // Saving
                await _context.PrizeSelectionSteps.AddAsync(prizeSelectionStep, cancellationToken);

                prize.SelectionSteps.Add(prizeSelectionStep);
                await _context.SaveChangesAsync(cancellationToken);

                // Mapping
                var prizeSelectionStepEnvelope = _mapper.Map <PrizeSelectionStep, PrizeSelectionStepEnvelope>(prizeSelectionStep);

                return(prizeSelectionStepEnvelope);
            }