diff --git a/coffeecard/CoffeeCard.Library/Services/v2/AccountService.cs b/coffeecard/CoffeeCard.Library/Services/v2/AccountService.cs index 19b2447e..e1aef2df 100644 --- a/coffeecard/CoffeeCard.Library/Services/v2/AccountService.cs +++ b/coffeecard/CoffeeCard.Library/Services/v2/AccountService.cs @@ -234,7 +234,7 @@ public async Task SearchUsers(String search, int pageNum, in throw new ArgumentException($"The value of {nameof(pageNum)} is outside of the range of total users"); } - var userByPage = await query + var usersByPage = await query .OrderBy(u => u.Id) .Skip(skip).Take(pageLength) .Select(u => new SimpleUserResponse @@ -250,7 +250,7 @@ public async Task SearchUsers(String search, int pageNum, in return new UserSearchResponse { TotalUsers = totalUsers, - Users = userByPage + Users = usersByPage }; } diff --git a/coffeecard/CoffeeCard.Library/Services/v2/IMenuItemService.cs b/coffeecard/CoffeeCard.Library/Services/v2/IMenuItemService.cs new file mode 100644 index 00000000..6f85551d --- /dev/null +++ b/coffeecard/CoffeeCard.Library/Services/v2/IMenuItemService.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using CoffeeCard.Models.DataTransferObjects.v2.Product; +using CoffeeCard.Models.DataTransferObjects.v2.Products; + +namespace CoffeeCard.Library.Services.v2 +{ + public interface IMenuItemService : IDisposable + { + Task> GetAllMenuItemsAsync(); + Task AddMenuItemAsync(AddMenuItemRequest newMenuItem); + Task UpdateMenuItemAsync(int menuItemid, UpdateMenuItemRequest changedMenuItem); + } +} \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Library/Services/v2/ITicketService.cs b/coffeecard/CoffeeCard.Library/Services/v2/ITicketService.cs index 2731647f..924ef0b4 100644 --- a/coffeecard/CoffeeCard.Library/Services/v2/ITicketService.cs +++ b/coffeecard/CoffeeCard.Library/Services/v2/ITicketService.cs @@ -10,7 +10,7 @@ public interface ITicketService : IDisposable { Task IssueTickets(Purchase purchase); - Task> GetTickets(User user, bool includeUsed); + Task> GetTicketsAsync(User user, bool includeUsed); public Task UseTicketAsync(User user, int productId); diff --git a/coffeecard/CoffeeCard.Library/Services/v2/MenuItemService.cs b/coffeecard/CoffeeCard.Library/Services/v2/MenuItemService.cs new file mode 100644 index 00000000..f6e3e95c --- /dev/null +++ b/coffeecard/CoffeeCard.Library/Services/v2/MenuItemService.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using CoffeeCard.Common.Errors; +using CoffeeCard.Library.Persistence; +using CoffeeCard.Models.DataTransferObjects.v2.Product; +using CoffeeCard.Models.DataTransferObjects.v2.Products; +using CoffeeCard.Models.Entities; +using Microsoft.EntityFrameworkCore; +using Serilog; + +namespace CoffeeCard.Library.Services.v2 +{ + public sealed class MenuItemService : IMenuItemService + { + private readonly CoffeeCardContext _context; + + public MenuItemService(CoffeeCardContext context) + { + _context = context; + } + + public async Task> GetAllMenuItemsAsync() + { + return await _context.MenuItems + .OrderBy(p => p.Id) + .Select(p => new MenuItemResponse + { + Id = p.Id, + Name = p.Name + }) + .ToListAsync(); + } + + public async Task AddMenuItemAsync(AddMenuItemRequest newMenuItem) + { + var nameExists = await CheckMenuItemNameExists(newMenuItem.Name); + if (nameExists) + { + throw new ConflictException($"Menu item already exists with name {newMenuItem.Name}"); + } + + var menuItem = new MenuItem() + { + Name = newMenuItem.Name + }; + + _context.MenuItems.Add(menuItem); + await _context.SaveChangesAsync(); + + var result = new MenuItemResponse + { + Id = menuItem.Id, + Name = menuItem.Name + }; + + return result; + } + + private async Task CheckMenuItemNameExists(string name) + { + return await _context.MenuItems + .AnyAsync(p => p.Name == name); + } + + public async Task UpdateMenuItemAsync(int id, UpdateMenuItemRequest changedMenuItem) + { + var menuItem = await _context.MenuItems.FirstOrDefaultAsync(p => p.Id == id); + + if (menuItem == null) + { + Log.Warning("No menu item was found by Menu Item Id: {Id}", id); + throw new EntityNotFoundException($"No menu item was found by Menu Item Id {id}"); + } + + var nameExists = await CheckMenuItemNameExists(changedMenuItem.Name); + if (nameExists) + { + throw new ConflictException($"Menu item already exists with name {changedMenuItem.Name}"); + } + + menuItem.Name = changedMenuItem.Name; + + await _context.SaveChangesAsync(); + + var result = new MenuItemResponse + { + Id = id, + Name = menuItem.Name + }; + + return result; + } + + public void Dispose() + { + _context?.Dispose(); + } + } +} diff --git a/coffeecard/CoffeeCard.Library/Services/v2/ProductService.cs b/coffeecard/CoffeeCard.Library/Services/v2/ProductService.cs index 28e94443..728f5594 100644 --- a/coffeecard/CoffeeCard.Library/Services/v2/ProductService.cs +++ b/coffeecard/CoffeeCard.Library/Services/v2/ProductService.cs @@ -5,6 +5,7 @@ using CoffeeCard.Common.Errors; using CoffeeCard.Library.Persistence; using CoffeeCard.Models.DataTransferObjects.v2.Product; +using CoffeeCard.Models.DataTransferObjects.v2.Products; using CoffeeCard.Models.Entities; using Microsoft.EntityFrameworkCore; using Serilog; @@ -84,10 +85,15 @@ public async Task AddProduct(AddProductRequest newProduc NumberOfTickets = newProduct.NumberOfTickets, ExperienceWorth = 0, Visible = newProduct.Visible, - ProductUserGroup = newProduct.AllowedUserGroups.Select(userGroup => new ProductUserGroup - { - UserGroup = userGroup - }).ToList() + ProductUserGroup = newProduct.AllowedUserGroups + .Select(userGroup => new ProductUserGroup + { + UserGroup = userGroup + }).ToList(), + EligibleMenuItems = _context.MenuItems + .Where(mi => newProduct.MenuItemIds + .Contains(mi.Id)) + .ToList() }; _context.Products.Add(product); @@ -100,7 +106,13 @@ public async Task AddProduct(AddProductRequest newProduc Name = product.Name, NumberOfTickets = product.NumberOfTickets, Visible = product.Visible, - AllowedUserGroups = newProduct.AllowedUserGroups + AllowedUserGroups = newProduct.AllowedUserGroups, + MenuItems = product.EligibleMenuItems + .Select(mi => new MenuItemResponse + { + Id = mi.Id, + Name = mi.Name + }) }; return result; @@ -109,16 +121,23 @@ public async Task AddProduct(AddProductRequest newProduc public async Task UpdateProduct(UpdateProductRequest changedProduct) { var product = await GetProductAsync(changedProduct.Id); + product.Price = changedProduct.Price; product.Description = changedProduct.Description; product.NumberOfTickets = changedProduct.NumberOfTickets; product.Name = changedProduct.Name; product.Visible = changedProduct.Visible; - product.ProductUserGroup = changedProduct.AllowedUserGroups.Select(userGroup => new ProductUserGroup - { - ProductId = changedProduct.Id, - UserGroup = userGroup - }).ToList(); + product.ProductUserGroup = changedProduct.AllowedUserGroups + .Select(userGroup => new ProductUserGroup + { + ProductId = changedProduct.Id, + UserGroup = userGroup + }) + .ToList(); + product.EligibleMenuItems = _context.MenuItems + .Where(mi => changedProduct.MenuItemIds + .Contains(mi.Id)) + .ToList(); await _context.SaveChangesAsync(); @@ -129,7 +148,13 @@ public async Task UpdateProduct(UpdateProductRequest cha Name = product.Name, NumberOfTickets = product.NumberOfTickets, Visible = product.Visible, - AllowedUserGroups = changedProduct.AllowedUserGroups + AllowedUserGroups = changedProduct.AllowedUserGroups, + MenuItems = product.EligibleMenuItems + .Select(item => new MenuItemResponse + { + Id = item.Id, + Name = item.Name + }) }; return result; diff --git a/coffeecard/CoffeeCard.Library/Services/v2/TicketService.cs b/coffeecard/CoffeeCard.Library/Services/v2/TicketService.cs index a305c10a..8fa169e7 100644 --- a/coffeecard/CoffeeCard.Library/Services/v2/TicketService.cs +++ b/coffeecard/CoffeeCard.Library/Services/v2/TicketService.cs @@ -43,9 +43,9 @@ public async Task IssueTickets(Purchase purchase) Log.Information("Issued {NoTickets} Tickets for ProductId {ProductId}, PurchaseId {PurchaseId}", purchase.NumberOfTickets, purchase.ProductId, purchase.Id); } - public Task> GetTickets(User user, bool includeUsed) + public async Task> GetTicketsAsync(User user, bool includeUsed) { - return _context.Tickets + return await _context.Tickets .Where(t => t.Owner.Equals(user) && t.IsUsed == includeUsed) .Include(t => t.Purchase) .Include(t => t.UsedOnMenuItem) @@ -57,7 +57,8 @@ public Task> GetTickets(User user, bool includeUsed) ProductId = t.ProductId, ProductName = t.Purchase.ProductName, UsedOnMenuItemName = t.UsedOnMenuItem != null ? t.UsedOnMenuItem.Name : null - }).ToListAsync(); + }) + .ToListAsync(); } public async Task UseTicketAsync(User user, int productId) diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddMenuItemRequest.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddMenuItemRequest.cs new file mode 100644 index 00000000..89477462 --- /dev/null +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddMenuItemRequest.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using CoffeeCard.Models.Entities; + +namespace CoffeeCard.Models.DataTransferObjects.v2.Product +{ + /// + /// Initiate a new menuitem add request. + /// + public class AddMenuItemRequest + { + /// + /// Gets or sets the name of the product. + /// + /// Product Name + /// Latte + [Required] + [MinLength(1, ErrorMessage = "Name cannot be an empty string")] + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddProductRequest.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddProductRequest.cs index 148b75ac..09c54a74 100644 --- a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddProductRequest.cs +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/AddProductRequest.cs @@ -8,69 +8,67 @@ namespace CoffeeCard.Models.DataTransferObjects.v2.Product /// /// Initiate a new product add request. /// - /// - /// { - /// "Name": "Latte", - /// "Price": 25, - /// "NumberOfTickets": 10, - /// "Description": "xxx", - /// "Visible": true, - /// "AllowedUserGroups": ["Manager", "Board"] - /// } - /// public class AddProductRequest { /// /// Gets or sets the price of the product. /// /// Product Price - /// 10 + /// 10 [Required] - [Range(0, int.MaxValue, ErrorMessage = "Price must be a non-negative integer.")] + [Range(0, int.MaxValue, ErrorMessage = "Price must be a non-negative integer")] public int Price { get; set; } /// /// Gets or sets the number of tickets associated with the product. /// - /// Number of tickets associated with a product - /// 5 + /// Number of tickets associated with a product + /// 5 [Required] - [Range(0, int.MaxValue, ErrorMessage = "Number of Tickets must be a non-negative integer.")] + [Range(0, int.MaxValue, ErrorMessage = "Number of Tickets must be a non-negative integer")] public int NumberOfTickets { get; set; } /// /// Gets or sets the name of the product. /// - /// Product Name - /// Latte + /// Product Name + /// Latte [Required] - [MinLength(1, ErrorMessage = "Name cannot be an empty string.")] + [MinLength(1, ErrorMessage = "Name cannot be an empty string")] public string Name { get; set; } /// /// Gets or sets the description of the product. /// - /// Product Description - /// A homemade latte with soy milk + /// Product Description + /// A homemade latte with soy milk [Required] - [MinLength(1, ErrorMessage = "Description cannot be an empty string.")] + [MinLength(1, ErrorMessage = "Description cannot be an empty string")] public string Description { get; set; } /// /// Gets or sets the visibility of the product. Default is true. /// - /// Product Visibility - /// true + /// Product Visibility + /// true + [Required] [DefaultValue(true)] public bool Visible { get; set; } = true; /// /// Gets or sets the user groups that can access the product. /// - /// Product User Groups - /// Manager, Board + /// Product User Groups + /// ["Manager", "Board"] [Required] - public IEnumerable AllowedUserGroups { get; set; } = new List(); + public IEnumerable AllowedUserGroups { get; set; } + /// + /// Gets or sets the menu items that are eligible for the product. + /// + /// Product Menu Item Ids + /// [1, 2] + [Required] + public IEnumerable MenuItemIds { get; set; } } } \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/ChangedProductResponse.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/ChangedProductResponse.cs index 2fac818a..38d54616 100644 --- a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/ChangedProductResponse.cs +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/ChangedProductResponse.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using CoffeeCard.Models.DataTransferObjects.v2.Products; using CoffeeCard.Models.Entities; namespace CoffeeCard.Models.DataTransferObjects.v2.Product @@ -13,7 +14,7 @@ public class ChangedProductResponse /// /// Gets or sets the price of the product. /// - /// 150 + /// 150 [Required] [Range(0, int.MaxValue, ErrorMessage = "Price must be a non-negative integer.")] public int Price { get; set; } @@ -21,8 +22,8 @@ public class ChangedProductResponse /// /// Gets or sets the number of tickets associated with the product. /// - /// Number of Tickets of a Product - /// 5 + /// Number of Tickets of a Product + /// 5 [Required] [Range(0, int.MaxValue, ErrorMessage = "Number of tickets must be a non-negative integer.")] public int NumberOfTickets { get; set; } @@ -30,8 +31,8 @@ public class ChangedProductResponse /// /// Gets or sets the name of the product. /// - /// Product Name - /// Espresso + /// Product Name + /// Espresso [Required] [MinLength(1, ErrorMessage = "Name cannot be an empty string.")] public string Name { get; set; } @@ -39,8 +40,8 @@ public class ChangedProductResponse /// /// Gets or sets the description of the product. /// - /// Product Description - /// A homemade espresso from fresh beans + /// Product Description + /// A homemade espresso from fresh beans [Required] [MinLength(1, ErrorMessage = "Description cannot be an empty string.")] public string Description { get; set; } @@ -48,17 +49,25 @@ public class ChangedProductResponse /// /// Gets or sets the visibility of the product. /// - /// Product Visibility - /// true + /// Product Visibility + /// true [Required] public bool Visible { get; set; } /// /// Gets or sets the user groups that can access the product. /// - /// Product User Groups - /// Manager, Board + /// Product User Groups + /// ["Manager", "Board"] [Required] - public IEnumerable AllowedUserGroups { get; set; } = new List(); + public IEnumerable AllowedUserGroups { get; set; } + + /// + /// Gets or sets the eligibible menu items for the product. + /// + /// Product Menu Items + /// ["Espresso", "Cappuccino"] + [Required] + public IEnumerable MenuItems { get; set; } } } \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateMenuItemRequest.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateMenuItemRequest.cs new file mode 100644 index 00000000..c34728f4 --- /dev/null +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateMenuItemRequest.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using CoffeeCard.Models.Entities; + +namespace CoffeeCard.Models.DataTransferObjects.v2.Product +{ + /// /// + /// Initiate an update product request. + /// + public class UpdateMenuItemRequest + { + + /// + /// Gets or sets the updated name of the product. + /// + /// Product Name + /// Espresso + [Required] + [MinLength(1, ErrorMessage = "Name cannot be an empty string")] + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateProductRequest.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateProductRequest.cs index e0aa10b2..8cea1ecb 100644 --- a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateProductRequest.cs +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Product/UpdateProductRequest.cs @@ -8,32 +8,21 @@ namespace CoffeeCard.Models.DataTransferObjects.v2.Product /// /// /// Initiate an update product request. /// - /// - /// { - /// "Id": 1, - /// "Price": 150, - /// "NumberOfTickets": 10, - /// "Name": "Espresso", - /// "Description": "A coffee made by forcing steam through ground coffee beans.", - /// "Visible": false, - /// "AllowedUserGroups": ["Manager", "Board"] - /// } - /// public class UpdateProductRequest { /// /// Gets or sets the ID of the product to update. /// - /// Product Id - /// 1 + /// Product Id + /// 1 [Required] public int Id { get; set; } /// /// Gets or sets the updated price of the product. /// - /// Product Price - /// 10 + /// Product Price + /// 10 [Required] [Range(0, int.MaxValue, ErrorMessage = "Price must be a non-negative integer.")] public int Price { get; set; } @@ -42,7 +31,7 @@ public class UpdateProductRequest /// Gets or sets the updated number of tickets associated with the product. /// /// Number of Tickets of a Product - /// 5 + /// 5 [Required] [Range(0, int.MaxValue, ErrorMessage = "Number of Tickets must be a non-negative integer.")] public int NumberOfTickets { get; set; } @@ -50,8 +39,8 @@ public class UpdateProductRequest /// /// Gets or sets the updated name of the product. /// - /// Product Name - /// Espresso + /// Product Name + /// Espresso [Required] [MinLength(1, ErrorMessage = "Name cannot be an empty string.")] public string Name { get; set; } @@ -59,8 +48,8 @@ public class UpdateProductRequest /// /// Gets or sets the updated description of the product. /// - /// Product Description - /// A homemade espresso from fresh beans + /// Product Description + /// A homemade espresso from fresh beans [Required] [MinLength(1, ErrorMessage = "Description cannot be an empty string.")] public string Description { get; set; } @@ -68,17 +57,26 @@ public class UpdateProductRequest /// /// Gets or sets the updated visibility of the product. Default is true. /// - /// Product Visibility - /// true + /// Product Visibility + /// true + [Required] [DefaultValue(true)] public bool Visible { get; set; } = true; /// /// Gets or sets the user groups that can access the product. /// - /// Product User Groups - /// Manager, Board + /// Product User Groups + /// ["Manager", "Board"] + [Required] + public IEnumerable AllowedUserGroups { get; set; } + + /// + /// Gets or sets the eligible menu items for the product. + /// + /// Product Menu Item Ids + /// [1, 2] [Required] - public IEnumerable AllowedUserGroups { get; set; } = new List(); + public IEnumerable MenuItemIds { get; set; } } } \ No newline at end of file diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Products/ProductResponse.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Products/ProductResponse.cs index f7d4578d..cf79177b 100644 --- a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Products/ProductResponse.cs +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Products/ProductResponse.cs @@ -94,7 +94,7 @@ public class ProductResponse /// The menu items that this product can be used on. /// /// Menu items - /// Cappuccino, Caffe Latte + /// ["Cappuccino", "Caffe Latte"] /// Optional for backwards compatibility public IEnumerable EligibleMenuItems { get; set; } } diff --git a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Ticket/TicketResponse.cs b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Ticket/TicketResponse.cs index 72c9894b..1ada3574 100644 --- a/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Ticket/TicketResponse.cs +++ b/coffeecard/CoffeeCard.Models/DataTransferObjects/v2/Ticket/TicketResponse.cs @@ -7,15 +7,6 @@ namespace CoffeeCard.Models.DataTransferObjects.v2.Ticket /// /// Representing a ticket for a product /// - /// - /// { - /// "id": 122, - /// "dateCreated": "2022-01-09T21:03:52.2283208Z", - /// "dateUsed": "2022-01-09T21:03:52.2283208Z", - /// "productId": 1, - /// "productName: "Coffee" - /// } - /// public class TicketResponse { /// diff --git a/coffeecard/CoffeeCard.WebApi/Controllers/v2/MenuItemsController.cs b/coffeecard/CoffeeCard.WebApi/Controllers/v2/MenuItemsController.cs new file mode 100644 index 00000000..e942f1c0 --- /dev/null +++ b/coffeecard/CoffeeCard.WebApi/Controllers/v2/MenuItemsController.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using CoffeeCard.Models.DataTransferObjects.v2.Product; +using CoffeeCard.Models.DataTransferObjects.v2.Products; +using CoffeeCard.Models.Entities; +using CoffeeCard.WebApi.Helpers; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using IMenuItemService = CoffeeCard.Library.Services.v2.IMenuItemService; + +namespace CoffeeCard.WebApi.Controllers.v2 +{ + /// + /// Controller for creating, changing, and deactivating a product + /// + [ApiController] + [Authorize] + [ApiVersion("2")] + [Route("api/v{version:apiVersion}/menuitems")] + public class MenuItemsController : ControllerBase + { + private readonly IMenuItemService _menuItemService; + + /// + /// Initializes a new instance of the class. + /// + public MenuItemsController(IMenuItemService menuItemsService) + { + _menuItemService = menuItemsService; + } + + /// + /// Returns a list of all menu items + /// + /// List of all menu items + /// Successful request + /// Invalid credentials + /// User not allowed to access menu items + [HttpGet] + [AuthorizeRoles(UserGroup.Board)] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> GetAllMenuItems() + { + return Ok(await _menuItemService.GetAllMenuItemsAsync()); + } + + /// + /// Adds a menu item + /// + /// Menu item to add + /// Menu item + /// Menu item successfully added + /// Invalid credentials + [HttpPost] + [AuthorizeRoles(UserGroup.Board)] + [ProducesResponseType(typeof(MenuItemResponse), StatusCodes.Status201Created)] + public async Task> AddMenuItem(AddMenuItemRequest menuItem) + { + return CreatedAtAction(nameof(GetAllMenuItems), await _menuItemService.AddMenuItemAsync(menuItem)); + } + + /// + /// Updates a menu item + /// + /// Menu item to update + /// Menu item + /// Menu item successfully updated + /// Invalid credentials + /// Menu item not found + /// + [HttpPut("{id}")] + [AuthorizeRoles(UserGroup.Board)] + [ProducesResponseType(typeof(MenuItemResponse), StatusCodes.Status200OK)] + public async Task> UpdateMenuItem([FromRoute] int id, UpdateMenuItemRequest menuItem) + { + return Ok(await _menuItemService.UpdateMenuItemAsync(id, menuItem)); + } + } +} diff --git a/coffeecard/CoffeeCard.WebApi/Controllers/v2/TicketsController.cs b/coffeecard/CoffeeCard.WebApi/Controllers/v2/TicketsController.cs index be8b5bfc..4ad040b7 100644 --- a/coffeecard/CoffeeCard.WebApi/Controllers/v2/TicketsController.cs +++ b/coffeecard/CoffeeCard.WebApi/Controllers/v2/TicketsController.cs @@ -40,13 +40,13 @@ public TicketsController(ITicketService ticketService, ClaimsUtilities claimsUti /// Successful request /// Invalid credentials [HttpGet] - [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - public async Task>> Get([FromQuery] bool includeUsed) + public async Task>> Get([FromQuery] bool includeUsed) { var user = await _claimsUtilities.ValidateAndReturnUserFromClaimAsync(User.Claims); - return Ok(await _ticketService.GetTickets(user, includeUsed)); + return Ok(await _ticketService.GetTicketsAsync(user, includeUsed)); } /// diff --git a/coffeecard/CoffeeCard.WebApi/Startup.cs b/coffeecard/CoffeeCard.WebApi/Startup.cs index 54a539ca..dc0aaa9e 100644 --- a/coffeecard/CoffeeCard.WebApi/Startup.cs +++ b/coffeecard/CoffeeCard.WebApi/Startup.cs @@ -78,6 +78,7 @@ public void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddSingleton(_environment.ContentRootFileProvider);