diff --git a/MyShop/MyShop.Core/Contracts/IBasketService.cs b/MyShop/MyShop.Core/Contracts/IBasketService.cs index 21a7a40..bd3b7ea 100644 --- a/MyShop/MyShop.Core/Contracts/IBasketService.cs +++ b/MyShop/MyShop.Core/Contracts/IBasketService.cs @@ -14,6 +14,7 @@ public interface IBasketService void RemoveFromBasket(HttpContextBase httpContext, string itemId); List GetBasketItems(HttpContextBase httpContext); BasketSummaryViewModel GetBasketSummary(HttpContextBase httpContext); + void ClearBasket(HttpContextBase httpContext); } } diff --git a/MyShop/MyShop.Core/Contracts/IOrderService.cs b/MyShop/MyShop.Core/Contracts/IOrderService.cs new file mode 100644 index 0000000..d98847a --- /dev/null +++ b/MyShop/MyShop.Core/Contracts/IOrderService.cs @@ -0,0 +1,18 @@ +using MyShop.Core.Models; +using MyShop.Core.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyShop.Core.Contracts +{ + public interface IOrderService + { + void CreateOrder(Order baseOrder, List basketItems); + List GetOrderList(); + Order GetOrder(string Id); + void UpdateOrder(Order updatedOrder); + } +} diff --git a/MyShop/MyShop.Core/Models/Order.cs b/MyShop/MyShop.Core/Models/Order.cs new file mode 100644 index 0000000..3e6fb3d --- /dev/null +++ b/MyShop/MyShop.Core/Models/Order.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyShop.Core.Models +{ + public class Order : BaseEntity + { + public Order() { + this.OrderItems = new List(); + } + + public string FirstName { get; set; } + public string Surname { get; set; } + public string Email { get; set; } + public string Street { get; set; } + public string City { get; set; } + public string State { get; set; } + public string ZipCode { get; set; } + public string OrderStatus { get; set; } + public virtual ICollection OrderItems { get; set; } + } +} diff --git a/MyShop/MyShop.Core/Models/OrderItem.cs b/MyShop/MyShop.Core/Models/OrderItem.cs new file mode 100644 index 0000000..e0ae2a4 --- /dev/null +++ b/MyShop/MyShop.Core/Models/OrderItem.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyShop.Core.Models +{ + public class OrderItem : BaseEntity + { + public string OrderId { get; set; } + public string ProductId { get; set; } + public string ProductName { get; set; } + public decimal Price { get; set; } + public string Image { get; set; } + public int Quanity { get; set; } + } +} diff --git a/MyShop/MyShop.Core/MyShop.Core.csproj b/MyShop/MyShop.Core/MyShop.Core.csproj index d710ecc..26b77f3 100644 --- a/MyShop/MyShop.Core/MyShop.Core.csproj +++ b/MyShop/MyShop.Core/MyShop.Core.csproj @@ -43,11 +43,14 @@ + + + diff --git a/MyShop/MyShop.DataAccess.SQL/DataContext.cs b/MyShop/MyShop.DataAccess.SQL/DataContext.cs index b269b5b..b26d07c 100644 --- a/MyShop/MyShop.DataAccess.SQL/DataContext.cs +++ b/MyShop/MyShop.DataAccess.SQL/DataContext.cs @@ -20,5 +20,7 @@ public DataContext() public DbSet Baskets { get; set; } public DbSet BasketItems { get; set; } public DbSet Customers { get; set; } + public DbSet Orders { get; set; } + public DbSet OrderItems { get; set; } } } diff --git a/MyShop/MyShop.DataAccess.SQL/Migrations/201801101446455_AddedOrders.Designer.cs b/MyShop/MyShop.DataAccess.SQL/Migrations/201801101446455_AddedOrders.Designer.cs new file mode 100644 index 0000000..9140edf --- /dev/null +++ b/MyShop/MyShop.DataAccess.SQL/Migrations/201801101446455_AddedOrders.Designer.cs @@ -0,0 +1,29 @@ +// +namespace MyShop.DataAccess.SQL.Migrations +{ + using System.CodeDom.Compiler; + using System.Data.Entity.Migrations; + using System.Data.Entity.Migrations.Infrastructure; + using System.Resources; + + [GeneratedCode("EntityFramework.Migrations", "6.2.0-61023")] + public sealed partial class AddedOrders : IMigrationMetadata + { + private readonly ResourceManager Resources = new ResourceManager(typeof(AddedOrders)); + + string IMigrationMetadata.Id + { + get { return "201801101446455_AddedOrders"; } + } + + string IMigrationMetadata.Source + { + get { return null; } + } + + string IMigrationMetadata.Target + { + get { return Resources.GetString("Target"); } + } + } +} diff --git a/MyShop/MyShop.DataAccess.SQL/Migrations/201801101446455_AddedOrders.cs b/MyShop/MyShop.DataAccess.SQL/Migrations/201801101446455_AddedOrders.cs new file mode 100644 index 0000000..e5cf09d --- /dev/null +++ b/MyShop/MyShop.DataAccess.SQL/Migrations/201801101446455_AddedOrders.cs @@ -0,0 +1,54 @@ +namespace MyShop.DataAccess.SQL.Migrations +{ + using System; + using System.Data.Entity.Migrations; + + public partial class AddedOrders : DbMigration + { + public override void Up() + { + CreateTable( + "dbo.OrderItems", + c => new + { + Id = c.String(nullable: false, maxLength: 128), + OrderId = c.String(maxLength: 128), + ProductId = c.String(), + ProductName = c.String(), + Price = c.Decimal(nullable: false, precision: 18, scale: 2), + Image = c.String(), + Quanity = c.Int(nullable: false), + CreatedAt = c.DateTimeOffset(nullable: false, precision: 7), + }) + .PrimaryKey(t => t.Id) + .ForeignKey("dbo.Orders", t => t.OrderId) + .Index(t => t.OrderId); + + CreateTable( + "dbo.Orders", + c => new + { + Id = c.String(nullable: false, maxLength: 128), + FirstName = c.String(), + Surname = c.String(), + Email = c.String(), + Street = c.String(), + City = c.String(), + State = c.String(), + ZipCode = c.String(), + OrderStatus = c.String(), + CreatedAt = c.DateTimeOffset(nullable: false, precision: 7), + }) + .PrimaryKey(t => t.Id); + + } + + public override void Down() + { + DropForeignKey("dbo.OrderItems", "OrderId", "dbo.Orders"); + DropIndex("dbo.OrderItems", new[] { "OrderId" }); + DropTable("dbo.Orders"); + DropTable("dbo.OrderItems"); + } + } +} diff --git a/MyShop/MyShop.DataAccess.SQL/Migrations/201801101446455_AddedOrders.resx b/MyShop/MyShop.DataAccess.SQL/Migrations/201801101446455_AddedOrders.resx new file mode 100644 index 0000000..683873b --- /dev/null +++ b/MyShop/MyShop.DataAccess.SQL/Migrations/201801101446455_AddedOrders.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + H4sIAAAAAAAEAO1cW2/bNhR+H7D/IOhpG1LLSR/WBXaL1GkGY7k1TophLwUj0Y4widJEKrAx7JftYT9pf2FHN4oSdbVlxc6MvsQU+R2S50rynP779z+jD0vbUp6xR02HjNXjwVBVMNEdwySLseqz+Zt36of3334z+mTYS+VL0u9t0A9GEjpWnxhzTzWN6k/YRnRgm7rnUGfOBrpja8hwtJPh8Cft+FjDAKEClqKM7nzCTBuHP+DnxCE6dpmPrCvHwBaN2+HLLERVrpGNqYt0PFavVrMnxx2cI4bOdB1TOph9vlSVM8tEMJkZtuaqgghxGGIw1dMHimfMc8hi5kIDsu5XLoZ+c2RRHC/hNO3edDXDk2A1WjowgdJ9yhy7JeDx23h7tPzwtTZZ5dsHG/gJNpqtglWHmzhWPyL6O2ZThm1VyZM7nVhe0JXv8sTx8CDiySAdeKQIn4+4VIDwBP+OlIlvMd/DY4J95iHrSLn1Hy1T/wWv7p3fMRkT37LEScI04VumAZpuPcfFHlvd4Xk89amhKlp2nJYfyIcJY6IlgRiAUKvKFVpeYrJgTyDuJ+9U5cJcYiNpieXigZigAzCIeT78vIYJo0cL8+9aJc14p7qgXE0Ifhq+Xk0J/uyA0mcfEZCjhM6UsLcnrfdl4mHEsHHGEhhQYnwPduBmPqeY1eCNtFSWG0j4WtJ9kOxtchDwrtGzuQi5UawzYF2oqtxhK+xDn0w3sukxf75mul14jn3nWHy0+PXrzPE9HSZw75R2uUfeIpj0WlI2CaULey3lLBl2kLRqSQO/7fVg1y5Mj7Lgz61TukQ9EfpkI9PaOhUAxphtncxEcDpbXAtYsa1T+c10J9B5+1vWj5e98QzQ0PZhJB93sIDVfIw26jUFkTGlXqzgrWfqnMo51k0bgVG89eCv+KgLezfTUcCO9pHs1EaL7a9hn4LuUFrXMQUHM7ArEcrM98ghQDkEKNumE6p9sCSf7ngwVHVg5XFM8Xk1/PxV7JSeVvPfpLOq1GGjk2rsdiew8oXjrVoa6dzog7muETi+yzst2W2FZz2hOQhLNQ9r3PrJsAM5OcdU90w3ek3Y66C7N9XqJ7rfjgKfUeroZqihmZvVzM1pdl6fiKHUX6NGm5FexcKOgPaaLugrTGOsDgeDY2nJldCJU5Ogo1uFLPwPEjaoO/YwCR71JuB6wYCYhMm2wSS66SKrdoW5kQ3tSsAITiP/5Ry7mBgwxdo9aEI8fVWSp8Ap5Yxe3R6NNEFeqsVICmjKOF0e3aR8jk+LrSSoNCjK425RfMrW1oPwlC2/CWl+ldSD5ERmCcYwGIG9xAshhoI2vCwKJR4ojqMJGtvOvBAEmDPMih6LUjtYYEQkaSoCKgepBUiec4og0heiGhDxlCChCCLdBKYUonZ4NtA3cRGSdJRohlkBJUEIYpXnU/b1T+hY/kaYl/dGvo6vQhAQSXMauTYJKZ57PjjNLrrBhsjHS3k7qi12M5stLCARr4qdKDXReZi225BEO9yspBlCWpQilKQSaSW5RKMr5LoQyAm5RXGLMosSiyZvZu3TbewIQ9NpQdYNny2nxBwPQsvcVyANMw3v+QIz+YiCWG9i2FI30YiW6F1CSbaTMtcShUzGBH9H4wpzrES7KjudGOQC1mcHTitYKi4Uf3mwEuR5IQt5BUeyiWP5Nin3oOWj03hJxCiPosqRhBcSEUpobo7F7/RFJN7YHEc4PYhIQrOMNdJyXJKiAUkocgqal7MWUtidBK4tfX1J3h7xJo1fNucOj3fa86d86HY4lGSXiAhJW3MU4WlGBBKam2Ol6SEiVNraHCl+XhFh4qbmGMnjiQiStLXQA8nQTVpaufjhIzuNsKk5Bn/WEFF446vU6sqYr61apweQ9npdMXY7is1PuiJE6fG3HKdLl59JeyhAa6vg8S1rFilsao4RX3FmNjpqOoQySo1idaZU6ypUX8rUpX/jyQUZW540HrzbS3u3zKO8ZDyTD69SqeWLr831O39R1l7TaxG2dHbhV3sZtpVc+L0uCeiQ8eszvC9Gy3a9rUnPvCyLQJkP/cY13YlvFxHSzqmAdI+a78Kp8/vU3L3pKL7DrC/UlC41oy5BPoDzbBrBheZsReFsEKrQYPaHNbFMWG/a4QpCyTmmLEoGUU+Gxye5Qs/dKbrUKDWsgjvg4srLLMd6yGkhz8jTn5AnZ7VsWNuYAkuvelNi4OVY/TMceapMf02eSIwjJYwqTpWh8lfVjNZKX09m9J2Nlt+3RculXJukQYpgXV6HAT+DamcnzusQ8mF+7LjmcX/l6kV2rfjaca/2LVsnt5HsS5nmG6Hl6902AsukjG+ElE0L3whKTP3ecE5CevdGSLkU7s2W9xIaWXJhuFcqmSvcauUh47G76yALarg2xBNSRo2t1mn9LwODggvDvVKmbp1SrsTp4JMq5rSLPqmgdGj/fFzlzd5eKWc+I39vebHHPCiyjVIVSTtOFJSM7LCP71QIuwsY+hDnDoo9uqrsiDKU+y/l6K9uoyQFYs8LNbopy5C430shRm9lF41Z//KFFnIqcckLmHwpXV1JEd3egxl7dIDTkamqymkvJlRRaVFOoB48LbWoqMIoIiDUbzQt0qiu0SgiUpHyXkilvISjFL0eWSrdqC/uKKJWUCXSjHBVCUgFIRm/3wKRghqOBsUgopzk0993s/hDrtGor/SQVlleq9RJaYf89AjmU/ifZMF4U3ORQgT/ryzBesZw8j5TMncSA56bUdIlF9FdYYaM4LXfY+Yc6Qw+B8/+YXXwF2T54Z3AIzam5MZnrs9gydh+tDKvzoEfqKIf1q9k5zy6CSNx2sUSYJpmEIfekI++aRl83hcFMWcJROBgfsbQHvES/BVYghVHunZIQ6B4+7hfvMe2awEYvSEz9IzXmdsDxZd4gfRV8oJcDlLPiOy2j85NtPCQTWOMdDz8BBk27OX7/wBaThdHUFkAAA== + + + dbo + + \ No newline at end of file diff --git a/MyShop/MyShop.DataAccess.SQL/MyShop.DataAccess.SQL.csproj b/MyShop/MyShop.DataAccess.SQL/MyShop.DataAccess.SQL.csproj index 56b077e..eddc306 100644 --- a/MyShop/MyShop.DataAccess.SQL/MyShop.DataAccess.SQL.csproj +++ b/MyShop/MyShop.DataAccess.SQL/MyShop.DataAccess.SQL.csproj @@ -60,6 +60,10 @@ 201801032024566_AddCustomer.cs + + + 201801101446455_AddedOrders.cs + @@ -84,6 +88,9 @@ 201801032024566_AddCustomer.cs + + 201801101446455_AddedOrders.cs + \ No newline at end of file diff --git a/MyShop/MyShop.Services/BasketService.cs b/MyShop/MyShop.Services/BasketService.cs index 64c7651..6c8bb60 100644 --- a/MyShop/MyShop.Services/BasketService.cs +++ b/MyShop/MyShop.Services/BasketService.cs @@ -143,5 +143,11 @@ join p in productContext.Collection() on item.ProductId equals p.Id return model; } } + + public void ClearBasket(HttpContextBase httpContext) { + Basket basket = GetBasket(httpContext, false); + basket.BasketItems.Clear(); + basketContext.Commit(); + } } } diff --git a/MyShop/MyShop.Services/MyShop.Services.csproj b/MyShop/MyShop.Services/MyShop.Services.csproj index 3948ccc..9708073 100644 --- a/MyShop/MyShop.Services/MyShop.Services.csproj +++ b/MyShop/MyShop.Services/MyShop.Services.csproj @@ -42,6 +42,7 @@ + diff --git a/MyShop/MyShop.Services/OrderService.cs b/MyShop/MyShop.Services/OrderService.cs new file mode 100644 index 0000000..6b43726 --- /dev/null +++ b/MyShop/MyShop.Services/OrderService.cs @@ -0,0 +1,49 @@ +using MyShop.Core.Contracts; +using MyShop.Core.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MyShop.Core.ViewModels; + +namespace MyShop.Services +{ + public class OrderService : IOrderService + { + IRepository orderContext; + public OrderService(IRepository OrderContext) { + this.orderContext = OrderContext; + } + + public void CreateOrder(Order baseOrder, List basketItems) + { + foreach (var item in basketItems) { + baseOrder.OrderItems.Add(new OrderItem() + { + ProductId = item.Id, + Image = item.Image, + Price = item.Price, + ProductName = item.ProductName, + Quanity = item.Quanity + }); + } + + orderContext.Insert(baseOrder); + orderContext.Commit(); + } + + public List GetOrderList() { + return orderContext.Collection().ToList(); + } + + public Order GetOrder(string Id) { + return orderContext.Find(Id); + } + + public void UpdateOrder(Order updatedOrder) { + orderContext.Update(updatedOrder); + orderContext.Commit(); + } + } +} diff --git a/MyShop/MyShop.WebUI.Tests/Controllers/BasketControllerTests.cs b/MyShop/MyShop.WebUI.Tests/Controllers/BasketControllerTests.cs index 435b879..91016c7 100644 --- a/MyShop/MyShop.WebUI.Tests/Controllers/BasketControllerTests.cs +++ b/MyShop/MyShop.WebUI.Tests/Controllers/BasketControllerTests.cs @@ -8,6 +8,7 @@ using MyShop.WebUI.Controllers; using System.Web.Mvc; using MyShop.Core.ViewModels; +using System.Security.Principal; namespace MyShop.WebUI.Tests.Controllers { @@ -20,12 +21,15 @@ public void CanAddBasketItem() //setup IRepository baskets = new MockContext(); IRepository products = new MockContext(); + IRepository orders = new MockContext(); + IRepository customers = new MockContext(); var httpContext = new MockHttpContext(); IBasketService basketService = new BasketService(products, baskets); - var controller = new BasketController(basketService); + IOrderService orderService = new OrderService(orders); + var controller = new BasketController(basketService, orderService, customers); controller.ControllerContext = new System.Web.Mvc.ControllerContext(httpContext, new System.Web.Routing.RouteData(), controller); //Act @@ -45,6 +49,8 @@ public void CanAddBasketItem() public void CanGetSummaryViewModel() { IRepository baskets = new MockContext(); IRepository products = new MockContext(); + IRepository orders = new MockContext(); + IRepository customers = new MockContext(); products.Insert(new Product() { Id = "1", Price = 10.00m }); products.Insert(new Product() { Id = "2", Price = 5.00m }); @@ -55,9 +61,9 @@ public void CanGetSummaryViewModel() { baskets.Insert(basket); IBasketService basketService = new BasketService(products, baskets); + IOrderService orderService = new OrderService(orders); + var controller = new BasketController(basketService, orderService, customers); - - var controller = new BasketController(basketService); var httpContext = new MockHttpContext(); httpContext.Request.Cookies.Add(new System.Web.HttpCookie("eCommerceBasket") { Value = basket.Id }); controller.ControllerContext = new System.Web.Mvc.ControllerContext(httpContext, new System.Web.Routing.RouteData(), controller); @@ -71,5 +77,52 @@ public void CanGetSummaryViewModel() { } + + [TestMethod] + public void CanCheckoutAndCreateOrder() { + IRepository customers = new MockContext(); + IRepository products = new MockContext(); + products.Insert(new Product() { Id = "1", Price = 10.00m }); + products.Insert(new Product() { Id = "2", Price = 5.00m }); + + IRepository baskets = new MockContext(); + Basket basket = new Basket(); + basket.BasketItems.Add(new BasketItem() { ProductId = "1", Quanity = 2, BasketId = basket.Id }); + basket.BasketItems.Add(new BasketItem() { ProductId = "1", Quanity = 1, BasketId = basket.Id }); + + baskets.Insert(basket); + + IBasketService basketService = new BasketService(products, baskets); + + IRepository orders = new MockContext(); + IOrderService orderService = new OrderService(orders); + + customers.Insert(new Customer() { Id = "1", Email = "brett.hargreaves@gmail.com", ZipCode = "90210" }); + + IPrincipal FakeUser = new GenericPrincipal(new GenericIdentity("brett.hargreaves@gmail.com", "Forms"), null); + + + var controller = new BasketController(basketService, orderService, customers); + var httpContext = new MockHttpContext(); + httpContext.User = FakeUser; + httpContext.Request.Cookies.Add(new System.Web.HttpCookie("eCommerceBasket") + { + Value = basket.Id + }); + + controller.ControllerContext = new ControllerContext(httpContext, new System.Web.Routing.RouteData(), controller); + + //Act + Order order = new Order(); + controller.Checkout(order); + + //assert + Assert.AreEqual(2, order.OrderItems.Count); + Assert.AreEqual(0, basket.BasketItems.Count); + + Order orderInRep = orders.Find(order.Id); + Assert.AreEqual(2, orderInRep.OrderItems.Count); + + } } } diff --git a/MyShop/MyShop.WebUI.Tests/Mocks/MockHttpContext.cs b/MyShop/MyShop.WebUI.Tests/Mocks/MockHttpContext.cs index 6c0d3c2..694b847 100644 --- a/MyShop/MyShop.WebUI.Tests/Mocks/MockHttpContext.cs +++ b/MyShop/MyShop.WebUI.Tests/Mocks/MockHttpContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Principal; using System.Text; using System.Threading.Tasks; using System.Web; @@ -12,6 +13,7 @@ public class MockHttpContext : HttpContextBase private MockRequest request; private MockResponse response; private HttpCookieCollection cookies; + private IPrincipal FakeUser; public MockHttpContext() { cookies = new HttpCookieCollection(); @@ -19,6 +21,16 @@ public MockHttpContext() { this.response = new MockResponse(cookies); } + public override IPrincipal User { + get { + return this.FakeUser; + } + set { + this.FakeUser = value; + } + + } + public override HttpRequestBase Request { get { return request; diff --git a/MyShop/MyShop.WebUI/App_Start/UnityConfig.cs b/MyShop/MyShop.WebUI/App_Start/UnityConfig.cs index 0bc1f73..548fed8 100644 --- a/MyShop/MyShop.WebUI/App_Start/UnityConfig.cs +++ b/MyShop/MyShop.WebUI/App_Start/UnityConfig.cs @@ -52,7 +52,10 @@ public static void RegisterTypes(IUnityContainer container) container.RegisterType, SQLRepository>(); container.RegisterType, SQLRepository>(); container.RegisterType, SQLRepository>(); + container.RegisterType, SQLRepository>(); + container.RegisterType(); + container.RegisterType(); } } } \ No newline at end of file diff --git a/MyShop/MyShop.WebUI/Controllers/AdminController.cs b/MyShop/MyShop.WebUI/Controllers/AdminController.cs new file mode 100644 index 0000000..012445c --- /dev/null +++ b/MyShop/MyShop.WebUI/Controllers/AdminController.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; + +namespace MyShop.WebUI.Controllers +{ + [Authorize(Roles ="Admin")] + public class AdminController : Controller + { + // GET: Admin + public ActionResult Index() + { + return View(); + } + } +} \ No newline at end of file diff --git a/MyShop/MyShop.WebUI/Controllers/BasketController.cs b/MyShop/MyShop.WebUI/Controllers/BasketController.cs index 6dc4347..69898ff 100644 --- a/MyShop/MyShop.WebUI/Controllers/BasketController.cs +++ b/MyShop/MyShop.WebUI/Controllers/BasketController.cs @@ -1,4 +1,5 @@ using MyShop.Core.Contracts; +using MyShop.Core.Models; using System; using System.Collections.Generic; using System.Linq; @@ -9,10 +10,14 @@ namespace MyShop.WebUI.Controllers { public class BasketController : Controller { + IRepository customers; IBasketService basketService; + IOrderService orderService; - public BasketController(IBasketService BasketService) { + public BasketController(IBasketService BasketService, IOrderService OrderService, IRepository Customers) { this.basketService = BasketService; + this.orderService = OrderService; + this.customers = Customers; } // GET: Basket2 public ActionResult Index() @@ -40,5 +45,52 @@ public PartialViewResult BasketSummary() { return PartialView(basketSummary); } + + [Authorize] + public ActionResult Checkout() { + Customer customer = customers.Collection().FirstOrDefault(c => c.Email == User.Identity.Name); + + if (customer != null) + { + Order order = new Order() + { + Email = customer.Email, + City = customer.City, + State = customer.State, + Street = customer.Street, + FirstName = customer.FirstName, + Surname = customer.LastName, + ZipCode = customer.ZipCode + }; + + return View(order); + } + else { + return RedirectToAction("Error"); + } + + } + + [HttpPost] + [Authorize] + public ActionResult Checkout(Order order) { + + var basketItems = basketService.GetBasketItems(this.HttpContext); + order.OrderStatus = "Order Created"; + order.Email = User.Identity.Name; + + //process payment + + order.OrderStatus = "Payment Processed"; + orderService.CreateOrder(order, basketItems); + basketService.ClearBasket(this.HttpContext); + + return RedirectToAction("Thankyou", new { OrderId = order.Id }); + } + + public ActionResult ThankYou(string OrderId) { + ViewBag.OrderId = OrderId; + return View(); + } } } \ No newline at end of file diff --git a/MyShop/MyShop.WebUI/Controllers/ManageController.cs b/MyShop/MyShop.WebUI/Controllers/ManageController.cs index 76266fa..8d14d87 100644 --- a/MyShop/MyShop.WebUI/Controllers/ManageController.cs +++ b/MyShop/MyShop.WebUI/Controllers/ManageController.cs @@ -18,6 +18,7 @@ public class ManageController : Controller public ManageController() { + } public ApplicationSignInManager SignInManager diff --git a/MyShop/MyShop.WebUI/Controllers/OrderManagerController.cs b/MyShop/MyShop.WebUI/Controllers/OrderManagerController.cs new file mode 100644 index 0000000..42de4e9 --- /dev/null +++ b/MyShop/MyShop.WebUI/Controllers/OrderManagerController.cs @@ -0,0 +1,48 @@ +using MyShop.Core.Contracts; +using MyShop.Core.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; + +namespace MyShop.WebUI.Controllers +{ + [Authorize(Roles = "Admin")] + public class OrderManagerController : Controller + { + IOrderService orderService; + + public OrderManagerController(IOrderService OrderService) { + this.orderService = OrderService; + } + // GET: OrderManager + public ActionResult Index() + { + List orders = orderService.GetOrderList(); + + return View(orders); + } + + public ActionResult UpdateOrder(string Id) { + ViewBag.StatusList = new List() { + "Order Created", + "Payment Processed", + "Order Shipped", + "Order Complete" + }; + Order order = orderService.GetOrder(Id); + return View(order); + } + + [HttpPost] + public ActionResult UpdateOrder(Order updatedOrder, string Id) { + Order order = orderService.GetOrder(Id); + + order.OrderStatus = updatedOrder.OrderStatus; + orderService.UpdateOrder(order); + + return RedirectToAction("Index"); + } + } +} \ No newline at end of file diff --git a/MyShop/MyShop.WebUI/Controllers/ProductCategoryManagerController.cs b/MyShop/MyShop.WebUI/Controllers/ProductCategoryManagerController.cs index bec7555..16eb0f7 100644 --- a/MyShop/MyShop.WebUI/Controllers/ProductCategoryManagerController.cs +++ b/MyShop/MyShop.WebUI/Controllers/ProductCategoryManagerController.cs @@ -9,6 +9,7 @@ namespace MyShop.WebUI.Controllers { + [Authorize(Roles = "Admin")] public class ProductCategoryManagerController : Controller { IRepository context; diff --git a/MyShop/MyShop.WebUI/Controllers/ProductManagerController.cs b/MyShop/MyShop.WebUI/Controllers/ProductManagerController.cs index e11c863..b3d1d80 100644 --- a/MyShop/MyShop.WebUI/Controllers/ProductManagerController.cs +++ b/MyShop/MyShop.WebUI/Controllers/ProductManagerController.cs @@ -11,6 +11,7 @@ namespace MyShop.WebUI.Controllers { + [Authorize(Roles = "Admin")] public class ProductManagerController : Controller { IRepository context; diff --git a/MyShop/MyShop.WebUI/MyShop.WebUI.csproj b/MyShop/MyShop.WebUI/MyShop.WebUI.csproj index cbb36a2..ffde975 100644 --- a/MyShop/MyShop.WebUI/MyShop.WebUI.csproj +++ b/MyShop/MyShop.WebUI/MyShop.WebUI.csproj @@ -208,9 +208,11 @@ + + @@ -304,10 +306,17 @@ + + + + + + + diff --git a/MyShop/MyShop.WebUI/Views/Admin/Index.cshtml b/MyShop/MyShop.WebUI/Views/Admin/Index.cshtml new file mode 100644 index 0000000..8138965 --- /dev/null +++ b/MyShop/MyShop.WebUI/Views/Admin/Index.cshtml @@ -0,0 +1,20 @@ +@{ + ViewBag.Title = "Admin"; +} + +

Admin Pages

+ +
+

Product Management

+
+ @Html.ActionLink("Product Categories", "Index", "ProductCategoryManager", null, new { @class="list-group-item" }) + @Html.ActionLink("Product", "Index", "ProductManager", null, new { @class = "list-group-item" }) +
+
+
+

Order Management

+
+ @Html.ActionLink("Orders", "Index", "OrderManager", null, new { @class = "list-group-item" }) +
+
+
diff --git a/MyShop/MyShop.WebUI/Views/Basket/Checkout.cshtml b/MyShop/MyShop.WebUI/Views/Basket/Checkout.cshtml new file mode 100644 index 0000000..68e90b9 --- /dev/null +++ b/MyShop/MyShop.WebUI/Views/Basket/Checkout.cshtml @@ -0,0 +1,71 @@ +@model MyShop.Core.Models.Order + +@using (Html.BeginForm()) +{ + @Html.AntiForgeryToken() + +
+

Order

+
+ @Html.ValidationSummary(true, "", new { @class = "text-danger" }) + + +
+ @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" }) +
+
+ +
+ @Html.LabelFor(model => model.Surname, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Surname, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.Surname, "", new { @class = "text-danger" }) +
+
+ +
+ @Html.LabelFor(model => model.Street, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Street, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.Street, "", new { @class = "text-danger" }) +
+
+ +
+ @Html.LabelFor(model => model.City, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.City, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.City, "", new { @class = "text-danger" }) +
+
+ +
+ @Html.LabelFor(model => model.State, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.State, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.State, "", new { @class = "text-danger" }) +
+
+ +
+ @Html.LabelFor(model => model.ZipCode, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.ZipCode, new { htmlAttributes = new { @class = "form-control" } }) + @Html.ValidationMessageFor(model => model.ZipCode, "", new { @class = "text-danger" }) +
+
+ +
+
+ +
+
+
+} + +
+ @Html.ActionLink("Back to Basket", "Index") +
diff --git a/MyShop/MyShop.WebUI/Views/Basket/Index.cshtml b/MyShop/MyShop.WebUI/Views/Basket/Index.cshtml index 3e1eb82..78d19c5 100644 --- a/MyShop/MyShop.WebUI/Views/Basket/Index.cshtml +++ b/MyShop/MyShop.WebUI/Views/Basket/Index.cshtml @@ -48,6 +48,7 @@ Basket Total @String.Format("{0:c}", (from p in Model select p.Price * p.Quanity).Sum()) + Checkout diff --git a/MyShop/MyShop.WebUI/Views/Basket/ThankYou.cshtml b/MyShop/MyShop.WebUI/Views/Basket/ThankYou.cshtml new file mode 100644 index 0000000..238d088 --- /dev/null +++ b/MyShop/MyShop.WebUI/Views/Basket/ThankYou.cshtml @@ -0,0 +1,7 @@ +@{ + ViewBag.Title = "Thank You"; +} + +

Thank You

+Thank you for your order.

+Your Order Id = @ViewBag.OrderId diff --git a/MyShop/MyShop.WebUI/Views/OrderManager/Index.cshtml b/MyShop/MyShop.WebUI/Views/OrderManager/Index.cshtml new file mode 100644 index 0000000..66c0497 --- /dev/null +++ b/MyShop/MyShop.WebUI/Views/OrderManager/Index.cshtml @@ -0,0 +1,48 @@ +@model IEnumerable + + + + + + + + + + + + +@foreach (var item in Model) { + + + + + + + + + +} + +
+ @Html.DisplayNameFor(model => model.CreatedAt) + + @Html.DisplayNameFor(model => model.FirstName) + + @Html.DisplayNameFor(model => model.Surname) + + @Html.DisplayNameFor(model => model.Email) + + @Html.DisplayNameFor(model => model.OrderStatus) +
+ @Html.DisplayFor(modelItem => item.CreatedAt) + + @Html.DisplayFor(modelItem => item.FirstName) + + @Html.DisplayFor(modelItem => item.Surname) + + @Html.DisplayFor(modelItem => item.Email) + + @Html.DisplayFor(modelItem => item.OrderStatus) + + @Html.ActionLink("Manage Order", "UpdateOrder", new { id=item.Id }) +
diff --git a/MyShop/MyShop.WebUI/Views/OrderManager/OrderItems.cshtml b/MyShop/MyShop.WebUI/Views/OrderManager/OrderItems.cshtml new file mode 100644 index 0000000..76b0f4b --- /dev/null +++ b/MyShop/MyShop.WebUI/Views/OrderManager/OrderItems.cshtml @@ -0,0 +1,45 @@ +@model IEnumerable + + + + + + + + + + +@foreach (var item in Model) { + + + + + + + +} + + + + + + +
+ @Html.DisplayNameFor(model => model.ProductName) + + @Html.DisplayNameFor(model => model.Price) + + @Html.DisplayNameFor(model => model.Quanity) + Line Order
+ @Html.DisplayFor(modelItem => item.ProductName) + + @Html.DisplayFor(modelItem => item.Price) + + @Html.DisplayFor(modelItem => item.Quanity) + + @String.Format("{0:c}", item.Price * item.Quanity) +
+ Order Total + + @String.Format("{0:c}", (from p in Model select p.Quanity * p.Price).Sum()) +
diff --git a/MyShop/MyShop.WebUI/Views/OrderManager/UpdateOrder.cshtml b/MyShop/MyShop.WebUI/Views/OrderManager/UpdateOrder.cshtml new file mode 100644 index 0000000..5ef5889 --- /dev/null +++ b/MyShop/MyShop.WebUI/Views/OrderManager/UpdateOrder.cshtml @@ -0,0 +1,91 @@ +@model MyShop.Core.Models.Order + +@using (Html.BeginForm()) +{ + @Html.AntiForgeryToken() + +
+

Order

+
+ @Html.HiddenFor(model => model.Id) + +
+
+ @Html.LabelFor(model => model.OrderStatus, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.DropDownListFor(model => model.OrderStatus, new SelectList(ViewBag.StatusList), new { @class = "form-control" }) +
+
+ +
+ @Html.LabelFor(model => model.CreatedAt, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.DisplayFor(model => model.CreatedAt, new { htmlAttributes = new { @class = "form-control" } }) +
+
+ +
+ @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.DisplayFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } }) +
+
+ +
+ @Html.LabelFor(model => model.Surname, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.DisplayFor(model => model.Surname, new { htmlAttributes = new { @class = "form-control" } }) +
+
+ +
+ @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.DisplayFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) +
+
+ +
+
+
+ @Html.LabelFor(model => model.Street, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.DisplayFor(model => model.Street, new { htmlAttributes = new { @class = "form-control" } }) +
+
+ +
+ @Html.LabelFor(model => model.City, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.DisplayFor(model => model.City, new { htmlAttributes = new { @class = "form-control" } }) +
+
+ +
+ @Html.LabelFor(model => model.State, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.DisplayFor(model => model.State, new { htmlAttributes = new { @class = "form-control" } }) +
+
+ +
+ @Html.LabelFor(model => model.ZipCode, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.DisplayFor(model => model.ZipCode, new { htmlAttributes = new { @class = "form-control" } }) +
+
+
+ +
+
+ +
+
+
+ + @Html.Partial("OrderItems", Model.OrderItems) +} + +
+ @Html.ActionLink("Back to List", "Index") +
diff --git a/MyShop/MyShop.WebUI/Views/Shared/_Layout.cshtml b/MyShop/MyShop.WebUI/Views/Shared/_Layout.cshtml index 7a5ce9c..f9ad8b0 100644 --- a/MyShop/MyShop.WebUI/Views/Shared/_Layout.cshtml +++ b/MyShop/MyShop.WebUI/Views/Shared/_Layout.cshtml @@ -22,8 +22,10 @@