From f79806e8994b22162a949d6ddd382bf3f9782088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20Tom=C3=A1s?= Date: Sun, 14 May 2017 14:48:37 +0200 Subject: [PATCH] Created Ship order process in WebMVC app Create Ship order command and handler in Ordering.api Create Order management page in WebMVC app --- .../Controllers/BasketController.cs | 3 + .../Commands/CreateOrderCommand.cs | 2 +- .../Application/Commands/ShipOrderCommand.cs | 21 ++++++ ...egateWhenOrderStartedDomainEventHandler.cs | 2 - .../Application/Sagas/OrderProcessSaga.cs | 66 ++++++++++++++----- .../Controllers/OrdersController.cs | 17 ++++- .../AggregatesModel/OrderAggregate/Order.cs | 5 ++ src/Web/WebMVC/Controllers/OrderController.cs | 14 ++-- .../Controllers/OrderManagementController.cs | 43 ++++++++++++ src/Web/WebMVC/Infrastructure/API.cs | 5 ++ src/Web/WebMVC/Models/OrderDTO.cs | 11 ++++ src/Web/WebMVC/Models/OrderProcessAction.cs | 25 +++++++ src/Web/WebMVC/Services/IOrderingService.cs | 3 +- src/Web/WebMVC/Services/OrderingService.cs | 30 ++++++++- src/Web/WebMVC/ViewModels/Order.cs | 26 +++++++- src/Web/WebMVC/Views/Cart/Index.cshtml | 3 +- src/Web/WebMVC/Views/Order/Create.cshtml | 4 +- src/Web/WebMVC/Views/Order/Detail.cshtml | 3 +- src/Web/WebMVC/Views/Order/Index.cshtml | 12 +++- .../WebMVC/Views/OrderManagement/Index.cshtml | 43 ++++++++++++ src/Web/WebMVC/Views/Shared/_Header.cshtml | 8 ++- .../css/shared/components/header/header.css | 14 ++++ .../IdentifierCommandHandlerTest.cs | 4 +- .../Application/NewOrderCommandHandlerTest.cs | 6 +- .../Ordering/Domain/OrderAggregateTest.cs | 10 +-- 25 files changed, 328 insertions(+), 52 deletions(-) create mode 100644 src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommand.cs create mode 100644 src/Web/WebMVC/Controllers/OrderManagementController.cs create mode 100644 src/Web/WebMVC/Models/OrderDTO.cs create mode 100644 src/Web/WebMVC/Models/OrderProcessAction.cs create mode 100644 src/Web/WebMVC/Views/OrderManagement/Index.cshtml diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index 9a120efc0..68e323187 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -61,6 +61,9 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers value.State, value.Country, value.ZipCode, value.CardNumber, value.CardHolderName, value.CardExpiration, value.CardSecurityNumber, value.CardTypeId, value.Buyer, value.RequestId, basket); + // Once basket is checkout, sends an integration event to + // ordering.api to convert basket to order and proceeds with + // order creation process _eventBus.Publish(eventMessage); if (basket == null) diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs index 19fa3b818..fc6fd97d0 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs @@ -88,7 +88,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands var result = new List(); basketItems.ForEach((item) => { result.Add(new OrderItemDTO() { - ProductId = int.TryParse(item.Id, out int id) ? id : -1, + ProductId = int.TryParse(item.ProductId, out int id) ? id : -1, ProductName = item.ProductName, PictureUrl = item.PictureUrl, UnitPrice = item.UnitPrice, diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommand.cs new file mode 100644 index 000000000..d56123ba7 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommand.cs @@ -0,0 +1,21 @@ +using MediatR; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Threading.Tasks; + +namespace Ordering.API.Application.Commands +{ + public class ShipOrderCommand : IAsyncRequest + { + + [DataMember] + public int OrderNumber { get; private set; } + + public ShipOrderCommand(int orderNumber) + { + OrderNumber = orderNumber; + } + } +} \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs index b2120904c..77714d1b0 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs @@ -26,8 +26,6 @@ namespace Ordering.API.Application.DomainEventHandlers.OrderStartedEvent { var cardTypeId = (orderStartedEvent.CardTypeId != 0) ? orderStartedEvent.CardTypeId : 1; - //var userGuid = _identityService.GetUserIdentity(); - var buyer = await _buyerRepository.FindAsync(orderStartedEvent.UserId); bool buyerOriginallyExisted = (buyer == null) ? false : true; diff --git a/src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs b/src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs index 8a4c51795..47dcbe6f5 100644 --- a/src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs +++ b/src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs @@ -1,5 +1,4 @@ -using Autofac.Features.OwnedInstances; -using MediatR; +using MediatR; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; @@ -7,15 +6,10 @@ using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; using Ordering.API.Application.Commands; using Ordering.API.Application.IntegrationCommands.Commands; -using Ordering.API.Application.IntegrationEvents.Events; +using Ordering.API.Application.IntegrationEvents; using Ordering.Domain.Exceptions; -using System; -using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Threading.Tasks; -using Ordering.API.Application.IntegrationEvents; -using Ordering.API.Application.IntegrationEvents.Events; namespace Ordering.API.Application.Sagas { @@ -29,19 +23,16 @@ namespace Ordering.API.Application.Sagas /// public class OrderProcessSaga : Saga, IIntegrationEventHandler, - IAsyncRequestHandler + IAsyncRequestHandler, + IAsyncRequestHandler { - private readonly IMediator _mediator; - private readonly Func> _dbContextFactory; private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; public OrderProcessSaga( - Func> dbContextFactory, OrderingContext orderingContext, - IMediator mediator, IOrderingIntegrationEventService orderingIntegrationEventService) + OrderingContext orderingContext, + IOrderingIntegrationEventService orderingIntegrationEventService) : base(orderingContext) { - _dbContextFactory = dbContextFactory; - _mediator = mediator; _orderingIntegrationEventService = orderingIntegrationEventService; } @@ -85,12 +76,41 @@ namespace Ordering.API.Application.Sagas /// public async Task Handle(CancelOrderCommand command) { + var result = false; var orderSaga = FindSagaById(command.OrderNumber); CheckValidSagaId(orderSaga); - // Set order status tu cancelled + // Not possible to cancel order when + // it has already been shipped + if (orderSaga.GetOrderStatusId() != OrderStatus.Cancelled.Id + || orderSaga.GetOrderStatusId() != OrderStatus.Shipped.Id) + { + orderSaga.SetOrderStatusId(OrderStatus.Cancelled.Id); + result = await SaveChangesAsync(); + } + return result; + } + + /// + /// Handler which processes the command when + /// administrator executes ship order from app + /// + /// + /// + public async Task Handle(ShipOrderCommand command) + { + var result = false; + var orderSaga = FindSagaById(command.OrderNumber); + CheckValidSagaId(orderSaga); - return true; + // Only ship order when + // its status is paid + if (orderSaga.GetOrderStatusId() == OrderStatus.Paid.Id) + { + orderSaga.SetOrderStatusId(OrderStatus.Shipped.Id); + result = await SaveChangesAsync(); + } + return result; } private void CheckValidSagaId(Order orderSaga) @@ -115,6 +135,18 @@ namespace Ordering.API.Application.Sagas } } + public class ShipOrderCommandIdentifiedHandler : IdentifierCommandHandler + { + public ShipOrderCommandIdentifiedHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager) + { + } + + protected override bool CreateResultForDuplicateRequest() + { + return true; // Ignore duplicate requests for processing order. + } + } + #endregion } } diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs index 2d4ce4059..d8e658f16 100644 --- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -28,7 +28,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers } [Route("cancel")] - [HttpPost] + [HttpPut] public async Task CancelOrder([FromBody]CancelOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId) { bool commandResult = false; @@ -42,6 +42,21 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers } + [Route("ship")] + [HttpPut] + public async Task ShipOrder([FromBody]ShipOrderCommand command, [FromHeader(Name = "x-requestid")] string requestId) + { + bool commandResult = false; + if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) + { + var requestShipOrder = new IdentifiedCommand(command, guid); + commandResult = await _mediator.SendAsync(requestShipOrder); + } + + return commandResult ? (IActionResult)Ok() : (IActionResult)BadRequest(); + + } + [Route("{orderId:int}")] [HttpGet] public async Task GetOrder(int orderId) diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs index 9cc8c06bd..d9468a342 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs @@ -120,6 +120,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O } } + public int GetOrderStatusId() + { + return _orderStatusId; + } + private void AddOrderStartedDomainEvent(string userId, int cardTypeId, string cardNumber, string cardSecurityNumber, string cardHolderName, DateTime cardExpiration) { diff --git a/src/Web/WebMVC/Controllers/OrderController.cs b/src/Web/WebMVC/Controllers/OrderController.cs index b8efd930e..8f34c2282 100644 --- a/src/Web/WebMVC/Controllers/OrderController.cs +++ b/src/Web/WebMVC/Controllers/OrderController.cs @@ -59,18 +59,12 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers return View(model); } - [HttpPut] - public async Task Cancel(Order model) + public async Task Cancel(string orderId) { - if (ModelState.IsValid) - { - var user = _appUserParser.Parse(HttpContext.User); - await _orderSvc.CancelOrder(model); + await _orderSvc.CancelOrder(orderId); - //Redirect to historic list. - return RedirectToAction("Index"); - } - return View(model); + //Redirect to historic list. + return RedirectToAction("Index"); } public async Task Detail(string orderId) diff --git a/src/Web/WebMVC/Controllers/OrderManagementController.cs b/src/Web/WebMVC/Controllers/OrderManagementController.cs new file mode 100644 index 000000000..abd0b21ab --- /dev/null +++ b/src/Web/WebMVC/Controllers/OrderManagementController.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using WebMVC.Models; +using Microsoft.eShopOnContainers.WebMVC.Services; +using Microsoft.eShopOnContainers.WebMVC.ViewModels; +using Microsoft.AspNetCore.Authorization; + +namespace WebMVC.Controllers +{ + [Authorize] + public class OrderManagementController : Controller + { + private IOrderingService _orderSvc; + private readonly IIdentityParser _appUserParser; + public OrderManagementController(IOrderingService orderSvc, IIdentityParser appUserParser) + { + _appUserParser = appUserParser; + _orderSvc = orderSvc; + } + + public async Task Index() + { + var user = _appUserParser.Parse(HttpContext.User); + var vm = await _orderSvc.GetMyOrders(user); + + return View(vm); + } + + [HttpPost] + public async Task OrderProcess(string orderId, string actionCode) + { + if (OrderProcessAction.Ship.Code == actionCode) + { + await _orderSvc.ShipOrder(orderId); + } + + return RedirectToAction("Index"); + } + } +} diff --git a/src/Web/WebMVC/Infrastructure/API.cs b/src/Web/WebMVC/Infrastructure/API.cs index f23b94288..fc170ffcc 100644 --- a/src/Web/WebMVC/Infrastructure/API.cs +++ b/src/Web/WebMVC/Infrastructure/API.cs @@ -46,6 +46,11 @@ { return $"{baseUri}/cancel"; } + + public static string ShipOrder(string baseUri) + { + return $"{baseUri}/ship"; + } } public static class Catalog diff --git a/src/Web/WebMVC/Models/OrderDTO.cs b/src/Web/WebMVC/Models/OrderDTO.cs new file mode 100644 index 000000000..13646ea38 --- /dev/null +++ b/src/Web/WebMVC/Models/OrderDTO.cs @@ -0,0 +1,11 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace WebMVC.Models +{ + public class OrderDTO + { + [Required] + public string OrderNumber { get; set; } + } +} \ No newline at end of file diff --git a/src/Web/WebMVC/Models/OrderProcessAction.cs b/src/Web/WebMVC/Models/OrderProcessAction.cs new file mode 100644 index 000000000..bd746bb36 --- /dev/null +++ b/src/Web/WebMVC/Models/OrderProcessAction.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace WebMVC.Models +{ + public class OrderProcessAction + { + public string Code { get; private set; } + public string Name { get; private set; } + + public static OrderProcessAction Ship = new OrderProcessAction(nameof(Ship).ToLowerInvariant(), "Ship"); + + protected OrderProcessAction() + { + } + + public OrderProcessAction(string code, string name) + { + Code = code; + Name = name; + } + } +} diff --git a/src/Web/WebMVC/Services/IOrderingService.cs b/src/Web/WebMVC/Services/IOrderingService.cs index fca0151f1..1de2c631c 100644 --- a/src/Web/WebMVC/Services/IOrderingService.cs +++ b/src/Web/WebMVC/Services/IOrderingService.cs @@ -11,7 +11,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services { Task> GetMyOrders(ApplicationUser user); Task GetOrder(ApplicationUser user, string orderId); - Task CancelOrder(Order order); + Task CancelOrder(string orderId); + Task ShipOrder(string orderId); Order MapUserInfoIntoOrder(ApplicationUser user, Order order); BasketDTO MapOrderToBasket(Order order); void OverrideUserInfoIntoOrder(Order original, Order destination); diff --git a/src/Web/WebMVC/Services/OrderingService.cs b/src/Web/WebMVC/Services/OrderingService.cs index 7140b0eb3..d9eba7392 100644 --- a/src/Web/WebMVC/Services/OrderingService.cs +++ b/src/Web/WebMVC/Services/OrderingService.cs @@ -66,13 +66,17 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services return order; } - async public Task CancelOrder(Order order) + async public Task CancelOrder(string orderId) { var token = await GetUserTokenAsync(); - var requestId = order.RequestId.ToString(); + var order = new OrderDTO() + { + OrderNumber = orderId + }; + var cancelOrderUri = API.Order.CancelOrder(_remoteServiceBaseUrl); - var response = await _apiClient.PutAsync(cancelOrderUri, order, token, requestId); + var response = await _apiClient.PutAsync(cancelOrderUri, order, token, Guid.NewGuid().ToString()); if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError) { @@ -82,6 +86,26 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services response.EnsureSuccessStatusCode(); } + async public Task ShipOrder(string orderId) + { + var token = await GetUserTokenAsync(); + var order = new OrderDTO() + { + OrderNumber = orderId + }; + + var shipOrderUri = API.Order.ShipOrder(_remoteServiceBaseUrl); + + var response = await _apiClient.PutAsync(shipOrderUri, order, token, Guid.NewGuid().ToString()); + + if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError) + { + throw new Exception("Error in ship order process, try later."); + } + + response.EnsureSuccessStatusCode(); + } + public void OverrideUserInfoIntoOrder(Order original, Order destination) { destination.City = original.City; diff --git a/src/Web/WebMVC/ViewModels/Order.cs b/src/Web/WebMVC/ViewModels/Order.cs index 213914208..28dbe9968 100644 --- a/src/Web/WebMVC/ViewModels/Order.cs +++ b/src/Web/WebMVC/ViewModels/Order.cs @@ -1,4 +1,5 @@ -using Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -6,6 +7,7 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; +using WebMVC.Models; namespace Microsoft.eShopOnContainers.WebMVC.ViewModels { @@ -51,6 +53,9 @@ namespace Microsoft.eShopOnContainers.WebMVC.ViewModels public string Buyer { get; set; } + public List ActionCodeSelectList => + GetActionCodesByCurrentState(); + // See the property initializer syntax below. This // initializes the compiler generated field for this // auto-implemented property. @@ -72,6 +77,25 @@ namespace Microsoft.eShopOnContainers.WebMVC.ViewModels CardExpiration = new DateTime(int.Parse(year), int.Parse(month), 1); } + + private List GetActionCodesByCurrentState() + { + var actions = new List(); + switch (Status?.ToLower()) + { + case "paid": + actions.Add(OrderProcessAction.Ship); + break; + } + + var result = new List(); + actions.ForEach(action => + { + result.Add(new SelectListItem { Text = action.Name, Value = action.Code }); + }); + + return result; + } } public enum CardType diff --git a/src/Web/WebMVC/Views/Cart/Index.cshtml b/src/Web/WebMVC/Views/Cart/Index.cshtml index 1111df0cf..d9386a1fd 100644 --- a/src/Web/WebMVC/Views/Cart/Index.cshtml +++ b/src/Web/WebMVC/Views/Cart/Index.cshtml @@ -10,7 +10,8 @@
- @Html.Partial("_Header", new Header(){ Controller = "Catalog", Text = "Back to catalog" }) + @Html.Partial("_Header", new List
() { + new Header() { Controller = "Catalog", Text = "Back to catalog" } }) @await Component.InvokeAsync("CartList", new { user = UserManager.Parse(User) })
diff --git a/src/Web/WebMVC/Views/Order/Create.cshtml b/src/Web/WebMVC/Views/Order/Create.cshtml index 79ced5b3a..24a987fa9 100644 --- a/src/Web/WebMVC/Views/Order/Create.cshtml +++ b/src/Web/WebMVC/Views/Order/Create.cshtml @@ -6,8 +6,8 @@ ViewData["Title"] = "New Order"; } -@Html.Partial("_Header", new Header() { Controller = "Cart", Text = "Back to cart" }) - +@Html.Partial("_Header", new List
() { + new Header() { Controller = "Cart", Text = "Back to cart" } })
diff --git a/src/Web/WebMVC/Views/Order/Detail.cshtml b/src/Web/WebMVC/Views/Order/Detail.cshtml index ef112a1c2..c17ffb2a9 100644 --- a/src/Web/WebMVC/Views/Order/Detail.cshtml +++ b/src/Web/WebMVC/Views/Order/Detail.cshtml @@ -7,7 +7,8 @@ }
- @Html.Partial("_Header", new Header() { Controller = "Order", Text = "Back to list" }) + @Html.Partial("_Header", new List
() { + new Header() { Controller = "Catalog", Text = "Back to catalog" } })
diff --git a/src/Web/WebMVC/Views/Order/Index.cshtml b/src/Web/WebMVC/Views/Order/Index.cshtml index 83cc8b992..227b95686 100644 --- a/src/Web/WebMVC/Views/Order/Index.cshtml +++ b/src/Web/WebMVC/Views/Order/Index.cshtml @@ -7,7 +7,9 @@ }
- @Html.Partial("_Header", new Header() { Controller = "Catalog", Text = "Back to catalog" }) + @Html.Partial("_Header", new List
() { + new Header() { Controller = "Catalog", Text = "Back to catalog" }, + new Header() { Controller = "OrderManagement", Text = "Orders Management" } })
@@ -25,9 +27,15 @@
@Html.DisplayFor(modelItem => item.Date)
$ @Html.DisplayFor(modelItem => item.Total)
@Html.DisplayFor(modelItem => item.Status)
-
+
Detail
+
+ @if ((item.Status.ToLower() != "shipped") && (item.Status.ToLower() != "cancelled")) + { + Cancel + } +
}
diff --git a/src/Web/WebMVC/Views/OrderManagement/Index.cshtml b/src/Web/WebMVC/Views/OrderManagement/Index.cshtml new file mode 100644 index 000000000..d108f2281 --- /dev/null +++ b/src/Web/WebMVC/Views/OrderManagement/Index.cshtml @@ -0,0 +1,43 @@ +@using Microsoft.eShopOnContainers.WebMVC.ViewModels + +@model IEnumerable + +@{ + ViewData["Title"] = "My Orders"; +} + +
+ @Html.Partial("_Header", new List
() { + new Header() { Controller = "Catalog", Text = "Back to catalog" } }) + +
+
+
Order number
+
Date
+
Total
+
Status
+
+
+ + @foreach (var item in Model) + { +
+
@Html.DisplayFor(modelItem => item.OrderNumber)
+
@Html.DisplayFor(modelItem => item.Date)
+
$ @Html.DisplayFor(modelItem => item.Total)
+
@Html.DisplayFor(modelItem => item.Status)
+
+ + + + +
+
+ } +
+
\ No newline at end of file diff --git a/src/Web/WebMVC/Views/Shared/_Header.cshtml b/src/Web/WebMVC/Views/Shared/_Header.cshtml index 894a92af2..9c06eabd3 100644 --- a/src/Web/WebMVC/Views/Shared/_Header.cshtml +++ b/src/Web/WebMVC/Views/Shared/_Header.cshtml @@ -1,7 +1,11 @@ -@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Header + +@model IEnumerable
- @Model.Text + @foreach (var header in @Model) + { + @header.Text + }
diff --git a/src/Web/WebMVC/wwwroot/css/shared/components/header/header.css b/src/Web/WebMVC/wwwroot/css/shared/components/header/header.css index 89fd203bd..737c18dbb 100644 --- a/src/Web/WebMVC/wwwroot/css/shared/components/header/header.css +++ b/src/Web/WebMVC/wwwroot/css/shared/components/header/header.css @@ -3,6 +3,20 @@ height: 4rem; } +.esh-header-title { + color: rgba(255, 255, 255, 0.5) !important; + line-height: 4rem; + text-transform: uppercase; + text-decoration: none; + transition: color 0.35s; + margin-right: 15px; +} + + .esh-header-title:hover { + color: #FFFFFF !important; + transition: color 0.35s; + } + .esh-header-back { color: rgba(255, 255, 255, 0.5) !important; line-height: 4rem; diff --git a/test/Services/UnitTest/Ordering/Application/IdentifierCommandHandlerTest.cs b/test/Services/UnitTest/Ordering/Application/IdentifierCommandHandlerTest.cs index d9cc878a5..a7eddfc0d 100644 --- a/test/Services/UnitTest/Ordering/Application/IdentifierCommandHandlerTest.cs +++ b/test/Services/UnitTest/Ordering/Application/IdentifierCommandHandlerTest.cs @@ -4,6 +4,7 @@ using System.Text; namespace UnitTest.Ordering.Application { + using global::Ordering.API.Application.Models; using MediatR; using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; @@ -70,7 +71,8 @@ namespace UnitTest.Ordering.Application private CreateOrderCommand FakeOrderRequest(Dictionary args = null) { return new CreateOrderCommand( - null, + new List(), + userId: args != null && args.ContainsKey("userId") ? (string)args["userId"] : null, city: args != null && args.ContainsKey("city") ? (string)args["city"] : null, street: args != null && args.ContainsKey("street") ? (string)args["street"] : null, state: args != null && args.ContainsKey("state") ? (string)args["state"] : null, diff --git a/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs b/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs index 2979fa561..87725f669 100644 --- a/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs +++ b/test/Services/UnitTest/Ordering/Application/NewOrderCommandHandlerTest.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; namespace UnitTest.Ordering.Application { + using global::Ordering.API.Application.Models; using MediatR; using System.Collections; using System.Collections.Generic; @@ -66,13 +67,14 @@ namespace UnitTest.Ordering.Application private Order FakeOrder() { - return new Order(new Address("street", "city", "state", "country", "zipcode"), 1, "12", "111", "fakeName", DateTime.Now.AddYears(1)); + return new Order("1", new Address("street", "city", "state", "country", "zipcode"), 1, "12", "111", "fakeName", DateTime.Now.AddYears(1)); } private CreateOrderCommand FakeOrderRequestWithBuyer(Dictionary args = null) { return new CreateOrderCommand( - null, + new List(), + userId: args != null && args.ContainsKey("userId") ? (string)args["userId"] : null, city: args != null && args.ContainsKey("city") ? (string)args["city"] : null, street: args != null && args.ContainsKey("street") ? (string)args["street"] : null, state: args != null && args.ContainsKey("state") ? (string)args["state"] : null, diff --git a/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs b/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs index 40bc66431..90bf412ef 100644 --- a/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs +++ b/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs @@ -110,7 +110,7 @@ public class OrderAggregateTest var expectedResult = 1; //Act - var fakeOrder = new Order(new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); + var fakeOrder = new Order("1", new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); //Assert Assert.Equal(fakeOrder.DomainEvents.Count, expectedResult); @@ -133,8 +133,8 @@ public class OrderAggregateTest var expectedResult = 2; //Act - var fakeOrder = new Order(new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); - fakeOrder.AddDomainEvent(new OrderStartedDomainEvent(fakeOrder,cardTypeId,cardNumber,cardSecurityNumber,cardHolderName,cardExpiration)); + var fakeOrder = new Order("1", new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); + fakeOrder.AddDomainEvent(new OrderStartedDomainEvent(fakeOrder, "1", cardTypeId,cardNumber,cardSecurityNumber,cardHolderName,cardExpiration)); //Assert Assert.Equal(fakeOrder.DomainEvents.Count, expectedResult); } @@ -153,8 +153,8 @@ public class OrderAggregateTest var cardSecurityNumber = "123"; var cardHolderName = "FakeName"; var cardExpiration = DateTime.Now.AddYears(1); - var fakeOrder = new Order(new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); - var @fakeEvent = new OrderStartedDomainEvent(fakeOrder, cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); + var fakeOrder = new Order("1", new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); + var @fakeEvent = new OrderStartedDomainEvent(fakeOrder, "1", cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); var expectedResult = 1; //Act