Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions exercise.pizzashopapi/Data/DataContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,23 @@ public DataContext()

}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
{
optionsBuilder.UseNpgsql(connectionString);
}

//set primary of order?

//seed data?
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<OrderMenuItem>()
.HasKey(omi => new { omi.OrderId, omi.MenuItemId });

base.OnModelCreating(modelBuilder);
}

public DbSet<Pizza> Pizzas { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<MenuItem> MenuItems { get; set; }
public DbSet<DeliveryDriver> DeliveryDrivers { get; set; }
public DbSet<OrderMenuItem> OrderMenuItems { get; set; }
}
}
92 changes: 82 additions & 10 deletions exercise.pizzashopapi/Data/Seeder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,102 @@ namespace exercise.pizzashopapi.Data
{
public static class Seeder
{
public async static void SeedPizzaShopApi(this WebApplication app)
public async static Task SeedPizzaShopApi(this WebApplication app)
{
using(var db = new DataContext())
using (var scope = app.Services.CreateScope()) // Use a scoped service provider
{
if(!db.Customers.Any())
var db = scope.ServiceProvider.GetRequiredService<DataContext>(); // Get DataContext from DI

Console.WriteLine("🔵 Running database seeder...");

if (!db.Customers.Any())
{
Console.WriteLine("🟢 Seeding Customers...");
db.Customers.AddRange(
new Customer() { Name = "Nigel" },
new Customer() { Name = "Dave" },
new Customer() { Name = "Enock" }
);
await db.SaveChangesAsync();
}

if (!db.Pizzas.Any())
{
db.Add(new Customer() { Name="Nigel" });
db.Add(new Customer() { Name = "Dave" });
Console.WriteLine("🟢 Seeding Pizzas...");
db.Pizzas.AddRange(
new Pizza() { Name = "Cheese & Pineapple", Price = 10.99m },
new Pizza() { Name = "Vegan Cheese Tastic", Price = 12.99m },
new Pizza() { Name = "Pepperoni Classic", Price = 11.99m }
);
await db.SaveChangesAsync();
}
if(!db.Pizzas.Any())

if (!db.MenuItems.Any())
{
db.Add(new Pizza() { Name = "Cheese & Pineapple" });
db.Add(new Pizza() { Name = "Vegan Cheese Tastic" });
Console.WriteLine("🟢 Seeding Menu Items...");
db.MenuItems.AddRange(
new MenuItem() { Name = "Burger", Type = "Food", Price = 8.99m },
new MenuItem() { Name = "Fries", Type = "Food", Price = 3.99m },
new MenuItem() { Name = "Coke", Type = "Drink", Price = 1.99m },
new MenuItem() { Name = "Orange Juice", Type = "Drink", Price = 2.49m },
new MenuItem() { Name = "Chocolate Milkshake", Type = "Drink", Price = 4.99m }
);
await db.SaveChangesAsync();
}

if (!db.DeliveryDrivers.Any())
{
Console.WriteLine("🟢 Seeding Delivery Drivers...");
db.DeliveryDrivers.AddRange(
new DeliveryDriver() { Name = "John" },
new DeliveryDriver() { Name = "Sarah" }
);
await db.SaveChangesAsync();
}

//order data
if(1==1)
if (!db.Orders.Any())
{
Console.WriteLine("🟢 Seeding Orders...");

var dave = db.Customers.First(c => c.Name == "Dave");
var nigel = db.Customers.First(c => c.Name == "Nigel");
var you = db.Customers.First(c => c.Name == "Enock");

var pineapplePizza = db.Pizzas.First(p => p.Name == "Cheese & Pineapple");
var veganPizza = db.Pizzas.First(p => p.Name == "Vegan Cheese Tastic");
var pepperoniPizza = db.Pizzas.First(p => p.Name == "Pepperoni Classic");

var driverJohn = db.DeliveryDrivers.First(d => d.Name == "John");
var driverSarah = db.DeliveryDrivers.First(d => d.Name == "Sarah");

db.Orders.AddRange(
new Order() { CustomerId = dave.Id, PizzaId = pineapplePizza.Id, OrderDate = DateTime.UtcNow, DeliveryDriverId = driverJohn.Id },
new Order() { CustomerId = nigel.Id, PizzaId = veganPizza.Id, OrderDate = DateTime.UtcNow, DeliveryDriverId = driverSarah.Id },
new Order() { CustomerId = you.Id, PizzaId = pepperoniPizza.Id, OrderDate = DateTime.UtcNow, DeliveryDriverId = driverJohn.Id }
);
await db.SaveChangesAsync();
}

if (!db.OrderMenuItems.Any())
{
Console.WriteLine("Seeding Order Menu Items...");

var orders = db.Orders.ToList();
var menuItems = db.MenuItems.ToList();

if (orders.Count > 0 && menuItems.Count > 0)
{
db.OrderMenuItems.AddRange(
new OrderMenuItem() { OrderId = orders[0].Id, MenuItemId = menuItems[0].Id, Quantity = new Random().Next(1, 5) }, // Random quantity between 1-4
new OrderMenuItem() { OrderId = orders[1].Id, MenuItemId = menuItems[1].Id, Quantity = new Random().Next(1, 5) },
new OrderMenuItem() { OrderId = orders[2].Id, MenuItemId = menuItems[2].Id, Quantity = new Random().Next(1, 5) }
);

await db.SaveChangesAsync();
}
}

Console.WriteLine("✅ Database seeding complete.");
}
}
}
Expand Down
149 changes: 146 additions & 3 deletions exercise.pizzashopapi/EndPoints/PizzaShopApi.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using exercise.pizzashopapi.Repository;
using exercise.pizzashopapi.Models;
using exercise.pizzashopapi.Models.DTO;
using exercise.pizzashopapi.Repository;
using exercise.pizzashopapi.Repository.GenericRepositories;
using exercise.pizzashopapi.Repository.SpecificRepositories;
using Microsoft.AspNetCore.Mvc;

namespace exercise.pizzashopapi.EndPoints
Expand All @@ -7,9 +11,148 @@ public static class PizzaShopApi
{
public static void ConfigurePizzaShopApi(this WebApplication app)
{

var api = app.MapGroup("/api");

var orders = api.MapGroup("/orders");
orders.MapGet("/", GetOrders);
orders.MapGet("/customer/{customerId}", GetOrdersByCustomer);
orders.MapPut("/{orderId}/assignDriver/{driverId}", AssignDriverToOrder);
orders.MapGet("/driver/{driverId}", GetOrdersByDriver);

var menu = api.MapGroup("/menu");
menu.MapPost("/addToOrder/{orderId}", AddMenuItemToOrder);
}

[ProducesResponseType(StatusCodes.Status200OK)]
public static async Task<IResult> GetOrders(IOrderRepository repository)
{
var orders = await repository.GetAllOrdersWithDetails();

var orderDTOs = orders.Select(order => new OrderDTO
{
Id = order.Id,
CustomerId = order.CustomerId,
CustomerName = order.Customer?.Name ?? "Unknown",
PizzaId = order.PizzaId,
PizzaName = order.Pizza?.Name ?? "Unknown",
PizzaPrice = order.Pizza?.Price ?? 0,
DeliveryDriverId = order.DeliveryDriverId,
DeliveryDriverName = order.DeliveryDriver?.Name ?? "Not Assigned",
OrderDate = order.OrderDate,

// ✅ Include all menu items in the response
MenuItems = order.OrderMenuItems.Select(omi => new MenuItemDTO
{
Id = omi.MenuItemId,
Name = omi.MenuItem?.Name ?? "Unknown",
Type = omi.MenuItem?.Type ?? "Unknown",
Price = omi.MenuItem?.Price ?? 0,
Quantity = omi.Quantity
}).ToList()

}).ToList();

return TypedResults.Ok(orderDTOs);
}



[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public static async Task<IResult> GetOrdersByCustomer(IOrderRepository repository, int customerId)
{
var orders = await repository.GetOrdersByCustomer(customerId);
if (!orders.Any()) return TypedResults.NotFound($"No orders found for customer with ID {customerId}");

var orderDTOs = orders.Select(order => new OrderDTO
{
Id = order.Id,
CustomerId = order.CustomerId,
CustomerName = order.Customer?.Name ?? "Unknown",
PizzaId = order.PizzaId,
PizzaName = order.Pizza?.Name ?? "Unknown",
PizzaPrice = order.Pizza?.Price ?? 0,
DeliveryDriverId = order.DeliveryDriverId,
DeliveryDriverName = order.DeliveryDriver?.Name ?? "Not Assigned",
OrderDate = order.OrderDate
}).ToList();

return TypedResults.Ok(orderDTOs);
}

[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public static async Task<IResult> AssignDriverToOrder(IOrderRepository repository, int orderId, int driverId)
{
var order = await repository.GetById(orderId);
if (order == null) return TypedResults.NotFound($"Order with ID {orderId} not found");

order.DeliveryDriverId = driverId;
await repository.Update(order);

// Fetch updated order with details
var updatedOrder = await repository.GetOrdersByDriver(driverId);
var orderDTOs = updatedOrder.Select(o => new OrderDTO
{
Id = o.Id,
CustomerId = o.CustomerId,
CustomerName = o.Customer?.Name ?? "Unknown",
PizzaId = o.PizzaId,
PizzaName = o.Pizza?.Name ?? "Unknown",
PizzaPrice = o.Pizza?.Price ?? 0,
DeliveryDriverId = o.DeliveryDriverId,
DeliveryDriverName = o.DeliveryDriver?.Name ?? "Not Assigned",
OrderDate = o.OrderDate
}).FirstOrDefault();

return TypedResults.Ok(orderDTOs);
}

[ProducesResponseType(StatusCodes.Status200OK)]
public static async Task<IResult> GetOrdersByDriver(IOrderRepository repository, int driverId)
{
var orders = await repository.GetOrdersByDriver(driverId);

if (!orders.Any()) return TypedResults.NotFound($"No orders found for driver with ID {driverId}");

var orderDTOs = orders.Select(order => new OrderDTO
{
Id = order.Id,
CustomerId = order.CustomerId,
CustomerName = order.Customer?.Name ?? "Unknown",
PizzaId = order.PizzaId,
PizzaName = order.Pizza?.Name ?? "Unknown",
PizzaPrice = order.Pizza?.Price ?? 0,
DeliveryDriverId = order.DeliveryDriverId,
DeliveryDriverName = order.DeliveryDriver?.Name ?? "Not Assigned",
OrderDate = order.OrderDate
}).ToList();

return TypedResults.Ok(orderDTOs);
}

[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public static async Task<IResult> AddMenuItemToOrder(
IOrderRepository orderRepository,
IOrderMenuItemRepository orderMenuItemRepository,
IRepository<MenuItem> menuRepository,
int orderId,
[FromBody] OrderMenuItemRequest request)
{
var order = await orderRepository.GetById(orderId);
if (order == null) return TypedResults.NotFound($"Order with ID {orderId} not found");

var menuItem = await menuRepository.GetById(request.MenuItemId);
if (menuItem == null) return TypedResults.BadRequest($"Menu item with ID {request.MenuItemId} does not exist");

if (request.Quantity < 1) return TypedResults.BadRequest("Quantity must be at least 1.");

await orderMenuItemRepository.AddMenuItemToOrder(orderId, request.MenuItemId, request.Quantity);

return TypedResults.Ok($"Item '{menuItem.Name}' (x{request.Quantity}) added to order {orderId}");
}


}
}
Loading