From 9fa6c5512cf229bd84ba131577f4a8d2b1efb770 Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Sat, 26 Nov 2022 00:25:57 -0600 Subject: Añadida lógica de rifa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Controllers/RafflesController.cs | 32 ++++++++++++++++++++++++++++++-- Logics/RafflePlayLogic.cs | 39 +++++++++++++++++++++++++++++++++++++++ Models/Raffle.cs | 6 ++++++ Services/GameService.cs | 16 +++++++++------- Services/IRaffleService.cs | 2 ++ Services/RaffleService.cs | 8 ++++++++ 6 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 Logics/RafflePlayLogic.cs diff --git a/Controllers/RafflesController.cs b/Controllers/RafflesController.cs index 26b5a96..82e05a4 100644 --- a/Controllers/RafflesController.cs +++ b/Controllers/RafflesController.cs @@ -2,6 +2,8 @@ using AutoMapper; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using BackendPIA.Forms; +using BackendPIA.Errors; +using BackendPIA.Logics; using BackendPIA.Models; using BackendPIA.Services; @@ -10,10 +12,12 @@ namespace BackendPIA.Controllers { [ApiController] public class RafflesController : ControllerBase { private readonly IRaffleService _service; + private readonly IGameService _game_service; private readonly IMapper _mapper; - public RafflesController(IMapper mapper, IRaffleService service) { + public RafflesController(IMapper mapper, IRaffleService service, IGameService game_service) { _service = service; + _game_service = game_service; _mapper = mapper; } @@ -55,7 +59,7 @@ namespace BackendPIA.Controllers { [Authorize(Roles = "Administrator")] [HttpDelete("{id:int}")] - public async Task Update(long id) { + public async Task Delete(long id) { var result = await _service.DeleteRaffle(id); if(!result) @@ -63,5 +67,29 @@ namespace BackendPIA.Controllers { return StatusCode(303, new { Message = "The resource has been deleted"} ); } + + [Authorize] + [HttpGet("{id:int}/available_tickets")] + public async Task>> AvailableTickets(long id) { + IEnumerable available_tickets = from number in Enumerable.Range(1, 54) select number; + IEnumerable taken_tickets = await _service.GetTakenTickets(id); + + if(!taken_tickets.Any()) + return NotFound(new NotFoundError(404, $"The raffle with id {id} doesn't exist or doesn't have any tickets.")); + + return Ok(new { Numbers = available_tickets.Except(taken_tickets) }); + } + + [Authorize(Roles = "Administrator")] + [HttpPost("{id:int}/play")] + public async Task>> Play(long id) { + RafflePlayLogic logic = new RafflePlayLogic(_game_service, _service, id); + bool result = await logic.Call(); + + if(!result) + return BadRequest(new { ErrorMessage = logic.ErrorMessage }); + + return Ok(logic.Winners); + } } } \ No newline at end of file diff --git a/Logics/RafflePlayLogic.cs b/Logics/RafflePlayLogic.cs new file mode 100644 index 0000000..026bb91 --- /dev/null +++ b/Logics/RafflePlayLogic.cs @@ -0,0 +1,39 @@ +using BackendPIA.Models; +using BackendPIA.Services; + +namespace BackendPIA.Logics { + public class RafflePlayLogic { + private readonly IGameService _game_service; + private readonly IRaffleService _raffle_service; + private readonly long _raffle_id; + public string? ErrorMessage { get; set; } + public IEnumerable? Winners { get; set;} + + public RafflePlayLogic(IGameService game_service, IRaffleService raffle_service, long raffle_id) { + _game_service = game_service; + _raffle_service = raffle_service; + _raffle_id = raffle_id; + } + + public async Task Call() { + var raffle = await _raffle_service.GetRaffle(_raffle_id); + + // Checks. + if(raffle == null) { + ErrorMessage = $"The raffle with id {_raffle_id} couldn't be found."; + + return false; + } + + if(raffle.Winners >= _raffle_service.GetRaffleTickets(_raffle_id).Count()) { + ErrorMessage = $"Can't play: not enough players."; + + return false; + } + + Winners = await _game_service.GetWinners(_raffle_id); + + return true; + } + } +} \ No newline at end of file diff --git a/Models/Raffle.cs b/Models/Raffle.cs index a798bd6..96a5a62 100644 --- a/Models/Raffle.cs +++ b/Models/Raffle.cs @@ -1,4 +1,6 @@ using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using System.Runtime.Serialization; namespace BackendPIA.Models { public class Raffle { @@ -10,7 +12,11 @@ namespace BackendPIA.Models { [Range(1, 54, ErrorMessage = "Value for {0} must be between {1} and {2}.")] public int Winners { get; set; } public bool IsClosed { get; set; } + [JsonIgnore] + [IgnoreDataMember] public ICollection? Tickets { get; set; } + [JsonIgnore] + [IgnoreDataMember] public ICollection? Prizes { get; set; } } } \ No newline at end of file diff --git a/Services/GameService.cs b/Services/GameService.cs index 01c084a..76f5061 100644 --- a/Services/GameService.cs +++ b/Services/GameService.cs @@ -10,10 +10,10 @@ namespace BackendPIA.Services { } public async Task> GetWinners(long raffle_id) { - var raffle = await _context.Raffles.Include(r => r.Tickets.Select(t => t.Owner)).FirstOrDefaultAsync(r => r.Id == raffle_id); - Queue prizes = new Queue(_context.Prizes.Where(p => p.RaffleId == raffle_id).Select(p => p.Id)); - var tickets = await _context.Tickets.Where(t => t.RaffleId == raffle_id).Select(t => t.Number).ToListAsync(); - List winners = GetTicketNumbers(raffle.Winners, tickets); + var raffle = await _context.Raffles.Include(r => r.Tickets).ThenInclude(t => t.Owner).FirstOrDefaultAsync(r => r.Id == raffle_id); + Queue prizes = new Queue(_context.Prizes.Where(p => p.RaffleId == raffle_id).OrderBy(p => p.Tier).Select(p => p.Id)); + // var tickets = await _context.Tickets.Where(t => t.RaffleId == raffle_id).Select(t => t.Number).ToListAsync(); + List winners = GetTicketNumbers(raffle.Winners, raffle.Tickets); List raffle_winners = new List(); foreach(int winner in winners) { @@ -23,22 +23,24 @@ namespace BackendPIA.Services { await _context.AddAsync(raffle_winner); } + raffle.IsClosed = true; await _context.SaveChangesAsync(); return raffle_winners; } - private List GetTicketNumbers(int limit, List tickets) { + private List GetTicketNumbers(int limit, ICollection tickets) { List winners = new List(); Random rng = new Random(); while(winners.Count < limit) { int i = rng.Next(tickets.Count - 1); - if(winners.Contains(tickets[i])) // Check for duplicate numbers. + if(winners.Contains(tickets.ElementAt(i).Number)) // Check for duplicate numbers. continue; - winners.Append(tickets[i]); + winners.Add(tickets.ElementAt(i).Number); + tickets.ElementAt(i).IsWinner = true; } return winners; diff --git a/Services/IRaffleService.cs b/Services/IRaffleService.cs index 2326629..059edd7 100644 --- a/Services/IRaffleService.cs +++ b/Services/IRaffleService.cs @@ -7,5 +7,7 @@ namespace BackendPIA.Services { public Task> GetRaffles(string query); public Task GetRaffle(long id); public Task DeleteRaffle(long id); + public Task> GetTakenTickets(long id); + public IEnumerable GetRaffleTickets(long id); } } \ No newline at end of file diff --git a/Services/RaffleService.cs b/Services/RaffleService.cs index 58401b8..c86ea3b 100644 --- a/Services/RaffleService.cs +++ b/Services/RaffleService.cs @@ -52,5 +52,13 @@ namespace BackendPIA.Services { return true; } + + public async Task> GetTakenTickets(long id) { + return await _context.Tickets.Where(t => t.RaffleId == id).Select(t => t.Number).ToListAsync(); + } + + public IEnumerable GetRaffleTickets(long id) { + return _context.Tickets.Where(t => t.RaffleId == id); + } } } \ No newline at end of file -- cgit v1.2.3