diff --git a/README.md b/README.md index 714679a..3f1f0bf 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Pizza Shop needs a very simple ordering system with just just 3 tables, Customer - Write all endpoints in the PizzaShopApi.cs - Use your initiative to create relevant endpoints such as GetOrders, GetOrdersByCustomerId, GetPizzas etc.. -- Use Dependency Injection to instance the DbContext Repository +- Use Dependency Injection to instance the DbContext Retoppository - Inject the IRepository into the EndPoints in the PizzaShopApi - An order consists of 1 customer ordering 1 pizza. - Seed some data for the orders. Dave likes a Cheese & Pineapple pizza and Nigel likes Vegan ones. diff --git a/exercise.pizzashopapi/DTO/CustomerDTO.cs b/exercise.pizzashopapi/DTO/CustomerDTO.cs new file mode 100644 index 0000000..f76cd21 --- /dev/null +++ b/exercise.pizzashopapi/DTO/CustomerDTO.cs @@ -0,0 +1,9 @@ +namespace exercise.pizzashopapi.DTO +{ + public class CustomerDTO + { + public int Id { get; set; } + public string Name { get; set; } + public List Orders { get; set; } = new List(); + } +} diff --git a/exercise.pizzashopapi/DTO/OTDTO.cs b/exercise.pizzashopapi/DTO/OTDTO.cs new file mode 100644 index 0000000..800fe5c --- /dev/null +++ b/exercise.pizzashopapi/DTO/OTDTO.cs @@ -0,0 +1,8 @@ +namespace exercise.pizzashopapi.DTO +{ + public class OTDTO + { + public string name { get; set; } + + } +} diff --git a/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs b/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs new file mode 100644 index 0000000..fa1542b --- /dev/null +++ b/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs @@ -0,0 +1,10 @@ +namespace exercise.pizzashopapi.DTO +{ + public class OrderSimplifiedDTO + { + public string productname { get; set; } + public string productType { get; set; } + + public Listproducttoppings { get; set; } + } +} diff --git a/exercise.pizzashopapi/DTO/OrderToppingsDTO.cs b/exercise.pizzashopapi/DTO/OrderToppingsDTO.cs new file mode 100644 index 0000000..96db120 --- /dev/null +++ b/exercise.pizzashopapi/DTO/OrderToppingsDTO.cs @@ -0,0 +1,8 @@ +namespace exercise.pizzashopapi.DTO +{ + public class OrderToppingsDTO + { + public int orderId { get; set; } + public int toppingId { get; set; } + } +} diff --git a/exercise.pizzashopapi/DTO/ProductDTO.cs b/exercise.pizzashopapi/DTO/ProductDTO.cs new file mode 100644 index 0000000..47b2ea3 --- /dev/null +++ b/exercise.pizzashopapi/DTO/ProductDTO.cs @@ -0,0 +1,9 @@ +namespace exercise.pizzashopapi.DTO +{ + public class ProductDTO + { + public int Id { get; set; } + public int price { get; set; } + public string name { get; set; } + } +} diff --git a/exercise.pizzashopapi/DTO/ToppingsDTO.cs b/exercise.pizzashopapi/DTO/ToppingsDTO.cs new file mode 100644 index 0000000..0b84346 --- /dev/null +++ b/exercise.pizzashopapi/DTO/ToppingsDTO.cs @@ -0,0 +1,9 @@ +namespace exercise.pizzashopapi.DTO +{ + public class ToppingsDTO + { + public int Id { get; set; } + public string name { get; set; } + public int cost { get; set; } + } +} diff --git a/exercise.pizzashopapi/Data/DataContext.cs b/exercise.pizzashopapi/Data/DataContext.cs index 129199e..3cf8e3c 100644 --- a/exercise.pizzashopapi/Data/DataContext.cs +++ b/exercise.pizzashopapi/Data/DataContext.cs @@ -16,13 +16,49 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseNpgsql(connectionString); + //set primary of order? //seed data? + + } - public DbSet Pizzas { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().HasKey(x => x.orderId); + modelBuilder.Entity() + .HasMany(c => c.Orders) + .WithOne(o => o.Customer). + HasForeignKey(o => o.customerId); + + modelBuilder.Entity() + .HasOne(x => x.Product) + .WithMany() + .HasForeignKey(x => x.productId); + + modelBuilder.Entity() + .HasKey(ot => new { ot.OrderId, ot.ToppingId }); + + modelBuilder.Entity() + .HasOne(ot => ot.Order) + .WithMany(o => o.toppings) + .HasForeignKey(ot => ot.OrderId); + + modelBuilder.Entity() + .HasOne(ot => ot.Topping) + .WithMany(t => t.OrderToppings) + .HasForeignKey(ot => ot.ToppingId); + } + + + + + public DbSet Products { get; set; } public DbSet Customers { get; set; } public DbSet Orders { get; set; } + public DbSet Toppings { get; set; } + public DbSet OrderToppings { get; set; } } } diff --git a/exercise.pizzashopapi/Data/Seeder.cs b/exercise.pizzashopapi/Data/Seeder.cs index f87fbef..ba5b01e 100644 --- a/exercise.pizzashopapi/Data/Seeder.cs +++ b/exercise.pizzashopapi/Data/Seeder.cs @@ -4,30 +4,141 @@ namespace exercise.pizzashopapi.Data { public static class Seeder { - public async static void SeedPizzaShopApi(this WebApplication app) + public async static void SeedProductShopApi(this WebApplication app) { using(var db = new DataContext()) { if(!db.Customers.Any()) { - db.Add(new Customer() { Name="Nigel" }); - db.Add(new Customer() { Name = "Dave" }); + db.Add(new Customer() { Id = 1, Name="Nigel" }); + db.Add(new Customer() { Id = 2, Name = "Dave" }); + db.Add(new Customer() { Id = 3, Name = "Axel" }); await db.SaveChangesAsync(); } - if(!db.Pizzas.Any()) + if(!db.Products.Any()) { - db.Add(new Pizza() { Name = "Cheese & Pineapple" }); - db.Add(new Pizza() { Name = "Vegan Cheese Tastic" }); + db.Add(new Product() + { + Id = 1, + Type = "Pizza", + Name = "Cheese & Pineapple", + Price = 10, + + }); + db.Add(new Product() { Id = 2, Type = "Pizza", Name = "Vegan Cheese Tastic" , Price = 20 }); + db.Add(new Product() { Id = 3, Type = "Pizza", Name = "Kebab Pizza", Price = 15 }); + db.Add(new Product() { Id = 4, Type = "Burger", Name = "Whopper Cheese", Price=15 }); await db.SaveChangesAsync(); } + if (!db.Toppings.Any()) + { + db.Add(new Toppings() + { + name = "meat", + id = 1, + cost = 4 + }); + + db.Add(new Toppings() + { + name = "gold", + id = 2, + cost = 40 + }); + + db.Add(new Toppings() + { + name = "truffle", + id = 3, + cost = 15 + }); + db.Add(new Toppings() + { + name = "BBQ sauce", + id = 4, + cost = 2 + }); + + + } + //order data - if(1==1) + if (!db.Orders.Any()) { + db.Add(new Order() + { + productId = 1, + customerId = 2, + orderId = 1, + toppings = new List(){ + new OrderToppings() { + + ToppingId = 1 + }, + new OrderToppings() { + + ToppingId = 2 + } + } + }); + + db.Add(new Order() + { + productId = 3, + customerId = 3, + orderId = 2, + toppings = new List(){ + new OrderToppings() { + + ToppingId = 1 + }, + new OrderToppings() { + + ToppingId = 3 + } + } + }); + + db.Add(new Order() + { + productId = 2, + customerId = 1, + orderId = 3, + toppings = new List(){ + new OrderToppings() { + + ToppingId = 1 + }, + new OrderToppings() { + + ToppingId = 2 + } + } + }); + db.Add(new Order() + { + productId = 4, + customerId = 1, + orderId = 4, + toppings = new List(){ + new OrderToppings() { + + ToppingId = 1 + }, + new OrderToppings() { + + ToppingId = 4 + } + } + }); + await db.SaveChangesAsync(); } + + } } } diff --git a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs b/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs deleted file mode 100644 index f8be2b0..0000000 --- a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs +++ /dev/null @@ -1,15 +0,0 @@ -using exercise.pizzashopapi.Repository; -using Microsoft.AspNetCore.Mvc; - -namespace exercise.pizzashopapi.EndPoints -{ - public static class PizzaShopApi - { - public static void ConfigurePizzaShopApi(this WebApplication app) - { - - } - - - } -} diff --git a/exercise.pizzashopapi/EndPoints/ProductShopApi.cs b/exercise.pizzashopapi/EndPoints/ProductShopApi.cs new file mode 100644 index 0000000..a7a1502 --- /dev/null +++ b/exercise.pizzashopapi/EndPoints/ProductShopApi.cs @@ -0,0 +1,79 @@ +using exercise.pizzashopapi.DTO; +using exercise.pizzashopapi.Models; +using exercise.pizzashopapi.Repository; +using Microsoft.AspNetCore.Mvc; + +namespace exercise.pizzashopapi.EndPoints +{ + public static class ProductShopApi + { + public static void ConfigureProductShopApi(this WebApplication app) + { + var restaurant = app.MapGroup("/restaurant"); + restaurant.MapGet("/products", GetProducts); + restaurant.MapGet("/customers", GetCustomers); + } + + public static async Task GetProducts(IRepository repo) + { + IEnumerableproducts = await repo.GetProducts(); + return TypedResults.Ok(products); + } + + public static async Task GetCustomers(IRepository repo) + { + + ListDTOList = new List (); + + foreach (Customer customer in await repo.GetCustomers()) + { + CustomerDTO dto = new CustomerDTO(); + dto.Name = customer.Name; + dto.Id = customer.Id; + foreach (Order order in await repo.GetOrdersByCustomer(customer.Id)) + { + OrderSimplifiedDTO orderDTO = new OrderSimplifiedDTO(); + Product product = await repo.GetProductById(order.productId); + + orderDTO.productname = product.Name; + orderDTO.productType = product.Type; + orderDTO.producttoppings = new List(); + + if (order.toppings != null) + { + foreach (OrderToppings toppings in order.toppings.ToList()) + { + Toppings top = await repo.GetToppingsById(toppings.ToppingId); + OTDTO OTD = new OTDTO(); + OTD.name = top.name; + orderDTO.producttoppings.Add(OTD); + } + + + + + dto.Orders.Add(orderDTO); + } + } + DTOList.Add(dto); + + } + + + + return TypedResults.Ok(DTOList); + } + public static async Task GetOrders(IRepository repo) + { + IEnumerable orders = await repo.GetOrders(); + return TypedResults.Ok(orders); + } + + public static async Task GetOrderByCustomer(IRepository repo, int id) + { + IEnumerable orders = await repo.GetOrdersByCustomer(id); + return TypedResults.Ok(orders); + } + + } +} diff --git a/exercise.pizzashopapi/Models/Customer.cs b/exercise.pizzashopapi/Models/Customer.cs index 2ca83bd..63c87bf 100644 --- a/exercise.pizzashopapi/Models/Customer.cs +++ b/exercise.pizzashopapi/Models/Customer.cs @@ -6,5 +6,6 @@ public class Customer { public int Id { get; set; } public string Name { get; set; } + public List Orders { get; set; } } } diff --git a/exercise.pizzashopapi/Models/Order.cs b/exercise.pizzashopapi/Models/Order.cs index fbe6113..36f6fe8 100644 --- a/exercise.pizzashopapi/Models/Order.cs +++ b/exercise.pizzashopapi/Models/Order.cs @@ -4,7 +4,15 @@ namespace exercise.pizzashopapi.Models { public class Order { + public int orderId { get; set; } + public int customerId { get; set; } + public int productId { get; set; } + + public List toppings { get; set; } + public Customer Customer { get; set; } + + public Product Product { get; set; } } } diff --git a/exercise.pizzashopapi/Models/OrderToppings.cs b/exercise.pizzashopapi/Models/OrderToppings.cs new file mode 100644 index 0000000..f7f45f1 --- /dev/null +++ b/exercise.pizzashopapi/Models/OrderToppings.cs @@ -0,0 +1,11 @@ +namespace exercise.pizzashopapi.Models +{ + public class OrderToppings + { + public int OrderId { get; set; } + public Order Order { get; set; } + + public int ToppingId { get; set; } + public Toppings Topping { get; set; } + } +} diff --git a/exercise.pizzashopapi/Models/Pizza.cs b/exercise.pizzashopapi/Models/Product.cs similarity index 78% rename from exercise.pizzashopapi/Models/Pizza.cs rename to exercise.pizzashopapi/Models/Product.cs index 5c085ec..134a2c7 100644 --- a/exercise.pizzashopapi/Models/Pizza.cs +++ b/exercise.pizzashopapi/Models/Product.cs @@ -3,10 +3,12 @@ namespace exercise.pizzashopapi.Models { - public class Pizza + public class Product { public int Id { get; set; } + public string Type { get; set; } public string Name { get; set; } public decimal Price { get; set; } + } } \ No newline at end of file diff --git a/exercise.pizzashopapi/Models/Toppings.cs b/exercise.pizzashopapi/Models/Toppings.cs new file mode 100644 index 0000000..51e2c0d --- /dev/null +++ b/exercise.pizzashopapi/Models/Toppings.cs @@ -0,0 +1,10 @@ +namespace exercise.pizzashopapi.Models +{ + public class Toppings + { + public int id { get; set; } + public string name { get; set; } + public int cost {get;set;} + public List OrderToppings { get; set; } + } +} diff --git a/exercise.pizzashopapi/Program.cs b/exercise.pizzashopapi/Program.cs index c04a440..32107be 100644 --- a/exercise.pizzashopapi/Program.cs +++ b/exercise.pizzashopapi/Program.cs @@ -28,8 +28,8 @@ app.MapControllers(); -app.ConfigurePizzaShopApi(); +app.ConfigureProductShopApi(); -app.SeedPizzaShopApi(); +app.SeedProductShopApi(); app.Run(); diff --git a/exercise.pizzashopapi/Repository/IRepository.cs b/exercise.pizzashopapi/Repository/IRepository.cs index b114ea8..79dd344 100644 --- a/exercise.pizzashopapi/Repository/IRepository.cs +++ b/exercise.pizzashopapi/Repository/IRepository.cs @@ -5,7 +5,11 @@ namespace exercise.pizzashopapi.Repository public interface IRepository { Task> GetOrdersByCustomer(int id); - - + Task> GetProducts(); + Task> GetCustomers(); + Task> GetOrders(); + TaskGetOrderById(int id); + Task GetProductById(int id); + Task GetToppingsById(int id); } } diff --git a/exercise.pizzashopapi/Repository/Repository.cs b/exercise.pizzashopapi/Repository/Repository.cs index e109fce..c77a973 100644 --- a/exercise.pizzashopapi/Repository/Repository.cs +++ b/exercise.pizzashopapi/Repository/Repository.cs @@ -1,14 +1,71 @@ using exercise.pizzashopapi.Data; using exercise.pizzashopapi.Models; +using Microsoft.EntityFrameworkCore; namespace exercise.pizzashopapi.Repository { public class Repository : IRepository { private DataContext _db; - public Task> GetOrdersByCustomer(int id) + + public Repository(DataContext db) + { + _db = db; + } + + public async Task> GetOrdersByCustomer(int id) + { + IEnumerableorders = await _db.Orders.Where(x => x.customerId == id).Include(o => o.toppings).ToListAsync(); + return orders; + } + + public async Task> GetProducts() + { + return await _db.Products.ToListAsync(); + } + + public async Task> GetCustomers() + { + var customers = await _db.Customers.Include(c => c.Orders).ToListAsync(); + return customers; + } + + public async Task> GetOrders() + { + return await _db.Orders.ToListAsync(); + } + + public async Task GetOrderById(int id) + { + return _db.Orders.Where(x => x.orderId == id).FirstOrDefault()!; + } + + public async TaskAddTopping(Toppings topping) + { + _db.Toppings.Add(topping); + _db.SaveChanges(); + return topping; + } + + public async TaskAddToppingToOrder(Toppings topping, OrderToppings top) + { + top.Topping = topping; + top.ToppingId = topping.id; + _db.Toppings.Add(topping); + _db.OrderToppings.Add(top); + _db.SaveChanges(); + + return top; + } + + public async Task GetProductById(int id) + { + return _db.Products.Where(x => x.Id == id).FirstOrDefault()!; + } + + public async Task GetToppingsById(int id) { - throw new NotImplementedException(); + return _db.Toppings.Where(x => x.id == id).FirstOrDefault(); } } }