summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Controllers/TicketsController.cs74
-rw-r--r--Logics/CreateTicketLogic.cs69
-rw-r--r--Program.cs1
-rw-r--r--Services/ITicketService.cs10
-rw-r--r--Services/RaffleService.cs7
-rw-r--r--Services/TicketService.cs39
6 files changed, 194 insertions, 6 deletions
diff --git a/Controllers/TicketsController.cs b/Controllers/TicketsController.cs
new file mode 100644
index 0000000..97a4a26
--- /dev/null
+++ b/Controllers/TicketsController.cs
@@ -0,0 +1,74 @@
+using AutoMapper;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using BackendPIA.Errors;
+using BackendPIA.Forms;
+using BackendPIA.Logics;
+using BackendPIA.Models;
+using BackendPIA.Services;
+
+namespace BackendPIA.Controllers {
+ [Route("api/raffles/{raffleId:int}/tickets")]
+ [ApiController]
+ public class TicketsController : ControllerBase {
+ private readonly IMapper _mapper;
+ private readonly ITicketService _ticket_service;
+ private readonly ApplicationDbContext _context;
+ private readonly UserManager<UserAccount> _manager;
+
+ public TicketsController(IMapper mapper, ITicketService service, ApplicationDbContext context, UserManager<UserAccount> manager) {
+ _mapper = mapper;
+ _ticket_service = service;
+ _context = context;
+ _manager = manager;
+ }
+
+ [Authorize]
+ [HttpGet]
+ public async Task<ActionResult<IEnumerable<TicketDTO>>> Index(long raffleId) {
+ var result = await _ticket_service.GetTickets(raffleId);
+
+ if(result == null)
+ return StatusCode(404, new NotFoundError(404, "The resource doesn't exist"));
+
+ return Ok(_mapper.Map<List<TicketDTO>>(result));
+ }
+
+ [Authorize]
+ [HttpGet("{id:int}")]
+ public async Task<ActionResult<TicketDTO>> Show(long raffleId, long id) {
+ var result = await _ticket_service.GetTicket(raffleId, id);
+
+ if(result == null)
+ return StatusCode(404, new NotFoundError(404, "The resource doesn't exist"));
+
+ return Ok(_mapper.Map<TicketDTO>(result));
+ }
+
+ [Authorize]
+ [HttpPost]
+ public async Task <ActionResult<TicketDTO>> Create(long raffleId, TicketForm form) {
+ string email = HttpContext.User.Claims.Where(c => c.Type.Contains("email")).First().Value;
+ var user = await _manager.FindByEmailAsync(email);
+ CreateTicketLogic logic = new CreateTicketLogic(_ticket_service, _context, _mapper, form, user, raffleId);
+ var result = await logic.Call();
+
+ if(!result)
+ return StatusCode(422, new InvalidInputError(422, logic.ErrorMessage));
+
+ return Ok(_mapper.Map<TicketDTO>(logic.Created));
+ }
+
+ [Authorize(Roles = "Administrator")]
+ [HttpDelete("{id:int}")]
+ public async Task <ActionResult> Delete(long raffleId, long id) {
+ bool result = await _ticket_service.DeleteTicket(raffleId, id);
+
+ if(!result)
+ return StatusCode(404, new NotFoundError(404, "The ticket couldn't be found."));
+
+ return Ok(new { Message = "The ticket has been deleted."});
+ }
+ }
+} \ No newline at end of file
diff --git a/Logics/CreateTicketLogic.cs b/Logics/CreateTicketLogic.cs
new file mode 100644
index 0000000..df64a1a
--- /dev/null
+++ b/Logics/CreateTicketLogic.cs
@@ -0,0 +1,69 @@
+using AutoMapper;
+using BackendPIA.Services;
+using BackendPIA.Models;
+using BackendPIA.Forms;
+
+namespace BackendPIA.Logics {
+ public class CreateTicketLogic {
+ private readonly ITicketService _ticket_service;
+ private readonly ApplicationDbContext _context;
+ private readonly UserAccount _user;
+ private readonly long _raffle_id;
+ private readonly IMapper _mapper;
+ private readonly TicketForm _form;
+ public string? ErrorMessage { get; set; }
+ public Ticket? Created { get; set; }
+
+ public CreateTicketLogic(ITicketService service, ApplicationDbContext context, IMapper mapper, TicketForm form, UserAccount user, long raffle_id) {
+ _ticket_service = service;
+ _mapper = mapper;
+ _form = form;
+ _user = user;
+ _raffle_id = raffle_id;
+ _context = context;
+ }
+
+ public async Task<bool> Call() {
+ // Check if the user exists.
+ if(_user == null)
+ return false;
+
+ // Check if the given raffle exists-
+ if(!_context.Raffles.Any(r => r.Id == _raffle_id)) {
+ ErrorMessage = "The raffle doesn't exist.";
+
+ return false;
+ }
+
+ // Check if the user already has a ticket for the given raffle.
+ if(_context.Tickets.Where(t => t.RaffleId == _raffle_id).Where(t => t.UserAccountId == _user.Id).Count() > 0) {
+ ErrorMessage = $"There's already a ticket for {_user.UserName}.";
+
+ return false;
+ }
+
+ // Check if the number has been taken.
+ if(_context.Tickets.Where(t => t.RaffleId == _raffle_id).Where(t => t.Number == _form.Number).Count() > 0) {
+ ErrorMessage = $"There's already a registered ticket with the number {_form.Number}.";
+
+ return false;
+ }
+
+ var ticket = _mapper.Map<Ticket>(_form);
+ ticket.RaffleId = _raffle_id;
+
+ // Check if the given raffle has reached the ticket limit.
+ if(_context.Tickets.Where(t => t.RaffleId == _raffle_id).Count() >= 54) {
+ ErrorMessage = $"The raffle with id {_raffle_id} has reached the ticket limit";
+
+ return false;
+ }
+
+ ticket.UserAccountId = _user.Id;
+ ticket.IsWinner = false;
+ Created = await _ticket_service.CreateTicket(ticket);
+
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/Program.cs b/Program.cs
index 38c1b4b..008bfc7 100644
--- a/Program.cs
+++ b/Program.cs
@@ -28,6 +28,7 @@ builder.Services.AddAutoMapper(typeof(Program));
builder.Services.AddSingleton<ITokenGenerator>(s => new TokenGenerator(builder.Configuration["Jwt:Key"]));
builder.Services.AddScoped<IUserAccountService, UserAccountService>();
builder.Services.AddScoped<IRaffleService, RaffleService>();
+builder.Services.AddScoped<ITicketService, TicketService>();
// End of custom services configuration.
// Swagger configuration.
diff --git a/Services/ITicketService.cs b/Services/ITicketService.cs
new file mode 100644
index 0000000..b25ec83
--- /dev/null
+++ b/Services/ITicketService.cs
@@ -0,0 +1,10 @@
+using BackendPIA.Models;
+
+namespace BackendPIA.Services {
+ public interface ITicketService {
+ public Task<Ticket> CreateTicket(Ticket to_create);
+ public Task<IEnumerable<Ticket>> GetTickets(long raffle_id);
+ public Task<Ticket> GetTicket(long raffle_id, long id);
+ public Task<bool> DeleteTicket(long raffle_id, long id);
+ }
+} \ No newline at end of file
diff --git a/Services/RaffleService.cs b/Services/RaffleService.cs
index 6cdae3b..58401b8 100644
--- a/Services/RaffleService.cs
+++ b/Services/RaffleService.cs
@@ -38,12 +38,7 @@ namespace BackendPIA.Services {
}
public async Task<Raffle> GetRaffle(long id) {
- var raffle = await _context.Raffles.FindAsync(id);
-
- if(raffle == null)
- return null;
-
- return raffle;
+ return await _context.Raffles.FindAsync(id);
}
public async Task<bool> DeleteRaffle(long id) {
diff --git a/Services/TicketService.cs b/Services/TicketService.cs
new file mode 100644
index 0000000..3ac9660
--- /dev/null
+++ b/Services/TicketService.cs
@@ -0,0 +1,39 @@
+using Microsoft.EntityFrameworkCore;
+using BackendPIA.Models;
+
+namespace BackendPIA.Services {
+ public class TicketService : ITicketService {
+ private readonly ApplicationDbContext _context;
+
+ public TicketService(ApplicationDbContext context) {
+ _context = context;
+ }
+
+ public async Task<Ticket> CreateTicket(Ticket to_create) {
+ await _context.AddAsync(to_create);
+ await _context.SaveChangesAsync();
+
+ return to_create;
+ }
+
+ public async Task<IEnumerable<Ticket>> GetTickets(long raffle_id) {
+ return await _context.Tickets.Where(t => t.RaffleId == raffle_id).ToListAsync();
+ }
+
+ public async Task<Ticket> GetTicket(long raffle_id, long id) {
+ return await _context.Tickets.Where(t => t.RaffleId == raffle_id).FirstOrDefaultAsync(t => t.Id == id);
+ }
+
+ public async Task<bool> DeleteTicket(long raffle_id, long id) {
+ var to_delete = await _context.Tickets.Where(t => t.RaffleId == raffle_id).FirstOrDefaultAsync(t => t.Id == id);
+
+ if(to_delete == null)
+ return false;
+
+ _context.Tickets.Remove(to_delete);
+ await _context.SaveChangesAsync();
+
+ return true;
+ }
+ }
+} \ No newline at end of file