Moved Create Order from MVC logic client to Purchase logic.

This commit is contained in:
Eduard Tomàs 2018-02-01 14:04:20 +00:00
parent 2a2f3a4da1
commit 2a81a080ba
16 changed files with 136 additions and 64 deletions

View File

@ -26,7 +26,7 @@
"DownstreamHost": "purchasebff", "DownstreamHost": "purchasebff",
"DownstreamPort": 80, "DownstreamPort": 80,
"UpstreamPathTemplate": "/purchase-bff/{everything}", "UpstreamPathTemplate": "/purchase-bff/{everything}",
"UpstreamHttpMethod": [ "POST", "PUT" ], "UpstreamHttpMethod": [ "POST", "PUT", "GET" ],
"AuthenticationOptions": { "AuthenticationOptions": {
"AuthenticationProviderKey": "IdentityApiKey", "AuthenticationProviderKey": "IdentityApiKey",
"AllowedScopes": [] "AllowedScopes": []

View File

@ -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<IActionResult> 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);
}
}
}

View File

@ -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<OrderItemData> OrderItems { get; } = new List<OrderItemData>();
}
}

View File

@ -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; }
}
}

View File

@ -3,7 +3,7 @@
"windowsAuthentication": false, "windowsAuthentication": false,
"anonymousAuthentication": true, "anonymousAuthentication": true,
"iisExpress": { "iisExpress": {
"applicationUrl": "http://localhost:61631/", "applicationUrl": "http://localhost:58243/",
"sslPort": 0 "sslPort": 0
} }
}, },
@ -26,4 +26,4 @@
"applicationUrl": "http://localhost:61632/" "applicationUrl": "http://localhost:61632/"
} }
} }
} }

View File

@ -44,6 +44,31 @@ namespace PurchaseBff.Services
int i = 0; 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<string> GetUserTokenAsync() async Task<string> GetUserTokenAsync()
{ {
var context = _httpContextAccessor.HttpContext; var context = _httpContextAccessor.HttpContext;

View File

@ -10,5 +10,7 @@ namespace PurchaseBff.Services
{ {
Task<BasketData> GetById(string id); Task<BasketData> GetById(string id);
Task Update(BasketData currentBasket); Task Update(BasketData currentBasket);
OrderData MapBasketToOrder(BasketData basket, bool isDraft);
} }
} }

View File

@ -3,7 +3,7 @@
"windowsAuthentication": false, "windowsAuthentication": false,
"anonymousAuthentication": true, "anonymousAuthentication": true,
"iisExpress": { "iisExpress": {
"applicationUrl": "http://localhost:56695/", "applicationUrl": "http://localhost:57622/",
"sslPort": 0 "sslPort": 0
} }
}, },

View File

@ -3,7 +3,7 @@
"windowsAuthentication": false, "windowsAuthentication": false,
"anonymousAuthentication": true, "anonymousAuthentication": true,
"iisExpress": { "iisExpress": {
"applicationUrl": "http://localhost:56698/", "applicationUrl": "http://localhost:57623/",
"sslPort": 0 "sslPort": 0
} }
}, },

View File

@ -49,10 +49,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{ {
var user = _appUserParser.Parse(HttpContext.User); var user = _appUserParser.Parse(HttpContext.User);
var basket = await _basketSvc.SetQuantities(user, quantities); var basket = await _basketSvc.SetQuantities(user, quantities);
if (action == "[ Checkout ]") if (action == "[ Checkout ]")
{ {
var order = _basketSvc.MapBasketToOrder(basket);
return RedirectToAction("Create", "Order"); return RedirectToAction("Create", "Order");
} }
} }

View File

@ -27,9 +27,9 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
public async Task<IActionResult> Create() public async Task<IActionResult> Create()
{ {
var user = _appUserParser.Parse(HttpContext.User); var user = _appUserParser.Parse(HttpContext.User);
var basket = await _basketSvc.GetBasket(user); var order = await _basketSvc.GetOrderDraft(user.Id);
var order = _basketSvc.MapBasketToOrder(basket);
var vm = _orderSvc.MapUserInfoIntoOrder(user, order); var vm = _orderSvc.MapUserInfoIntoOrder(user, order);
vm.CardExpirationShortFormat(); vm.CardExpirationShortFormat();

View File

@ -9,6 +9,8 @@ namespace WebMVC.Infrastructure
{ {
public static string AddItemToBasket(string baseUri) => $"{baseUri}/basket/items"; public static string AddItemToBasket(string baseUri) => $"{baseUri}/basket/items";
public static string UpdateBasketItem(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 public static class Basket

View File

@ -93,28 +93,16 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
return JsonConvert.DeserializeObject<Basket>(jsonResponse); return JsonConvert.DeserializeObject<Basket>(jsonResponse);
} }
public Order MapBasketToOrder(Basket basket) public async Task<Order> GetOrderDraft(string basketId)
{ {
var order = new Order(); var token = await GetUserTokenAsync();
order.Total = 0; var draftOrderUri = API.Purchase.GetOrderDraft(_purchaseUrl, basketId);
var json = await _apiClient.GetStringAsync(draftOrderUri, token);
basket.Items.ForEach(x => return JsonConvert.DeserializeObject<Order>(json);
{
order.OrderItems.Add(new OrderItem()
{
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;
} }
public async Task AddItemToBasket(ApplicationUser user, int productId) public async Task AddItemToBasket(ApplicationUser user, int productId)
{ {
var token = await GetUserTokenAsync(); var token = await GetUserTokenAsync();

View File

@ -14,6 +14,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
Task<Basket> UpdateBasket(Basket basket); Task<Basket> UpdateBasket(Basket basket);
Task Checkout(BasketDTO basket); Task Checkout(BasketDTO basket);
Task<Basket> SetQuantities(ApplicationUser user, Dictionary<string, int> quantities); Task<Basket> SetQuantities(ApplicationUser user, Dictionary<string, int> quantities);
Order MapBasketToOrder(Basket basket); Task<Order> GetOrderDraft(string basketId);
} }
} }

View File

@ -3,7 +3,7 @@
"windowsAuthentication": false, "windowsAuthentication": false,
"anonymousAuthentication": true, "anonymousAuthentication": true,
"iisExpress": { "iisExpress": {
"applicationUrl": "http://localhost:56727/", "applicationUrl": "http://localhost:57625/",
"sslPort": 0 "sslPort": 0
} }
}, },

View File

@ -68,40 +68,7 @@ namespace UnitTest.Ordering.Application
Assert.IsAssignableFrom<Order>(viewResult.ViewData.Model); Assert.IsAssignableFrom<Order>(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<ApplicationUser>()))
.Returns(Task.FromResult(fakeBasket));
_basketServiceMock.Setup(x => x.MapBasketToOrder(It.IsAny<BasketModel>()))
.Returns(fakeOrder);
_orderServiceMock.Setup(x => x.MapUserInfoIntoOrder(It.IsAny<ApplicationUser>(), It.IsAny<Order>()))
.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<ViewResult>(actionResult);
Assert.IsAssignableFrom<Order>(viewResult.ViewData.Model);
}
private BasketModel GetFakeBasket(string buyerId)
{
return new BasketModel()
{
BuyerId = buyerId
};
}
private Order GetFakeOrder() private Order GetFakeOrder()
{ {