From 2a81a080bacb978172c88097acb3c064b483d2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduard=20Tom=C3=A0s?= Date: Thu, 1 Feb 2018 14:04:20 +0000 Subject: [PATCH] Moved Create Order from MVC logic client to Purchase logic. --- .../configuration/configuration.json | 2 +- .../Controllers/OrderController.cs | 40 +++++++++++++++++++ src/BFFs/PurchaseBff/Models/OrderData.cs | 33 +++++++++++++++ src/BFFs/PurchaseBff/Models/OrderItemData.cs | 17 ++++++++ .../Properties/launchSettings.json | 4 +- .../PurchaseBff/Services/BasketService.cs | 25 ++++++++++++ .../PurchaseBff/Services/IBasketService.cs | 2 + .../Basket.API/Properties/launchSettings.json | 2 +- .../Properties/launchSettings.json | 2 +- src/Web/WebMVC/Controllers/CartController.cs | 2 - src/Web/WebMVC/Controllers/OrderController.cs | 4 +- src/Web/WebMVC/Infrastructure/API.cs | 2 + src/Web/WebMVC/Services/BasketService.cs | 24 +++-------- src/Web/WebMVC/Services/IBasketService.cs | 2 +- src/Web/WebSPA/Properties/launchSettings.json | 2 +- .../Application/OrderControllerTest.cs | 35 +--------------- 16 files changed, 135 insertions(+), 63 deletions(-) create mode 100644 src/BFFs/PurchaseBff/Controllers/OrderController.cs create mode 100644 src/BFFs/PurchaseBff/Models/OrderData.cs create mode 100644 src/BFFs/PurchaseBff/Models/OrderItemData.cs diff --git a/src/Apigw/OcelotApiGw/configuration/configuration.json b/src/Apigw/OcelotApiGw/configuration/configuration.json index 5216c9540..cc2defca6 100644 --- a/src/Apigw/OcelotApiGw/configuration/configuration.json +++ b/src/Apigw/OcelotApiGw/configuration/configuration.json @@ -26,7 +26,7 @@ "DownstreamHost": "purchasebff", "DownstreamPort": 80, "UpstreamPathTemplate": "/purchase-bff/{everything}", - "UpstreamHttpMethod": [ "POST", "PUT" ], + "UpstreamHttpMethod": [ "POST", "PUT", "GET" ], "AuthenticationOptions": { "AuthenticationProviderKey": "IdentityApiKey", "AllowedScopes": [] diff --git a/src/BFFs/PurchaseBff/Controllers/OrderController.cs b/src/BFFs/PurchaseBff/Controllers/OrderController.cs new file mode 100644 index 000000000..7e7b00c1b --- /dev/null +++ b/src/BFFs/PurchaseBff/Controllers/OrderController.cs @@ -0,0 +1,40 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using PurchaseBff.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace PurchaseBff.Controllers +{ + [Route("api/v1/[controller]")] + [Authorize] + public class OrderController : Controller + { + private readonly IBasketService _basketService; + public OrderController(IBasketService basketService) + { + _basketService = basketService; + } + + [Route("draft/{basketId}")] + [HttpGet] + public async Task GetOrderDraft(string basketId) + { + if (string.IsNullOrEmpty(basketId)) + { + return BadRequest("Need a valid basketid"); + } + // Get the basket data and build a order draft based on it + var basket = await _basketService.GetById(basketId); + if (basket == null) + { + return BadRequest($"No basket found for id {basketId}"); + } + + var order = _basketService.MapBasketToOrder(basket, isDraft: true); + return Ok(order); + } + } +} diff --git a/src/BFFs/PurchaseBff/Models/OrderData.cs b/src/BFFs/PurchaseBff/Models/OrderData.cs new file mode 100644 index 000000000..c561a53ad --- /dev/null +++ b/src/BFFs/PurchaseBff/Models/OrderData.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace PurchaseBff.Models +{ + public class OrderData + { + public string OrderNumber { get; set; } + public DateTime Date { get; set; } + public string Status { get; set; } + public decimal Total { get; set; } + public string Description { get; set; } + public string City { get; set; } + public string Street { get; set; } + public string State { get; set; } + public string Country { get; set; } + public string ZipCode { get; set; } + public string CardNumber { get; set; } + public string CardHolderName { get; set; } + public bool IsDraft { get; set; } + public DateTime CardExpiration { get; set; } + public string CardExpirationShort { get; set; } + public string CardSecurityNumber { get; set; } + + public int CardTypeId { get; set; } + + public string Buyer { get; set; } + + public List OrderItems { get; } = new List(); + } +} diff --git a/src/BFFs/PurchaseBff/Models/OrderItemData.cs b/src/BFFs/PurchaseBff/Models/OrderItemData.cs new file mode 100644 index 000000000..bdc7b361e --- /dev/null +++ b/src/BFFs/PurchaseBff/Models/OrderItemData.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace PurchaseBff.Models +{ + public class OrderItemData + { + public int ProductId { get; set; } + public string ProductName { get; set; } + public decimal UnitPrice { get; set; } + public decimal Discount { get; set; } + public int Units { get; set; } + public string PictureUrl { get; set; } + } +} diff --git a/src/BFFs/PurchaseBff/Properties/launchSettings.json b/src/BFFs/PurchaseBff/Properties/launchSettings.json index 709d1b89a..d6c88d211 100644 --- a/src/BFFs/PurchaseBff/Properties/launchSettings.json +++ b/src/BFFs/PurchaseBff/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:61631/", + "applicationUrl": "http://localhost:58243/", "sslPort": 0 } }, @@ -26,4 +26,4 @@ "applicationUrl": "http://localhost:61632/" } } -} +} \ No newline at end of file diff --git a/src/BFFs/PurchaseBff/Services/BasketService.cs b/src/BFFs/PurchaseBff/Services/BasketService.cs index 881718baf..fd16843a1 100644 --- a/src/BFFs/PurchaseBff/Services/BasketService.cs +++ b/src/BFFs/PurchaseBff/Services/BasketService.cs @@ -44,6 +44,31 @@ namespace PurchaseBff.Services int i = 0; } + public OrderData MapBasketToOrder(BasketData basket, bool isDraft) + { + var order = new OrderData + { + Total = 0, + IsDraft = isDraft + }; + + basket.Items.ForEach(x => + { + order.OrderItems.Add(new OrderItemData() + { + ProductId = int.Parse(x.ProductId), + + PictureUrl = x.PictureUrl, + ProductName = x.ProductName, + Units = x.Quantity, + UnitPrice = x.UnitPrice + }); + order.Total += (x.Quantity * x.UnitPrice); + }); + + return order; + } + async Task GetUserTokenAsync() { var context = _httpContextAccessor.HttpContext; diff --git a/src/BFFs/PurchaseBff/Services/IBasketService.cs b/src/BFFs/PurchaseBff/Services/IBasketService.cs index 0c33c5c41..79319536f 100644 --- a/src/BFFs/PurchaseBff/Services/IBasketService.cs +++ b/src/BFFs/PurchaseBff/Services/IBasketService.cs @@ -10,5 +10,7 @@ namespace PurchaseBff.Services { Task GetById(string id); Task Update(BasketData currentBasket); + + OrderData MapBasketToOrder(BasketData basket, bool isDraft); } } diff --git a/src/Services/Basket/Basket.API/Properties/launchSettings.json b/src/Services/Basket/Basket.API/Properties/launchSettings.json index 0045edd47..013205c33 100644 --- a/src/Services/Basket/Basket.API/Properties/launchSettings.json +++ b/src/Services/Basket/Basket.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:56695/", + "applicationUrl": "http://localhost:57622/", "sslPort": 0 } }, diff --git a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json index 28f08bad2..a0b19b3bf 100644 --- a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json +++ b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:56698/", + "applicationUrl": "http://localhost:57623/", "sslPort": 0 } }, diff --git a/src/Web/WebMVC/Controllers/CartController.cs b/src/Web/WebMVC/Controllers/CartController.cs index 41484d79c..660da1d56 100644 --- a/src/Web/WebMVC/Controllers/CartController.cs +++ b/src/Web/WebMVC/Controllers/CartController.cs @@ -49,10 +49,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers { var user = _appUserParser.Parse(HttpContext.User); var basket = await _basketSvc.SetQuantities(user, quantities); - if (action == "[ Checkout ]") { - var order = _basketSvc.MapBasketToOrder(basket); return RedirectToAction("Create", "Order"); } } diff --git a/src/Web/WebMVC/Controllers/OrderController.cs b/src/Web/WebMVC/Controllers/OrderController.cs index 11e688728..a5bf4785e 100644 --- a/src/Web/WebMVC/Controllers/OrderController.cs +++ b/src/Web/WebMVC/Controllers/OrderController.cs @@ -27,9 +27,9 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers public async Task Create() { + var user = _appUserParser.Parse(HttpContext.User); - var basket = await _basketSvc.GetBasket(user); - var order = _basketSvc.MapBasketToOrder(basket); + var order = await _basketSvc.GetOrderDraft(user.Id); var vm = _orderSvc.MapUserInfoIntoOrder(user, order); vm.CardExpirationShortFormat(); diff --git a/src/Web/WebMVC/Infrastructure/API.cs b/src/Web/WebMVC/Infrastructure/API.cs index 765ee3e9b..d6f485e21 100644 --- a/src/Web/WebMVC/Infrastructure/API.cs +++ b/src/Web/WebMVC/Infrastructure/API.cs @@ -9,6 +9,8 @@ namespace WebMVC.Infrastructure { public static string AddItemToBasket(string baseUri) => $"{baseUri}/basket/items"; public static string UpdateBasketItem(string baseUri) => $"{baseUri}/basket/items"; + + public static string GetOrderDraft(string baseUri, string basketId) => $"{baseUri}/order/draft/{basketId}"; } public static class Basket diff --git a/src/Web/WebMVC/Services/BasketService.cs b/src/Web/WebMVC/Services/BasketService.cs index 1c4b2aa87..208ea71ad 100644 --- a/src/Web/WebMVC/Services/BasketService.cs +++ b/src/Web/WebMVC/Services/BasketService.cs @@ -93,27 +93,15 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services return JsonConvert.DeserializeObject(jsonResponse); } - public Order MapBasketToOrder(Basket basket) + public async Task GetOrderDraft(string basketId) { - var order = new Order(); - order.Total = 0; - - basket.Items.ForEach(x => - { - order.OrderItems.Add(new OrderItem() - { - ProductId = int.Parse(x.ProductId), + var token = await GetUserTokenAsync(); + var draftOrderUri = API.Purchase.GetOrderDraft(_purchaseUrl, basketId); + var json = await _apiClient.GetStringAsync(draftOrderUri, token); + return JsonConvert.DeserializeObject(json); + } - PictureUrl = x.PictureUrl, - ProductName = x.ProductName, - Units = x.Quantity, - UnitPrice = x.UnitPrice - }); - order.Total += (x.Quantity * x.UnitPrice); - }); - return order; - } public async Task AddItemToBasket(ApplicationUser user, int productId) { diff --git a/src/Web/WebMVC/Services/IBasketService.cs b/src/Web/WebMVC/Services/IBasketService.cs index 78898de7d..cfbea5ff0 100644 --- a/src/Web/WebMVC/Services/IBasketService.cs +++ b/src/Web/WebMVC/Services/IBasketService.cs @@ -14,6 +14,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services Task UpdateBasket(Basket basket); Task Checkout(BasketDTO basket); Task SetQuantities(ApplicationUser user, Dictionary quantities); - Order MapBasketToOrder(Basket basket); + Task GetOrderDraft(string basketId); } } diff --git a/src/Web/WebSPA/Properties/launchSettings.json b/src/Web/WebSPA/Properties/launchSettings.json index 9be3bf34a..8a55ca730 100644 --- a/src/Web/WebSPA/Properties/launchSettings.json +++ b/src/Web/WebSPA/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:56727/", + "applicationUrl": "http://localhost:57625/", "sslPort": 0 } }, diff --git a/test/Services/UnitTest/Ordering/Application/OrderControllerTest.cs b/test/Services/UnitTest/Ordering/Application/OrderControllerTest.cs index 12f2be395..a60ce3bb3 100644 --- a/test/Services/UnitTest/Ordering/Application/OrderControllerTest.cs +++ b/test/Services/UnitTest/Ordering/Application/OrderControllerTest.cs @@ -68,40 +68,7 @@ namespace UnitTest.Ordering.Application Assert.IsAssignableFrom(viewResult.ViewData.Model); } - [Fact] - public async Task Get_create_order_success() - { - //Arrange - var fakeBuyerId = "1"; - var fakeBasket = GetFakeBasket(fakeBuyerId); - var fakeOrder = GetFakeOrder(); - - _basketServiceMock.Setup(x => x.GetBasket(It.IsAny())) - .Returns(Task.FromResult(fakeBasket)); - - _basketServiceMock.Setup(x => x.MapBasketToOrder(It.IsAny())) - .Returns(fakeOrder); - - _orderServiceMock.Setup(x => x.MapUserInfoIntoOrder(It.IsAny(), It.IsAny())) - .Returns(fakeOrder); - - //Act - var orderController = new OrderController(_orderServiceMock.Object, _basketServiceMock.Object, _identityParserMock.Object); - orderController.ControllerContext.HttpContext = _contextMock.Object; - var actionResult = await orderController.Create(); - - //Assert - var viewResult = Assert.IsType(actionResult); - Assert.IsAssignableFrom(viewResult.ViewData.Model); - } - - private BasketModel GetFakeBasket(string buyerId) - { - return new BasketModel() - { - BuyerId = buyerId - }; - } + private Order GetFakeOrder() {