summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Controllers/RafflesController.cs32
-rw-r--r--Logics/RafflePlayLogic.cs39
-rw-r--r--Models/Raffle.cs6
-rw-r--r--Services/GameService.cs16
-rw-r--r--Services/IRaffleService.cs2
-rw-r--r--Services/RaffleService.cs8
6 files changed, 94 insertions, 9 deletions
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<ActionResult> Update(long id) {
+ public async Task<ActionResult> 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<ActionResult<IEnumerable<int>>> AvailableTickets(long id) {
+ IEnumerable<int> available_tickets = from number in Enumerable.Range(1, 54) select number;
+ IEnumerable<int> 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<ActionResult<IEnumerable<RaffleWinner>>> 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<RaffleWinner>? 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<bool> 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<Ticket>? Tickets { get; set; }
+ [JsonIgnore]
+ [IgnoreDataMember]
public ICollection<Prize>? 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<IEnumerable<RaffleWinner>> GetWinners(long raffle_id) {
- var raffle = await _context.Raffles.Include(r => r.Tickets.Select(t => t.Owner)).FirstOrDefaultAsync(r => r.Id == raffle_id);
- Queue<long> prizes = new Queue<long>(_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<int> 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<long> prizes = new Queue<long>(_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<int> winners = GetTicketNumbers(raffle.Winners, raffle.Tickets);
List<RaffleWinner> raffle_winners = new List<RaffleWinner>();
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<int> GetTicketNumbers(int limit, List<int> tickets) {
+ private List<int> GetTicketNumbers(int limit, ICollection<Ticket> tickets) {
List<int> winners = new List<int>();
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<IEnumerable<Raffle>> GetRaffles(string query);
public Task<Raffle> GetRaffle(long id);
public Task<bool> DeleteRaffle(long id);
+ public Task<IEnumerable<int>> GetTakenTickets(long id);
+ public IEnumerable<Ticket> 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<IEnumerable<int>> GetTakenTickets(long id) {
+ return await _context.Tickets.Where(t => t.RaffleId == id).Select(t => t.Number).ToListAsync();
+ }
+
+ public IEnumerable<Ticket> GetRaffleTickets(long id) {
+ return _context.Tickets.Where(t => t.RaffleId == id);
+ }
}
} \ No newline at end of file